【漏洞复现】Docker runC 容器逃逸漏洞(CVE-2019-5736)

2024-02-09 18:40

本文主要是介绍【漏洞复现】Docker runC 容器逃逸漏洞(CVE-2019-5736),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 声明
  • 一、漏洞描述
  • 二、漏洞原理
  • 三、漏洞分析
  • 四、POC分析
  • 五、利用方式
  • 六、影响版本
  • 七、环境搭建
  • 八、漏洞复现
  • 九、修复建议


声明

本篇文章仅用于技术研究和漏洞复现,切勿将文中涉及攻击手法用于非授权下渗透攻击行为,操作有风险,出现任何后果与本作者无关,谨慎操作!!!

重点看Tips提示

一、漏洞描述

2019年2月11日,runC的维护团队报告了一个新发现的漏洞,SUSE Linux GmbH高级软件工程师Aleksa Sarai公布了影响Docker, containerd, Podman, CRI-O等默认运行时容器runc的严重漏洞CVE-2019-5736。漏洞会对IT运行环境带来威胁,漏洞利用会触发容器逃逸、影响整个容器主机的安全,最终导致运行在该主机上的其他容器被入侵。漏洞影响AWS, Google Cloud等主流云平台。日前,该容器逃逸漏洞的PoC利用代码已在GitHub上公布。这是CVE-2019-5736漏洞利用的Go语言实现。漏洞利用是通过覆写和执行主机系统runc二进制文件完成的。


二、漏洞原理

漏洞点在于runC,runC是一个容器运行时,最初是作为Docker的一部分开发的,后来作为一个单独的开源工具和库被提取出来。作为 “低级别” 容器运行时,runC主要由 “高级别” 容器运行时(例如Docker)用于生成和运行容器,尽管它可以用作独立工具。像Docker这样的 “高级别” 容器运行时通常会实现镜像创建和管理等功能,并且可以使用runC来处理与运行容器相关的任务:创建容器、将进程附加到现有容器等。在Docker18.09.2之前的版本中使用的runC版本小于1.0-rc6,因此允许攻击者重写宿主机上的runC二进制文件,攻击者可以在宿主机上以root身份执行任意命令。


三、漏洞分析

  • runC
    runC是docker中最为核心的部分,容器的创建、运行、销毁等操作都是通过runC程序来完成的。我们来看一下runC文件,如下所示:
    在这里插入图片描述
    当我们运行docker run等命令的时候实际上在底层调用的是runC程序,所以整个流程大概如下:
    在这里插入图片描述
    其中虚线位置表示,当runC生成一个子进程后runC程序将会结束占用。
    当触发POC后,runC程序会被重写并执行:
    在这里插入图片描述

  • /proc/

    根据官方文档,/proc/文件夹类似于一个文件系统,其中存放着各个进程与本地文件之间的映射,其中:

    /proc/[PID]/exe: 一种特殊的软连接,是该进程自身对应的本地文件

    /proc/[PID]/fd/: 这个目录下存放了该进程打开的所有文件描述符

    /proc/self/: 不同的进程访问该目录时获得的信息是不同的,内容等价于/proc/本进程pid/

    /proc/[PID]/exe的特殊之处在于当权限通过的情况下打开这个文件,内核将会之间返回一个指向该文件的文件描述符,并非按照传统的打开方式做路径分析和文件查找,这就会导致绕过了mnt命名空间和chroot的限制。

    当执行docker exec命令的时候,runc启动并加入到容器的命名空间中去,其实这个时候,容器内的进程已经能够通过内部的/proc/观察到它,因此通过打开/proc/[runc-PID]/exe可以获取宿主机上的runc文件标识符,由此能够达到覆盖的能力。

四、POC分析

