绿盟科技发布Linux内核本地提权漏洞威胁预警通告 这个漏洞9年才被修复  。就 CVE-2016-5195  这个漏洞,绿盟科技发布技术分析及防护方案。

Linux内核的内存子系统在处理写时拷贝(Copy-on-Write,缩写为COW)时存在条件竞争漏洞,导致可以破坏私有只读内存映射。一个低权限的本地用户能够利用此漏洞获取其他只读内存映射的写权限,进而可以获取整个系统的最高权限。漏洞详情如下:

https://github.com/dirtycow/dirtycow.github.io/wiki/VulnerabilityDetails

漏洞验证程序

POC链接地址如下:

https://github.com/dirtycow/dirtycow.github.io/blob/master/dirtyc0w.c

受影响的范围

该漏洞从Linux内核版本>=2.6.22以后就开始存在,影响全版本Linux,直到2016年10月18日才修复。其中Red Hat、Debian和Ubuntu三个发行版的受影响及修复情况见如下链接:

漏洞分析

COW=Copy On Write写时复制,当程序准备写一块映射的区域,则会生成一块映射的复制,对此区域的任何修改都不会写回原来的文件。在通常的情况下,如果在COW时候发生了缺页异常,则处理缺页异常的函数handle_mm_fault()函数则会停止页表写入并重试COW。

通常情况下,当一个程序写一个内存页,且这个物理页不可写的时候,会触发异常,因为当前物理页在用户空间,不在内核空间中。所以调用handle_pte_fault,这个函数经过一系列的判断,发现是因为内存页不可写导致的异常,则会调用do_wp_page来完成写时复制(COW)。不过,父子进程是以匿名映射来共享内存的,所以只需要完成reuse_swap_page即可。但是,会丢失FOLL_WRITE标志位。

如果另一个线程不停的告诉内核这个物理页不再需要、可以释放,当内核释放掉那个物理页后,handle_mm_fault在处理一个读错误(!pte_present)从而获得一个pagecache也就是文件的缓存。从而破坏私有映射完成只读文件的写入。

作者在修复代码中是这样处理的,在解除映射的时候检查了COW状态和页表的脏位(dirty bit),如下图所示:

作者在代码中增加了一个COW的标识来表示COW是否完成,设置COW位为未完成。而且,当程序要写一块内存时,必须满足以下条件:

这块内存可写或者完成COW而且脏位被设置。这样就保证了程序不会在没有COW的情况下完成写操作。

LINUX内核本地提权漏洞修复建议

  • 使用绿盟科技的远程评估系统RSAS进行安全评估。
  • 短期服务:绿盟科技工程师现场处理。确保第一时间消除网络内相关风险点,控制事件影响范围,提供事件分析报告。
  • 中期服务:提供 3-6个月的风险监控与巡检服务。根除风险,确保事件不复发。
  • 长期服务:基于行业业务风险解决方案(威胁情报+攻击溯源+专业安全服务)。

 

本安全公告仅用来描述可能存在的安全问题,绿盟科技不为此安全公告提供任何保证或承诺。由于传播、利用此安全公告所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,绿盟科技以及安全公告作者不为此承担任何责任。绿盟科技拥有对此安全公告的修改和解释权。如欲转载或传播此安全公告,必须保证此安全公告的完整性,包括版权声明等全部内容。未经绿盟科技允许,不得任意修改或者增减此安全公告内容,不得以任何方式将其用于商业目的。