一、简介
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); }; 第一次:调用__get_user_pages_locked函数 __get_user_pages_locked(struct task_struct *tsk, struct mm_st
4A评测 - 免责申明
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。
不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!
程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。
侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)