Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

admin 2022年5月8日14:13:06评论33 views字数 2600阅读8分40秒阅读模式

本篇文章一方面算是完成瑞不可当团队交代的作业之一,另一方面算是在各位技术大牛针对这个漏洞的分析文章的基础之上来个锦上添花。所以,先感谢之前各位大牛针对这个漏洞(CVE-2022-0847)的详细描述,我只是从gdb调试的角度来复现这个漏洞的利用过程(本次是从用户态层面调试,下次是从内核态层面调试),参考文章很多,不一一列举,包括但不限于如下内容:

《大白话图解 Linux 脏管道(Dirty Pipe) 漏洞(CVE-2022-0847)》

https://blog.csdn.net/weixin_44820088/article/details/123364275

《Linux内核权限提升漏洞“DirtyPipe”(CVE-2022-0847)分析》

https://mp.weixin.qq.com/s/RoGHvNW2Y6dZOjgsBVVm5Q

一、Exp文件的编译执行

从这个地址下载exp文件并编译:

https://haxx.in/files/dirtypipez.c

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

该exp执行效果简单直接,一步到位:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

该漏洞的另外一种利用方法的介绍也可以参看如下链接发布的内容:

https://mp.weixin.qq.com/s/nfX29mmLbkLtmr-055oX1Q

二、EXP文件的两个要素:

整个exp有详细的备注内容,非常清晰。我这里就说两个关键要素:

1、关键结构体pipe-buf指向某个page,实际指向了suid文件。我们在exp执行过程中使用/usr/bin/chsh这个文件,意思就是pipe-buf指向了/usr/bin/chsh这个文件。

2、关键结构体pipe-buf 带着PIPE_BUF_FLAG_CAN_MERGE,意思就是还可以向这个page中写入内容。

结合这两个关键因素,就相当于可以向/usr/bin/chsh文件中写入内容,就这样一个只是可读的suid就变成了可写的文件。至于写成什么样子,就是各个exp攻击灵活的地方了。但是根本上同时构建这两个要素就是所有该漏洞exp的基础。

  三、EXP执行过程中用户态动态调试

第一阶段:main函数准备环节

Gdb进入main函数:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

设置main断点,一步一步调试: 

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

这一段就是将fd中的从第1个字节开始算起,406个字节长度的内容拷贝到orig_byte中。备份好,后面恢复的时候会使用上。

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

其中对应的data如下内容:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

其中,/usr/bin/chsh获得的fd如下:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

对应的elfcode的长度为406:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

这里的0x7f被注释掉,因为用不到,因为fd会设置offset为1。

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

至此,main函数完成了准备阶段,将/usr/bin/chsh的offset为1之后的406个字节拷贝到orig_bytes中。

第二阶段:exp的hax函数

源码如下:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

关键是进入到hax中去执行:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

汇编代码进入hax函数:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

解释一下:file就是/usr/bin/chsh,  offset 设置为1,data指向我们构建好的elfcode,len就是406个字节。

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

查看hax函数实现:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

是的,再次打开suid文件:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

是的,再次得到3:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

第三阶段:进入prepare函数

进入这个函数的目的就是实现关键要素里面的第二个要素。

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

此时p[2]

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

栈上的一堆乱码而已。完成pipe之后:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

接着两个for循环:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

其中buffer的大小为4096,

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

而r的初始大小为65536

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

两个for循环的操作下来的效果就是16个page,连续注入和然后连续清空。目的就是保存flag为0x10,就是can merge后续的内容,这里留个悬念,我会在复现内核态的gdb调试效果里面展开。

第四阶段:进入splice函数

这个环节主要目的就是实现exp的第一个要素:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

还记得上面获得pipe

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

这里根据如下的描述:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

从/usr/bin/chsh 这个文件的offset为0的地方开始,move(传递,搬动)一个1字节的内容到,pipe的出口fd的offset为0的地方。

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

Flag为0,不是上面这些数值,说明正常处理,不做其他特殊处理,下面就是最核心的图片

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

这里的splice的效果非常妙,是整个漏洞的核心,在内核态(很快我会来补充这个漏洞在内核态的gdb的调试效果),效果就是将/usr/bin/chsh的page,挂到了pipe管道结构体中的pipe_buffer上。从这张图中的信息,就是pipe-buf通过splice函数的操作,直接指向了我们在程序设置/usr/bin/chsh文件,碰巧同时pipe-buf指向的page还保留了PIPE_BUF_FLAG_CAN_MERGE这个flag。

第五阶段:改造可写的suid文件

目前为止,已经凑齐了两个要素,剩下的就是充分利用内存中这个可写的suid文件page:

接着向pipe中写入我们之前准备的elfcode内容。

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

这里的data就是我们前面准备的elfcode,而len就是elfcode的长度。Write完成之后,查看一下nbytes的数值:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

Ok,说明顺利将elfcode写入到了suid文件中,现在的suid文件就是我们想要的样子了。下面就好办了。

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

最后hax函数收尾。下面就又回到main函数中了。

第六阶段:执行全新的suid文件和收尾

Call hax之后就回到main了:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

这个阶段的源码如下三个部分:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

第一个部分就是先执行新的suid程序,最终会产生能够产生/tmp/sh文件,该文件可以启动root权限的shell。

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

第二个部分就是还是使用hax函数来恢复我们修改过的suid的文件为最初的suid,如何恢复,使用我们最初保存的orig_bytes,这样做还是比较讲究的,执行完收尾工作。

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

第三个部分就是整个exp的结尾,启动具有root权限的shell

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

这个阶段的三个部分调试之前,在还未执行该system(path)之前,tmp文件夹的内容如下:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

之所以,这个三个部分一起调试,是因为system函数会产生子进程,该子进程会去执行elfcode的操作:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

执行一下,gdb直接到了shell:

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

同时tmp文件下也产生了对应的sh文件。

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

可以看到tmp文件夹下也生成的sh文件。至此,gdb在用户态的调试也结束了,可以看到顺利拿到shell。后续,会详细分析内核态下两个关键要素的状态。










原文始发于微信公众号(瑞不可当):Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年5月8日14:13:06
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试https://cn-sec.com/archives/981844.html

发表评论

匿名网友 填写信息