07-02-2013, 03:47 PM
A Taxonomy of Buffer Overflow Characteristics
1A Taxonomy of Buffer.pdf (Size: 352.53 KB / Downloads: 18)
Abstract
Significant work on vulnerabilities focuses on buffer overflows, in which data exceeding the bounds of an array is loaded
into the array. The loading continues past the array boundary, causing variables and state information located adjacent to the array to
change. As the process is not programmed to check for these additional changes, the process acts incorrectly. The incorrect action
often places the system in a nonsecure state. This work develops a taxonomy of buffer overflow vulnerabilities based upon
characteristics, or preconditions that must hold for an exploitable buffer overflow to exist. We analyze several software and hardware
countermeasures to validate the approach. We then discuss alternate approaches to ameliorating this vulnerability.
INTRODUCTION
BUFFER overflows occur when a sequence of bytes of length
n is placed into an array, or buffer, of length less than n.
This simple error is all too common. In this paper, we focus
on the buffer overflows that cause security problems.
It is well documented that buffer overflows can cause
security problems. For example, a buffer overflow allowed
a worm entry into a large number of UNIX systems in 1988
[1], [2], [3]. The trend has continued, with buffer overflows
providing entry points for worms such as Blaster [4],
Slammer [5], Apache/mod_ssl [6], and Code Red [7], [8].
Buffer overflows have also created other vulnerabilities in
various programs and systems. For example, the Common
Vulnerabilities and Exposures list [9] reported 100 buffer
overflows identified in 2011 (so far), 413 identified in 2010,
587 identified in 2009, and 611 identified in 2008. The
problem continues to exist despite efforts to eliminate it.
In this paper, we examine the causes for buffer overflow
vulnerabilities by looking at the factors that create them. We
present a classification scheme that distinguishes among
the different types of buffer overflow vulnerabilities, and use
this scheme to demonstrate the limits of proposed solutions.
This suggests more effective solutions for handling multiple
classes of buffer overflows. We do this by first deriving the
preconditions necessary for the vulnerability to exist based
on how these vulnerabilities are exploited, and then use
pseudocode to refine these preconditions into common
characteristics.
BACKGROUND
Architectural considerations are key to understanding
buffer overflow attacks and defenses. The following discussion
gives a high-level overview of such considerations and
attacks. Aleph-One [16] and Conover [17] present detailed
descriptions of how these attacks work.
Architectural Considerations
During program execution, buffer overflows can occur in
three different areas of process memory: the data area, the
stack, and the heap. The effects are constrained by the area
in which the overflow occurs.
The data area of process memory provides space for
nontransient variables such as global or static variables.
These are defined before the process begins executing and
are not deleted. They may or may not be initialized, but the
memory for this area is typically contiguous. Variables in
this area are bound to fixed virtual memory locations in the
process address space.
Executable Buffer Overflow
An executable buffer overflow occurs when executable code
is loaded into a buffer, and some quantity (a return address
or function pointer) is altered to cause that code to be
executed. Its simplest incarnation involves a buffer allocated
on the stack. The data being entered is typically a set of
machine-language instructions to be executed. The value in
the location where the return address is stored is reset to be
the address of the machine instructions in the buffer. As a
result, when the routine returns, and the value in the location
for the return addresses is popped and put into the Program
Counter (PC), the input machine instructions execute.
Executable Buffer Overflow
First, consider a buffer overflow on the stack. Here, the
attacker inputs a string containing no-ops, a small machinelanguage
program, and multiple copies of an address
corresponding to one in the buffer before the machine
language program. When this string is read and stored on
the stack, it overwrites the return address. When the input
routine returns, the machine-language program is executed.
Stated succinctly, this attack is: “input an extra long
stream of instructions and a return address; the return
address overwrites the one on the stack; on return, the
corrupted address causes a return into the stack and executes
the machine-language program stored there.”
CONCLUSION AND FUTURE WORK
This paper provides a methodology for analyzing buffer
overflow vulnerabilities. It derives specific preconditions that
must hold in order for an attacker to exploit a buffer
overflow vulnerability, and then reframes them in terms of
well-defined characteristics. These are both necessary and
sufficient for the buffer overflows to be exploitable.
The preconditions distinguish among four distinct types
of buffer overflows: direct executable, indirect executable,
direct data, and indirect data. These have common characteristics
as well as different characteristics. This suggests
two approaches.