应用层WAF绕过

admin 2022年4月9日02:19:00评论29 views字数 2455阅读8分11秒阅读模式

应用层WAF绕过

一、引言

应用层WAF绕过
WAF (Web Application Firewall)即应用防火墙。主要是用于HTTP(S)协议的校验、拦截恶意(攻击)请求,放行正常的业务请求。WAF的类型分为三类:网络层、应用层、云WAF。 本次分享主要是研究应用层的WAF绕过,对于应用层的WAF是指WAF解析的是NGINX或者Apache处理过的HTTP数据包,也就是中间件初步处理后转发给WAF处理。要想绕过WAF的过滤,那么就得研究NGINX解析数据包与后端PHP或者其他语言解析的数据包有何不同。我们通过他们差异绕过这些WAF的过滤。

应用层WAF绕过



应用层WAF绕过

二、基本理论

应用层WAF绕过

2.1 form-data


multipart/form-data会将表单的数据处理为一条消息,以标签为单元,用分隔符分开。既上传键值对,也可以上传文件。当上传的字段是文件时,会有Content-Type来表名文件类型;content-disposition,用来说明字段的一些信息;由于有boundary隔离,所以multipart/form-data既可以上传文件,也可以上传键值对,它采用了键值对的方式,所以可以上传多个文件。

应用层WAF绕过


2.2 x-www- form-urlencoded


application/x-www-from-urlencoded,会将表单内的数据转换为键值对,&分隔。当form的action为get时,浏览器用x-www-form-urlencoded的编码方式,将表单数据编码为 (name1=value1&name2=value2…),然后把这个字符串append到url后面,用?分隔,跳转 到这个新的url。

应用层WAF绕过


应用层WAF绕过

三、实战绕过

应用层WAF绕过

3.1 文件上传绕过


我们以ngx_lua_waf源码来学习WAF是如何判断上传文件后缀。waf.lua 45-49 line.应用层WAF绕过

我们可以看到WAF是通过这么一个正则来匹配到文件后缀的,这个正则的缺陷在于如果我们在,Content-Disposition中引入垃圾数据,会导致正则匹配失败。但是在PHP这种引入垃圾数据的 Content-Disposition是可以解析成功的。这也是单一型Bypass绕过的常见技巧。

应用层WAF绕过


3.2 双写boundary绕过


WAF为了降低误报率并不会上传文件的内容进行过滤,那么我们能不能让WAF以为我们是在上传文件但是实际我们传输的是普通的POST数据包呢?答案是可以的,这是我们Bypass思想的核心所在。
例如靶机:gqleung/bypass_waf_1,我们双写了boundary,但是WAF会认为boundary=a才是真正的消息,而boundary=b仅仅是boundary=a的内容,但是PHP会根据 Content-Type中的boundary来确定是哪个boundary消息的。这样在上传文件包不被检查的时候可以导致POST包的过滤可以被Bypass。例如下面的HTTP数据包,真实的数据包就是b从而绕过WAF的拦截。如图所示:
 

应用层WAF绕过

 

应用层WAF绕过

3.3.造假boundary绕过


如果数据包中存在两个相同的boundary块头PHP则会以第一个boundary头为主,内容则以第二个boundary块为主。但是某些WAF会以第第二个为主,即便WAF所有boundary块都检查,如果第二个是上传包根据我们前面的前提(WAF为了降低业务误报率,不检查上传的内容)也可以绕过WAF的检查。我们再次以靶机:gqleung/bypass_waf_1靶机为例子构造如下数据包:

应用层WAF绕过

应用层WAF绕过

3.4 Content-Disposition引号闭合绕过


我们看到下面的数据包,第一个Content-Disposition: form-data; name='fla; filename="exp.fw",我们在name中删掉了一个引号,这样的话再PHP中解析就会闭合到最后一个引号。但是在WAF中仍然以为是上传文件。当然用双引号也是可以的,但是闭合会闭合到下一个双引号。
应用层WAF绕过
 

3.5 参数溢出绕过


我们使用的WAF是基于lua-nginx-module-0.10.9rc7 开发,该模块存在的问题是最大能够获取的参数数量是100个,也就是说该WAF最大的检查数量是100个参数,如果是101个参数那么地101个起不会检查直接放行。这就是所谓的最大参数溢出绕过。

应用层WAF绕过


以靶机gqleung/bypass_waf_3 为例,我们如果直接读取/etc/passwd会直接被WAF拦截,如果前面加一百个参数就可以绕过。

应用层WAF绕过


3.6 skip_upload


在PHP中存在一个叫skip_upload的变量来控制是否是上传。下面看一段PHP源码(php- 5.3.3/main/rfc1867.c line 991)从代码我们可以得知,只需要c小于0即可使得skip_upload=1,也就是跳过上传。在前面几个分支我们可以知道只要参数中存在]就会使得c--。

应用层WAF绕过

根据上面的理论分析,我们只需要构造两个Content-Disposition,其中一个是上传的,在他name中加入]符号让上传被忽略,另外Content-Disposition是正常的POST参数,这样我们在通过WAF时候WAF会认为我们的是上传文件而非POST数据,但是PHP中却跳过了上传最终导致了WAF的检查被绕过。

应用层WAF绕过


在PHP源码中 rfc1867.c line 909 可以看到如果skip_upload=1的情况有一种是Maximum number of allowable file uploads has been exceeded ,也就是上传的文档数量超过了最大允许范围就会跳过超过数量的上传。那么这个最大文档数量是多少呢?他是由php.ini中max_file_uploads决定的默认值就是20.也就是说我们的上传文档数量超过20就会被忽略。

应用层WAF绕过


我们同样以靶机gqleung/bypass_waf_3为例根据前面的理论分析我们构造上传包如下,第二十个我们可以使用正常的POST就可以收到参数。 

应用层WAF绕过


原文始发于微信公众号(山石网科安全技术研究院):应用层WAF绕过

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月9日02:19:00
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   应用层WAF绕过http://cn-sec.com/archives/889527.html

发表评论

匿名网友 填写信息