利用 multipart boundary 绕过 WAF
2021-08-02 11:43:06 Author: mp.weixin.qq.com(查看原文) 阅读量:21 收藏

0x00 前言

WAF(Web Application Firewall)是很常见的 Web 安全基础设施,许多云厂商、大厂、乙方安全公司均有相应的产品。然而,不得不承认,WAF 只能有限提升安全防护能力,不能拦截一些稍微复杂的攻击。正常业务不应当过度依赖 WAF,况且 WAF 还存在误拦截正常业务流量的可能。

目前已知的一些绕过 WAF 的手段包括但不限于:

  • Chunked encoding 绕过

  • IBM037 等罕见编码绕过

多嘴一句:最早提出 IBM037 编码绕过 WAF 的应该是Soroush Dalili 在 SteelCon 2017 上的议题 [1],然而国内众多相关文章,基本没有标记出处,很奇怪。

笔者最近在分析 Go 语言的 HTTP 协议解析实现的时候,发现了一种能够利用 multipart boundary 绕过 WAF 的方法,在 Python 的一些 Web 框架上也适用,因而将其分享出来。

0x01 绕过

multipart/form-data 是一种非常常见的 HTML 表单编码方式,绝大部分的 Web 服务器、框架实现,均支持此编码。其编码后的请求大致如下所示,表单数据通过boundary分割。

POST /test HTTP/1.1Host: example.comContent-Type: multipart/form-data; boundary=“boundary”
—boundaryContent-Disposition: form-data; name=“field1”
value1—boundaryContent-Disposition: form-data; name=“field2”; filename=“example.txt”
value2—boundary—

那么只要满足上述协议要求,服务端就可以正常获取到字段内容了,如下图所示。

那么如果构造多个 boundary 会有什么效果?很遗憾,一些服务端实现(比如 Go 语言)不允许多个 boundary,数据传递失败:

多个 Content-Type 倒是可行,然而多数服务端,包括 WAF 的实现,基本上只认第一个出现的 Content-Type 。

只能另辟蹊径。

回到协议解析本身

在 Go 语言的实现中,multipart/form-data 中对 boundary 的解析是通过 mime.ParseMediaType 实现的:

然而 mime.ParseMediaType 对 MediaType 参数的解析有个有趣的细节,正常情况下,参数不允许重复,如下图 190行 所示,这也是上文请求失败的原因。

然而在 203行 处,却允许参数的覆盖,只要目标参数满足 RFC 2231 的格式。RFC 2231中描述了一种名为 Parameter Value Continuations 的规范 [2],其核心部分如下图所示,大意是一个参数URL,可以等价拆成两个分别名为URL*0、URL*1的参数。

那么,boundary 能否通过同样的方式覆盖呢?实际测试一下,发现可行。Go 会将boundary*0="real-";boundary*1="boundary" 当作最终的 boundary 。

绕过某云 WAF

上节中提到的怪异但符合Parameter Value Continuations 规范[2] 的数据包,应该是一个绕过 WAF 的神器。笔者随即写了一个存在 SQL 注入漏洞的服务,挂在某国内领头羊云厂商的 WAF 后面进行测试,证实了这个猜想。

这个测试服务的 id 字段存在注入,正常情况下,因为没有任何攻击特征,WAF 不会拦截:

进行注入,WAF 会正常拦截:

然而当我们请出 RFC 2231 [2]大爷,整个注入攻击变得畅通无阻。

本质上是利用了 WAF 和 服务端 的协议解析差异来绕过防护的,应当可以绕过一大票 WAF 产品。这里没有一一测试各家产品,不是为了避免拿来党,主要还是因为懒。

0x02 举一反三

上述绕过方式是基于 RFC 2231 的,因此其它支持  RFC 2231  [2]的服务端实现也应当可以绕过。笔者对比较流行的 Python 框架 —— Flask 进行了测试,毫无意外地利用成功了。然而 Flask 的服务端实现和 Go 有细微的差异,最终解析出来的 boundary 参数,会拼接原始的 boundary 参数,如下图所示。

其它语言、框架应有类似的特性。

0x03 总结

WAF 绕过的本质是利用了 WAF 和 服务端 的协议解析差异。类似的差异应该还有许多。最后重复一下一开始提到的观点:WAF 并不可靠,不要过度依赖 WAF。


引用:

[1] https://www.slideshare.net/SoroushDalili/a-forgotten-http-invisibility-cloak

[2] https://datatracker.ietf.org/doc/html/rfc2231#section-3


文章来源: http://mp.weixin.qq.com/s?__biz=MzA4NzQwNzY3OQ==&mid=2247483736&idx=1&sn=cf428dff768df031d6fe0f3f37e9d214&chksm=9038ac08a74f251e91761274e2432b0b251362b95ccd57613f3cd3a21da7deca7b94ba423b5a&mpshare=1&scene=24&srcid=0802rpcU1tzUiWaz3RfNaU0m&sharer_sharetime=1627875785954&sharer_shareid=5191b3dcb328f693d5261ba6bca8d267#rd
如有侵权请联系:admin#unsafe.sh