文件上传漏洞
文件上传漏洞简介
文件上传漏洞出现在有上传功能的应用程序中。如果应用程序对用户的上传文件没有控制或者上传功能存在缺陷,攻击者可以利用应用程序的文件上传漏洞将木马,病毒等有危害的文件上传到服务器上面,控制服务器。
文件上传漏洞产生的主要原因是:应用程序中存在上传功能,但是对上传的文件没有经过严格的合法性检验或者检验函数存在缺陷,导致攻击者可以上传木马文件到服务器。
文件上传漏洞危害极大,这是因为利用文件上传漏洞可以直接将恶意代码上传到服务器上,可能会造成服务器的网页被篡改,网站被挂马,服务器被远程控制,被安装后门等严重的后果。
文件上传漏洞,字面意思可以利用WEB上传一些特定的文件。
一般情况下文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。文件上传本身是web中最为常见的一种功能需求,关键是文件上传之后服务器端的处理、解释文件的过程是否安全。
一般的情况有:
1、上传Web脚本语言,服务器的WEB容器解释开执用户上传的脚本,导致代码执行。
2、上传病毒、木马文件,攻击者用以诱骗用户或管理员下载执行。
3、上传.htaccess配置文件,以此来控制文件在该目录下解析的行为。
4、上传钓鱼图片或包含了脚本的图片,某些浏览器会作为脚本执行,实施钓鱼或欺诈。
如何判断文件上传漏洞
1、已知Web网站在登录前或者登录后具有上传页面。
2、上传的文件具备可执行性或能够影响服务器行为,所以文件所在的目录必须在WEB容器覆盖的路径之内。
3、用户可以从WEB上访问这个文件,从而使得WEB容器解释执行该文件。
4、上传后的文件必须经过安全检查,不会被格式化、压缩等处理改变其内容
MIME 类型
MIME 类型概述
媒体类型(通常称为Multipurpose Internet Mail Extensions或MIME类型)是一种标准,用来表示文档、文件或字节流的性质和格式。
通用结构:Type/subtype MIME的组成结构非常简单;由类型与子类型两个字符串中间用分隔而组成。不允许空格存在。type表示可以被分多个子类的独立类别。subtype表示细分后的每个类型。MIME类型对大小写不敏感,但是传统写法都是小写。
Mutipurpose Internet Mail Extensions,多用途 Internet 邮箱扩展。
MIME是一个描述消息内容类型的 internet 标准。
最早应用于电子邮件系统,后来也应用到浏览器。
MIME是描述消息内容类型的因特网标准。
MIME 消息能包含文本、图像、音频、视频以及其他应用。
Content-Type用于定义网络文件的类型和网页的编码,用来告诉文件接收方将以什么形式、什么编码读取这个文件。
MIME 类型常见分类
分类 | 描述 | 典型类型 |
---|---|---|
text | 表明是普通文本 | text/plain, text/html, text/css, text/javascript |
image | 表示是某种图像,不包括视频文件,但是包括动态图* | image/gif /image/png, image/jpeg, image/bmp, image/webp |
audio | 音频文件 | audio/midi, audio/mpeg, audio/webm, audio/ogg, audio/wav, |
video | 表示某种视频文件 | video/webm, video/ogg |
application | 表示某种二进制数据 | application/octet-stream,/pkcs12, application/vnd.mspowerpoint, application/xhtml+xml, application/xml, application/pdf,application/json |
后缀名黑白名单
黑名单:后端代码中明确不让上传的文件后缀名。
比如:asp、php、jsp、aspx、cgi、war等
白名单:后端代码中明确可以上传文件的类型
比如:jpg、png、zip、rar、gif····
常见文件头信息(十六进制)
文件头是位于文件开头的一段承担一定任务的数据,一般都在开头的部分。
常见文件的文件头:
JPEG (jpg), 文件头:FFD8FF
PNG (png), 文件头:89504E47 文件尾:0000000049454E44AE426082
GIF (gif), 文件头:47494638
ZIP Archive (zip), 文件头:504B0304 文件尾:00000000
XML (xml), 文件头:3C3F786D6C
HTML (html), 文件头:68746D6C3E
$_FILES函数代码审计
$_FILES['upfile']['name']; //客户端上传文件的原名称,不包含路径
$_FILES['upfile']['type']; //上传文件的MIME类型
$_FILES['upfile']['tmp_name']; //已上传文件在服务器端保存的临时文件名,包含路径
$_FILES['upfile']['error']; //上传文件出现的错误号,为一个整数
$_FILES['upfile']['size']; //已上传文件的大小,单位为字节
前端JS过滤绕过
前端JS过滤绕过上传漏洞是因为应用程序是在前端通过JS代码进行的验证,而不是在程序后端进行的验证,这样就可以通过修改前端JS代码的方式进行绕过上传过滤,上传木马。
①BurpSuite抓包绕过JS验证
JS的验证是在前端进行验证,将木马的后缀先改为jpg,这样就可以符合前端JS的验证,然后再通过抓包工具BurpSuite将发往服务器的数据包截包后,修改jpg后缀为php,因为后端没有验证这样就可以成功上传后缀为php的木马。
②修改前端JS上传木马
按F12打开开发者模式。或者查看页面元素,就可以看到对应的HTML源代码,找到form表单,在快捷菜单中选择“编辑HTML”命令修改JS代码,在类型中添加.php|,这样JS验证就运行了php后缀文件的上传。
文件名过滤绕过
①文件名大小写绕过
用像 AsP,pHp 之类的文件名绕过黑名单检测
②黑名单绕过
用黑名单里没有的名单进行攻击,比如黑名单里没有php3、php5、cdx、asa 或 cer 之类
③白名单绕过(文件扩展名检测)
白名单拥有比黑名单更好的的防御机制,如$WhiteList = array('rar','jpg','png','bmp','gif','jpg','doc');
在获取到文件扩展名后对$WhiteList数组里的扩展名迭代判断,如果文件扩展名被命中,程序将认为文件是合法的,否则不允许上传。
Content-Type过滤绕过
绕过原因分析:
不同的文件都会对应的不同的Content-Type,比如jpg文件的Content-Type为image/jpeg,php文件的Content-Type为application/octet-stream。Content-Type是在数据包的请求包头中,开发者会通过Content-Type的类型判断文件是否允许上传,但是Content-Type的类型可以通过抓包篡改,这样就可以通过抓包修改数据包的Content-Type来绕过Content-Type判断。
1、上传一个PHP文件
2、使用burpsuite拦截查看MIME类型
3、发现PHP文件的MIME类型为application/octet-stream
4、服务端会判断文件类型是否是image/gif
5、无法通过验证
6、需要将http请求中的Content-Type更改为image/gif类型
7、绕过上传
①MIME验证
文件头过滤绕过
不同的文件都有特定的文件头格式,开发者通过检查上传文件的文件头检测文件类型,但是这种检测方式同样可以被绕a,只要在木马文件的头部添加对应的文件头,这样既可以绕过检测又不影响木马文件的正常运行。
常见的文件头如下:
JPEG 0xFFD8FF
PNG 0x89504E470D0A1A0A
GIF 47 49 46 38 39 61 (GIF89a)
exif_imagetype() 读取一个图像的第一个字节并检查其签名,如果发现了恰当的签名则返回一个对应的常量,否则返回 FALSE。
①添加文件头
1、木马的头文件中添加图片文件的文件头即可绕过检测,木马的内容:
GIF89a<?php @eval($_REQUEST[123]);?>
②制作图片马
2、通过copy命令进行图片木马制作绕过检测
111.jpg是正常的图片文件,a.txt是木马的代码```
通过copy命令,“copy 111.jpg /b + a.txt /a test.php”,将两个文件合成到test.php木马文件中。
.htaccess文件上传
.htaccess文件上传是利用.htaccess文件可以对Web服务器配置的功能,实现对jpg、png等后缀的文件当做PHP文件解析的过程。
.htaccess文件(分布式配置文件)提供了一种基于每个目录进行配置更改的方法,包含一个或多个配置指令的文件放在特定的文档目录中,并且文件中的指令适用于该目录及其所有子目录。
.htaccess是Web服务器的一个配置文件,可以通过.htaccess文件实现Web服务器中的定义文件的解析方式、重定向等配置。
.htaccess文件作用是文件名包含zhss(不论文件后缀名)的都会以指定代码执行
①上传.htaccess文件
1)指定要上传的文件名+后缀:test.jpg
<Files test.jpg> ForceType application/x-httpd-php SetHandler application/x-httpd-php </Files>
2)指定要上传的文件后缀:
AddType application/x-httpd-php .jpg
3)只指定要上传的文件名(前缀):zhss
<FilesMatch "zhss"> SetHandler application/x-httpd-php </FilesMatch>
Windows系统特性绕过
①空格绕过
②.绕过
③::$DATA绕过
④点+空格+点
文件截断上传
①%00截断
截断的产生主要原因就是存在%00这个字符,PHP<5.3.4时,会把它当做结束符,导致后面的数据直接忽略,造成截断,上传时如果上传文件的路径可控,可以通过00截断,进行木马上传。
截取的数据包,把标记的内容修改成../upload/test.php%00。这样实际是将1.jpg的内容移动到test.php文件中了。
②%00截断之url编码截断
③%00截断之hex值截断
%00和0x00截断,原理都是一样的,都是利用16进制的00截断原理 。
Pass-11中对url进行解码。将%00解码成0x00,而Pass-12中没有url解码这一步,直接在hex的值中修改。形成0x00截断。
竞争条件文件上传
竞争条件是指多个线程在没有进行锁操作或者同步操作同时访问同一个共享代码、变量、文件等,运行的结果依赖于不同线程访问数据的顺序。
脏牛漏洞就是利用的Linux内核竞争条件进行的攻击,竞争条件同样在Web应用中也存在大量的漏洞场景,比如利用竞争条件进行木马文件上传。
$allow_ext = array("gif","png","jpg");
$filename = $_FILES['upfile']['name'];
move_uploaded_file($_FILES['upfile']['tmp_name'],"./up/".$filename);
$file = "./up/".$filename;
echo "文件上传成功: ".$file."\n<br />";
$ext = array_pop(explode(".",$_FILES['upfile']['name']));
if (!in_array($ext,$allow_ext)){
unlink($file);
die("此文件类型不允许上传已删除");
}
本段代码首先将用户上传的文件保存在up目录下,然后又判断了上传的文件的后缀是否在allow_ext中,如果不在通过unlink函数再去删除已经上传的文件。漏洞点在于文件在保存到服务器之前并没有进行合法性的检查,虽然保存后进行了文件的检查,但是通过竞争条件漏洞,通过上传有写文件功能的木马,在删除木马之前访问已经上传的木马,可以写入新的木马。
首先抓取两个数据包
第二个包进行无参爆破
成功
二次渲染绕过
文件上传漏洞修复
1.使用白名单限制文件上传的类型。
2.对上传文件进行随机重命名,并且文件的扩展名不允许用户自定义。
3.对文件上传的文件夹进行权限限制,去掉脚本的执行权限。
4.对文件的内容进行恶意代码的检测。