一、背景简介

脏牛漏洞(CVE-2016–5195)是公开后影响范围最广和最深的漏洞之一,这十年来的每一个Linux版本,包括Android、桌面版和服务器版都受到其影响。恶意攻击者通过该漏洞可以轻易地绕过常用的漏洞防御方法,对几百万的用户进行攻击。尽管已针对该漏洞进行了补丁修复,但国外安全公司Bindecy对该补丁和内容做出深入研究后发现,脏牛漏洞的修复补丁仍存在缺陷,由此产生了“大脏牛”漏洞。基于多年以来针对移动端漏洞的技术积累和安全对抗,安天移动安全对“大脏牛”漏洞进行了详细的技术分析,并提供了验证方案,全文如下。

二、漏洞原理分析

2.1 脏牛漏洞回顾

在分析大脏牛漏洞前,我们需要对原始的脏牛漏洞利用方式进行完整的分析理解: 之前的漏洞是在get_user_pages函数中,这个函数能够获取用户进程调用的虚拟地址之后的物理地址,调用者需要声明它想要执行的具体操作(例如写/锁等操作),所以内存管理可以准备相对应的内存页。具体来说,也就是当进行写入私有映射的内存页时,会经过一个COW(写时拷贝)的过程,即复制只读页生成一个带有写权限的新页,原始页可能是私有保护不可写的,但它可以被其他进程映射使用。用户也可以在COW后的新页中修改内容之后重新写入到磁盘中。         

现在我们来具体看下get_user_pages函数的相关代码:

整个while循环的目的是获取请求页队列中的每个页,反复操作直到满足构建所有内存映射的需求,这也是retry标签的作用。   

follow_page_mask读取页表来获取指定地址的物理页(同时通过PTE允许)或获取不满足需求的请求内容。在follow_page_mask操作中会获取PTE的spinlock,用来保护试图获取内容的物理页不会被释放掉。

faultin_page函数申请内存管理的权限(同样有PTE的spinlock保护)来处理目标地址中的错误信息。在成功调用faultin_page后,锁会自动释放,从而保证follow_page_mask能够成功进行下一次尝试,以下是涉及到的代码。         

原始的漏洞代码在faultin_page底部:

上面这个判断语句想要表示的是,如果当前VMA中的标志显示当前页不可写,但是用户又执行了页的写操作,那么内核会执行COW操作,并且在处理中会有VM_FAULT_WRITE标志。换句话说在执行了COW操作后,上面的if判断为真,这时就移除了FOLL_WRITE标志。         

一般情况下在COW操作后移除FOLL_WRITE标志是没有问题的,因为这时VMA指向的页是刚经过写时拷贝复制的新页,我们是有写权限的,后续不进行写权限检查并不会有问题。 但是,考虑这样一种情况,如果在这个时候用户通过madvise(MADV_DONTNEED)将刚刚申请的新页丢弃掉,那这时本来在faultin_page后应该成功的follow_page_mask会再次失败,又会进入faultin_page的逻辑,但是这个时候已经没有FOLL_WRITE的权限检查了,只会检查可读性。这时内核就会将只读页面直接映射到我们的进程空间里,这时VMA指向的页不再是通过COW获得的页,而是文件的原始页,这就获得了任意写文件的能力。   

基本来看,上述的过程流也就是脏牛漏洞的利用过程。   

在faultin_page中有对应的修复补丁:

同时也加入了另一个新的follow_page_mask函数:

与减少权限请求数不同,get_user_pages现在记住了经过COW循环的过程。之后只需要有FOLL_FORCEFOLL_COW标志声明过且PTE标记为污染,就可以获取只读页的写入操作。

2.2 大脏牛漏洞分析

THP通过PMD(Pages Medium目录,PTE文件下一级)的_PAGE_PSE设置来打开,PMD指向一个2MB的内存页而非PTEs目录。PMDs在每一次扫描到页表时都会通过pmd_trans_huge函数进行检查,所以我们可以通过观察PMD指向pfn还是PTEs目录来判断是否可以聚合。在一些结构中,大PUDs(上一级目录)同样存在,这会导致产生1GB的页。 仔细查看脏牛补丁中关于THP的部分,我们可以发现大PMDs中用了和can_follow_write_pte同样的逻辑,其添加的对应函数can_follow_write_pmd

