Runner
Overview
Enumeration
Starting with a full tcp nmap scan, we can see that there are three services open on the host.
There’s a client-facing website on port 80 that’s selling their CI/CD pipeline, but not much else. Port 8000 is fingerprinted as “nagios” but just appears to be some backend exposing an API. After fuzzing for a bit of time, not much progress is made. Only a /health and /version endpoint.
Fuzzing for virtual hosts is unsuccessful using some standard subdomain lists. However, using a custom wordlist from scraped words on the site did find a new vhost. Pointing skweez at the sales site and running that list through ffuf against vhosts gives us the host teamcity.runner.htb.
Updating /etc/hosts, we see that JetBrains TeamCity is hosted an exposed.
Foothold
A quick vulnerability lookup for version 2023.05.3 provides an unauthenticated administrator account creation with a known exploit [CVE-2023-42793]. After validating the script, we succesfully exploit the application and obtain administrative access.
We confirm the exploit worked and login as the new admin. We see two other users in the application (john & matthew).
Browsing the application, we note an empty project with no agents so looks like any remote code execution through a runner isn’t possible. We do, however, see that can browse the data directory and even back it up. We first discover an SSH key.
We’ll try that in a second, but while we’re here, we also back up the site and download the zip.
We grab some user hashes from the database dump and throw them into john. After a few minutes, we crack the hash for matthew.
User Flag
Attempting to login via ssh as matthew:piper123 is unsuccessful. However, the ssh key used for authentication on TeamCity also works against the host system as user john.
We grab the user.txt flag.
Privilege Escalation
Once on the host, we check our groups and other potential privileges, but nothing stands out. During the internal enumeration, we notice that nginx to proxy requests for portainer-administration.
We add portainer-administration.runner.htb to our hosts file and attempt to login as matthew:piper123 and the credentials work.
Browsing the app, we try to make a container with a binded volume and maybe get root access to the file system. However, looks like the standard portainer ways of doing that are non-existent. However, with our access to the system as john, we note that runc is version 1.1.7.
Root Flag
This version is vulnerable to Leaky Vessels. We go and create a new image and provide the following payload in an attempt to access the root file system.
Building the image gives us the flag.
If we wanted full system access, we could write a rev shell cron job or something similar as we now have read/write as root on the local file system.