File upload attack hunting - extension/content-type/magic-byte bypass to web-shell RCE, path traversal in filename, SVG/XML XSS, zip slip, and pixel-flood DoS. Wiki-first, FIND schema output.
npx skills add https://github.com/Encod3d-Sec/TORCH --skill hunt-upload
Assumes hunt-core for the scope gate, two-account rule, confirmation gate, enumeration limits, stop conditions, wiki protocol, FIND output, and Deadends. Do not re-derive any of that here.
qmd_query "file upload webshell extension content-type magic-byte bypass SVG XXE zip slip path traversal" via wiki-search MCP
Hub: [[web-moc]] (live index). Primary page: [[file-upload]]. Payload arsenal: wiki/payloads/file-upload.md.
Anchors: [[path-traversal-lfi]].
Rank the sinks first - not every upload reaches code:
Then attack in layers, cheapest first: extension -> content-type -> magic-byte -> parser/render.
shell.php shell.phtml shell.php5 shell.phar shell.pHp
shell.php.jpg shell.jpg.php shell.php%00.jpg shell.php;.jpg
shell.php/ shell.php.... (trailing dot/space on Windows)
.htaccess -> AddType application/x-httpd-php .jpg (then upload .jpg shell)
web.config (IIS) .jsp/.jspx/.war (Java) .asp/.aspx (IIS)
Content-Type: image/png; prepend real magic bytes (GIF89a;, \xFF\xD8\xFF JPEG, %PDF-) before the payload; polyglot (valid image + PHP).filename="../../../../var/www/html/shell.php" to escape the upload dir / overwrite files.<script> -> stored XSS ([[xss]]); SVG/XML with external entity -> [[xxe]] (file read/SSRF).../ paths inside zip) on extract; symlink in archive -> read host files.?cmd=id); OOB callback if blind. For traversal, fetch the written/read target back from the path you claimed it hit.python3 scripts/wiki-stage.py --kind technique --slug <slug> --target-page techniques/web/file-upload.md.Double extension (shell.php.jpg / shell.jpg.php), null byte (shell.php%00.jpg), content-type spoof (Content-Type: image/png on a script), magic-byte prefix (GIF89a; + payload), and case variation (.pHp, .PHtml). Combine them - a single-layer allowlist rarely survives extension + content-type + magic-byte applied together.
hunt-rce for post-exploitation and CVE-specific escalation.hunt-xss (marker discipline, blind-XSS beacon for a stored context).hunt-injection (OOB-mandatory for blind XXE).NOT confirmation: the upload was accepted; a 200 or a returned file URL; the file shows up in a listing; a stored path you have not fetched back; a script uploaded but never requested; a traversal filename accepted with nothing actually read or written outside the upload dir.
IS confirmation: the uploaded file executed as code - fetch it back and it runs your command (?cmd=id returns output) or fires an OOB callback when blind; or the traversal demonstrably wrote or read outside the upload dir, proven by fetching that target back. SVG/XML: the script fires in a victim context, or the external entity returns file contents / an OOB hit. Reproduce in a clean session.
CRITICAL if code execution; HIGH if stored XSS / XXE / arbitrary file write to a sensitive path; MEDIUM if upload of a dangerous type with no execution path proven.
Append: - [ ] upload <host> <endpoint> -- ext+CT+magic+traversal all blocked; files re-encoded + served from CDN no-exec
Record which layers you cleared and which held, so the next pass does not retry them.
Take encod3d-sec/hunt-upload from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.