In association with heise online


Two types of errors can cause a heap overflow: either the size of allocated memory is static and an attacker can make sure that too much data is written into it; or, the calculation for how much memory to allocate was in error due to being based on information from the attacker.

Whatever the reason for the heap overflow, attackers can always write forwards in the memory, but not backwards. In other words, the overflow cannot overwrite its own heap header, which is at the front of the data block, but it can overwrite one or more of the subsequent headers.

Here, an important distinction between a buffer overflow on the stack and one on the heap becomes clear: attackers have to know which heap implementation the program is currently using in order to prepare management information with the right manipulated values. In contrast, the stack layout is more or less the same no matter what program is running, and it basically does not matter which values are overwritten aside from the return address.

Another difference makes life harder for attackers: unlike the stack, no memory areas can be overwritten on the heap that the program uses directly as a jump address. He may only manipulate data for heap management -- in other words, the pointers next and prev as well as the fields size and used.

It therefore becomes clear that SimpleHeap has to perform other operations on the heap if overwritten values can be used at all. If the program is terminated directly after an overflow, the overwritten values are useless and the attack unsuccessful. However, one obvious candidate for a targeted attack is the function SimpleHeap_free(), which has to be called at some point for each allocated block.

To have their own code executed, attackers have to make sure that the victim's system overwrites an area of memory from which it will later load a jump address. The pointer operations with next and prev in SimpleHeap are promising candidates for this purpose.

If we now take a look at SimpleHeap_free() from this perspective, the process of defragmentation is immediately striking. Here, management information which can be readily manipulated is used for write operations. In particular, in


attackers can control both the value which is to be written and the target address, if they manage that hdr->next points to a header that they have created with an overflow. They then only need to set the used field to 0 for SimpleHeap to execute the command when the buffer is released. The correct values in hdr->next->prev and hdr->next->next->prev ensure that the memory location chosen by the attacker will be overwritten with a particular value. In principle, with hdr->next attackers can control all further dereferencing. This is also illustrated by the assembler code, generated by the compiler for the critical statement (but that is not necessary for understanding the rest of the article).


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


mov eax, [ebp+hdr]   ; EAX = hdr
mov ecx, [eax] ; ECX = data at the address in EAX, so that
; ECX = hdr->next
mov edx, [ebp+hdr] ; EDX = hdr
mov eax, [edx] ; EAX = data at the address in EDX, so that
; EAX = hdr->next
mov edx, [eax] ; EDX = data at the address in EAX, so that
; EDX = hdr->next->next
mov eax, [ecx+4] ; EAX = data at the address in ECX + 4, so that
; EAX = hdr->next->prev
mov [edx+4], eax ; Daten at the address in EDX + 4 = EAX, so that
; hdr->next->next->prev = hdr->next->prev
Print Version | Permalink:
  • Twitter
  • Facebook
  • submit to slashdot
  • StumbleUpon
  • submit to reddit

  • July's Community Calendar

The H Open

The H Security

The H Developer

The H Internet Toolkit