https://grahamhelton.com/blog/nodes-proxy-rce
Пост огромный с кучей технических подробносте, поэтому я тут постараюсь относительно кратко описать чо там и как. Если где-то ошибся, то поправьте в комментах.
Как следует из названия, не смотря на то что у атакующего аккаунта есть права Nodes/Proxy GET (первый прикреплённый скрин), автор получил RCE (второй скрин)
Ключевым моментом в реализации атаки является логика обработки подключений к kubelet.
Когда мы делаем kubectl exec, то подрубаемся к kubelet-у на ноде через API Kubernetes. Что бы обеспечить интерактивность используется WebSocket и тут возникает проблема.
Авторизация осуществляется во время хэндшейка HTTP GET, а вот последующие действия, которые требуют CREATE не проверяются. Проверить это можно через websocat
websocat \
--insecure \
--header "Authorization: Bearer $TOKEN" \
--protocol "v4.channel.k8s.io" \
"wss://$NODE_IP:10250/exec/default/nginx/nginx?output=1&error=1&command=hostname"
nginx
{"metadata":{},"status":"Success"}
До кучи AuditPolicy ещё и не регистрирует команды.
PoC можно посмотреть тут (Иван, привет 🌝)
https://labs.iximiuz.com/tutorials/nodes-proxy-rce-c9e436a9
+ скрипт тоже положу в комменты
Весь "тулинг" и более подробное описание автор обещает выложить позже.
Сводная информация
Vulnerable Permission - nodes/proxy GET
Kubernetes Version Tested - v1.34, v1.35
Required Network Access - Kubelet API (Port 10250)
Impact - Code execution in any Pod on
reachable Nodes
Disclosure Status - Won’t fix (Intended behavior)
Helm charts Affected - 69
Среди 69 чартов
- prometheus-community/prometheus
- grafana/promtail
- datadog/datadog
- elastic/elastic-agent
- cilium/cilium
Как видно из таблицы, стоит "Won’t fix" для этой проблемы. Почему? Потому что "всё работает как надо" сказала автору команда Kubernetes и сослалась на KEP-2862 (https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/2862-fine-grained-kubelet-authz/README.md)
Добрая четверть поста описывает почему KEP-2862 не решает проблему.
Что с этим делать? Минимизировать привилегии (кто бы мог подумать)
Не давать излишние права вида
rules:
- apiGroups: [""]
resources: ["nodes/proxy"]
verbs: ["get"]
Спасибо подписчику за наводку

