1

For a heap overflow to occur and arbitrary code to be executed, the function free() performs the step :

hdr->next->next->prev = hdr->next->prev

I understand that the address of hdr->next->next->prev is calculated as hdr->next->next + 4 . Pretty clear.

Now, this value will be overwritten by the address hdr->next->prev which is controlled by the attacker and which contains the shell code possibly in the heap itself(assuming it is executable)

The target address i.e. the value in hdr->next->next in a vanilla heap overflow should be the address in the stack that stores the return address after free() has completed its job.

Q1. How does an attacker determine the Exact address of the return pointer of free() on the stack ?

Q2. The whole reason this occurs is because the pointer adds 4 to the hdr->next->next value to write the prev pointer. Has this been fixed or is it still one of the reasons for current heap overflows. (The reason why I'm asking this is, I am aware of other heap exploitations such as double free and so on, just want to make sure if the primitive reason was fixed)

1 Answer 1

2

A great, in-depth resource on a buffer overflow attack is the Smashing the Stack tutorial by Aleph One. While stack overflow and heap overflow are subtly different, the techniques are similar/related.

Felix "FX" Lindner writes an excellent article (2006) on The H Security which describes your exploit in depth. Condensed version below; strongly recommend the full article for clarity.

In answer to Q1, determining the exact address pointer for the stack is the catch. Often - because of stack allocation, varying program and data length, etc, you can't detect the exact position without significant knowledge of the memory layout . Instead, a common technique is to pad a series of instructions around the payload code in an attempt to "hit" the stack pointer. A series of NOP instructions are written before the payload code so that "if" the SP is caught in the resulting buffer overflow, the SP will advance until it runs your payload. For the case where the SP is "after" your payload code, you might write a series of JMP instructions all pointing to the head of the payload. (See the tutorial; Aleph covers this process in detail).

The goal of this heap overflow is to corrupt heap record metadata just prior to the 'write' operation implicit in the assignment of hdr->next->prev to hdr->next->next->prev. With the linked list corrupted, it is possible to overwrite the return address used by the end of free on the stack.

In answer to Q2, I'll assume you're asking about the GNU Libc implementation of free(). Other implementations will likely have different code. Multiple sanity checks now exist to prevent invalid sized objects and double free, etc. (See the _int_free() and related functions in Git). This is not to say (definitively) the vector is impossible through other means, but it is more difficult now.

A third (draft?) source of information on this subject is a whitepaper by Justin Ferguson: Understanding the Heap by Breaking It

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .