Heap Overflow

Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!

Other ways to support HackTricks:

Basic Information

A heap overflow is like a stack overflow but in the heap. Basically it means that some space was reserved in the heap to store some data and stored data was bigger than the space reserved.

In stack overflows we know that some registers like the instruction pointer or the stack frame are going to be restored from the stack and it could be possible to abuse this. In case of heap overflows, there isn't any sensitive information stored by default in the heap chunk that can be overflowed. However, it could be sensitive information or pointers, so the criticality of this vulnerability depends on which data could be overwritten and how an attacker could abuse this.

In order to find overflow offsets you can use the same patters as in stack overflows.

Stack Overflows vs Heap Overflows

In stack overflows the arranging and data that is going to be present in the stack at the moment the vulnerability can be triggered is fairly reliable. This is because the stack is linear, always increasing in colliding memory, in specific places of the program run the stack memory usually stores similar kind of data and it has some specific structure with some pointers at the end of the stack part used by each function.

However, in the case of a heap overflow, because the used memory isn’t linear but allocated chunks of are usually in separated positions of memory (not one next to the other) because of bins and zones separating allocations by size and because previous freed memory is used before allocating new chunks. It’s complicated to know the object that is going to be colliding with the one vulnerable to a heap overflow. So, when a heap overflow is found, it’s needed to find a reliable way to make the desired object to be next in memory from the one that can be overflowed.

One of the techniques used for this is Heap Grooming which is used for example in this post. In the post it’s explained how when in iOS kernel when a zone run out of memory to store chunks of memory, it expands it by a kernel page, and this page is splitted into chunks of the expected sizes which would be used in order (until iOS version 9.2, then these chunks are used in a randomised way to difficult the exploitation of these attacks).

Therefore, in the previous post where a heap overflow is happening, in order to force the overflowed object to be colliding with a victim order, several kallocs are forced by several threads to try to ensure that all the free chunks are filled and that a new page is created.

In order to force this filling with objects of a specific size, the out-of-line allocation associated with an iOS mach port is an ideal candidate. By crafting the size of the message, it’s possible to exactly specify the size of kalloc allocation and when the corresponding mach port is destroyed, the corresponding allocation will be immediately released back to kfree.

Then, some of these placeholders can be freed. The kalloc.4096 free list releases elements in a last-in-first-out order, which basically means that if some place holders are freed and the exploit try lo allocate several victim objects while trying to allocate the object vulnerable to overflow, it’s probable that this object will be followed by a victim object.

Example libc

In this page it's possible to find a basic Heap overflow emulation that shows how overwriting the prev in use bit of the next chunk and the position of the prev size it's possible to consolidate a used chunk (by making it thing it's unused) and then allocate it again being able to overwrite data that is being used in a different pointer also.

Another example from protostar heap 0 shows a very basic example of a CTF where a heap overflow can be abused to call the winner function to get the flag.

In the protostar heap 1 example it's possible to see how abusing a buffer overflow it's possible to overwrite in a near chunk an address where arbitrary data from the user is going to be written to.

Example ARM64

In the page https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/ you can find a heap overflow example where a command that is going to be executed is stored in the following chunk from the overflowed chunk. So, it's possible to modify the executed command by overwriting it with an easy exploit such as:

python3 -c 'print("/"*0x400+"/bin/ls\x00")' > hax.txt
Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!

Other ways to support HackTricks:

Last updated