Rusty_rev
Dernière mise à jour
Cet article vous a-t-il Γ©tΓ© utile ?
Dernière mise à jour
Cet article vous a-t-il Γ©tΓ© utile ?
Flag: HACKDAY{D0N7_637_rU57Y}
Ce challenge est un premier programme, appelΓ© loader, qui charge en mΓ©moire un second puis l'exΓ©cute.
Si l'on regarde oΓΉ est utilisΓ©e cette fonction, on dΓ©couvre un appel Γ la fonction write
est fait juste après sur le fichier créé :
On va lancer le binaire avec GDB et break Γ ce niveau-lΓ pour voir ce qui est Γ©crit :
Une fois arrivΓ© au breakpoint, on voit que ce que l'on Γ©crit dans le fichier anonyme commence par ELF. C'est lΓ que l'on comprend que c'est un loader qui charge notre vrai programme en mΓ©moire. On va donc dump
celui-ci, pour ça on utilise l'adresse affichée dans le paramètre buf
et la taille affichΓ©e dans nbytes
.
La commande dump
utilise une adresse de dΓ©but et une adresse de fin, il faut donc additionner la taille Γ l'adresse de dΓ©but pour obtenir l'adresse de fin, 0x7ffff7c71010 + 0x5f9c0 = 0x7ffff7cd09d0
:
Maintenant, je passe sur IDA pour le binaire qu'on vient d'extraire. La dΓ©compilation est plus explicite et visuelle pour le WriteUp.
En lanΓ§ant le programme, on nous affiche la phrase Please input your password
. On commence donc par chercher la string password
pour savoir oΓΉ nous sommes dans le programme.
En regardant les refs Γ celle-ci, on arrive sur la fonction sub_8434
:
En regardant un peu Γ quoi correspondent les refs utilisΓ©es dans la fonction, on peut voir qu'en fonction de v55
, on place GG WP
, Wrong password
, Reboot computer
ou l'ASCII Art AmongUs
en mΓ©moire.
Il y a Γ©galement une ligne intΓ©ressante : on compare v79
Γ 23
et ensuite, on fait tout un tas de comparaisons avant d'Γ©crire GG WP
.
ApartΓ© concernant v55
, il s'agit du rΓ©sultat d'une fonction alΓ©atoire, on peut le voir facilement :
Pour attendre le if
qui nous intΓ©resse (celui en vert dans le screen prΓ©cΓ©dent) il ne faut pas que v55
soit Γ©gal Γ 1, 2, 3, ou 4. Donc, Γ chaque fois qu'on analysera dynamiquement le programme, on va le forcer Γ 5.
Toujours concernant l'analyse dynamique, on va devoir rebase notre IDA pour avoir les mΓͺmes adresses que sur notre GDB. Pour Γ§a, on commence par utiliser vmmap
dans gdb et on regarde le start du programme : 0x00555555554000
.
Maintenant, on va setup Γ§a dans IDA : Edit
> Segments
> Rebase program...
Parfait, on a les mΓͺmes adresses dans les deux, ce sera plus simple Γ suivre. Notre fonction sub_8434
est maintenant Γ l'adresse sub_55555555C434
.
Comme j'ai dit tout Γ l'heure, on va fixe notre variable v55
. Pour ça, on va break juste après l'appel à la fonction rand et changer la valeur. Le résultat est dans EAX, donc on change EAX (logique).
Maintenant, on va break sur la comparaison avec 23, c'est Γ l'adresse 0x55555555CE1F
En lanΓ§ant le programme avec le mot de passe "test", on voit que c'est rsp+40
qui est comparΓ© Γ 23 (0x17). Et la valeur dans rsp+40
est 4 :
On en déduit facilement que c'est la longueur de notre mot de passe, il faut donc qu'il fasse 23 caractères.
En continuant sur la comparaison qui nous intΓ©resse, on voit que :
rbx
est comparΓ© avec 0x5555555A1050
(valeur : A5E7F33F8DE1F5
)
rbx+7
est comparΓ© avec 0x5555555A1040
(valeur : 0FCA1B12650FE105220FCF1436E83C3A
)
De plus, avec notre mot de passe test, RBX contient une valeur sur 4 octets. Avec d'autres mots de passe et en breakant au mΓͺme endroit, on se rend compte que RBX contient notre mot de passe "chiffrΓ©".
Le chiffrement est fait caractère par caractère et la position du caractère compte également. On peut le voir assez facilement en faisant différentes tentatives :
Conclusion : il faut que le rΓ©sultat de notre mot de passe chiffrΓ© donne les deux valeurs qu'on a vues juste avant, c'est-Γ -dire : A5E7F33F8DE1F50FCA1B12650FE105220FCF1436E83C3A
.
Ce qu'on va faire, c'est tester tous les caractères à toutes les positions possibles et récupérer leur valeur chiffrée. On pourra ainsi comparer avec le résultat attendu pour voir les correspondances. En python, ça donne ce script :
On a un script Python GDB qui permet de lancer le programme et rΓ©cupΓ©rer le rΓ©sultat du chiffrement dans output.txt
, maintenant il nous faut un script pour tester tous les caractères :
Le rΓ©sultat :
Ici, j'utilise Ghidra pour dΓ©compiler le binaire. Dans la partie SymbolTree, on voit que la fonction memfd_create
est utilisΓ©e. Un petit tour sur pour voir qu'elle permet de crΓ©er un fichier anonyme en mΓ©moire et retourne son file descriptor.