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字节,可选)

    image

  • 怎么用”TOA”实现传递客户端ip呢?

    有”转发服务”和”后端真实服务器”两个角色。

    image

    “转发服务”在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,它和本文这种方式有什么区别呢?