
Shellshock
Shellshock
Veuillez télécharger les fichiers docker-compose.yml et poc.py Installez impérativement la bibliothèque requests via pip install requests !!! Si vous utilisez uv, veuillez placer la bibliothèque requests dans le venv via uv !!!
| Description officielle du CVE |
|---|
| Dans les versions de GNU Bash antérieures à 4.3, il existait un problème de traitement des chaînes de caractères placées après une définition de fonction dans les valeurs des variables d'environnement. En exploitant cette vulnérabilité, un attaquant distant pouvait exécuter du code arbitraire via un environnement falsifié. Cette vulnérabilité a été constatée dans la fonctionnalité ForceCommand d'OpenSSH sshd, dans les modules mod_cgi et mod_cgid du serveur Apache HTTP, dans des scripts exécutés par des clients DHCP non spécifiés, ainsi que dans plusieurs situations où l'exécution de Bash et la définition des variables d'environnement s'effectuent à travers des frontières de privilèges différentes. Elle est également connue sous le nom de « ShellShock ». Remarque : le correctif initial apporté à ce problème était erroné, et le CVE-2014-7169 a été attribué pour résoudre cette vulnérabilité, qui subsistait encore après ce correctif incorrect. |

| Configuration de l'environnement |
|---|
Configuration du fichier Docker
| os | serveur web | version de bash |
|---|---|---|
| Debian 10 | Apach | 4.2.37(1) |

Rédaction d'un Dockerfile permettant de maintenir le serveur Web actif lors de l'exécution de la commande docker compose up
Comme l'OS, Apache, etc. du Dockerfile proviennent tous de dépôts externes, nous avons taggé l'image construite puis l'avons poussée sur Docker Hub, puis avons référencé cette image dans le fichier docker-compose.yml afin qu'aucun problème ne survienne même si les sources d'origine sont supprimées.

| Conditions de vulnérabilité |
|---|
Un shell Bash présentant la vulnérabilité Shellshock est requis. Pour ma part, j'ai téléchargé et utilisé la version 4.2.37(1) du shell Bash.

De plus, le code n'étant exécuté qu'après avoir été enregistré dans une variable d'environnement puis après l'appel de bash, un programme capable d'invoquer bash doit exister. J'ai téléchargé le programme CGI que le serveur Web utilisait pour traiter les requêtes des clients. Selon la spécification CGI (RFC 3875), le serveur Web est conçu pour placer toutes les informations d'en-tête envoyées par le navigateur dans les variables d'environnement Linux afin de les traiter.
Dans ces conditions, le serveur Web envoie une requête et les informations d'en-tête sont stockées dans les variables d'environnement (selon la spécification CGI). L'attaque est complète lorsque le CGI appelle le shell Bash, qui présente la vulnérabilité d'exécution des chaînes placées après une définition de fonction dans les variables d'environnement.
Requête (envoi avec du code intégré dans l'en-tête User-Agent) -> le CGI appelle bash -> connexion du shell inversé
| Procédure de reproduction |
|---|

| Résultat obtenu |
|---|
Le terminal qui était en écoute à l'étape 2 de la procédure de reproduction est connecté au shell Bash du conteneur et permet d'exécuter des commandes telles que whoami, id, etc.

| Cause de la vulnérabilité |
|---|
'''
if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))
{
string_length = strlen (string);
temp_string = (char *)xmalloc (3 + string_length + char_index);
strcpy (temp_string, name);
temp_string[char_index] = ' ';
strcpy (temp_string + char_index + 1, string);
parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);
// 이하 생략
'''
La cause de la vulnérabilité se trouve dans la fonction initialize_shell_variables, au sein du code variables.c du shell Bash. Cette fonction étant elle-même trop longue, je n'en ai gardé que la partie essentielle.
'''
if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))
'''
La condition if ci-dessus vérifie, via STREQN ("() {", string, 4), si les 4 premiers caractères sont "() {". Si c'est le cas, la chaîne est traitée comme une fonction. Étonnamment, aucun filtrage n'est appliqué à string après cette vérification, d'où le problème.
'''
strcpy (temp_string, name);
temp_string[char_index] = ' ';
strcpy (temp_string + char_index + 1, string);
''' Le code ci-dessus est le processus de concaténation du nom et de la valeur. Comme il s'agit de la valeur vérifiée précédemment, string commence par () { et name est le nom de la variable d'environnement.
Le nom et la valeur de la variable d'environnement sont ainsi combinés puis transmis au code ci-dessous pour être analysés. Comme le seul filtre était la vérification de () { ci-dessus, toutes les commandes ajoutées après la fonction, telles que whoami, id, pwd, etc., sont exécutées.
'''
parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);
'''
| Mesures correctives |
|---|
| Mettre à niveau Bash vers une version non affectée par la vulnérabilité Shellshock. |
| Ne pas utiliser de programmes qui invoquent le shell Bash. |