Simple crack me.

Information

  • category: reverse
  • points: 50

Description

Note: Enclose the flag with flag{}

1 file: generic_crackme_redux.bin

Writeup

Execute the program:

$ ./generic_crackme_redux.bin 
Enter access code: 1111
Bzzzzrrrppp

Ltrace the program:

ltrace ./generic_crackme_redux.bin

printf("Enter access code: ")                                                                                                                      = 19
__isoc99_scanf(0x557444018018, 0x7ffd67e4bb14, 0, 0Enter access code: 11
)                                                                                               = 1
puts("Bzzzzrrrppp"Bzzzzrrrppp
)                                                                                                                                = 12
+++ exited (status 0) +++

Well, we need to dig deeper using radare2.

$ r2 -d generic_crackme_redux.bin
[0x7ffb5769d100]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[Warning: Invalid range. Use different search.in=? or anal.in=dbg.maps.x
Warning: Invalid range. Use different search.in=? or anal.in=dbg.maps.x
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Check for objc references
[x] Check for vtables
[TOFIX: aaft can't run in debugger mode.ions (aaft)
[x] Type matching analysis for all functions (aaft)
[x] Use -AA or aaaa to perform additional experimental analysis.
[0x7ffb5769d100]> afl
0x55b310500070    1 46           entry0
0x55b310502fe0    1 4124         reloc.__libc_start_main
0x55b310500030    1 6            sym.imp.puts
0x55b310500040    1 6            sym.imp.__stack_chk_fail
0x55b310500050    1 6            sym.imp.printf
0x55b3104ff000    3 209  -> 202  loc.imp._ITM_deregisterTMCloneTable
0x55b310500060    1 6            sym.imp.__isoc99_scanf
0x55b310500186    6 131          main
0x55b310500160    5 153  -> 60   entry.init0
0x55b310500110    5 65   -> 55   entry.fini0
0x55b310502ff8    1 4100         reloc.__cxa_finalize
0x55b3105000a0    4 41   -> 34   fcn.55b3105000a0
[0x7ffb5769d100]> s main
[0x55b310500186]> pdf
/ (fcn) main 131
|   int main (int argc, char **argv, char **envp);
|           ; var int32_t var_ch @ rbp-0xc
|           ; var int32_t var_8h @ rbp-0x8
|           ; DATA XREF from entry0 @ 0x55b310500091
|           0x55b310500186      55             push rbp
|           0x55b310500187      4889e5         mov rbp, rsp
|           0x55b31050018a      4883ec10       sub rsp, 0x10
|           0x55b31050018e      64488b042528.  mov rax, qword fs:[0x28] ; [0x28:8]=-1 ; '(' ; 40
|           0x55b310500197      488945f8       mov qword [var_8h], rax
|           0x55b31050019b      31c0           xor eax, eax
|           0x55b31050019d      488d3d600e00.  lea rdi, str.Enter_access_code: ; 0x55b310501004 ; "Enter access code: "
|           0x55b3105001a4      b800000000     mov eax, 0
|           0x55b3105001a9      e8a2feffff     call sym.imp.printf     ; int printf(const char *format)
|           0x55b3105001ae      488d45f4       lea rax, [var_ch]
|           0x55b3105001b2      4889c6         mov rsi, rax
|           0x55b3105001b5      488d3d5c0e00.  lea rdi, [0x55b310501018] ; "%d"
|           0x55b3105001bc      b800000000     mov eax, 0
|           0x55b3105001c1      e89afeffff     call sym.imp.__isoc99_scanf ; int scanf(const char *format)
|           0x55b3105001c6      8b45f4         mov eax, dword [var_ch]
|           0x55b3105001c9      89c7           mov edi, eax
|           0x55b3105001cb      e899ffffff     call 0x55b310500169
|           0x55b3105001d0      84c0           test al, al
|       ,=< 0x55b3105001d2      740e           je 0x55b3105001e2
|       |   0x55b3105001d4      488d3d400e00.  lea rdi, str.Access_granted ; 0x55b31050101b ; "Access granted"
|       |   0x55b3105001db      e850feffff     call sym.imp.puts       ; int puts(const char *s)
|      ,==< 0x55b3105001e0      eb0c           jmp 0x55b3105001ee
|      |`-> 0x55b3105001e2      488d3d410e00.  lea rdi, str.Bzzzzrrrppp ; 0x55b31050102a ; "Bzzzzrrrppp"
|      |    0x55b3105001e9      e842feffff     call sym.imp.puts       ; int puts(const char *s)
|      |    ; CODE XREF from main @ 0x55b3105001e0
|      `--> 0x55b3105001ee      b800000000     mov eax, 0
|           0x55b3105001f3      488b55f8       mov rdx, qword [var_8h]
|           0x55b3105001f7      644833142528.  xor rdx, qword fs:[0x28]
|       ,=< 0x55b310500200      7405           je 0x55b310500207
|       |   0x55b310500202      e839feffff     call sym.imp.__stack_chk_fail ; void __stack_chk_fail(void)
|       `-> 0x55b310500207      c9             leave
\           0x55b310500208      c3             ret
[0x55b310500186]> 

Visualize the main:

Our scope is to print "Access granted".

Pseudocode main:

int main()
{
    int x;
    scanf("%d", &x);
    if(flag(x) == 0)          // flag() = 0x55b310500169, 
        puts("Bzzzzrrrppp");  // '\0' because return is in al (8 bit)
    else
        puts("Access granted");

    return 0;
}

Let’s see what the function flag() = 0x55b310500169 does:

[0x55b310500186]> s 0x55b310500169
[0x55b310500169]> pd
        ; CALL XREF from main @ 0x55b3105001cb
        0x55b310500169      55             push rbp
        0x55b31050016a      4889e5         mov rbp, rsp
        0x55b31050016d      897dfc         mov dword [rbp - 4], edi
        0x55b310500170      8b55fc         mov edx, dword [rbp - 4]
        0x55b310500173      89d0           mov eax, edx
        0x55b310500175      c1e002         shl eax, 2
        0x55b310500178      01d0           add eax, edx
        0x55b31050017a      01c0           add eax, eax
        0x55b31050017c      3d92c20a00     cmp eax, 0xac292
        0x55b310500181      0f94c0         sete al
        0x55b310500184      5d             pop rbp
        0x55b310500185      c3             ret

Pseudocode:

char flag(int x)
{
    int a = x;
    a = a * 4;   // shl eax, 2           (4x)
    a = a + x;   // add eax, edx         (5x)
    a = a + a;   // add eax,eax          (5x + 5x) = 10x
    if (a == 0xac292)  // cmp eax, 0xac292
        return 1;    // sete al, return 1 if ZF = 1
    else
        return 0;
}

To print "Access granted" we need that the flag function returns 0x1. To do so we just need to solve (10 * x) = 0xac292 –> x = 0xac292 / 10 –> x = 70517.

$ ./generic_crackme_redux.bin
Enter access code: 70517
Access granted

Flag

flag{70517}