POC地址:https://github.com/Frichetten/CVE-2019-5736-PoC

  • #!

    在unix中,凡是被#!注释的,统统是加载器的路径,常见的有#!/bin/sh,表示将该注释后的代码交给/bin/sh处理,我们常见的处理python脚本一般在bash中输入python run.py,而如果在run.py中将注释换成#!/path/to/python,则在bash中执行run.py即可。

    在此poc中,作者将/bin/sh进行了覆盖,修改成了#!/proc/self/exe,意义在于当宿主机执行docker exec -it ID /bin/sh时,/bin/sh将会替换成执行调用者自己,也就是宿主机下的runc文件,此时将会执行runc文件。

  • 两个for循环

    在第一个for循环中,攻击者持续监测/proc/目录,当产生runc进程时,以可读的方式打开runc文件夹获取文件标识符。

    在第二个for循环中,攻击者持续监听等待runc程序结束占用后就能够用之前循环获得的文件标识符以可写的方式向runc文件内写入payload。

攻击链流程图
在这里插入图片描述

五、利用方式

宿主机利用攻击者提供的image来创建一个新的container,拥有container root权限,并且该container后续被docker exec attach。一句话描述,docker 18.09.2之前的runC存在漏洞,攻击者可以修改runC的二进制文件导致提权。

六、影响版本

  • Docker Version <=18.09.2
  • runC Version <=1.0-rc6

七、环境搭建

下载地址:前往下载
在这里插入图片描述
添加更新源到 /etc/apt/source.list文件中
Sudo apt-get update ##更新apt软件包索引
在这里插入图片描述
Sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common ##安装软件包,以允许apt通过HTTPS使用镜像仓库。
在这里插入图片描述
Curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add – ##添加Docker的官方GPG密钥
在这里插入图片描述
Sudo apt-key fingerprint 0EBFCD88 ## 验证密钥指纹是否为 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
在这里插入图片描述
Sudo add-apt-repository “deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable” ##设置稳定存储库,直接写入到/etc/apt/source.list文件中。

Sudo apt-get update ##再次更新apt软件包索引,可以看出新增docker镜像仓库。
在这里插入图片描述
到这里环境均已准备完毕!!!

八、漏洞复现

Tips:建议提前拍好快照,漏洞复现完成之后可能会造成docker无法使用

卸载已经安装的docker
sudo apt-get remove docker docker-engine docker-ce docker.io
列出docker可用版本
apt-cache madison docker-ce
在这里插入图片描述
以下列表中选择低于18.09.2版本进行安装
Sudo apt-get install docker-ce=18.06.1-ce-3-0-ubuntu
在这里插入图片描述
启动docker并查看docker和runc版本(均在漏洞影响范围内)
在这里插入图片描述
下载CVE-2019-5736漏洞POC
git clone https://github.com/Frichetten/CVE-2019-5736-PoC.git
在这里插入图片描述
修改payload内容
在这里插入图片描述
此时编译payload需要go环境,直接安装即可,生成可执行脚本main
在这里插入图片描述
编译完成后,我们运行一个漏洞环境(以CVE-2020-1957漏洞为例)

这里需要注意一下,安装完docker-ce之后,docker-compose是默认没有的,直接使用apt-get install docker-compose 或 pip install docker-compose命令可能会出现错误(尝试安装),解决方法就是下载一个docker-compose来进行安装,命令如下:

curl -L https://get.daocloud.io/docker/compose/releases/download/v2.6.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose //下载docker-compose 版本为2.6.1 并添加到 /usr/local/bin目录下
sudo chmod +x /usr/local/bin/docker-compose //赋予docker-compose执行权限
docker-compose -v //查看版本

##以上命令需要root权限执行!!!

启动环境
在这里插入图片描述
执行以下命令将生成的main脚本cp到docker容器中(这就是模拟攻击者获取了docker容器权限,在容器中上传payload进行docker逃逸)

docker cp /home/szg/CVE-2019-5736-PoC/main 3d5341ae0bf5:/home

执行如下命令,进入容器,查看脚本是否拷进容器并启动main脚本

