安全矩阵

 找回密码
 立即注册
搜索
查看: 876|回复: 0

突破防线:探索利用畸形表单绕过WAF的攻击方法与防御策略

[复制链接]

260

主题

275

帖子

1065

积分

金牌会员

Rank: 6Rank: 6

积分
1065
发表于 2023-5-30 12:08:03 | 显示全部楼层 |阅读模式
本帖最后由 luozhenni 于 2023-5-30 12:07 编辑

突破防线:探索利用畸形表单绕过WAF的攻击方法与防御策略
原文链接:突破防线:探索利用畸形表单绕过WAF的攻击方法与防御策略
原创 安全研究院 [url=]知其安科技[/url] 2023-05-29 18:30 发表于北京收录于合集#WAF1个#边界安全1个

简介

内容概要:
利用Web服务器和WAF(Web应用防火墙)对RFC1867在兼容实现上的差异,探索利用畸形表单绕过WAF的不同情形。
最后,介绍了防御此类攻击的运营方案。
本文将从以下几个方面进行介绍:
1、构造畸形表单绕过WAF的攻击方法及原因。
2、探索该攻击方法,在面对不同的Web服务时,是否是通用有效的。
3、探索该攻击方法,绕过WAF的实战效果。

一为什么畸形表单能绕过WAF?

  • HTTP文件上传的定义——RFC1867
为什么畸形表单能绕过WAF——不得不看文件上传的请求格式规范——RFC1867。
RFC1867中规定:要上传文件,其HTTP请求中的Content-Type字段,须设定为multipart/form-data,同时用一个filename="example.txt"字段,来表示文件的名字[2],HTTP请求包格式如下:
  1. POST /test.html HTTP/1.1
  2. Host: example.org
  3. Content-Type: multipart/form-data;boundary="boundary"
复制代码
  1. --boundary
  2. Content-Disposition: form-data; name="field1"
复制代码
  1. POST params
  2. --boundary
  3. Content-Disposition: form-data; name="field2"; filename="example.txt"
复制代码
  1. POST FILE CONTENTS
  2. --boundary--
复制代码
虽然RFC这么说了,但具体的实现,还得看不同的Web服务器,服务器是否一定能准确领会呢?
事实上,RFC是“Request for Comments”,中文翻译为:请求意见稿,而非一个强制的标准。因此,WAF和业务服务器,作为复杂网络架构中的不同主体,对这个RFC的实现,可能会因为读者的个体理解,存在差异(Inconsistency)。
因此,我们提出以下几个问题进行思考:
1、看起来,是否传入 filename=,是传文件、传参数之间的区别点。那么这里是否区分大小写?
2、类似于“HPP参数污染”的攻击手段,假如同时出现了2行Content-Type: multipart/form-data;boundary="xx"请求头,后端服务器会取哪一行?
3、数据与数据之间的边界,定义是否清晰?具体而言,boundary、filename,能否出现空字符,如\00。这里是否需要自动清理异常字符的逻辑?
4、同样地,Content-Disposition的边界在哪里?允许出现多个Content-Disposition头吗?当出现多个时,后端会取哪一个?

恰恰是WAF、Web服务器对以上这些问题的不同解答,能让我们绕过WAF进行攻击。

WAF处理文件上传请求
现在的WAF,几乎都会检测上传文件的POST请求,但出于实时检测的性能考虑,某些WAF对上传文件的大小有限制。




Azure WAF对文件大小的检测限制,100MB若用户上传的文件大小,超过设定的上限。有些WAF便不再分析该文件的内容,会直接放行该请求。为了认知的简便,我们在本文中假设:WAF对上传文件的大小限制为0——也就是说,对于某个HTTP请求,若WAF识别其为文件上传请求,就直接放行,不再拦截。
PHP处理文件上传请求

为了更好的切入场景,我们不妨举一个后端服务器为PHP的例子,场景如下:1. 为了演示起见,后端PHP源代码如下2. 实际的攻击场景,可能是:我们在渗透过程中,要使用参数名为KEY的POST参数,来开展攻击。因此只要后端接收到键名为KEY的POST参数,哪怕会引入一些特殊符号(后文会提到),也会判为“攻击成功”。

  1. <?php
  2.     echo "_POST\t";
  3.     // 真实的攻击场景,可能是:
  4.     // echo system($_POST['KEY']);
  5.     var_dump($_POST);
