内核漏洞挖掘技术系列(7)——静态模式匹配
字数 2158 2025-08-04 08:17:33

内核漏洞挖掘技术:静态模式匹配检测Double Fetch漏洞

1. 概述

本文档详细介绍了使用静态模式匹配技术检测内核Double Fetch漏洞的方法,基于USENIX Security 2017论文《Detecting Kernel Double-Fetch Bugs in Dependable Systems via Static Analysis》和开源工具doublefetch。

2. Double Fetch漏洞原理

Double Fetch漏洞是指内核代码中两次从用户空间获取同一数据而中间没有适当验证的情况。攻击者可以在两次获取之间修改用户空间数据,导致内核使用不一致的数据,可能引发安全漏洞。

2.1 漏洞分类

论文将Double Fetch漏洞分为三类:

  1. Type Selection(类型选择)

    • 先获取消息头识别消息类型
    • 根据类型获取和处理整个消息
    • 第二次获取时可能被修改类型
  2. Size Checking(大小检查)

    • 先获取消息头确定大小
    • 分配缓冲区后获取整个消息
    • 第二次获取后使用的大小可能被修改
  3. Shallow Copy(浅拷贝)

    • 第一个缓冲区包含指向第二个缓冲区的指针
    • 只复制第一个缓冲区,第二个缓冲区需第二次获取
    • 两次获取之间指针指向的数据可能被修改

3. 静态分析工具架构

开源工具doublefetch包含三个主要部分:

text-filter/      # 文本过滤方法源代码
cocci/            # 基于coccinelle的模式匹配方法
auto_fix/         # 自动修补工具

3.1 核心组件

cocci/目录包含关键文件:

  • testdir/: 存放待分析的内核源文件
  • startcocci_linux.sh: 启动分析的shell脚本
  • pattern_match_linux.cocci: Coccinelle规则脚本
  • copy_files.py: 复制潜在漏洞文件到outcome目录

4. 匹配模式规则

论文实现了6种基于Coccinelle的检测规则:

4.1 基本规则(Rule 0)

匹配对同一地址的两次读取操作(basic pattern)。

4.2 精炼规则(Refined Patterns)

  1. No Pointer Change(指针不变)

    • 确保两次获取操作使用相同的用户指针
    • 排除指针自增、添加偏移量或重新赋值的情况
  2. Pointer Aliasing(指针别名)

    • 处理用户指针被赋给另一个指针的情况
    • 可能在函数开头或两次获取之间发生
  3. Explicit Type Conversion(显式类型转换)

    • 处理内核中常见的指针类型转换
    • 例如在size checking场景中的头指针转换
  4. Combination of Element Fetch and Pointer Fetch

    • 处理获取整个结构和获取结构元素的情况
    • 例如get_user(len,ptr->len)copy_from_user(msg,ptr,len)
  5. Loop Involvement(循环处理)

    • 处理循环中的误报情况
    • 排除上一次迭代的第二次获取与下一次迭代的第一次获取的匹配

5. 工具使用流程

  1. 安装依赖:apt-get install coccinelle
  2. 将内核源文件复制到testdir/目录
  3. 运行分析脚本:./startcocci_linux.sh
  4. 检查结果:
    • result.txt: 包含匹配结果
    • outcome/: 包含潜在漏洞的源文件

6. 避免Double Fetch的建议

  1. 不要拷贝两次消息头

    • 第二次获取时只拷贝消息体
  2. 使用相同的值

    • 只使用第一次获取的数据
  3. 覆盖数据

    • 用第一次获取的头部覆盖第二次获取的头部
  4. 比较数据

    • 比较两次获取的数据,不一致则中止
  5. 同步获取

    • 使用锁或临界区保证原子性(有性能开销)

7. 相关研究与改进

IEEE S&P 2018论文《Precise and Scalable Detection of Double-Fetch Bugs in OS Kernels》提出了DEADLINE工具:

  1. 使用静态分析收集multi-read操作
  2. 对每组关联的multi-read进行符号执行检查
  3. 在LLVM IR层面验证是否满足Double Fetch的形式化定义
  4. 显著减少了误报率

8. 静态与动态方法比较

比较维度 静态匹配 动态挖掘(如bochspwn)
漏洞复现 可能有误报,需人工验证 通常可复现
适用范围 仅开源系统 开源/闭源系统均可
代码覆盖 全代码扫描 依赖fuzzer覆盖率
深层问题 难发现编译优化等问题 可发现深层问题

9. 扩展应用

静态匹配技术不仅限于Double Fetch检测,还可用于:

  1. 发现相似漏洞模式
    • 例如copy_from_user参数写反的错误
  2. 使用Semmle QL或Coccinelle搜索特定模式
  3. 审计已知漏洞的变体

