Shadow Credentials

Theory

The Kerberos authentication protocol works with tickets in order to grant access. An ST (Service Ticket) can be obtained by presenting a TGT (Ticket Granting Ticket). That prior TGT can only be obtained by validating a first step named "pre-authentication" (except if that requirement is explicitly removed for some accounts, making them vulnerable to ASREProast). The pre-authentication can be validated symmetrically (with a DES, RC4, AES128 or AES256 key) or asymmetrically (with certificates). The asymmetrical way of pre-authenticating is called PKINIT.
The client has a public-private key pair, and encrypts the pre-authentication data with their private key, and the KDC decrypts it with the client’s public key. The KDC also has a public-private key pair, allowing for the exchange of a session key. (specterops.io)
Active Directory user and computer objects have an attribute called msDS-KeyCredentialLink where raw public keys can be set. When trying to pre-authenticate with PKINIT, the KDC will check that the authenticating user has knowledge of the matching private key, and a TGT will be sent if there is a match.
There are multiple scenarios where an attacker can have control over an account that has the ability to edit the msDS-KeyCredentialLink (a.k.a. "kcl") attribute of other objects (e.g. member of a special group, has powerful ACEs, etc.). This allows attackers to create a key pair, append to raw public key in the attribute, and obtain persistent and stealthy access to the target object (can be a user or a computer).

Practice

In order to exploit that technique, the attacker needs to:
    1.
    be in a domain with at least one Domain Controller running Windows Server 2016 or above
    2.
    be in a domain where the Domain Controller(s) has its own key pair (for the session key exchange) (e.g. happens when AD CS is enabled or when a certificate authority (CA) is in place).
    3.
    have control over an account that can edit the target object's msDs-KeyCredentialLink attribute.
If those per-requisites are met, an attacker can
    1.
    create an RSA key pair
    2.
    create an X509 certificate configured with the public key
    3.
    create a KeyCredential structure featuring the raw public key and add it to the msDs-KeyCredentialLink attribute
    4.
    authenticate using PKINIT and the certificate and private key
UNIX-like
Windows
From UNIX-like systems, the msDs-KeyCredentialLink attribute of a user or computer target can be manipulated with the pyWhisker tool.
1
pywhisker.py -d "FQDN_DOMAIN" -u "user1" -p "CERTIFICATE_PASSWORD" --target "TARGET_SAMNAME" --action "list"
Copied!
A Pull Request (#1132, awaiting review) includes pywhisker's "add" feature in ntlmrelayx.
1
ntlmrelayx -t ldap://dc02 --shadow-credentials --shadow-target 'dc01#x27;
Copied!
When the public key has been set in the msDs-KeyCredentialLink of the target, we can use Dirk-jan's gettgtpkinit.py from PKINITtools tool to request a TGT (Ticket Granting Ticket) for the target object.
1
gettgtpkinit.py -cert-pfx "PATH_TO_CERTIFICATE" -pfx-pass "CERTIFICATE_PASSWORD" "FQDN_DOMAIN/TARGET_SAMNAME" "TGT_CCACHE_FILE"
Copied!
The ticket obtained can then be used to authenticate with pass-the-cache or an UnPAC-the-hash attack can be conducted.
From Windows systems, the msDs-KeyCredentialLink attribute of a target user or computer can be manipulated with the Whisker tool.
1
Whisker.exe add /target:"TARGET_SAMNAME" /domain:"FQDN_DOMAIN" /dc:"DOMAIN_CONTROLLER" /path:"cert.pfx" /password:"pfx-password"
Copied!
When the public key has been set in the msDs-KeyCredentialLink of the target, Rubeus can be used to request a TGT (Ticket Granting Ticket) for the target object.
1
Rubeus.exe asktgt /user:"TARGET_SAMNAME" /certificate:"BASE64_CERTIFICATE" /password:"CERTIFICATE_PASSWORD" /domain:"FQDN_DOMAIN" /dc:"DOMAIN_CONTROLLER" /show
Copied!
That ticket will then be usable with pass-the-ticket to authenticate.
Nota bene
User objects can't edit their own msDS-KeyCredentialLink attribute while computer objects can. This means the following scenario could work: trigger an NTLM authentication from DC01, relay it to DC02, make pywhisker edit DC01's attribute to create a Kerberos PKINIT pre-authentication backdoor on it, and have persistent access to DC01 with PKINIT and pass-the-cache.
Computer objects can edit their own msDS-KeyCredentialLink attribute but can only add a KeyCredential if none already exists.

Resources

https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab
posts.specterops.io
GitHub - eladshamir/Whisker: Whisker is a C# tool for taking over Active Directory user and computer accounts by manipulating their msDS-KeyCredentialLink attribute, effectively adding "Shadow Credentials" to the target account.
GitHub
GitHub - ShutdownRepo/pywhisker: Python version of the C# tool for "Shadow Credentials" attacks
GitHub
Last modified 9d ago
Copy link