Il s'agit d'une vulnérabilité logicielle présente dans le shell Unix bash. Ce logiciel est responsable de l’exécution de programmes, que ce soit des programmes lancés par des utilisateurs que d’autres programmes, et est souvent utilisé par les serveurs web pour lancer des sous-programmes responsables de la génération des pages. Cette faille touche l’environnement, un ensemble de données transmises de programme en programme, qui contient des informations utiles pour l’exécution de ces derniers. Dans le cas d’un serveur web, il est utilisé pour transmettre toutes les informations sur une requête (quelle page demande l’utilisateur, quel navigateur il utilise, de quelle page il vient, …) au programme suivant. Le problème est une fonctionnalité ajoutée à bash il y a longtemps (en 1989) qui permet d’utiliser l’environnement pour passer des fonctions, des morceaux de code qui peuvent être utilisées par le shell pour exécuter certaines tâches. Cette fonctionnalité peut se révéler utile et n’est pas vraiment le problème: dans le cas d’un serveur web, bash se contenterait de passer le code de la fonction au programme de génération de la page et ne jamais les utiliser. Mais voici le problème: si la fonction est écrite correctement, elle peut forcer bash à exécuter du code à son lancement, ce qui n’est pas souhaitable. Cela veut dire qu’une personne peut simplement demander une page et introduire un en-tête HTTP spécialement préparé, et lorsque bash va lire l’environnement contenant les données malicieuses, il va tenter de les exécuter. Et cela permet d’exécuter toutes sortes d’attaques.
Exploitation (POC)
Démo
d'une attaque Shellshock par injection d'entête HTTP :
Le test
démontré consiste à envoyer à un serveur web[1],
disponible sur le réseau, un paquet HTTP
forgé avec des entêtes HTTP contenant une injection de commande. Le serveur,
étant vulnérable contre ShellShock, va passer les valeurs des entêtes HTTP sous
forme de variables Bash et par conséquent les commandes incluses seront
exécutées de manière illicite.
Schéma global du réseau
Le réseau virtuel
privé mis en place tourne sous Virtualbox selon l’architecture suivante :
Les adresses
IP des deux machines ont été affectées par le serveur DHCP, propre à
l'adaptateur ethernet #2 avec le pool d’adresse 192.168.220.220-100/24.
Machine d'attaque :
Récolte
d’informations :
En réalisant
un mapping du réseau avec Nmap sur l’adresse 192.168.220.100/24 nous avons
découvert l’adresse 192.168.220.103 sur laquelle nous avons effectué un scan
plus approfondi.
Nous pouvons
constater les différents ports ouverts et les différentes versions de
services en vigueurs sur ces ports. On constate
également le déploiement d’interfaces de connexions administratives via SSH
d'une part, et un serveur Web qui tourne sur le port 80 d'autre part.
En tentant
d'y accéder au site web à travers un navigateur, on tombe sur la page suivante
:
Si on s'attarde sur le contenu de la page web, on verra bien
qu'elle inclut des informations sur le système (le serveur web en question). En
parcourant le code source de cette page, on s'aperçoit de la fonction appelé
par un script pour générer une telle sortie. Il s'agit de la fonction status()
qui est définit ainsi :
En fait,
cette fonction fait appel à un script CGI dont on a pu clairement obtenir le
chemin.
En indiquant
le chemin du script dans la barre d'adresse, on retrouve bien les informations
précédentes sur le système ainsi :
A présent,
nous allons actualiser la page tout en interceptant la requête de chargement de
la page avec le proxy Burp afin d'y
injecter notre code malicieux dans l'en-tête HTTP. Plus précisément, nous
allons modifier la valeur du champ 'User Agent' de l'en-tête HTTP comme suit :
On modifie
cette valeur par le code suivant afin de tester si le serveur est vulnérable
contre ShellShock :
A priori, il
s'agit d'un code plus ou moins bénin qui va afficher la chaine de caractère
précisée, dans la page retournée, ainsi
:
En effet,
notre code a été interprété par Bash et a été correctement exécuté, ce qui
affirme l'existence de la faille ShellShock dans le serveur web en question.
Encore plus
critique, nous allons tenter de charger le fichier /etc/passwd depuis le
serveur :
Le résultat est le suivant :
Désormais, la gravité de la faille commence à prendre de
l'ampleur étant donné qu'on a pu charger le fichier des mots de passes des
utilisateurs depuis le serveur.
Pour finir, nous allons tenter de maintenir un reverse shell
sur le serveur en ouvrant un port sur notre machine et en tenant de s'y
connecter depuis le serveur afin qu'on puisse obtenir un shell dessus.
A titre d'exemple, on ouvre le port 31337 sur notre machine
comme suit :
Ensuite, on injecte le code malicieux suivant permettant le
back connect :
On voie clairement notre adresse IP incluse dans le code
injecté dans la figure précédente.
A présent, si on revient vers notre terminal (là où netcat
écoute sur le port 31337),
On pourra suivre l'établissement de la connexion étant donné
que le mode verbose (option -v) a bien été précisée.
Une fois connecté, on pourra exécuter des commandes à distance
ainsi :
Ce qui reflète d'ailleurs toute la criticité de de cette
vulnérabilité.
Sachez que l'exploitation de cette vulnérabilité pourrait se
faire automatiquement de manière très rapide en utilisant le framwork
Metasploit et l'exploit exploit/multi/http/apache_mod_cgi_bash_env_exec.
Il suffira d'indiquer uniquement l'adresse IP du serveur web ainsi que le lien
vers le script CGI. L'obtention d'un shell se fait aisément en utilisant la payload "linux/x86/meterpreter/reverse_tcp" de metasploit.