文件上传漏洞详解
前言
刷完了upload-labs
对文件上传漏洞有了些许认识
在此做个小结与记录
1、文件上传漏洞概述
文件上传漏洞是指由于程序员未对上传的文件进行严格的验证和过滤,而导致的用户可以越过其本身权限向服务器上上传可执行的动态脚本文件。
这里上传的文件可以是木马,病毒,恶意脚本或者WebShell等。
这种攻击方式是最为直接和有效的,“文件上传”本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。
如果服务器的处理逻辑做的不够安全,则会导致严重的后果
2、一些基本概念
web容器
web容器是一种服务程序,在服务器一个端口就有一个提供相应服务的程序,而这个程序就是处理从客户端发出的请求,如tomcat、apache、nginx等等。(可以理解为给编程语言提供环境)
中间件:提供系统软件和应用软件之间连接的软件,以便于软件各部件之间的沟通。中间件处在操作系统和更高一级应用程序之间。
容器:给处于其中的应用程序组件(ASP,JSP,PHP)提供一个环境。使处于其中的应用程序组件之间跟容器中的环境变量接口交互,不必关注其他系统问题。
服务器:www服务器或http服务器。提供web信息游览服务。它只需支持http协议、html文档格式以及url,向游览器提供服务的程序。
IIS
IIS全称是互联网信息服务,包括FTP/FTPS、NNTP、HTTP/HTTPS、SMTP等服务。
.net Framework是基础类库,是程序运行的底层框架。
IIS是架设Web服务器用来提供网页游览服务的,属于系统环境。
一般用ASP.NET开发软件,然后靠IIS对公网提供服务。
文件解析
当服务器接收到一个HTTP请求的时候,IIS首先需要决定如何去处理这个请求(服务器处理.aspx和.html肯定是不一样的),根据的是文件的后缀名
服务器获取所请求的页面(也可以是文件)的后缀名后接下来会在服务器端寻找可以处理这类后缀名的应用程序,如果IIS找不到可以处理此类文件的应用程序,那么IIS将直接把这个文件返还给客户端
一句话木马
Asp一句话:
Php 一句话:
Aspx一句话:
配合菜刀或蚁剑使用,若是图片配合Edjpgcom
3、web容器解析漏洞
文件解析漏洞,是指Web容器(Apache、nginx、iis等)在解析文件时出现了漏洞,以其他格式执行出脚本格式的效果
Apache解析漏洞
1、多后缀
在Apache1.x,2.x中,Apache 解析文件的规则是从右到左开始判断解析,如果后缀名为不可识别文件解析,就再往左判断
因此可以上传一个test.php.qwea文件绕过验证且服务器依然会将其解析为php
注:Apache能够认识的文件在mime.types文件里
应对:后缀验证尽量使用白名单的方式,这样即使使用不存在的后缀名,也无法绕过
2、配置问题导致漏洞
如果在 Apache 的 conf 里有这样一行配置 AddHandler php5-script .php
这时只要文件名里包含.php 即使文件名是 test2.php.jpg 也会以 php 来执行。
如果在 Apache 的 conf 里有这样一行配置 AddType application/x-httpd-php .jpg
即使扩展名是 jpg,一样能以 php 方式执行
应对:apache配置文件,禁止.php.这样的文件执行
Order Allow,Deny Deny from all
3、罕见后缀
Apache配置文件中会有.+.ph(p[345]?|t|tml)此类的正则表达式
也就是说php3,php4,php5,pht,phtml这样的后缀也是可以被解析的
4、.htaccess文件
生效条件
Apache的配置文件中写上AllowOverride All
Apache要加载mod_Rewrite模块:LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so
.htaccess文件可以配置很多事情
如是否开启站点的图片缓存、自定义错误页面、自定义默认文档、设置WWW域名重定向、设置网页重定向、设置图片防盗链和访问权限控制
例1
AddType application/x-httpd-php xxx
就成功地使该.htaccess文件所在目录及其子目录中的后缀为.xxx的文件被Apache当做php文件
例2
SetHandler application/x-httpd-php
Apache把shell.jpg文件解析为php文件
Nginx解析漏洞
1、PHP CGI解析漏洞
Nginx默认是以CGI的方式支持PHP解析的,普遍的做法是在Nginx配置文件中通过正则匹配设置SCRIPT_FILENAME
当访问xx.com/phpinfo.jpg/1.php这个URL时,$fastcgi_script_name会被设置为phpinfo.jpg/1.php,然后构造成SCRIPT_FILENAME传递给PHP CGI
如果开启fix_pathinfo这个选项,就会触发在PHP中的如下逻辑:
PHP会认为SCRIPT_FILENAME是phpinfo.jpg,而1.php是PATH_INFO,所以就会将phpinfo.jpg作为PHP文件来解析
另一种
若PHP配置文件中cgi.fix_pathinfo默认是开启
上传test.jpg,内容如下
<?PHP fputs(fopen('shell.php','w'),'<?php eval($_POST[cmd])?>');?>
然后访问test.jpg/.php,在这个目录下就会生成一句话木马shell.php
2、空字节代码执行漏洞
旧版本(0.5.,**0.6.,0.7,0.8<=0.7.65<=0.8.37)
发出请求http://example.com/file.ext%00.php就会将file.ext作为PHP文件解析
Ngnix在遇到%00空字节时与后端FastCGI处理不一致
导致可以在图片中嵌入PHP代码然后通过访问xxx.jpg%00.php来执行其中的代码
应对:禁止在上传文件目录下执行php。
在nginx虚拟机配置或者fcgi.conf配置加如下代码
if ($request_filename ~* (.*)\.php) { set $php_url $1;}if (!-e $php_url.php) { return 403;}
IIS5.x-6.x解析漏洞
1、目录解析(6.0)
形式:www.xxx.com/xx.asp/xx.jpg
原理: 服务器默认会把.asp,.asa目录下的文件都解析成asp文件。
2、文件解析(6.0)
形式:www.xxx.com/xx.asp;.jpg
原理:服务器默认不解析;号后面的内容,因此xx.asp;.jpg便被解析成asp文件了
4、绕过上传校验
前端限制
当用户在客户端选择文件点击上传的时候,客户端还没有向服务器发送任何消息,就对本地文件进行检测来判断是否是可以上传的类型,这种方式称为前台脚本检测扩展名
绕过方法:
绕过前台脚本检测扩展名,就是将所要上传文件的扩展名更改为符合脚本检测规则的扩展名,通过BurpSuite工具,截取数据包,并将数据包中文件扩展名更改回原来的,达到绕过的目的
例如:文件名本来为evil.jpg,上传时,用BurpSuite截包后,将数据包中的名字改为evil.php(或其它脚本类型)即可
如果是JS脚本检测,在本地浏览器客户端禁用JS即可
可使用火狐浏览器的NoScript插件、IE中禁用掉JS等方式实现
服务器端检测
1、黑名单过滤
黑名单过滤是一种不安全的方式
黑名单定义了一系列不安全的扩展名
服务器端在接收文件后,与黑名单扩展名对比
如果发现文件扩展名与黑名单里的扩展名匹配,则认为文件不合法
绕过方法:
特殊后缀:php3,php4,php5,pht,phtml
.htaccess文件:见上面解析漏洞
.user.ini文件:auto_prepend_file=test.jpg,让所有php文件都“自动”包含test.jpg文件
后缀大小写:PHP、Php、pHp
双写后缀
1.php. .(点+空格+点)绕过
见下面系统相关
2、白名单过滤
白名单定义允许上传的扩展名,拥有比黑名单更好的防御机制
如:$WhiteList=array(rar',jpg',png,bmpy,gif,jpg;doc);
在获取到文件扩展名后对 WhiteList数组里的扩展名迭代判断,如果文件扩展名被命中,程序将认为文件是合法的,否则不允许上传
绕过方法:
主要是%00截断上传攻击,见下面
3、MIME验证
MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准
MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据
HTTP协议规定了上传资源的时候在Header中使用Content-Type 字段表示文件的MIME 类型
当具有该扩展名的文件被访问时,浏览器会自动使用指定的应用程序来打开
绕过方法:
使用各种各样的工具(如burpsuite)强行篡改Header就可以
将Content-Type: application/php改为其他web程序允许的类型
Content-Type: image/jpg
Content-Type: image/png
Content-Type: text/plain
4、目录验证
在文件上传时,程序通常允许用户将文件放到指定的目录中
然而有些Web开发人员为了让代码更“健壮”,通常会做一个操作
如果指定的目录存在,就将文件写入目录中,不存在则先建立目录,然后写入
5、%00截断上传攻击
在许多语言函数中,处理字符串的函数中0x00被认为是终止符
文件名后缀有一个%00字节,可以截断某些函数对文件名的判断
忽略后面上传的文件或图片,只上传截断前的文件或图片
条件:php 版本<5.3.4,php的magic_quotes_gpc为OFF状态
例
filename=test.php%00.txt
txt是合法上传,被截断,最终呈现的是test.php
使用场景:
上传时路径可控,使用00截断
文件下载时,00截断绕过白名单检查
文件包含时,00截断后面限制(主要是本地包含时)
其它与文件操作有关的地方都可能使用00截断
6、文件幻数检测
主要是检测文件内容开始处的文件幻数,比如图片类型的文件幻数如下