文件上传漏洞

原理

文件上传漏洞是WEB安全中经常利用到的一种漏洞形式。这种类型的攻击从大的类型上来说是攻击“数据与代码分离原则”的一种攻击。
在文件上传功能处,若服务端脚本语言未对上传的文件进行严格验证和过滤,导致恶意用户上传恶意的脚本文件时就有可能获取执行服务端命令的能力,这就是文件上传漏洞

前端表单

1
2
3
4
5
6
7
8
9
<html>
<body>
<form action="upload_file.php" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" /><br>
<input type="submit" name="submit" value="submit" />
</form>
</body>
</html>

其中upload_file.php规定了处理上传数据的后台php脚本文件
method规定上传的方法为post方法
enctype规定了上传数据的编码方式
multipart/form-data表示不进行编码,文件上传的表单一般采用此方式


后端处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
if ($_FILES["file"]["error"]) {
echo "Error:".$_FILES["file"]["error"]."<br />";
}else {
echo "Upload:".$_FILES["file"]["name"]."<br />";
echo "Type:".$_FILES["file"]["type"]."<br />";
echo "Size:".($_FILES["file"]["size"]/1024)."Kb<br />";
echo "Stored in:".$_FILES["file"]["tmp_name"]."<br />";
}

if(file_exists("upload/".$_FILES["file"]["name"])) {
echo $_FILES["file"]["name"]." already exists.";
} else {
move_uploaded_file($_FILES["file"]["tmp_name"], "upload/".$_FILES["file"]["name"]);
echo "Stored in: "."upload/".$_FILES["file"]["name"];
}
?>

服务器拿到上传的文件数据后,会先将其存为一个临时文件,由$_FILES这个全局变量调取使用

$_FILES里有很多文件对应的属性
type:文件类型
name:文件名
size:文件大小
tmp_name:临时文件的存储位置
通过对这些属性进行判断与限制,可控制文件上传的类别、大小等


检测方式

常见的对上传文件的检测方式

  • 任意上传
  • js验证
  • 文件扩展名检测
  • MIME-type加测
  • 文件头检测(x504B:压缩包;文本文件文件头就是本身)
  • 文件加载检测

漏洞

常见类型

  • 任意文件上传:没有任何校验
  • 绕过js校验上传:校验发生在前端
  • 绕过后端校验上传:校验发生在后端

    • 绕过文件类型校验
    • 绕过扩展名校验
    • 绕过文件头校验
  • 结合解析漏洞上传:中间件解析漏洞造成

  • 其它类型

解析漏洞

IIS6.0

  • 目录解析
    漏洞原理:
    服务器默认会把xx.asp目录下的文件都解析成asp文件

漏洞形式:

1
www.xxx.com/xx.asp/xx.jpg

  • 文件解析
    漏洞原理:服务器默认不解析;后面的内容,因此xx.asp;.jpg便被解析成asp文件了

Apache 1.x 2.x

实验环境:wamp2.0
漏洞原理:Apache解析文件的规则为从右到左开始判断解析,若后缀名为不可识别文件解析,则再往左判断
例如:test.php.a.b.a.b,此两种后缀是Apache不可识别解析,Apache将会把test.php.a.b解析成test.php

漏洞形式:

1
www.test.com/test.php.a

其余配置问题:

  1. 若Apache的conf里有如下配置,则文件名里只要包含.php,即使文件名形如:test2.php.jpg,依旧会以PHP文件来执行
    1
    AddHandler php5-script.php

Nginx 1.4.6

漏洞原理:
Nginx接收到文件路径(URI)形如:/test.jpg/test.php之后,一遇到后缀是.php,即判断该文件是PHP文件,并转交给php去处理。而php处理是发现/test.jpg/test.php不存在,便删去最后面的/test.php,而又发现/test.jpg存在,便将/test.jpg当成要执行的文件了,但又因后缀为.jpg,则php认定此文件不是php文件,于是返回Access denied
此中涉及到php的一个选项:cgi.fix_pathinfo,该值默认为1,表示开启。开启此选项后,php可对文件路径进行“修理”。
例如:当php遇到文件路径/1.jpg/2.txt/3.php是,若/1.jpg/2.txt/3.php不存在,则会去掉最后的/3.php,然后判断/1.jpg/2.txt是否存在。若存在,则把/1.jpg/2.txt当作文件/1.jpg/2.txt/3.php,此时若/1.jpg/2.txt仍不存在,则再去掉/2.txt,以此类推

