Hack The Box: WhiteRabbit Machine Walkthough – Insane Difficulity
Introduction to WhiteRabbit:

In this writeup, we will explore the “WhiteRabbit” machine from Hack The Box, categorized as an easy 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 “WhiteRabbit” machine from Hack The Box by achieving the following objectives:
User Flag:
The user flag began with a publicly accessible Uptime Kuma guest dashboard that inadvertently exposed internal service names and subdomains, including Wiki.js, Gophish, and n8n. A leaked n8n workflow JSON file on the unauthenticated Wiki.js instance revealed the exact webhook endpoint, the hardcoded HMAC-SHA256 secret, and a vulnerable email parameter prone to blind SQL injection. This dump uncovered the restic repository password from bob’s command history. Leveraging bob’s NOPASSWD sudo privilege for restic, a snapshot was restored containing bob’s private SSH key from /dev/shm. After gaining access as bob, the same restic privilege was abused again to dump a root-level snapshot that included morpheus’s private SSH key. Finally, SSH access as morpheus allowed reading of the user.txt flag.
Root Flag:
From the morpheus shell, exploration revealed a custom SUID binary at /opt/neo-password-generator/neo-password-generator. The binary was transferred off-box and reverse-engineered, exposing a predictable pseudorandom password generator that used srand() seeded directly from a command-line argument. A signed integer overflow in the seed calculation (1725028842 * 1000 + add) created a small, predictable negative seed space. The binary was faithfully recreated locally, and a brute-force script generated candidate passwords until a valid one was found, granting SSH access as neo. Once inside as neo, sudo -l revealed full passwordless sudo privileges ((ALL : ALL) ALL). A simple sudo su elevated to root, allowing direct access to root.txt and completing the box.
Enumerating the Machine
Reconnaissance:
Nmap Scan:
Begin with a network scan to identify open ports and running services on the target machine.
nmap -sC -sV -oA initial 10.10.11.63Nmap Output:
┌─[dark@parrot]─[~/Documents/htb/whiterabbit]
└──╼ $nmap -sC -sV -oA initial 10.10.11.63
# Nmap 7.94SVN scan initiated Fri Dec 12 13:57:59 2025 as: nmap -sC -sV -oA initial 10.10.11.63
Nmap scan report for 10.10.11.63
Host is up (0.045s latency).
Not shown: 997 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.9 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 0f:b0:5e:9f:85:81:c6:ce:fa:f4:97:c2:99:c5:db:b3 (ECDSA)
|_ 256 a9:19:c3:55:fe:6a:9a:1b:83:8f:9d:21:0a:08:95:47 (ED25519)
80/tcp open http Caddy httpd
|_http-title: Did not follow redirect to http://whiterabbit.htb
|_http-server-header: Caddy
2222/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 c8:28:4c:7a:6f:25:7b:58:76:65:d8:2e:d1:eb:4a:26 (ECDSA)
|_ 256 ad:42:c0:28:77:dd:06:bd:19:62:d8:17:30:11:3c:87 (ED25519)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Dec 12 13:58:09 2025 -- 1 IP address (1 host up) scanned in 10.19 seconds
Analysis:
- 22/tcp (SSH): Standard OpenSSH service on Ubuntu, likely requiring valid credentials for remote access.
- 80/tcp (HTTP): Caddy web server redirecting to
whiterabbit.htb, indicating name-based virtual hosting. - 2222/tcp (SSH): Secondary OpenSSH instance on a non-standard port, suggesting an alternate or restricted access path.
Web Enumeration:
Perform web enumeration to discover potentially exploitable directories and files.

Visiting http://whiterabbit.htb, we’re presented with the public landing page of “White Rabbit – Pentesting Services”, a professional marketing site featuring a stylised rabbit mascot and sections about their penetration testing offerings.

Browsing the “Latest News” section on the main whiterabbit.htb site, we see a blog-style update explicitly mentioning the use of Uptime Kuma for uptime and network monitoring during client pentesting engagements, directly confirming its deployment.

Running Gobuster in VHOST enumeration mode against whiterabbit.htb using a medium-sized subdomain wordlist, the tool completes its scan with nearly 5,000 entries tested and reports no additional virtual hosts discovered.

Executing ffuf with Host-header fuzzing (Host: FUZZ.whiterabbit.htb) and filtering for non-zero response sizes, we successfully identify a hidden virtual host that returns a 302 redirect
Initial Web Exposure via Uptime Kuma

