WAF攻防实践(5)
问题背景
How to Break Through Cloud-Based WAF 提到: 攻击者可以利用”TOA模块”伪造客户端ip,如果厂商有ip白名单,攻击者就有可能绕过WAF的防护。
按照我的理解,因为这种攻击方式可以用来伪造源ip,所以它不仅可以用来绕过WAF,还适用于”存在白名单ip防御措施”的场景,比如当后台管理系统只能”白名单ip”访问。
当然这种绕过方式也有一定的前置条件,而且我感觉满足条件的攻击场景应该不多,所以这种绕过方式出现概率应该不高。
建议读者先看一下原文的六页ppt,再来看我这篇”学习总结”。相比于原文,我补充了”测试脚本”和”测试时需要注意的两个小坑”,希望能节约读者测试验证时花费的时间。
本文主要研究以下问题:
- TOA是什么?
- 怎么测试目标是否存在这类问题?
我在这个案例学到了一些小的知识点:
- tcp报文的options字段的格式
- 企业中怎么获取真实 client ip
- 怎么用scapy发送带seq、ack序号的报文
分析过程
TOA是什么?
是”TCP_option_address”的缩写;它和”X-Forwarded-For”一样,可以用来传递真实的”客户端ip”。
两者的区别在于:”X-Forwarded-For”工作在”应用层”,”TOA”工作在”tcp层”
Tcp Options字段可以包含不固定数量个下面这样的数据结构:
Kind(1字节) | Length(1字节,可选) | Info(n字节,可选)
怎么用”TOA”实现传递客户端ip呢?
有”转发服务”和”后端真实服务器”两个角色。
“转发服务”在tcp包的options字段塞入真实的”客户端ip”。
在”后端真实服务器”安装一些”内核模块”后,应用程序就可以用getpeername、accept等系统调用拿到真实的”客户端ip”。这些”内核模块”(比如百度ttm、华为toa)hook了用来接受包的内核函数。当收到数据包时,它们会遍历tcp包的options字段,然后取出真实的”客户端ip”,最终返回给应用层。
怎么绕过WAF?
在云waf架构中,一个http请求的数据流是:客户端(浏览器) -> 转发服务(bgw) -> waf检测集群 -> 源站。
其中waf检测集群拿到的”客户端ip”是”转发服务”处理后的。
如果客户端发包时在tcp包的options字段加入伪造的客户端ip和端口,且”转发服务”没有检查tcp包的options字段中是否有伪造的”客户端ip”,就会导致”waf检测集群”拿到伪造的客户端ip和端口。
如果有对来源ip做白名单机制,就会存在绕过。
怎么测试目标是否存在这类问题?
针对云waf可以这么测试:客户端发攻击包同时伪造来源ip,然后在控制台查看拦截日志。如果拦截日志中的攻击源ip不是真实ip,就说明存在问题。
客户端发包代码见 gist
其中有两点需要注意:
系统收到服务端的syn-ack包时,因为网络连接不存在,所以会回复一个rst包。这会影响测试,因此测试前要屏蔽掉回复的rst包。
在伪造ip时,tcp options需要和测试目标”后端真实服务器”用的数据结构相同。这个数据结构可以参考 百度ttm、华为toa。
另外建议在客户端抓包看下流量是否符合预期,以下是我测试时抓包的数据,可以看到tcp options字段已经有了我设置的”kind是238的数据”。
1
2
3
4
5
6
7[root@instance-fj5pftdp ~]# tcpdump host 120.92.15.189
...
17:27:08.411615 IP instance-fj5pftdp.entextxid > 120.92.15.189.http: Flags [S], seq 0, win 8192, options [unknown-238 0xcafe94c16441,nop,nop,eol], length 0
17:27:08.462963 IP 120.92.15.189.http > instance-fj5pftdp.entextxid: Flags [S.], seq 4179803533, ack 1, win 8192, options [unknown-238 0xcafe94c16441,nop,nop,eol], length 0
17:27:08.496708 IP instance-fj5pftdp.entextxid > 120.92.15.189.http: Flags [.], seq 1:50, ack 1, win 8192, options [unknown-238 0xcafe94c16441,nop,nop,eol], length 49: HTTP: GET /?a=../../../ HTTP/1.1
17:27:08.548138 IP 120.92.15.189.http > instance-fj5pftdp.entextxid: Flags [.], ack 50, win 29200, length 0
17:27:08.550722 IP 120.92.15.189.http > instance-fj5pftdp.entextxid: Flags [.], seq 1:513, ack 50, win 29200, length 512: HTTP: HTTP/1.1 403 Forbidden
总结
厂商只要转发包时,抹去所有tcp options字段 或者 检查tcp opitons有没有奇怪的kind,就可以避免这个问题,这也是我觉得这种问题出现概率不高的原因。我没有对很多厂商做测试,如果大家有啥新发现,可以公众号后台私信我。
另外我把数据包文件放在了test.pcap,如果对tcp options格式字段有疑问,就可以用wireshark打开数据包看看。
留给读者一个问题:nmap -S 参数也能伪造源ip,它和本文这种方式有什么区别呢?