文件上传漏洞

文件上传漏洞

前言

文件上传漏洞可以说是⽇常渗透测试用得最多的⼀个漏洞,因为用它获得服务器权限最快最直接。但是想真正把这个漏洞利用好却不那么容易,其中有很多技巧,也有很多需要掌握的知识。俗话说,知⼰知彼⽅能百战不殆,因此想要研究怎么防护漏洞,就要了解怎么去利用。

特点

 利用简单
 危害大

产生原因

 缺少必要的校验

找文件上传点(关键)

 管理后台页⾯
 用户后台页⾯
 前台页⾯
 目录扫描 ==>扫描到后台不需要登陆就能访问的上传页⾯

测试思维和流程

测试思维

根据已有信息、条件分析目标⽹站架构,再以此架构为基础,从我们已经掌握的知识中过滤出适合此架构的攻击⽅法。

测试流程

思想指挥⾏动,那有了思想指导,我们就落实好久可以了。

  1. 分析目标架构
    ⽹站使用后端语言、中间件、目标服务器类型、版本等
  2. 根据分析结果使用已有⼿段依次测试。

突破 绕过 文件上传

前端验证的突破

如何探查是为前端验证

 右键查看源代码
 直接上传文件,如果⽹站⾮常快的弹出提示。

如何绕过前端验证

通过浏览器审查元素对⽹页的代码查看,找到对文件格式或⼤⼩的限制然后修改即可;
通过Burpsuite⼯具对浏览器进⾏代理,抓包对包里的内容进⾏修改。
浏览器禁用JavaScript脚本

什么是前端验证

通过JavaScript对上传操作的控制。如下:

<div id="upload_panel">
<ol>
<li>
<h3>任务</h3>
<p>上传⼀个<code>webshell</code>到服务器。</p>
</li>
<li>
<h3>上传区</h3>
<form enctype="multipart/form-data" method="post" onsubmit="return
checkFile()">
<p>请选择要上传的图⽚:<p>
<input class="input_file" type="file" name="upload_file"/>
<input class="button" type="submit" name="submit" value="上传"/>
</form>
<div id="msg">
</div>
<div id="img">
</div>
</li>
</ol>
</div>
</div>
<div id="footer">
<center>Copyright&nbsp;@&nbsp;<span id="copyright_time"></span>&nbsp;by&nbsp;<a
href="http://gv7.me" target="_bank">c0ny1</a></center>
</div>
<div class="mask"></div>
<div class="dialog">
<div class="dialog-title">提&nbsp;示<a href="javascript:void(0)" class="close"
title="关闭">关闭</a></div>
 <div class="dialog-content"></div>
</div>
</body>
<script type="text/javascript" src="/upload-labs/js/jquery.min.js"></script>
<script type="text/javascript" src="/upload-labs/js/prism.js"></script>
<script type="text/javascript" src="/upload-labs/js/prism-line-numbers.min.js"></script>
<script type="text/javascript" src="/upload-labs/js/prism-php.min.js"></script>
<script type="text/javascript" src="/upload-labs/js/index.js"></script>
</html>
<script type="text/javascript">
function checkFile() {
var file = document.getElementsByName('upload_file')[0].value;
if (file == null || file == "") {
alert("请选择要上传的文件!");
return false;
}
//定义允许上传的文件类型
var allow_ext = ".jpg|.png|.gif";
//提取上传文件的类型
var ext_name = file.substring(file.lastIndexOf("."));
//判断上传文件类型是否允许上传
if (allow_ext.indexOf(ext_name) == -1) {
var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:"
+ ext_name;
alert(errMsg);
return false;
}
}
</script>

文件内容检查的突破

测试流程

上传⼀张正常图⽚,验证上传功能是否正常
最好直接上传⼀张图⽚马,可绕过content-type,文件头,getimagesize(),php_exif检查 (先上传JPG文件(确保文件内容合法上传上去),且图片代码里有可执行的一句话木马,先保证上传成功,然后在考虑把后缀变为Php的问题(文件包含,解析漏洞等等),因为现在的网站上传做的好,他的一些规则进行禁用上传)
针对⼆次渲染,寻找图⽚数据中不会被转换的部分,将代码插⼊其中

content-type检查

绕过
使用burp suite抓包直接修改content-type值

什么是content-type检查

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']
['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '文件类型不正确,请重新上传!';
}
} else {
$msg = UPLOAD_PATH.'文件夹不存在,请⼿⼯创建!';
}
}
=

文件头检查绕过

在文件头部添加gif89a

gif89a
<?php
phpinfo();
?>

图⽚⼀句话
结合文件包含漏洞或者解析漏洞

getimagesize()检查和php_exif模块检查

校验头部
getimagesize()函数
示例

<?php
$remote_png_url = 'http://www.runoob.com/wp-content/themes/w3cschool.cc/assets/img/logo-
domain-green2.png';
$img_data = getimagesize($remote_png_url);
print_r($img_data );
?>

