Welcome to Scribd, the world's digital library. Read, publish, and share books and documents. See more
Standard view
Full view
of .
Look up keyword
Like this
0 of .
Results for:
No results containing your search query
P. 1


Ratings: (0)|Views: 1,390|Likes:

More info:

Published by: Ruslan_Khakimov_4413 on Nov 17, 2012
Copyright:Attribution Non-commercial


Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less





— 1 —Abstract
 Buffer overflows have been the most common form of security vulnerability for the last ten years. More over, buffer overflow vulnerabilitiesdominate the area of remote network penetra-tion vulnerabilities, where an anonymous Inter-net user seeks to gain partial or total control of a host. If buffer overflow vulnerabilities could be effectively eliminated, a very large portion of the most serious security threats would also beeliminated. In this paper, we survey the varioustypes of buffer overflow vulnerabilities and attacks, and survey the various defensive mea-sures that mitigate buffer overflow vulnerabili-ties, including our own StackGuard method. Wethen consider which combinations of techniquescan eliminate the problem of buffer overflowvulnerabilities, while preserving the functional-ity and performance of existing systems.
Buffer overflows have been the most common formof security vulnerability in the last ten years. Moreover, buffer overflow vulnerabilities
in thearea of remote network penetration vulnerabilities,where an anonymous Internet user seeks to gain partialor total control of a host. Because these kinds of attacksenable anyone to take total control of a host, they repre-sent one of the most serious classes security threats.Buffer overflow attacks form a substantial portionof all security attacks simply because buffer overflowvulnerabilities are so common [15] and so easy toexploit [30, 28, 35, 20]. However, buffer overflow vul-nerabilities
dominate in the class of remotepenetration attacks because a buffer overflow vulnera-bility presents the attacker with exactly what they need:the ability to inject and execute attack code. Theinjected attack code runs with the privileges of the vul-nerable program, and allows the attacker to bootstrapwhatever other functionality is needed to control(“own” in the underground vernacular) the host com-puter.For instance, among the five “new” “remote tolocal” attacks used in the 1998 Lincoln Labs intrusiondetection evaluation, three were essentially social engi-neering attacks that snooped user credentials, and twowere buffer overflows. 9 of 13 CERT advisories from1998 involved buffer overflows [34] and at least half of 1999 CERT advisories involve buffer overflows [5]. Aninformal survey on the Bugtraq security vulnerabilitymailing list [29] showed that approximately 2/3 of respondents felt that buffer overflows are the leadingcause of security vulnerability.
Buffer overflow vulnerabilities and attacks come ina variety of forms, which we describe and classify inSection 2. Defenses against buffer overflow attackssimilarly come in a variety of forms, which we describein Section 3, including which kinds of attacks and vul-nerabilities these defenses are effective against. TheImmunix project has developed the StackGuard defen-sive mechanism [14, 11], which has been shown to behighly effective at resisting attacks without compromis-ing system compatibility or performance [9]. Section 4discusses which combinations of defenses complementeach other. Section 5 presents our conclusions.
2Buffer Overflow Vulnerabilities andAttacks
The overall goal of a buffer overflow attack is tosubvert the function of a privileged program so that theattacker can take control of that program, and if the pro-gram is sufficiently privileged, thence control the host.Typically the attacker is attacking a
program, andimmediately executes code similar to “exec(sh)” to geta
shell, but not always. To achieve this goal, theattacker must achieve two sub-goals:
uer verows:Attacks and Defenses for the Vulnerability of the Decade
Crispin Cowan, Perry Wagle, Calton Pu,Steve Beattie, and Jonathan WalpoleDepartment of Computer Science and EngineeringOregon Graduate Institute of Science
*. This work supported in part by DARPA grant F30602-96-1-0331, and DARPA contract DAAH01-99-C-R206.(c) Copyright 1999 IEEE. Reprinted, with permission, fromProceedings of DARPA Information SurvivabilityConference and Expo (DISCEX),
To appear as an invited talk at SANS 2000 (SystemAdministration and Network Security),
1.The remaining 1/3 of respondants identified“misconfiguration” as the leading cause of securityvulnerability.
— 2 —
1.Arrange for suitable code to be available in the pro-gram's address space.2.Get the program to jump to that code, with suitableparameters loaded into registers & memory.We categorize buffer overflow attacks is in terms of achieving these two sub-goals. Section 2.1 describeshow the attack code is placed in the victim program’saddress space (which is where the “buffer” part comesfrom). Section 2.2 describes how the attacker overflowsa program buffer to alter adjacent program state (whichis where the “overflow” part comes from) to induce thevictim program to jump to the attack code. Section 2.3discusses some issues in combining the code injectiontechniques from Section 2.1 with the control flow cor-ruption techniques from Section 2.2.
2.1 Ways to Arrange for Suitable Code to Be inthe Program's Address Space
There are two ways to arrange for the attack code tobe in the victim program’s address space: either injectit, or use what is already there.
Inject it:
The attacker provides a string as input to theprogram, which the program stores in a buffer. Thestring contains bytes that are actually native CPUinstructions for the platform being attacked. Herethe attacker is (ab)using the victim program’s buff-ers to store the attack code. Some nuances on thismethod:The attacker does not have to overflow any buff-ers to do this; sufficient payload can be injectedinto perfectly reasonable buffers.The buffer can be located anywhere:on the stack (automatic variables)on the heap (malloc’d variables)in the static data area (initialized or uninitial-ized)
It is already there:
Often, the code to do what theattacker wants is already present in the program’saddress space. The attacker need only parameterizethe code, and then cause the program to jump to it.For instance, if the attack code needs to execute
”, and there exists code inlibc that executes “
)” where “arg” is astring pointer argument, then the attacker need onlychange a pointer to point to “
” and jumpto the appropriate instructions in the
2.2 Ways to Cause the Program to Jump to theAttacker's Code
All of these methods seek to alter the program’scontrol flow so that the program will jump to the attack code. The basic method is to
a buffer that hasweak or non-existent bounds checking on its input witha goal of corrupting the state of an
part of theprogram’s state, e.g. adjacent pointers, etc. By over-flowing the buffer, the attacker can overwrite the adja-cent program state with a near-arbitrary
sequence of bytes, resulting in an arbitrary bypass of C’s type sys-tem
and the victim program’s logic.The classification here is the kind of program statethat the attacker’s buffer overflow seeks to corrupt. Inprinciple, the corrupted state can be
kind of state.For instance, the original Morris Worm [37] used abuffer overflow against the
program to cor-rupt the name of a file that
would execute. Inpractice, most buffer overflows found in “the wild”seek to corrupt
code pointers
: program state that pointsat code. The distinguishing factors among buffer over-flow attacks is the kind of state corrupted, and where inthe memory layout the state is located.
Activation Records:
Each time a function is called, itlays down an
activation record 
on the stack [1] thatincludes, among other things, the return address thatthe program should jump to when the function exits,i.e. point at the code injected in Section 2.1. Attacksthat corrupt activation record return addresses over-flow automatic variables, i.e. buffers local to thefunction, as shown in Figure1. By corrupting thereturn address in the activation record, the attackercauses the program to jump to attack code when thevictim function returns and dereferences the returnaddress. This form of buffer overflow is called a“stack smashing attack” [14, 30, 28, 35] and consti-tute a majority of current buffer overflow attacks
Function Pointers:
void (* foo)()
” declaresthe variable
which is of type “pointer to func-tion returning
.” Function pointers can be allo-cated anywhere (stack, heap, static data area) and sothe attacker need only find an overflowable bufferadjacent to a function pointer in any of these areasand overflow it to change the function pointer.Some time later, when the program makes a callthrough this function pointer, it will instead jump tothe attacker's desired location. An example of thiskind of attack appeared in an attack against the
program for Linux.
Longjmp buffers:
C includes a simple checkpoint/roll-back system called setjmp/longjmp. The idiom is tosay “
” to checkpoint, and say
” to go back to the check-point. However, if the attacker can corrupt the stateof the buffer, then “
” will
2.There are some bytes that are hard to inject, such as controlcharacters and null bytes that have special meaning to I/Olibraries, and thus may be filtered before they reach theprogram’s memory.3.That this is possible is an indication of the weakness of C’stype system.
— 3 —
 jump to the attacker's code instead. Like functionpointers,
