freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之内核态调试
2022-05-09 15:34:42
所属地 江苏省

本篇文章是在《Gdb调试复现Dirty Pipe漏洞(CVE-2022-0847)之用户态调试》(参考链接:https://www.freebuf.com/vuls/330722.html)的基础上,继续深入到内核态进行调试。所以,各位看官可以先看看用户态调试的内容再看本篇内核态调试,当然,技术大牛可直接看内核态调试。

第一、准备环节-增加内核调试辅助语句:

首先,为了更好的查看关键因素的变化:稍微做了两处修改:

第一处:splice前后,增加getchar和puts;

第二处:prepare pipe过程中,增加getchar和puts;

修改后代码执行结果如下:

下面内容重点关注程序运行启动之后,该漏洞利用的两个关键要素:prepare_pipe函数、splice函数的内核态分析,此外对只读的suid文件的写入进行分析。

第二、关键因素-prepare_pipe函数的内核调试

这里的prepare_pipe函数有两个环节:第一个环节是write循环,第二个环节是read循环。

在第一个环节中,当程序执行到prepare_pipe函数中write循环,这里的内核态重点是关注flag信息,此时执行状态如下:

对应的内核态执行内容:

一步一步的调试,查看flags数值变化:

结合如下的代码

可以看到517行将该flags设置为0x10,也就是can merge,这里以pipe->bufs[1]->flags为例,看内核流程和对应的变量。

这里只是显示了一次循环的结果,总计有16次循环,都会将此flags设置为can merge标记。

第二个环节就是进入到read循环,对应的执行状态和代码如下:

Read完成后,原有的flag没有改变,依旧是0x10,最终prepare_pipe结束之前得到的flags信息如下:

其中,显示3个bufs对应的flags的位置如下:

从而可以看出,prepare_pipe已经顺利完成了flags的设置,全部设置为can merge的flag。

第三、关键因素-splice函数的内核调试

设置断点

对应此时的内核代码:

以及对应的栈帧信息

进入该函数之后,可以查看flags,根据我们在用户态的推断,此时应该是0x10,gdb显示确实也是如此:

此图说明,第一个要素此时已经准备好了。下面就是splice里面的关键的page的赋值

在尚未执行到buf-page=page时,这里的buf->page和page的值如下:

完成page赋值之后,pipe的bufs[0],已经赋值为chsh这个suid文件的page了。

请记下此处的page信息0xffffea00002b3000,这里的page就是后续我们write函数的目的地址。只有能够write到这个page中,才能算是漏洞利用成功。

第四、将elfcode写入到只读suid文件对应的可读写的内存page中

设置write断点:

对应的用户态代码如下

一步一步调试进入到内核态中if判断的分支中:

此时,各个变量对应的数值如下:

此时,该page就是/usr/bin/chsh这个suid文件在内存中的page,因为该page的flag为0x10,can merge,所以,后续的内容只要不超过这个page大小,就会继续在这个page中写入。这里的chars就是elfcode。大小只有0x196,加上1之后,不超过一个page的大小。所以,就直接覆写到该page中了。这里的操作就是本漏洞利用的重点。

该处函数执行流会进入到如下代码段:

此时453行的ret为0,接着执行copy_page_from_iter函数,查看此时的汇编代码:

此时,就查看调用时的参数,终于可以确认该pipe_write函数的目的是处于0xffffea00002b3000的page。

此处执行的copy_page_from_iter的C代码如下:

接着进入到copy_page_from_iter_iovec,

进入copy_page_from_iter_iovec函数的栈之后:

然后查看该函数中关键的变量page和buf信息如下:

此时,由上图可见,最核心的两个参数都已经准备好了,page就是我们前面得到的可以merge的page,而拷贝的内容就是buf,也是我们准备好的elfcode。该流程继续执行下去就完成了将elfcode拷贝到该page中,而该page对应着具有suid权限的/usr/bin/chsh文件。

至此,内核态最核心的两个关键要素以及写入suid文件对应的page这三个部分就差不多了,剩下的就参考用户态调试即可。还是要感谢发现这个漏洞的Max Kellermann以及国内众多针对这个漏洞的展开详细描述的各位专家。这两篇文章(用户态调试和内核态调试)如有不到之处,还请各位多指教。最后,完结散花。

# GDB调试 # dirty pipe # CVE-2022-0847 # 内核态
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录