— 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.
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  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
: 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.
Each time a function is called, itlays down an
on the stack  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
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.
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 “
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.