查看: 10585|回复: 5

Discuz 防护绕过分析

[复制链接]
  • TA的每日心情

    2020-10-2 23:00
  • 签到天数: 10 天

    [LV.3]偶尔看看II

    发表于 2013-3-21 11:01:45 | 显示全部楼层 |阅读模式
    转自360
    144823tupakt1mfjpudssm.jpg
    最终防注入检查函数在discuz_database_safecheck::checkquery(%s)中,如下

    1.         protected static $checkcmd = array('SELECT', 'UPDATE', 'INSERT', 'REPLACE', 'DELETE');
    2.         protected static $config;

    3.         public static function checkquery($sql) {

    4.                 if (self::$config === null) {
    5.                         self::$config = getglobal('config/security/querysafe');
    6.                 }

    7.                 if (self::$config['status']) {
    8.                         $cmd = trim(strtoupper(substr($sql, 0, strpos($sql, ' '))));
    9.                         if (in_array($cmd, self::$checkcmd)) {
    10.                                 $test = self::_do_query_safe($sql);
    11.                                 if ($test < 1) {

    12.                                         throw new DbException('It is not safe to do this query', 0, $sql);
    13.                                 }
    14.                         }
    15.                 }
    16.                 return true;
    17.         }
    复制代码
    当%s中包含$checkcmd中关键字时就会调用_do_query_safe($sql)进行检查

    1.         private static function _do_query_safe($sql) {

    2.                 $sql = str_replace(array('\\\\', '\\\'', '\"', '\'\''), '', $sql);
    3.                 $mark = $clean = '';
    4.                 if (strpos($sql, '/') === false && strpos($sql, '#') === false && strpos($sql, '-- ') === false)
    5.                 //当$sql中包含/、#、--等字符时就会进入对应替换代码{
    6.                         $clean = preg_replace("/'(.+?)'/s", '', $sql);
    7.                 } else {
    8.                         $len = strlen($sql);
    9.                         $mark = $clean = '';
    10.                         for ($i = 0; $i < $len; $i++) {
    11.                                 $str = $sql[$i];
    12.                                 switch ($str) {
    13.                                         case '\''://防注入绕过出现在这里,当$sql中包含/*这样的字符串之后的内容会被替换为空,直到出现*/
    14.                                                 if (!$mark) {
    15.                                                         $mark = '\'';
    16.                                                         $clean .= $str;
    17.                                                 } elseif ($mark == '\'') {
    18.                                                         $mark = '';
    19.                                                 }
    20.                                                 break;
    21.                                         case '/':
    22.                                                 if (empty($mark) && $sql[$i + 1] == '*') {
    23.                                                         $mark = '/*';
    24.                                                         $clean .= $mark;
    25.                                                         $i++;
    26.                                                 } elseif ($mark == '/*' && $sql[$i - 1] == '*') {
    27.                                                         $mark = '';
    28.                                                         $clean .= '*';
    29.                                                 }
    30.                                                 break;
    31.                                         case '#':
    32.                                                 if (empty($mark)) {
    33.                                                         $mark = $str;
    34.                                                         $clean .= $str;
    35.                                                 }
    36.                                                 break;
    37.                                         case "\n":
    38.                                                 if ($mark == '#' || $mark == '--') {
    39.                                                         $mark = '';
    40.                                                 }
    41.                                                 break;
    42.                                         case '-':
    43.                                                 if (empty($mark) && substr($sql, $i, 3) == '-- ') {
    44.                                                         $mark = '-- ';
    45.                                                         $clean .= $mark;
    46.                                                 }
    47.                                                 break;

    48.                                         default:

    49.                                                 break;
    50.                                 }
    51.                                 $clean .= $mark ? '' : $str;
    52.                         }
    53.                 }
    54.                 //那么黑客提交/*xxx*/字符之间的xxx会被替换为空,或者#或者-- 时对应后面的内容替换为空保存到$clean变量中
    55.                 //被替换为空的$clean变量再做下面过滤

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

    57.                 if (self::$config['afullnote']) {
    58.                         $clean = str_replace('/**/', '', $clean);//这里使得/**/完全被替换为空,从而绕过下面$note变量的过滤
    59.                 }
    60. .........
    复制代码
    这里黑客可以提交/*! Sql */,把sql放到注释符中间替换为空,mysql中的/*!可以判断mysql版本决定是否执行,从而绕过了disczu内置的防注入检查,也可以使用注释#xxx%0a sql绕过,不过由于#号没有被替换为空,最终会被dnote中的关键字拦截.

    所以这里提醒广大站长检查config配置(\config\config_global.php)文件中的

    1. $_config['security']['querysafe']['afullnote'] = '0' //禁止 msyql 当中使用注释
    复制代码
    看这个afullnote的值是否是0,如果是1请改为0.
    并非某些厂商说的那样只要是最新版本就没风险的说法。如下是一个最新版本的discuz环境,因为插件的sql注入原因结合配置项是$_config['security']['querysafe']['afullnote'] = '1'开启了mysql注释功能,导致一样受到sql注入攻击威胁。
    145451uf8a44u84zf2sqt7.png
    所以再提醒广大站长安全问题的重要性。
    由低版本升级过来的,即使现在是最新版本,由于不会自动修改配置项,导致这种升级全部存在安全隐患。

    评分

    参与人数 1i币 +10 收起 理由
    90_ + 10

    查看全部评分

    回复

    使用道具 举报

  • TA的每日心情

    2024-12-14 22:22
  • 签到天数: 1631 天

    [LV.Master]伴坛终老

    发表于 2013-3-21 11:04:10 | 显示全部楼层
    360团队最近还是比较攒的
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2013-3-21 11:40:44 | 显示全部楼层
    {:soso_e179:}

    评分

    参与人数 1i币 -8 收起 理由
    90_ -8 恶意灌水

    查看全部评分

    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2013-3-21 14:42:50 | 显示全部楼层
    学习学习  谢谢分享
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2022-7-5 19:16
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2013-3-21 15:41:45 | 显示全部楼层
    虽然看不懂但是感谢你的分享,我多看即便就可以看出点门道了。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2017-4-6 09:55
  • 签到天数: 55 天

    [LV.5]常住居民I

    发表于 2013-3-21 18:10:48 | 显示全部楼层
    讲的很详细了,受用
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    指导单位

    江苏省公安厅

    江苏省通信管理局

    浙江省台州刑侦支队

    DEFCON GROUP 86025

    旗下站点

    邮箱系统

    应急响应中心

    红盟安全

    联系我们

    官方QQ群:112851260

    官方邮箱:security#ihonker.org(#改成@)

    官方核心成员

    Archiver|手机版|小黑屋| ( 苏ICP备2021031567号 )

    GMT+8, 2024-12-28 12:26 , Processed in 0.029806 second(s), 18 queries , Gzip On, MemCache On.

    Powered by ihonker.com

    Copyright © 2015-现在.

  • 返回顶部