文件上传漏洞
文件上传漏洞
漏洞介绍
文件上传漏洞是指由于程序员在对用户文件上传部分的控制不足或者处理缺陷,而导致用户可以越过其本身权限向服务器上上传可执行的动态脚本文件。
攻击者利用系统缺陷绕过对文件的验证和处理,将恶意文件(如配置文件、木马和病毒、包含脚本的图片等)上传到服务器并通过文件获得服务器上相应的权力,或通过诱导外部用户访问、下载上传的病毒或木马文件,达到攻击的目的
bypass
htaccess
htaccess文件是Apache服务器中的一个配置文件,它可以用来控制网页的访问权限、重定向、解析规则等。如果服务器没有禁止或过滤htaccess文件的上传,且允许用户使用自定义的htaccess文件,那么攻击者就可以利用htaccess文件来绕过文件类型检测,或者改变文件的解析方式,从而执行恶意代码。
例如,攻击者可以上传一个名为.htaccess的文件,其内容如下:
AddType application/x-httpd-php .jpg
这样就可以让服务器将.jpg后缀的文件当作php文件解析,然后再上传一个包含php代码的.jpg文件,就可以执行任意命令。
为了防止这种漏洞,应该在服务器端对上传的文件进行严格的检查,包括文件名、内容、类型、大小等,并设置合理的权限和目录。另外,也可以禁用或限制htaccess文件的功能,避免用户自定义配置影响服务器安全。
当.htaccess文件被放置在一个目录中时,它会影响到这个目录及其子目录中的所有文件。如果你上传了一个.htaccess文件到一个目录中,那么这个目录下所有的文件都会受到这个文件的影响
.user.ini
这个文件是php.ini的补充文件,当网页访问的时候就会自动查看当前目录下是否有.user.ini,然后将其补充进php.ini,并作为cgi的启动项。
与htaccess类似,但用的更广,只要使用了fastcgi,就都可以通过该文件修改配置。
php除了扫描php.ini配置文件外,还会扫描.user.ini文件,.user.ini是一个
| 配置项 | 含义 |
|---|---|
| auto_prepend_file | 指定在主文件之前自动解析的文件名,相当于把指定文件名的文件插入到主文件开头,如果为none表明禁用该配置项 |
| auto_append_file | 指定在主文件之后自动解析的文件名,相当于把指定文件名的文件插入到主文件末尾,如果为none表明禁用该配置项 |
验证机制
前端js检查
文件类型限制
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;
}
}
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.'文件夹不存在,请手工创建!';
}
}
后端检查
文件后缀名检查
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".ini");
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //收尾去空
if(!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
if (move_uploaded_file($temp_file,$img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
windows文件解析漏洞
-
在windows中如果文件名加上
::\$DATA就会把::\$DATA后面的数据当做文件流处理而不做任何检测,即1.php::\$DATA上传成功后会被解析为1.php文件 -
对于windows来说,文件名除了末尾为空格会去掉以外,末尾为点都可以去掉
即
1.php..和1.php[空格]都会被解析为1.php文件
上传文件名:1.php::\$DATA、1.php..、1.php[空格]
后台存储为:1.php
访问:1.php
后台解析为:当做php文件处理
中间件解析漏洞
- IIS 5.x/6.0解析漏洞
- IIS 7.0/IIS 7.5/
- Nginx <0.8.3畸形解析漏洞
- Nginx <8.03 空字节代码执行漏洞
- Apache解析漏洞
IIS 5.x/6.0解析漏洞
IIS6.0默认的可执行文件除了.asp外还包含.asa、.cer、.cdx
拥有以下特性:
-
xxx.asp目录下的文件全按asp文件处理,因此只要将任意后缀的文件上传到该目录中,然后访问就可以拿到shell上传文件名:
任意文件名和后缀后台存储为:
原文件名和后缀访问:
原文件名和后缀后台解析为:当做asp文件处理
-
xxx.asp;.jpg中;后面的部分不会被解析,即该文件名会被解析为xxx.asp并处理上传文件名:
xxx.asp;.jpg后台存储为:
xxx.asp访问:
xxx.asp后台解析为:当做asp文件处理
IIS 7.0/7.5解析漏洞/nginx 0.8.3解析漏洞
利用条件:开启Fast-CGI
上传1.jpg然后在访问时在1.jpg后面加上/.php将其当做php文件解析
上传文件名:1.jpg
后台存储为:1.jpg
访问:1.jpg/.php
后台解析为:当做php文件处理
nginx %00空字节解析漏洞
影响版:0.5.,0.6., 0.7 <= 0.7.65, 0.8 <= 0.8.37
首先上传图片马xxx.jpg,然后访问的时候输入xxx.jpg%00.php,然后图片马内部的php脚本就会被执行
上传文件名:xxx.jpg
后台存储为:xxx.jpg
访问:xxx.jpg%00.php
后台解析为:图片马里面的脚本会执行,图片也会显示
Apache解析漏洞
apache从右到左开始解析,遇到无法解析的就继续向左判断
1.php.wof如果遇到.wof无法解析成功,就会解析成1.php文件
上传文件名:1.php.d.c.e
后台存储为:1.php.d.c.e
访问:1.php.d.c.e
后台解析为:当做php文件处理
配置解析漏洞
在apache中的配置文件中存在类似的配置:AddHandler php5-script .php,只要包含.php的文件名就可以被当做php脚本解析
在apache中的配置文件中存在类似的配置:AddType application/x-httpd-php .jpg,jpg文件就会被当做php脚本解析
漏洞修复
- 对上传文件类型进行验证,除在前端验证外在后端依然要做验证,后端可以进行扩展名检测,重命名文件,MIME类型检测以及限制上传文件的大小等限制来防御,或是将上传的文件其他文件存储服务器中。
- 对上传文件的目录设置为不可执行,禁止脚本权限,或者设置为只读,禁止写入。
- 对上传文件的内容进行检测,防止包含恶意代码或程序文件。
- 对上传文件的路径进行限制,防止目录遍历或文件包含。
- 对上传文件的名称进行过滤,防止跨站脚本攻击或SQL注入。
- 对上传文件的处理结果进行检查,防止返回敏感信息或错误提示。
工具
import requests
import os
# 上传文件的路径
upload_url = "http://example.com/upload.php"
# 上传文件的类型
file_type = "php"
# 上传文件的内容(无害的)
file_content = "<?php echo 'Hello World'; ?>"
# 生成一个临时文件
temp_file = "test." + file_type
with open(temp_file, "w") as f:
f.write(file_content)
# 构造一个 multipart/form-data 格式的请求体
files = {"file": (temp_file, open(temp_file, "rb"), file_type)}
# 发送请求并获取响应
response = requests.post(upload_url, files=files)
# 删除临时文件
os.remove(temp_file)
# 打印响应内容
print(response.text)
冰蝎
冰蝎是一种新型的木马连接工具,具备强大的功能,只要将冰蝎码上传到服务器并能够成功访问,那就可以执行诸多实用的功能,包括获取服务器基本信息,执行系统命令,文件管理,数据库管理,反弹meterpreter,执行自定义代码等。冰蝎使用动态二进制加密技术来保护流量特征。
中国蚁剑
中国蚁剑是一款由中国黑客团队研发的网络安全工具,主要用于远程攻击和控制计算机系统。该工具具有许多高级功能,例如端口扫描、漏洞利用、文件管理、远程执行命令、密码破解等。由于其强大的功能和易用性,中国蚁剑被广泛应用于渗透测试和攻击行为中。
fuxploider
Fuxploider是一款功能强大的开源渗透测试工具,该工具专门针对文件上传漏洞而设计,可以帮助广大研究人员以自动化的方式检测和利用目标站点文件上传表单中的安全问题。
GitHub - almandin/fuxploider: File upload vulnerability scanner and exploitation tool.
使用方式:
python311 fuxploider.py -u "http://61.147.171.105:51905/index.php" --not-regex "wrong file type"