This excerpt is from Chapter 7, Buffer Overflow of Exploiting Software: How to Break Code written by Greg Hoglund and Gary McGraw, and published by Addison-Wesley Professional. You can download the entire Chapter 7 here for free.
The buffer overflow is the whipping boy of software security. The main
reason for omnipresent discussion and hype surrounding the buffer
overflow is that the buffer overflow remains the principal method used to
exploit software by remotely injecting malicious code into a target. Although
the techniques of buffer overflow have been widely published elsewhere,
this chapter remains a necessity. The buffer overflow has evolved
over the years, as have a number of other attack techniques and, as a result,
powerful new buffer overflow attacks have been developed. If nothing else,
this chapter will serve as a foundation as you come to grips with the subtle
nature of buffer overflows.
Buffer Overflow 101
The buffer overflow remains the crown jewel of attacks, and it is likely to
remain so for years to come. Part of this has to do with the common existence
of vulnerabilities leading to buffer overflow. If holes are there, they
will be exploited. Languages that have out-of-date memory management
capability such as C and C++ make buffer overflows more common than
they should be.1 As long as developers remain unaware of the security rami-
fications of using certain everyday library functions and system calls, the
buffer overflow will remain commonplace.
Control flow and memory vulnerabilities can take many forms. A search
for the words "buffer overflow" using Google returns more than 176,000 hits. Clearly the once-esoteric and closely guarded technique is now all too
common. Yet, most attackers (and defenders) have only the most rudimentary
understanding of buffer overflows and the harm they are capable of
inflicting. Most people with a passing interest in security (those who read
security papers and attend security conferences and trade shows) know that
buffer overflows allow remote code to be injected into a system and then
run. The upshot of this fact is that worms and other sorts of malicious mobile
code have a clear path for attacking a system and leaving behind a backdoor
such as a rootkit. In too many cases, remote code injection via buffer
overflow is possible and a backdoor can be easily installed.
Buffer overflows are a kind of memory usage vulnerability. This is
primarily an accident of computer science history. Memory was once a
precious resource, and thus managing memory was critical. In some older
systems, such as the Voyager spacecraft, memory was so precious that once
certain sections of machine code were no longer needed, the code was erased
forever from the memory module, freeing up space for other uses. This
effectively created a program that was self-destructive and could only be run
once. Contrast this with a modern system in which memory is gobbled up in
huge multimegabyte swaths and almost never released. Most software systems
connected to the network today have abhorrent memory problems,
especially when directly connected to hostile environments like the Internet.
Memory is cheap, but the effects of bad memory management are very expensive.
Bad memory usage can lead to internal corruption within a program
(especially with reference to control flow), denial-of-service problems,
and even remote exploits like buffer overflows.
Ironically, the world already knows how to avoid the buffer overflow
problem; however, knowledge of the solutions, available for years, has done
little to thwart the rampant growth of buffer overflow problems in networked
code. In truth, fixing the problem is well within our grasp technically,
but sociologically we have a longer way to go. The main problem is
that developers for the most part remain blithely unaware of the issue. It is
likely that for the next five to ten years, buffer overflow problems of various
types will continue to plague software.
The most common form of buffer overflow, called the stack overflow,
can be easily prevented by programmers. More esoteric forms of memory corruption, including the heap overflow, are harder to avoid. By and large,
memory usage vulnerabilities will continue to be a fruitful resource for exploiting software until modern languages that incorporate modern memory
management schemes are in wider use.
Download the rest of Chapter 7, Buffer Overflow from Exploiting Software: How to Break Code.