记一道强网杯Pwn题——baby_heap
字数 1833 2025-08-20 18:17:53

强网杯Pwn题baby_heap详细解析与利用技术

题目概述

这是一道来自2024年强网杯的Pwn题目,考察的是堆利用技术,结合了UAF漏洞和putenv调用链修改的技术点。题目提供了经典的菜单程序,包含添加、删除、编辑、显示等功能,并设置了沙箱限制。

题目分析

主要函数功能

  1. main函数:经典的菜单布局,提供6个选项:

    • 添加商品
    • 删除商品
    • 编辑商品
    • 显示商品
    • 环境变量操作
    • 任意地址写
  2. set_IO函数

    • 使用memset清零_IO_wfile_jumps及其后0x300字节
    • 使用mprotect设置_IO_wfile_jumps_mmap及其后0x1000字节为只读
  3. 沙箱限制

    • 禁用了execve、open、openat等系统调用
  4. 堆操作函数

    • add:最多申请5个堆块,大小限制在[0x500,0x600)区间
    • delete:存在UAF漏洞
    • edit:只有一次修改机会
    • show:只有一次展示机会
  5. environment函数

    • 提供setenv、getenv、putenv操作
    • putenv函数是本题的关键漏洞点
  6. write_whatever函数

    • 提供限定地址内的地址写功能

漏洞点分析

  1. UAF漏洞:delete函数未清空指针,导致释放后仍可使用
  2. putenv调用链putenv -> strchr -> __libc_alloca_cutoff -> strlen -> __add_to_environ
  3. 关键函数位置:strlen函数在libc的.got.plt段中紧挨着_GLOBAL_OFFSET_TABLE_+16的位置

利用思路

解法一:篡改strlen@got.plt指向(预期解法)

核心思路

  1. 利用UAF泄露libc和堆地址
  2. 构造ROP链实现openat2和sendfile系统调用
  3. 通过修改GOT表实现控制流劫持
  4. 利用putenv调用链触发漏洞

详细步骤

  1. 泄露地址

    • 通过large bin attack泄露libc地址
    • 通过unsorted bin泄露堆地址
  2. 构造ROP链

    • 使用mprotect修改堆内存权限
    • 使用openat2打开文件
    • 使用sendfile读取文件内容
  3. GOT表修改

    • 修改_GLOBAL_OFFSET_TABLE_+8指向可控堆地址
    • 修改_GLOBAL_OFFSET_TABLE_+16为栈迁移gadget
    • 修改strlen@got.plt指向特定地址
  4. 触发漏洞

    • 调用putenv触发修改后的调用链
    • 执行ROP链获取flag

关键代码

# 构造ROP链
New_orw = p64(pop_rdi) + p64(heap - 0x950) + p64(pop_rsi) + p64(0x1000) + p64(pop_rdx_r12) + p64(7) + p64(0) + p64(mprotect) + p64(heap+0x78)
New_orw += asm(shellcraft.pushstr('./flag') + shellcraft.openat2(-100, 'rsp', heap_base+0x3000, 0x30) + shellcraft.sendfile(1, 3, 0, 0x1000))

# 修改GOT表
cmd(6)
p.sendafter(b'Input your target addr \n',p64(GOT_1))
p.send(p64(pop_rsp_13_14_15_rbp) + p64(PLT_GOT_0))

解法二:篡改strncmp@got.plt指向(非预期解法)

核心思路

  1. 修改strncmp@got.plt指向puts函数
  2. 利用putenv调用链中的strncmp调用泄露环境变量
  3. 从环境变量中获取flag

详细步骤

  1. 泄露libc地址
  2. 获取strncmp@got.plt地址
  3. 修改strncmp@got.plt指向puts
  4. 调用putenv触发环境变量打印

关键代码

# 修改strncmp@got.plt
cmd(6)
p.sendafter(b'Input your target addr \n',p64(strncmp_got))
p.send(p64(puts))

# 触发putenv
cmd(5)
p.sendlineafter(b'Maybe you will be sad !\n',b'2')

技术要点总结

  1. UAF利用

    • 通过释放后重用泄露地址
    • 结合large bin attack实现信息泄露
  2. putenv调用链

    • 理解libc函数调用关系
    • 利用strlen在调用链中的关键位置
  3. GOT表修改技巧

    • 利用_GLOBAL_OFFSET_TABLE_结构
    • 通过修改相邻GOT表项实现控制流劫持
  4. 沙箱绕过

    • 使用openat2替代被禁用的open/openat
    • 使用sendfile读取文件内容
  5. ROP链构造

    • 在受限环境下构造有效ROP链
    • 使用mprotect修改内存权限

