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>