CVE-2022-0847(Dirty Pipe)

简介

2022年03月07日,国外安全研究员Max Kellermann披露了一个Linux内核本地权限提升漏洞 CVE-2022-0847。攻击者通过利用此漏洞可进行任意可读文件重写,将普通权限用户提升到 root权限。该漏洞原理类似于 CVE-2016-5195(Dirty Cow),因此作者将此漏洞命名为“Dirty Pipe”。

漏洞作者原文:https://dirtypipe.cm4all.com

影响范围

  • Linux内核版本大于等于5.8,或小于5.16.11,5.15.25,5.10.102

漏洞原理

  • 页面(Page):CPU管理的最小内存单位, 一个页面通常为4kB大小, linux内存管理的最底层的一切都是关于页面的, 文件IO也是如此, 如果程序从文件中读取数据, 内核将先把它从磁盘读取到专属于内核的页面缓存(Page Cache)中, 后续再把它从内核区域复制到用户程序的内存空间中;
  • 管道(Pipe):一种用于单向进程间通信的工具, 它包含一个输入端和一个输出端, 程序将数据从一段输入, 从另一端读出; 在内核中, 为了实现这种数据通信, 需要以页面(Page)为单位维护一个环形缓冲区(通过pipe_buffer实现), 它通常最多包含16个页面, 且可以被循环利用,如果最近的写入没有完全填满页面,则后续写入可能会附加到该现有页面而不是分配新页面。;
  • 零拷贝(Zero-copy):如果每一次都把文件数据从内核空间拷贝到用户空间, 将会拖慢系统的运行速度, 也会额外消耗很多内存空间, 所以出现了splice()系统调用, 它的任务是从文件中获取数据并写入管道中, 期间一个特殊的实现方式便是: 目标文件的页面缓存数据不会直接复制到Pipe的环形缓冲区内, 而是以索引的方式(即内存页框地址、偏移量、长度 所表示的一块内存区域)复制到了pipe_buffer的结构体中, 如此就避免了从内核空间向用户空间的数据拷贝过程, 所以被称为"零拷贝";
  • 匿名管道缓冲区工作方式:当一个程序使用管道写入数据时, pipe_write()调用会处理数据写入工作, 默认情况下, 多次写入操作是要写入环形缓冲区的一个新的页面的, 但是如果单次写入操作没有写满一个页面大小, 就会造成内存空间的浪费, 所以pipe_buffer中的每一个页面都包含一个PIPE_BUF_FLAG_CAN_MERGE属性, 该属性可以在下一次pipe_write()操作执行时, 指示内核继续向同一个页面继续写入数据, 而不是获取一个新的页面进行写入,这就是匿名管道缓冲区的工作方式(anon_pipe_buf_ops)。

程序使用splice函数进行拷贝文件时,由于函数copy_page_to_iter_pipe 和 push_pipe缺乏对其flags成员的初始化,未清除页面的PIPE_BUF_FLAG_CAN_MERGE属性,通过将新数据写入以特殊方式准备的管道,就可以覆盖页面缓存中的数据,从而实现任意可读文件覆盖写入。

漏洞利用

利用条件

  1. 攻击者必须具有读取权限(因为它需要拼接一个页面到管道中)
  2. 偏移量不能位于页面边界上(因为该页面的至少一个字节必须已拼接到管道中,即不能为0或4096的倍数)
  3. 写入不能跨越页面边界(因为将为其余部分创建一个新的匿名缓冲区)
  4. 无法调整文件大小(因为管道有自己的页面填充管理,并且不会告诉页面缓存追加了多少数据)

利用步骤

  1. 创建管道。
  2. 用任意数据填充管道(在所有环条目中设置 PIPE_BUF_FLAG_CAN_MERGE 标志)。
  3. 排空管道(在 struct pipe_inode_info环上的所有 struct pipe_buffer 实例中保留设置的标志)。
  4. 将目标文件(使用 O_RDONLY 打开)中的数据从目标偏移之前的位置拼接到管道中。
  5. 将任意数据写入管道;由于设置了 PIPE_BUF_FLAG_CAN_MERGE,此数据将覆盖缓存的文件页面,而不是创建新的异常结构 pipe_buffer。

Exp

经过改良的版本:https://haxx.in/files/dirtypipez.c,该Exp通过将设置UID和GID为0并执行/bin/sh的shellcode注入到SUID程序,生成新的SUID程序/tmp/sh,运行/tmp/sh直接获取root权限shell。

实例

使用上边的Exp,如图:

CVE-2022-0847(Dirty Pipe)_第1张图片

使用漏洞作者提供的Poc,如图:

CVE-2022-0847(Dirty Pipe)_第2张图片

参考

https://sensorstechforum.com/cve-2022-0847-linux-kernel/

https://paper.seebug.org/1843/

你可能感兴趣的:(渗透测试,CVE-2022-0847,Dirty,Pipe,Linux内核提权漏洞)