Buffer overflow: Ten years of attack and defense vulnerabilities-vulnerability Research

Source: Internet
Author: User
Tags anonymous arrays perl interpreter
Absrtact: In the past decade, the type of buffer overflow is the most common form of security vulnerabilities. More seriously, buffer overflow vulnerabilities account for the vast majority of remote network attacks, which can give an anonymous Internet user access to some or all of the control of a host computer! If buffer overflow vulnerabilities are effectively eliminated, a large part of the security threat can be mitigated. In this article, we have examined various types of buffer overflow vulnerabilities and attacks, and we have studied various defenses to eliminate the effects of these vulnerabilities, including our own stack protection methods. Then we want to consider how to use these methods to eliminate these vulnerabilities while ensuring that the existing system features and performance are unchanged.
I. Foreword in the past decade, the type of buffer overflow is the most common form of security vulnerabilities. More seriously, buffer overflow vulnerabilities account for the vast majority of remote network attacks, which can give an anonymous Internet user access to some or all of the control of a host computer! Because such attacks make it possible for anyone to gain control of the host, it represents a very serious security threat. The reason why buffer overflow attacks become a common security attack is that buffer overflow vulnerabilities are too common and easy to implement. Furthermore, the buffer overflow is the primary means of a remote attack because the buffer overflow vulnerability gives the attacker everything he wants: to colonize and execute the attack code. The implanted attack code runs a buffer overflow procedure with certain privileges, thus obtaining the control of the attacked host. For example, of the 5 remote attacks that Lincoln laboratories used to assess intrusion detection in 1998, 3 were based on social engineering trusts and 2 were buffer overflows. Of the 13 recommendations of Cert in 1998, 9 were related to buffer overflows, and in 1999 at least half of the recommendations were related to buffer overflows. In the Bugtraq survey, 2/3 of respondents considered a buffer overflow vulnerability to be a serious security issue. There are many forms of buffer overflow vulnerabilities and attacks, and we will describe and categorize them in the second part. The corresponding defense means are different with the attack method, we will put in the third part of the description, its content includes for each type of attack effective defense means. We also want to introduce stack protection methods, which are effective in resolving buffer overflow vulnerabilities and without sacrificing system compatibility and performance. In the fourth part, we will discuss the comprehensive use of various defense methods. Finally, in part five, we conclude.
Buffer overflow vulnerabilities and attack buffer overflow attacks are designed to disrupt the functionality of programs that have certain privileges running, allowing attackers to gain control of the program, and if the program has sufficient permissions, the entire host is controlled. In general, an attacker attacks the root program and then executes code like "EXEC (SH)" To obtain the root shell, but not always. To achieve this, an attacker would have to achieve the following two goals:
1. Arrange the appropriate code in the address space of the program.
2.  by properly initializing registers and memory, let the program jump to the address space we arrange   to execute.   We classify buffer overflow attacks against these two targets. In the 2.1  section, we will describe how the attack code is placed in the address space of the attacked program   (this is the origin of the "buffer" name). In 2.2 parts, we introduce   how an attacker can overflow a buffer of a program, and execution moves to the attack code   (this is the origin of "overflow"). In 2.3 parts, we describe the techniques that integrate the code scheduling and program execution processes that are discussed in the 2.1  and 2.2 parts.  2.1  how to arrange the appropriate code in the address space of the program   There are two methods of arranging the attack code in the address space of the attack: :  the attacker enters a string into the program being attacked, and the program puts the character The   string is placed in the buffer. This string contains data that is a sequence of instructions that can be run on the attacked   hardware platform. Here the attacker uses the buffer   area of the attacked program to store the attack code. There are two different ways to do this: 1.  an attacker does not have to overflow any buffers for this purpose and can find enough   space to place the attack code  2.  buffer can be set anywhere: stack (automatic variable), heap (Dynamic score  ) and static data areas (initialized or uninitialized)   take advantage of existing code:  sometimes the attacker wants code that is already in the attacked program, and what the attacker needs to do is pass some parameters to the code, Then make the program jump to our   goals. For example, the attack code requires "exec ("/bin/sh ")", while the code in the  LIBC library executes "exec (ARG)", where Arg makes a pointer argument to a word   string, so the attacker simply redirect the incoming parameter pointer to the   "/bin/sh", then switch to the corresponding instruction sequence in the LIBC library.  2.2  procedures to transfer to the attack code   All of these methods are seeking to change the execution process of the program to make it jump   to the attack code. The basic thing is to overflow a buffer with no boundary check or other weakness  , which disrupts the normal execution order of the program. By spilling a   buffer, an attacker could overwrite the adjacent program space in a near-violent way and direct   Skip the system's check.   ThisThe base of the classification is the program space type   type of buffer overflow that the attacker seeks. In principle, it is possible to have any space. For example, the original Morris worm used   fingerd program buffer overflow, disrupting fingerd to execute the file name   Word. In fact, many buffer overflows are using brute force methods to seek to change the program   pointer. This kind of program's different place is the program space breakthrough and the memory space   the localization is different.   (Figure 1)   activation record (activation records):  whenever a function call occurs, the caller leaves an activation   record on the stack that contains the address that   returned at the end of the function. By spilling these automatic variables, the attacker causes the return address to refer to the   to attack code, as shown in Figure 1. By changing the return address of the program, when the function is tuned   ended, the program jumps to the address set by the attacker, rather than the original   site. This type of buffer overflow is known as "Stack smashing attack", which makes   the current common buffer overflow attack mode.   function pointer (function pointers):  "void  (* foo) ()" declares a variable   amount foo with a return value of void function pointers. The function pointer can be used to set any address space in the  , so the attacker could simply find a buffer that could overflow in the vicinity of the function pointer in any space, and then overflow the buffer to change the function's reference   stitch.  
At some point, when the program calls the function through the function pointer, the process   of the program is implemented according to the attacker's intent! One of its attack paradigms is the Superprobe program under Linux  .   Long jump Buffer (longjmp buffers):  contains a simple inspection/recovery system in the C language called  SETJMP/LONGJMP. The meaning is to set   at the checkpoint "setjmp (buffer)", use "longjmp (buffer)" To restore the inspection   point. However, if an attacker were able to enter the buffer space, then   "longjmp" was actually a jump to the attacker's code. Like a function refers to a   PIN, the longjmp buffer can point anywhere, so the attacker would have to do   find a buffer to overflow. A typical example is perl 5.003, where the attacker first enters the longjmp buffer   zone used to recover the buffer overflow, and then induces access to the recovery mode, which causes the Perl interpreter to jump to the attack   code!  2.3  integrated code colonization and Process Control technology   Now we study integrated code colonization and process Control techniques.   The simplest and most common type of buffer overflow attack is in a string   synthesizes the code entry and activation record. An attacker locates an automatic variable,  that can overflow and then passes a large string to the program, which is implanted into the code when the buffer overflow change   activation record is raised. This is the template for the attack identified by Levy.   Because C in the habit of only for users and parameters to open a very small buffer, so this leak   hole attack examples of a few.   Code colonization and buffer overflows do not have to be done in one action. Attack   can place code within a buffer, which cannot overflow the buffer. Then,  the attacker to transfer a pointer to the program by spilling another buffer. This method is   used to resolve the   situation where the buffer for overflow is not large enough (cannot drop all the code).   If an attacker attempts to use a resident code instead of an external generation   code, they usually have to have the code as parameterized. For example, part of the code snippet in libc (which   all C programs want it to connect) executes   exec (something), where somthing is the parameter. The attacker then causes   to change the parameters of the program with a buffer overflow, and then the benefitUse another buffer overflow to point the path   order pointer to a specific code snippet in libc.  3.  buffer Overflow Protection method   There are currently four basic ways to protect buffers from buffer overflow attacks and   effects. The method to force write the correct code is described in 3.1.  
In 3.2, the   was introduced to prevent the buffer from being executed by the operating system, thus preventing the attacker from colonizing the attack   code. This method effectively prevents many buffer overflow attacks, but the attacker   does not necessarily have to colonize the attack code to implement buffer overflow attacks (see 2.1  section), so this approach is still very weak. In 3.3, we introduced   use the compiler's boundary check to implement buffer protection. This method makes the buffer   area overflow impossible, thus completely eliminates the buffer overflow threat, but the phase   is very expensive. In 3.4 We introduce an indirect method, the square   method to perform an integrity check before the program pointer fails. In this way, although this method does not invalidate all the buffer overflows of  , it does prevent most buffer   overflow attacks, and the buffer overflow that escapes the protection of this method is difficult to implement  . Then in 3.5, we want to analyze this protection method for compatibility and performance advantage   (with array bounds checking).  3.1  writing the right code   writing the right code is a very meaningful but time-consuming task, especially if you write   writing C language with error prone programs (such as the 0-knot   tail of strings), This style is caused by the tradition of ignoring correctness because of the pursuit of performance. The   tube took a long time to make people know how to write a secure program, and the program with an   full vulnerability still appeared. So people have developed tools and techniques to help   inexperienced programmers write safe and correct programs.   The easiest way to do this is to use grep to search for vulnerable library   calls in the source code, such as calls to strcpy and sprintf, both of which do not check   the length of the input parameters. In fact, the standard libraries of each version C have such questions   questions.   to look for common   vulnerabilities such as buffer overflows and operating system competition conditions, the Code review team examines a lot of code. Yet there is still a slip of the   in. Despite the use of strncpy and snprintf these substitution functions to prevent buffer   overflow from occurring, but because of the problem of writing code, there will still be a case of this situation hair   health. For example, the LPRM program is the best example, although it passed the code security   Check, but there are still buffer overflow problems exist.   In order to deal with these problems, people have developed some advanced error-checking tools, such as  fault injection. The purpose of these tools is to pass the humanTo randomly generate   some buffers overflow to look for code security vulnerabilities. There are also static analysis tools   used to detect the presence of buffer overflows.   Although these tools help programmers develop more secure programs, these tools are not likely to identify all buffer overflow vulnerabilities due to the features of the C   language. So,  debugging technology can only be used to reduce the possibility of buffer overflow, and can not completely eliminate the existence of its  . Unless the programmer can guarantee that his program is foolproof, it will use the contents of the   3.2 to 3.4 parts to ensure the reliability of the program.  
3.2 A non executing buffer allows an attacker to execute code that is implanted into the program's input buffer by making the data segment address space of the attacked program unavailable, a technique known as a buffer technology that is not executed. In fact, many older UNIX systems are designed this way, but the recent UNIX and MS Windows systems are often dynamically placed into executable code in data segments due to better performance and functionality. Therefore, in order to maintain the compatibility of the program can not make the data section of all programs can not be executed. But we can set the stack data segment is not executable, so that you can maximize the compatibility of the program. Linux and Solaris have both released kernel patches for this. Because almost no legitimate program holds code in the stack, this practice produces almost no compatibility issues, except for the two exceptions in Linux where executable code must be put on the stack: signal delivery: Linux executes on the stack by releasing the code to the process stack and then causing the interrupt To implement the sending of UNIX signals to the process. A patch that is not an execution buffer is allowed to execute when the signal is sent. Online reuse of GCC: the study found that GCC placed executable code in the stack area for online reuse. However, turning off this feature does not create any problems, and only some of the features seem to be out of use. The protection of a non-execution stack can effectively deal with a buffer overflow attack that puts code into an automatic variable, but it has no effect on other forms of attack (see 2.1). You can skip this protection by referencing a pointer to a resident program. Other attacks can be done by putting code into heaps or static data segments to bypass protection.
 3.3  array boundary check   colonization code causing buffer overflow is an aspect that disrupts the execution flow of the program   is another aspect. Unlike non-performing buffer protection, array boundary checks are completely placed   the generation and attack of buffer overflows. In this way, as long as the array cannot be overflowed, overflow   attack will not be discussed. In order to achieve array boundary checking, all the   read-write operations of the arrays should be checked to ensure that the operations of the arrays are within the correct range. The most   direct method is to check all array operations, but you can usually use some optimization   techniques to reduce the number of checks. At present, there are several methods of checking: 3.3.1 compaq c  compiler  compaq The C compiler developed for Alpha cpu (Unix ping   in Tru64 The platform is CC and is CCC on alpha linux platforms to support limited boundary check   (using-check_bounds parameters). These restrictions are:   only the array references that are displayed are checked, for example, "a[3]" is checked, and   "* (a+3)" is not.   because all C arrays are passed by the pointer at the time of transmission, the array passed to the function   number is not checked.   a risky library function, such as strcpy, does not perform boundary checks   checks at compile time, even if a boundary check is specified.   Because the use of pointers in C language array operation and transmission is so frequency   complexity, so this limitation is very serious. Usually this boundary check is used to program   error checking, and there is no guarantee of buffer overflow vulnerabilities.  

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.