Linux内核dirtyCOW漏洞分析
2024-11-1 16:24:35 Author: www.freebuf.com(查看原文) 阅读量:1 收藏

freeBuf

主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

一、简介

dirtyCOW(编号CVE-2016-5195)是一个常用于Linux本地提权的漏洞,可以修改操作系统中的任意文件,包括系统存储的账户信息文件,影响的Linux内核版本在2.6.22 到 4.9.x之间。

二、基本原理

dirtyCOW的触发基于race condition,通过内核错误处理机制的逻辑缺陷实施攻击。攻击过程需要父子进程之间的合作。当子进程向一个只读文件发出写请求时,发起write()系统调用,write()中调用get_user_pages获取进程内存中请求的文件页面,某个进程如果需要修改硬盘中的文件,需要把该文件映射到内存中,再通过get_user_pages获得页面后,才可以进行修改。

第一次调用时内存中并没有进程指定的文件,所以会发生缺页处理,在处理缺页的过程中内核得知发起该请求的是一个子进程,所以使用COW(copy on write写时复制)处理,把该文件复制到父子进程的内存区域,然后单独复制一个副本给子进程,包括该文件的权限。

第一次缺页处理完成后,返回到__get_user_page函数,第二次尝试获得该文件对应的页面,检查到该文件对于进程而言原本只有写权限,所以又一次发生缺页处理,此次缺页处理经过逻辑判断,会认为这次要处理的是一个发生了COW的页面权限问题,所以将继续使用已经复制到内存的页面,并删除某些关于权限的重要标志,为该进程设置对该页面的写权限,接着再返回到__get_user_pages函数继续获取页面。

这样做本身没什么问题,因为子进程获得的内存中的文件页面只是一个COW副本,对其进行修改并不会保存到原始文件中。但是,如果此时父进程发起madvice()调用,向内核建议置空该页面,也就是把该页面到文件的映射取消,只留下页表项(包含了子进程的权限信息,此时已经被设置为可写),在进行页面检查前把该页面置空,那么在__get_user_pages函数继续执行时,会发生第三次缺页处理。

本次缺页处理会因为之前的一些重要标志的删除,把这次请求视作一个不需要写权限的缺页处理,调用do_read_fault函数,该函数会把原始文件直接映射到该页表项对应的内存区域中。因为内核认为这次缺失的页面进程只需要对其进行读操作,为了节省内存,所以把该文件直接映射,这样做本身没有什么问题,但是此时的页表项是之前对于COW副本的页表项,仍然具有写权限,导致子进程可以对该页表项对应的原始文件进行写操作,修改后的数据会被保存回硬盘中,最终导致了越权写操作。

如果该文件是/etc/passwd,保存了系统上所有用户的权限设置信息,对其进行越权写,就可以使得攻击者获得root权限。

三、控制流分析

以下是整个控制流代码的简化版(分为四次执行过程):

//接口函数,负责把参数传递给处理函数
get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
unsigned long start, unsigned long nr_pages, int write,
int force, struct page **pages, struct vm_area_struct **vmas)

{
return __get_user_pages_locked(tsk, mm, start, nr_pages, write, force,
pages, vmas, NULL, false, FOLL_TOUCH);
};
第一次:调用_

已在FreeBuf发表 0 篇文章

本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022


文章来源: https://www.freebuf.com/vuls/414287.html
如有侵权请联系:admin#unsafe.sh