Accessing http://status.whiterabbit.htb/dashboard displays the Uptime Kuma login page with a standard username/password form and a “Remember me” option.
Uptime Kuma – Open-Source Uptime Monitoring

Uptime Kuma is a self-hosted, open-source monitoring tool that tracks the uptime and performance of websites, servers, and online services. It provides a real-time web dashboard, historical statistics, and alerts via channels like email, Discord, or Slack when services go down. Supporting multiple protocols such as HTTP(S), TCP, and Ping, it lets users monitor critical systems without relying on third-party services, giving full control over their data and notifications.

Viewing the source of http://status.whiterabbit.htb/dashboard, we see the standard Uptime Kuma login page source, featuring typical meta tags, Vue.js bundles, and the characteristic “Uptime Kuma/title” noscript message prompting JavaScript enablement.

When you visit https://n8n.io (as the status page monitoring reveals), you see the official landing page for n8n, a fair-code workflow automation platform that White Rabbit runs in production.
Discover the uptime version

Inspecting the bundled JavaScript at /assets/index-CYsZUV7d.js, we quickly spot the hardcoded frontendVersion string returning “1.23.13”

The official Uptime Kuma public status page provides real-time visibility into the operational state of monitored systems. It displays uptime metrics, incident history, and performance data, allowing stakeholders to quickly assess service health and track any disruptions without requiring authentication.

Trying /status at http://status.whiterabbit.htb/status returns a blank page, but based on the Uptime Kuma demo, it’s probably a general status endpoint.
Discovery of Internal Services

An unauthenticated Uptime Kuma page at /status/temp publicly lists all monitored services as operational.
Wiki.js Information Disclosure

When you land on http://a668910b5514e.whiterabbit.htb, Wiki.js greets you with its clean, modern homepage. A visible “ToDo” page lists just one item: the staff still needs to add authentication.

When you visit http://ddb09a8558c9.whiterabbit.htb, Gophish welcomes you with its clean login page. This open-source phishing framework displays only the iconic fishing-hook logo and a straightforward “Username / Password” sign-in form.
GoPhish Webhooks workflow

An internal Wiki.js article at /gophish_webhooks documents Gophish–n8n workflows, including screenshots and the full exported JSON.

Diving deeper into the leaked workflow notes, we read the full explanation of signature processing, user validation, phishing-score updates, and the existence of a debug node clearly labelled “DEBUG: REMOVE SOON”.

The exported n8n documentation includes a legitimate Gophish POST example with the required signature header and a “Clicked Link” payload.

When you save the leaked n8n workflow locally, the suggested filename “gophish_to_phishing_score_database.json” immediately reveals its purpose.
n8n Webhook Authentication Bypass

Visiting the n8n instance at http://28efa87fdf.whiterabbit.htb, we’re presented with the standard n8n login screen prompting for email and password, along with a “Critical update available” banner.

When you attempt to call the raw webhook URL directly at /webhook/d96af3a4-21bd-4bcb-bd34-37bfc67dfdid, n8n returns a 404 JSON response.
SQL Injection via Signed Webhook

Sending a raw GET request to the same webhook path returns another 404 with the same helpful error message and a hint to activate the workflow via the top-right toggle.

The replayed webhook returned 200 OK with “User is not in database,” indicating an active endpoint that rejected the test payload.

The exported workflow includes “no signature” and “invalid signature” branches that expose plain-text errors for missing or incorrect x-gophish-signature headers.

A leaked n8n workflow node exposes a hard‑coded SHA‑256 HMAC secret for Gophish webhook signing.
Generating an HMAC-SHA256 Signature from a Minified JSON Payload Using CyberChef

Using CyberChef, we generate the correct HMAC-SHA256 by signing the minified JSON body with the UTF-8 secret jBiTicmv7gxc6IS. This produces the signature 2db3eee889e9ee285ce57acbe51caae7dd4863ab9cadf21be4262be8f9fb5ff7.

The finalised payload includes the correct secret, minified JSON, and a valid HMAC, enabling data extraction or command execution via OUTFILE.
Testing Request Integrity with Burp Suite

We craft the first request in Burp using the original payload and an incorrect signature. The server returns the expected “Provided signature is not valid” response.

