在学习完了SQL注入的原理SQL注入的类型后那么可以说SQL注入已经大致了解了,但事实是现实中开发人员不可能让你这么简单就攻击到数据库,他们一般会对已输入或可输入的数据做一定限制,这篇文章我主要对SQL注入中代码或者waf过滤的绕过做一次总结。

大小写绕过

这是最简单也是最鸡肋的绕过方式,可以利用的原因有两个:SQL语句对大小写不敏感、开发人员做的黑名单过滤过于简单。

mysql 注入过滤set关键字 sql注入过滤哪些_SQL注入

双写绕过

双写绕过的原理是后台利用正则匹配到敏感词将其替换为空。即如果过滤了select,我们输入123select456 后会被检测出敏感词,最后替换得到的字符串由123select456 ---> 123456。这种过滤的绕过也很简单即双写select即可,如:selselectect  ---> select ,进行一次这样的过滤就双写,两次就三写以此类推。看下面例子:

mysql 注入过滤set关键字 sql注入过滤哪些_sql_02

这里很清楚的看到错误的信息,or应该是被过滤了,我们利用上面讲的绕过方式,

mysql 注入过滤set关键字 sql注入过滤哪些_sql_03

 成功了,这也就是双写绕过的方法,挺简单的。

空格过滤

如果遇到空格被过滤了,主要的几个思路都是想办法找一个代替品,能代替空格的有几个:

注释绕过  /**/ :正常情况下只要这个没有被过滤就一定能代替。


括号过滤 () :将所有的关键字都用括号括起来就可以达到替代空格分隔的作用如下,

正常: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*****。

逗号过滤

有函数或者指令在使用时需要用到逗号,因此绕过逗号的方法因函数或指令的不同而不同。

substring()

mysql 注入过滤set关键字 sql注入过滤哪些_安全_04

不用在意函数,substrsubstring差不多。可以看到从上面本应用逗号的情况到下面直接用from……for代替。

如果需要用到mid()函数,其中也有逗号绕过的方法与substring()相同,用from……for替代逗号。

limit 0,1

limit 0,1中存在逗号,那么如果逗号被过滤了我们替代的方法是用offset,即

mysql 注入过滤set关键字 sql注入过滤哪些_mysql 注入过滤set关键字_05

这里要注意一下,如果使用了offset,原本逗号前后的数据要相互交换一下。

union

联合注入中我们需要select 1,2,3,4……,而如果过滤了逗号这里又该如何绕呢?这里其实挺有意思的,联合查询select 1,2,3,4……经过测试可以单独写如下

mysql 注入过滤set关键字 sql注入过滤哪些_web安全_06

括号后面的a、b、c是随意命名的是省略了as的写法,为什么我要这么写?这样写就可以把逗号过滤,我们使用offset代替可以得到,

mysql 注入过滤set关键字 sql注入过滤哪些_mysql 注入过滤set关键字_07

所以联合查询的逗号绕过是利用join代替。

等于号过滤

如果只过滤了等于号可以用以下代替

<> :不等于的意思 !=


regexp、like、rlike

mysql 注入过滤set关键字 sql注入过滤哪些_sql_08

逻辑运算符过滤

过滤了or、and、xor、not可以用相对应的字符代替:&&、||、| 、!

mysql 注入过滤set关键字 sql注入过滤哪些_web安全_09

如果都不能用则可以考虑使用笛卡尔积(^),

mysql 注入过滤set关键字 sql注入过滤哪些_web安全_10

这种可以直接不使用and or这些连接符。

编码绕过

编码绕过说实话传统很少用上,但是有时他的利用真的就会出其不意,所以还是了解一下。

十六进制绕过

mysql 注入过滤set关键字 sql注入过滤哪些_sql_11

mysql 注入过滤set关键字 sql注入过滤哪些_sql_12

相似函数的互相替代

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():这两个函数在处理英文时作用相同,但是处理中文等时不一致。
 

7)or过滤导致information无法使用可以用如下几个代替进行查表:

sys.x$schema_flattened_keys
sys.x$schema_table_statistics_with_buffer
sys.schema_table_statistics_with_buffer


字段的查询则利用无列名配合爆破如:

(select 1,xxxxx) > (select * from tablename)