Linux sudo漏洞(CVE-2017-1000367)复现和利用思路分析

栏目: 编程工具 · 发布时间: 7年前

内容简介:Linux sudo漏洞(CVE-2017-1000367)复现和利用思路分析

* 本文作者:李丽,本文属FreeBuf原创奖励计划,未经许可禁止转载

漏洞背景

在今年5.30日linux sudo被爆出存在安全漏洞,sudo版本是1.8.20以及之前的版本都有可能会受到漏洞的影响,在开启selinux的情况和普通用户在sudoer者中,可以使普通用户造成覆盖任意文件,造成权限的提升。

漏洞分析

出现漏洞主要在sudo中的/src/ttyname.c中的

char *get_proccess_ttyname()函数中,这个函数功能获取终端名称,会有多种方式获取终端名称,而此次漏洞是出现在根据读取/proc/pid/stat的方式先获取设备号,然后根据设备号获取设备名的函数中,如图所示:

Linux sudo漏洞(CVE-2017-1000367)复现和利用思路分析

从网上下了一个漏洞版本的1.8.18版本sudo源码,分析char *get_proccess_ttyname()函数的整体的执行流程。

Linux sudo漏洞(CVE-2017-1000367)复现和利用思路分析

然后看一下读取/proc/pid/stat处的代码:

Linux sudo漏洞(CVE-2017-1000367)复现和利用思路分析

可以看出是按照空格来区分来读取信息,也就是读取第7个空格之前的信息,也就是第7段的信息,百度了以下发现第7段的信息如果是非0的话就是代表设备号。

[root@localhost ~]# cat /proc/6873/stat
6873 (a.out) R 6723 6873 6723 34819 6873 8388608 77 0 0 0 41958 31 0 0 25 0 3 0 5882654 1409024 56

这里面的第7项也就是34819就是当前终端的设备号,第2项a.out就是进程名字。

这里在回顾一下源代码中获取设备号的逻辑是判断有7个空格取空格前一项也就是第7项数据,第二项是进程的名字,漏洞就出现在这里,进程名字是我们可以可控的,那么如果进程名字里面出现空格的话,还能获取到正确的设备名么,当然就是不能,那么进程名是可变的,我们就可以通过构造带有空格的进程名字来伪装设备号,例如进程名字。 “34873“那么我们获取到的设备号就是34873。

那么根据上面的代码的分析流程可以看出,34873的设备号就是不存在的,那么如果我们创建一个软连接为

“34873 ”链接到/usr/bin/sudo下,当我执行这个软连接时,就会调用到sudo本身的get_proccess_ttyname

函数中,因为这个时候在/proc/pid/stat 的进程名字是“34873 ”所以获取到的设备号就是34873这个我们自己伪造的设备号,但是这时大家都在想了,我们伪造了一个假的设备号有什么用么?因为get_proccess_ttyname的获取是如果找不到这个设备号对应的设备名称那么就是返回空,那么如果后续的官方的伪装成任意文件的设备终端就不了了之了,那么我们应该根据这个可以伪装任意设备号的漏洞来一步一步的把当前的设备名字伪装成任意文件呢?

这里我们在看以下查找设备名字的流程,根据设备号先在几个指定的目录下去遍历例如 /dev/pts /dev/pt等目录进行遍历用stat函数获取设备号,看是否相同,下图所示

Linux sudo漏洞(CVE-2017-1000367)复现和利用思路分析

因为这个设备号对应的设备名字是不存在的所以在这几个指定的目录下是找不到的,那么如果找不到的话,函数就是会从/dev下遍历所有目录,除了几个设置忽略的目录:

Linux sudo漏洞(CVE-2017-1000367)复现和利用思路分析

忽略的目录

Linux sudo漏洞(CVE-2017-1000367)复现和利用思路分析

就是除了这几个目录,最后一次会遍历所有的文件去查找设备名,这个时候漏洞的另外一个关键的点出来了,可以看/dev目录下有两个特殊目录,一个是/dev/shm,一个是/dev/mqueue,因为有的系统没有/dev/mqueue,所以我就看一下/dev/shm的这个文件夹:

Linux sudo漏洞(CVE-2017-1000367)复现和利用思路分析

可以看出这个文件夹普通用户是有写权限的,就是说明普通用户可以随便改里面的内容,那么我们是不是就可以当遍历到/dev/shnm/目录下的时候,我们创建一个软连接例如/dev/shnm/_tty的一个软连接,使这个软连接指向一个设备号为我们伪造的34873的设备号,那么我们是不是就是可以获取到设备名称了,它就是软连接的名称/dev/shnm/_tty,因为这个软连接我们是可以控制的,我们可以把这个软连接在get_proccess_ttyname函数返回后,我们可以把这个软连接重新链接到任意的文件,例如一些私密的文件/etc/passwd等。

这个时候我们已经获取了一个假的软连接,这个软连接可以指向任何文件位置,那么我们如何使造成往文件中写内容呢,这里看以下官网的漏洞分析:

Linux sudo漏洞(CVE-2017-1000367)复现和利用思路分析

大概意思就是,在一个selinux开启的系统上,sudo进程会通过这个relabel_tty()这个函数以O_RDWR读写方式打开复制一份的sudo终端设备文件,并把输入流,输出流,错误流写入到设备终端文件中去。

