Abusing Roles/ClusterRoles in Kubernetes
Last updated
Last updated
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE) GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
ここでは、潜在的に危険なRolesおよびClusterRolesの構成を見つけることができます。
kubectl api-resources
を使用して、すべてのサポートされているリソースを取得できることを忘れないでください。
異なる特権を持つ別のプリンシパルにアクセスする技術を指します(Kubernetesクラスター内または外部クラウドへのアクセス)。Kubernetesには、特権を昇格させるための4つの主な技術があります:
Kubernetesクラスター内または外部クラウドで、より良い特権を持つ他のユーザー/グループ/SAをなりすますことができる
Kubernetesクラスター内または外部クラウドで、より良い特権を持つSAを見つけたり、アタッチしたりすることができるポッドを作成/パッチ/実行できる
SAのトークンがシークレットとして保存されているため、シークレットを読むことができる
コンテナからノードにエスケープできる場合、ノードで実行されているコンテナのすべてのシークレット、ノードの資格情報、およびノードが実行されているクラウド内でのノードの権限を盗むことができる
言及に値する5番目の技術は、ポッド内でポートフォワードを実行する能力です。これにより、そのポッド内の興味深いリソースにアクセスできる可能性があります。
ワイルドカード(*)は、任意の動詞を持つ任意のリソースに対する権限を与えます。これは管理者によって使用されます。ClusterRole内では、攻撃者がクラスター内の任意のnamespaceを悪用できることを意味します。
RBACでは、特定の権限が重大なリスクをもたらします:
create
: 任意のクラスターリソースを作成する能力を付与し、特権昇格のリスクを伴います。
list
: すべてのリソースをリストすることを許可し、機密データが漏洩する可能性があります。
get
: サービスアカウントからシークレットにアクセスすることを許可し、セキュリティの脅威をもたらします。
ポッドを作成する権限を持つ攻撃者は、特権のあるサービスアカウントをポッドにアタッチし、そのトークンを盗んでサービスアカウントを偽装することができます。実質的に権限を昇格させることになります。
bootstrap-signer
サービスアカウントのトークンを盗み、攻撃者に送信するポッドの例:
以下は、コンテナが持つことができるすべての権限を示しています:
特権アクセス(保護を無効にし、能力を設定する)
namespace hostIPCおよびhostPidを無効にする これにより権限を昇格させることができます
hostNetwork namespaceを無効にし、ノードのクラウド権限を盗むためのアクセスとネットワークへのより良いアクセスを提供します
ホストをマウントする / コンテナ内に
ポッドを作成するには:
このツイートからのワンライナーといくつかの追加:
今、ノードにエスケープできるようになったので、以下のページでポストエクスプロイト技術を確認してください:
おそらく、あなたはステルス性を高めたいと思っているでしょう。以下のページでは、前のテンプレートで言及された特権の一部のみを有効にしてポッドを作成した場合にアクセスできるものを確認できます:
特権 + hostPID
特権のみ
hostPath
hostPID
hostNetwork
hostIPC
前の特権ポッド構成を作成/悪用する方法の例は https://github.com/BishopFox/badPods で見つけることができます。
ポッド(およびオプションでサービスアカウント)を作成できる場合、ポッドまたはサービスアカウントにクラウドロールを割り当てることによってクラウド環境で特権を取得できるかもしれません。そして、それにアクセスします。 さらに、ホストネットワーク名前空間を持つポッドを作成できる場合、ノードインスタンスのIAMロールを盗むことができます。
詳細については、以下を確認してください:
これらの権限を悪用して、新しいポッドを作成し、前の例のように特権を確立することが可能です。
以下のyamlは、デーモンセットを作成し、ポッド内のSAのトークンを外部に流出させます:
pods/exec
は、ポッド内のシェルでコマンドを実行するために使用されるkubernetesのリソースです。これにより、コンテナ内でコマンドを実行したり、シェルに入ったりすることができます。
したがって、ポッドに入ってSAのトークンを盗んだり、特権ポッドに入ってノードに脱出し、ノード内のすべてのポッドのトークンを盗んでノードを(悪用)することが可能です。
この権限は、指定されたポッド内の1つのポートに1つのローカルポートを転送することを許可します。これは、ポッド内で実行されているアプリケーションを簡単にデバッグできるようにするためのものですが、攻撃者はこれを悪用して、ポッド内の興味深い(データベースなど)または脆弱なアプリケーション(ウェブ?)にアクセスする可能性があります。
この研究で示されているように、ホストの /var/log/
ディレクトリがマウントされたポッドにアクセスまたは作成できる場合、コンテナからエスケープすることができます。
これは基本的に、Kube-APIがコンテナのログを取得しようとする際(kubectl logs <pod>
を使用)、ポッドの 0.log
ファイルを Kubelet サービスの /logs/
エンドポイントを使用してリクエストするためです。
Kubeletサービスは /logs/
エンドポイントを公開しており、これは基本的に コンテナの /var/log
ファイルシステムを公開しているだけです。
したがって、コンテナの /var/log/ フォルダーに書き込むアクセス権を持つ攻撃者は、この動作を2つの方法で悪用することができます:
コンテナの 0.log
ファイル(通常は /var/logs/pods/namespace_pod_uid/container/0.log
にあります)を /etc/shadow
を指すシンボリックリンクに変更します。そうすれば、次のようにしてホストのシャドウファイルを抽出することができます:
攻撃者が nodes/log
を読む権限を持つ任意のプリンシパルを制御している場合、彼は単に /host-mounted/var/log/sym
に シンボリックリンク を作成し、https://<gateway>:10250/logs/sym/
にアクセスすることでホストのルート ファイルシステムをリスト表示することができます(シンボリックリンクを変更することでファイルへのアクセスが可能になります)。
実験室と自動化されたエクスプロイトは https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts で見つけることができます
運が良ければ、高度な特権を持つ能力 CAP_SYS_ADMIN
が利用可能であれば、フォルダーをrwとして再マウントすることができます:
この研究に記載されているように、保護をバイパスすることが可能です:
ホストパスマウントの代わりに、PersistentVolumeとPersistentVolumeClaimを使用して、書き込み可能なアクセスでコンテナ内のホストフォルダをマウントすることで、前のようなエスケープを防ぐことを目的としていました。
ユーザーのなりすまし権限を持つ攻撃者は、特権アカウントになりすますことができます。
kubectl
コマンドで--as=<username>
パラメータを使用してユーザーになりすますか、--as-group=<group>
を使用してグループになりすますだけです:
またはREST APIを使用します:
シークレットをリストする権限は、攻撃者が実際にシークレットを読み取ることを許可する可能性があります REST APIエンドポイントにアクセスすることで:
読み取り権限を持つトークンを所持している攻撃者は、それを使用するために秘密の正確な名前を必要としますが、より広範な 秘密のリスト表示 権限とは異なり、依然として脆弱性があります。システム内のデフォルトサービスアカウントは列挙可能で、それぞれが秘密に関連付けられています。これらの秘密は、静的なプレフィックスの後にランダムな5文字の英数字トークン(特定の文字を除く)を持つ名前の構造を持っています。ソースコードによると。
トークンは、完全な英数字範囲ではなく、限られた27文字のセット(bcdfghjklmnpqrstvwxz2456789
)から生成されます。この制限により、可能な組み合わせの総数は14,348,907(27^5)に減少します。したがって、攻撃者は数時間でトークンを推測するためのブルートフォース攻撃を実行することが現実的であり、機密サービスアカウントにアクセスすることによって特権の昇格につながる可能性があります。
リソース certificatesigningrequests
に create
の動詞がある場合(または少なくとも certificatesigningrequests/nodeClient
にある場合)、新しいノードの新しいCeSRを作成できます。
ドキュメントによると、この要求を自動承認することが可能ですので、その場合は 追加の権限は必要ありません。そうでない場合は、要求を承認できる必要があり、これは certificatesigningrequests/approval
の更新と、リソース名 <signerNameDomain>/<signerNamePath>
または <signerNameDomain>/*
での signers
の承認を意味します。
必要なすべての権限を持つ ロールの例 は次のとおりです:
新しいノードCSRが承認されたので、ノードの特別な権限を悪用して秘密を盗み、権限を昇格させることができます。
この投稿とこちらでは、GKE K8s TLSブートストラップ構成が自動署名で設定されており、新しいK8sノードの資格情報を生成するために悪用され、その後それを使用して秘密を盗むことで権限を昇格させます。 前述の権限を持っていれば、同じことができます。最初の例は、新しいノードがコンテナ内の秘密にアクセスするのを防ぐエラーを回避します。なぜなら、ノードは自分にマウントされたコンテナの秘密にしかアクセスできないからです。
これを回避する方法は、興味のある秘密がマウントされているコンテナのノード名のノード資格情報を作成することです(ただし、最初の投稿でそれを行う方法を確認してください):
EKS(AWSに必要)クラスターのkube-system名前空間で**configmaps
を変更できる主体は、aws-auth configmapを上書きすることでクラスター管理者権限を取得できます。
必要な動詞はupdate
とpatch
、またはconfigmapが作成されていない場合はcreate
**です:
aws-auth
を使用して、他のアカウントのユーザーにアクセスを提供することで持続性を確保できます。
ただし、aws --profile other_account eks update-kubeconfig --name <cluster-name>
は異なるアカウントからは機能しません。しかし、実際にはaws --profile other_account eks get-token --cluster-name arn:aws:eks:us-east-1:123456789098:cluster/Testing
は、名前の代わりにクラスターのARNを指定すれば機能します。
kubectl
を機能させるには、被害者のkubeconfigを設定し、aws exec argsに--profile other_account_role
を追加するだけで、kubectlは他のアカウントのプロファイルを使用してトークンを取得し、AWSに連絡します。
GCPのプリンシパルにK8sの権限を割り当てる方法は2つあります。いずれの場合も、プリンシパルはクラスターにアクセスするための資格情報を取得するために**container.clusters.get
**の権限が必要です。そうでなければ、自分自身のkubectl設定ファイルを生成する必要があります(次のリンクを参照)。
K8s APIエンドポイントに話しかけると、GCP認証トークンが送信されます。その後、GCPはK8s APIエンドポイントを通じて、最初にプリンシパル(メールアドレスによる)がクラスター内にアクセス権を持っているかどうかを確認し、次にGCP IAMを介してアクセス権を持っているかどうかを確認します。 もしいずれかが****真であれば、応答が返されます。そうでなければ、GCP IAMを介して権限を与えることを提案するエラーが表示されます。
最初の方法はGCP IAMを使用することで、K8sの権限には対応するGCP IAMの権限があります。プリンシパルがそれを持っていれば、使用できるようになります。
2つ目の方法は、クラスター内でK8sの権限を割り当てることで、ユーザーをそのメールアドレスで特定します(GCPサービスアカウントを含む)。
TokenRequests(serviceaccounts/token
)を作成できるプリンシパル。K8s APIエンドポイントに話しかけると、SAs(こちらの情報)。
update
またはpatch
pods/ephemeralcontainers
を行えるプリンシパルは、他のポッドでコード実行を得ることができ、特権のあるsecurityContextを持つ一時的なコンテナを追加することでノードから抜け出す可能性があります。
validatingwebhookconfigurations
またはmutatingwebhookconfigurations
に対してcreate
、update
、またはpatch
のいずれかの動詞を持つプリンシパルは、権限を昇格させるためにそのようなwebhookconfigurationsの1つを作成できる可能性があります。
mutatingwebhookconfigurations
の例については、この投稿のこのセクションを確認してください。
次のセクションで読むことができるように:組み込みの特権昇格防止、プリンシパルは新しい権限を持たずにロールやクラスターのロールを更新または作成することはできません。**roles
またはclusterroles
に対して動詞escalate
**を持っている場合を除いて。
その場合、彼はより良い権限を持つ新しいロールやクラスターのロールを更新/作成できます。
nodes/proxy
サブリソースにアクセスできるプリンシパルは、Kubelet APIを介してポッドでコードを実行できます(こちらに従って)。Kubelet認証に関する詳細はこのページにあります:
Kubelet APIに認可された状態でRCEを取得する方法の例はこちら。
ポッドを削除できるプリンシパル(pods
リソースに対するdelete
動詞)、またはポッドを追い出す(pods/eviction
リソースに対するcreate
動詞)、またはポッドの状態を変更できる(pods/status
へのアクセス)と、他のノードをスケジュール不可にすることができる(nodes/status
へのアクセス)か、ノードを削除できる(nodes
リソースに対するdelete
動詞)かつポッドを制御している場合、他のノードからポッドを盗むことができ、そうすることで侵害された****ノードで実行され、攻撃者はそれらのポッドからトークンを盗むことができます。
services/status
を変更できる主体は、status.loadBalancer.ingress.ip
フィールドを設定して 未修正の CVE-2020-8554 を悪用し、クラスターに対する MiTM 攻撃を開始することができます。CVE-2020-8554 のほとんどの緩和策は、ExternalIP サービスを防ぐだけです(こちら による)。
nodes/status
または pods/status
に対して update
または patch
権限を持つ主体は、スケジューリング制約に影響を与えるためにラベルを変更できます。
Kubernetes には、特権昇格を防ぐための 組み込みメカニズム があります。
このシステムは、ユーザーが役割や役割バインディングを変更することで特権を昇格させることができないことを保証します。このルールの施行は API レベルで行われ、RBAC 認証者が非アクティブな場合でも保護を提供します。
このルールは、ユーザーは役割が含むすべての権限を持っている場合にのみ役割を作成または更新できると定めています。さらに、ユーザーの既存の権限の範囲は、作成または変更しようとしている役割の範囲と一致しなければなりません:ClusterRoles の場合はクラスター全体、Roles の場合は同じネームスペース(またはクラスター全体)に制限されます。
前述のルールには例外があります。主体が roles
または clusterroles
に対して 動詞 escalate
を持っている場合、彼は自分自身が権限を持っていなくても役割やクラスター役割の特権を増加させることができます。
この技術は以前は機能していましたが、私のテストによると、前のセクションで説明した理由でもはや機能していません。すでに権限を持っていない場合、自分自身または別の SA に特権を与えるために rolebinding を作成/変更することはできません。
Rolebindings を作成する特権は、ユーザーが サービスアカウントに役割をバインドすることを可能にします。この特権は、ユーザーが侵害されたサービスアカウントに管理者権限をバインドできるため、特権昇格につながる可能性があります。
デフォルトでは、ポッド間の通信には暗号化がありません。相互認証、双方向、ポッドからポッドへ。
あなたの .yaml を作成してください。
.yamファイルを編集し、コメントアウトされていない行を追加します:
プロキシのログを確認してください:
More info at: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
Admission Controllerは、オブジェクトの永続化の前にKubernetes APIサーバーへのリクエストを傍受しますが、リクエストが認証され、承認された後です。
攻撃者が何らかの方法でMutationg Admission Controllerを注入することに成功すれば、すでに認証されたリクエストを変更することができます。これにより、潜在的に権限昇格を行ったり、より一般的にはクラスター内に持続することが可能になります。
例は https://blog.rewanthtammana.com/creating-malicious-admission-controllers から:
ステータスを確認して、準備ができているかどうかを確認します:
次に、新しいポッドをデプロイします:
ErrImagePull
エラーが表示された場合は、次のいずれかのクエリでイメージ名を確認してください:
上の画像に示されているように、私たちはイメージ nginx
を実行しようとしましたが、最終的に実行されたイメージは rewanthtammana/malicious-image
です。何が起こったのでしょうか?
./deploy.sh
スクリプトは、Kubernetes APIへのリクエストをその設定行に従って変更するミューテイティングウェブホックアドミッションコントローラーを確立します。これにより、観察される結果に影響を与えます:
The above snippet replaces the first container image in every pod with rewanthtammana/malicious-image
.
ポッドとサービスアカウント: デフォルトでは、ポッドはサービスアカウントトークンをマウントします。セキュリティを強化するために、Kubernetesはこの自動マウント機能を無効にすることを許可しています。
適用方法: Kubernetesバージョン1.6以降、サービスアカウントまたはポッドの設定でautomountServiceAccountToken: false
を設定します。
選択的な含有: RoleBindingsまたはClusterRoleBindingsに必要なユーザーのみが含まれるようにします。定期的に監査し、関連性のないユーザーを削除して厳格なセキュリティを維持します。
ロールとClusterRoles: クラスター全体に適用されるClusterRolesおよびClusterRoleBindingsではなく、名前空間特有の権限にはRolesおよびRoleBindingsを使用することを推奨します。このアプローチは、より細かい制御を提供し、権限の範囲を制限します。
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)