# GCP - Network Docker Escape

{{#include ../../../banners/hacktricks-training.md}}

## Stato iniziale

In entrambi i writeup in cui questa tecnica è specificata, gli attaccanti sono riusciti a ottenere accesso **root** all'interno di un container **Docker** gestito da GCP con accesso alla rete host (e le capability **`CAP_NET_ADMIN`** e **`CAP_NET_RAW`**).

## Spiegazione dell'attacco

Su un'istanza Google Compute Engine, l'ispezione regolare del traffico di rete rivela numerose **richieste HTTP in chiaro** all'istanza metadata su `169.254.169.254`. Il [**Google Guest Agent**](https://github.com/GoogleCloudPlatform/guest-agent), un servizio open-source, effettua frequentemente tali richieste.

Questo agente è progettato per **monitorare le modifiche nei metadata**. In particolare, i metadata includono un **campo per le chiavi pubbliche SSH**. Quando una nuova chiave SSH pubblica viene aggiunta ai metadata, l'agente la **autorizza automaticamente** nel file `.authorized_key`. Può anche **creare un nuovo utente** e aggiungerlo ai **sudoers** se necessario.

L'agente controlla le modifiche inviando una richiesta per recuperare tutti i valori dei metadata in modo ricorsivo (`GET /computeMetadata/v1/?recursive=true`). Questa richiesta è progettata per indurre il metadata server a rispondere solo se c'è stata una modifica nei metadata rispetto all'ultima lettura, identificata da un Etag (`wait_for_change=true&last_etag=`). Inoltre viene incluso un parametro di **timeout** (`timeout_sec=`). Se non si verifica alcuna modifica entro il timeout specificato, il server risponde con i valori **invariati**.

Questo meccanismo permette all'IMDS (Instance Metadata Service) di rispondere dopo **60 secondi** se non è avvenuta alcuna modifica di configurazione, creando una potenziale **finestra per l'iniezione di una risposta di configurazione falsificata** verso il guest agent.

Un attaccante potrebbe sfruttare ciò eseguendo un attacco Man-in-the-Middle (MitM), spoofando la risposta dal server IMDS e **inserendo una nuova chiave pubblica**. Questo potrebbe consentire l'accesso SSH non autorizzato all'host.

### Tecnica di Escape

Sebbene l'ARP spoofing sia inefficace sulle reti Google Compute Engine, una [**versione modificata di rshijack**](https://github.com/ezequielpereira/rshijack) sviluppata da [**Ezequiel**](https://www.ezequiel.tech/2020/08/dropping-shell-in.html) può essere utilizzata per l'iniezione di pacchetti nella comunicazione al fine di iniettare l'utente SSH.

Questa versione di rshijack permette di fornire i numeri ACK e SEQ come argomenti da linea di comando, facilitando lo spoof di una risposta prima della risposta reale del Metadata server. Inoltre viene utilizzato un [**piccolo Shell script**](https://gist.github.com/ezequielpereira/914c2aae463409e785071213b059f96c#file-fakedata-sh) per restituire un **payload appositamente creato**. Questo payload induce il Google Guest Agent a **creare un utente `wouter`** con una chiave pubblica specificata nel file `.authorized_keys`.

Lo script usa lo stesso ETag per impedire che il Metadata server notifichi immediatamente al Google Guest Agent valori di metadata diversi, ritardando così la risposta.

Per eseguire lo spoofing, sono necessari i seguenti passaggi:

1. **Monitorare le richieste al Metadata server** usando **tcpdump**:

<details>
<summary>Monitorare le richieste al server metadata con tcpdump</summary>
```bash
tcpdump -S -i eth0 'host 169.254.169.254 and port 80' &
```
</details>

Cerca una riga simile a:

<details>
<summary>Esempio di riga di output di tcpdump</summary>
```
<TIME> IP <LOCAL_IP>.<PORT> > 169.254.169.254.80: Flags [P.], seq <NUM>:<TARGET_ACK>, ack <TARGET_SEQ>, win <NUM>, length <NUM>: HTTP: GET /computeMetadata/v1/?timeout_sec=<SECONDS>&last_etag=<ETAG>&alt=json&recursive=True&wait_for_change=True HTTP/1.1
```
</details>

2. Invia i metadati falsi con l'ETAG corretto a rshijack:

<details>
<summary>Invia metadati falsi e connettiti via SSH all'host</summary>
```bash
fakeData.sh <ETAG> | rshijack -q eth0 169.254.169.254:80 <LOCAL_IP>:<PORT> <TARGET_SEQ> <TARGET_ACK>; ssh -i id_rsa -o StrictHostKeyChecking=no wouter@localhost
```
</details>

Questo passaggio autorizza la chiave pubblica, consentendo la connessione SSH con la corrispondente chiave privata.

## Riferimenti

- [https://www.ezequiel.tech/2020/08/dropping-shell-in.html](https://www.ezequiel.tech/2020/08/dropping-shell-in.html)
- [https://www.wiz.io/blog/the-cloud-has-an-isolation-problem-postgresql-vulnerabilities](https://www.wiz.io/blog/the-cloud-has-an-isolation-problem-postgresql-vulnerabilities)

{{#include ../../../banners/hacktricks-training.md}}
