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

# Bugku CTF - game1 writeup (zh-TW)
- URL: https://taiwanding.com/bugku-ctf-game1-writeup-zh-tw/
- Published: 2025-10-22T09:06:47.000Z
- Updated: 2025-11-03T09:09:33.000Z
- Author: Kevin Chen
- Tags: Bugku, CTF, #Obfuscator

## 題目資訊

- **分類**: Web
- **題目名稱**: game1
- **題目連結**: [https://ctf.bugku.com/challenges/detail/id/236.html](https://ctf.bugku.com/challenges/detail/id/236.html?ref=taiwanding.com)
- 解決人次: 11102

## 解題過程

### Step 1: 初步分析網頁結構

訪問題目網址，看到一個疊疊樂遊戲，查看原始碼發現幾個關鍵文件：

```html
<script src="./dist/main.js"></script>
<script src="./assets/zepto-1.1.6.min.js"></script>
<script src="./base.js"></script>

```

重點關注遊戲結束時的邏輯：

```javascript
function overShowOver() {
    var ppp='111.x.x.x';
    var sign = Base64.encode(score.toString());
    xmlhttp.open("GET","score.php?score="+score+"&ip="+ppp+"&sign="+sign,true);
    xmlhttp.send();
}

```

🔍 **發現重點**：

- 遊戲結束時會發送分數到 `score.php`
- 使用了自定義的 `Base64` 編碼
- 硬編碼 IP 位址：`111.x.x.x (這是作者的ip地址)`

### Step 2: 分析 base.js 混淆代碼

`base.js` 文件被嚴重混淆：

```javascript
eval(function(p, a, c, k, e, d) {
    e = function(c) {
        return (c < a ? "" : e(parseInt(c / a))) + ...
    };
    ...
}('5 z={b:"R+/=",L:y(e){5 t="";...', 60, 60, '|||||var||String|...'));

```

這是標準的 JavaScript Packer 混淆。

### Step 3: 解混淆 base.js

使用 Node.js 直接執行混淆代碼：

```bash
node << 'EOF'
var result = (function(p, a, c, k, e, d) {
    // ... 混淆代碼 ...
})('5 z={b:"R+/=",L:y(e){...}', 60, 60, '...'.split('|'), 0, {});
console.log(result);
EOF

```

解混淆後發現關鍵部分：

```javascript
var Base64 = {
    _0: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
    
    encode: function(e) {
        // ... Base64 編碼邏輯 ...
        return "zM" + t + "==";  // ⚠️ 關鍵！
    },
    
    // ... 其他函數 ...
}

```

🎯 **重大發現**：這不是標準的 Base64！

- 格式：`"zM" + Base64(score) + "=="`
- 前綴固定為 `zM`
- 後綴固定為 `==`

### Step 4: 驗證簽名算法

測試簽名生成：

```python
import base64

def custom_base64_encode(score_str):
    encoded = base64.b64encode(score_str.encode()).decode()
    return f"zM{encoded}=="

# 測試
print(custom_base64_encode("100"))    # zMMTAw==
print(custom_base64_encode("999999")) # zMOTk5OTk5==

```

### Step 5: 測試高分數

既然是遊戲，嘗試**超高分數**看看會不會有特殊邏輯：

```python
import base64
import requests

score = 999999
sign = f"zM{base64.b64encode(str(score).encode()).decode()}=="

url = f"http://117.72.52.127:13084/score.php"
params = {
    'score': score,
    'ip': '111.x.x.x',
    'sign': sign
}

response = requests.get(url, params=params)
print(response.text)

```

🎉 **成功回應**：

```
flag{Redacted}

```

### 完整 Payload

```bash
http://117.72.52.127:13084/score.php?score=999999&ip=111.x.x.x&sign=zMOTk5OTk5%3D%3D

```

## 學習重點

### 1\. JavaScript 混淆識別與解混淆

**識別 Packer 混淆特徵**：

```javascript
eval(function(p,a,c,k,e,d){...}('混淆字符串',數字,數字,'字典'.split('|'),0,{}))

```

**解混淆方法**：

- 使用線上工具：[https://matthewfl.com/unPacker.html](https://matthewfl.com/unPacker.html?ref=taiwanding.com)

### 2\. 自定義編碼識別

標準 Base64 vs 題目的 Base64：

```
標準: MTAwMA==
題目: zMMTAwMA==
      ^^     ^^
      前綴   後綴固定

```

**關鍵點**：

- 仔細分析編碼函數的 `return` 語句
- 注意任何硬編碼的前綴/後綴

### 3\. 弱簽名驗證漏洞

題目的簽名算法問題：

```
❌ 只用 Base64 編碼，沒有密鑰
❌ 完全可預測，可偽造任意分數

```

### 4\. CTF 中的邏輯猜測

這題的成功有運氣成分，**可能的伺服器邏輯**：

```php
// 推測的 score.php 邏輯
if ($score >= 999999) {
    echo "flag{...}";  // 高分直接返回 flag
} else {
    if ($ip != "111.x.x.x") {
        die("Host not allowed");
    }
    // 正常邏輯...
}

```

**學習啟示**：

- ✅ 成功拿到 flag
- ⚠️ 但不完全確定為什麼成功
- 💡 理想情況應該測試邊界值（999998, 1000000 等）來驗證假設

##