We used CyberChef to recreate the minified JSON and compute a valid HMAC for the malicious payload.

A basic SQLi in the email field using ExtractValue returned a partial database list via an error message.


When you send the fully signed SQL injection request, the server responds with another detailed MySQL error.

We send a signed SQL injection payload to the n8n webhook. This triggers an XPath error that leaks all table names in the phishing database, including victims and campaigns. The still-active Gophish → n8n → MySQL chain confirms full blind SQLi exploitation with valid HMAC authentication.

We execute the final signed payload to extract full command history entries. These include usernames and timestamps, retrieved through the still-active n8n webhook → MySQL injection chain.

Opening the sql.py exploit script reveals a clean, fully automated Python tool. It loops 1,500 times to blind-extract the entire temp.command_log table, including IDs, commands, and dates.

Running the python3 sql.py script, we observe it quickly cycling through timestamps from August 30, 2024. It appears to be enumerating entries from the leaked temp.command_log table.
Credential Discovery from Command Logs

On Parrot OS, we install Restic with sudo apt install restic, fetching the latest version from the official repository. It is now ready to interact with White Rabbit’s backup system.

Attempting to use Restic without proper configuration results in a fatal error. It cannot reach http://75951e6ff.whiterabbit.htb/config, confirming the backup server runs on that subdomain.
To authenticate with the Restic repository, we create a password file containing ygcsvcuMdfZ89yaRL1TKhe5jAmth7vvxw and set its permissions to 600. We then export the RESTIC_REPOSITORY and RESTIC_PASSWORD_FILE environment variables.

Running restic snapshots, we confirm a single snapshot exists: ID 272cad5 from 2025-03-06, tagged with the path /dev/shm/bob/ssh.
Lateral Movement to bob

Using restic restore latest, we authenticated and restored snapshot 272cad5 from /dev/shm/bob/ssh on the remote repository.

Landing inside the restored snapshot, we find ourselves in /home/dark/Documents/htb/whiterabbit/restored_data/dev/shm/bob/ssh – a clear sign we’ve successfully recovered bob’s SSH directory from a restic backup.

Landing in the restored snapshot directory, we see a single file: bob.7z – the compressed archive containing bob’s SSH credentials that was accidentally left in /dev/shm.
Recovering Credentials from the 7-Zip Archive

Attempting to crack the 7z archive with 7zzjohn, we hit the classic “Can’t locate Compress::Raw::Lzma” error** because the required Perl module is missing on Parrot OS.

We install the missing LZMA Perl module with sudo apt install libcompress-raw-lzma-perl, fixing 7zz for John and allowing clean hash extraction.

We used 7zz john to crack the 7z, extracted the contents, and saved Bob’s password hash to hash.txt.

Finally, we dumped the cracked hash and viewed it with cat hash.txt, revealing Bob’s full password hash: $7z$.... Strictly unnecessary at this point, but satisfying to confirm.

John The Ripper quickly identifies the password as lq2w3e4r5t6y (a common keyboard-walk pattern shifted down one row, present in rockyou).
Inspecting Contents of bob.7z


Extracting the 7z archive with 7z x, we successfully decompress bob.7z after providing the password, revealing bob’s private key and config files.

Listing the restored directory post-extraction, we now have bob, bob.7z, bob.pub, config, and hash.txt – everything we need to own the box.

Pivoting to bob over SSH

Fixing permissions and SSHing directly as bob, we run chmod 600 bob and ssh -i bob bob@10.10.11.63 – instant shell, no password needed.

Checking bob’s sudo privileges, we run sudo -l and discover bob can run /usr/bin/restic as root with NOPASSWD – the golden ticket for privilege escalation.

Successfully initializing bob’s own local restic repository, we create dark at f22eeb5f29 after providing a valid password, ready for our own backups.

Running restic backup /root as bob with full sudo privileges, we create a new snapshot 2c446829 of the entire root directory – adding 4 new files and 3 new directories (including /root/morpheus and its keys) to our personal repository dark, all without ever needing root’s password.

Listing the latest snapshot 2c446829 as bob, we see a full backup of /root including .bashrc, .profile, .ssh, and crucially /root/morpheus and /root/morpheus.pub.

Dumping morpheus’s private key from the root snapshot, we use restic dump on path /root/morpheus and extract the full OpenSSH private key – confirming we now own root.
Pivot to morpheus

