文件上传——WAF绕过及修复
文件上传——WAF绕过及修复
0.前言
在进行学习之前,我们需要了解在上传数据包的4个参数:
- Content-Disposition:一般可以更改
- name:表单参数值,不能更改
- filename:文件名,可以更改
- Content-Type:文件MIME,视情况更改

以安全狗为例,在安全狗中是有着对应的文件检测功能


可以看到,在这个过程中,由于安全狗开启了php的防护功能,所以我们无法上传成功php脚本。常规绕过思路来讲,就是让WAF无法检测出是php或者使用非php语言的脚本(jsp等)。
1.绕过方法——数据溢出(防止匹配xxx.后缀)
数据溢出的原理就是提供大量的数据;当数据特别多的时候,程序会有崩溃或者截止的办法,从而达到防止匹配的目的,比如我们一直增加文件名的数据



可以看到,当我们的垃圾数据足够多的时候,会导致后台的服务平台崩溃,这是一种办法,当然尽管崩溃了,我们依旧没办法成功上传php文件,这个位置显然不行,所以我们尝试另外的位置。


这种是绕过了WAF,并且也显示提交了,但是后台查看并没有上传的php文件的,后面在演示的过程中,在垃圾数据中加入了;,也就有了文件,这里需要注意


2.绕过方法——符号变异(防止匹配’”;)
首先分析数据包的有效符号

要知道,在数据包中;代表语句结束,而我们可以看到在filename后面是没有;号的,我们可以尝试写个;上去并插入内容

显然没有成功,在注入中很多函数和符号存在等价替换,所以我们尝试使用单引号代替双引号。或者去掉一个双引号取消掉闭合影响他判断,这样子就有三中情况,第一种识别为”qq名字的php,第二种是无法匹配到,为没有最后一个”的闭合就直接放行了,第三种是直接扔掉



可以看到,我们最终绕过了安全狗成功上传了php文件,也就是说明安全狗匹配的是单引号和双引号之间的内容,是上面讲到的第二种:无法匹配到,为没有最后一个”的闭合,就直接放行了,所以成功了。再尝试把两个引号都去掉也是可以成功的。但当我们去掉前面的;,上传缺又失败了,所以最终得出安全狗的;号匹配是匹配最后的一个;。
3.绕过方法——数据截断(%00 ; 换行)
数据截断的原理和上一篇讲的内容差不多,也就是在上传的文件名字后加入相应的符号标识,对文件名数据进行截断从而绕过匹配

上传后还是被截断了,因为存在php的文件内容数据,所以还是被识别出来了,现在我们尝试使用;.进行操作。;代表一个语句的结束,所以当我们输入;后,安全狗只会匹配到;之前的内容,所以能绕过成功

还有换行技巧,当我们换行后,在安全狗中识别的内容是p\nh\np,显然在识别中使用了\n进行了验证的干扰,最后上传成功

这个版本的安全狗中,斜杆也能当做一种截断

4.绕过方法——重复数据(参数多次)
顾名思义就是使用多个参数,首先我们创建两个参数,试探一下WAF以哪一个为准,检测哪一个


明显可以看到上传的是y.jpg文件,最终上传检测的是最后的文件名为准。我们就尝试将后面的文件名字改为php文件名,前多加许多的文件名参数,试探WAF是全部检测,还是存在检测上限

可以看见还是被拦截了,那就有两种可能, 一种是参数不够多,没有,一种是对面能够完全匹配所有参数,所以尝试加大参数的数量

可以看见,当我们加大参数数据量时,最终绕过了安全狗,成功上传了php文件,也就是说该版本的安全狗并不是全部匹配,而是存在了一定的匹配次数,还有一种参数加入就是借用白名单的机制,当我们吧前面的数据复制到filename的引号中,当后台接收到内容时间,内容上的前部分会被忽略不计,安全狗就会误认为是正常数据就直接通过检测(说实话这里我没搞懂,可能是WAF部件的检测原理层面)

5.WAF绕过总结
总的来说研究就是不断的测试,测试有一个先后的测试顺序,要明白哪些数据能够修改,哪些部分不能改动。把WAF的构造和匹配机制了解清楚,其实是能够有方法去进行漏洞查找的。
这里小迪视频中提供了两个比较好的测试Fuzz字典
使用fuzz测试举例



6.文件上传的安全修复方案
后端验证:采用服务端验证模式,然后采用以下内容的相关检测
- 后缀验证:基于黑名单,白名单过滤
- MIME检测:基于上传自带类型检测
- 内容检测:文件头,完整性验证
自带函数过滤
- 自带函数过滤:参考uploadlabs函数——getimage(该函数只能是图片)
- 自定义函数过滤:function check_file(){}
- WAF防护产品:宝塔,云盾,安全公司产品等