首页 > 其他分享 >CTFpwn进阶之路从栈到堆---初步理解

CTFpwn进阶之路从栈到堆---初步理解

时间:2024-01-06 13:33:43浏览次数:40  
标签:bin 管理器 进阶 chunk --- CTFpwn prev fastbin size

曾听过某大佬讲,pwn的等级大致分为三种,栈,堆,内核。

这篇文章总结了我目前对堆的理解,肯定不够深入,不过我将更注重于偏抽象和本质的东西,希望各位看完能有些不同的收获。

堆题小结

就我目前的理解来说,堆和栈有个很不同的地方。

栈的漏洞经常是可以栈溢出直接改变函数返回地址,通过pop|ret做到连续的劫持程序流以及修改寄存器的值。

堆的漏洞经常会导致任意已知地址写或泄露(这一点具体原因等会说) ,对于程序流的劫持经常是通过改got表实现(如果relro保护开了那则经常是改写mallocrealloc函数中的hook来做到劫持程序流,通常只能劫持程序流一次。onegadget在这种情况就有用武之地了。

总体来说,堆题劫持程序流比起栈题更加不自由,难度更大,且劫持之后收益也更小(堆的已知地址任意写一般都是用来改gothook,,因为很少能泄漏到栈地址。)

当然,这些都是我目前的理解,实际上我做过的堆题也不多,只是感觉堆题似乎是这样的。

堆概述

首先,堆只分两种,binchunkchunk是使用中的堆,bin是释放后的堆。

chunk管理

这里有一个特殊机制说明一下,任何的申请的堆size都会被调整成整SIZE_SZ*2的整数(SIZE_SZ是一个宏定义,在32位中是4,在64位中是8),这就导致size的最后三位bit必定为0,这三位都用来做一个标记位,前两个标记位我不记得是用来干嘛的了。但是最后一位很重要,它标记着物理地址的前一个chunk是否被使用)

chunk的管理方式很简单,基本只根据物理地址及size和prev_size和标记位管理。

