HTB Dream Diary: Chapter 4 复盘详解
字数 2290 2025-12-06 12:12:25

HTB Dream Diary: Chapter 4 漏洞利用详解

题目概述

题目名称:HTB Dream Diary: Chapter 4
难度等级:INSANE
保护机制:Full RELRO、Stack Canary、NX、PIE
libc版本:2.32(引入指针加密机制)
沙箱策略:黑名单沙箱,禁用execve、open等危险系统调用

逆向分析

初始化函数分析

int (**protect_init())(const char *s) {
    seccomp_init();                    // 初始化沙箱
    boundary_start = (&puts + 0x28F7E); // 设置内存申请边界
    boundary_end = (&puts + 0x2957E);
}

沙箱规则分析

通过seccomp-tools dump分析沙箱规则:

  • 禁用:execve、execveat、open、creat、fork、vfork等
  • 允许:read、write、mprotect、mmap等

核心数据结构

struct page {  // 大小0x320字节
    __int64 type;     // 页面类型:1=只读,2=可读写
    char buf_[776];   // 数据缓冲区
    __int64 fd;       // 前向指针
    __int64 bk;       // 后向指针
};

功能模块分析

添加页面(add)

  • 两种分配方式:malloc(不清空内存)、calloc(清空内存)
  • 大小固定为0x320字节
  • 通过双向循环链表管理
  • 内存范围检查:禁止申请libc的rw段内存

删除页面(delete) - 关键漏洞

if (traverse_and_select() || count != 1) {
    // 断链操作
    fd = ::current->fd;
    bk = ::current->bk;
    fd->bk = bk;
    bk->fd = fd;
    free(::current);
    ::current = current;  // UAF:指针指向已释放内存
}

漏洞点:当count=1时,释放后current指针未清空,产生UAF

编辑页面(edit)

  • 只能编辑type=2的可读写页面
  • 可对UAF的chunk进行写操作

利用策略

阶段一:信息泄露

堆布局策略

  1. 申请9个chunk(0x320大小)
  2. 释放前6个填充tcachebin(7/7)
  3. 释放第7、8个合并为0x660的unsortedbin chunk
  4. 释放第9个进入tcachebin

触发sorting机制

关键技术:利用scanf内部缓冲区机制

  • scanf初始栈缓冲区大小:0x400
  • 输入超过0x400字节触发malloc(0x800)
  • 这将把unsortedbin chunk排序到largebin

泄露地址

  1. 通过malloc申请chunk(保留原有数据)
  2. 打印内容泄露heap和libc地址
    • heap地址:从largebin chunk的fd/bk泄露
    • libc地址:从unsortedbin chunk的bk泄露main_arena

阶段二:TSU+攻击

Tcache Stashing Unlink Attack Plus原理

当smallbin不为空且tcache未满时:

// glibc malloc.c 逻辑
while (tcache->counts[tc_idx] < mp_.tcache_count 
       && (tc_victim = last(bin)) != bin) {
    // 将smallbin chunk转移到tcache
}

通过修改smallbin chunk的bk指针,实现任意地址分配。

攻击tcache_perthread_struct

优势:绕过safe-linking指针加密

  • 目标地址:heap_base + 0x200(tcache_perthread_struct位置)
  • 条件满足:目标地址+0x18处有可写指针

布局步骤

  1. 构造smallbin链:A → B → C(C为可控UAF chunk)
  2. 修改C的bk指向tcache_perthread_struct - 0x10
  3. 申请small size chunk触发TSU+
  4. 获得tcache_perthread_struct的控制权

阶段三:劫持free_hook

修改tcache条目

  1. 控制tcache_perthread_struct后,修改0x330大小的tcache条目
  2. 将条目指向free_hook - 0x10(因为写操作从+8偏移开始)

COP Gadget利用

mov rdx, [rdi+8]  ; 可控:rdi指向chunk,[rdi+8]可控
mov [rsp], rax
call [rdx+0x20]    ; 可控跳转

利用链

  1. free(chunk) → rdi=chunk_addr
  2. 通过COP gadget设置rdx
  3. 调用[rdx+0x20] = setcontext+61进行栈迁移

阶段四:绕过沙箱执行

栈迁移到堆

  • 目标地址:heap_base + 0x308
  • 布置ROP链调用mprotect修改内存权限

x86/x64架构切换

; 切换至x86模式执行shellcode
push 0x23        ; x86代码段选择子
push x86_entry
retfq

x86_entry:
; x86 shellcode在这里执行

无execve读取flag

Shell内置命令绕过

echo *              # 查看目录文件
read line < flag; echo $line  # 读取flag文件

替代方案(如需要shellcode):

  • 使用openat+sendfile系统调用
  • 避免被沙箱拦截的系统调用

完整利用流程

堆风水布局

  1. 初始堆布局:9个chunk精心排列
  2. 触发scanf的malloc(0x800)进行sorting
  3. 泄露heap和libc基址

攻击序列

  1. 信息泄露:通过largebin残留数据泄露关键地址
  2. TSU+攻击:构造smallbin链,修改bk实现任意写
  3. 劫持控制流:通过tcache_perthread_struct控制tcache,打free_hook
  4. 栈迁移:COP + setcontext将栈迁移到堆
  5. 权限修改:ROP调用mprotect使shellcode可执行
  6. 架构切换:retfq切换到x86模式执行shellcode
  7. 读取flag:使用Shell内置命令绕过沙箱

技术要点总结

