目录
1 相关基础知识
1.1 MIME类型检测概述
1.1.1 概述
定义:MIME(Multipurpose Internet Mail Extensions)多用于互联网邮件扩展类型,是描述消息内容类型的因特尔标准,也即文件类型。MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。
意义:MIME设计的最初目的是为了在发送电子邮件时附加多媒体数据,让邮件客户程序能根据其类型进行处理。然而当它被HTTP协议支持之后,它的意义就更为显著了。它使得HTTP传输的不仅是普通的文本,而变得丰富多彩。
1.1.2 文件格式
每个MIME类型由两部分组成,前面是数据的大类别,video、image、application、text、audio、multipart、message等,后面定义具体的种类。常见的MIME类型(通用型)如下表,更多类型请百度。
文件类型 | 后缀名 | MIME |
---|---|---|
超文本标记语言文本 | .html | text/html |
xml文档 | .xml | text/xml |
普通文本 | .txt | text/plain |
PDF文档 | application/pdf | |
Microsoft Word文件 | .word | application/msword |
PNG图像 | .png | image/png |
GIF图形 | .gif | image/gif |
JPEG图形 | .jpeg,.jpg | image/jpeg |
au声音文件 | .au | audio/basic |
MIDI音乐文件 | .mid, .midi | audio/midi, audio/x-midi |
RealAudio音乐文件 | .ra, .ram | audio/x-pn-realaudio |
MPEG文件 | .mpg,.mpeg | video/mpeg |
AVI文件 | .avi | video/x-msvideo |
GZIP文件 | .gz | application/x-gzip |
TAR文件 | .tar | application/x-tar |
1.1.3 检测与绕过
如果服务端代码是通过Content-Type的值来判断文件的类型,那么就存在被绕过的可能,因为Content-Type的值是通过客户端传递的,是可以任意修改的 。
1.2 后缀名检测概述
服务器端检测除了MIME检测外,还有文件后缀名检测,检测策略包括白名单策略域黑名单策略。
黑名单策略:不允许上传名单内的后缀名的文件。对于黑名单策略限制的服务器,一般先将待上传的文件在大类中修改后缀名,测试是否能成功执行代码,如果可以,待上传后便可直接执行无需借助其他漏洞,常见的同类后缀名如下表所示:
类型 | 常见后缀名 |
---|---|
php类 | .php .php2 .php3 .php5 .phtml |
asp类 | .asp .aspx .ascx .ashx .asa .cer |
jsp类 | .jsp .jspx |
白名单策略:由白名单策略只能允许上传名单内的后缀名。为了让文件能否成功上传,可能修改的后缀名将导致文件无法正常执行,常需要配合其他漏洞来执行所上传的文件。
文件解析顺序:在Apache的解析顺序中,是从右到左开始解析文件后缀的,如果最右侧的扩展名不可识别,就继续往左判断,直到遇到可以解析的文件后缀为止,所以如果上传的文件名类似 1.php.xxxx ,因为后缀xxxx不可以解析,所以向左解析后缀php。利用该规则可以绕过黑名单检测。
尝试将后缀名修改为php类的其他后缀,然后尝试用浏览器访问看看能否正常打开,不同类型的后缀文件的可执行性测试结果如下表:
后缀名 | 能否执行 |
---|---|
.php | 能 |
.Php | 能 |
.pHp | 能 |
.phP | 能 |
.php2 | 否 |
.php3 | 否 |
.php4 | 否 |
.php5 | 否 |
.phtml | 否 |
.php.xxxx | 否 |
1.3 文件内容检测概述
1.3.1 简介
服务器端检测除了MIME检测,文件后缀名检测外,为了保障安全性,服务器还需要对文件内容进行检测。
对于图片文件,PHP中有一个函数getimagesize(),这个函数本身检测图片大小,但是在检测之前还会判断目标文件是否是一张图片,因此,可以使用该函数来检测文件内容是否输出图片类型。
由于同一类型文件的头部内容也是一样的,服务器也常根据文件的头部内容进行判断。
1.3.2 图片马的制作方法
目的:让服务器对文件内容进行检测时,将文件判断为图片。
(1) 方法一:直接编辑
新建文件并命名为info.gif,文件内容如下。该文件在函数getimagesize()检测时,会被识别为gif图片,但是该文件无法直接在服务器端执行里面的代码,需要借助其他漏洞才能执行。
GIF89a
<?php
phpinfo();
?>
(2)方法二:合并文件
- 准备一张图片,例如此处文件名为upfile.png。
- 准备一个php一句话木马文件,比如此处文件名为phpinfo.php,内容为
<?php phpinfo(); ?>
。 - 合并文件。在windows系统下,运行cmd,先cd到图片与文件所在文件夹下再执行命令,输入命令
copy upfile.png/b+phpinfo.php/a muma.png
。需要注意的是需要先cd到两个文件所在的路径下执行命令。
- 以记事本方式打开生成的文件,可以看到里面包含着php代码语句。
(3) 方法三:利用十六进制编辑器
需要了解的是,各种图片的文件头部都是相同的,比如说所有的jpg图片的头部文件是一致的;不同格式的图片之间的头部文件是不同的,这个头部文件称为文件幻术。而函数getimagesize()无法识别文件幻术生成的文件。
常见的图片文件类型如下:
文件格式 | 头部 |
---|---|
.gif | 47 49 46 38 39 61 F1 00 2C 01 F7 00 00 64 32 33 |
.jpg | FF D8 FF E0 00 10 4A 46 69 46 00 01 01 01 01 2C |
.png | 89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 |
新建文件,命名为16.png,文件内容如下。注意,需要在16进制编辑器中将第一行转换为ASCII码。
89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52
<?php phpinfo(); ?>
2 实例操作环境及前期准备简介
2.1 操作环境
靶场:基于WAMP环境的upload-labs靶场,搭建过程可参考文章《【环境搭建-03】基于WAMP环境的upload-labs漏洞靶场的搭建》。
攻击机:kali虚拟机,自带BurpSuite软件。
靶场与攻击机处于同一个局域网下。
2.2 前期准备
准备好一个文件,该文件可能是木马,也可能是其他任意文件,本实验以php探针作为测试文件,来验证是否存在文件上传漏洞以及绕过漏洞检测的方法。
文件名为:phpinfo.php,文件内容:<?php phpinfo();?>。
3 MIME类型检测与绕过实例
(1)kali虚拟机打开BurpSuite,开启代理拦截功能.具体可参考《【Burp Suite工具-2】BurpSuite工作原理及菜单栏介绍》
(2)kali虚拟机上打开其火狐浏览器,输入网址http://172.16.1.1/upload-labs/
访问upload-labs,并点击进入第二关。点击浏览选择刚刚准备的探针文件phpinfo.php。
(3)在kali虚拟机上打开其火狐浏览器,并为浏览器设置代理。具体可参考《【Burp Suite工具-2】BurpSuite工作原理及菜单栏介绍》
(4)点击上传后出现错误提示。在页面点击上传按钮,之后在BurpSuite界面我们看到成功拦截到请求,点击forward,返回网页,看到出现提示”文件类型不正确,请重新上传“。
(5)查看源代码,判断是否存在JS检测。在52~56行,可以看到表单中有事件检测,但是没有找打对应的函数,应该是没有JS检测的。
(6)将请求拦截并发送到repeater模块。点击浏览选择刚刚准备的探针文件phpinfo.php,并点击上传。可以看到BurpSuite成功拦截到请求,这意味着浏览器端并没有检测文件后缀名。将拦截的请求,右键发送到repeater模块。
(7)在BurpSuite中的repeater模块,将http请求中的文件后缀名改为png或其他图片后缀名,点击send,可以看到响应中仍然出现错误提示。
(7)在BurpSuite中的repeater模块,将http请求中的Content-Type修改为image/png或其他MIME类型,点击send,可以看到响应中正常。
(8)在BurpSuite中的Proxy模块中按照上一步操作,将http请求中的Content-Type修改为image/png或其他MIME类型,点击forward,可以看到请求发送成功,并收到后端的响应显示如下,由于该文件不是真的图片,因此显示失败。
(9)鼠标右键上图中红框位置(本该是显示图片的位置),点击“新建标签页打开”,可以看到在新的页面成功执行该文件,并返回探针信息内容。如果是其他页面语句,也将成功执行。
4 文件后缀名检测与绕过实例
测试顺序:前端JS→MIME类型→文件后缀。因为修改后缀名可能会导致文件无法成功执行。具体操作步骤如下:
(1)kali虚拟机打开BurpSuite,开启代理拦截功能.具体可参考《【Burp Suite工具-2】BurpSuite工作原理及菜单栏介绍》
(2)kali虚拟机上打开其火狐浏览器,输入网址http://172.16.1.1/upload-labs/
访问upload-labs,并点击进入第三关。点击浏览选择准备的探针文件phpinfo.php。期间弹出的burpsuite拦截请求,均点击forward。
(3)点击上传后出现错误提示。在页面点击上传按钮,之后在BurpSuite界面我们看到成功拦截到请求,点击forward,返回网页,看到出现提示”不允许上传.asp,.aspx,.php,.jsp后缀文件! “。
(4)查看源代码,判断是否存在JS检测。可以看到表单中有事件检测,但是没有找打对应的函数,应该是没有JS检测的。
(5)将请求拦截并发送到repeater模块。点击浏览选择准备的探针文件phpinfo.php,并点击上传。可以看到BurpSuite成功拦截到请求。将拦截的请求,右键发送到repeater模块。
(6)在BurpSuite中的repeater模块,将http请求中的文件后缀名改为php2,点击send,可以看到文件上传成功。
(7)在BurpSuite中的Proxy模块中按照上一步操作,将http请求中的文件后缀名改为php2,点击forward,可以看到请求发送成功,并收到后端的响应显示如下,由于该文件不是真的图片,因此显示失败。
(8)右键该图片并点击新标签打开,显示如下,虽然该文件成功绕过后缀名检测,但是服务器未能成功执行该文件,估计是根据服务器设置支持的文件后缀名有关。
5 文件内容检测与绕过实例
测试顺序:前端JS→MIME类型→文件后缀→文件内容。因为这个还要修改文件内容,相关工作量较大。
(1)kali虚拟机打开BurpSuite,开启代理拦截功能.具体可参考《【Burp Suite工具-2】BurpSuite工作原理及菜单栏介绍》
(2)kali虚拟机上打开其火狐浏览器,输入网址http://172.16.1.1/upload-labs/
访问upload-labs,并点击进入第14关。点击浏览选择刚刚准备的探针文件phpinfo.php。期间弹出的burpsuite拦截请求,均点击forward。
(3)点击上传后出现错误提示。在页面点击上传按钮,之后在BurpSuite界面我们看到成功拦截到请求,点击forward,返回网页,看到出现提示”文件未知,上传失败“。
(4)查看源代码,判断是否存在JS检测。可以看到表单中没有事件检测。
(5)将请求拦截并发送到repeater模块。点击浏览选择刚刚准备的探针文件phpinfo.php,并点击上传。可以看到BurpSuite成功拦截到请求,这意味着浏览器端并没有检测文件后缀名。将拦截的请求,右键发送到repeater模块。
(6)在BurpSuite中的repeater模块,将http请求中的文件后缀名改为png或其他图片后缀名,点击send,可以看到响应中仍然出现错误提示。
(7)在BurpSuite中的repeater模块,将http请求中的Content-Type修改为image/png或其他MIME类型,点击send,可以看到仍然出现错误提示。
(8)此时怀疑,服务器会检测文件内容,选用1.3.2节中的方法一制作图片木马,名称为phpinfo.gif
,点击浏览选择图片木马phpinfo.gif
,并点击上传。期间弹出的burpsuite拦截请求,均点击forward。
(9)可以看到该文件直接上传成功,由于文件具体内容并非图片,因此此处无法正常显示图片内容。
(9)图片虽然上传成功,但是无法用网页去打开,需要配合以后学习的文件包含漏洞、服务器解析漏洞等,才能让该文件成功执行。现在先直接在服务器找打上传的图片马,以记事本打开,可以看到里面的恶意代码并没有被删除,说明文件成功上传。
注意:虽然服务器端无法运行文件中的代码(要执行需要配合服务器解析漏洞、文件包含漏洞等其他漏洞去实现,比如将该文件另存为php格式的文件等等),但是渗透测试报告中仍应记录该情况,存在任意文件上传漏洞。
6 总结
(1)理清绕过测试的顺序,先看前端JS检测能否绕过,再看服务器端检测能否绕过(MIME类型绕过→后缀名绕过→文件内容绕过。)
(2)掌握服务器端检测与绕过的方法(包含MIME类型、后缀名、文件内容)
(3)掌握图片马的制作方法;
(4)了解文件头部内容以及服务器检验文件内容与类型的方法;