diff --git a/pwn_demos/malloc/bk_consolidation/readme.md b/pwn_demos/malloc/bk_consolidation/readme.md index c7fab39..5a61255 100644 --- a/pwn_demos/malloc/bk_consolidation/readme.md +++ b/pwn_demos/malloc/bk_consolidation/readme.md @@ -35,7 +35,7 @@ void main() { printf("Then we will reallocate the memory of chunk0 without actually freeing it.\n\n"); printf("Starting off, we will change the chunk header of chunk1, to make it look like the previous chunk is freed.\n"); - printf("We will need to set the prev_size equal to the size of chunk1.\n"); + printf("We will need to set the prev_size equal to the size of chunk0.\n"); printf("In addition to that, we will need to clear the prev_inuse flag of the size value of chunk1.\n\n"); chunk1[-2] = (CHUNK_SIZE0 + 0x10); diff --git a/pwn_demos/tcache/tcache_linked_list/readme.md b/pwn_demos/tcache/tcache_linked_list/readme.md index dcf5c27..fbcf8d3 100644 --- a/pwn_demos/tcache/tcache_linked_list/readme.md +++ b/pwn_demos/tcache/tcache_linked_list/readme.md @@ -10,7 +10,6 @@ Here is the code which we will be looking at: #include #define CHUNK_SIZE0 0x100 -#define CHUNK_SIZE1 0x10 long target = 0xdeadbeef; @@ -28,14 +27,10 @@ void main() { printf("First, we will allocate our heap chunks.\n"); printf("Three 0x%x byte chunks to be freed and inserted into the tcache.\n", CHUNK_SIZE0); - printf("There will be three 0x%x byte chunks inbetween those three, to prevent consolidation.\n\n", CHUNK_SIZE1); chunk0 = malloc(CHUNK_SIZE0); - malloc(CHUNK_SIZE1); chunk1 = malloc(CHUNK_SIZE0); - malloc(CHUNK_SIZE1); chunk2 = malloc(CHUNK_SIZE0); - malloc(CHUNK_SIZE1); memset(chunk0, 0x00, CHUNK_SIZE0); memset(chunk1, 0x00, CHUNK_SIZE0); @@ -94,11 +89,11 @@ void main() { ## Walkthrough So, let's actually go through this in a debugger. Here are the major steps: - * Insert Chunks into tcache - * Alter next ptr of a tcache chunk to an address we want to allocate a chunk to - * Allocate altered chunk, set new head to address we want to allocate - * Allocate chunk to address we want to - * Write/Read memory at address we want to, get arbitrary read/write +* Insert Chunks into tcache +* Alter next ptr of a tcache chunk to an address we want to allocate a chunk to +* Allocate altered chunk, set new head to address we want to allocate +* Allocate chunk to address we want to +* Write/Read memory at address we want to, get arbitrary read/write Now, in order to do this in an actual program, you would likely need three bugs. You need an infoleak of the heap, so you can break heap ASLR (since you need to know the heap address space because of the next ptr mangling). You need to know the address of the thing you want to allocate a chunk to, which because PIE is enabled and we want to overwrite a global variable, we would need a PIE infoleak to break PIE ASLR. Lastly you would need a bug to actually overwrite the next ptr of a chunk in the tcache (be it a Use After Free, Double Free, Heap Overflow, etc). In this instance, we are effectively using a Use After Free. diff --git a/pwn_demos/unsorted_bin/last_remainder/readme.md b/pwn_demos/unsorted_bin/last_remainder/readme.md index 88154bf..d83cbcd 100644 --- a/pwn_demos/unsorted_bin/last_remainder/readme.md +++ b/pwn_demos/unsorted_bin/last_remainder/readme.md @@ -93,7 +93,7 @@ When the last_remainder chunk is the only chunk in the unsorted bin, malloc can How we will accomplish our goal is by doing this. We will have a chunk, become the last_remainder, that is before the areas we want to allocate. We will expand it's size via overwriting the chunk size, to encompass the areas we want to allocate. Right after that chunk, we will set a fake chunk header, with a `prev_size` that matches our expanded last_remainder chunk size, and a chunk size that has the `prev_inuse` bit flag not set (and hopefully lines up with the next chunk, to avoid potential issues). -Then simply, we will first allocate a chunk from the last_remainder, to line it up with `chunk0` (`0x5d0`). Then, we will simply reallocate `chunk0/chunk1/chunk2` (they are all directly adjacent, no alignment allocations in between necissary). +Then simply, we will first allocate a chunk from the last_remainder, to line it up with `chunk0` (`0x5d0`). Then, we will simply reallocate `chunk0/chunk1/chunk2` (they are all directly adjacent, no alignment allocations in between necessary). Let's see this in action: diff --git a/pwn_demos/unsorted_bin/unsorted_linked/readme.md b/pwn_demos/unsorted_bin/unsorted_linked/readme.md index 84bbd0d..5579386 100644 --- a/pwn_demos/unsorted_bin/unsorted_linked/readme.md +++ b/pwn_demos/unsorted_bin/unsorted_linked/readme.md @@ -70,7 +70,7 @@ void main() { So, how will this code work? We will effectively create a fake unsorted bin chunk, and overwrite the fwd ptr of one unsorted bin chunk, and the bk ptr of another unsorted bin chunk to effectively insert the fake unsorted bin chunk into the unsorted bin. For the fake unsorted bin chunk, we will set the fwd/bk ptrs to the two chunks we linked to the fake unsorted bin chunk, as it should. -In addition to that, we will need to set some things for the fake unsorted bin chunk. We will need to set the `prev_size` (to `0x00`), and the size of the chunk header (I will be setting it to `0x50`). In addition to that, we will need to make a fake chunk header right after our fake chunk, as there should be one if this was an actual malloc chunk. The `prev_size` must match the size of our chunk, which will be `0x50`. For the size, I just put `0x50` (not a lot of thought here, the `prev_inuse` isn't set, however this might cause some problems under the right condition). For the size of the fake unsorted bin chunk, there are three main considerations for it. The first, is that the amount of data we will be able to write to the chunk will be directly tied to the size of it. The second is that we will need a fake chunk header right after our fake unsorted bin chunk, whose location will be determined by the start of our fake unsorted bin chunk, and its size. The third consideration, is if the chunk gets moved over into either a small / large bin, its size will determine which bin it gets moved over into. +In addition to that, we will need to set some things for the fake unsorted bin chunk. We will need to set the `prev_size` (to `0x00`), and the size of the chunk header (I will be setting it to `0x40`). In addition to that, we will need to make a fake chunk header right after our fake chunk, as there should be one if this was an actual malloc chunk. The `prev_size` must match the size of our chunk, which will be `0x40`. For the size, I just put `0x50` (not a lot of thought here, the `prev_inuse` isn't set, however this might cause some problems under the right condition). For the size of the fake unsorted bin chunk, there are three main considerations for it. The first, is that the amount of data we will be able to write to the chunk will be directly tied to the size of it. The second is that we will need a fake chunk header right after our fake unsorted bin chunk, whose location will be determined by the start of our fake unsorted bin chunk, and its size. The third consideration, is if the chunk gets moved over into either a small / large bin, its size will determine which bin it gets moved over into. For our code, we will start off via allocating some chunks, and freeing two of them to insert them into the unsorted bin. Then on the stack, we will construct our fake chunk and link it against the two unsorted bin chunks. Then, we will overwrite the fwd/bk pointers of the two unsorted bin chunks, to insert our fake chunk. We will call malloc again to move our fake chunk over to the small bin, then allocate it with the final `malloc(0x2c)` function call.