Viewing the recovered Morpheus private key locally, we can morpheus and stare at a pristine OpenSSH private key – root access is now just an SSH away.

SSHing in as morpheus using the recovered key, we successfully authenticate to morpheus@10.10.11.63 and land directly on the minimized Ubuntu 24.04 system.

Landing the final blow as morpheus on WhiteRabbit, we run cat user.txt and reveal the user flag
Escalate to Root Privileges Access
Privilege Escalation:

Failing sudo as morpheus, we repeatedly get “Sorry, try again” – confirming no easy password reuse and forcing us to look deeper for privilege escalation.
SUID Binary Discovery

Exploring /opt as morpheus, we discover the neo-password-generator directory containing a single executable – clearly the SUID binary we’re hunting.
Reverse Engineering the Binary

SCP-ing the neo-password-generator binary back to our machine, we successfully pull the 15KB ELF for static and dynamic analysis.

Checking the file type of neo-password-generator, we confirm it’s a 64-bit LSB pie executable, dynamically linked, not stripped – perfect for reverse engineering.
PRNG Design Analysis

Vulnerability 1: Integer Truncation in Seed Calculation (Critical Exploit Path)
The seed is calculated as tv_sec * 1000 + tv_usec / 1000, producing a 64-bit millisecond timestamp (approximately 1.7 trillion in late 2025). While this value fits safely within a signed 64-bit integer, it is commonly truncated when passed to srand(), either by casting to a 32-bit unsigned integer or via a modulo operation. This truncation silently discards the higher bits, reducing the effective seed space from trillions of possibilities to at most 4.29 billion, and often far fewer in practice. As a result, what appears to be a large entropy source becomes a manageable brute-force space, making this the primary exploitation vector.
Vulnerability 2: Predictable Seed from Low-Entropy Source
The seed relies entirely on the current system time in milliseconds, which provides very little entropy. An attacker with approximate knowledge of when the program was executed—derived from logs, challenge timing, or user interaction—can constrain the search window to a narrow range such as ±10–60 seconds. This reduces the number of candidate seeds to roughly 20,000–120,000. Because PRNGs are deterministic, testing this limited range is sufficient to reliably reproduce the generated output.
Vulnerability 3: Use of Weak, Non-Cryptographic PRNG
The password generation uses the standard rand() function seeded via srand(), which is not designed for security purposes. It exhibits predictable output patterns, weak lower bits, and easily reproducible sequences. Even if seeded correctly, rand() remains unsuitable for password generation. Combined with the truncated and time-based seed, an attacker can replicate the algorithm and regenerate the password with minimal effort, fully compromising the mechanism.

Grepping /etc/passwd for shell users, we spot root, neo (UID/GID 1000), and morpheus (UID/GID 1001) – hinting neo might be the intended escalation target.

Viewing the full decompiled dark.c source, we see a predictable password generator using srand(param_1) and rand() % 62 over a fixed charset, seeded directly from the command-line argument.

Running gcc on the decompiled dark.c, we hit an integer overflow warning on the line generate_password(1725028842*1000 + add) – a classic seed manipulation hint.

Executing our reconstructed dark binary, we successfully generate a password like L70f2aFEohexXuk07tEw… – proving our reverse engineering is accurate and ready for seed brute-force.

Dumping our local dark binary output to pass.txt, we prepare the reconstructed neo-password-generator for transfer and analysis. Spotting the overflow in the seed calculation, we realize 1725028842 * 1000 overflows a signed int, giving us a predictable negative seed range to brute-force neo’s password.
Authentication as neo


Testing multiple generated passwords via ssh, we see a long list of failed Paramiko errors until the correct one grants “Linux – Shell access!”.

Successfully authenticating as neo, we bypass the banner errors and gain a stable shell on neo@10.10.11.63.

Running sudo -l as neo, we discover the nuclear option: (ALL : ALL) ALL – neo can execute any command as any user, including root, without a password.

Switching to root with plain sudo su as neo, we seamlessly become root at /home/neo# – confirming neo has unrestricted sudo access.

Escalating instantly as neo with sudo -s, we drop straight into a root shell at /home/neo# – no password needed.

Catting root.txt from neo’s home as root, we uncover the root flag
The post Hack The Box: WhiteRabbit Machine Walkthough – Insane Difficulity appeared first on Threatninja.net.


































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































