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

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

缺陷编号: WooYun-2015-118730

漏洞标题: 帝友P2P借贷系统某处代码执行漏洞

相关厂商: 厦门帝网信息科技有限公司

漏洞作者: Rtsjx

提交时间: 2015-06-07 11:31

公开时间: 2015-09-09 11:32

漏洞类型: 命令执行

危害等级: 高

自评Rank: 20

漏洞状态: 厂商已经确认

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

Tags标签: 文件上传漏洞 任意webshell 文件上传

9人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-06-07: 细节已通知厂商并且等待厂商处理中
2015-06-11: 厂商已经确认,细节仅向厂商公开
2015-06-14: 细节向第三方安全合作伙伴开放(绿盟科技唐朝安全巡航无声信息
2015-08-05: 细节向核心白帽子及相关领域专家公开
2015-08-15: 细节向普通白帽子公开
2015-08-25: 细节向实习白帽子公开
2015-09-09: 细节向公众公开

简要描述:

唉……这代码质量,顿时给跪下了。

详细说明:

这个洞洞需要结合上次爆的默认密钥一起来爽。



====================上集回顾====================



帝友在整个程序中使用了自定义的对称加密方式(通常被定义为authcode或类似名称),而如果不显式指定或修改源码,函数将会调用默认密钥。这是本漏洞触发的前置条件。



===================上集回顾完===================



随着审计工作的愉快进行,我发现到/plugins/avatar/avatar.class.php中一个方法长得很有趣:



code 区域
function onuploadavatar() {

@header("Expires: 0");
@header("Cache-Control: private, post-check=0, pre-check=0, max-age=0", FALSE);
@header("Pragma: no-cache");
//header("Content-type: application/xml; charset=utf-8");

$this->init_input($this->getgpc('agent', 'G'));

$uid = $this->input('uid');
if(empty($uid)) {
return -1;
}
if(empty($_FILES['Filedata'])) {
return -3;
}

list($width, $height, $type, $attr) = getimagesize($_FILES['Filedata']['tmp_name']);
$imgtype = array(1 => '.gif', 2 => '.jpg', 3 => '.png');
$filetype = $imgtype[$type];
$tmpavatar = AVATAR_DATADIR.'./tmp/upload'.$uid.$filetype; //【这里拼合了$uid和$filetype两个变量作为move_uploaded_file的参数】
file_exists($tmpavatar) && @unlink($tmpavatar);
if(@copy($_FILES['Filedata']['tmp_name'], $tmpavatar) || @move_uploaded_file($_FILES['Filedata']['tmp_name'], $tmpavatar)) {
@unlink($_FILES['Filedata']['tmp_name']);
list($width, $height, $type, $attr) = getimagesize($tmpavatar);
if($width < 10 || $height < 10 || $type == 4) {
@unlink($tmpavatar);
return -2;
}
} else {
@unlink($_FILES['Filedata']['tmp_name']);
return -4;
}
$avatarurl = AVATAR_DATAURL.'/tmp/upload'.$uid.$filetype;
return $avatarurl;
}





我们重点来关心$uid和$filetype是否可控。



$uid赋值来自于

code 区域
$uid = $this->input('uid');





而$filetype则来自于$imgtype数组中的元素。

code 区域
$filetype = $imgtype[$type]





首先来看input方法:



code 区域
function input($k) {
return isset($this->input[$k]) ? (is_array($this->input[$k]) ? $this->input[$k] : trim($this->input[$k])) : NULL;
}





input方法只是简单的返回了当前对象的input属性数组中对应元素或者null。我们可以发现,在onuploadavatar方法中,init_input方法会被调用。而这个init_input方法干了啥事儿:



code 区域
function init_input($getagent = '') {
$input = $this->getgpc('input', 'R'); //【这里直接引用了用户传递进来的input参数】

if($input) {
$input = $this->authcode($input, 'DECODE', 'deck'); //【全国人民喜闻乐见的authcode出现了!这里指定了默认密钥deck!】

parse_str($input, $this->input);
$this->input = $this->daddslashes($this->input, 1, TRUE);
$agent = $getagent ? $getagent : $this->input['agent'];

if(($getagent && $getagent != $this->input['agent']) || (!$getagent && md5($_SERVER['HTTP_USER_AGENT']) != $agent)) {
exit('Access denied for agent changed');
} elseif($this->time - $this->input('time') > 3600) {
exit('Authorization has expired');
}
}
if(empty($this->input)) {
exit('Invalid input');
}
}





看到authcode我就放心的知道,这里存在默认密钥的利用点。换句话说,被init_input解码的参数如果来自于用户,则在未修改此处代码的情况下【可控】。





这时候,如果这个点要能被利用,那么还需要满足后缀可控。但是,程序中使用了一个不是来自用户的变量(依据getimagesize函数返回值)去向$filetype赋值,而且强制指定了jpg/png/gif三种扩展名。





我们来到世界上最好的语言PHP的官网上查找getimagesize的说明。机智的我发现了这一点:



getimagesize





getimagesize除了能识别jpg/png/gif之外还他喵的能处理其他多种类型的图片。于是,我进行这些尝试:



bmp





tif





可以发现,如果使用bmp或者tif的图片文件可以让getimagesize返回值数组的第三个元素不落在$imgtype的键名中。



在PHP中,拼合一个不存在键名的数组元素等于拼合空数组。



此时,PoC可以使用以下方式构造:



$uid = (解码后)fuckyou.php && 一个包含<?php @eval($_POST[a]); ?>的BMP图片。



调用默认加密过程将特殊的$uid转换为base64,然后直接向



{打个码吧,免得太直白了}?m=user&inajax=1&a=uploadavatar&appid=1&input={啦啦啦不告诉你}&agent=hahahahahahah&avatartype=virtual



提交上传请求,接着访问一下,哟吼~



Webshell







(P.S:由于帝友使用了加密参数,所有这个洞能bypass掉各种waf,自带打狗棒的节奏不能更爽……)

漏洞证明:

Webshell

修复方案:

自求多福。

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


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:20

确认时间:2015-06-11 11:31

厂商回复:

您好,非常感谢您检测的帝友P2P借贷系统某处代码执行漏洞,您的报告发出后,我司技术人员第一时间对帝友旗下所有系统进行逐个排查,确认了该漏洞是来自帝友P2P网络借贷系统V3版。该漏洞是由于$uid和$filetype逻辑上的不严谨,通过构造$uid和用其他格式图片植入php代码即可绕过,就可以上传一个php文件,经过紧急处理后,现在已修复完毕。
在此,也感谢您上次检查出的帝友P2P系统支付密码重置的问题。该漏洞早在2015年1月1日我司已经修复并联系客户更新,由于对乌云网的操作流程不了解,误采取了“忽略处理”,这是我司考虑不够周全,深表歉意。
我们会加强漏洞的排查,将系统安全放在第一位。欢迎您继续对我们的系统进行检测,大众的监督是我们前进的助力。

最新状态:

暂无


漏洞评价:

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

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

评价

  1. 2015-06-11 12:43 | phith0n 认证白帽子 ( 普通白帽子 | Rank:804 漏洞数:125 | 一个想当文人的黑客~)
    1

    厂商态度赞

  2. 2015-06-11 14:31 | Rtsjx ( 实习白帽子 | Rank:31 漏洞数:4 | ......)
    0

    我还以为厂商有了绿盟就不管洞洞了……

  3. 2015-09-09 13:00 | HackBraid 认证白帽子 ( 普通白帽子 | Rank:1854 漏洞数:296 | 风暴网络安全空间: http://www.heysec.or...)
    0

    额,原来是这个漏洞

  4. 2015-09-09 15:04 | BeenQuiver ( 普通白帽子 | Rank:103 漏洞数:27 | 专注而高效,坚持好的习惯千万不要放弃)
    0

    绕过waf神技能

  5. 2015-09-09 16:30 | 大师兄 ( 实习白帽子 | Rank:31 漏洞数:8 | 每日必关注乌云)
    0

    @厦门帝网信息科技有限公司 态度很赞!!

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