docker exec -it 3d5341ae0bf5 /bin/sh (第一次需使用/bin/sh启动)

在这里插入图片描述
KALI启动监听
在这里插入图片描述
ubuntu启动一个新终端,执行如下命令再次进入容器,触发payload,成功反弹shell,此时权限为服务器权限,docker逃逸成功。
在这里插入图片描述
在这里插入图片描述

九、修复建议

更新容器至 18.09.2版本以上。

这篇关于【漏洞复现】Docker runC 容器逃逸漏洞(CVE-2019-5736)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/695006

相关文章

如何高效移除C++关联容器中的元素

《如何高效移除C++关联容器中的元素》关联容器和顺序容器有着很大不同,关联容器中的元素是按照关键字来保存和访问的,而顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的,本文介绍了如何高效移除C+... 目录一、简介二、移除给定位置的元素三、移除与特定键值等价的元素四、移除满足特android定条件的元

Docker镜像修改hosts及dockerfile修改hosts文件的实现方式

《Docker镜像修改hosts及dockerfile修改hosts文件的实现方式》:本文主要介绍Docker镜像修改hosts及dockerfile修改hosts文件的实现方式,具有很好的参考价... 目录docker镜像修改hosts及dockerfile修改hosts文件准备 dockerfile 文

Docker镜像pull失败两种解决办法小结

《Docker镜像pull失败两种解决办法小结》有时候我们在拉取Docker镜像的过程中会遇到一些问题,:本文主要介绍Docker镜像pull失败两种解决办法的相关资料,文中通过代码介绍的非常详细... 目录docker 镜像 pull 失败解决办法1DrQwWCocker 镜像 pull 失败解决方法2总

如何将Tomcat容器替换为Jetty容器

《如何将Tomcat容器替换为Jetty容器》:本文主要介绍如何将Tomcat容器替换为Jetty容器问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Tomcat容器替换为Jetty容器修改Maven依赖配置文件调整(可选)重新构建和运行总结Tomcat容器替

通过Docker Compose部署MySQL的详细教程

《通过DockerCompose部署MySQL的详细教程》DockerCompose作为Docker官方的容器编排工具,为MySQL数据库部署带来了显著优势,下面小编就来为大家详细介绍一... 目录一、docker Compose 部署 mysql 的优势二、环境准备与基础配置2.1 项目目录结构2.2 基

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

C++常见容器获取头元素的方法大全

《C++常见容器获取头元素的方法大全》在C++编程中,容器是存储和管理数据集合的重要工具,不同的容器提供了不同的接口来访问和操作其中的元素,获取容器的头元素(即第一个元素)是常见的操作之一,本文将详细... 目录一、std::vector二、std::list三、std::deque四、std::forwa

关于Docker Desktop的WSL报错问题解决办法

《关于DockerDesktop的WSL报错问题解决办法》:本文主要介绍关于DockerDesktop的WSL报错问题解决办法的相关资料,排查发现是因清理%temp%文件夹误删关键WSL文件,... 目录发现问题排查过程:解决方法其实很简单:重装之后再看就能够查到了:最后分享几个排查这类问题的小www.cp

Python容器类型之列表/字典/元组/集合方式

《Python容器类型之列表/字典/元组/集合方式》:本文主要介绍Python容器类型之列表/字典/元组/集合方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 列表(List) - 有序可变序列1.1 基本特性1.2 核心操作1.3 应用场景2. 字典(D

如何使用Docker部署FTP和Nginx并通过HTTP访问FTP里的文件

《如何使用Docker部署FTP和Nginx并通过HTTP访问FTP里的文件》本文介绍了如何使用Docker部署FTP服务器和Nginx,并通过HTTP访问FTP中的文件,通过将FTP数据目录挂载到N... 目录docker部署FTP和Nginx并通过HTTP访问FTP里的文件1. 部署 FTP 服务器 (