0x02 - crackme01 by noracodes
| binary | crackme01.64 |
|---|---|
| sha256 | f4100598da4381f16322e55a4a2716f6f8a52879804f406d933008b7669d8f00 |
This evening’s sample is crackme01.64, which is the first in a collection of crackmes included in a great tutorial by noracodes, which can be found here. This sample was built locally on my machine, so the SHA256 will almost certainly be different for you:
❯ file crackme01.64
crackme01.64: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=09321964d66c4fcf4295babb61fe33daed332352, for GNU/Linux 3.2.0, not stripped
The binary is not stripped, so we have some symbols to work with:
❯ nm crackme01.64
000000000000037c r __abi_tag
0000000000004028 B __bss_start
0000000000004028 b completed.0
w __cxa_finalize@GLIBC_2.2.5
0000000000004018 D __data_start
0000000000004018 W data_start
00000000000010a0 t deregister_tm_clones
0000000000001110 t __do_global_dtors_aux
0000000000003dd8 d __do_global_dtors_aux_fini_array_entry
0000000000004020 D __dso_handle
0000000000003de0 d _DYNAMIC
0000000000004028 D _edata
0000000000004030 B _end
00000000000011d0 T _fini
0000000000001150 t frame_dummy
0000000000003dd0 d __frame_dummy_init_array_entry
000000000000213c r __FRAME_END__
0000000000003fe8 d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
0000000000002058 r __GNU_EH_FRAME_HDR
0000000000001000 T _init
0000000000002000 R _IO_stdin_used
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
U __libc_start_main@GLIBC_2.34
0000000000001159 T main
U printf@GLIBC_2.2.5
U puts@GLIBC_2.2.5
00000000000010d0 t register_tm_clones
0000000000001070 T _start
U strncmp@GLIBC_2.2.5
0000000000004028 D __TMC_END__
Instead of using Ghidra, I decide to disassemble this one using objdump:
❯ objdump -M intel --disassemble=main ./crackme01.64
0000000000001159 <main>:
1159: 55 push rbp
115a: 53 push rbx
115b: 48 83 ec 08 sub rsp,0x8
115f: 83 ff 02 cmp edi,0x2
1162: 75 40 jne 11a4 <main+0x4b>
1164: 48 8b 6e 08 mov rbp,QWORD PTR [rsi+0x8]
1168: ba 09 00 00 00 mov edx,0x9
116d: 48 8d 35 ab 0e 00 00 lea rsi,[rip+0xeab] # 201f <_IO_stdin_used+0x1f>
1174: 48 89 ef mov rdi,rbp
1177: e8 b4 fe ff ff call 1030 <strncmp@plt>
117c: 89 c3 mov ebx,eax
117e: 85 c0 test eax,eax
1180: 74 35 je 11b7 <main+0x5e>
1182: 48 89 ee mov rsi,rbp
1185: 48 8d 3d 9d 0e 00 00 lea rdi,[rip+0xe9d] # 2029 <_IO_stdin_used+0x29>
118c: b8 00 00 00 00 mov eax,0x0
1191: e8 ba fe ff ff call 1050 <printf@plt>
1196: bb 01 00 00 00 mov ebx,0x1
119b: 89 d8 mov eax,ebx
119d: 48 83 c4 08 add rsp,0x8
11a1: 5b pop rbx
11a2: 5d pop rbp
11a3: c3 ret
11a4: 48 8d 3d 59 0e 00 00 lea rdi,[rip+0xe59] # 2004 <_IO_stdin_used+0x4>
11ab: e8 90 fe ff ff call 1040 <puts@plt>
11b0: bb ff ff ff ff mov ebx,0xffffffff
11b5: eb e4 jmp 119b <main+0x42>
11b7: 48 89 ee mov rsi,rbp
11ba: 48 8d 3d 80 0e 00 00 lea rdi,[rip+0xe80] # 2041 <_IO_stdin_used+0x41>
11c1: b8 00 00 00 00 mov eax,0x0
11c6: e8 85 fe ff ff call 1050 <printf@plt>
11cb: eb ce jmp 119b <main+0x42>
The big takeaway here is that the only call instructions are for library functions (printf, puts,strncmp), so there’s really nothing else going on in the program other than main.
I run rabin2on the binary to dump the strings:
❯ rabin2 -z ./crackme01.64
[Strings]
nth paddr vaddr len size section type string
―――――――――――――――――――――――――――――――――――――――――――――――――――――――
0 0x00002004 0x00002004 26 27 .rodata ascii Need exactly one argument.
1 0x0000201f 0x0000201f 9 10 .rodata ascii password1
2 0x00002029 0x00002029 23 24 .rodata ascii No, %s is not correct.\n
3 0x00002041 0x00002041 20 21 .rodata ascii Yes, %s is correct!\n
Sometimes, it’s that easy!
❯ ./crackme01.64 password1
Yes, password1 is correct!