buffers can be allocated any-where, so the attacker need only find an adjacentoverflowable buffer. An example of this form of attack appeared against Perl 5.003. The attack firstcorrupted a
buffer used to recover whenbuffer overflows are detected, and then induces therecovery mode, causing the Perl interpreter to jumpto the attack code.
2.3 Combining Code Injection and ControlFlow Corruption Techniques
Here we discuss some issues in combining theattack code injection (Section 2.1) and control flow cor-ruption (Section 2.2) techniques.The simplest and most common form of bufferoverflow attack combines an injection technique withan activation record corruption in a single string. Theattacker locates an overflowable automatic variable,feeds the program a large string that simultaneouslyoverflows the buffer to change the activation record,and contains the injected attack code. This is the tem-plate for an attack outlined by Levy [30]. Because the Cidiom of allocating a small local buffer to get user orparameter input is so common, there are a lot of instances of code vulnerable to this form of attack.The injection and the corruption do not have to hap-pen in one action. The attacker can inject code into onebuffer without overflowing it, and overflow a differentbuffer to corrupt a code pointer. This is typically doneif the overflowable buffer
have bounds checkingon it, but gets it wrong, so the buffer is only overflow-able up to a certain number of bytes. The attacker doesnot have room to place code in the vulnerable buffer, sothe code is simply inserted into a different buffer of suf-ficient size.If the attacker is trying to use already-resident codeinstead of injecting it, they typically need to parameter-ize the code. For instance, there are code fragments in
(linked to virtually every C program) that do
” where “
” is aparameter. The attacker then uses buffer overflows tocorrupt the argument, and another buffer overflow tocorrupt a code pointer to point into
at the appro-priate code fragment.
3Buffer Overflow Defenses
There are four basic approaches to defendingagainst buffer overflow vulnerabilities and attacks. Thebrute force method of writing correct code is describedin Section 3.1. The operating systems approachdescribed in Section 3.2 is to make the storage areas forbuffers non-executable, preventing the attacker frominjecting attack code This approach stops many bufferoverflow attacks, but because attackers do not necessar-ily need to inject attack code to perpetrate a buffer over-flow attack (see Section 2.1) this method leavessubstantial vulnerabilities. The direct compilerapproach described in Section 3.3 is to perform arraybounds checks on all array accesses. This method com-pletely eliminates the buffer overflow problem by mak-ing overflows impossible, but imposes substantialcosts. The indirect compiler approach described in Sec-tion 3.4 is to perform integrity checks on code pointersbefore dereferencing them. While this technique doesnot make buffer overflow attacks
, it doesstop most buffer overflow attacks, and the attacks that itdoes not stop are difficult to create, and the compatibil-ity and performance advantages over array boundschecking are substantial, as described in Section 3.5.
3.1 Writing Correct Code
“To err is human, but to really foul up requires acomputer.” -- Anon. Writing correct code is a laudablebut remarkably expensive proposition [13, 12], espe-cially when writing in a language such as C that haserror-prone idioms such as null-terminated strings and aculture that favors performance over correctness.Despite a long history of understanding of how to writesecure programs [6] vulnerable programs continue toemerge on a regular basis [15]. Thus some tools andtechniques have evolved to help novice developerswrite programs that are somewhat less likely to containbuffer overflow vulnerabilities.The simplest method is to
the source code forhighly vulnerable library calls such as
that do not check the length of their argu-ments. Versions of the C standard library have alsobeen developed that complain when a program links tovulnerable functions like
.Code auditing teams have appeared [16, 2] with anexplicit objective of auditing large volumes of code byhand, looking for common security vulnerabilities suchas buffer overflows and file system race conditions [7].However, buffer overflow vulnerabilities can be subtle.Even defensive code that uses safer alternatives such as
 AttackcodereturnaddressLocalvariables buffer
Figure 1: Buffer Overflow Attack AgainstActivation Record

You're Reading a Free Preview

/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->