mcpbeat Sign in

Hunt Upload Agent Skill

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.

1k tokens
context cost
the whole folder, loaded on every use
1
files
instructions only
0
copies elsewhere
how many repositories repackaged it
320
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/Encod3d-Sec/TORCH --skill hunt-upload

The instruction itself

9 sections, as written by the author

Hunt: File 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.

Wiki

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]].

Attack surface

Rank the sinks first - not every upload reaches code:

  • Avatar / profile / logo / signature fields - most common; frequently re-encoded, so check whether the original bytes are served back.
  • Document / CSV / XML import - parser sinks (XXE, formula injection, zip).
  • Ticket / message attachments - often served under the original name and type from a reachable path.
  • Image-processing (thumbnails -> ImageMagick/Ghostscript), SVG/PDF render, EXIF parsers - the processor is the bug, not the store.
  • Firmware / plugin / theme upload - direct code load; highest value when present.

Then attack in layers, cheapest first: extension -> content-type -> magic-byte -> parser/render.

Methodology

  • Baseline: upload a valid file; note stored path, returned URL, filename transformation, and whether it is reachable + executed by the server.
  • Extension bypass:
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 / magic-byte bypass: set Content-Type: image/png; prepend real magic bytes (GIF89a;, \xFF\xD8\xFF JPEG, %PDF-) before the payload; polyglot (valid image + PHP).
  • Path traversal in filename: filename="../../../../var/www/html/shell.php" to escape the upload dir / overwrite files.
  • SVG / XML: SVG with <script> -> stored XSS ([[xss]]); SVG/XML with external entity -> [[xxe]] (file read/SSRF).
  • Archive: zip-slip (../ paths inside zip) on extract; symlink in archive -> read host files.
  • Image processing: ImageMagick/Ghostscript (ImageTragick CVE-2016-3714), pixel-flood DoS, EXIF payload executed by a downstream parser.
  • Confirm by execution, through Burp. Request the uploaded shell in Burp Repeater (operator visibility) and run a command (?cmd=id); OOB callback if blind. For traversal, fetch the written/read target back from the path you claimed it hit.
  • Distill (confirmed, generic): per hunt-core, python3 scripts/wiki-stage.py --kind technique --slug <slug> --target-page techniques/web/file-upload.md.

Evasion (when a layer rejects)

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.

Chaining

  • Upload -> web-shell RCE: once a shell executes, hand off hunt-rce for post-exploitation and CVE-specific escalation.
  • SVG/HTML -> stored XSS: hand off hunt-xss (marker discipline, blind-XSS beacon for a stored context).
  • SVG/XML/DOCX -> XXE: hand off hunt-injection (OOB-mandatory for blind XXE).

Confirmation gate

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.

Severity

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.

Deadends

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.

How to use it

Copy the folder

Take encod3d-sec/hunt-upload from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

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.