Linux sudo漏洞(CVE-2017-1000367)复现和利用思路分析

这块没太分析,通过设置某个参数,并且在selinux开启的时候,就会把stdin等输入到虚拟终端的设备文件中,因为虚拟终端的设备文件,普通用户是写不了的,这个函数既然可以往/dev/pts/文件中写内容,那么同理一下可以往我们软连接重定向的/etc/passwd里面写入内容,这样就可以完成造成任意文件的内容覆盖,造成权限的提升。

漏洞触发的关键几点

1:可以伪造任意不存在的设备号

2:在伪造任意的设备号后,在遍历查找设备名的时候,/dev/shnm 是个用户可控的目录因为有写权限,可以这时候创建一个软连接并且指向一个设备文件,这个设备文件的设备号就是我们伪造的那个。

3:在之后替换我们的软连接的指向位置,在selinux开启的时候sudo构造”-r”, “unconfined_r”等参数

就会把输入,输出写到我们伪装的敏感文件中去,达到提权。

官方分析漏洞分析解释和自己的疑问解答

第一步:在/dev/shnm/_tmp,先创建一个空的链接/dev/shm/_tmp__tty指向/dev/pts/57,它的设备号就是我们伪造的34873.

Q:为什么最开始就创建一个空的链接指向,而不是直接创建一个/dev/pts/57的虚拟设备文件,为什么/dev/pts/57它的设备号就是34873

Linux sudo漏洞(CVE-2017-1000367)复现和利用思路分析

A:因为要是最开始就创建一个链接指向的话,因为get_proccess_ttyname函数会先遍历/dev/pts等几个目录,一开始创建的话就在/dev/pts下就会找到了,也就不能漏洞利用了,我在 Linux 下我试了一下/dev/pts/1的设备号是34817之后就是递增的关系,所以/dev/pts/57是34873

第二步:我们执行/dev/shm/_tmp/     34873 指向sudo的软连接,这时候就会搜索设备号,没什么疑问。

第三步:设备标志,为了把输出能写到设备文件中去。

第四步:监控/dev/shm/_tmp的open函数,为什么能走到这里,因为它在/dev/pts/下没有找到,我们没有创建/dev/pts/57

第五步:这个时候我们监控到open /dev/shm/_tmp函数的消息,启动另外一个进程把这个阻塞住,然后不断的去获取/dev/pts/57虚拟终端就是poc的下列代码

Linux sudo漏洞(CVE-2017-1000367)复现和利用思路分析

当获取完了之后,把sudo的进程放下,这个时候遍历到软连接的时候,这个软连接指向的/dev/pts/57就是存在的,设备号就是34873,就会找到返回终端名字 /dev/shm/_tmp/_tty 就成功伪造了一个可以指向任意文件的软连接了。poc代码中在阻塞之前还用了这样一段代码

Linux sudo漏洞(CVE-2017-1000367)复现和利用思路分析

为什么要这么做呢,就是因为害怕当我们触发open函数的时候当我们阻塞的时候这个时候sudo的函数都已经执行完了,因为是多核的调度,那这时候我们的虚拟终端还没有创建,那么这就是不会成功利用了,为了让它不能在得到在阻塞之前就执行完了,用到了setpriority这个函数,这个函数的作用是使这两个进程都用一个CPU进行执行,并且执行sudo的那个进程的优先级是低的19,阻塞的那个进程是-20优先级是高的,而且竞争一个cpu执行,所以所以很大几率上可以阻塞住的,这就是官网分析上所提到的2次的竞争才利用成功,其实poc有时候是利用失败的,就是说没竞争过,在阻塞的时候,sudo的都已经查找到那个软连接了,结果那个软连接还是空的,所以就是失败了。

第六步:同理在要关闭的时候,这个时候把软连接换成我们想要覆盖的文件,可以达到覆盖目的。

利用思路图解

Linux sudo漏洞(CVE-2017-1000367)复现和利用思路分析

漏洞复现

1.把自己添加到sudoer者中,然后开启selinux保证开启,执行git上的漏洞poc,poc链接会在最后参考链接中,发现大部分可以成功,覆盖文件如图:

Linux sudo漏洞(CVE-2017-1000367)复现和利用思路分析

官方补丁

1.修复了在空格处的判断

2.在忽略路径中添加了/dev/shnm和/dev/mqueue

Linux sudo漏洞(CVE-2017-1000367)复现和利用思路分析

因为第一次分析,可能还有很多不对的地方,还请大家多多批评指正,谢谢

qq:2606627006

参考链接

http://seclists.org/fulldisclosure/2017/Jun/3

https://github.com/c0d3z3r0/sudo-CVE-2017-1000367

http://www.securityfocus.com/bid/98838

http://www.freebuf.com/vuls/136156.html

* 本文作者:李丽,本文属FreeBuf原创奖励计划,未经许可禁止转载


以上所述就是小编给大家介绍的《Linux sudo漏洞(CVE-2017-1000367)复现和利用思路分析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

ANSI Common Lisp

ANSI Common Lisp

Paul Graham / Prentice Hall / 1995-11-12 / USD 116.40

For use as a core text supplement in any course covering common LISP such as Artificial Intelligence or Concepts of Programming Languages. Teaching students new and more powerful ways of thinking abo......一起来看看 《ANSI Common Lisp》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具