
Buffer Overflows: Attacks and Defenses for the Vulnerability of the Decade* Crispin Cowan, Perry Wagle, Calton Pu, Steve Beattie, and Jonathan Walpole Department of Computer Science and Engineering Oregon Graduate Institute of Science & Technology ([email protected]) http://www.cse.ogi.edu/DISC/projects/immunix Abstract bility presents the attacker with exactly what they need: Buffer overflows have been the most common the ability to inject and execute attack code. The form of security vulnerability for the last ten injected attack code runs with the privileges of the vul- years. More over, buffer overflow vulnerabilities nerable program, and allows the attacker to bootstrap dominate the area of remote network penetra- whatever other functionality is needed to control tion vulnerabilities, where an anonymous Inter- (“own” in the underground vernacular) the host com- net user seeks to gain partial or total control of puter. a host. If buffer overflow vulnerabilities could be effectively eliminated, a very large portion of For instance, among the five “new” “remote to the most serious security threats would also be local” attacks used in the 1998 Lincoln Labs intrusion eliminated. In this paper, we survey the various detection evaluation, three were essentially social engi- types of buffer overflow vulnerabilities and neering attacks that snooped user credentials, and two attacks, and survey the various defensive mea- were buffer overflows. 9 of 13 CERT advisories from sures that mitigate buffer overflow vulnerabili- 1998 involved buffer overflows [34] and at least half of ties, including our own StackGuard method. We 1999 CERT advisories involve buffer overflows [5]. An then consider which combinations of techniques informal survey on the Bugtraq security vulnerability can eliminate the problem of buffer overflow mailing list [29] showed that approximately 2/3 of vulnerabilities, while preserving the functional- respondents felt that buffer overflows are the leading ity and performance of existing systems. cause of security vulnerability.1 1 Introduction Buffer overflow vulnerabilities and attacks come in Buffer overflows have been the most common form a variety of forms, which we describe and classify in Section 2. Defenses against buffer overflow attacks of security vulnerability in the last ten years. More similarly come in a variety of forms, which we describe over, buffer overflow vulnerabilities dominate in the in Section 3, including which kinds of attacks and vul- area of remote network penetration vulnerabilities, nerabilities these defenses are effective against. The where an anonymous Internet user seeks to gain partial Immunix project has developed the StackGuard defen- or total control of a host. Because these kinds of attacks enable anyone to take total control of a host, they repre- sive mechanism [14, 11], which has been shown to be highly effective at resisting attacks without compromis- sent one of the most serious classes security threats. ing system compatibility or performance [9]. Section 4 Buffer overflow attacks form a substantial portion discusses which combinations of defenses complement of all security attacks simply because buffer overflow each other. Section 5 presents our conclusions. vulnerabilities are so common [15] and so easy to exploit [30, 28, 35, 20]. However, buffer overflow vul- 2 Buffer Overflow Vulnerabilities and nerabilities particularly dominate in the class of remote penetration attacks because a buffer overflow vulnera- Attacks The overall goal of a buffer overflow attack is to *. This work supported in part by DARPA grant F30602-96-1- subvert the function of a privileged program so that the 0331, and DARPA contract DAAH01-99-C-R206. attacker can take control of that program, and if the pro- gram is sufficiently privileged, thence control the host. (c) Copyright 1999 IEEE. Reprinted, with permission, from Typically the attacker is attacking a root program, and Proceedings of DARPA Information Survivability immediately executes code similar to “exec(sh)” to get Conference and Expo (DISCEX), http:// a root shell, but not always. To achieve this goal, the schafercorp-ballston.com/discex/ attacker must achieve two sub-goals: To appear as an invited talk at SANS 2000 (System 1.The remaining 1/3 of respondants identified Administration and Network Security), http:// “misconfiguration” as the leading cause of security www.sans.org/newlook/events/sans2000.htm vulnerability. — 1 — 1. Arrange for suitable code to be available in the pro- weak or non-existent bounds checking on its input with gram's address space. a goal of corrupting the state of an adjacent part of the 2. Get the program to jump to that code, with suitable program’s state, e.g. adjacent pointers, etc. By over- parameters loaded into registers & memory. flowing the buffer, the attacker can overwrite the adja- cent program state with a near-arbitrary2 sequence of We categorize buffer overflow attacks is in terms of bytes, resulting in an arbitrary bypass of C’s type sys- achieving these two sub-goals. Section 2.1 describes tem3 and the victim program’s logic. how the attack code is placed in the victim program’s address space (which is where the “buffer” part comes The classification here is the kind of program state that the attacker’s buffer overflow seeks to corrupt. In from). Section 2.2 describes how the attacker overflows principle, the corrupted state can be any kind of state. a program buffer to alter adjacent program state (which For instance, the original Morris Worm [37] used a is where the “overflow” part comes from) to induce the buffer overflow against the program to cor- victim program to jump to the attack code. Section 2.3 fingerd rupt the name of a file that would execute. In discusses some issues in combining the code injection fingerd techniques from Section 2.1 with the control flow cor- practice, most buffer overflows found in “the wild” seek to corrupt code pointers: program state that points ruption techniques from Section 2.2. at code. The distinguishing factors among buffer over- flow attacks is the kind of state corrupted, and where in 2.1 Ways to Arrange for Suitable Code to Be in the memory layout the state is located. the Program's Address Space Activation Records: Each time a function is called, it There are two ways to arrange for the attack code to lays down an activation record on the stack [1] that be in the victim program’s address space: either inject includes, among other things, the return address that it, or use what is already there. the program should jump to when the function exits, Inject it: The attacker provides a string as input to the i.e. point at the code injected in Section 2.1. Attacks program, which the program stores in a buffer. The that corrupt activation record return addresses over- string contains bytes that are actually native CPU flow automatic variables, i.e. buffers local to the instructions for the platform being attacked. Here function, as shown in Figure1. By corrupting the the attacker is (ab)using the victim program’s buff- return address in the activation record, the attacker ers to store the attack code. Some nuances on this causes the program to jump to attack code when the method: victim function returns and dereferences the return address. This form of buffer overflow is called a • The attacker does not have to overflow any buff- “stack smashing attack” [14, 30, 28, 35] and consti- ers to do this; sufficient payload can be injected tute a majority of current buffer overflow attacks into perfectly reasonable buffers. Function Pointers: “void (* foo)()” declares • The buffer can be located anywhere: the variable foo which is of type “pointer to func- tion returning .” Function pointers can be allo- • on the stack (automatic variables) void cated anywhere (stack, heap, static data area) and so • on the heap (malloc’d variables) the attacker need only find an overflowable buffer • in the static data area (initialized or uninitial- adjacent to a function pointer in any of these areas ized) and overflow it to change the function pointer. Some time later, when the program makes a call It is already there: Often, the code to do what the through this function pointer, it will instead jump to attacker wants is already present in the program’s the attacker's desired location. An example of this address space. The attacker need only parameterize kind of attack appeared in an attack against the the code, and then cause the program to jump to it. superprobe program for Linux. For instance, if the attack code needs to execute “exec(“/bin/sh”)”, and there exists code in Longjmp buffers: C includes a simple checkpoint/roll- libc that executes “exec(arg)” where “arg” is a back system called setjmp/longjmp. The idiom is to string pointer argument, then the attacker need only say “setjmp(buffer)” to checkpoint, and say change a pointer to point to “/bin/sh” and jump “longjmp(buffer)” to go back to the check- to the appropriate instructions in the libc library point. However, if the attacker can corrupt the state [41]. of the buffer, then “longjmp(buffer)” will 2.2 Ways to Cause the Program to Jump to the 2.There are some bytes that are hard to inject, such as control Attacker's Code characters and null bytes that have special meaning to I/O All of these methods seek to alter the program’s libraries, and thus may be filtered before they reach the control flow so that the program will jump to the attack program’s memory. code. The basic method is to overflow a buffer that has 3.That this is possible is an indication of the weakness of C’s type system. — 2 — ize the code. For instance, there are code fragments in FFFF libc (linked to virtually every C program) that do Attack “exec(something)” where “something” is a parameter.
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages11 Page
-
File Size-