复制代码
  1. echo "\n\n";
  2.     echo "_FILES\t";
  3.     var_dump($_FILES);
  4.     echo "\n\n";
  5.    
  6.     echo "_GET\t";
  7.     var_dump($_GET);
  8.     echo "\n\n";
复制代码

畸形boundary值
通过构造畸形的boundary,使得:后端服务器认为其是POST表单请求,但WAF认为其是个POST文件上传请求——由于WAF不拦截文件上传请求,所以后端服务器能正常接收到POST参数。如下图所示:



看起来传的是文件,其实传的是POST参数
那么,如果把关键字THE_PAYLOAD改为真正的攻击参数,即为攻击成功,例如:


  1. POST /post.php HTTP/1.1
  2. Host: 127.0.0.1
  3. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36
  4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
  5. Connection: close
  6. Content-Type: multipart/form-data; boundary=boundary=----WebKitFormBoundaryqNDkoxvBDubtc5fJ;
  7. Content-Length: 377

  8. ----WebKitFormBoundaryqNDkoxvBDubtc5fJ
  9. Content-Disposition: form-data; name="fake";filename="1.jpg"
  10. Content-Type: image/jpeg

  11. PADDING_CONTENT
  12. --boundary=----WebKitFormBoundaryqNDkoxvBDubtc5fJ
  13. Content-Disposition: form-data; name="KEY";
  14. Content-Type: image/jpeg

  15. `cat ../../../../../etc/passwd`
  16. --boundary=----WebKitFormBoundaryqNDkoxvBDubtc5fJ--
  17. ----WebKitFormBoundaryqNDkoxvBDubtc5fJ--
复制代码

注意,在这里,我们构造的畸形boundary为:boundary=----
WebKitFormBoundaryqNDkoxvBDubtc5fJ(正常的值是----
WebKitFormBoundaryqNDkoxvBDubtc5fJ,我们构造的内容前面多了个boundary=)
畸形Content-Disposition头
再举一个例子,在PHP识别文件上传时,不允许Content-Disposition请求头带有不可见字符\r,下图中的第10行实际上被PHP忽略了。




带有特殊符号【\r】的Content-Disposition头,被PHP忽略了。
具体解释如下:
1、若有2行,PHP取第1行。PHP在处理含有2行及以上Content-Disposition头的请求时,会取第1行。当然,是“符合标准”的第1行。
2、不过,如果第1行不符合标准,例如像图中那样带有\r这个特殊字符,PHP就会去判断下面1行的Content-Disposition头是否符合标准,直到找到“符合标准”的第1行为止。
3、在上图中,PHP先“看到”第10行的Content-Disposition头,不过由于其不符合标准,所以PHP只好取下面的第11行,结果第11行,我们给的是传POST参数的请求。所以,如果WAF没有考虑到这一点(例如:通过取第一行来确定Content-Disposition),就会识别成“文件上传请求”,从而放行该请求,造成绕过。
结论

攻击者构造的畸形请求(长得像“上传文件”的“表单”请求),被WAF当成了文件上传请求,但实际却是POST表单请求,从而实现攻击目的。示意图如下:



知其安安全研究院在PHP内置Web Server 中进行了测试,通过在不同位置、以不同方式构造畸形表单,最终整理出21种绕过WAF的攻击手法,作为【畸形表单绕过手法】自动化验证场景。
二畸形表单的兼容性测试

由于这些攻击手法主要基于PHP测试完成,这些请求虽然畸形,但PHP依然能“理解”——兼容PHP。但在其他web服务中(例如Java),是否也同样兼容呢?我们下面实际测试一下攻击手法在不同中间件下的“兼容性”,或者叫“有效性”。
有效性
一次有效的攻击,不但要绕过WAF,还要求后端接收到的参数值中,包含攻击参数
• 正面:构造HTTP畸形请求包,要能绕过WAF、到达后端服务器。
• 反面:虽然请求包是畸形的,但也要被后端服务器“理解”才行。
• 有效:概念上,类似于log4j 2 RCE漏洞,只要参数中含有攻击payload,即认为可以造成危害,是有效的攻击。
SpringBoot

在SpringBoot框架下进行了测试,源代码如下:




