Desole, pas trop eu l'occasion de mettre le blog a jour recemment (question de flemme sans doute). Bon cette entree a pour but de relever un truc marrant sous Windows. J'ai bosse sur
MS08-034, l'elevation de privilege locale sur le serveur WINS, et c'etait plutot marrant a faire. La socket de notification est en ecoute sur 127.0.0.1, vous lui envoyez de la merde, vous avez un write4, gagne.
Bon le truc c'est que l'idee du correctif adoptee par Microsoft est plutot pas mal. On chiffre les donnees avec
CryptProtectData, on les envoie, puis le serveur dechiffre avec CryptUnprotectData, et voila. Vu que seul l'utilisateur qui a chiffre peut dechiffrer, ca assure que seul LOCALSYSTEM puisse communiquer sur la socket, probleme regle.
D'ou l'idee d'aller regarder ce qui se passe au niveau de la fonction de chiffrement. J'aime bien la crypto, mais je n'ai jamais passe trop de temps sur la crypto de Windows en soi. Plus sur les programmes tierce partie. Je me ballade donc dans les DLLs associees, lsasrv.dll, cryptsvc.dll, psbase.dll, tout ca. Je tombe sur le morceau de code suivant:
call esi ; LocalAlloc(x,x) ; LocalAlloc(x,x)
test eax, eax
mov [ebx], eax
jz loc_743CB422
push dword ptr [edi]
push eax
call _SystemFunction036@8
; SystemFunction036(x,x)
test al, al
jz loc_743CB412
call ?FIsEncryptionPermitted@@YGHXZ
; FIsEncryptionPermitted(void)
test eax, eax
jnz short loc_743CB387
mov eax, [ebx]
mov dword ptr [eax], 6D8A886Ah
mov eax, [ebx]
mov dword ptr [eax+4], 4EAA37A8h
loc_743CB387: ; CODE XREF: FMyEncryptKeyBlock(ushort const *,ushort const *,uchar * const,uchar * *,ulong *,_DESKey *,_DESKey *)+97j
push dword ptr [ebx] ; unsigned __int8 *
push [ebp+var_DC] ; struct _DESKey *
call ?FMyMakeDESKey@@YGHPAU_DESKey@@PAE@Z
; FMyMakeDESKey(_DESKey *,uchar *)
Marrant ca. La fonction SystemFunction036 est un generateur pseudo aleatoire fort, mais si le chiffrement n'est pas autorise, alors les donnees utilisees pour la cle DES ne sont plus aleatoire mais hardcodees. Regardons donc la fonction en question:
call ds:__imp__GetSystemDefaultLCID@0 ; GetSystemDefaultLCID()
cmp ax, 40Ch
jz loc_743C524E
loc_743C1599: ; CODE XREF: FIsEncryptionPermitted(void)+3CEFj
push 0Ah ; cchData
lea ecx, [ebp+var_10]
push ecx ; lpLCData
push LOCALE_ICOUNTRY ; LCType
push eax ; Locale
call ds:__imp__GetLocaleInfoA@16 ; GetLocaleInfoA(x,x,x,x)
test eax, eax
jz loc_743C525A
loc_743C15B0: ; CODE XREF: FIsEncryptionPermitted(void)+3CFAj
push offset a33 ; "33"
lea eax, [ebp+var_10]
push eax ; lpString1
call ds:__imp__lstrcmpA@8 ; lstrcmpA(x,x)
Le LCID 0x40c est le francais, le country code 33 est pour la France. Et ca provient d'un XP SP2 a jour.
Heureux possesseurs de Windows Francophones, il semblerait que certaines fonctions cryptographiques de votre OS (pas toutes, rassurez vous) vous propose 32768 fois moins d'entropie qu'un OpenSSH sous Debian.