Heap-Exploitation
Preview
- Double Free
- Making malloc return an already allocated fastchunk
- Forging chunks
- Making malloc return a nearly arbitrary pointer
- Unlink Explit
- Getting (nearly) arbitrary write access
- OFF-BY-ONE
- Depending on the one-byte-overflow
- House of Spirit
- Making malloc return a nearly arbitrary pointer
- House of Lore
- Making malloc return a nearly arbitrary pointer
- House of Force
- Making malloc return a nearly arbitrary pointer
- House of Einherjar
- Making malloc return a nearly arbitrary pointer
First-Fit
normal bins
- Whenever any chunk (not a fastchunk) is free()’d, it ends up in the unsorted bin.
- Insertion happens at the HEAD of the list.
- On requesting new chunks (not fast chunk), initially unsorted bins will be looked up as small bins will be empty.
- If a single chunk is present in the unsorted bin, an exact check is not made and if the chunk’s >= the one requested, it will be splited inti two and the chunk of requested size will be returned.
Example
Step1
|
|

Step2
|
|

Step3
|
|

fastbins
- This is also true in the case of fast chunks. Instead of freeing into unsorted bin, fast
chunks end up in fastbins . - As mentioned earlier, fastbins maintain a singly linked listand chunks are inserted and deleted from the HEAD end. This reverses the order of chunksobtained.
Example
Step 1
|
|
fastbins list
HEAD -> TAIL
Step 2
|
|
fastbins list
HEAD -> d -> c -> b -> a -> TAIL
Step 3
|
|
fastbins list
HEAD -> b -> a -> TAIL
Step 4
|
|
fastbins list
HEAD -> TAIL
PS:
Due to that Insertions happen at HEAD and removals happen at HEAD as well
a’ == d
b’ == c
c’ == b
d’ == a
Use after Free Vulnerability
- malloc might return chunks that were ealier used and free()’d.
- Once a chunk has been free()’d, it should be assumed that the attacker can now control the data inside the chunk.
- That particular chunk should never be used again. Instead, always allocate a new chunk.
Example
|
|
Double Free
- Freeing a resource more than can lead to memory leaks. The allocator’s data structures get corrupted and can be exploited by an attacker.
- In the sample program below, a fastbin chunk will be free()’d twice.
- To avoid
double freeorcorruption (faststop)security check by glibc, another chunk will be free()’d in between the two free()s. - The same chunk will be returned by two different
malloc. Both the pointers will point to the same memory address. - Attacker can change the chunk by using any pointer of these two.
Example
Step 1
|
|
Step 2
|
|

Step 3
|
|
Exploit
Arbitrary Write
- Change bytes of malloc()d d to change FD to address of faked fastbin.
- free() d, so f->FD == &faked fastbin
- free() f, so faked fastbin will be in fastbins list of this size.
malloc() for the same type of size fastbin chunk, we can control faked chunk mem.
Leak Address
free() d, so f->FD will be set by glibc
- puts(f), so we get f->FD as a address of a fastbin in HEAP
Forging chchunks
- After a chunk is freed, it is inserted in a list of bins. However the pointer is still available in the program.
- Attacker may use the pointer to control the list of bins and insert his own forged chunk into this list.
Example
In the case of fastbin freelist
|
|
- The forged chunk’s size parameter was set equal to 0x20 (which is the size of a), so it can be inserted into the same fastbin_list of this size (So that it passes the security check “malloc(): memory corruption (fast)”).
- malloc() return is equal to chunk.fd when it is free()’d
Unlink Exploit
http://blog.flier.net.cn/2017/10/16/unlink/
OFF-BY-ONE
This kind of EXP makes use of the one-byte-heap-overflow
What is off-by-one heap overflow

- When (P->SIZE & 0x1) == 1 (P->PREV_INUSE == 1), P->PREV_SIZE may be used by the previous chunk as data.
- However, if P->PREV_INUSE == 0, P->PREV_SIZE will be used in UNLINK.
- malloc() a chunk whose size is special.

- Then we call strcpy(a string which size == 124) (etc. ), we can overflow PREV_INUSE to 0.
Example
Step 1
We get two chunks, and the chunk_2 can be off-by-one attacked.
|
|
Step 2
Make a buf consisting of a fake chunk header and some “A” and a lowest byte of next_chunk->SIZE.
|
|
Step 3
free() chunk_3 to unlink our fake chunk header
|
|
Overview
BEFORE FREE

AFTER FREE ( UNLINK )

EXP
- Use the overwrited malloc_return_ptr (which now points to &ptr - 3 now) to overwrite near malloc reutrn ptrs to GOT table.
- Use the overwrited ptrs to overwrite GOT
- free(a) —–> system(a) , etc.
to be continue ……