Étude réalisée par
Jean-Claude BELLAMY © 1999 |
|
Les informations qui
suivent n'ont rien d'occulte! Bien que mettant en évidence un défaut de
sécurité dans NT, elles n'émanent pas d'un site quelconque de "hacker". Au
contraire, elles ont pour but de mettre en garde contre une utilisation
malintentionnée de Windows NT, et de modifier sa configuration
en conséquence. Elles s'adressent donc avant tout aux administrateurs de
stations de travail Windows NT.
Elles proviennent d'études personnelles et des sources suivantes :
Origine |
Lien & titre |
Date | |
|
Microsoft |
"Restricting Changes to Base System Objects" http://support.microsoft.com/support/kb/articles/q218/4/73.asp |
20/04/99 05/03/99 25/02/99 |
|
L0pht Heavy Industries |
"Any local user can gain administator privileges and/or take full control over the system" http://www.L0pht.com/advisories.html |
18/02//99 |
Les versions suivantes de Windows NT sont concernées :
Sous certaines conditions opératoires, un utilisateur sans aucun privilège (compte "invité" p.ex.) peut modifier en mémoire certaines librairies système importantes et grâce à cela s'approprier des droits très élevés, lui permettant d'effectuer n'importe quelle opération relevant du niveau administrateur.
Windows NT met en oeuvre un système de "cache" en mémoire
virtuelle dans lequel il charge des librairies dynamiques (DLL)
particulièrement importantes et surtout très fréquemment
utilisées. Elles sont alors partagées entre tous les programmes. Cela évite
des copies redondantes en mémoire de ces DLL, améliorant ainsi l'utilisation de la mémoire
et les performances du système. A partir du moment où une de ces DLL a
été placée dans le cache, elle n'est plus jamais rechargée depuis un fichier
sur disque.
Le chargement de ces DLL est effectué au démarrage de Windows (avant
ouverture d'une session), à partir d'une liste contenue dans la clef
suivante de la base de registres :
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\KnownDLLs
On y retrouve une vingtaine de DLL, dont "kernel32.dll",
"user32.dll", "url.dll", "version.dll",...
Ce système est (était?) censé accroitre la sécurité, puisque le remplacement
sur disque d'une de ces DLL par une autre (de même nom mais modifiée)
est totalement vain.
En effet, prenons l'exemple de "comdlg32.dll", qui sert à afficher les
boites de dialogue standard. Si au cours d'une session on décide de remplacer cette
librairie par une autre version, (en admettant qu'il n'y ait à cet instant aucune
application y faisant appel), cette opération sera inopérante, puisque Windows
continuera à utiliser la version initiale de comdlg32, placée dans le cache.
Or les objets créés
dans ce cache le sont avec des permissions de contôle total pour "Tout
le monde" !
Donc, il est tout à fait possible à un utilisateur n'ayant aucun privilège
de vider, modifier, ajouter un
"objet" (= une DLL), en particulier une librairie système
comme "kernel32.dll". A l'aide de cette librairie modifiée, se
comportant en quelque sorte comme un "Cheval de Troie", il va être
possible d'effectuer n'importe quelle opération par la suite.
Pour plus
d'informations sur le principe des "knownDLLs", consulter
l'article Q164501
Windows NT Uses KnownDLLs Registry Entry to Find DLLs
http://support.microsoft.com/support/kb/articles/q164/5/01.asp
L'idée de base mise en oeuvre par L0ph Heavy Industries pour mettre en évidence ce défaut a été la suivante :
Le point d'entrée (DLLMain), appelé sytématiquement à chaque chargement de la DLL par n'importe quel processus, a été réécrit complètement. Toutes les autres API renvoient simplement à la DLL d'origine. DLLmain effectue une énumération des objets "Windows Station", puis pour chaque, énumération des "Windows Desktop", avec communication du nom du propriétaire de l'objet et interrogation de l'utilisateur s'il veut lancer ou non un "shell" pour cette station/desktop. Tant qu'il voit son nom comme propriétaire, l'utilisateur doit répondre "non", jusqu'à ce qu'apparaisse comme propriétaire : AUTORITE NT/SYSTEM. A ce moment là, la DLL modifiée kernel32 va ouvrir une fenêtre console de commandes (command.com de DOS), mais qui n'a rien d'anodine, puisque le propriétaire en est AUTORITE NT/SYSTEM. Donc tout processus exécuté depuis cette fenêtre va hériter des droits AUTORITE NT/SYSTEM, c'est-à-dire avec le plus haut niveau de privilèges! Ainsi, l'utilisateur n'ayant aucun droit - en théorie - pourra donc exécuter le gestionnaire des utilisateurs, ouvrir son compte, et le modifier à sa guise, en s'octroyant par exemple le niveau administrateur.
Toute application "classique" lancée par l'utilisateur hérite des privilèges de l'utilisateur, mais il peut y avoir des processus intermédiaires, lancés alors par Windows, et ayant alors AUTORITE NT/SYSTEM comme propriétaire. Cela se produit quand on lance une application d'un autre sous-système. On rappelle à cet effet qu'il y a 3 sous-systèmes sous Windows NT, en mode "user" (mode protégé), situés au dessus du système de base, en mode "kernel" (non protégé) :
- Win32 (Applications Windows 32 bits + NT Virtual DOS Machine, dans laquelle s'exécuteront les applications Windows 16 bits et les applications DOS)
- POSIX (Applications en mode caractère, normalisées, portables sous d'autres systèmes d'exploitation telles que UNIX)
- OS/2 (Applications en mode caractère du système d'exploitation d'IBM)
Par défaut, une session Windows est dans le sous-système Win32. Les autres sous-systèmes (POSIX et OS/2) sont alors inactifs. Si, depuis une fenêtre de commandes (Win32) on lance une application POSIX, cela va se traduire par l'exécution première du processus Win32 psxss.exe (Application sous-système POSIX, qui va donner le contrôle ensuite à la DLL Client POSIX psxdll.dll). Or ce processus, qui nécessite temporairement le passage en mode kernel, a donc pour propriétaire AUTORITE NT/SYSTEM. Par ailleurs, psxss.exe fait appel à kernel32.dll (ne serait-ce que pour les API LoadLibrary et GetProcAddress ). Donc il va provoquer à un certain moment l'exécution du point d'entrée modifié de kernel32.dll, et ainsi pemettre le lancement d'un shell appartenant à AUTORITE NT/SYSTEM..
On utilise deux fichiers fournis par L0pht (anciennement sur http://www.L0pht.com/advisories/hackdll.zip, disponible ici) :
A cause de la présence sur ce site
du fichier
hackdll.zip, certains anti-virus
peuvent se méprendre et détecter à tort la présence d'un "cheval de
Troie".
C'est le cas de PCCILLIN, produit de
TREND, qui croit déceler
le troyen "TROJ_DLLHACK.A".
Je peux affirmer que c'est totalement faux, l'intégralité du présent
document ayant été composée par mes soins et est garantie sans virus.
Par ailleurs, on a créé un compte dans le groupe "invités" (aucun
privilège) du nom de "DICK"
On commence par recopier dans le répertoire c:\temp
la DLL originale kernel32.dll, renommée ici en realkern.dll. Ce
répertoire et ce nouveau nom sont obligatoires, la nouvelle DLL eggdll.dll
effectuant une redirection "en dur" (nom et chemin) vers elle. L0pht
ayant fourni les sources,
il est toutefois possible de recompiler cette librairie si on veut changer de nom
et/ou de répertoire.
Ensuite on lance une session sous le compte DICK.
On ouvre une fenêtre de commandes, dans laquelle on vide du cache la DLL
kernel32.Dll, puis on la remplace par eggdll.dll.
Il ne faut plus toucher à cette fenêtre, toute action provoquant le
retour à la situation initiale.
Depuis une autre fenêtre de commandes, on lance une commande POSIX. Le Resource KIT de NT en contient tout un répertoire (commandes "vi", "ls", "cat", "rmdir", "grep",...), mais on peut toujours se contenter de taper p.ex. la commande posix /c calc (NB: le programme "calc" a été pris au hasard. Ce n'est pas un programme POSIX, donc il y aura à la fin un refus de la part du lanceur "posix" de l'exécuter, mais cela n'a pas d'importance, puisque ce que l'on désire seulement est le démarrage du processus psxss.exe)
Une première boite de dialogue apparaît alors, due à kernel32.dll modifiée :
On répond ici "Non", car le propriétaire |
![]() |
D'autres boites analogues vont se suivre, jusqu'a ce qu'apparaisse : On répond alors "Oui" à cette question, |
![]() |
puis à celles qui suivent : |
![]() |
Une fenêtre de commande nommée "System Console" apparaît alors : |
|
Fenêtre console créée par kernel32.dll Le propriétaire est AUTORITE NT |
![]() |
Lancement du gestionnaire d'utilisateurs depuis cette
fenêtre.
|
|
On peut modifier totalement le compte "DICK"
(et les autres) !
|
|
Fenêtre console ouverte normalement par DICK. Le propriétaire est DICK |
|
Lancement du gestionnaire d'utilisateurs depuis cette
fenêtre.
|
|
On ne peut pas modifier le compte "DICK" !
|
On peut d'ailleurs vérifier cette "dualité" de comptes, en exécutant la commande whoami, soit depuis une fenêtre de commandes traditionnelle, soit depuis une fenêtre de commandes lancée depuis la fenêtre System Console.
Fenêtre ordinaire | Fenêtre spéciale |
![]() |
![]() |
La première solution proposée consiste à fixer à 1 la valeur (DWORD) ProtectionMode contenue dans la clef
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager
(cette valeur est 0 par défaut).
Cette protection n'est réellement efficace que si l'accès à cette clef est protégé (réservé aux administrateurs)
Cette modification introduit un effet indésirable très gênant dans certains cas !
On s'est rendu compte que si elle est activée, certaines commandes deviennent impossibles à effectuer par un utilisateur non administrateur. En effet, ce paramétrage active la certification C2. Par exemple, il n'est plus possible de supprimer un "raccourci" créé sur un chemin par la commande subst ("accès refusé"), ce qui peut être très contraignant avec certains scripts.
Par ailleurs, dans le même article Q218473, daté successivement du 05/03/99 puis du 20/04/99, Microsoft propose une deuxième solution, composée d'un patch. Il est constitué d'une nouvelle version du module smss.exe (Windows NT Session Manager), que l'on peut télécharger depuis le serveur FTP de Microsoft ftp.microsoft.com, depuis le répertoire /bussys/winnt/winnt-public/fixes/xxx/nt40/hotfixes-postSP4/smss-fix ("xxx" désigne la version de langue)
Le patch existe en deux versions, une pour plate-forme Intel, une pour plate-forme Alpha.
Il suffit de lancer l'exécutable pour installer le patch.
Je l'ai testé et il fonctionne bien, toute modification des DLL en cache est désormais refusée.
La modification de la base de registre ne s'impose donc pas, sauf si on désire avoir un poste de travail certifié C2.
L0pht Heavy Industries propose (gratuitement) un "hotfix" (anciennement sur http://www.L0pht.com/advisories/dllfix.zip, disponible ici, ainsi que la source), composé d'un service, donc lancé au démarrage de NT, qui contrôle totalement le cache et interdit toute modification non autorisée.
Après l'avoir installé et lancé, on a pu d'ailleurs tester son efficacité :
Il existe une autre méthode pour accéder à un compte administrateur (ou autre) sous NT4 ou même Windows 2000 en absence du mot de passe. Elle est décrite dans le chapitre consacré à Windows NT, et fait appel à une disquette bootable Linux spécialement conçue à cet effet.