Tutorial singkat kali ini akan membahas cara menyelesaikan soal crackme EyeCandyLOCKED. Tutorial ini akan menggunakan radare2 yang dilengkapi dengan plugin ghidra. Berikut ini adalah langkah-langkahnya:

Pertama, ekstrak terlebih dahulu arsip soal tersebut:

% tar xvf EyeCandyLOCKED.tar.gz

Setelah itu, kita periksa tipe crackme yang telah diekstrak:

% file EyeCandyLOCKED
EyeCandyLOCKED: ELF 64-bit LSB crackme, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=a2f07f96d62e5485980091b97aea74ddbe54648e, with debug_info, not stripped

Ternyata crackme tersebut adalah ELF 64-bit dan tidak di-strip. Selanjutnya gunakan radare2 dengan plugin ghidra (opsional) untuk melakukan disassembly terhadap crackme tersebut.

% r2 -A EyeCandyLOCKED
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Check for objc references
[x] Check for vtables
[x] Type matching analysis for all functions (aaft)
[x] Propagate noreturn information
[x] Use -AA or aaaa to perform additional experimental analysis.
[0x00400d80]>

Setelah crackme tersebut di-load ke radare2, maka kita dapat melakukan dekompilasi terhadap fungsi main dengan perintah berikut ini:

