
NTLMv1 Multitool
Cet outil convertit les hash NTLMv1 en NTLM, ou plus précisément il formate les réponses au défi NTLMv1 dans un format pouvant être craqué avec le mode 14000 de hashcat.
Si vous spécifiez --ct3, l’outil calcule les 4 derniers caractères du hash NTLM pour vous. Si vous spécifiez --json, alors --ct3 est implicite et le résultat est renvoyé sous l’élément pt3, par exemple :
python3 ntlmv1.py --ntlm "DC1$::MOG:AC51EC464A91A35A04A862DA3106EC2B352661ECEF909C5E:AC51EC464A91A35A04A862DA3106EC2B352661ECEF909C5E:1122334455667788" --json
{"ntlmv1": "DC1$::MOG:AC51EC464A91A35A04A862DA3106EC2B352661ECEF909C5E:AC51EC464A91A35A04A862DA3106EC2B352661ECEF909C5E:1122334455667788", "user": "DC1$", "domain": "MOG", "challenge": "1122334455667788", "lmresp": "AC51EC464A91A35A04A862DA3106EC2B352661ECEF909C5E", "ntresp": "AC51EC464A91A35A04A862DA3106EC2B352661ECEF909C5E", "ct3": "352661ECEF909C5E", "ct3_crack": "ct3_to_ntlm.bin 352661ECEF909C5E 1122334455667788", "pt3": "8c71", "hash1": "AC51EC464A91A35A:1122334455667788", "hash2": "04A862DA3106EC2B:1122334455667788"}
Enfin, dans cette mise à jour, j’ai déplacé les fonctions dans main() afin que vous puissiez simplement importer le module pour une utilisation directe.
J’ai ajouté 2 nouvelles options, --hashcat et --hcutils, qui définissent respectivement le chemin vers votre hashcat et vos hashcat-utils afin que vous puissiez faire un copier-coller direct depuis l’outil.
Vous lanceriez l’outil comme ceci si votre répertoire hashcat se trouvait dans ~/git/hashcat et votre répertoire hashcat-utils dans ~/git/hashcat-utils :
python3 ./ntlmv1.py --ntlm "SERVER1$::MOG:9DE7F41D81C1207400000000000000000000000000000000:DE766A98B60D1C911DCFFFDBB3E521314B2CE34EAB63CC7B:1122334455667788" --hashcat "~/git/hashcat" --hcutils "~/git/hashcat-utils"
Oui, c’est normalement compatible Python 3, et j’ai également fusionné ntlmv1 et ntlmv1-ess.
Multitool NTLMv1
Cet outil modifie les hash NTLMv1/NTLMv1-ESS/MSCHAPv2 afin qu’ils puissent être craqués avec le mode DES 14000 de hashcat.
Cet outil est basé sur les travaux d’atom de l’équipe Hashcat https://hashcat.net/forum/thread-5832.html
Il est également basé sur https://hashcat.net/forum/thread-5912.html et https://www.youtube.com/watch?v=LIHACAct2vo
Installez l’outil de nouvelle génération ntlmv1_nextgen.py comme commande globale ntlmv1-multi avec uv :
uv tool install .
ntlmv1-multi --ntlmv1 "hashcat::DUSTIN-5AA37877:76365E2D142B5612980C67D057EB9EFEEE5EF6EB6FF6E04D:727B4E35F947129EA52B9CDEDAE86934BB23EF89F50FC595:1122334455667788"
Ou exécutez-le directement depuis le dépôt sans l’installer :
uv run ntlmv1_nextgen.py --ntlmv1 "hashcat::DUSTIN-5AA37877:..."
Le projet fournit un pyproject.toml (Python 3.14+, dépendance pycryptodome), donc uv résout tout pour vous ; le script original ntlmv1.py fonctionne toujours en autonome avec n’importe quel interpréteur Python 3.
ntlmv1_nextgen.py)ntlmv1_nextgen.py (installé comme commande ntlmv1-multi) est l’analyseur moderne. Il accepte les hash NTLMv1, les blobs $99$ et MSCHAPv2, gère automatiquement ESS, et peut réaliser la conversion complète NTLMv1 -> NTLM à partir d’un potfile craqué en une seule étape. Options disponibles :
Pour capturer, utilisez responder avec l’option --lm. Sans --lm, vous activez ESS, ce qui prendra plus de temps à craquer. Une nouvelle option est également disponible, --disable-ess, qui tente de désactiver ESS et de forcer la rétrogradation. Essayez d’abord --disable-ess et si cela échoue, essayez --lm. Si vous utilisez --disable-ess ou --lm, assurez-vous que votre défi client est 1122334455667788 pour utiliser le FPGA ; cela peut toutefois déclencher certaines protections IDS/IPS réseau si elles voient ce trafic.
La capture ressemblera à ceci.
[SMB] NTLMv1 Client : 184.64.60.62
[SMB] NTLMv1 Username : DUSTIN-5AA37877\hashcat
[SMB] NTLMv1 Hash : hashcat::DUSTIN-5AA37877:76365E2D142B5612980C67D057EB9EFEEE5EF6EB6FF6E04D:727B4E35F947129EA52B9CDEDAE86934BB23EF89F50FC595:1122334455667788
[*] Skipping previously captured hash for DUSTIN-5AA37877\hashcat
La partie hash ressemble à ceci :
hashcat::DUSTIN-5AA37877:76365E2D142B5612980C67D057EB9EFEEE5EF6EB6FF6E04D:727B4E35F947129EA52B9CDEDAE86934BB23EF89F50FC595:1122334455667788
Utilisez donc le multitool comme ceci (il est également compatible Python 2) :
python3 ntlmv1.py --ntlmv1 hashcat::DUSTIN-5AA37877:76365E2D142B5612980C67D057EB9EFEEE5EF6EB6FF6E04D:727B4E35F947129EA52B9CDEDAE86934BB23EF89F50FC595:1122334455667788
Il produira les données suivantes sans modifier les défis serveur, etc.
['hashcat', '', 'DUSTIN-5AA37877', '76365E2D142B5612980C67D057EB9EFEEE5EF6EB6FF6E04D', '727B4E35F947129EA52B9CDEDAE86934BB23EF89F50FC595', '1122334455667788']
Hostname: DUSTIN-5AA37877
Username: hashcat
Challenge: 1122334455667788
LM Response: 76365E2D142B5612980C67D057EB9EFEEE5EF6EB6FF6E04D
NT Response: 727B4E35F947129EA52B9CDEDAE86934BB23EF89F50FC595
CT1: 727B4E35F947129E
CT2: A52B9CDEDAE86934
CT3: BB23EF89F50FC595
To Calculate final 4 characters of NTLM hash use:
./ct3_to_ntlm.bin BB23EF89F50FC595 1122334455667788
To crack with hashcat create a file with the following contents:
727B4E35F947129E:1122334455667788
A52B9CDEDAE86934:1122334455667788
To crack with hashcat:
./hashcat -m 14000 -a 3 -1 charsets/DES_full.charset --hex-charset hashes.txt ?1?1?1?1?1?1?1?1
Le mot de passe utilisé dans ce cas est « password » et nous pouvons vérifier le hash NTLM avec
echo -n password | iconv -f utf8 -t utf16le | openssl dgst -md4
(stdin)= 8846f7eaee8fb117ad06bdd830b7586c
Avec l’utilitaire hashcat-utils ct3_to_ntlm.bin écrit par atom, vous pouvez calculer les 4 derniers caractères du hash NTLM à partir du défi NTLMv1, que l’outil affiche :
./ct3_to_ntlm.bin BB23EF89F50FC595 1122334455667788
586c
Cela correspond à la fin du hash NTLM, nous sommes donc prêts. L’étape suivante consiste à craquer les hash avec hashcat, il faut donc créer un fichier hashes.txt contenant :
727B4E35F947129E:1122334455667788
A52B9CDEDAE86934:1122334455667788
Pour craquer cela avec hashcat, vous utilisez
./hashcat -m 14000 -a 3 -1 charsets/DES_full.charset --hex-charset hashes.txt ?1?1?1?1?1?1?1?1
Note importante : hashcat renvoie des clés DES et non des clés NTLM. Vous devrez les convertir en NTLM à l’aide de deskey_to_ntlm.pl depuis Hashcat Utils, ce qui peut être fait avec
./deskey_to_ntlm.pl [cracked des key 1]
./deskey_to_ntlm.pl [cracked des key 2]
Vous combinez ensuite les deux clés NTLM avec la troisième partie du mot de passe, calculée par (ce que l’outil affiche) :
./ct3_to_ntlm.bin BB23EF89F50FC595 1122334455667788
Additionnez ces 3 éléments et vous êtes prêt.
Si vous testez simplement mon code et connaissez déjà le mot de passe, vous pouvez utiliser le convertisseur DES :
python ntlm-to-des.py --ntlm b4b9b02e6f09a9bd760f388b67351e2b
DESKEY1: b55d6d04e67926
DESKEY2: bcba83e6895b9d
echo "$HEX[b55d6d04e67926]">>des.cand
echo "$HEX[bcba83e6895b9d]">>des.cand
En gros, vous faites ce qui suit :
echo "$HEX[b55d6d04e67926]">>des.cand
echo "$HEX[bcba83e6895b9d]">>des.cand
./hashcat -m 14000 -a 0 hashes.txt des.cand
Et vous devriez obtenir des hash crackés.
ESS modifie le défi serveur. Si vous voyez ESS dans votre responder parce que vous n’avez pas utilisé --lm ou que le client est configuré pour ne pas fournir de réponse LM, ESS est alors engagé. De plus, --disable-ess tentera de forcer la désactivation d’ESS, mais cela nécessite une copie récente (août 2021 ou plus récente) d’impacket et de responder.
La sortie ESS ressemble à ceci :
[SMB] NTLMv1-SSP Client : 184.64.60.62
[SMB] NTLMv1-SSP Username : DUSTIN-5AA37877\hashcat
[SMB] NTLMv1-SSP Hash : hashcat::DUSTIN-5AA37877:85D5BC2CE95161CD00000000000000000000000000000000:892F905962F76D323837F613F88DE27C2BBD6C9ABCD021D0:1122334455667788
Le hash proprement dit ressemble à ceci :
hashcat::DUSTIN-5AA37877:85D5BC2CE95161CD00000000000000000000000000000000:892F905962F76D323837F613F88DE27C2BBD6C9ABCD021D0:1122334455667788
Pour utiliser l’outil, lancez (il est compatible Python 3) :
python3 ntlmv1.py --ntlmv1 "hashcat::DUSTIN-5AA37877:85D5BC2CE95161CD00000000000000000000000000000000:892F905962F76D323837F613F88DE27C2BBD6C9ABCD021D0:1122334455667788"
L’outil affichera :
Hashfield Split:
['hashcat', '', 'DUSTIN-5AA37877', '85D5BC2CE95161CD00000000000000000000000000000000', '892F905962F76D323837F613F88DE27C2BBD6C9ABCD021D0', '1122334455667788']
Hostname: DUSTIN-5AA37877
Username: hashcat
LM Response: 85D5BC2CE95161CD00000000000000000000000000000000
NT Response: 892F905962F76D323837F613F88DE27C2BBD6C9ABCD021D0
Client Challenge: 1122334455667788
SRV Challenge: b36d2b9a8607ea77
To Calculate final 4 characters of NTLM hash use:
./ct3_to_ntlm.bin 2BBD6C9ABCD021D0 1122334455667788 85D5BC2CE95161CD00000000000000000000000000000000
To crack with hashcat create a file with the following contents:
892F905962F76D32:b36d2b9a8607ea77
3837F613F88DE27C:b36d2b9a8607ea77
To crack with hashcat:
./hashcat -m 14000 -a 3 -1 charsets/DES_full.charset --hex-charset hashes.txt ?1?1?1?1?1?1?1?1
Le mot de passe utilisé dans ce cas est password, dont le hash NTLM est b4b9b02e6f09a9bd760f388b67351e2b
echo -n password | iconv -f utf8 -t utf16le | openssl dgst -md4
(stdin)= 8846f7eaee8fb117ad06bdd830b7586c
Donc, pour calculer les 4 derniers caractères du hash NTLM pour notre défi NTLMv1-ESS, nous utilisons la commande suivante issue de la sortie de l’outil pour obtenir 586c
./ct3_to_ntlm.bin 2BBD6C9ABCD021D0 1122334455667788 85D5BC2CE95161CD00000000000000000000000000000000
Selon l’outil, nous devons créer un fichier de hash avec le contenu suivant, qui contient les défis SRV modifiés pour gérer ESS :
892F905962F76D32:b36d2b9a8607ea77
3837F613F88DE27C:b36d2b9a8607ea77
Pour craquer avec hashcat, nous utilisons la commande suivante selon l’outil :
./hashcat -m 14000 -a 3 -1 charsets/DES_full.charset --hex-charset hashes.txt ?1?1?1?1?1?1?1?1
Note importante : hashcat renvoie des clés DES et non des clés NTLM. Vous devrez les convertir en NTLM à l’aide de deskey_to_ntlm.pl depuis Hashcat Utils, ce qui peut être fait avec
./deskey_to_ntlm.pl [cracked des key 1]
./deskey_to_ntlm.pl [cracked des key 2]
Maintenant, en supposant que nous connaissions déjà le hash NTLM dans ce cas parce que nous l’avons créé et que nous voulions valider l’outillage, nous utilisons ce qui suit :
python ntlm-to-des.py --ntlm b4b9b02e6f09a9bd760f388b67351e2b
Cela produira quelques données pour nous :
DESKEY1: b55d6d04e67926
DESKEY2: bcba83e6895b9d
echo "$HEX[b55d6d04e67926]">>des.cand
echo "$HEX[bcba83e6895b9d]">>des.cand
La partie importante ici est :
echo "$HEX[b55d6d04e67926]">>des.cand
echo "$HEX[bcba83e6895b9d]">>des.cand
Nous pouvons maintenant craquer avec hashcat en utilisant la commande suivante, sans attendre 8 jours :
./hashcat -m 14000 -a 0 hashes.txt des.cand
python ntlm-to-des.py --ntlm 8846f7eaee8fb117ad06bdd830b7586c
DESKEY1: b55d6d05e6792652
DESKEY2: bdba82e6895a9d6a
echo "$HEX[b55d6d05e6792652]">>des.cand
echo "$HEX[bdba82e6895a9d6a]">>des.cand
L’outil prend désormais en charge la sortie JSON. Définissez le drapeau --json et il produira une sortie JSON :
python3 ntlmv1.py --ntlmv1 "SERVER1$::MOG:7EF3F506F5EA510E00000000000000000000000000000000:1217169BD7BE0270A033899BD440016D3E6DACAF5894D504:ff81dfd6b12c269d" --json
{"ntlmv1": "SERVER1$::MOG:7EF3F506F5EA510E00000000000000000000000000000000:1217169BD7BE0270A033899BD440016D3E6DACAF5894D504:ff81dfd6b12c269d", "user": "SERVER1$", "domain": "MOG", "challenge": "ff81dfd6b12c269d", "lmresp": "7EF3F506F5EA510E00000000000000000000000000000000", "ntresp": "1217169BD7BE0270A033899BD440016D3E6DACAF5894D504", "ct3": "3E6DACAF5894D504", "srvchallenge": "888f8ee0fa031808", "ct3_crack": "ct3_to_ntlm.bin 3E6DACAF5894D504 ff81dfd6b12c269d 7EF3F506F5EA510E00000000000000000000000000000000", "hash1": "1217169BD7BE0270:888f8ee0fa031808", "hash2": "A033899BD440016D:888f8ee0fa031808", "CRACK_SH": "$NETLM$888f8ee0fa031808$1217169BD7BE0270A033899BD440016D3E6DACAF5894D504"}
Les champs importants sont :
Après avoir craqué les hash DES du mode 14000 avec hashcat, les clés DES crackées apparaissent dans votre potfile sous forme de lignes ct:challenge:key (la clé est normalement stockée sous forme $HEX[...] car ce sont des octets bruts). Au lieu de copier manuellement les clés avec --key1/--key2, pointez ntlmv1_nextgen.py vers le potfile et il récupérera les clés, les validera par rapport aux textes chiffrés, et effectuera la conversion complète NTLMv1 -> NTLM en une étape :
python3 ntlmv1_nextgen.py --ntlmv1 "hashcat::DUSTIN-5AA37877:76365E2D142B5612980C67D057EB9EFEEE5EF6EB6FF6E04D:727B4E35F947129EA52B9CDEDAE86934BB23EF89F50FC595:1122334455667788" --potfile ~/.local/share/hashcat/hashcat.potfile
Le hash NTLM récupéré est affiché sous le champ NTLM (ou ntlm en --json). --potfile fonctionne avec --ntlmv1, --99 et --mschapv2, gère les hash ESS (correspondance sur le défi dérivé de MD5) et ignore les entrées de potfile non liées. Les --key1/--key2 explicites restent prioritaires sur les correspondances du potfile.
Les potfiles hashcat et rainbowcrackalack sont tous deux acceptés. Le champ de clé crackée peut être un blob $HEX[...] de hashcat, des octets imprimables bruts, une clé brute de 8 octets en hexadécimal (16 caractères), ou une clé brute de 7 octets en hexadécimal (14 caractères) (la forme émise par rainbowcrackalack) — tout est normalisé et re-validé par rapport au texte chiffré avant utilisation.
Ce dépôt est basé sur les posts du forum d’atom, l’auteur de hashcat, et sur les recherches de moxie marlinspike. Comme le code d’atom est en grande partie sous licence MIT, ce projet a également adopté cette licence par compatibilité. Ce projet n’est pas sous licence GPL afin que toute entité puisse l’intégrer dans un projet commercial sans restrictions.
| Option | Description |
|---|
--ntlmv1 <hash> | Hash NTLMv1 au format Responder (user::host:LM:NT:challenge). |
--99 <blob> | Blob base64 au style $99$. |
--mschapv2 <hash> | Hash MSCHAPv2 au format John the Ripper. |
--nthash <hex> | Hash NTLM de 32 caractères ; dérive les clés DES et les candidats hashcat. |
--password <pw> | Dérive les clés DES --key1/--key2 à partir d’un mot de passe connu. |
--key1 <hex> / --key2 <hex> | Fournit directement les clés DES 16 hex pour CT1/CT2 (prioritaires sur --potfile). |
--potfile <path> | Potfile hashcat/rainbowcrackalack des clés du mode 14000 craquées ; récupère automatiquement key1/key2 pour terminer la conversion NTLMv1 -> NTLM. |
--hashcat | Émet les chaînes au format hashcat pour CT1/CT2. |
--json | Sortie JSON uniquement (implique le calcul CT3). |