Buffer Overflow

1. Understanding Buffer Overflows

Buffer overflow is a condition in a program where a function attempts to copy more data into a buffer than it can hold. The extra data that cannot be stored, then replaces/overrides another piece of data on the stack.

Suppose the computer allocates a buffer of 40 bytes (or pieces) of memory to store 10 integers (4 bytes per integer)

An attacker sends the computer 11 integers (a total of 44 bytes) as input.

Whenever was in the location after the ten 40 bytes (allocated for our buffer), gets overwritten with the 11th integer of our input.

Remember that the stack grows backward. Therefore the data in the buffer are copied from lowest memory addresses to the highest memory addresses.

One of the vulnerable function in C is strcpy() function, which allows buffer overflows to happen, because it has no limit on how big the copied data should be. Using this function, we can overwrite the stack and alter the code flow. The safer alternative of strcpy() is strncpy()

Example:

Suppose we have the following code:

int main(int argc, char** argv)
{
  argv[1] = (char*)"AAABBBCCCDDDEEEFFFGGGHHHI"
  char buffer[10];
  strnpy(buffer, argv[1], sizeof(buffer));
  return 0;
}

The following is the new stack frame process review:

  1. Push the function parameters

  2. Call the function

  3. Execute the prologue (which updates EBP and ESP to create the new stack frame)

  4. Allocate local variables

Before

...

Other local variables

Buffer[10]

EBP

Function return address (EIP)

Parameters of function

Local variables of main

Return address of main

Parameters of main

...

After

...

Other local variables

AAAB

BBCC

CDDD

EEEF

FFFG

GGHH

HI

...

As a pentester, you can replace EIP with the address of the payload you wish to run. This is where it is important to know memory addresses of certain registers.

We can use a helper in order to pass the hexadecimal code as an argument with a 'filler' data. Below is an example of a helper:

import sys
import os

payload = "\x41"*22 # \x41 = ASCII for 'A', which is a 'filler' data
payload += "\x48\x15\x40"
command = "goodpwd.exe %s" %(payload)

print path
os.system(command)

We did not add \x00 (NULL) byte, in order for the stycpy() to not to stop copying data.

Note : Watch Vivek Ramachandran videos

Last updated