在学习完了SQL注入的原理、SQL注入的类型后那么可以说SQL注入已经大致了解了,但事实是现实中开发人员不可能让你这么简单就攻击到数据库,他们一般会对已输入或可输入的数据做一定限制,这篇文章我主要对SQL注入中代码或者waf过滤的绕过做一次总结。
这是最简单也是最鸡肋的绕过方式,可以利用的原因有两个:SQL语句对大小写不敏感、开发人员做的黑名单过滤过于简单。
双写绕过的原理是后台利用正则匹配到敏感词将其替换为空。即如果过滤了select,我们输入123select456 后会被检测出敏感词,最后替换得到的字符串由123select456 ---> 123456。这种过滤的绕过也很简单即双写select即可,如:selselectect ---> select ,进行一次这样的过滤就双写,两次就三写以此类推。看下面例子:
这里很清楚的看到错误的信息,or应该是被过滤了,我们利用上面讲的绕过方式,
成功了,这也就是双写绕过的方法,挺简单的。
如果遇到空格被过滤了,主要的几个思路都是想办法找一个代替品,能代替空格的有几个:
注释绕过 /**/ :正常情况下只要这个没有被过滤就一定能代替。
括号过滤 () :将所有的关键字都用括号括起来就可以达到替代空格分隔的作用如下,
正常:select * from user
括号:(select)*(from)(user)
url编码:这种遇到可以试试。用%20代替空格或者用其他的url编码
%09、%0a、%0b、%0c、%0d 、%a0、%00
回车换行替代:回车换行也可以用做分隔功能替代空格。
Tab替代:Tab可以做分隔功能。
遇到我们平常用的 --+ 注释过滤,我们可以用以下几种注释代替:
#、;%00、-- (两个减号一个空格)
用其他数据闭合:
select * from user where id='1'
||
V
select * from user where id='1' or '1' ='1'
引号过滤有两种全款,一种是不能出现引号、一种是会被转义,转义的处理方法上一篇已经说过了就是宽字节注入的绕过,如果是无法出现引号又必修得用引号,可以将参数的值和单引号或者双引号绑定在一起然后转换为16进制最后在输入时在前加0x*****。
有函数或者指令在使用时需要用到逗号,因此绕过逗号的方法因函数或指令的不同而不同。
不用在意函数,substr与substring差不多。可以看到从上面本应用逗号的情况到下面直接用from……for代替。
如果需要用到mid()函数,其中也有逗号绕过的方法与substring()相同,用from……for替代逗号。
limit 0,1中存在逗号,那么如果逗号被过滤了我们替代的方法是用offset,即
这里要注意一下,如果使用了offset,原本逗号前后的数据要相互交换一下。
联合注入中我们需要select 1,2,3,4……,而如果过滤了逗号这里又该如何绕呢?这里其实挺有意思的,联合查询select 1,2,3,4……经过测试可以单独写如下
括号后面的a、b、c是随意命名的是省略了as的写法,为什么我要这么写?这样写就可以把逗号过滤,我们使用offset代替可以得到,
所以联合查询的逗号绕过是利用join代替。
如果只过滤了等于号可以用以下代替
<> :不等于的意思 !=
regexp、like、rlike
过滤了or、and、xor、not可以用相对应的字符代替:&&、||、| 、!
如果都不能用则可以考虑使用笛卡尔积(^),
这种可以直接不使用and or这些连接符。
编码绕过说实话传统很少用上,但是有时他的利用真的就会出其不意,所以还是了解一下。
1)sleep() <-->benchmark()
2)ascii() <-–>hex()、bin(),替代之后再使用对应的进制转string即可
3)group_concat() <–->concat_ws()
4)substr() <--> substring() <--> mid()
5)user() <--> @@user、datadir–>@@datadir
6)ord() <-–> ascii():这两个函数在处理英文时作用相同,但是处理中文等时不一致。
参考:SQL注入绕过的姿势_真的强啊!的博客-CSDN博客_sql注入from绕过
SQL注入时当and、or等字符被过滤了怎么办_litchi125的博客-CSDN博客_sql注入过滤and
SQL注入过滤的绕过_12622800的技术博客_51CTO博客
https://www.csdn.net/tags/MtTaEgwsMTY0OTk1LWJsb2cO0O0O.html#2_12