ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

pwn - Heap Exploitation

2022-05-07 02:32:26  阅读:207  来源: 互联网

标签:bin 链表 chunk free Exploitation 大小 内存 Heap pwn


今天整理了一下Heap部分的一些笔记,小汇总一下

在程序运行过程中,堆可以提供动态分配的内存,允许程序申请大小未知的内存。堆是程序虚拟空间地址的一块连续的线性区域,由地址向地址上增长

堆题漏洞一般在delete()函数上,多半是指针未清空导致成为野指针,从而可以进行UAF

实现堆利用的方法

  • ptmalloc2 - glibc
  • dlmalloc - General purpose allocator
  • jemalloc - Firefox and FreeBSD
  • tcmalloc - Google
  • libumem - Solaris

ps:与系统交互的函数主要是(s)brk函数以及mmap,munmap函数,不是malloc或者free

malloc

malloc(size_t n)

  • malloc返回对应大小字节的内存块的指针,此外,该函数对一些异常进行了处理
    • n = 0 , 返回当前系统允许的堆的最小内存块
    • 当n为负数时,由于在大多数系统上,size_t是无符号常数,所以会系统会申请很大的内存空间,但通常来说都会失败,因为系统没有那么多的内存可以分配

free

free(void* p)

  • free函数会释放由p指向的内存块,这个内存块可能是通过malloc得到的,也可能是通过相关函数realloc得到的
  • 对异常的处理
    • 当p为空指针时,函数不执行任何操作
    • 当p被释放后,再次释放会出现乱七八糟的效果,即double free
    • 除了被禁用mallopt的情况下,当释放很大的内存空间时,程序会将这些内存空间还给系统,以便于减小程序所使用的内存空间

(s)brk

操作系统提供了brk函数,glibc库提供了sbrk函数,我们可以通过增加brk的大小来向操作系统申请内存

  • 堆的起始地址start_brk和堆的当前末尾brk指向同一地址,根据是否开启ASLR两者的具体位置会有所不同
    • 不开启ASLR:start_brk和brk会指向data/bss段的结尾
    • 开启ASLR:start_brk和brk,也会指向同一位置,只是这个位置会在data/bss段的结尾后随机偏移

chunk

  • 结构其实就是header段+data段
  • size_alignment = 0x10的倍数(malloc 0x18 会拿到 0x20 的大小)
  • 整个memory大小为header(0x10) + data

由malloc申请的内存为chunk,这块内存在ptmalloc内部用malloc_chunk结构体表示,当程序申请的chunk被free掉后,会加入到相应的空闲管理列表

  • chunk结构统一,无论大小,处于分配还是释放状态
  • 根据是否被释放,表现形式会有所不同
字段 释意
prev_sizeimage-20220507005803636 如果该chunk物理相邻的前一个地址chunk(两个指针的地址差值为前一个chunk大小)是空闲的话,那该字段记录的是前一个chunk的大小,否则记录前一个chunk(低地址chunk)的数据
P->PREV_INUSE(P):上一个chunk是否使用中
M->MMAPED(M):chunk是否通过mmap生成
NON_MAIN_AREA(N):该chunk是否不属于main area
size chunk的大小必须是2*SIZE_SZ的整数倍;32位SIZE_SZ大小为4,64位SIZE_SZ大小为8
fd chunk处于分配状态,fd开始是用户数据;若chunk空闲,则fd指向下一个(非物理相邻)的空闲chunk.,bk指向上一个(非物理相邻)的空闲chunk;通过fd,bk将空闲的chunk块加入到空闲的chunk块链表进行统一管理

bin

用户释放掉的chunk不会马上返回给系统,会由ptmalloc管理heap和mmap映射区域中空闲的chunk,ptmalloc管理器会挑一块适合的给用户,这样可以避免频繁的系统调用,降低内存分配的开销

根据chunk的大小和使用状态将chunk初步划分为4类:fast bins,small bins,large bins,unsorted bins

除了fast bin是单链表,其余(small bin,large bin,unsorted bin)都是双链表

堆溢出

程序向堆块中写入的字节数超过了堆块本身可使用的字节数(可利用的字节数都不小于用户申请的字节数),因而导致了数据溢出,并覆盖到物理相邻的高地址的下一个堆块

Fast Bin

  • chunk的大小在32字节-128字节(0x20 - 0x80)的chunk称为fast chunk(大小为内存中struct_malloc_chunk的大小)
  • Fastbin链表个数为10个
  • 快速地进行小内存的分配和释放
  • 单链表(使用fd指针,bk没有用到),故fastbin中增添或者删除fast chunk都是在对链表尾进行操作
  • fastbin链表的每个chunk大小相同,不同链表之间的chunk不同
  • LIFO(Last In First Out)
  • 被free掉的时候会将下一块chunk p设置成为0

Unsorted Bin

  • 释放较小或较大的chunk时,如果系统没有将他们添加到对应的bins中,系统就会将这些chunk添加到unsorted bin中去
  • 为了glibc mallc机制第二次机会利用最近释放的chunk(第一次是fastbin),加快内存的分配和释放,不再花费额外的时间去查找额外的chunk
  • Unsortedbin链表个数为1个
  • free chunks组成的循环双链表
  • 对大小没有限制
  • FIFO

Small Bin

  • 小于1024字节(0x400)的chunk称之为small chunk,small bin用于管理small chunk
  • smallbin链表个数62个
  • 相邻的free chunk需要进行合并操作,合并成一个大free chunk
  • 内存分配速度:fas tbin < small bin < large bin
  • free chunks组成的循环双链表
  • FIFO
  • small bin链表中每个chunk大小相同,不同链表之间chunk大小不同
  • free:small chunk free之后,会检查该chunk相邻的chunk是否free,如果是的话将进行合并操作,将这些chunks合并成为新的chunk,然后将它们从small bin中移除,最后将新的chunk添加到unsorted bin中,之后unsourted bin进行整理再添加到对应的bin链上

Large Bin

  • 大小等于1024字节(0x400)的chunk称为large chunk
  • largebin链表个数为63个,分为6组
  • 用fd_nextsize , bk_nextsize连接起来
  • 其合并类似于small bin
  • 同一个largebin链表每个chunk可以不一样(从大到小排序)
  • large chunk可以添加,删除在large bin中的任何一个位置

Unsorted Bin

  • 双向链表(Circular doubly linked list)
  • free的chunk size > fastbin时,不会直接放到对应的bin里,会先丢到Unsorted Bin
  • malloc fastbin size大小时会先去fastbin list里找,若没有则会到unsorted bin找,如果找到一样大小的则回传,若无但找到大小大于所需大小的chunk则会切割回传,剩下的部分都会丢回unsorted bin,最后实在没有会从top chunk切出来回传

标签:bin,链表,chunk,free,Exploitation,大小,内存,Heap,pwn
来源: https://www.cnblogs.com/M1sceden4/p/16240903.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有