Simultanément avait aussi lieu le Padocon qui lui aussi semblait vraiment simpa bien que d'un niveau bien hard ;-) .
Bref , concentrons-nous sur le sujet de ce billet , a savoir : le Bin01 du CTF "Security By Default".
La premiere chose que l'on remarque dessuite via l'utilitaire "file" : ce binaire est du type elf32 , non stippé .
Ainsi j'ai pu facilement commencer dans un premier temp une rapide analyse a l'aide d'Hexrays afin de réaliser un arbre des appels de fonctions ainsi que des dumps ASM puis C pour bien cerner la bête et voir comment agir.
(Les parties du code ne nous intérréssant pas on bien sur été supprimées)
...
mov edx, offset format ; "\n--- Welcome to '%s' systems.\n"
mov [esp+4], eax
mov [esp], edx ; format
call _printf
lea eax, [esp+6Bh]
mov [esp], eax
call tor
mov edx, offset aS ; "%s"
mov [esp+4], eax
mov [esp], edx ; format
call _printf
mov eax, ds:stdin@@GLIBC_2_0
mov [esp], eax ; stream
call _fflush
lea eax, [esp+1894h]
mov [esp], eax ; s
call _gets
lea eax, [esp+58h]
mov [esp], eax
call tor
mov edx, offset aS ; "%s"
mov [esp+4], eax
mov [esp], edx ; format
call _printf
mov eax, ds:stdin@@GLIBC_2_0
mov [esp], eax ; stream
call _fflush
lea eax, [esp+10C4h]
mov [esp], eax ; s
call _gets
lea eax, [esp+4Bh]
mov [esp], eax
call tor
mov edx, offset aS ; "%s"
mov [esp+4], eax
mov [esp], edx ; format
call _printf
mov eax, ds:stdin@@GLIBC_2_0
mov [esp], eax ; stream
call _fflush
mov eax, [esp+2068h]
mov [esp], eax ; s
call _gets
lea eax, [esp+39h]
mov [esp], eax
call tor
mov edx, offset aS ; "%s"
mov [esp+4], eax
mov [esp], edx ; format
call _printf
mov eax, ds:stdin@@GLIBC_2_0
mov [esp], eax ; stream
call _fflush
lea eax, [esp+8F4h]
mov [esp], eax ; s
call _gets
lea eax, [esp+1Bh]
mov [esp], eax ; s
call untrash
lea eax, [esp+1Bh]
mov [esp], eax
call tor
mov edx, offset aS ; "%s"
mov [esp+4], eax
mov [esp], edx ; format
call _printf
mov eax, ds:stdin@@GLIBC_2_0
mov [esp], eax ; stream
call _fflush
lea eax, [esp+124h]
mov [esp], eax ; s
call _gets
mov dword ptr [esp+2064h],
jmp short loc_8048A47
; ---------------------------------------------------------------------------
loc_8048A0D:
mov eax, [esp+206Ch]
mov eax, [eax]
cmp eax, [esp+2064h]
jnz short loc_8048A3F
lea eax, [esp+9Bh]
mov [esp], eax
call tor
mov edx, offset aAlertS ; "ALERT: %s\n"
mov [esp+4], eax
mov [esp], edx ; format
call _printf
loc_8048A3F:
add dword ptr [esp+2064h], 1
loc_8048A47:
cmp dword ptr [esp+2064h], 9
jle short loc_8048A0D
mov eax, [esp+206Ch]
mov eax, [eax]
test eax, eax
jz short loc_8048AA9
lea eax, [esp+0B0h]
mov [esp], eax ; s
call untrash
lea eax, [esp+0B0h]
mov [esp], eax
call tor
mov ebx, eax
lea eax, [esp+0F9h]
mov [esp], eax
call tor
mov edx, offset aSS ; "%s %s\n"
mov [esp+8], ebx
mov [esp+4], eax
mov [esp], edx ; format
call _printf
mov eax, 0
jmp short loc_8048AF0
; ---------------------------------------------------------------------------
loc_8048AA9:
mov dword ptr [esp+4], offset s2 ; "admin_r00t"
lea eax, [esp+124h]
mov [esp], eax ; s1
call _strcmp
test eax, eax
jnz short loc_8048AEB
lea eax, [esp+112h]
mov [esp], eax
call tor
mov edx, offset aS_0 ; "%s :)\n"
mov [esp+4], eax
mov [esp], edx ; format
call _printf
mov eax, 45h
jmp short loc_8048AF0
; ---------------------------------------------------------------------------
loc_8048AEB:
mov eax, 45h
loc_8048AF0:
add esp, 2074h
pop ebx
pop esi
pop edi
mov esp, ebp
pop ebp
retn
main endp
; ---------------------------------------------------------------------------
...
...
Dans cet extrait du code assembleur , ces fonctions semblent etre celles qui nous intéressent , a partir de la on réalise un désassemblage qui donne :
J'ai ensuite étudié l'algo un peu plus en profondeur via un dump C d'Hexrays qui s'avéra trés instructif quand au fonctionnement ducrackme.
...
printf("\n--- Welcome to '%s' systems.\n", v0);
v1 = tor(&v34);
printf("%s", v1);
fflush(stdin);
gets(&v70);
v2 = tor(&v28);
printf("%s", v2);
fflush(stdin);
gets(&v69);
v3 = tor(&v24);
printf("%s", v3);
fflush(stdin);
gets((char *)v72);
v4 = tor(&v19);
printf("%s", v4);
fflush(stdin);
gets(&v68);
untrash((const char *)&v11);
v5 = tor(&v11);
printf("%s", v5);
fflush(stdin);
gets(&v67);
for ( i = -5; i <= 9; ++i )
{
if ( *(_DWORD *)v73 == i )
{
v6 = tor(&v47);
printf("ALERT: %s\n", v6);
}
}
if ( *(_DWORD *)v73 )
{
untrash(&v53);
v8 = tor((int *)&v53);
v9 = tor(&v55);
printf("%s %s\n", v9, v8);
result = 0;
}
else
{
if ( strcmp(&v67, "admin_r00t") )
{
result = 69;
}
else
{
v10 = tor(&v62);
printf("%s :)\n", v10);
result = 69;
}
}
return result;
...
Voila , nous somme au coeur du problème a présent, j'me suis donc dit que j'allais travailler ça de façon a patcher le binaire pour luifaire cracher son flag et ne plus avoir d'outputs frustrants comme les :
ALERT: You are not welcome.
ou encore
It's not so easy Dude ! (aprés patching de plusieurs sauts conditionels/call par exemple).
Le but recherché étant d'obtenir le flag de validation , j'ai fait ça de façon rapide mais absolument pas esthétique , puristes s'abstenir !
Pour y parvenir il ne me resta plus qu'a rechercher certaines fonctions (dont celle qui construisent et donne le précieux sésame) puis a patcher afin de jumper au bon endroit.
Voici quelques une des modifs ainsi effectuées :
Parti de cette instruction jmp loc_8048a47 , on jump en 0x8048a47 et on apporte les modifs adéquates.
La capture suivante propose 2 vues a savoir a gauche le binaire dans sa version originale , a droite sa version patchée .
La chaine contenue dans strz__s__s__8048bed se trouvait donc etre "admin_r00t %s %s\n\0" :-^ .
Voila , restait alors qu'a chopper le flag et a valider :
sh-3.2$ ./copie\ de\ n00b-login
--- Welcome to 'Epicness Security' systems.
Insert name: kmkz
Insert last name: sec0d
Insert sex: Faible(:P)
Inserd birthday: 1337
Insert passwd: pawned!
Damn it! SYSTEM FAILURE: iTSeeMsThaTWeAreNotEpicnessAtAlL
1 commentaire:
c'toi le poil, escroc
Enregistrer un commentaire