Malicious file upload

SkillFiles & storage

Turn a file upload into RCE or stored XSS/SSRF. Load on any upload: avatars, attachments, import CSV/XML, profile images, document processors, "upload your resume". Signals: multipart/form-data, filename in response, an uploads/ path, image thumbnailing, PDF/office parsing.

Instructions available. Your AI can read the instructions. Execution depends on the setup they require.

Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.

Then ask your AI: use the Malicious file upload skill

What this skill tells your AI

The instructions your AI receives, as published by noorqureshi/sploitagent in skills/web/web-file-upload/SKILL.md and read by ahel’s review.

When it applies

The app accepts a file and later stores, serves, parses, or converts it. Impact depends on what happens to the file after upload — served from webroot? passed to a parser? rendered?

Why it works

Validation is usually on the wrong signal (extension or Content-Type, both attacker-set) while the dangerous behaviour is downstream: the web server executes .php in the uploads dir, a parser follows external entities, or the file is served with an HTML content-type.

Method

Payloads & full variation set: cheatsheet.md next to this file — work the set, not the first line.

  1. Find the after-upload behaviour: where is it stored, what URL serves it, what parses it?
  2. RCE via executable extension when uploads are under a script-executing webroot: upload shell.php; if blocked, try .phtml .php5 .phar, double ext shell.php.jpg, null byte shell.php%00.jpg, case .pHp, trailing dot/space, or a polyglot (valid JPEG + PHP in a comment) with a .php name.
  3. Content-Type / magic-byte bypass: keep a real image header (GIF89a;) then payload; change the multipart Content-Type to image/png while the name stays .php.
  4. Parser-based: SVG upload → XSS/SSRF/XXE (SVG is XML+script); office/PDF → SSRF/XXE via external resources; image libraries (ImageMagick) → command exec via crafted files.
  5. Path traversal in filename: ../../var/www/html/shell.php to escape the uploads dir.

Gotchas

  • Upload succeeds but stored outside webroot / served as text/plain → no RCE; pivot to XSS/SSRF instead.
  • Random server-side filenames defeat direct access — look for a predictable/leaked path.
  • WAF strips <?php → use <?= or <script language="php">.

Verify success

Browse to the uploaded script and get command output, or the SVG/XML fires in a victim context / triggers an OOB callback.

References

PortSwigger file-upload labs; OWASP Unrestricted File Upload.

Signals

GitHub stars
20
Forks
7
Last commit
Sep 2026
Advanced
Item type
skill
Key
web-file-upload
Source
github.com/noorqureshi/sploitagent