CISCN&CCB25半决赛pwn题解
字数 1366 2025-08-29 08:29:59

CISCN&CCB25半决赛PWN题解 - 堆溢出漏洞分析与利用

题目概述

这是一道来自CISCN&CCB25半决赛的PWN题目,主要考察堆溢出漏洞的利用。题目实现了一个基于protobuf协议的程序,提供了增删查改四个功能,存在堆溢出漏洞,最终目标是获取shell。

漏洞分析

1. 程序交互与protobuf结构

程序使用protobuf协议进行通信,关键结构定义如下:

syntax = "proto2";
message devicemsg{
    required int32 option = 1;      // 功能选项
    required int32 chunk_sizes = 2; // 堆块大小
    required int32 heap_chunks_id = 3; // 堆块ID
    required bytes heap_content = 4;  // 堆内容
}

交互注意事项

  • 程序首先读取4字节作为payload长度
  • 后续payload会被解析为protobuf结构
  • 需要特别注意chunk_sizes和实际堆块大小的区别

2. 漏洞点定位

主要漏洞存在于edit功能中:

v2 = **((_QWORD **)&heaplist + v1);       // 获取堆块size
read(0, s, 0x100uLL); 
snprintf(*((char **)&heaplist + v1), (size_t)"%lu", s, 8LL); // 溢出点

漏洞细节

  • 可以写入0x100字节数据到堆上
  • 能够覆盖相邻堆块的元数据,特别是size字段
  • 通过控制size字段可以实施后续攻击

3. 功能分析

程序提供四个主要功能:

  1. add - 分配堆块
  2. delete - 释放堆块
  3. edit - 编辑堆块(存在溢出)
  4. show - 显示堆块内容

漏洞利用步骤

1. 泄露libc地址

  1. 分配两个相邻堆块
  2. 使用edit功能溢出第一个堆块,覆盖第二个堆块的size字段
  3. 释放被修改size的堆块,使其进入unsorted bin
  4. 通过show功能泄露unsorted bin中的fd指针(指向main_arena)

2. 泄露堆地址

  1. 再次利用堆溢出修改unsorted bin的fd指针
  2. 通过特定布局使堆地址被包含在可读内存中
  3. 使用show功能泄露堆地址

3. Tcache攻击

  1. 使用堆溢出修改tcache的fd指针
  2. 通过tcache poisoning攻击tcache perthread结构
  3. 控制tcache的counters来操纵堆分配

4. 攻击IO结构体

  1. 伪造堆块size为0x1e1
  2. 通过tcache攻击申请到伪造的堆块
  3. 控制堆块数量为7后释放,使libc地址落入堆块fd位
  4. 修改fd指向stdout结构体上方
  5. 爆破倒数第四位地址
  6. 修改stdout结构体的flags为0xfbad1800
  7. 覆盖write_base低位以泄露libc地址

5. 获取shell

  1. 再次使用tcache攻击,这次目标是__free_hook
  2. 申请free_hook-8的堆块以便写入
  3. 将__free_hook覆盖为system地址
  4. 释放一个包含"/bin/sh"的堆块获取shell

关键技术点

  1. 堆溢出控制:精确控制溢出数据以修改相邻堆块的size和fd指针
  2. tcache攻击:利用tcache poisoning攻击tcache perthread结构
  3. IO结构体攻击:通过修改stdout结构体泄露libc地址
  4. 地址爆破:需要爆破倒数第四位地址以精确控制目标位置
  5. protobuf交互:正确构造protobuf消息与程序交互

防御措施

  1. 增加堆块间的保护机制(如canary)
  2. 对用户输入的size进行严格校验
  3. 使用安全的字符串拷贝函数替代snprintf
  4. 及时更新libc版本以利用新的防护机制

总结

这道题目综合考察了堆溢出、tcache攻击和IO结构体攻击等技术,需要选手对glibc堆管理机制有深入理解。通过精确控制堆布局和利用多种攻击技术组合,最终实现任意代码执行。

CISCN&CCB25半决赛PWN题解 - 堆溢出漏洞分析与利用 题目概述 这是一道来自CISCN&CCB25半决赛的PWN题目,主要考察堆溢出漏洞的利用。题目实现了一个基于protobuf协议的程序,提供了增删查改四个功能,存在堆溢出漏洞,最终目标是获取shell。 漏洞分析 1. 程序交互与protobuf结构 程序使用protobuf协议进行通信,关键结构定义如下: 交互注意事项 : 程序首先读取4字节作为payload长度 后续payload会被解析为protobuf结构 需要特别注意 chunk_sizes 和实际堆块大小的区别 2. 漏洞点定位 主要漏洞存在于edit功能中: 漏洞细节 : 可以写入0x100字节数据到堆上 能够覆盖相邻堆块的元数据,特别是size字段 通过控制size字段可以实施后续攻击 3. 功能分析 程序提供四个主要功能: add - 分配堆块 delete - 释放堆块 edit - 编辑堆块(存在溢出) show - 显示堆块内容 漏洞利用步骤 1. 泄露libc地址 分配两个相邻堆块 使用edit功能溢出第一个堆块,覆盖第二个堆块的size字段 释放被修改size的堆块,使其进入unsorted bin 通过show功能泄露unsorted bin中的fd指针(指向main_ arena) 2. 泄露堆地址 再次利用堆溢出修改unsorted bin的fd指针 通过特定布局使堆地址被包含在可读内存中 使用show功能泄露堆地址 3. Tcache攻击 使用堆溢出修改tcache的fd指针 通过tcache poisoning攻击tcache perthread结构 控制tcache的counters来操纵堆分配 4. 攻击IO结构体 伪造堆块size为0x1e1 通过tcache攻击申请到伪造的堆块 控制堆块数量为7后释放,使libc地址落入堆块fd位 修改fd指向stdout结构体上方 爆破倒数第四位地址 修改stdout结构体的flags为0xfbad1800 覆盖write_ base低位以泄露libc地址 5. 获取shell 再次使用tcache攻击,这次目标是__ free_ hook 申请free_ hook-8的堆块以便写入 将__ free_ hook覆盖为system地址 释放一个包含"/bin/sh"的堆块获取shell 关键技术点 堆溢出控制 :精确控制溢出数据以修改相邻堆块的size和fd指针 tcache攻击 :利用tcache poisoning攻击tcache perthread结构 IO结构体攻击 :通过修改stdout结构体泄露libc地址 地址爆破 :需要爆破倒数第四位地址以精确控制目标位置 protobuf交互 :正确构造protobuf消息与程序交互 防御措施 增加堆块间的保护机制(如canary) 对用户输入的size进行严格校验 使用安全的字符串拷贝函数替代snprintf 及时更新libc版本以利用新的防护机制 总结 这道题目综合考察了堆溢出、tcache攻击和IO结构体攻击等技术,需要选手对glibc堆管理机制有深入理解。通过精确控制堆布局和利用多种攻击技术组合,最终实现任意代码执行。