然而在大PMD中,一个页可以通过touch_pmd函数,无需COW循环就标记为dirty:

这个函数在每次get_user_pages调用follow_page_mask试图访问大页面时被调用,很明显这个注释有问题,而现在dirty bit并非无意义的,尤其是在使用get_user_pages来读取大页时,这个页会无需经过COW循环而标记为dirty,使得can_follow_write_pmd的逻辑发生错误。

在此时, 如何利用该漏洞就很明显了,我们可以使用类似脏牛的方法。这次在我们丢弃复制的内存页后,必须触发两次page fault,第一次创建它,第二次写入dirty bit。

调用链:

经过这个过程可以获得一个标记为脏的页面,并且是未COW的,剩下的就是要获取FOLL_FORCE和FOLL_COW标志了。这个过程可以采取类似dirtyCOW的利用方式。   

总结这个漏洞利用的思路如下:   

  1. 首先经过COW循环,获取到FOLL_COW标志
  2. 用madvise干掉脏页
  3. 再次获取页将直接标记为脏
  4. 写入

三、影响范围

3.1 漏洞影响范围

由于从2.6.38内核后才开始支持THP,所以漏洞影响所有内核在2.6.38以上并且开启THP的Linux系统。万幸的是在大多数Android系统的内核中没有开启THP,所以对于Android系统几乎没有影响。

3.2 如何在系统上查看是否受到影响

如果是开发者,有内核源码可以查看编译的config文件,看CONFIG_TRANSPARENT_HUGEPAGE是否打开

如果没有源码,在shell中可以查看/sys/kernel/mm/transparent_hugepage/enabled,如果输出结果为[always]表示透明大页被启用、[never]表示透明大页被禁用、[madvise]表示只在MADV_HUGEPAGE标志的VMA中启用THP,例如:

如果以上两者都没有,可以查看/proc/meminfo,如果连HugePage*都没有,那就说明没有开启大页面,也不会受到漏洞影响。

四、验证代码

验证POC请参照:https://github.com/bindecy/HugeDirtyCowPOC

五、修复建议

截止到文章发布时间,Linux各发行版本还未公布针对该漏洞的补丁信息,软件开发人员可通过:https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/commit/?h=linux-4.9.y&id=7031ae2ab37d3df53c4a4e9903329a5d38c745ec 新编译Linux修复该漏洞。如果开发人员暂时无法编译和替换内核,可以通过关闭透明大页(THP)来缓解。

六、总结

“脏牛”漏洞是Linux内核之父Linus亲自修复的,他提交的补丁单独针对“脏牛”而言并没有问题。从我们的分析过程中发现,内核的开发者希望将“脏牛”的修复方法引用到PMD的逻辑中,但是由于PMD的逻辑和PTE并不完全一致才最终导致了“大脏牛”漏洞。连内核的开发者都会犯错,更何况普通的开发者。

“大脏牛”漏洞再一次提示我们,即便是官方修复过的漏洞仍有可能由修复补丁引入新的严重漏洞,漏洞在修复后需要我们像对待原始漏洞一样继续跟踪其修复补丁。

七、参考资料

  1. https://medium.com/bindecy/huge-dirty-cow-cve-2017-1000405-110eca132de0
  2. https://bbs.pediy.com/thread-223056.htm
  3. https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-1000405