关键技术突破

  1. scanf内部机制利用:通过输入长度控制触发特定大小malloc
  2. TSU+攻击优化:直接攻击tcache_perthread_struct绕过指针加密
  3. COP Gadget应用:创新的控制流转移方式
  4. 多架构shellcode:x64到x86切换绕过沙箱限制

防护绕过技巧

  1. Safe-linking绕过:通过结构体攻击避免指针解密
  2. 沙箱绕过:利用Shell内置命令+架构切换
  3. 内存保护绕过:精确的堆布局和ROP链构造

扩展思考

漏洞利用的演进

从传统的tcache poisoning到TSU+攻击,体现了对glibc内存管理机制深入理解的重要性。

防御建议

  1. 加强UAF漏洞的检测和防护
  2. 对敏感函数指针进行额外保护
  3. 沙箱规则需要更加精细化

本案例展示了现代pwn题目中多种高级技术的综合应用,为堆漏洞利用提供了重要的技术参考。

HTB Dream Diary: Chapter 4 漏洞利用详解 题目概述 题目名称 :HTB Dream Diary: Chapter 4 难度等级 :INSANE 保护机制 :Full RELRO、Stack Canary、NX、PIE libc版本 :2.32(引入指针加密机制) 沙箱策略 :黑名单沙箱,禁用execve、open等危险系统调用 逆向分析 初始化函数分析 沙箱规则分析 通过seccomp-tools dump分析沙箱规则: 禁用:execve、execveat、open、creat、fork、vfork等 允许:read、write、mprotect、mmap等 核心数据结构 功能模块分析 添加页面(add) 两种分配方式:malloc(不清空内存)、calloc(清空内存) 大小固定为0x320字节 通过双向循环链表管理 内存范围检查:禁止申请libc的rw段内存 删除页面(delete) - 关键漏洞 漏洞点 :当count=1时,释放后current指针未清空,产生UAF 编辑页面(edit) 只能编辑type=2的可读写页面 可对UAF的chunk进行写操作 利用策略 阶段一:信息泄露 堆布局策略 申请9个chunk(0x320大小) 释放前6个填充tcachebin(7/7) 释放第7、8个合并为0x660的unsortedbin chunk 释放第9个进入tcachebin 触发sorting机制 关键技术 :利用scanf内部缓冲区机制 scanf初始栈缓冲区大小:0x400 输入超过0x400字节触发malloc(0x800) 这将把unsortedbin chunk排序到largebin 泄露地址 通过malloc申请chunk(保留原有数据) 打印内容泄露heap和libc地址 heap地址:从largebin chunk的fd/bk泄露 libc地址:从unsortedbin chunk的bk泄露main_ arena 阶段二:TSU+攻击 Tcache Stashing Unlink Attack Plus原理 当smallbin不为空且tcache未满时: 通过修改smallbin chunk的bk指针,实现任意地址分配。 攻击tcache_ perthread_ struct 优势 :绕过safe-linking指针加密 目标地址:heap_ base + 0x200(tcache_ perthread_ struct位置) 条件满足:目标地址+0x18处有可写指针 布局步骤 构造smallbin链:A → B → C(C为可控UAF chunk) 修改C的bk指向tcache_ perthread_ struct - 0x10 申请small size chunk触发TSU+ 获得tcache_ perthread_ struct的控制权 阶段三:劫持free_ hook 修改tcache条目 控制tcache_ perthread_ struct后,修改0x330大小的tcache条目 将条目指向free_ hook - 0x10(因为写操作从+8偏移开始) COP Gadget利用 利用链 : free(chunk) → rdi=chunk_ addr 通过COP gadget设置rdx 调用[ rdx+0x20 ] = setcontext+61进行栈迁移 阶段四:绕过沙箱执行 栈迁移到堆 目标地址:heap_ base + 0x308 布置ROP链调用mprotect修改内存权限 x86/x64架构切换 无execve读取flag Shell内置命令绕过 : 替代方案 (如需要shellcode): 使用openat+sendfile系统调用 避免被沙箱拦截的系统调用 完整利用流程 堆风水布局 初始堆布局:9个chunk精心排列 触发scanf的malloc(0x800)进行sorting 泄露heap和libc基址 攻击序列 信息泄露 :通过largebin残留数据泄露关键地址 TSU+攻击 :构造smallbin链,修改bk实现任意写 劫持控制流 :通过tcache_ perthread_ struct控制tcache,打free_ hook 栈迁移 :COP + setcontext将栈迁移到堆 权限修改 :ROP调用mprotect使shellcode可执行 架构切换 :retfq切换到x86模式执行shellcode 读取flag :使用Shell内置命令绕过沙箱 技术要点总结 关键技术突破 scanf内部机制利用 :通过输入长度控制触发特定大小malloc TSU+攻击优化 :直接攻击tcache_ perthread_ struct绕过指针加密 COP Gadget应用 :创新的控制流转移方式 多架构shellcode :x64到x86切换绕过沙箱限制 防护绕过技巧 Safe-linking绕过 :通过结构体攻击避免指针解密 沙箱绕过 :利用Shell内置命令+架构切换 内存保护绕过 :精确的堆布局和ROP链构造 扩展思考 漏洞利用的演进 从传统的tcache poisoning到TSU+攻击,体现了对glibc内存管理机制深入理解的重要性。 防御建议 加强UAF漏洞的检测和防护 对敏感函数指针进行额外保护 沙箱规则需要更加精细化 本案例展示了现代pwn题目中多种高级技术的综合应用,为堆漏洞利用提供了重要的技术参考。