CVE-2017–1000405漏洞原理分析
字数 2204 2025-08-18 11:38:32
CVE-2017-1000405 (大脏牛)漏洞深度分析
1. 漏洞背景
CVE-2017-1000405,又称"大脏牛"(Huge Dirty Cow),是继2016年著名的"脏牛"(Dirty Cow,CVE-2016-5195)漏洞之后,Linux内核中发现的又一个严重提权漏洞。该漏洞由Bindecy安全团队发现,影响范围广泛:
- 影响版本:Linux内核2.6.38至4.14
- 影响设备:服务器、桌面系统、移动设备等所有使用受影响内核版本的设备
- 漏洞性质:内核提权漏洞
- 根源:对CVE-2016-5195漏洞修补不完整导致
2. 前置知识:脏牛漏洞(CVE-2016-5195)回顾
要理解大脏牛漏洞,必须先了解其前身脏牛漏洞的原理。
2.1 脏牛漏洞核心机制
脏牛漏洞位于get_user_pages函数中(mm/gup.c),当通过write系统调用向/proc/self/mem写入数据时,内核会调用此函数获取要写入的内存地址。
漏洞触发流程:
get_user_pages调用follow_page_mask获取内存页表项,要求页表项指向的内存映射具有可写权限- 如果第一次获取失败,调用
faultin_page进行缺页处理 - 第二次调用
follow_page_mask尝试获取页表项 - 如果第二次仍失败(如页表项指向只读映射),第三次调用
follow_page_mask时不再要求写权限 - 获取成功后内核会对这个只读内存进行强制写入操作
2.2 关键竞争条件
当第二次获取页表项失败后,如果另一个线程执行:
madvise(addr, addrlen, MADV_DONTNEED)
其中addr~addrlen是一个只读文件的VM_PRIVATE只读内存映射,会导致:
- 该映射的页表项被置空
- 第三次
follow_page_mask调用成功获取页表项 - 由于不要求写权限,缺页处理时内核不会执行COW(Copy-On-Write)操作
- 最终导致对只读文件的越权写入,实现权限提升
3. 大脏牛漏洞(CVE-2017-1000405)分析
3.1 漏洞根源
大脏牛漏洞源于脏牛漏洞补丁中关于大页(Huge Page)内存管理的缺陷:
- Linux支持大页内存管理(THP - Transparent Huge Pages):
- 常规页:4KB
- 大页:2MB或1GB
- 补丁中的
touch_pmd函数允许页面无需COW循环就被标记为dirty - 该函数在
follow_page_mask每次获取get_user_pages试图访问大页时被调用 - 错误逻辑导致:读取大页时,页面会无需COW循环就被标记为dirty
3.2 漏洞利用原理
- 攻击者可获取复制的内存页
- 可以污染两次原始页:
- 第一次:创建页面
- 第二次:写入dirty bit
- 利用方式与原始脏牛漏洞类似
3.3 漏洞利用POC
官方提供的漏洞验证代码:
https://github.com/bindecy/HugeDirtyCowPOC
4. 影响范围
4.1 受影响版本
- Linux内核2.6.38至4.14
- 需要系统开启大页内存管理支持
详细受影响版本参考:
https://nvd.nist.gov/vuln/detail/CVE-2017-1000405/cpes?expandCpeRanges=true
4.2 受影响设备
- 服务器
- 桌面系统
- 移动设备(Android等)
- 其他使用Linux内核的设备
5. 修复方案
5.1 官方补丁
建议所有受影响系统升级到已修复的内核版本。官方已发布相关补丁。
5.2 临时缓解措施
对于无法立即升级的系统,可考虑:
- 禁用THP(透明大页)功能:
echo never > /sys/kernel/mm/transparent_hugepage/enabled - 限制对
/proc/self/mem的访问权限
6. 技术细节补充
6.1 关键函数分析
get_user_pages():
- 位于mm/gup.c
- 负责获取用户空间页面的内核映射
- 可能触发缺页处理
follow_page_mask():
- 用于获取页表项
- 在脏牛漏洞中关键的三次调用逻辑
touch_pmd():
- 大脏牛漏洞的关键函数
- 错误地允许页面无需COW就被标记为dirty
6.2 内存映射类型
VM_SHARE:
- 映射更改会写回文件
- 需要进程有文件写权限
VM_PRIVATE:
- 映射更改不会写回文件
- 在脏牛漏洞利用中起关键作用
6.3 COW机制
Copy-On-Write(写时复制)是Linux内存管理的重要机制:
- 当进程尝试写入共享的只读内存时
- 内核会创建该页面的副本供写入
- 原始页面保持不受影响
- 在大脏牛漏洞中,COW机制被绕过