HTB Auth-or-not:一个自实现堆管理的pwn练习
字数 1410 2025-08-29 08:30:24

HTB Auth-or-not PWN题解:自定义堆管理漏洞分析与利用

题目概述

这是一个来自Hack The Box的PWN挑战,名为"Auth-or-not",主要考察对自定义堆管理器的漏洞分析和利用能力。题目实现了一个自定义的内存管理机制,通过分析其内存布局和操作逻辑,我们可以发现并利用其中的漏洞。

逆向分析

主要结构体

题目保留了符号信息,关键结构体定义如下:

struct Author {
    char Name[16];
    char Surname[16];
    char *Note;         // 通过ta_alloc分配
    size_t NoteSize;    // 用户可控
    void (*Print)(char*); // 函数指针,可用于RCE
};

功能函数

  1. add_author:

    • 使用ta_alloc自定义分配器申请内存
    • NoteSize完全由用户控制
    • 当输入-1时,会返回无符号的-1,实际上分配0字节内存但仍可写入数据,导致堆溢出
  2. get_from_user:

    • 读取用户输入时没有NULL终止符
    • 结合%s打印操作可泄露后续内存内容
  3. print_author:

    • 通过结构体调用Print函数指针
    • 关键利用点,可用于RCE
  4. delete_author:

    • 只清空结构体指针,不清理Note指针
    • 存在UAF(Use After Free)隐患

漏洞分析

主要漏洞点

  1. 整数溢出导致堆溢出:

    • NoteSize输入为-1时,NoteSize+1变为0
    • 但仍能写入数据,造成堆溢出
  2. 信息泄露:

    • get_from_user不添加NULL终止符
    • 通过精心构造可泄露栈地址、PIE地址和libc地址
  3. UAF问题:

    • delete_author不清理Note指针
    • 结合堆布局可实现内存重用

堆布局观察

申请两个author后的栈上模拟堆布局:

第一次申请:
- 大小: -1 (实际0)
- 地址: 0x7fff30589f18 (可控)
- 内容被第二次申请覆盖

这种布局意味着:

  1. 释放第一次申请
  2. 重新申请并覆盖第二次申请的部分内容
  3. 通过精心构造可泄露地址信息

利用策略

利用步骤

  1. 泄露栈和PIE地址:

    • 完全覆盖NameSurname字段
    • 相邻的Note指针会被Print打印出来
    • 调整指针指向可泄露PrintNote函数地址,计算PIE基址
  2. 泄露libc地址:

    • 题目未提供libc文件
    • 需要泄露libc符号地址并通过libc database查询
    • 实验确定具体libc版本
  3. 实现RCE:

    • 覆盖Print函数指针为system
    • Print调用时传入Note指针作为参数
    • Note内容设置为/bin/sh即可获取shell

关键技巧

  1. 堆风水(Heap Feng Shui):

    • 通过控制分配和释放顺序操纵内存布局
    • 实现内存重用和覆盖
  2. 地址计算:

    • 通过泄露的地址计算关键函数地址
    • 包括PIE基址、libc基址等
  3. 函数指针劫持:

    • 利用自定义堆管理器的缺陷覆盖函数指针
    • 将控制流导向system等危险函数

EXP编写要点

辅助函数

  1. 泄露地址函数:

    def leak_address():
        # 构造特定布局
        # 触发信息泄露
        # 解析返回数据获取地址
        return address
    
  2. 计算偏移:

    def calculate_offsets(leaked_addr):
        pie_base = leaked_addr - 0x1234  # 根据实际偏移调整
        libc_base = leaked_libc_addr - 0x5678
        return pie_base, libc_base
    

完整利用流程

  1. 泄露PIE地址
  2. 泄露libc地址并确定版本
  3. 计算system地址
  4. 构造内存布局覆盖Print指针
  5. 设置Note内容为/bin/sh
  6. 触发Print调用获取shell

总结

这道题目展示了自定义堆管理器的常见漏洞模式:

  1. 整数处理不当导致的溢出
  2. 内存管理不严谨导致的UAF
  3. 函数指针缺乏保护

通过分析内存布局而非深入堆管理细节,可以更高效地发现和利用漏洞。关键点在于:

  • 观察内存实际布局而非陷入实现细节
  • 利用信息泄露构建完整的内存图景
  • 通过堆操作控制关键数据结构的覆盖

这种思路适用于大多数自定义内存管理的PWN题目。

HTB Auth-or-not PWN题解:自定义堆管理漏洞分析与利用 题目概述 这是一个来自Hack The Box的PWN挑战,名为"Auth-or-not",主要考察对自定义堆管理器的漏洞分析和利用能力。题目实现了一个自定义的内存管理机制,通过分析其内存布局和操作逻辑,我们可以发现并利用其中的漏洞。 逆向分析 主要结构体 题目保留了符号信息,关键结构体定义如下: 功能函数 add_ author : 使用 ta_alloc 自定义分配器申请内存 NoteSize 完全由用户控制 当输入 -1 时,会返回无符号的 -1 ,实际上分配0字节内存但仍可写入数据,导致堆溢出 get_ from_ user : 读取用户输入时没有NULL终止符 结合 %s 打印操作可泄露后续内存内容 print_ author : 通过结构体调用 Print 函数指针 关键利用点,可用于RCE delete_ author : 只清空结构体指针,不清理 Note 指针 存在UAF(Use After Free)隐患 漏洞分析 主要漏洞点 整数溢出导致堆溢出 : 当 NoteSize 输入为 -1 时, NoteSize+1 变为 0 但仍能写入数据,造成堆溢出 信息泄露 : get_from_user 不添加NULL终止符 通过精心构造可泄露栈地址、PIE地址和libc地址 UAF问题 : delete_author 不清理 Note 指针 结合堆布局可实现内存重用 堆布局观察 申请两个author后的栈上模拟堆布局: 这种布局意味着: 释放第一次申请 重新申请并覆盖第二次申请的部分内容 通过精心构造可泄露地址信息 利用策略 利用步骤 泄露栈和PIE地址 : 完全覆盖 Name 和 Surname 字段 相邻的 Note 指针会被 Print 打印出来 调整指针指向可泄露 PrintNote 函数地址,计算PIE基址 泄露libc地址 : 题目未提供libc文件 需要泄露libc符号地址并通过libc database查询 实验确定具体libc版本 实现RCE : 覆盖 Print 函数指针为 system Print 调用时传入 Note 指针作为参数 将 Note 内容设置为 /bin/sh 即可获取shell 关键技巧 堆风水(Heap Feng Shui) : 通过控制分配和释放顺序操纵内存布局 实现内存重用和覆盖 地址计算 : 通过泄露的地址计算关键函数地址 包括PIE基址、libc基址等 函数指针劫持 : 利用自定义堆管理器的缺陷覆盖函数指针 将控制流导向 system 等危险函数 EXP编写要点 辅助函数 泄露地址函数 : 计算偏移 : 完整利用流程 泄露PIE地址 泄露libc地址并确定版本 计算 system 地址 构造内存布局覆盖 Print 指针 设置 Note 内容为 /bin/sh 触发 Print 调用获取shell 总结 这道题目展示了自定义堆管理器的常见漏洞模式: 整数处理不当导致的溢出 内存管理不严谨导致的UAF 函数指针缺乏保护 通过分析内存布局而非深入堆管理细节,可以更高效地发现和利用漏洞。关键点在于: 观察内存实际布局而非陷入实现细节 利用信息泄露构建完整的内存图景 通过堆操作控制关键数据结构的覆盖 这种思路适用于大多数自定义内存管理的PWN题目。