输出

Array
(
[0] => 290
[1] => 69
[2] => 3
[3] => width="290" height="69"
[bits] => 8
[mime] => image/png
)

解释

索引 0 给出的是图像宽度的像素值
索引 1 给出的是图像⾼度的像素值
索引 2 给出的是图像的类型,返回的是数字,其中1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 =
BMP,7 = TIFF(intel byte order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,11 =
JPX,12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM
索引 3 给出的是⼀个宽度和⾼度的字符串,可以直接用于 HTML 的 <image> 标签
索引 bits 给出的是图像的每种颜⾊的位数,⼆进制格式
索引 channels 给出的是图像的通道值,RGB 图像默认是 3
索引 mime 给出的是图像的 MIME 信息,此信息可以用来在 HTTP Content-type 头信息中发送正确的信息,如:
header("Content-type: image/jpeg");

绕过
在文件头部添加gif89a
图⽚⼀句话,结合解析漏洞或文件包含漏洞

image create from jpeg⼆次渲染

⼆次渲染:就是根据用户上传的图⽚,新生成⼀个图⽚,将原始图⽚删除,将新图⽚添加到数据库中。⽐如⼀些⽹站根据用户上传的头像生成⼤中⼩不同尺⼨的图像。
绕过
寻找渲染前后不变的地⽅,替换成⼀句话

白名单验证的突破

修改MIME类型绕过白名单限制(Content-type验证)

 MIME(Multipurpose Internet Mail Extensions)多用途互联⽹邮件扩展类型。是设定某种扩展名的文件用⼀种应用程序来打开的⽅式类型,当该扩展名文件被访问的时候,浏览器会⾃动使用指定应用程序来打开。多用于指定⼀些客户端⾃定义的文件名,以及⼀些媒体文件打开⽅式。

id 后缀名 MIME
0 gif image/gif
1 jpg image/jpeg
2 png image/png
3 bmp image/bmp
4 psd application/octet-stream
5 ico image/x-icon
6 rar application/octet-stream
7 zip application/zip
8 7z application/octet-stream
9 exe application/octet-stream
10 avi video/avi
11 rmvb application/vnd.rn-realmedia-vbr
12 3gp application/octet-stream
13 flv application/octet-stream
14 mp3 audio/mpeg
15 wav audio/wav
16 krc application/octet-stream
17 lrc application/octet-stream
18 txt text/plain
19 doc application/msword
20 xls application/vnd.ms-excel
21 ppt application/vnd.ms-powerpoint
22 pdf application/pdf
23 chm application/octet-stream
24 mdb application/msaccess
25 sql application/octet-stream
26 con application/octet-stream
27 log text/plain
28 dat application/octet-stream
29 ini application/octet-stream
30 php application/octet-stream
31 html text/html
32 ttf application/octet-stream
33 fon application/octet-stream
34 js application/x-javascript
35 xml text/xml
36 dll application/octet-stream
37 dll application/octet-stream

00截断绕过白名单限制

条件
 php版本⼩于5.3.4 详情关注CVE-2006-7243
 php的magic_quotes_gpc为OFF状态
能够进⾏截断的点 :所有跟 路径和文件命名的地方,都可以去测试尝试
GET和POST请求进⾏截断时的区别
post不会像get对%00进⾏解码,所以需要在⼗六进制中⼿动修改。

解析漏洞绕过白名单限制

双重拓展名

 apache 文件名解析时,是从后⾯开始检查后缀,按最后⼀个合法后缀执⾏。如: shell.php.xxx 因为 xxx 不被apache解析,所以apache会跳过 .xxx ,⽽解析最后⼀个后缀名,即.php,从⽽把这个文件当php文件解析了

iis解析漏洞
iis6.0

*.asp;1.jpg

iis7.0/7.5/Nginx<8.03
 php.ini里默认cgi.fix_pathinfo=1,对其进⾏访问的时候,在URL路径后添加.php后缀名会当做php文件进⾏解析,漏洞由此产生。
上传1.jpg,访问http://www.xxx.com/1.jpg/.php,此时1.JPG会被当做PHP脚本文件来解析。

⼤⼩写

黑名单验证的突破

操作系统特性

 windows操作系统对⼤⼩写不敏感,即php和Php在windows看来是⼀样的
 Windows系统下,如果上传的文件名中test.php::$DATA会在服务器上生成⼀个test.php的文件,其中内容和所上传文件内容相同,并被解析。即上传文件xxx.php::$DATA = xxx.php
 Windows下文件名结尾加⼊.,空格,<,·>,>>>,0x81-0xff等字符,会被windows⾃动去除

语言特性

语言 可解析后缀
php php,php5,php4,php3,php2,pHp,pHp5,pHp4,pHp3,pHp2,html,htm,phtml,pht,Html,Htm,pHtml
jsp jsp,jspa,jspx,jsw,jsv,jspf,jtml,jSp,jSpx,jSpa,jSw,jSv,jSpf,jHtml
asp/aspx asp,aspx,asa,asax,ascx,ashx,asmx,cer,aSp,aSpx,aSa,aSax,aScx,aShx,aSmx,cEr

中间件特性

  • 解析漏洞
    iis6.0,iis7.0/7.5,iis8.0/10.0
    apache

  • .htaccess

代码不严谨

 双写绕过 (只做了一次的校验删除) 1.ASaspp -> 1.ASp
 对于空格,点只做了单次过滤 (只做了一次的校验删除) 1.php. . -> 1.php.

测试思路

 使用字典+burp,去fuzz后缀名寻找成功上传的思路
 ⼿⼯测试

https://gv7.me/articles/2018/make-upload-vul-fuzz-dic/

上传点要么验证做的很好,要么很垃圾,我们没必要盯着一个大的网站的站点去找上传漏洞,可以通过信息收集,去找它一个犄角旮旯地方的上传点,上传绕过机率高..

解析漏洞

如何探查目标是什么类型的web服务器

通过查看相应的http请求,会在头部暴露出web服务器类型

安装浏览器插件

通过第三⽅⽹站

解析漏洞详解

IIS

IIS5.X~6.0

  • 目录解析漏洞
    服务器默认会把.asp,.asa目录下的文件都解析成asp文件。前提是可以控制文件上传的路径或者是文件名
xxx.asp/xxx.jpg
  • 文件命解析漏洞
    服务器默认不会取解析分号后⾯的内容。前提是可以控制文件名。
xx.asp;.jpg
  • 畸形文件命解析漏洞
    iis6.0下的可执⾏文件还有 asa、cer、cdx ,注意,不⼀定能解析aspx,因为aspx是.net环境。

IIS7.0/7.5

  • 利用解析图⽚中的代码上传webshell
    如果开启Fast-CGI模式,上传1.jpg,内容如下:
<?PHP fputs(fopen('dark5.php','w'),'<?php eval($_POST[cmd])?>');?>

访问 1.jpg/.php ,那么1.jpg就会被解析执⾏。

  • fck+iis7.5
    a.aspx.a.aspx.jpg..jpg

Apache

不可识别解析后缀

  • Apache的文件解析过程是从右到左开始判断解析,如果为不可识别的后缀解析,就再往左判断。
  • 在Apache的解析中,除了“php|php3|phtml”等规定的后缀中,任何的后缀加⼊,都是不会被识别解析的,也会被跳过后缀处理。
    dark5.php.k1.w2.a3 -> dark5.php

.htaccess

  • htaccess文件是Apache服务器中的⼀个配置文件,它负责相关目录下的⽹页配置。通过htaccess文件,可以帮我们实现:⽹页301重定向、⾃定义404错误页⾯、改变文件扩展名、允许/阻⽌特定的用户或者目录的访问、禁⽌目录列表、配置默认文档等功能。
  • 该漏洞适用于目标web服务器为apache,并且.htaccess可以被上传执⾏的情况。
  • 当.htaccess文件内容为SetHandler application/x-httpd-php时,即设置当前目录所有文件都使用PHP解析,那么⽆论上传任何文件,只要文件内容符合PHP语言代码规范,就会被当作PHP执⾏。不符合则报错。
  • 在Apache中如果需要启动 .htaccess,必须在http.conf中设置 AllowOverride 为All
<FilesMatch "1.jpg"> SetHandler application/x-httpd-php </FilesMatch>

Nginx

CGI 和上面IIS7.0/7.5 一样
空字节代码执⾏

dark5.jpg%00.php //类似00截断

双文件上传和竞争上传

双文件上传

应用场景

  • 南⽅/良精CMS
  • 正则默认匹配第⼀个filename的情况下

利用原理
  服务端默认取第⼆个文件作为真正的上传文件,但是在检测时只检测了第⼀个文件。或者只验证了第⼀个filename
的拓展名。
利用⽅法

  • 直接在审查元素中添加⼀个上传表单 (在原上传表单下添加一个上传表单)
  • burp抓包之后在数据包中添加 (复制多一份原表单的数据并更改为php上传)

竞争上传

应用场景
  访问webshell的时候,短时间内可以访问到,再次访问就访问不到了
利用原理
  代码逻辑为:先将文件上传到服务器,然后检测后缀名,如果不符合再通过unlink删除文件,因此可以通过条件竞争的⽅式在unlink之前,访问webshell。
利用⽅法
  使用burp suite不停的上传,同时用python脚本不停的访问上传的文件。

<?php fputs(fopen("./info.php", "w"), '<?php @eval($_POST["drops"]) ?>'); ?> // 不断的访问上传的文件
posted @ 2020-11-29 18:16  Black-Sweater  阅读(186)  评论(0编辑  收藏  举报