Hands-On File Upload Bypass Techniques: 10 Lab Solutions
Level 1: Client‑Side JavaScript Validation
A PHP web shell (info.php) contains:
<?php phpinfo(); ?>
The upload form invokes a checkFile() function to filter file types. Three workarounds exist:
- Remove the
checkFile()call from the page source locally and submit the form. - Disable JavaScript entirely in the browser (e.g., Firefox → F12 → Settings → Disable JavaScript).
- Change the file extension to
.jpg, send the request through Burp Suite, and revert the filename to.phpin the intercepted packet before forwarding.
All approach bypass the client‑side check, and the shell becomes accessible.
Level 2: MIME Type Verification
The server inspects the Content-Type header:
($_FILES['upload_file']['type'] == 'image/jpeg') ||
($_FILES['upload_file']['type'] == 'image/png') ||
($_FILES['upload_file']['type'] == 'image/gif')
Upload a .php file while intercepting with Burp. Modify the Content-Type to image/jpeg, image/png, or image/gif. The file passes the MIME check and is saved on the server.
Level 3: Limited Blacklist Extension
The server blocks only .asp, .aspx, .php, and .jsp. Other executable PHP extensions are not listed. Rename the payload to shell.php5 and upload it directly – the blacklist is circumvented.
Level 4: .htaccess Configuration Upload
Many extensions are forbidden, but .htaccess is absent from the blacklist. First, craft an .htaccess file with:
AddType application/x-httpd-php .png
Next, upload a PHP shell disguised as shell.png. After both files are14, accessing the .png file causes Apache to interpret it as PHP, executing the embedded code.
Level 5:encoding Functions Introduced
Examining the source reveals functions for case conversion and trimming. The blacklist still covers .htaccess and numerous other extensions. This level does not present a direct bypass; it sets the stage for11.
Level 6: Mixed‑Case Extension Bypass
The validation routine does not normalize case before comparing against the blacklist:
$file_ext = strtolower($file_ext); // missing in this level
Renaming the file to shell.Php passes the check, while the server still executes the PHP code.
Level 7: Trailing Space Insertion
The code removes trailing dots (deldot) but does not trim trailing spaces. Using Burp, modify the filename to shell.php . The uploaded file retains the space, and the blacklist matching fails because the extension is "php " (not .php).
Level 8: Trailing Dot Attack
Similarly,16 does not strip a trailing dot from the processed filename. Append a dot (shell.php.). Windows file systems automatical remove the dot upon saving, leaving a valid .php file.
Level 9: NTFS ::$DATA Stream Bypass
On Windows, appending ::$DATA to a filename treats the appended part as an alternate data stream,13. The9 code this time has removed the str_ireplace('::$DATA', '', $file_ext) call. Rename the file to shell.php::$DATA. The server saves it as shell.php, bypassing the extension check.
Level 10: Double Extension Writing
All previous tricks are12, but the16 uses str_ireplace to remove only exact blacklisted patterns from the extension. Supply a filename like shell.pphphp. The replacement deletes the inner .php, resulting in .php as the final extension and successfully uploading the shell.