web基础漏洞-文件上传漏洞
1、介绍
文件上传漏洞,是因为在网站的文件上传业务中,未严格限制上传的类型,从而导致可访问、可执行的文件被上传到服务端,访问执行后造成危害。
- 根据上传文件的类型,可以分为静态文件或脚本语言文件。
- 静态文件主要包括.html,.js等,可以导致钓鱼、xss、csrf等漏洞。
- 脚本语言文件主要指jsp、php、asp和aspx。需要考虑目标服务器容器是否支持。
- 根据脚本语言的任务,可以分为预定任务和临时任务。
- 预定任务,访问激活上传的文件,直接执行预定义的任务,比如创建更隐蔽的木马,篡改配置,删除文件等等
- 临时任务,访问上传的文件时在请求中提交本次任务的代码,解析执行
- 根据上传与激活场景,可以分为一般场景、cms漏洞、服务器容器漏洞
- 一般场景,未进行严格的后端代码限制
- 基于默认的cms
- 服务器容器漏洞,又分为直接PUT和解析漏洞
注意:
- 文件上传提示成功,并且给出路径,但是访问时404,有可能是文件名称包括非ascii码,在上传后写入文件时导致文件名乱码。解决办法是尽量使用数字和字母定义文件名
- 如果上传的文件单纯是接收参数并eval解析执行,但是直接访问时未携带参数,此时响应可能为404
2、简单的检查和绕过
2.1 未进行防护
- 绕过1:直接上传木马文件
2.2 前端检查
一般是检查文件后缀名
- 绕过1:F12篡改前端代码
- 绕过2:python脚本直接文件上传
- 绕过3:将木马文件的后缀名改为合法值,比如.jpg。上传过程,burp拦截,将文件后缀名改回原值
2.3 服务端检查content-type
- 绕过1:上传木马文件,burp拦截篡改content-type类型为合法值
3、服务端检查文件后缀名
通过黑白名单检查,也是主流的方法。白名单方法的约束性更强,而黑名单总是会难以覆盖所有。
3.1 通用绕过
(1)大小写混杂
(2)双写绕过
如果是黑名单检测,并将匹配值删除,可以尝试双写绕过
- 即设置后缀名为.phphpp,检测后为.php
- 如果waf是n次检测,那么可以使用n+1双写
(3)逻辑漏洞
- 基于白名单时,可能存在逻辑漏洞,比如默认文件名都是只有一个.字符,但实际为a.jpg.php的形式
3.2 php相关绕过
(1)后缀名替代
- phtml、pht是早期的php+html的文件后缀名
- apache配置文件中会有.+.ph(p[345]?|t|tml)此类的正则表达式,文件名满足即可被当做php解析
- 绕过方式:修改木马文件后缀名为.php1、.php2、.php3、.php4、.php5、.phtml、.pht及其各自的大小写混杂
(2)%00截断
%00截断。这个漏洞利用的前提是php版本为5.3以下,且php.ini中magic_quotes_gpc=Off 默认是On
- magic_quotes_gpc类似addslashes()函数,是对转移字符过滤的。
- 原理:php是用C语言写的,C语言中字符串用\0表示结束,%00和\0在二进制中是字节00.因此在字符串之间插入\0或者%00,可以使字符串截断.
- 特征:
- 上传后文件名为:路径+带随机数的文件名+文件扩展名.有些路径是开发者为了省事通过GET请求传递的,我们可以进行修改.
- 假设正常情况下上传后文件全名为 /upload/test151236.jpg
- 通过修改GET请求传递的路径,变为 /upload/test.php%00,然后上传一个正常合法的图片,此时文件全名就变为 /upload/test.php%00test151236.jpg %00后面的字符被截断,因此文件全名就变为:/upload/test.php
3.3 windows机制
(1)文件名末尾
windows文件机制,对于文件名末尾,任意多的.字符和空格字符组合,会直接抹除
- 有些服务器代码先去掉文件末尾的点.,然后对文件名从右往左第一个点后面的内容(服务器认为是文件扩展名)进行黑名单检测.
- 绕过方式:将木马文件后缀名设置为.php.space. 类似值,通过waf和服务器代码检查,保存为文件时系统自动转为.php的后缀名
(2)data
如果后缀名没有对::$DATA进行判断,利用windows系统NTFS特征可以绕过上传
在windows的时候如果文件名+"::$DATA",会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA之前的文件名,其实和空格绕过点绕过类似
- 特征:服务器没有过滤::$DATA或过滤不完全.通常是用正则匹配过滤::$DATA,但是这样并不能完全过滤.
- 绕过方式:文件后缀改为.php$::DATA直接绕过php的黑名单。或者改为.php::$DAT::$DATAA绕过正则过滤的::$DATA
windows禁止:字符作为文件名
4、服务端检查文件魔数
读取文件内容,通过检查文件头进行判断,一般是前两字节判断文件的真实类型。或者通过文件加载检查,一般调用api或函数进行加载测试。
- 绕过1:对于文件头检测,在php文件中首行添加GIF98等表示文件类型的文本标志
- 绕过2:针对文件加载检查,制作图片木马绕过,将一段一句话木马以二进制的方式加载到一个正常的图片文件的最后。
copy 1.jpg/b +2.php/a 3.jpg
5、防护
(1)服务端检查,白名单严格限制文件名后缀,避免使用危险函数读取文件
(2)随机改写文件名,这适用于不会将上传后的文件供用户查看的情况
(3)根据文件内容改写文件扩展名,可以防御图片马以及可执行扩展名,对于无法解读的,命名为unknown
(4)上传目录设置为不可执行