What was the lab?
Basically, the lab was about finding the password within compiled code, by using GDB/pwndbg.
Here is an idea of the code. This is not the exact code that the lab had but the idea remains the same.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /* Sample code to compare password Author: Nik Alleyne Blog: www.securitynik.com Compile with debug symbols $gcc -m32 -ggdb -mpreferred-stack-boundary=2 -o comparePassword comparePassword.c Compile without debug symbols $gcc -m32 -mpreferred-stack-boundary=2 -o comparePassword comparePassword.c */ #include <stdio.h> #include <string.h> // Function to compare password void compare_string() { // allocate space for the password char USER_PASS[254]; char PASSWORD[] = "SecurityNik"; printf("Enter the password: \n"); // read the user's password fgets(USER_PASS, sizeof(USER_PASS), stdin); // Compare what the user entered with what we expect if (strncmp(USER_PASS, PASSWORD, sizeof(PASSWORD)-1) == 0) printf("Welcome to my world! :-) \n"); else printf("Stay Out! \n"); } int main() { // Call the compare_string function compare_string(); return 0; } |
What was missing from above is the "strrev" function, which reverses a string. Anyhow, I don't believe it's absence if of major concern.
The code is compiled as follows:
The code is compiled as follows:
1 | └──╼ $gcc -m32 -mpreferred-stack-boundary=2 -o comparePassword32 comparePassword.c |
When this code is run, we get the following:
1 2 3 4 5 | ┌─[securitynik@securitynik]─[~/c-code] └──╼ $./comparePassword Enter the password: Testing1 Stay Out! |
Above, an incorrect password was entered.
The challenge at this point is to find the correct password using DBG. The way I solved the challenge was to use the "strings" command along with "rev" command. However, as mentioned above, the students wanted me to solve the problem using GDB/pwndbg.
There are many ways to solve this problem. Here is one:
Load the program into GDB.
The challenge at this point is to find the correct password using DBG. The way I solved the challenge was to use the "strings" command along with "rev" command. However, as mentioned above, the students wanted me to solve the problem using GDB/pwndbg.
There are many ways to solve this problem. Here is one:
Load the program into GDB.
1 2 3 4 5 | └──╼ $gdb comparePassword32 -q pwndbg: loaded 187 commands. Type pwndbg [filter] for a list. pwndbg: created $rebase, $ida gdb functions (can be used with print/break) Reading symbols from comparePassword32... (No debugging symbols found in comparePassword32) |
Next step, look at the functions being used in the program to understand what the program might be doing.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | pwndbg> info functions All defined functions: Non-debugging symbols: 0x00001000 _init 0x00001030 fgets@plt 0x00001040 puts@plt 0x00001050 __libc_start_main@plt 0x00001060 strncmp@plt 0x00001070 __cxa_finalize@plt 0x00001080 _start 0x000010c0 __x86.get_pc_thunk.bx 0x000010d0 deregister_tm_clones 0x00001110 register_tm_clones 0x00001160 __do_global_dtors_aux 0x000011b0 frame_dummy 0x000011b5 __x86.get_pc_thunk.dx 0x000011b9 compare_string 0x0000125a main 0x00001273 __x86.get_pc_thunk.ax 0x00001280 __libc_csu_init 0x000012e0 __libc_csu_fini 0x000012e1 __x86.get_pc_thunk.bp 0x000012e8 _fini |
Of greatest importance to us above is the "strncmp" functions. This function can be used to compare two strings and can be considered as the place where the password is being validated.
Next up, we set a breakpoint on our function of interest
1 2 3 4 5 | pwndbg> break strncmp Breakpoint 1 at 0x1060 pwndbg> info breakpoints Num Type Disp Enb Address What 1 breakpoint keep y 0x00001060 <strncmp@plt> |
Now that we have the function, let's run the program by executing the "run" command.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | pwndbg> run Starting program: /home/securitynik/c-code/comparePassword32 Enter the password: Testing1 Breakpoint 1, 0xf7f2b0b0 in ?? () from /lib32/libc.so.6 LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA ─────────────────────────────────[ REGISTERS ]────────────────────────────────── EAX 0xffffd13e ◂— 'Testing1\n' EBX 0x56559000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x3ef8 ECX 0x0 EDX 0xfbad2288 EDI 0xf7fac000 ◂— 0x1dfd6c ESI 0xf7fac000 ◂— 0x1dfd6c EBP 0xffffd240 —▸ 0xffffd248 ◂— 0x0 ESP 0xffffd120 —▸ 0x5655622d (compare_string+116) ◂— add esp, 0xc EIP 0xf7f2b0b0 ◂— push ebp ───────────────────────────────────[ DISASM ]─────────────────────────────────── ► 0xf7f2b0b0 push ebp 0xf7f2b0b1 mov edx, dword ptr [esp + 8] 0xf7f2b0b5 mov eax, dword ptr [esp + 0xc] 0xf7f2b0b9 mov ebp, dword ptr [esp + 0x10] 0xf7f2b0bd test ebp, ebp 0xf7f2b0bf je 0xf7f2b2b2 0xf7f2b0c5 mov cx, dx 0xf7f2b0c8 and cx, 0xfff 0xf7f2b0cd cmp cx, 0xff0 0xf7f2b0d2 ja 0xf7f2b129 0xf7f2b0d4 movdqu xmm2, xmmword ptr [edx] ───────────────────────────────────[ STACK ]──────────────────────────────────── 00:0000│ esp 0xffffd120 —▸ 0x5655622d (compare_string+116) ◂— add esp, 0xc 01:0004│ 0xffffd124 —▸ 0xffffd13e ◂— 'Testing1\n' 02:0008│ 0xffffd128 —▸ 0xffffd132 ◂— 'SecurityNik' 03:000c│ 0xffffd12c ◂— 0xb /* '\x0b' */ 04:0010│ 0xffffd130 ◂— 0x6553d000 05:0014│ 0xffffd134 ◂— 'curityNik' 06:0018│ 0xffffd138 ◂— 'tyNik' 07:001c│ eax-2 0xffffd13c ◂— 0x6554006b /* 'k' */ ─────────────────────────────────[ BACKTRACE ]────────────────────────────────── ► f 0 f7f2b0b0 f 1 5655622d compare_string+116 f 2 5655626c main+18 f 3 f7deaef1 __libc_start_main+241 ──────────────────────────────────────────────────────────────────────────────── pwndbg> |
Once I entered the invalid password, we then see that GDB/pwndbg reported the string I entered along with the another string below it. Could this other string be the password? Let's test that theory.
Executed the program again, with string which we now find during debugging.
1 2 3 4 | └──╼ $./comparePassword32 Enter the password: SecurityNik Welcome to my world! :-) |
Looks like we are now in. This means the password is "SecurityNik".
Obviously there was lots of testing I had to do to get to this point. However, hopefully the students reading can make sense of what I did.
Obviously there was lots of testing I had to do to get to this point. However, hopefully the students reading can make sense of what I did.
No comments:
Post a Comment