Reverse Engineering - Cracking a Password with GDB (Beginner-Friendly)
Overview
This write-up shows how to recover a hardcoded password by breaking in GDB and inspecting the registers used for function arguments.
The source code
Description
The program is “locked” by a password that is stored in memory and compared against your input at runtime.
Task
Recover the correct password and successfully authenticate.
Steps to solve
┌──(kali㉿kali)-[~/crackmes]
└─$ ./simp-password
Enter password: 1337
Wrong try again.
Run GDB and set a breakpoint at main:
┌──(kali㉿kali)-[~/crackmes]
└─$ gdb simp-password
(gdb) break *main
Breakpoint 1 at 0x11c9
Run the program:
(gdb) r
Starting program: /home/kali/crackmes/simp-password
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, 0x00005555555551c9 in main ()
Disassemble main and look for where your input is compared to the “real” password. Common patterns include:
cmp reg1, reg2test reg, regfollowed by a conditional jump likejne- a library call like
strcmp()(very common for string password checks)
(gdb) disassemble *main
In this code, we can spot a call to strcmp():
0x000000000000121e <+85>: mov rsi,rdx
0x0000000000001221 <+88>: mov rdi,rax
0x0000000000001224 <+91>: call 0x10c0 <strcmp@plt>
0x0000000000001229 <+96>: test eax,eax
0x000000000000122b <+98>: jne 0x123e <main+117>
This means:
-
Two pointers are prepared
-
They are passed to strcmp
-
If the result is not zero (jne), the password is wrong.
Reference: strcmp (cppreference)
On x86-64 Linux, function arguments are passed in registers:
- 1st argument:
RDI - 2nd argument:
RSI
strcmp(a, b) therefore compares:
RDI → a
RSI → b
Right before the call strcmp@plt, the program moves pointers into those registers.
mov rsi, rdx
mov rdi, rax
Set a breakpoint right before the strcmp() call so we can inspect its arguments, then continue and enter any password.
(gdb) break *(main+91)
Breakpoint 2 at 0x555555555224
(gdb) c
Continuing.
Enter password: 1337
Breakpoint 2, 0x0000555555555224 in main ()
Now inspect what strcmp() is about to compare. Since these look like C strings (null-terminated), use x/s:
0x000000000000121e <+85>: mov rsi,rdx
0x0000000000001221 <+88>: mov rdi,rax
(gdb) x/s $rdi
0x7fffffffdd10: "1337"
$rdi is your input. Now check $rsi:
(gdb) x/s $rsi
0x55555555601a: "iloveicecream"
$rsi is the stored password the program compares against.
Restart the program and test the recovered password:
┌──(kali㉿kali)-[~/crackmes]
└─$ ./simp-password
Enter password: iloveicecream
I love ice cream too!
Conclusion
-
Find where a comparison happens (strcmp, cmp, or test)
-
Break immediately before it
-
Inspect the registers or memory holding the values
-
Extract the secret