什么是文件上传漏洞?
文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。上传是正常的业务需求,网站必备功能。
在大多数情况下,文件上传漏洞一般都是指“上传Web脚本能够被服务器解析”的问题,也就是通常所说的webshell的问题。要完成这个攻击,要满足如下几个条件:
- 首先,上传的文件能够被Web容器解释执行。所以文件上传后所在的目录要是Web容器所覆盖到的路径。
- 其次,用户能够从Web上访问这个文件。如果文件上传了,但用户无法通过Web访问,或者无法使得Web容器解释这个脚本,那么也不能称之为漏洞。
- 最后,用户上传的文件若被安全检查、格式化、图片压缩等功能改变了内容,则也可能导致攻击不成功。
1 上传校验与绕过
程序员在防止上传漏洞时可以分为以下两种。
客户端检测:客户端使用JavaScript检测,在文件未上传时,在前端就对文件进行验证:
服务器端检测:服务端脚本一般会检测文件的MIME类型,检测文件扩展名是否合法,甚至有些程序员检测文件中是否嵌入恶意代码。
前端检查比较简单,现在使用的比较少。
1.1 文件检查方法
- 图片头校验:JPEG ==>FF D8 FF E0、PNG==>89 50 4E 47 0D 0A 1A 0A
- 文件类型校验(Content-Type验证):HTTP头中的content/type,互联网媒体类型,也叫做MIME类型。
- 文件后缀校验: .jpeg .txt .png
- 文件大小校验(CONTENT-LENGTH验证)。
- 上传的目录路径
过滤方式有黑名单和白名单两种,黑名单就是将禁止的文件类型列出来,白名单将允许的文件类型列出来,所以白名单过滤更好一些。
1.2 文件头校验绕过
方法1:
先建立一个a.txt文件,内容为
gif89a
<?php @eval($_POST['LSJ']);?>
改为.jpg ,变成一个伪图片
方法2:
找到一个真正图片,用C32或010Editor工具打开,在文件末尾加上脚本<?php @eval($_POST['LSJ']);?>。
方法3
使用DOS下的copy命令,copy 原始图片.jpg /b + 脚本.txt /a 合成.jpg,将图片与txt合成。
1.3 文件后缀校验绕过
方法1:
伪造一个图片木马,后缀为.jpg的木马。
将图片上传,成功绕过防御,然后再使用文件包含功能使图片中的内容当成PHP代码执行。
注意:如果上传的后保存的是图片后缀,PHP解释器是不会把他当成动态文件执行的,必须借助包含漏洞包含一下。
方法2:
借助其他条件,如%00截断,解析漏洞,富文本编辑器缺陷等。(在下文介绍)
1.4 文件类型校验绕过
在后端常用$_FILES全局数组获取上传文件的信息。
文件的类型在http头文件里是Content-Type,也就是MIME类型。它用来设定某种扩展名文件的打开方式,当具有该扩展名的文件被访问时,浏览器会自动使用指定的应用程序来打开。
HTML文档标记: text/html;
普通ASCII文档标记: text/html;
JPEG图片标记: image/jpeg;
GIF图片标记: image/gif;
js文档标记: application/javascript;
xml文件标记: application/xml;
较全的网址
https://www.runoob.com/http/http-content-type.html
方法1:
直接创建含有脚本的.php文件,
使用Burpsuit抓包,直接修改Content-Type类型伪文件类型,即将下图中的高亮区域改为image/png或其他图片的类型。
方法2:
改content-type,上传一个真正的含脚本a.jpg
抓包转到repeater里进行去改包:
把image/jpeg改为text/asp
把原本图片内容改成一句话木马
借助其他的条件:
%00截断,解析漏洞,富文本编辑器缺陷
1.5 文件大小校验绕过
Content-Length验证是指服务器会对上传的文件内容长度进行检查,超出限制大小的文件将不允许被上传。
针对这种类型的验证,我们可以通过上传一些非常短的恶意代码来绕过。上传文件的大小取决于,Web服务器上的最大长度限制。我们可以使用不同大小的文件来fuzzing上传程序,从而计算出它的限制范围。
2 辅助上传漏洞
2.1 00截断
截断上传攻击在ASP程序中最常见,下面看一段简单的ASP代码。
username = request ("username");
Response.write(username);
这两向代码非常简单,接收username值并输出,访问URL:?username=xxser%00admin,结果只输出了“xxser”。这就是截断的原型。
因为在许多语言的函数中,比如在C、PHP等语言的常用字符串处理函数中,0x00 被认为是终止符。注意PHP有版本限制,小于5.3.4。
利用:
上传一个a.php.jpg,burp抓包改包:
1.改filename为:a.php .jpg,(php后加个空格,然后去Hex里找到filename,在左面,把空格(20)改为00)
2.或者是直接改为a.php%00jpg,选中%00右击,去convertselection-URL-url-decode
2.2 解析漏洞
常见的Web容器有IIS、Nginx、Apache、 Tomcat等。
1. iis 6.0解析漏洞
IIS≤6.0在解析文件时存在以下解析漏洞。
(1)目录解析 /xx.asp/xx.jpg
当建立*.asa、*.asp、*.cer、*.cdx格式的文件夹时,其目录下的任意文件都将被IIS当作asp文件来解析。
例如:建立文件夹parsing.asp,在parsing.asp文件夹内新建一个文本文档 test.txt,其内容为<%=NOW()%>,然后在浏览器内访问。“NOW()”是ASP提供获取当前时间的函数,TXT是文本文档格式,IIS 是不会去解析此类文件的,应该会直接显示其内容,而在parsing.asp文件夹中,却被当作ASP脚本来解析。
(2)文件解析 xx.asp;.jpg
当文件为*.asp;1jpg时,IIS 6.0分号后面的不被解析,同样会以ASP脚本来执行,如:新建文件test.asp;1.jpg,内容为<%=NOW()%>
2. Apache解析漏洞
(1)文件解析
Apache (1*,2*)在解析文件时有一个原则:当碰到不认识的扩展名时,将会从后向前(从右向左)解析,直到碰到认识的扩展名为止,如果都不认识,则会暴露其源代码。
如: manage .php.rar.xs.aa 解析为php文件
(2).htaccess文件解析
.htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过.htaccess文件,可以实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
该文件默认开启,启用和关闭在 httpd.conf 文件中配置,.htaccess 文件生效的前提条件为:
· mod_rewrite 模块开启
· AllowOverride All
利用:
如果Apache中.htaccess可被执行并可被上传,那么可以尝试在.htaccess中写入:
<FilesMatch "shell.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
然后再上传shell.jpg的木马,这样shell.jpg就可被解析为PHP文件了。
3. Nginx 畸形解析漏洞
Nginx是一款高性能的Web服务器,通常用来作为PHP的解析容器。
访问http://www.xxser.com/1.jpg/1.php,此时的1jpg会被当作PHP脚本来执行,此时的1.php 是不存在的,1.ipg却已经按照PHP脚本来解析了。
这不是Nginx特有的漏洞,在IIS 7.0、JIS 7.5、Lighttpd等Web容器中也会出现这样的解析漏洞。(这种解析漏洞其实是PHP CGI的漏洞。在PHP的配置文件中有一个关键的选项: cgifi: x pathinfo。这个选项在某些版本中默认是开启的,在开启时访问URL,当不存在时PHP将会向前递归解析。)
(1)在默认Fast-CGI开启状况下上传名字为xx.jpg,内容为:
<?PHP fputs(fopen('shell.php','w'),'<?php eval($_POST[cmd])?>');?>
然后访问xx.jpg/.php,在这个目录下就会生成一句话木马shell.php。
(2)另一种Nginx文件漏洞是从左到右进行解析
既可绕过对后缀名的限制,又可上传木马文件,因此可以上传XXX.jpg.php
(3)Nginx≤0.8时
Ngnix在遇到%00空字节时与后端FastCGI处理不一致,导致可以在图片中嵌入PHP代码然后通过访问xxx.jpg%00.php来执行其中的代码.
4. 操作系统文件命令规则
(1)上传不符合windows文件命名规则的文件名
test.asp.
test.asp(空格)
test.php:1.jpg
test.php:: $DATA
会被windows系统自动去掉不符合规则符号后面的内容。
2.3 富文本编辑器缺陷
富文本编辑器,使用此类编辑器减少了程序开发的时间,但是却增加了许多安全隐患。
https://navisec.it/%e7%bc%96%e8%be%91%e5%99%a8%e6%bc%8f%e6%b4%9e%e6%89%8b%e5%86%8c/
3 WAF绕过
现在都是waf比较流行,过waf比较可以,比如某盾,某狗,某X。重点在于抓包,修改header里的部分内容,绕过正则范围,如Content-Disposition,Content-Type。
Content-Disposition: form-data; name="file_1"; filename="11.php"
1)filename与name
去掉引号
双引号变成单引号
大小写
空格
换行
交换name和filename的顺序
多个filename
多个分号
name和filename添加任意字符串
2)form-data
删
改
3)conteant_type本身
。。。
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryj1oRYFW91eaj8Ex2
补充:multipart/form-data请求,enctype规定了form表单在发送到服务器时候编码方式,它有如下的三个值。
①application/x-www-form-urlencoded:默认的编码方式。
②multipart/form-data:指定传输数据为二进制类型,比如图片、mp3、文件。
③text/plain:纯文体的传输。空格转换为 “+” 加号,但不对特殊字符编码。
1)boundary可以修改
比如,myboundary,BouNdaRy,等等
2)multipart/form-data大小写变化
3) boundary与multipart/form-data的组合可以考虑改一下
安全学习交流群:687398569