防御建议

  1. 修复UAF漏洞

    • 释放后及时清空指针
    • 使用双重释放检测机制
  2. 保护GOT表

    • 启用RELRO保护
    • 监控GOT表修改行为
  3. 沙箱加固

    • 限制更多危险系统调用
    • 监控非常规系统调用使用
  4. 环境变量清理

    • 确保比赛环境干净
    • 清除敏感环境变量

扩展思考

  1. 其他可能的利用方式

    • 利用__free_hook等传统hook点
    • 结合IO_FILE结构进行利用
  2. 防御演进

    • 如何防御类似的GOT表修改攻击
    • 更严格的沙箱策略设计
  3. 相关技术延伸

    • House of系列堆利用技术
    • 其他环境变量相关漏洞

这道题目展示了现代Pwn题目中堆利用与环境变量操作的结合,对理解libc内部机制和复杂漏洞利用链的构建有很好的学习价值。

强网杯Pwn题baby_ heap详细解析与利用技术 题目概述 这是一道来自2024年强网杯的Pwn题目,考察的是堆利用技术,结合了UAF漏洞和putenv调用链修改的技术点。题目提供了经典的菜单程序,包含添加、删除、编辑、显示等功能,并设置了沙箱限制。 题目分析 主要函数功能 main函数 :经典的菜单布局,提供6个选项: 添加商品 删除商品 编辑商品 显示商品 环境变量操作 任意地址写 set_ IO函数 : 使用memset清零 _IO_wfile_jumps 及其后0x300字节 使用mprotect设置 _IO_wfile_jumps_mmap 及其后0x1000字节为只读 沙箱限制 : 禁用了execve、open、openat等系统调用 堆操作函数 : add:最多申请5个堆块,大小限制在 [ 0x500,0x600)区间 delete:存在UAF漏洞 edit:只有一次修改机会 show:只有一次展示机会 environment函数 : 提供setenv、getenv、putenv操作 putenv函数是本题的关键漏洞点 write_ whatever函数 : 提供限定地址内的地址写功能 漏洞点分析 UAF漏洞 :delete函数未清空指针,导致释放后仍可使用 putenv调用链 : putenv -> strchr -> __libc_alloca_cutoff -> strlen -> __add_to_environ 关键函数位置 :strlen函数在libc的.got.plt段中紧挨着 _GLOBAL_OFFSET_TABLE_+16 的位置 利用思路 解法一:篡改strlen@got.plt指向(预期解法) 核心思路 : 利用UAF泄露libc和堆地址 构造ROP链实现openat2和sendfile系统调用 通过修改GOT表实现控制流劫持 利用putenv调用链触发漏洞 详细步骤 : 泄露地址 : 通过large bin attack泄露libc地址 通过unsorted bin泄露堆地址 构造ROP链 : 使用mprotect修改堆内存权限 使用openat2打开文件 使用sendfile读取文件内容 GOT表修改 : 修改 _GLOBAL_OFFSET_TABLE_+8 指向可控堆地址 修改 _GLOBAL_OFFSET_TABLE_+16 为栈迁移gadget 修改strlen@got.plt指向特定地址 触发漏洞 : 调用putenv触发修改后的调用链 执行ROP链获取flag 关键代码 : 解法二:篡改strncmp@got.plt指向(非预期解法) 核心思路 : 修改strncmp@got.plt指向puts函数 利用putenv调用链中的strncmp调用泄露环境变量 从环境变量中获取flag 详细步骤 : 泄露libc地址 获取strncmp@got.plt地址 修改strncmp@got.plt指向puts 调用putenv触发环境变量打印 关键代码 : 技术要点总结 UAF利用 : 通过释放后重用泄露地址 结合large bin attack实现信息泄露 putenv调用链 : 理解libc函数调用关系 利用strlen在调用链中的关键位置 GOT表修改技巧 : 利用_ GLOBAL_ OFFSET_ TABLE_ 结构 通过修改相邻GOT表项实现控制流劫持 沙箱绕过 : 使用openat2替代被禁用的open/openat 使用sendfile读取文件内容 ROP链构造 : 在受限环境下构造有效ROP链 使用mprotect修改内存权限 防御建议 修复UAF漏洞 : 释放后及时清空指针 使用双重释放检测机制 保护GOT表 : 启用RELRO保护 监控GOT表修改行为 沙箱加固 : 限制更多危险系统调用 监控非常规系统调用使用 环境变量清理 : 确保比赛环境干净 清除敏感环境变量 扩展思考 其他可能的利用方式 : 利用__ free_ hook等传统hook点 结合IO_ FILE结构进行利用 防御演进 : 如何防御类似的GOT表修改攻击 更严格的沙箱策略设计 相关技术延伸 : House of系列堆利用技术 其他环境变量相关漏洞 这道题目展示了现代Pwn题目中堆利用与环境变量操作的结合,对理解libc内部机制和复杂漏洞利用链的构建有很好的学习价值。