Express
Last updated
Last updated
Muy buenas y bienvenidos a la resolución de la máquina Express de VulNyx, esta es otra de las máquinas que hago para la plataforma de VulNyx, en este caso es una máquina que os será muy útil para entender varias técnicas de hacking web, recomiendo mucho esta máquina para los que quieran presentarse al CBBH.
A continuación veremos las técnicas que nos encontraremos, vamos a poner todas las que hay, como si fuera un pentest:
Information Disclosure - JavaScript File exposed
HTTP Verb Tempering - API token disclosure
Server-Side Request Forgery - Parameter url
Enumerating internal ports
Server-Side Template Injection - Internal Server SSTI parameter name - Remote Code Execution
De primeras tenemos la IP de la máquina en el dashboard de la propia cuando la arrancamos:
Pero si no fuera el caso, se puede enumerar la red para ver cual sería, con herramientas como fping, arp-scan o el propio nmap.
Una vez ya tenemos la IP, hacemos un escaneo nmap rápido:
Por metodología y al ser VulNyx, antes de incluso entrar a el servidor web, vamos a poner express.nyx
y entramos primero con la IP y después con el dominio a ver si cambia algo la página.
De primera con la IP nos aparece el Apache básico:
Si entramos a express.nyx nos aparece otra página totalmente distinta:
Al ser el creador de la página voy a ir directo al grano y no perder el tiempo con cosas que no tienen sentido hacer, es decir, me voy a centrar en explicar cada detalle mínimo que es lo que puedo diferenciar de otro writeup.
De acuerdo, te has encontrado que la página no tiene subdominios, ni vhost, ni algo que sacar en el código fuente o haciendo fuzzing... la cosa es que quiero que cogáis como metodología entrar en la web, abrir las DevTools (F12) > Network y que hagáis un F5 para ver que carga la web, muchas veces vais a encontrar cositas interesantes y es una parte importante que hacer si haces hacking web.
Vamos a hacerlo a ver que encontramos...
Como vemos en la imagen de arriba, hay un archivo JavaScript que parece que procesa una API? vamos a entrar al archivo a ver que hay dentro...
El archivo api.js esta mostrando endpoints API que parece que procesan datos, son los siguientes:
/api/music/list
No tiene ningún parámetro, se hace la petición con GET
/api/music/songs
No tiene ningún parámetro, se hace la petición con GET
/api/users
Tiene un parámetro GET llamado key
/api/admin/availability
Tiene 3 parámetros, se hace la petición con POST
id
url
token
Tras haber analizado el como funciona la página (así es como suelo tomar las notas cuando me enfrento a lectura de código) ahora podemos hacer algo con ella, empezamos por la primera API y ya vamos bajando, aunque más o menos cual es la más interesante (/api/admin/availability) aunque tiene un parámetro token, seguramente está restringida la llamada con cierto token especifico.
Empezamos llamado a la /api/music/list a ver que aparece:
Duplicamos la web y llamamos a la api, seguidamente capturamos con BurpSuite para trabajar más cómodos.
Y lo mandamos al Repeater
Simplemente se listan en json tipos de lista de música.
Con songs vemos que muestra canciones en formato json
Cuando llamamos a /api/users nos aparece otro mensaje
Recordamos que habia un parámetro GET llamado key, vamos a poner a ver que nos dice de diferente
Nos sigue apareciendo que "Unauthorized, wrong key!" eso quiere decir que para listar los usuarios es necesario una key especifica.
Y ahora te quedas... se tiene que hacer un fuzzing para buscar una key? Pero si no tenemos ninguna de ejemplo para saber los caracteres, longitud... tranquil@ porque no va por ahí.... antes de hacer fuzzing y te encuentras con una restricción al realizar una petición
¿Has pensado en que otra opción tienes?
HTTP VERB TEMPERING
Siempre antes de nada, juega con los metodos de petición a ver si sucede algo diferente, porque muchas veces un programador puede equivocarse y meter una restricción con una key o algo parecido para poder realizar la petición pero solo lo asigna para un metodo en vez de para cualquier petición, así que... y si ponemos POST en vez de GET?
¡Vaya! Ahora tenemos todos los usuarios y vemos que hay un tal parámetro token, que nos servirá para el siguiente endpoint API.
La cosa es que cualquier token no nos servirá... tenemos que buscar un token que tenga permisos elevados (admin), buscamos bien Y...
Tenemos a la poderosa Bug Bounty Hunter JESSS que es administradora del sistema...
Cogemos su token y nos vamos a la siguiente API.
Cuando intentamos de primeras hacer la llamada con los 3 parámetros a la API nos comenta que tiene que ser json
Tiene que ser una llamada tipo así:
Cuando mandamos la petición nos da el siguiente resultado:
Nos pone que al comprobar la URL esta a sido exitosa y está activa, que sucede si no lo esta o si pongo un token erroneo?
De primeras si pones un token inválido:
Y si pones una URL erronea:
Aquí es cuando entra la vulnerabilidad SSRF, sabiendo que el parámetro URL comprueba URLs, que sucede si nosotros ponemos un listener esperando una petición y ahora la URL la apuntamos a nosotros?
Recibimos la petición, eso quiere decir que el parámetro es vulnerable a SSRF, ahora nos preguntamos... que podemos hacer?
Pues hay varias opciones, pero la primera que nos tiene que venir a la mente es realizar un escaneo de puertos internamente de la máquina Express, para ver si hay otro servidor interno corriendo, esto lo haremos con la herramienta ffuf, pero se puede hacer con varias.
Antes de ejecutar el ffuf, tenemos que crear con seq un listado de puertos, haremos del 1 al 10000:
Vemos que se ha creado, esta llegará hasta el 10000.
Después ejecutaremos el siguiente comando:
Cuando ejecutamos nos aparece el tipico size, en este caso tenemos que quitar el de words con el comando -fw 36
Encontramos 2 puertos que no sabiamos de su existencia 5000 y 9000.
Os digo ya que el 5000 es el que está corriendo las APIs así que ese ya podemos acceder mediante el 80 porque, internamente realice un proxy para poder hacer las peticiones a través del 80, el importante es el 9000.
Llamamos al http://127.0.0.1:9000 mediante el parámetro URL a ver que nos muestra:
Si limpiamos bien lo que nos aparece en el response_data, vemos que es simplemente una servidor web que se realiza la petición con GET a la ruta /username con el parámetro name.
Es decir que sería algo así:
Veamos que pasa si lo ponemos de la manera de arriba:
Y dirás que vulnerabilidad habrá en este campo?
Aquí es cuando entra el SSTI que es una vulnerabilidad que se comprueba aplicando formulas matemáticas para saber si el campo es vulnerable o no, para ello vamos a utilizar mi checklist para ver si lo es o no.
Como veis bien arriba, tenemos payloads básicos que vamos a utilizar y después metodología para detectar el framework utilizado por detrás.
Empecemos con más avanzado... {{7*7}}
Se ve perfectamente que esta la detecta saliendo un 49. Siguiendo la metodología que enseñe anteriormente:
Si nos responde con un 49 significa que es vulnerable, ya que reconoció la expresión.
Si ponemos {{7*'7'}}
para detectar si es Jinja2 o Twig
Ponemos el {{7*'7'}}
para saber si es Jinja2 o Twig, así podemos coger payloads especificos del framework correcto.
Utilizamos el siguiente payload para conseguir ejecutar comandos remotamente:
Somos root
Utilizamos la busybox para mandarnos una revshell
La recibimos!
Aquí acaba el writeup de la máquina Express, espero que la hayáis disfrutado y sobretodo hayáis aprendido mucho que siempre es mi intención. Al final intento enseñar aquí mi metodología a la hora de enfrentarme a una web, que aun me queda mucho por aprender.
Chao