Checkpoint
- Target
- DC01.checkpoint.htb
- Host OS
- Windows Server 2025 (build 26100) — Domain Controller
- Start
- Assumed breach — one supplied low-privileged credential
- Foothold
- Tombstone reanimation → malicious VSIX on the DevDrop share
- Privesc
- dMSA BadSuccessor variant → Volatility hashdump → Pass-the-Hash
Reanimate-Tombstones → restore a deleted developer account → write access to
the DevDrop extension share → malicious VSIX → shell as ryan.brooks →
GenericWrite over svc_deploy → dMSA successor-link abuse leaks
svc_deploy's key → VMBackups share → .vmem snapshot → Volatility hashdump →
local Administrator hash reused by the domain Administrator → Pass-the-Hash → SYSTEM.
01Reanimating a tombstone
The starting account holds Reanimate-Tombstones on the domain, plus writable control over a deleted user object. That combination is the whole foothold: when an AD object is deleted it becomes a tombstone, and a tombstone keeps its old password hash. Restore the deleted developer account and it comes back with credentials that still work — in this case the same password the starting account was given.
Deleted-object recovery is a legitimate administrative capability, which is exactly why it is dangerous when it sits on a standard user: it is an identity-resurrection primitive, not a housekeeping convenience.
02Foothold — a VSIX supply chain
The restored account has read and write access to a share called DevDrop, which the developer workstation profile auto-installs VS Code 1.118.0 extensions from. Write access to a directory that something else automatically executes is a supply-chain path, not a file share.
A VSIX is a zip with a manifest. Setting activationEvents to * makes the extension
run as soon as the editor loads it, so the payload does not need any user interaction beyond the auto-install
that already happens:
# build a VSIX whose manifest activates on '*' and launches a PowerShell reverse shell
# then drop it where the profile auto-installs from
smbclient //DC01.checkpoint.htb/DevDrop -U 'checkpoint.htb\<restored-user>'
smb: \> put malicious.vsix
The callback lands as the developer, ryan.brooks.
03dMSA abuse — BadSuccessor on a patched DC
The developer holds GenericWrite over a service account, svc_deploy, and
svc_deploy is the sole member of BackupAccess. The intended route is the
dMSA migration primitive — the BadSuccessor class of issue
(CVE-2025-53779), where a delegated Managed Service Account can be pointed at a "superseded"
account and inherit its keys.
The direct version fails here: the DC is patched, so a dMSA aimed straight at Administrator returns
KRB_ERR_GENERIC — the fix requires a mutual successor link rather than a one-way claim.
The pivot is to satisfy that requirement using the two identities already held:
- As the low-privileged user, create a dMSA whose successor link points forward at
svc_deploy. - As the developer (who has
GenericWriteoversvc_deploy), write the reversemsDS-SupersededManagedAccountLink/ state attributes back at the dMSA. - With both directions present, the link is "mutual" and the KDC accepts it.
- Request a dMSA S4U2self ticket — the
KERB-DMSA-KEY-PACKAGEin the response carriessvc_deploy's previous key, i.e. its NT hash.
The lesson is a good one: "patched" closed the obvious path, but the primitive was still reachable by composing two permissions that each looked harmless on their own.
04Looting a memory image
As svc_deploy, the BackupAccess membership opens the VMBackups
share. Under NightlyBackup/.../memory forensics/ sits a 2 GB VMware .vmem snapshot —
a full memory image of a running machine, sitting on a file share.
Volatility 3 does the rest:
vol -f NightlyBackup.vmem windows.hashdump
That returns the local Administrator NT hash.
05Root — password reuse and Pass-the-Hash
The local Administrator hash is reused by the checkpoint.htb domain
Administrator. That is the last link: no exploit, just the same password in two places.
nxc smb DC01.checkpoint.htb -u Administrator -H <nt-hash> -x 'whoami'
# or: impacket-psexec -hashes :<nt-hash> checkpoint.htb/Administrator@DC01
root.txt sat under max.palmer's profile rather than Administrator's, so it needed
reading in the Administrator execution context (nxc -x or wmiexec) rather than a
plain SMB fetch.
06Operational gotchas
- HTB VPN path-MTU black hole. Large SMB transfers and dMSA Kerberos exchanges hang until
you clamp the tunnel:
sudo ip link set dev tun0 mtu 1300. - Kerberos clock skew. Use
faketimeper process, seeded from the DC's SMB2 time — do not change Kali's global clock, which breaks APT signature validity. - RC4 disabled. Request the TGT with a password so AES256 is negotiated; an NT-hash-only
TGT request returns
KDC_ERR_ETYPE_NOSUPP. - pypykatz had no rekall backend for the memory image — Volatility 3 in its own venv
(
bin/vol) was the working tool.
Tooling used throughout: nmap, NetExec (nxc), bloodyAD, ldapsearch with GSSAPI, smbclient,
Impacket (getTGT / getST / psexec), Volatility 3, netcat.
07If this were your environment
This is a Tier 0 incident: a single low-privileged credential reached SYSTEM on a Domain Controller. The immediate response is to rotate every credential involved including the built-in Administrator, and to remove the rogue dMSAs and successor links before anything else.
Reanimate-Tombstones and CREATE_CHILD granted to standard users
Deleted-object recovery on a standard account is an identity-resurrection primitive: tombstones retain their password hashes, so restoring one hands back a working identity.
- Strip
Reanimate-TombstonesandCREATE_CHILDfrom standard users. Deleted-object recovery belongs to a Tier 0 role with an approval trail. - Lock
msDS-Superseded*writes to Tier 0 so the dMSA successor primitive cannot be composed from ordinary delegations. - Review AD object DACLs continuously (BloodHound or equivalent) rather than at project milestones.
DISA STIG: Windows Server 2025 / Active Directory STIG — delegation and object permission requirements
Writable auto-installing extension share (VSIX supply chain)
Any account able to write to DevDrop could execute code in every developer's editor session. The share was an unsigned, unreviewed software distribution channel.
- Make the share read-only to consumers and publish through a pipeline that requires signing, scanning and approval.
- Enforce a VS Code extension allow-list by publisher and extension id, and disable auto-install from arbitrary paths.
- Treat any directory something auto-executes as a production deployment target, with the change control that implies.
CIS Controls v8: 2.x software inventory & allow-listing · 16.x application software security
Unpatched dMSA successor primitive, and memory images on a file share
The DC was missing the fix that closes the mutual-link variant, and a VMware .vmem snapshot —
containing live credential material — was readable by a service account's backup group.
- Patch the DC to KB5063878 / build 26100.4946 or later.
- Treat
.vmem/.vmssas credential material. Encrypt them at rest, restrict them to a Tier 0 backup role, and never leave them on a general-purpose share. - Audit what backup groups can actually read — "BackupAccess" quietly meant "read everyone's memory".
DISA STIG: Windows Server 2025 baseline
Local Administrator password reused by the domain Administrator
A hash recovered from one host's memory authenticated as the domain Administrator. Every preceding step only mattered because this last one was free.
- Deploy Windows LAPS so every local Administrator password is unique and rotated.
- Give every service account unique credentials; kill reuse between local, service and domain identities.
- Rotate the built-in Administrator (twice, to clear the krbtgt-style history concern) as part of Tier 0 recovery.
08Detection — the blue-team side
- dMSA and
msDS-Superseded*attribute changes — rare, and high signal. - Tombstone restores (deleted-object reanimation events) outside a change window.
- Writes of
.vsixfiles to any distribution share. - Downloads from VMBackups, especially multi-GB memory images.
- S4U ticket requests and Pass-the-Hash patterns (NTLM logons from unusual sources for privileged accounts).
09Takeaways
- "Patched" is not "not exploitable". The DC's fix blocked the one-way dMSA claim; composing two ordinary write permissions rebuilt the primitive.
- Deleted does not mean gone. Tombstones keep hashes — deleted-object recovery is a credential capability.
- Anything auto-installed is a deployment pipeline, and needs signing and approval like one.
- Memory images are credentials in a file. A backup group that can read them is a Tier 0 group.
- Password reuse turned four clever steps into a domain takeover. LAPS would have ended the chain.
◆If this were my environment
This path combined identity lifecycle mistakes, extension trust and delegated-account abuse. I would harden the entire administrative supply chain, from package provenance to Tier 0 account creation and monitoring.
- Remove stale and tombstoned privileged objects, review delegated rights continuously, and alert on dMSA creation or predecessor-link changes.
- Allow only signed, approved VSIX packages from controlled repositories and block extension installation on privileged workstations.
- Protect LSASS with Credential Guard and PPL, prevent privileged logons to lower-tier hosts, and use LAPS or gMSAs instead of reusable secrets.
- Apply certificate, directory and endpoint baselines through versioned policy; validate the resulting effective settings on every role.
Hardening guides and benchmarks
These references offer different implementation paths: consensus benchmarks, prescriptive government checklists, vendor baselines and application-security verification requirements. I would select the profile that matches the system's role, document exceptions, test it in staging and continuously measure drift.