Hack The Box - HTB Era Writeup - Medium - Season 8 Weekly - July 26th, 2025
Box Details:
- Name: ERA
- Difficulty: Medium
- OS: Linux (Ubuntu)
- Key Skills: Subdomain enumeration, File upload exploitation, SQL injection, FTP enumeration, PHP wrapper exploitation, Binary replacement privilege escalation
Executive Summary
This box involves discovering a file management subdomain, exploiting weak authentication mechanisms, leveraging PHP SSH2 wrappers for RCE, and performing a binary replacement attack for privilege escalation.
Attack Chain:
- Subdomain enumeration → File management portal
- Account registration → Database backup discovery
- Password hash cracking → FTP access
- Admin account takeover → PHP wrapper RCE
- Binary replacement → Root access
Enumeration
Initial Port Scan
We start with a comprehensive nmap scan to identify open ports and running services:
nmap -A -p- [ATTACKER_IP]
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-27 00:02 +05
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.5
80/tcp open http nginx 1.18.0 (Ubuntu)
Port Analysis:
- Port 21: FTP service running vsftpd 3.0.5
- Port 80: HTTP service running nginx 1.18.0 on Ubuntu
The main website on port 80 showed no useful content that could be exploited, which is why we proceeded to subdomain enumeration.
Subdomain Discovery
Since the main website has nothing useful to be exploited, we perform subdomain enumeration to discover additional attack surfaces:
ffuf -w /usr/share/amass/wordlists/bitquark_subdomains_top100K.txt \
-H "Host:FUZZ.era.htb" \
-u http://era.htb/ -mc 200
Command Breakdown:
-w: Specifies the wordlist for subdomain fuzzing-H "Host:FUZZ.era.htb": Sets the Host header with FUZZ as placeholder-u http://era.htb/: Target URL-mc 200: Match HTTP status code 200 (successful responses)
Discovery Result: We found the file subdomain

We add the discovered subdomain to our /etc/hosts file next to the main domain:
[ATTACKER_IP] era.htb file.era.htb
File Management Portal Analysis
Navigating to http://file.era.htb, we discover a file management system with multiple functionalities:

Available Features:
- Manage files: File management interface
- Upload files: File upload functionality
- Update security question: Security question management
- Login system: User authentication
Critical Observation: All of these functions require login authentication. However, we notice that the security question update feature can target any user as long as we know the correct username - this will become exploitable later when we discover usernames.
Initial Access
User Registration & System Exploration
Since we need access to the system, we start by registering a new user account:
Registration Process:
- Navigate to
http://file.era.htb/register.php - Create a new user account

User Dashboard Analysis
After successful registration and login, we access the user dashboard:

Dashboard Features:
- File Management: Users can manage their uploaded files
- File Upload: Users can upload files to the system
- Security Questions: Users can update security questions for any username (potential vulnerability)
File Upload Testing
We test the file upload functionality and make several important discoveries:

Upload Analysis:
- No file type verification: The system accepts any file type without validation
- No direct file access: Uploaded files cannot be accessed directly via URL
- Download script access: Files are accessible through a download script that downloads files to the user rather than executing them
This means we cannot directly execute uploaded files, but we can use the upload feature to discover other files in the system.
Automated File ID Enumeration
Since files are accessed via download.php?id=X, we create a script to brute force file IDs and discover existing files. We can use Burp Suite Intruder or the following Python script:
import requests
from bs4 import BeautifulSoup
from concurrent.futures import ThreadPoolExecutor, as_completed
# Configurations
base_url = "http://file.era.htb/download.php?id="
start_id = 1
end_id = 3000
max_threads = 50 # Increase/decrease based on your bandwidth & target server
cookies = {
"PHPSESSID": "YOUR COOKIE" # Get YOUR COOKIE
}
def check_id(file_id):
url = f"{base_url}{file_id}"
try:
response = requests.get(url, cookies=cookies, timeout=5)
content = response.text
if "Your Download Is Ready!" in content:
soup = BeautifulSoup(content, "html.parser")
file_link = soup.find("a", href=True)
filename = file_link.text.strip() if file_link else "Unknown File"
return f"[+] ID {file_id} -> ✅ FOUND: {filename}"
elif "The file you requested doesn't exist" in content:
return f"[-] ID {file_id} -> ❌ Not Found"
else:
return f"[?] ID {file_id} -> Unknown response"
except Exception as e:
return f"[!] ID {file_id} -> Error: {e}"
# Run in parallel
with ThreadPoolExecutor(max_workers=max_threads) as executor:
futures = [executor.submit(check_id, i) for i in range(start_id, end_id + 1)]
for future in as_completed(futures):
print(future.result())
Script Functionality:
- Multi-threaded scanning: Uses ThreadPoolExecutor for fast parallel requests
- Response analysis: Checks for "Your Download Is Ready!" to identify valid files
- Error handling: Manages timeouts and connection errors
- Session management: Uses cookies to maintain authenticated session
After running the script, we discover two critical files:

Critical Files Discovered:
http://file.era.htb/download.php?id=150 -> signing.zip
http://file.era.htb/download.php?id=54 -> site-backup-30-08-24.zip
Database Analysis & Credential Extraction
We download both files and examine their contents. The backup file (site-backup-30-08-24.zip) contains SQLite database files:

Database Content Analysis:
- User credentials: The database contains user accounts and password hashes
- System configuration: Database structure reveals application architecture
Users and Hashes Discovered: