CVE-2022-3910与DirtyCred:Linux权限提升漏洞解析
字数 1737 2025-08-29 08:30:18

CVE-2022-3910与DirtyCred: Linux权限提升漏洞深度解析

漏洞概述

CVE-2022-3910是Linux内核中的一个权限提升漏洞,存在于io_uring子系统的io_msg_ring功能中。该漏洞允许攻击者通过特定的操作序列实现文件结构体的释放后重用(UAF),结合DirtyCred技术可以实现从普通用户到root用户的权限提升。

漏洞环境

  • 影响内核版本:Linux kernel v5.19.0
  • 漏洞组件:io_uring子系统

漏洞成因分析

关键函数分析

漏洞位于io_msg_ring函数中,当调用io_put_file函数时未进行适当的检查:

// 漏洞代码逻辑
void io_msg_ring(...) {
    ...
    io_put_file(file);  // 未进行充分检查就调用
    ...
}

io_put_file函数的作用是检查文件是否存在,如果存在就将文件的引用计数(refcount)递减,当文件的refcount为0时释放该文件:

static void io_put_file(struct file *file) {
    if (file) {
        if (atomic_dec_and_test(&file->f_count))
            __fput(file);
    }
}

触发路径

该漏洞通过io_issue_sqe函数的IORING_OP_MSG_RING选项触发。

Fixed Files机制

io_uring中的"fixed files"机制是漏洞的关键:

  1. 使用IORING_REGISTER_FILES操作码注册文件时,内核会引用并保持这些文件描述符打开
  2. 这些文件描述符称为"fixed files"
  3. 应用程序可以关闭原始文件描述符,但io_uring中的引用仍然保持
  4. fixed files在后续操作中不是通过原始文件描述符引用,而是通过注册时的数组偏移量

引用计数问题

对于fixed files和普通文件,内核有不同的处理方式:

  1. 普通文件处理 (io_file_get_normal):

    • 使用fget增加引用计数
    • 使用fput减少引用计数
    • 不会出现UAF情况
  2. Fixed files处理 (io_file_get_fixed):

    • 从file_table中根据固定fd载入
    • 不涉及引用计数的变化
    • 正常逻辑中fixed files使用后不应进行递减操作

通过gdb调试可以观察到fixed file的引用计数:

pwndbg> p ((struct file*)0xffff888100ac3900)->f_count 
$2 = { counter = 2 }

漏洞利用分析

基本利用思路

  1. 注册一个文件为fixed file
  2. 利用漏洞删除它,获得一个被free掉的file结构体指针
  3. 通过精心设计的内存操作实现权限提升

DirtyCred技术

DirtyCred是一种利用内核凭证和文件对象释放后重用的攻击技术。在本漏洞中,需要解决以下问题:

  1. 如何将内存破坏漏洞转换为可利用的原语
  2. 如何延长文件"权限检查-数据写入"的竞争窗口
  3. 如何创建高权限的credential object来占据被释放的低权限对象的内存空间

关键利用步骤

  1. 内存置换

    • 利用漏洞free掉fixed file后,立即open一个新文件来占用原本的空间
    • 测试表明这种置换是可行的
  2. 延长竞争窗口

    • 内核文件系统写入流程:
      1. 文件权限检查(是否可写)
      2. 实际写入数据至文件
    • 需要在第一步和第二步之间将低权限文件结构体替换成特权文件
  3. 利用userfaultfd延长窗口

    • 内核在写入前会拷贝iovec向量数据,触发缺页异常
    • 使用userfaultfd可以控制这个缺页处理,延长竞争窗口

完整利用流程

  1. 进程1向低权限文件写入大量数据(约0.2GB)
  2. 进程2开始写操作:
    • 先检查文件读写权限(此时为低权限状态,检查通过)
    • 由于进程1正在写入,进程2会等待
  3. 在进程1检查结束后,进行UAF操作:
    • 将低权限文件替换为特权文件
  4. 进程1写入完成:
    • 文件已被篡改为特权文件并通过了读写检查
    • 数据被写入到特权文件中

漏洞修复

漏洞修复应关注io_put_file函数对fixed files的处理,确保不会错误地递减fixed files的引用计数或释放它们。

防御建议

  1. 及时更新内核到修复版本
  2. 限制普通用户使用userfaultfd功能
  3. 监控可疑的io_uring操作
  4. 使用内核防护机制如SLAB_HARDENED等

总结

CVE-2022-3910展示了io_uring子系统中fixed files处理不当可能导致严重的安全问题。结合DirtyCred技术,攻击者可以实现权限提升。理解这类漏洞的成因和利用技术对于系统安全防护至关重要。

CVE-2022-3910与DirtyCred: Linux权限提升漏洞深度解析 漏洞概述 CVE-2022-3910是Linux内核中的一个权限提升漏洞,存在于io_ uring子系统的 io_msg_ring 功能中。该漏洞允许攻击者通过特定的操作序列实现文件结构体的释放后重用(UAF),结合DirtyCred技术可以实现从普通用户到root用户的权限提升。 漏洞环境 影响内核版本:Linux kernel v5.19.0 漏洞组件:io_ uring子系统 漏洞成因分析 关键函数分析 漏洞位于 io_msg_ring 函数中,当调用 io_put_file 函数时未进行适当的检查: io_put_file 函数的作用是检查文件是否存在,如果存在就将文件的引用计数(refcount)递减,当文件的refcount为0时释放该文件: 触发路径 该漏洞通过 io_issue_sqe 函数的 IORING_OP_MSG_RING 选项触发。 Fixed Files机制 io_ uring中的"fixed files"机制是漏洞的关键: 使用 IORING_REGISTER_FILES 操作码注册文件时,内核会引用并保持这些文件描述符打开 这些文件描述符称为"fixed files" 应用程序可以关闭原始文件描述符,但io_ uring中的引用仍然保持 fixed files在后续操作中不是通过原始文件描述符引用,而是通过注册时的数组偏移量 引用计数问题 对于fixed files和普通文件,内核有不同的处理方式: 普通文件处理 ( io_file_get_normal ): 使用 fget 增加引用计数 使用 fput 减少引用计数 不会出现UAF情况 Fixed files处理 ( io_file_get_fixed ): 从file_ table中根据固定fd载入 不涉及引用计数的变化 正常逻辑中fixed files使用后不应进行递减操作 通过gdb调试可以观察到fixed file的引用计数: 漏洞利用分析 基本利用思路 注册一个文件为fixed file 利用漏洞删除它,获得一个被free掉的file结构体指针 通过精心设计的内存操作实现权限提升 DirtyCred技术 DirtyCred是一种利用内核凭证和文件对象释放后重用的攻击技术。在本漏洞中,需要解决以下问题: 如何将内存破坏漏洞转换为可利用的原语 如何延长文件"权限检查-数据写入"的竞争窗口 如何创建高权限的credential object来占据被释放的低权限对象的内存空间 关键利用步骤 内存置换 : 利用漏洞free掉fixed file后,立即open一个新文件来占用原本的空间 测试表明这种置换是可行的 延长竞争窗口 : 内核文件系统写入流程: 文件权限检查(是否可写) 实际写入数据至文件 需要在第一步和第二步之间将低权限文件结构体替换成特权文件 利用userfaultfd延长窗口 : 内核在写入前会拷贝iovec向量数据,触发缺页异常 使用userfaultfd可以控制这个缺页处理,延长竞争窗口 完整利用流程 进程1向低权限文件写入大量数据(约0.2GB) 进程2开始写操作: 先检查文件读写权限(此时为低权限状态,检查通过) 由于进程1正在写入,进程2会等待 在进程1检查结束后,进行UAF操作: 将低权限文件替换为特权文件 进程1写入完成: 文件已被篡改为特权文件并通过了读写检查 数据被写入到特权文件中 漏洞修复 漏洞修复应关注 io_put_file 函数对fixed files的处理,确保不会错误地递减fixed files的引用计数或释放它们。 防御建议 及时更新内核到修复版本 限制普通用户使用userfaultfd功能 监控可疑的io_ uring操作 使用内核防护机制如SLAB_ HARDENED等 总结 CVE-2022-3910展示了io_ uring子系统中fixed files处理不当可能导致严重的安全问题。结合DirtyCred技术,攻击者可以实现权限提升。理解这类漏洞的成因和利用技术对于系统安全防护至关重要。