torsdag 23 april 2009

CSSLP-uppsats 3: Secure Software Implementation/Coding

Här kommer min tredje uppsats för CSSLP-certifieringen. Ämnesområdet är Secure Software Implementation/Coding. Mer specifikt om buffer overflow.


The devil is in the details – an idiom suitable for secure coding. To build a secure system it doesn’t suffice with a good design. Many notorious security problems are coding errors such as a buffer overflow, a format string bug or a double free. To write secure code a developer needs to know how security attacks against these bugs work.

We will here briefly explain what a buffer overflow is and how an attack works.

The Basic Problem
The underlying reason that intrusions ”executing arbitrary code” are possible is that computers are general machines built to execute the instructions in memory whether these instructions do good or bad. An attacker’s goal is often to inject his/her own code and redirect the execution flow to the attack code instead of the original code. These kinds of attacks are known as code injection attacks.

Overflowing a Buffer
Simple, linear sets of data are called arrays or buffers. They are allocated as continuous chunks of memory and allow for quick access and insertion of data. The boundaries of such memory buffers need to be enforced by either the operating environment such as a virtual machine or the application itself.

Applications written in Java or C# get the boundary checks for free from the virtual machine but applications written in C or C++ have to check buffer boundaries themselves. This means that the application developer for instance has to write code to check that data copied into a buffer actually fits in the buffer. If he or she forgets about this a buffer overflow is possible. Such overflows where data spills over into adjacent memory often cause application crashes.

A Buffer Overflow Attack
If the application user can affect the data being copied into an overflowable buffer he or she might be able to design the data to manipulate the execution flow. The execution can be redirected to any available code in memory, possibly injected code of the attacker’s choice.

The two basic requirements for a buffer overflow attack are:
  1. Possibility to inject attack code or attack parameters
  2. Possibility to overwrite a code pointer
The first requirement is covered if there is an overflowable buffer. If the attacker wants to inject code the memory segment that holds the buffer needs to be executable. If the attacker instead injects parameters to a loaded function, e.g. the parameter ”/bin/sh” to the library function system(), the buffer memory doesn’t need to be executable.

Overwriting a code pointer means changing a memory value that points to code that is to be executed. Examples of such code pointers are the return address, function pointers, longjump buffers, and global offset table entries. The code pointer can either be overwritten directly through the buffer overflow or indirectly via a general pointer.

For further information on attacks and effective countermeasures we’d like to refer to our paper "A Comparison of Publicly Available Tools for Dynamic Buffer Overflow Prevention" [1].


References
[1] J. Wilander and M. Kamkar. A Comparison of Publicly Available Tools for Dynamic Buffer Overflow Prevention. In Proceedings of the 10th Network and Distributed System Security Symposium (NDSS'03), in San Diego, California. Pages 149--162, February 5-7, 2003.

Submitted by John Wilander (john.wilander@omegapoint.se) in partial fulfillment of the CSSLP experience assessment requirements.

1 kommentar:

AMIT sa...

So you know coding very well.Its a very good thing.And thanks for this post.

Minnesota Drug Rehab