测试结果:21种绕过手法中,有 12 种攻击手法兼容SpringBoot,其余攻击手法无效。
Java Servlet





注意:Java servlet默认不识别multipart请求,需要配置@MultipartConfig( )注解才支持。结果:

  • 在默认配置情况下测试,在 21 种攻击手法中,原生支持的手法只有 1 种。
  • 不过,在开启@MultipartConfig( )注解后[5],支持的攻击手法增加到 9 种。
其它中间件(Flask、Express)

安全研究院又分别测试了Python的Flask、Node.js的Express框架。兼容性情况如下表所示:







结论
21 种攻击手法,在不同中间件下的兼容效果,在50%左右。
• 可以看到攻击手法1、2、3这三个攻击手法,在不同的中间件中,可以兼容测试的所有后端服务器。它们的细节如下:





• #1
该方法使用的是0x00截断filename方式绕过,在filename 之前加入了0x00,而有些WAF在检测前会删除HTTP 协议中的0x00,这样就导致了WAF认为是含有filename的普通上传,而后端PHP则认为是POST参数。




•#2
该方法使用的是双写上传Content-Disposition描述行方式绕过,有些WAF会只取第二行的上传描述进行判断,但是实际上后端PHP会获取第一行的上传描述。




• #3
该方法使用的是双写整个multipart/form-data开头部分方式绕过,有些WAF只会取第二个part进行判断,但是实际上后端PHP会获取第一个part。由于该方法会引入一些垃圾数据,在命令注入及SQL 注入的攻击场景,需要尽可能将前面的内容闭合。可见,攻击手法虽是在PHP环境中挖掘出来的,但放到不同的web业务环境下,也有不错的兼容效果。这些攻击手法,兼容性是不错。不过,实际绕WAF的效果如何呢?笔者也进行了测试。
实战WAF拦截测试

将这 21 种攻击手法,选取了若干款WAF进行测试,结果如下表所示:



截至发稿时,此类畸形表单的攻击手法,可以绕过目前市面上的许多WAF,绕过率为50%左右。
上述思路绕WAF的其它案例
我们可以回顾下以往绕过WAF的手法,其实很多都是利用这类WAF跟业务服务器之间的解析差异。可以看到,leveryd师傅,利用WAF解析引擎与后端Java在解码base64的过程中的小差异[3],绕过WAF利用Shiro-550漏洞。




图源:你的扫描器可以绕过防火墙么?(一)
我们也可以看到,y4tacker师傅,利用Tomcat在处理文件名时,为了遵循RFC 6266而实现的一些“古怪”特性,而研究出的绕过手法[4]。


图源:探寻Tomcat文件上传流量层面绕waf新姿势 | Y4tacker's Blog
本文所说的绕过手法,也是类似的思路。绕过的关键在于如何构造这种畸形请求。
总结
从攻击者角度看,利用HTTP解析multipart/form-data请求的差异(传文件 vs 传参数),可以在某些场景下绕过WAF,也支持多种中间件。从防御者角度看,解析引擎与业务服务器虽然总是有差异,但防御此类攻击,大部分情况下不需要复杂的运营配置。笔者总结了以下运营思路,可以较好地防御此类攻击:
1. 在 WAF(Web 应用防火墙)等设备中,开启对文件的检测,并设置合理的文件大小上限,从而避免解析异常或资源耗尽的攻击。以下数据可供参考:a. 默认情况下,Tomcat 的POST 数据大小限制为 2 MB,对文件大小没有做限制。b. 默认情况下,Spring Boot 单次上传的最大文件大小为 1 MB(1,048,576 字节),最大请求大小(包括所有文件和表单数据)为 10 MB(10,485,760 字节)。
2. 开启WAF等设备中“HTTP RFC规范”的相关规则,检测或拦截畸形HTTP请求
3. 定期更新业务服务器和 WAF 等安全设备,以修复已知的漏洞和提高安全性。
看得清失效点,才能放心扛住攻击。
目前,知其安离朱安全验证平台,已对 本文中提到的 21 种攻击手法上线了验证规则,支持自动化验证WAF/IPS/NTA/IDS的拦截检测能力。




参考链接(本文大量参考了do9gy师傅的文章,在此表示感谢)

http://www.moonslow.com/article/tencent_waf_bypa




回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-28 16:03 , Processed in 0.013433 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表