💾 Archived View for radare.org › book › crackmes › ioli › ioli_0x06.gmi captured on 2023-11-04 at 12:00:17. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
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 <stdint.h> 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 <stdint.h> 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 <stdint.h> 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 <stdint.h> 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!