Description
Écrire un programme qui envoie le message correct et corriger le programme d'origine pour supprimer l'échange d'octets.
Analyse avec IDA
À l'exécution, le programme semble attendre indéfiniment. En le chargeant dans IDA, on voit qu'il attend un message via une file de messages POSIX :
mq_open("/my_queue", 64LL, a3);
mq_receive(v4, s1, 256LL, 0LL);
Plus loin, la variable s1 — qui reçoit le message — est utilisée
dans un strcmp. Le programme attend donc un mot de passe :
if ( !strcmp(s1, "passw0rd_admin") )
printf("The flag is : %s\n", aLrctfIpcMessag);
Le mot de passe passw0rd_admin est stocké en clair dans le binaire. Le flag est dans la variable aLrctfIpcMessag.
Solution — envoi IPC
On écrit un programme qui envoie le mot de passe via mq_send :
Le programme du challenge reçoit bien le message :
Problème : le message est modifié avant le test. Une fonction appelée juste
avant le strcmp altère deux octets :
*(BYTE *)(a1 + 2) = -1;
result = a1 + 7;
*(BYTE *)(a1 + 7) = -95;
return result;
Patch avec Radare2
Il faut transformer l'appel de cette fonction en un saut vers l'instruction
suivante. On localise l'adresse du call dans IDA :
Le call se trouve en 0x131E. On utilise Radare2 pour patcher :
Commande Radare2
wx eb03 @ 0x131E
wx— écriture d'octets brutseb— opcode JMP court03— offset : saute 3 octets (taille du CALL remplacé)@ 0x131E— adresse cible
Après patch, le binaire ne modifie plus notre mot de passe avant le test. On renvoie le message et le flag s'affiche :
LRCTF{**********}