Hunt Upload logo

Hunt Upload

Community
Encod3d-Sec
hunt-upload

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.

Overview

PublisherEncod3d-Sec
RepositoryTORCH
Skill namehunt-upload
Stars
334
Forks
48
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by Encod3d-Sec on GitHub. Read the source before you install it.

Installation

Install the Hunt Upload AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/Encod3d-Sec/TORCH/tree/main/skills/hunt/hunt-upload
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/Encod3d-Sec/TORCH.git /tmp/TORCH
mkdir -p .claude/skills
cp -r /tmp/TORCH/skills/hunt/hunt-upload .claude/skills/hunt-upload
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Hunt Upload in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Hunt Upload on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Hunt Upload is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

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

  1. Baseline: upload a valid file; note stored path, returned URL, filename transformation, and whether it is reachable + executed by the server.
  2. 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)
  1. 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).
  2. Path traversal in filename: filename="../../../../var/www/html/shell.php" to escape the upload dir / overwrite files.
  3. SVG / XML: SVG with <script> -> stored XSS ([[xss]]); SVG/XML with external entity -> [[xxe]] (file read/SSRF).
  4. Archive: zip-slip (../ paths inside zip) on extract; symlink in archive -> read host files.
  5. Image processing: ImageMagick/Ghostscript (ImageTragick CVE-2016-3714), pixel-flood DoS, EXIF payload executed by a downstream parser.
  6. 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.
  7. 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.

Frequently asked questions

What does the Hunt Upload AI skill do?

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.

Why use Hunt Upload on TypingMind?

Because you install it once and use it with any model. Hunt Upload is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Hunt Upload in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/Encod3d-Sec/TORCH/tree/main/skills/hunt/hunt-upload. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Hunt Upload?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Hunt Upload?

As many as you like. As long as a model supports skills, you can use Hunt Upload with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Hunt Upload AI skill free?

Yes. It is published on GitHub by Encod3d-Sec under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