图中两个chunk,黄色标记部分是表示这个chunk的大小size.蓝色部分标记的是前一个chunksize,也就是prev_size。但是图中两个chunk都在使用(堆管理器认为这个chunk在使用的根据是前面说的最后一bit的标记位。这时候每一个chunk都会借用下一个chunkprev_size,原因很简单,chunk只有在需要合并的时候才需要知道前一个chunk有多大,这个prev_size才能让堆管理器最快的找到前一个chunk判断是否能合并。而在使用时就没必要了。 (这个界面是vis指令调出来的,今天才发现我哥们不知道这个指令,所以特意说一嘴)

CTFpwn进阶之路从栈到堆---初步理解_堆初步

还是放出最经典的图吧(转自CSDN的Morphy_Amo)

chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         |Size of previous chunk 				|        	Size of chunk, in bytes|                     |A|M|P|
   mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         |             User data starts here...                          .
         .                                                               .
         .             (malloc_usable_size() bytes)                      .
         .                                                               |
nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
         |Size of previous chunk 				|        	Size of chunk, in bytes|                     |A|M|P|
   mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

bin

bin那就可有的说了,不过我也不是很懂

首先,binchunk最大的差别就是bin通过链表来管理。而chunk不是。

所有的bin都是链表。通过fd和bk指针堆管理器可以快速索引到任何bin

fastbin

范围大致为0x20-0x80字节(64位)0x10-0x40字节(32位).这个大小包含size及prev_size

之所以说是大致,是因为不同libc版本似乎范围不一样。(不过这个影响倒不大,大概知道就行了)

fastbin采用单链表结构,这也导致了fastbin必然是先进后出

图中这个例子就能看出来,除了最后一个fastbin,其他fastbin都有指向下一个fastbin的指针.

CTFpwn进阶之路从栈到堆---初步理解_堆初步_02

这样操作就是为了方便管理。

举个很怪的例子。比如你班主任(堆管理器)为了能尽快联系到班上(fastbin)所有人(每一个bin),把班上所有人根据身高,分为fastbin[0]fastbin[9],比如身高160全部进入fastbin[0]。(因为前面说堆的大小分配只支持整的,对应到这个例子就是假设所有人身高都是整数,所以这里说的身高160其实是严格160)

而其中每一个进入fastbin[0]的人拥有下一个进入的人的联系方式(fd指针),直到最后一个人什么都没有,如果班主任(堆管理器)需要用到身高160(特定size的bin)的人做某件事(分配给用户内存),那么他就找第一个人,第一个人去做事之前,会把第二个人的联系方式给班主任(堆管理器)。

此外班主任(堆管理器)还拥有一个花名册(数组),上面记录着fastbin[0]到fastbin[9]的每个bin的大小,记录着每个bin的第一个人的名字。

这样,堆管理器就能再需要用到特定大小的fastbin时很轻松找到了。

small&largebin

之所以放在一起讲,是因为这两个玩意基本就尺寸的差异。

其实只要懂了fastbin基本上就能理解这两个了。

1.fastbin是单链表模式管理,采取先进后出。

small&largebin采取双链表管理,比fastbin多了一个bk指针,采取先进先出原则。

2.其次就是largebin再多了一个fdnextsize和bknextsize这样对管理器就不需要像fastbin那样,专门为其维护保存一个储存大小的数组。而是直接通过该指针就能找到不同大小的largebin

unsortedbin

各种乱七八糟的bin都有可能进入这个bin

具体待会在堆管理流程再说

tcachebin

这个是在比较新的libc版本才有的,有点像fastbin。并且当同样大小(符合fastbin的大小)的tcachebin有了七个之后,接下来的释放操作就会放进fastbin

不过讲真,tcachebin我真不懂,留个坑,以后再填吧?

堆管理机制

我也不太懂,留个坑,下次填。可以看看博客园的一篇文章。那里有张图很不错,但是我复制上来就变成压缩阉割版了。如果有兴趣建议去看看他的。

CTFpwn进阶之路从栈到堆---初步理解_CTFpwn_03

标签:bin,管理器,进阶,chunk,---,CTFpwn,prev,fastbin,size
From: https://blog.51cto.com/u_16356440/9127176

相关文章

  • 无涯教程-Redis - TTL 命令函数
    RedisTTL命令用于获取键(key)到期的剩余时间(以秒为单位)。TTLkey-返回值整数值TTL(以毫秒为单位)或负值。TTL(以毫秒为单位)。-1,如果键(key)没有到期时间。-2,如果键(key)不存在。TTLkey-语法以下是RedisTTL命令的基本语法。redis127.0.0.1:6379>TTL......
  • D13005M-ASEMI高频电源开关D13005M
    编辑:llD13005M-ASEMI高频电源开关D13005M型号:D13005M品牌:ASEMI集电极电流:4A集电极电压:700V集电极-发射极电压:450V发射极-基极电压:12V集电极电流(脉冲):8A芯片个数:1封装:TO-220F工作温度:-50°C~150°C引脚数量:3集电极损耗:70W类型:插件塑封二极管、高压、高速D13005M描述:D13005M拥有广泛的......
  • Kubernetes最佳实践与进阶技巧
    @[TOC]Kubernetes最佳实践与进阶技巧Kubernetes(K8s)作为当前最流行的容器编排工具之一,已经在云原生应用开发中扮演着关键的角色。在这篇文章中,我们将深入探讨一些Kubernetes的最佳实践和进阶技巧,帮助开发者更好地利用和优化这一强大的容器编排平台。1.自定义调度策略Kubernetes的调......
  • Linux Debian12系统gnome桌面环境默认截屏截图工具gnome-screenshot
    一、简介:在Debian12中系统gnome桌面环境默认提供一个截图捕获工具screenshot,可以自定义区域截图、屏幕截图、窗口截图和录制视频,截图默认保存在“~/图片/截图”路径下。可以在应用程序中搜索screenshot,如下图:也可以在桌面右上角找到screenshot截图工具,如下图:二、快捷键截......
  • RocketMQ系统性学习-RocketMQ原理分析之源码启动、Broker启动流程分析
    欢迎关注公众号:【11来了】发送“资料”可以下载Redis、JVM系列文章PDF版本!作者为在读研究生,目前研二,计划在公众号记录学习常用中间件笔记,以及明年更新面试经历!RocketMQ原理分析启动RocketMQ源码分析RocketMQ之前,先确保可以成功启动起来NameServer启动在Idea中配置ROCK......
  • 无涯教程-Redis - PTTL 命令函数
    RedisPTTL命令用于获取键(key)到期的剩余时间(以毫秒为单位)。PTTLkey-返回值整数值TTL(以毫秒为单位)或负值。TTL(以毫秒为单位)。-1,如果键(key)没有有效期限。-2,如果键(key)不存在。PTTLkey-语法以下是RedisPTTL命令的基本语法。redis127.0.0.1:6379......
  • 无涯教程-Redis - PERSIST命令函数
    RedisPERSIST命令用于从键(key)中删除到期时间。PERSIST-返回值整数值1或01,如果从键(key)中删除了超时。0,如果键(key)不存在或没有关联的超时。PERSIST-语法以下是RedisPERSIST命令的基本语法。redis127.0.0.1:6379>PERSISTKEY_NAMEPERSIST-示例首先......
  • 【flink番外篇】9、Flink Table API 支持的操作示例(2)- 通过Table API 和 SQL 创建视图
    Flink系列文章一、Flink专栏Flink专栏系统介绍某一知识点,并辅以具体的示例进行说明。1、Flink部署系列本部分介绍Flink的部署、配置相关基础内容。2、Flink基础系列本部分介绍Flink的基础部分,比如术语、架构、编程模型、编程指南、基本的datastreamapi用法、四大基......
  • 50N65-ASEMI高压N沟道MOS管50N65
    编辑:ll50N65-ASEMI高压N沟道MOS管50N65型号:50N65品牌:ASEMI封装:TO-247连续漏极电流(Id):50A漏源电压(Vdss):650V功率(Pd):388W芯片个数:2引脚数量:3类型:插件、高压MOS管特性:N沟道MOS管、高压MOS管RDS(on):60mΩVGS:±30V封装尺寸:如图工作温度:-55°C~150°C50N65特性:50N65采用先进的沟槽技......
  • 无涯教程-Redis - DEL命令函数
    RedisDEL命令用于删除Redis中的现有键(key)。DELkey-返回值删除的键(key)数。DELkey-语法以下是RedisDEL命令的基本语法。redis127.0.0.1:6379>DELKEY_NAMEDELkey-示例首先,在Redis中创建一个键(key),并在其中设置一些值。redis127.0.0.1:6379>SETle......