[0x00400d80]> pdg @main
...
undefined8 main(void)
{
    int64_t iVar1;
    char cVar2;
    int64_t iVar3;
    undefined8 uVar4;
    int64_t in_FS_OFFSET;
    int64_t var_70h;
    int64_t var_60h;
    int64_t var_50h;
    int64_t var_40h;
    int64_t var_30h;
    int64_t var_20h;
    int64_t canary;

    iVar1 = *(int64_t *)(in_FS_OFFSET + 0x28);
    sym.imp.std::allocator_char_::allocator(&var_20h);

    sym.imp.std::basic_string_char__std::char_traits_char___std::allocator_char___::basic_string_char_const___std::allocator_char__const
              (&var_70h, 0x401488, &var_20h);
    sym.imp.std::allocator_char_::_allocator(&var_20h);
    sym.imp.putchar(10);
    iVar3 = sym.imp.ptrace(0, 0, 1, 0);
    if (iVar3 < 0) {
        uVar4 =
                sym.imp.std::basic_ostream_char__std::char_traits_char_____std::operator____std::char_traits_char____std::basic_ostream_char__std::char_traits_char______char_const
                          (reloc.std::cout, "Did you really think that you can mess around with me?!");
        sym.imp.std::ostream::operator___std::ostream______std::ostream
                  (uVar4,
                   sym.imp.std::basic_ostream_char__std::char_traits_char_____std::endl_char__std::char_traits_char____std::basic_ostream_char__std::char_traits_char
                  );

        sym.imp.std::basic_ostream_char__std::char_traits_char_____std::operator____std::char_traits_char____std::basic_ostream_char__std::char_traits_char______char_const
                  (reloc.std::cout,

                   "I am a \'crack me\' program for God\'s sake.. Debugging tools like that..?\nShow some respect ;)\n\nOutta here."
                  );
    } else {
        while( true ) {
            sym.imp.std::allocator_char_::allocator(&var_20h);

            sym.imp.std::basic_string_char__std::char_traits_char___std::allocator_char___::basic_string_char_const___std::allocator_char__const
                      (&var_60h, "*** THE DOOR IS LOCKED! ***\n\n", &var_20h);
            sym.print_center_std::string((int64_t)&var_60h);
            sym.imp.std::basic_string_char__std::char_traits_char___std::allocator_char___::_basic_string(&var_60h);
            sym.imp.std::allocator_char_::_allocator(&var_20h);

            sym.imp.std::basic_ostream_char__std::char_traits_char_____std::operator____std::char_traits_char____std::basic_ostream_char__std::char_traits_char______char_const
                      (reloc.std::cout, "Gimme your password: ");

            sym.imp.std::basic_istream_char__std::char_traits_char_____std::operator___char__std::char_traits_char___std::allocator_char____std::basic_istream_char__std::char_traits_char______std::basic_string_char__std::char_t
raits_char___std::allocator_char
                      (reloc.std::cin, &var_70h);
            cVar2 =
                    method.bool_std::operator___char__std::char_traits_char___std.allocator_char____std::basic_string_char__std::char_traits_char___std::allocator_char____const___char_const
                              ((int64_t)&var_70h, 0x401566);
            if (cVar2 == '\0') break;                                                                                                                                                                                      [13/262]

            sym.imp.std::basic_string_char__std::char_traits_char___std::allocator_char___::basic_string_std::string_const
                      (&var_50h, &var_70h, &var_70h);
            cVar2 = sym.checkIt_std::string((int64_t)&var_50h);
            sym.imp.std::basic_string_char__std::char_traits_char___std::allocator_char___::_basic_string(&var_50h);
            if (cVar2 == '\x01') {
                sym.imp.puts(0x4015cd);
                sym.imp.std::allocator_char_::allocator(&var_20h);

                sym.imp.std::basic_string_char__std::char_traits_char___std::allocator_char___::basic_string_char_const___std::allocator_char__const
                          (&var_40h, "*****************************", &var_20h);
                sym.print_center_std::string((int64_t)&var_40h);
                sym.imp.std::basic_string_char__std::char_traits_char___std::allocator_char___::_basic_string(&var_40h);
                sym.imp.std::allocator_char_::_allocator(&var_20h);
                sym.imp.std::allocator_char_::allocator(&var_20h);

                sym.imp.std::basic_string_char__std::char_traits_char___std::allocator_char___::basic_string_char_const___std::allocator_char__const
                          (&var_30h, "*** THE DOOR IS UNLOCKED! ***", &var_20h);
                sym.print_center_std::string((int64_t)&var_30h);
                sym.imp.std::basic_string_char__std::char_traits_char___std::allocator_char___::_basic_string(&var_30h);
                sym.imp.std::allocator_char_::_allocator(&var_20h);
                sym.imp.std::allocator_char_::allocator(&var_30h);

                sym.imp.std::basic_string_char__std::char_traits_char___std::allocator_char___::basic_string_char_const___std::allocator_char__const
                          (&var_20h, "*****************************", &var_30h);
                sym.print_center_std::string((int64_t)&var_20h);
                sym.imp.std::basic_string_char__std::char_traits_char___std::allocator_char___::_basic_string(&var_20h);
                sym.imp.std::allocator_char_::_allocator(&var_30h);
                uVar4 =
                        sym.imp.std::basic_ostream_char__std::char_traits_char_____std::operator____std::char_traits_char____std::basic_ostream_char__std::char_traits_char______char_const
                                  (reloc.std::cout,
                                   "\n\nYou did it broughhh!! :D High five dude! :D\nAnyway.. here is your prize :3");
                sym.imp.std::ostream::operator___std::ostream______std::ostream
                          (uVar4,
                           sym.imp.std::basic_ostream_char__std::char_traits_char_____std::endl_char__std::char_traits_char____std::basic_ostream_char__std::char_traits_char
                          );
                uVar4 =
                        sym.imp.std::basic_ostream_char__std::char_traits_char_____std::operator____std::char_traits_char____std::basic_ostream_char__std::char_traits_char______char_const
                                  (reloc.std::cout,

                                   "\n\t http://cdn.business2community.com/wp-content/uploads/2014/10/Witch-Hat-Cat-Costume-For-Halloween.jpg.jpg\n\n"
                                  );
                sym.imp.std::ostream::operator___std::ostream______std::ostream
                          (uVar4,
                           sym.imp.std::basic_ostream_char__std::char_traits_char_____std::endl_char__std::char_traits_char____std::basic_ostream_char__std::char_traits_char
                          );
                break;
            }
            uVar4 =
                    sym.imp.std::basic_ostream_char__std::char_traits_char_____std::operator____std::char_traits_char____std::basic_ostream_char__std::char_traits_char______char_const
                              (reloc.std::cout,

                               "\n\nWrong password!!\nTry again fella or type \"exit\" to..\nwell.. should I really explain this?\n"
                              );
            sym.imp.std::ostream::operator___std::ostream______std::ostream
                      (uVar4,
                       sym.imp.std::basic_ostream_char__std::char_traits_char_____std::endl_char__std::char_traits_char____std::basic_ostream_char__std::char_traits_char
                      );
        }
    }
    sym.imp.std::basic_string_char__std::char_traits_char___std::allocator_char___::_basic_string(&var_70h);
    uVar4 = 0;
    if (iVar1 != *(int64_t *)(in_FS_OFFSET + 0x28)) {
        uVar4 = sym.imp.__stack_chk_fail();
    }
    return uVar4;
}

