IOLI 0x06

nearly a routine to check this binary (not complete output in the following):

rabin2 -z ./crackme0x06

[Strings]

nth paddr      vaddr      len size section type  string

―――――――――――――――――――――――――――――――――――――――――――――――――――――――

0   0x00000738 0x08048738 4   5    .rodata ascii LOLO

1   0x00000740 0x08048740 13  14   .rodata ascii Password OK!\n

2   0x0000074e 0x0804874e 20  21   .rodata ascii Password Incorrect!\n

3   0x00000763 0x08048763 24  25   .rodata ascii IOLI Crackme Level 0x06\n

4   0x0000077c 0x0804877c 10  11   .rodata ascii Password:


rabin2 -I ./crackme0x06

arch     x86

baddr    0x8048000

bintype  elf

bits     32

compiler GCC: (GNU) 3.4.6 (Gentoo 3.4.6-r2, ssp-3.4.6-1.0, pie-8.7.10)

crypto   false

endian   little

havecode true

lang     c

machine  Intel 80386

maxopsz  16

minopsz  1

os       linux

static   false

va       true

and analyze it then decompile main

[0x08048400]> pdd@main

/* r2dec pseudo code output */

/* ./crackme0x06 @ 0x8048607 */

#include 


int32_t main (int32_t arg_10h) {

int32_t var_78h;

int32_t var_4h;

// adjusting stack

eax = 0;

eax += 0xf;

eax += 0xf;

eax >>= 4;

eax <<= 4;


// main logic

printf ("IOLI Crackme Level 0x06\n");

printf ("Password: ");

eax = &var_78h;

scanf (0x8048787, eax);

eax = arg_10h;

eax = &var_78h;

check (eax, arg_10h);

eax = 0;

return eax;

}

main has 3 arguments argc, argv, envp, and this program is compiled with GCC, so the stack should be like this :

[esp + 0x10] - envp

[esp + 0x0c] - argv

[esp + 0x08] - argc

[esp + 0x04] - return address

enter the check() and decompile it. this function is different from 0x05 now. but they still have similar code structure.

int32_t check (char * s, int32_t arg_ch) {

char * var_dh;

uint32_t var_ch;

uint32_t var_8h;

int32_t var_4h;

char * format;

int32_t var_sp_8h;

var_8h = 0;

var_ch = 0;

do {

eax = s;

eax = strlen (eax);

if (var_ch >= eax) {

goto label_0;

}

eax = var_ch;

eax += s;

eax = *(eax);

var_dh = al;

eax = &var_4h;

eax = &var_dh;

sscanf (eax, eax, 0x804873d);

edx = var_4h;

eax = &var_8h;

*(eax) += edx;

if (var_8h == 0x10) {

eax = arg_ch;

eax = s;

parell (eax, arg_ch);

}

eax = &var_ch;

*(eax)++;

} while (1);

label_0:

printf ("Password Incorrect!\n");

return eax;

}

Correct the sscanf part and parell part, both of them were generated incorrectly:

int32_t check (char * s, void* envp)

{

var_ch = 0;

var_8h = 0;

for (var_ch = 0; var_ch < strlen(s); ++var_ch)

{

var_dh = s[var_ch];

sscanf(&var_dh, %d, &var_4h);
// read from string[var_ch], store to var_4h

var_8h += var_4h;

if(var_8h == 0x10)

parell(s, envp);

}

printf("Password Incorrect!\n");

return 0;

}

no more info, we have to reverse parell() again.

#include 


uint32_t parell (char * s, char * arg_ch) {

sscanf (s, %d, &var_4h);


if (dummy (var_4h, arg_ch) == 0)

return 0;


for (var_bp_8h = 0; var_bp_8h <= 9; ++var_bp_8h){

if (var_4h & 1 == 0){

printf("Password OK!\n");

exit(0);

}

}


return 0;

}

well, there is a new check condition in parell() -- dummy (var_4h, arg_ch) == 0. then reverse dummy!

[0x080484b4]> pdd@sym.dummy

/* r2dec pseudo code output */

/* ./crackme0x06 @ 0x80484b4 */

#include 


int32_t dummy (char ** s1) {

int32_t var_8h;

int32_t var_4h;

char * s2;

size_t * n;

var_4h = 0;

do {

eax = 0;

edx = eax*4;

eax = s1;

if (*((edx + eax)) == 0) {

goto label_0;

}

eax = var_4h;

ecx = eax*4;

edx = s1;

eax = &var_4h;

*(eax)++;

eax = *((ecx + edx));

eax = strncmp (eax, 3, "LOLO");

} while (eax != 0);

var_8h = 1;

goto label_1;

label_0:

var_8h = 0;

label_1:

eax = 0;

return eax;

}

looks like a loop to process string. we can beautify it.

[0x080484b4]> pdd@sym.dummy

/* r2dec pseudo code output */

/* ./crackme0x06 @ 0x80484b4 */

#include 


int32_t dummy (char ** s1) {

for (var_4h = 0; strncmp(s1[var_4h], "LOLO", 3) != 0; var_4h++){

if (s1[i] == NULL)

return 0;

}

return 1;

}

There are 3 constraints to crackme_0x06:

• Digit Sum

• Odd Number

• should have an environment variable whose name started with "LOL".

$ ./crackme0x06

IOLI Crackme Level 0x06

Password: 12346

Password Incorrect!

$ export LOLAA=help

$ ./cracke0x06

IOLI Crackme Level 0x06

Password: 12346

Password OK!

Загрузка...