漏洞形式:

1
2
3
www.xxx.com/UploadFiles/image/1.jpg/1.php
www.xxx.com/UploadFiles/image/1.jpg%00.php
www.xxx.com/UploadFiles/image/1.jpg/%20\0.php


IIS7.5

类似于Nginx,都是由于php配置文件中,开启了cgi.fix_pathinfo,而这并非Nginx或IIS7.5本身的漏洞

漏洞形式:

1
www.xxx.com/UploadFiles/image/1.jpg/1.php


Windows系统

漏洞原理:
旧版Windows Server中存在空格和dot漏洞,类似于a.php.a.php这样的文件名存储后,会被Windows去掉点和空格,从而使得加上这两个特殊字串后,可以突破过滤,成功上传,并且被当作php代码执行

漏洞形式:

1
2
3
4
5
test.asp.
test.asp[空格]

test.php:1.jpg
test.php:: $DATA


富文本编辑器

参考:
https://www.webshell.cc/1006.html
https://blog.csdn.net/u011781521/article/details/59057759
https://www.cnblogs.com/qunshu/p/3286650.html
https://www.0dayhack.com/post-426.html


利用方法

前端验证绕过

  • 修改验证函数,在白名单中添加php等后缀名
  • 删除调用接口,不调用函数(浏览器->元素检查->右键在控制台使用)
  • 浏览器功能禁用js
  • 无视前端,抓包改包

MINE绕过

MINE是用于确认请求包中文件类型与后缀名之间的关系的
文件路径:Apache->conf->MINE.typtes
绕过方法:抓包,修改Content-Type字段


黑名单绕过

找出未被列入黑名单的可利用文件类型


.htaccess(仅Apache)

提供了针对目录改变配置的方法(需要Apache开启了相关配置)
将下列文件上传到利用路径下,可临时改变上传路径文件夹的解析规则,将所有以.a为后缀的文件都以php的方式解析

.htaccess

1
AddType application/x-httpd-php .a


大小写

未对后缀名大小写进行严格验证,导致黑名单出现逻辑漏洞


Windwos特性

文件后缀名后添加空格或点导致绕过
原理:Windows系统不允许文件后缀后添加点和空格,会将其自动去除
利用:使用burpsuite抓包改包
.,
.. 绕过删除末尾的点且不改名的上传


NTFS文件流特性

::$DATA:传输数据,将数据写入::$DATA之前的文件名中
寄生文件

1
echo <?php @eval($_POST['a']);?> >> jisheng.php:shell.exe


双写绕过

服务端使用了str_replace,str_ireplace等函数进行过滤

1
2
pphphp  # 正确
phphpp # 错误


截断上传(00截断)

基于一个组合逻辑漏洞造成的。攻击者修改上传过程中的POST包,在文件名后添加一个%00字节,则可以阶段某些函数对文件名的判断。

原因:在许多语言的函数中,如:C、PHP等语言的常用字符串处理函数中,0x00被认为是终止符。

受此影响的环境有Web应用和一些服务器,可构造如xxx.php[\0].jpg的文件,其中[\0]代表十六进制的0x00字符,以此绕过上传文件类型判断;但对服务器来说,此文件因为0x00字符截断的关系,最终却变成xxx.php

URL或POST请求实体中带有上传后存储路径的,考虑路径后跟文件名并且截断。
适用:PHP 5.2.x
需关掉配置文件magic_quotes_gpc()


文件头检测绕过

伪造文件头
如:图片马,配合文件包含使用

  1. 使用burpsuite抓包,先上传图片,删除后边内容,写入webshell
  2. 使用cmd命令行中的copy命令合成图片马:
    1
    copy moon.gif/b+webshell.PHP/a gifshell.gif

图片二次渲染绕过

服务端对上传的图片进行了二次渲染
绕过方法:对上传的图片马进行特殊处理,使得关键信息能在二次渲染后仍旧得以保留

危害

文件上传漏洞对Web应用来说是一种非常严重的漏洞。一般情况下,Web应用都会允许用户上传一些文件,如头像、附件等信息,若Web应用未对用户上传的文件进行有效的检查过滤,那么恶意用户就会上传一句话木马等Webshell,从而达到控制Web网站的目的


高危触发点

  • 相册、头像上传
  • 视频、照片分享
  • 附件上传(论坛发帖、邮件)
  • 文件管理器:即富文本编辑器(fckeitor、webeditor、xxxx editor等)

您的支持是我前进的动力!