10. 实践建议

  1. 结合静态和动态方法提高效果
  2. 对静态结果进行人工审计时:
    • 关注数据使用情况
    • 验证是否真的可能被利用
  3. 考虑Windows系统的静态分析可能性
    • 通过IDA反编译和符号文件辅助分析
    • 识别Windows内核中的类似模式
内核漏洞挖掘技术:静态模式匹配检测Double Fetch漏洞 1. 概述 本文档详细介绍了使用静态模式匹配技术检测内核Double Fetch漏洞的方法,基于USENIX Security 2017论文《Detecting Kernel Double-Fetch Bugs in Dependable Systems via Static Analysis》和开源工具doublefetch。 2. Double Fetch漏洞原理 Double Fetch漏洞是指内核代码中两次从用户空间获取同一数据而中间没有适当验证的情况。攻击者可以在两次获取之间修改用户空间数据,导致内核使用不一致的数据,可能引发安全漏洞。 2.1 漏洞分类 论文将Double Fetch漏洞分为三类: Type Selection (类型选择) 先获取消息头识别消息类型 根据类型获取和处理整个消息 第二次获取时可能被修改类型 Size Checking (大小检查) 先获取消息头确定大小 分配缓冲区后获取整个消息 第二次获取后使用的大小可能被修改 Shallow Copy (浅拷贝) 第一个缓冲区包含指向第二个缓冲区的指针 只复制第一个缓冲区,第二个缓冲区需第二次获取 两次获取之间指针指向的数据可能被修改 3. 静态分析工具架构 开源工具doublefetch包含三个主要部分: 3.1 核心组件 cocci/ 目录包含关键文件: testdir/ : 存放待分析的内核源文件 startcocci_linux.sh : 启动分析的shell脚本 pattern_match_linux.cocci : Coccinelle规则脚本 copy_files.py : 复制潜在漏洞文件到outcome目录 4. 匹配模式规则 论文实现了6种基于Coccinelle的检测规则: 4.1 基本规则(Rule 0) 匹配对同一地址的两次读取操作(basic pattern)。 4.2 精炼规则(Refined Patterns) No Pointer Change (指针不变) 确保两次获取操作使用相同的用户指针 排除指针自增、添加偏移量或重新赋值的情况 Pointer Aliasing (指针别名) 处理用户指针被赋给另一个指针的情况 可能在函数开头或两次获取之间发生 Explicit Type Conversion (显式类型转换) 处理内核中常见的指针类型转换 例如在size checking场景中的头指针转换 Combination of Element Fetch and Pointer Fetch 处理获取整个结构和获取结构元素的情况 例如 get_user(len,ptr->len) 和 copy_from_user(msg,ptr,len) Loop Involvement (循环处理) 处理循环中的误报情况 排除上一次迭代的第二次获取与下一次迭代的第一次获取的匹配 5. 工具使用流程 安装依赖: apt-get install coccinelle 将内核源文件复制到 testdir/ 目录 运行分析脚本: ./startcocci_linux.sh 检查结果: result.txt : 包含匹配结果 outcome/ : 包含潜在漏洞的源文件 6. 避免Double Fetch的建议 不要拷贝两次消息头 第二次获取时只拷贝消息体 使用相同的值 只使用第一次获取的数据 覆盖数据 用第一次获取的头部覆盖第二次获取的头部 比较数据 比较两次获取的数据,不一致则中止 同步获取 使用锁或临界区保证原子性(有性能开销) 7. 相关研究与改进 IEEE S&P 2018论文《Precise and Scalable Detection of Double-Fetch Bugs in OS Kernels》提出了DEADLINE工具: 使用静态分析收集multi-read操作 对每组关联的multi-read进行符号执行检查 在LLVM IR层面验证是否满足Double Fetch的形式化定义 显著减少了误报率 8. 静态与动态方法比较 | 比较维度 | 静态匹配 | 动态挖掘(如bochspwn) | |---------|---------|---------------------| | 漏洞复现 | 可能有误报,需人工验证 | 通常可复现 | | 适用范围 | 仅开源系统 | 开源/闭源系统均可 | | 代码覆盖 | 全代码扫描 | 依赖fuzzer覆盖率 | | 深层问题 | 难发现编译优化等问题 | 可发现深层问题 | 9. 扩展应用 静态匹配技术不仅限于Double Fetch检测,还可用于: 发现相似漏洞模式 例如 copy_from_user 参数写反的错误 使用Semmle QL或Coccinelle搜索特定模式 审计已知漏洞的变体 10. 实践建议 结合静态和动态方法提高效果 对静态结果进行人工审计时: 关注数据使用情况 验证是否真的可能被利用 考虑Windows系统的静态分析可能性 通过IDA反编译和符号文件辅助分析 识别Windows内核中的类似模式