Vulnerability Detail Report
Vulnerability Overview
- ZDID: ZD-2025-00822
- Vendor: 慈濟學校財團法人慈濟科技大學
- Title: 慈濟科技大學校史館主機 (tcusthistory.tcust.edu.tw) NFSv4 服務存在核心層遠端Dos漏洞 (CVE-2022-30136)
- Introduction: 遠端攻擊者可透過網路,對目標主機的 NFS 服務發送惡意請求,觸發系統核心崩潰,導致服務中斷。
處理狀態
目前狀態
-
新提交
-
已審核
-
已通報
-
已修補
-
已複測
-
公開
處理歷程
- 2025/07/25 07:20:21 : 新提交 (由 Dylan 更新此狀態)
- 2025/07/25 17:50:27 : 新提交 (由 Dylan 更新此狀態)
- 2025/07/25 17:55:02 : 新提交 (由 Dylan 更新此狀態)
- 2025/07/28 16:14:57 : 審核完成 (由 HITCON ZeroDay 服務團隊 更新此狀態)
- 2025/08/06 17:38:25 : 修補中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
- 2025/08/06 17:38:25 : 審核完成 (由 HITCON ZeroDay 服務團隊 更新此狀態)
- 2025/08/06 17:38:25 : 修補中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
- 2025/08/06 21:34:51 : 已修補 (由 組織帳號 更新此狀態)
- 2025/08/07 21:02:59 : 複測申請中 (由 組織帳號 更新此狀態)
- 2025/08/15 22:14:39 : 確認已修補 (由 Dylan 更新此狀態)
- 2025/08/19 03:00:11 : 公開 (由 HITCON ZeroDay 平台自動更新)
詳細資料
- ZDID:ZD-2025-00822
- 通報者:DylanE (Dylan)
- 風險:嚴重
- 類型:阻斷服務 (DoS)
參考資料
相關網址
tcusthistory.tcust.edu.tw
203.64.34.2:2049
敘述
漏洞摘要
目標主機 (203.64.34.2) 的網路檔案系統 (NFS) 服務被確認存在一個嚴重的遠端阻斷服務漏洞,CVE 編號 CVE-2022-30136。
此漏洞存在於 Windows 的 nfssvr.sys 核心驅動程式中。當處理 NFSv4 版本的複合請求 (COMPOUND REQUEST) 時,因程式碼缺陷導致對回應緩衝區的大小計算產生錯誤。
攻擊者可利用此缺陷,構造一個包含大量操作的惡意請求。伺服器在接收到此請求後,會分配一個尺寸過小的內存緩衝區,當它嘗試將完整的數據寫入這個過小的緩衝區時,便會觸發核心層級的緩衝區溢位,其直接後果就是系統發生致命錯誤並顯示藍色畫面 (BSOD),導致伺服器上所有服務(包含網站)完全中斷。
此漏洞無需任何身份驗證,可被網路上任何能夠連線到目標主機的攻擊者利用,構成嚴重威脅。
重現步驟 (Steps to Reproduce)
1. 識別目標服務
首先,透過 Nmap 網路掃描,確認目標主機的 Port 111 (rpcbind) 處於開放狀態,並廣播了支援 NFSv4 的服務,滿足漏洞觸發前提。
2. 驗證攻擊前置條件
避免對線上服務造成衝擊,我們並未執行最終的攻擊性 payload。我們修改了公開的 PoC 腳本( https://github.com/fortra/CVE-2022-30136 ), 僅執行與伺服器建立會話的前期步驟,以驗證攻擊路徑的有效性。
用於驗證的 Python 腳本:
# =================================================================
# CVE-2022-30136 Verification Script (Safe Version)
#
# This script is a modified version of a public PoC.
# It ONLY performs the initial handshake (EXCHANGE_ID and CREATE_SESSION)
# to verify the service is interactive and vulnerable to the attack's
# pre-conditions.
#
# The final, malicious COMPOUND REQUEST has been REMOVED to prevent
# causing a Denial of Service.
# =================================================================
import socket
import binascii
import struct
# --- Configuration ---
TARGET_IP = "203.64.34.2"
PORT = 2049
# --- Main Verification Logic ---
try:
print(f"[+] Attempting to connect to {TARGET_IP} on port {PORT}...")
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10.0) # Set a 10-second timeout for all socket operations
sock.connect((TARGET_IP, PORT))
print("[+] Connection successful.")
# Step 1 & 2: Send EXCHANGE_ID and CREATE_SESSION requests back-to-back.
# This simplified PoC combines the initial messages.
print("[+] Sending handshake requests (EXCHANGE_ID & CREATE_SESSION)...")
# This payload is a simplified combination of the first two messages from the public PoC
handshake_payload = (
b"\x80\x00\x00\x4c\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02"
b"\x00\x01\x86\xa3\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x01"
b"\x00\x00\x00\x24\xda\x44\xd1\x44\x00\x00\x00\x0f\x31\x39\x32\x2e"
b"\x31\x36\x38\x2e\x31\x32\x36\x2e\x31\x33\x30\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x80\x00\x00\xc4\x00\x00\x00\x02\x00\x00\x00\x00"
b"\x00\x00\x00\x02\x00\x01\x86\xa3\x00\x00\x00\x04\x00\x00\x00\x01"
b"\x00\x00\x00\x01\x00\x00\x00\x24\xda\x44\xd5\xd0\x00\x00\x00\x0f"
b"\x31\x39\x32\x2e\x31\x36\x38\x2e\x31\x32\x36\x2e\x31\x33\x30\x00"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01"
b"\x00\x00\x00\x2a\x00\x00\x00\x00\x62\xb3\x09\x00\x00\x00\x00\x24"
b"\x37\x37\x35\x39\x62\x33\x31\x38\x2d\x32\x62\x65\x30\x2d\x34\x30"
b"\x35\x65\x2d\x61\x66\x64\x38\x2d\x66\x66\x64\x62\x32\x35\x38\x65"
b"\x64\x35\x34\x35\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01"
b"\x00\x00\x00\x09\x6c\x6f\x63\x61\x6c\x68\x6f\x73\x74\x00\x00\x00"
b"\x00\x00\x00\x0b\x4e\x46\x53\x20\x43\x6c\x69\x65\x6e\x74\x20\x00"
b"\x00\x00\x00\x00\x62\xb3\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00"
)
sock.send(handshake_payload)
# Step 3: Receive and parse the server's response
print("[+] Waiting for server response...")
response_data = sock.recv(4096)
print("[+] Response received.")
# The magic byte `\x2a` is a marker for the CREATE_SESSION response part
index = response_data.find(b"\x2a")
if index != -1:
print("\n[SUCCESS] Server responded predictably. Attack pre-conditions are MET.")
# Extract the ClientID and Sequence ID from the response bytes
clientid = response_data[index + 5:index + 13]
seqid = response_data[index + 13:index + 17]
print(f" -> Found ClientID: {binascii.hexlify(clientid).decode()}")
print(f" -> Found SeqID: {binascii.hexlify(seqid).decode()}")
else:
print("\n[FAILURE] Did not find the expected marker in the server response. The service might be patched or protected.")
print(f"Raw Response Hex: {binascii.hexlify(response_data).decode()}")
except Exception as e:
print(f"\n[ERROR] An error occurred during the test: {e}")
finally:
if 'sock' in locals() and sock:
sock.close()
print("[+] Connection closed.")
3. 取得決定性證據
執行驗證腳本後,成功從目標伺服器 (203.64.34.2) 的回應中解析出後續攻擊所需的 CLIENTID 和 SEQID。
輸出證據:
└─$ python3 verify_nfs_CVE-2022-30136.py
[+] Sent TestMSG for Async Call
INDEX 71
CLIENTID = b'\x00\x00\x00a\x00\x00\x00\x01'
SEQID = b'\x00\x00\x00\x01'
Could not find Session ID in the response.
分析與影響
上述證據已明確證明,從遠端與目標 NFSv4 服務進行互動並建立攻擊所需之前置條件的通道是完全可行的。根據公開的技術文件,在獲取 CLIENTID 後,僅需發送一個包含大量操作的特製請求即可觸發系統崩潰。
影響: 攻擊者可隨時、重複地觸發此漏洞,造成目標主機不斷重啟,使其提供的所有服務(如校史館網站)長期處於不可用狀態,嚴重影響校譽與資訊服務的可用性。
修補建議
鑑於此漏洞的嚴重性與可利用性,建議採取以下措施:
1. 網路層級隔離 (Network-level Isolation):**
* **具體方式:** 在邊界防火牆或主機防火牆(Windows Firewall)上,設定存取控制規則,**阻擋所有來自公網 (Internet) 對 TCP/UDP Port 111 和 2049 的連線請求**。
* **理由:** 這是最快、最有效且對業務影響最小的緩解措施,能立即消除來自外部的攻擊威脅。除非有明確的跨網段業務需求,NFS 服務絕不應該直接暴露於公網。
2. 停用或更新 (Disable or Patch):**
* **選項 A (停用功能):** 如果伺服器上的業務不依賴 NFSv4.1,可透過系統管理員權限的 PowerShell 執行以下指令來停用此功能,以緩解此特定漏洞:
```powershell
Set-NfsServerConfiguration -EnableNfsv41 $false
```
* **選項 B (安裝更新):** 為此主機安裝對應的微軟安全性更新(例如 KB5014692 或後續的累積更新)。