Dans un domaine Windows, il se peut que les clients soient (temporairement) dans l’impossibilité de valider leur authentification auprès d’un contrôleur de domaine.
C’est particulièrement le cas des postes mobiles (portables/tablettes/…).
Pour permettre les ouvertures de sessions ou déverrouillage en mode hors-ligne, Windows peut conserver un certains nombres d’entrées utilisateurs en cache (par défaut 10 – http://technet.microsoft.com/library/cc957390.aspx).
Ces caches se trouvent dans la base de registre, à l’emplacement HKEY_LOCAL_MACHINE\SECURITY\Cache
(accessible à SYSTEM).
Ces entrées sont chiffrés symétriquement, mais l’on y retrouve quelques informations sur l’utilisateur, ainsi que des hash suffisants pour vérifier l’authentification.
Windows 2003/XP
L’algorithme de chiffrement est RC4.
Le hash étant utilisé pour vérifier l’authentification est calculé de la manière suivante :
DCC1 = MD4(MD4(Unicode(password)) . LowerUnicode(username))
soit
DCC1 = MD4(hashNTLM . LowerUnicode(username))
Devant les facilités d’attaques par pass-the-hash, l’on ne peut que se réjouir de ce « salage » par le nom d’utilisateur.
Il existe toutefois un nombre tables pré-calculées pour des utilisateurs tel que Administrator
facilitant les attaques sur ces hashs.
mimikatz # lsadump::cache Domain : WINXP SysKey : a4905bdecbbef089d5e7c26dd86cf285 Policy subsystem is : 1.7 LSA Key : 57af228842e63b532789b8f207a4e942 [NL$1 - 02/03/2014 21:26:51] RID : 000001f4 (500) User : CHOCOLATE\Administrateur MsCacheV1 : 53f1a7f5e51fdb29e32f07204fb8d54e mimikatz #
Windows Vista/2008 et >
L’algorithme de chiffrement est AES128.
Le hash étant utilisé pour vérifier l’authentification est calculé de la manière suivante :
DCC2 = PBKDF2(HMAC-SHA1, Iterations, DCC1, LowerUnicode(username))
avec DCC1 calculé de la même manière que pour 2003/XP
mimikatz # lsadump::cache Domain : WIN81 SysKey : ab023e1a0a41ae80986b0075bbcd645b Policy subsystem is : 1.12 LSA Key(s) : 1, default {021c6967-cf42-411f-8929-38feebd05ff1} [00] {021c6967-cf42-411f-8929-38feebd05ff1} b2e66d1c21b2c37db1c9b0c01438fff00f9754ce5159b2dc133c27d0f63efb81 * Iteration is set to default (10240) [NL$1 - 02/03/2014 21:33:05] RID : 000001f4 (500) User : CHOCOLATE\Administrateur MsCacheV2 : c1c34952b9bb06a561820e8f404da848 mimikatz #
Il n’y a finalement pas beaucoup de différence avec XP/2003 ; aucune donnée de salage supplémentaire n’est introduite.
Seul la fonction PBKDF2
introduit une nouvelle variable : un nombre d’itérations SHA1 avec le même sel que précédemment (le nom d’utilisateur).
Itérations
Seulement disponible sous NT6, ces itérations ont pour rôle de ralentir les attaques brutes.
Plus leur nombre est élevé, plus l’attaque brute sera longue (et l’ouverture de session Windows lente).
Ce nombre d’itérations est connu, il s’agit de 10240 (10 << 10). Cette valeur est bien évidemment hardcodée dans tous les programmes traitant les hashs MsCache v2 (que j’ai pu voir !)
- Cain – http://www.oxid.it/
- HashCat – http://hashcat.net
- PassLib – http://pythonhosted.org/passlib/lib/passlib.hash.msdcc2.html
- OpenWall – http://openwall.info/wiki/john/MSCash2_simple_code
Exemple avec Cain
Cain a réussi à valider le mot de passe waza1234/
pour le premier hash (il s’agit de la configuration par défaut).
La deuxième ligne contient en revanche le hash d’une configuration « modifiée » sur lequel Cain n’a pu vérifier le mot de passe.
Cette modification est le nombre d’itération, celui-ci est configurable par la base de registre :
HKEY_LOCAL_MACHINE\SECURITY\Cache
valeur DWORD(32) NL$IterationCount
- si ce nombre est inférieur à 10240, il s’agit d’un multiplicateur par 1024 (20 donnera donc 20480 itérations)
- si ce nombre est supérieur à 10240, il s’agit du nombre d’itérations (arrondi à 1024)
Code simplifié
if(pNL$IterationCount) // NL$IterationCount in registry { if(*pNL$IterationCount > 10240) { Iterations = *pNL$IterationCount & ~0x3ff; } else { Iterations = *pNL$IterationCount * 1024; } } else // No NL$IterationCount in registry (default), equ. 10 { Iterations = 10240; }
Conclusion en 3 points
- Il serait judicieux de pouvoir paramétrer le nombre d’itération dans des outils tel que Cain et HashCat ;
- Il est dommage que Microsoft n’ait pas choisi de saler ce hash DCC2 avec une donnée complexe propre à chaque système ;
- S’il est nécessaire de conserver la mise en cache, il est intéressant de modifier
NL$IterationCount
avec une valeur différente pour chaque système.
(pour désactiver toute mise en cache dans un domaine, positionnerCachedLogonsCount
à 0, voir ci-dessous)
Téléchargement & ressources
La version alpha prenant en charge ces améliorations est disponible : http://blog.gentilkiwi.com/mimikatz