Perhatikan baris berikut ini pada dekompilasi fungsi main di atas:

cVar2 = sym.checkIt_std::string((int64_t)&var_50h);
sym.imp.std::basic_string_char__std::char_traits_char___std::allocator_char___::_basic_string(&var_50h);
if (cVar2 == '\x01') {

    ...

    (&var_30h, "*** THE DOOR IS UNLOCKED! ***", &var_20h);

Bisa terlihat bahwa, password yang dimasukkan akan diperiksa oleh fungsi sym.checkIt_std::string dan hasilnya disimpan pada variabel cVar2. Jika cVar2 nilainya 1, maka akan artinya password yang dimasukkan benar dan akan muncul pesan *** THE DOOR IS UNLOCKED! ***. Berarti, kita perlu untuk mencari tahu seperti apa fungsi sym.checkIt_std::string tersebut. Gunakan perintah seperti ini:

[0x00400d80]> pdg @sym.checkIt_std::string

...

undefined8 sym.checkIt_std::string(int64_t arg1)
{
    int64_t iVar1;
    char *pcVar2;
    undefined8 uVar3;
    int64_t in_FS_OFFSET;
    int64_t var_68h;
    undefined8 var_58h;
    int64_t var_50h;
    int64_t canary;

    iVar1 = *(int64_t *)(in_FS_OFFSET + 0x28);
    var_50h._0_4_ = 100;
    var_50h._4_4_ = 0x30;
    var_58h._0_4_ = 0;
    do {
        if (0xd < (int32_t)var_58h) {
            uVar3 = 1;
code_r0x00400fad:
            if (iVar1 != *(int64_t *)(in_FS_OFFSET + 0x28)) {
                uVar3 = sym.imp.__stack_chk_fail();
            }
            return uVar3;
        }
        pcVar2 = (char *)sym.imp.std::string::operator___unsigned_long
                                   (arg1, (int64_t)(int32_t)var_58h, (int64_t)(int32_t)var_58h);
        if (*(int32_t *)((int64_t)&var_50h + (int64_t)(int32_t)var_58h * 4) != (int32_t)*pcVar2) {
            uVar3 = 0;
            goto code_r0x00400fad;
        }
        var_58h._0_4_ = (int32_t)var_58h + 1;
    } while( true );
}

Hasil dekompilasi di atas tampak normal, jadi kita coba disassemble fungsi di atas:

[0x00400d80]> pdf @sym.checkIt_std::string
            ; CALL XREF from main @ 0x401105
┌ 233: sym.checkIt_std::string (int64_t arg1);
│           ; var int64_t var_68h @ rbp-0x68
│           ; var int64_t var_59h @ rbp-0x59
│           ; var signed int64_t var_58h @ rbp-0x58
│           ; var uint32_t var_54h @ rbp-0x54
│           ; var int64_t var_50h @ rbp-0x50
│           ; var int64_t var_4ch @ rbp-0x4c
│           ; var int64_t var_48h @ rbp-0x48
│           ; var int64_t var_44h @ rbp-0x44
│           ; var int64_t var_40h @ rbp-0x40
│           ; var int64_t var_3ch @ rbp-0x3c
│           ; var int64_t var_38h @ rbp-0x38
│           ; var int64_t var_34h @ rbp-0x34
│           ; var int64_t var_30h @ rbp-0x30
│           ; var int64_t var_2ch @ rbp-0x2c
│           ; var int64_t var_28h @ rbp-0x28
│           ; var int64_t var_24h @ rbp-0x24
│           ; var int64_t var_20h @ rbp-0x20
│           ; var int64_t var_1ch @ rbp-0x1c
│           ; var int64_t var_18h @ rbp-0x18
│           ; var int64_t canary @ rbp-0x8
│           ; arg int64_t arg1 @ rdi
│           0x00400eda      55             push rbp                    ; /home/twister/Documents/CodeBlocksProjects/crackMe/main.cpp:13
│           0x00400edb      4889e5         mov rbp, rsp
│           0x00400ede      4883ec70       sub rsp, 0x70
│           0x00400ee2      48897d98       mov qword [var_68h], rdi    ; arg1
│           0x00400ee6      64488b042528.  mov rax, qword fs:[0x28]
│           0x00400eef      488945f8       mov qword [canary], rax
│           0x00400ef3      31c0           xor eax, eax
│           0x00400ef5      c745b0640000.  mov dword [var_50h], 0x64   ; /home/twister/Documents/CodeBlocksProjects/crackMe/main.cpp:14 ; 'd' ; 100
│           0x00400efc      c745b4300000.  mov dword [var_4ch], 0x30   ; '0' ; 48
│           0x00400f03      c745b8300000.  mov dword [var_48h], 0x30   ; '0' ; 48
│           0x00400f0a      c745bc720000.  mov dword [var_44h], 0x72   ; 'r' ; 114
│           0x00400f11      c745c0310000.  mov dword [var_40h], 0x31   ; '1' ; 49
│           0x00400f18      c745c4240000.  mov dword [var_3ch], 0x24   ; '$' ; 36
│           0x00400f1f      c745c86d0000.  mov dword [var_38h], 0x6d   ; 'm' ; 109
│           0x00400f26      c745cc400000.  mov dword [var_34h], 0x40   ; '@' ; 64
│           0x00400f2d      c745d06c0000.  mov dword [var_30h], 0x6c   ; 'l' ; 108
│           0x00400f34      c745d4690000.  mov dword [var_2ch], 0x69   ; 'i' ; 105
│           0x00400f3b      c745d8630000.  mov dword [var_28h], 0x63   ; /char_traits.h:1553 ; 'c' ; 99
│           0x00400f42      c745dc690000.  mov dword [var_24h], 0x69   ; /char_traits.h:2636 ; 'i' ; 105
│           0x00400f49      c745e06f0000.  mov dword [var_20h], 0x6f   ; 'o' ; 111
│           0x00400f50      c745e4750000.  mov dword [var_1ch], 0x75   ; 'u' ; 117
│           0x00400f57      c745e8730000.  mov dword [var_18h], 0x73   ; 's' ; 115
│           0x00400f5e      c745a8000000.  mov dword [var_58h], 0      ; /home/twister/Documents/CodeBlocksProjects/crackMe/main.cpp:15
...

Jika diperhatikan dengan seksama, maka bisa terlihat bahwa ada sederetan nilai yang disimpan ke dalam variabel. Agar lebih jelas, berikut ini adalah nilai yang dimaksud:

mov dword [var_50h], 0x64   ; 'd' ; 100
mov dword [var_4ch], 0x30   ; '0' ; 48
mov dword [var_48h], 0x30   ; '0' ; 48
mov dword [var_44h], 0x72   ; 'r' ; 114
mov dword [var_40h], 0x31   ; '1' ; 49
mov dword [var_3ch], 0x24   ; '$' ; 36
mov dword [var_38h], 0x6d   ; 'm' ; 109
mov dword [var_34h], 0x40   ; '@' ; 64
mov dword [var_30h], 0x6c   ; 'l' ; 108
mov dword [var_2ch], 0x69   ; 'i' ; 105
mov dword [var_28h], 0x63   ; 'c' ; 99
mov dword [var_24h], 0x69   ; 'i' ; 105
mov dword [var_20h], 0x6f   ; 'o' ; 111
mov dword [var_1ch], 0x75   ; 'u' ; 117
mov dword [var_18h], 0x73   ; 's' ; 115

Jika digabungkan, maka akan menghasilkan string d00r1$m@licious. Coba kita gunakan string tersebut sebagai password.

% ./EyeCandyLOCKED

                         *** THE DOOR IS LOCKED! ***


Gimme your password: d00r1$m@licious


                         *****************************
                         *** THE DOOR IS UNLOCKED! ***
                         *****************************


You did it broughhh!! :D High five dude! :D
Anyway.. here is your prize :3

         http://cdn.business2community.com/wp-content/uploads/2014/10/Witch-Hat-Cat-Costume-For-Halloween.jpg.jpg

Ternyata string tersebut (d00r1$m@licious) adalah password yang benar. Ini hanyalah salah satu dari sekian banyak langkah yang dapat digunakan untuk mendapatkan password tersebut. Anda bisa bereksperimen menggunakan metode lainnya. Sekian tutorial singkat kali ini, semoga bermanfaat. Terima kasih kepada Allah SWT, dan Anda yang telah membaca tutorial ini.

Bang jawab pertanyaan ku yang Disini