Express
Difficulty: Medium
Recon
1. Empezamos haciendo un reconocimiento de red para identificar el host de la máquina víctima:
sudo nmap -sn 192.168.56.0/24
Host identificados:
192.168.56.1
192.168.56.100
192.168.56.103 (objetivo)
192.168.56.101 (nuestra Kali atacante)
Vamos a realizar una enumeración de puertos sobre el objetivo para identificar que servicios está ejecutando, probar scripts contra ellos, etc:

Puertos identificados:
22/tcp
80/tcp
El puerto 80 abierto indica que se está ejecutando un servicio web, así que vamos a probar acceder a la IP del objetivo desde el navegador:

Nos aparece por defecto la página del servidor web que se está ejecutando, que en este caso es Apache 2.
Vamos a añadir el dominio de la máquina, que en este caso sería express.nyx al archivo /etc/hosts, apuntando a la IP que hemos identificado, para ver si accediendo desde el dominio vemos algo diferente en el navegador:


Un paso aconsejable siempre que nos encontramos con una web y no sabemos por donde tirar es hacer lo siguiente:
Entramos en las herramientas del navegador y nos vamos a la pestaña Network:

b. Recargamos la página a ver si carga algún archivo o algo que nos pueda interesar:

En este caso carga 2 archivos que podrían ser interesantes: script.js y api.js.
c. Hacemos doble click sobre api.js y se nos abre en el navegador:

Vemos que las funciones apuntan a diferentes endpoints que pueden resultarnos útiles para la explotación de la máquina.
JavaScript API Disclosure
En el caso de los endpoints de canciones, no se utiliza ningún parámetro, se hace directamente un get, pero en el caso de los usuarios si que vemos que se utiliza el parámetro key. Otro interesante es /api/admin/availability.
Vamos a BurpSuite y hacemos un Intercept de una solicitud a /api/music/list para enviarla al Repeater y trabajar con ella:


Esta request GET nos devuelve un listado de géneros musicales, probamos con songs:

Vamos a probar con el otro endpoint que es users, pero sin poner ninguna key, ya que no tenemos ninguna, a ver que mensaje nos devuelve:

En este punto, el siguiente paso teóricamente sería probar fuzzear las keys de usuario, pero no tenemos ninguna de referencia para hacerlo, podrían ser desde un ID a una key de múltiples números. A veces no hay que buscar complicarlo tanto.
Cambiamos el método GET de la request a POST:

Y eso es, nos devuelve un JSON con:
id de usuario
rol del usuario
token del usuario
nombre de usuario
Cómo podemos ver los roles de usuario, vamos a buscar un usuario admin:

Probamos a poner su key en el parámetro de /api/users?key${secretKey}:

Pero nos da un 400 Bad Request...parece que no es por donde tenemos que seguir.
Entre las funciones de api.js también había una que hacía un POST al endpoint /api/admin/availability, vamos a probar desde Burp:

Nos da un error por el Media Type, ya que sólo admite request en formato JSON.
Modificaremos nuestra request añadiendo los siguientes valores:

Por la URL nos da un url_status: “unreachable” ya que la máquina no tiene salida a internet en este caso.
Vamos a realizar otra comprobación, esta vez levantaremos en la máquina atacante un servidor web y apuntaremos el valor URL de la request hacía él:


En este caso nos da un success y active porque puede llegar hasta la URL. Con esto confirmamos que se trata de un SSRF.
Explotación
La primera opción, cómo cuando empezamos con un pentest y reconociendo un objetivo, es enumerar los puertos.
Creamos una lista con los números de puertos que queremos escanear:

Después utilizaremos fuff para fuzzear los puertos, utilizando el id, la URL local y el token del admin:

Nos aparece mucho ruido así que vamos a afinar más eliminando los que en Words den un 36:

Se vuelven a identificar los puertos que ya conociamos (22 y 80) y además otros 3:
5000
9000
55854
Probamos con las request de Burpsuite sobre los nuevos puertos descubiertos:
5000

9000

55854

El único que nos da un success y active es el 9000, además podemos observar que hay un formulario para hacer un submit de un nombre de usuario.
Vamos a probar a enviar por URL el nombre de un usuario random a ver que nos responde:


Vemos que reconoce lo que le pasamos por el parámetro, probaremos si es SSTI:
Para ello utilizamos las siguientes fórmulas:
Habrá que tener en cuenta esta teoría:

Empezamos con la primera fórmula:

No la ejecuta, así que siguiendo el esquema, hay que probar la fórmula de abajo del gráfico:

Esta si que funciona, por lo que según el esquema es Jinja2 o Twig, dependiendo del resultado de la siguiente fórmula:
Si nos sale 7777777 significa que es Jinja2.
Si nos sale 49 significa que es Twig.

Confirmamos que es Jinja2.
Con el siguiente payload comprobaremos que usuario somos:
Escalada de privilegios
Pondremos una consola a la escucha en nuestra máquina atacante:

Enviaremos una reverse shell con busybox desde la request de Burp en el Repeater:

Recibimos la conexión en el terminal a la escucha y ejecutamos comandos:

Somos root en el sistema objetivo, ahora vamos a buscar las flags:


Última actualización