Key point is Double Free Bug
free(buf1)->free(buf2)->free(buf1)
fastbin doesn't have bk, only fd
After free (buf1)->free(buf2)->free(buf1), fastbin becomes buf1->buf2->buf1.
Then after malloc buf1 and let's assume that we can write something on data of buf1.
Now buf1 is allocated, but on fastbin, buf1 is fd of buf2. So fastbin becomes like this: buf2->buf1->blahblah...
Therefore, after allocate same size of two chunks. We can allocate blahblah...part where we can write anything we want. So it means that we can allocate wherever we want.
Then why free(buf3)?: I think this is because last freed chunk can be consolidated with top chunk, so we make additional chunk.
**we can write large value into stack **
malloc->free->write (&target-2) to bk of the freed unsorted bin->malloc
we allocate & free chunk in size of unsorted bin Then, the chunk in unsorted bin has fd and bk. In this point, fd and bk both are main_arena+88, which is the address of top chunk.
Now, we write (&stack_var-2) to the bk of the freed unsorted bin. Then, we malloc the same size so the freed chunk is allocated. As a result, the fd of target chunk becomes main_arena+88.
we use unsorted bin attack to make io_list_all:&main_arena.Top
Top chunk + size has to be page aligned
Top chunk's prev_inuse bit has to be set.
when the size of Top chunk is smaller than the requested value, there are two possibilities.
- Extend the Top chunk
- mmap a newpage It the size requested is smaller than 0x21000, then the former is followed.->sysmalloc is invoked
malloc(0x400)->change top chunk size->malloc(0x1000)
now, old top chunk is in unsorted bin, and the fd and bk are both main_arena+88
io_list_all = (main_arena+88)+0x9a8=(fd or bk) +0x9a8
Let's assume we change the fd of the old top chunk to io_list_all-0x10
memcpy(top, "/bin/sh\x00",8);
old top chunk structure is
/bin/sh
fd bk(io_list_all-0x10)
chunk->bk=io_list-all-0x10
chunk->bk->fd=io_list_all
Therefore, io_list_all: main_arena+88(&main_arena.Top)
top[0]="/bin/sh"
top[1]=0x61 : size
top[24]=1
top[21]=2
top[22]=3
top[20]=&top[18]
top[15]=&winner;
top[27]=&top[12];
malloc(10)