知己知彼,百战不殆 --孙子兵法
[目录]
0x0 前言
0x1 WAF的常见特征
0x2 绕过WAF的方法
0x3 SQLi Filter的实现及Evasion
0x4 延伸及测试向量示例
0x5 本文小结
0x6 参考资料
0x0 前言
促使本文产生最初的动机是前些天在做测试时一些攻击向量被WAF挡掉了,而且遇到异常输入直接发生重定向。之前对WAF并不太了解,因此趁此机会科 普一下并查阅了一些绕过WAF的方法。网上关于绕过WAF有诸多文章,但是观察之后会发现大体上绕过WAF的方法就那八、九种,而且这些技术出来也有些日 子了,继续使用这些方法是否有效有待于我们在实际中去验证。看过数篇绕过WAF的文章后,前人对技术的总结已经比较全面,但是完整的内容可能分布在各处, 查阅起来不太方便。另外,我们谈绕过WAF,其实就是谈如何绕过过滤机制,如果在讨论bypass技术的时候明确一下现有的一些filter的实现及其 evasion,对于我这样的初学者来说是不是更好?还有就是如果在文章后面可以提供一些测试向量提供思路和参考,内容看起来很杂,但是也会比较方便呢? 抱着这些想法,同时也顶着巨大的压力(前人工作已经比较完善,这么大的信息量总结起来对我是一次挑战),我还是决定写出本文,这样更能适应自己的需求,也 可能更加适合一些朋友的需求。
本文内容从技术上来说并非原创,也没有很新的或重大的发现,乃是这几天从各种资料信息中进行整理所得。本文会对形如http://www.site.com的URI进行简化,约定为z.com。
0x1 WAF的常见特征
之所以要谈到WAF的常见特征,是为了更好的了解WAF的运行机制,这样就能增加几分绕过的机会了。本文不对WAF做详细介绍,只谈及几点相关的。
总体来说,WAF(Web Application Firewall)的具有以下四个方面的功能:
1. 审计设备:用来截获所有HTTP数据或者仅仅满足某些规则的会话
2. 访问控制设备:用来控制对Web应用的访问,既包括主动安全模式也包括被动安全模式
3. 架构/网络设计工具:当运行在反向代理模式,他们被用来分配职能,集中控制,虚拟基础结构等。
4. WEB应用加固工具:这些功能增强被保护Web应用的安全性,它不仅能够屏蔽WEB应用固有弱点,而且能够保护WEB应用编程错误导致的安全隐患。
WAF的常见特点:
异常检测协议:拒绝不符合HTTP标准的请求
增强的输入验证:代理和服务端的验证,而不只是限于客户端验证
白名单&黑名单:白名单适用于稳定的We应用,黑名单适合处理已知问题
基于规则和基于异常的保护:基于规则更多的依赖黑名单机制,基于异常更为灵活
状态管理:重点进行会话保护
另还有:Coikies保护、抗入侵规避技术、响应监视和信息泄露保护等
如果是对于扫描器,WAF有其识别之道:
扫描器识别主要由以下几点:
1) 扫描器指纹(head字段/请求参数值),以wvs为例,会有很明显的Acunetix在内的标识
2) 单IP+ cookie某时间段内触发规则次数
3) 隐藏的链接标签等(<a>)
4) Cookie植入
5) 验证码验证,扫描器无法自动填充验证码
6) 单IP请求时间段内Webserver返回http状态404比例, 扫描器探测敏感目录基于字典,找不到文件则返回404
0x2 绕过WAF的方法
从目前能找到的资料来看,我把这些绕过waf的技术分为9类,包含从初级到高级技巧
a) 大小写混合
b)替换关键字
c)使用编码
d)使用注释
e)等价函数与命令
f)特殊符号
g)HTTP参数控制
h)缓冲区溢出
i)整合绕过
a) 大小写绕过
大小写绕过用于只针对小写或大写的关键字匹配技术,正则表达式/express/i 大小写不敏感即无法绕过,这是最简单的绕过技术
举例:z.com/index.PHP?page_id=-15 uNIoN sELecT 1,2,3,4
示例场景可能的情况为filter的规则里有对大小写转换的处理,但不是每个关键字或每种情况都有处理
b)替换关键字
这种情况下大小写转化无法绕过,而且正则表达式会替换或删除select、union这些关键字,如果只匹配一次就很容易绕过
举例:z.com/index.php?page_id=-15 UNIunionON SELselectECT 1,2,3,4
同样是很基础的技术,有些时候甚至构造得更复杂:SeLSeselectleCTecT,不建议对此抱太大期望
c)使用编码
1.URL编码
在Chrome中输入一个连接,非保留字的字符浏览器会对其URL编码,如空格变为 、单引号'、左括号(、右括号)
普通的URL编码可能无法实现绕过,还存在一种情况URL编码只进行了一次过滤,可以用两次编码绕过:page.php?id=1%2f%2a*/UNION%2f%2a /SELECT
2.十六进制编码
举例:z.com/index.php?page_id=-15 /*!union*/ /*!select*/ 1,2,3,4…
SELECT(extractvalue(0x3C613E61646D696E3C2F613E,0x2f61))
示例代码中,前者是对单个字符十六进制编码,后者则是对整个字符串编码,使用上来说较少见一点
3.Unicode编码
Unicode有所谓的标准编码和非标准编码,假设我们用的utf-8为标准编码,那么西欧语系所使用的就是非标准编码了
看一下常用的几个符号的一些Unicode编码:
单引号: %u0027、%u02b9、%u02bc、%u02c8、%u2032、%uff07、