linux “大脏牛”漏洞分析(CVE-2017-1000405)相关推荐

  1. 安天移动安全发布“大脏牛”漏洞分析报告(CVE-2017-1000405)

    一.背景简介 脏牛漏洞(CVE-2016–5195)是公开后影响范围最广和最深的漏洞之一,这十年来的每一个Linux版本,包括Android.桌面版和服务器版都受到其影响.恶意攻击者通过该漏洞可以轻易 ...

  2. Linux利用脏牛漏洞提权

    实验环境:Centos6.5.ssh 实验步骤: 一.搭建实验环境 1.利用ssh连接Centos进行远程操作,在Centos6.5上安装http和php,输入yum -y install httpd ...

  3. 【内网—权限提升】——linux本地提权_脏牛漏洞提权

    文章目录 一.实验目的: 二.工具: 三.实验环境: 四.漏洞说明: 1. 原理: 2. 漏洞成因: 五.环境准备: 1. 安装Apache及php环境: 2. 安装gcc编译器(C语言编译器): 2 ...

  4. CVE-2022-0847 Linux内核提权漏洞分析

    文章目录 前言 漏洞复现 1.1 文件覆写poc/exp 1.2 覆写/etc/passwd 漏洞分析 2.1 Linux管道机制 2.2 splice系统调用 2.3 漏洞利用流程 总结 前言 20 ...

  5. Ubuntu内核提权(CVE-2017-16995)漏洞的复现脏牛漏洞

    Ubuntu内核提权漏洞的复现 这里先介绍一下漏洞,Ubuntu是一个以桌面应用为主的开源GNU/Linux操作系统,基于Debian GNU/Linux .近期有白帽子爆出 ubuntu 的最新版本 ...

  6. android local root,脏牛漏洞影响范围超出想象,以后所有Android手机都能被Root?

    原标题:脏牛漏洞影响范围超出想象,以后所有Android手机都能被Root? [新朋友]点击标题下面蓝字「皮鲁安全之家」关注 [老朋友]点击右上角,分享或收藏本页精彩内容 [公众号]搜索公众号:皮鲁安 ...

  7. PWN2OWN 2017 Linux 内核提权漏洞分析

    0.前言 在2017年PWN2OWN大赛中,长亭安全研究实验室(Chaitin Security Research Lab)成功演示了Ubuntu 16.10 Desktop的本地提权.本次攻击主要利 ...

  8. Linux脏牛漏洞提权复现

    操作系统: Linux ( CentOS 6.5) Web服务: PHP+Apache 环境搭建 第一步,配置yum源,安装PHP 进入yum目录 cd /etc/yum.repos.d/ 创建文件夹 ...

  9. linux禁用蓝牙模块,[原创]CVE-2020-12351:Linux蓝牙模块拒绝服务漏洞分析

    一. 漏洞信息 1. 漏洞简述 CVE-2020-12351是谷歌安全研究人员在Linux内核中发现的蓝牙安全漏洞.该漏洞位于net/bluetooth/l2cap_core.c,是一个基于堆的类型混 ...

最新文章

  1. 十个隐藏_LOL手游:新版增加42个英雄,大白兔:10个隐藏T0角色
  2. ssh 框架引入service_搭建SSH开发框架时autowired注入为空的问题
  3. ActiveMQ(一)简介与架构
  4. 页面中文显示问题之终结
  5. Sublime Text 2 中文包
  6. php asp.net des,转DES的dotNet到php实现
  7. python抓取网站URL小工具
  8. mysql 面试知识点笔记(七)RR如何避免幻读及非阻塞读、范式
  9. sklearn分类、回归器总结
  10. python装饰器Decorators
  11. 如何在集合中巧用Where来查找相关元素
  12. opensips mysql 版本_opensips搭建问题解决笔记
  13. 图形 3.6 纹理压缩——包体瘦身术——RGBA与ASTC与ETC2压缩与实际对比体验
  14. 你的数字生活:如何转变为一个个0和1?
  15. js打开服务器缓存文件夹路径,浅谈微信页面入口文件被缓存解决方案
  16. 基于物联网技术和RFID电子客票的铁路自动检票机
  17. UTF-8的BOM是什么意思
  18. h5如何上传文件二进制流_前端H5中JS用FileReader对象读取blob对象二进制数据,文件传输...
  19. 数据仓库——数据仓库架构、维度数据建模、雪花模型和星型模型
  20. jvm如何实现隐藏_反映一个隐藏的jvm超级大国

热门文章

  1. 阿里云接入的认证方式,一机一密、一型一密、动态注册
  2. [转]如何提升你的沟通技巧
  3. 不用图片的DIV圆角(兼容各浏览器)
  4. python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解
  5. DevOps:软件架构师行动指南1.7 障碍
  6. 《iOS 6高级开发手册(第4版)》——导读
  7. vCenter Server Appliance 5.5忘记root密码
  8. Oracle提示错误消息ORA-28001: the password has expired
  9. SCCM 2007系列5 播发操作系统下
  10. 5.MySQL Cluster(MySQL集群)