Writing buffer overflow exploits - a tutorial for beginners
===========================================================
Security papers - members.tripod.com/mixtersecurity/papers.html
Buffer overflows in user input dependent buffers have become one of
the biggest security hazards on the internet and to modern computing in
general. This is because such an error can easily be made at programming
level, and while invisible for the user who does not understand or cannot
acquire the source code, many of those errors are easy to exploit. This
paper makes an attempt to teach the novice - average C programmer how an
overflow condition can be proven to be exploitable.
[hide=10]
_______________________________________________________________________________
1. Memory
Note: The way I describe it here, memory for a process is organized on most
computers, however it depends on the type of processor architecture.
This example is for x86 and also roughly applies to sparc.
The principle of exploiting a buffer overflow is to overwrite parts of
memory which aren't supposed to be overwritten by arbitrary input and
making the process execute this code. To see how and where an overflow
takes place, lets take a look at how memory is organized.
A page is a part of memory that uses its own relative addressing, meaning
the kernel allocates initial memory for the process, which it can then
access without having to know where the memory is physically located in
RAM. The processes memory consists of three sections:
- code segment, data in this segment are assembler instructions that
the processor executes. The code execution is non-linear, it can skip
code, jump, and call functions on certain conditions. Therefore, we
have a pointer called EIP, or instruction pointer. The address where
EIP points to always contains the code that will be executed next.
- data segment, space for variables and dynamic buffers
- stack segment, which is used to pass data (arguments) to functions
and as a space for variables of functions. The bottom (start) of the
stack usually resides at the very end of the virtual memory of a page,
and grows down. The assembler command PUSHL will add to the top of the
stack, and POPL will remove one item from the top of the stack and put
it in a register. For accessing the stack memory directly, there is
the stack pointer ESP that points at the top (lowest memory address)
of the stack.
_______________________________________________________________________________
2. Functions
A function is a piece of code in the code segment, that is called,
performs a task, and then returns to the previous thread of execution.
Optionally, arguments can be passed to a function. In assembler, it
usually looks like this (very simple example, just to get the idea):
memory address code
[code]0x8054321 <main+x>