HEAP UNLINK ATTACK
WHAT IS UNLINK
|
|
WHEN UNLINK SHOULD BE CALLED
(1) pass the CHECK of UNLINK
FD->bk == P && BK->fd == P(2) prev/after chunk is marked as free()’d
When GLIBC free a chunk, it will going to see whether the chunk before/after is free. If it is, then the chunk before/after will be unlink()’d off its double-linked list and these two chunks merge into one chunk.
HOW TO BYPASS CHECK
(1) got a address of the PTR to the address of &LABEL(fake chunk) ( &chunk header + word_size * 2 )
PTR(the ptr to the fake chunk LABEL)Before Overflow
| PREV_SIZE(get prev LABEL here) | SIZE(lowest bit PREV_USE) |
|---|---|
| the user data(malloc return) | user data |
| …… | …… |
| PREV_SIZE(get prev LABEL here) | SIZE(lowest bit PREV_USE) |
After Overflow(along with with fake chunk make)
| PREV_SIZE(get prev LABEL here) | SIZE(lowest bit PREV_USE) |
|---|---|
| PREV_SIZE (faked) | SIZE (faked) |
| FD(faked)(malloc_return - word_size * 3) | BK(faked)(malloc_return - word_size * 2) |
| …… | …… |
| PREV_SIZE (&LABEL_FREEING - &LABEL_fake) | SIZE(lowest bit set to 0) |
So, we get the PTR to the LABEL of the fake chunk by using the malloc return of previous chunk .
(2) write heap to make a fake LABEL
PREV_SIZE: Any Value
SIZE: Any Value
FD: the address of PTR(mentioned above) - word_size * 3 (we need FD->bk)
BK: the address of PTR(mentioned above) - word_size * 2 (we need BK->fd)
(3) overwrite the chunk FREEING
- &LABEL(FREEING chunk) - PREV_SIZE(FREEING chunk) == &LABEL(fake chunk)
- So, PREV_SIZE(FREEING chunk) should be the value of &LABEL(FREEING chunk) minus &LABEL(fake chunk)
- The lowest bit of SIZE(FREEING chunk) which marking whether the PREV_chunk been used as 0
WHAT HAPPENED WHEN BAD UNLINK DONE
- The FD->bk (PTR - word_size * 3 + word_size * 3) is set as BK, which is PTR - word_size * 2
- The BK->fd (PTR - word_size * 2 + word_size * 2 is set as FD, which is PTR - word_size * 3
- So the ptr list has been destroyed, but the mem between ptrs has been free()’d.
- Next time we call malloc, we will get the mem and can write it easily;