La prise en charge Windows Vista Service Pack 1 (SP1) se termine le 12 juillet 2011. Pour continuer à recevoir des mises à jour de sécurité pour Windows, assurez-vous que vous exécutez Windows Vista avec Service Pack 2 (SP2). Pour plus d’informations, consultez cette page web de Microsoft : La prise en charge se termine pour certaines versions d’Windows.
Lorsqu’une application charge dynamiquement une bibliothèque de liens dynamiques sans spécifier de chemin d’accès complet, Windows tente de localiser la DLL en recherchant un ensemble bien défini d’annuaires. Si un pirate malveillant prend le contrôle de l’un des répertoires, il peut forcer l’application à charger une copie malveillante de la DLL au lieu de la DLL qu’elle attendait. Ces attaques, appelées « attaques en préchargement de DLL », sont courantes à tous les systèmes d’exploitation qui supportent le chargement dynamique des bibliothèques DLL partagées. L’effet de telles attaques peut être qu’un pirate informatique peut exécuter du code dans le contexte de l’utilisateur qui exécute l’application. Lorsque l’application est en cours d’exécuter en tant qu’administrateur, cela peut entraîner une élévation locale du privilège. Nous sommes au courant du renouvellement de l’intérêt de ces attaques. Pour limiter l’effet de ce problème sur nos clients communs, nous publions ce document à l’adresse de la communauté des développeurs afin de leur assurer qu’ils sont au courant de ce problème et disposent des outils nécessaires pour le résoudre dans leurs applications.
Résumé
Description des attaques en préchargement de DLL
Attaques basées sur LoadLibrary
Lorsqu’une application charge dynamiquement une DLL sans spécifier de chemin d’accès complet, Windows tente de localiser cette DLL en recherchant linéairement un ensemble bien défini d’annuaires, appelés ordre de recherche DLL. Si Windows recherche la DLL dans l’ordre de recherche de la DLL, elle la charge. Toutefois, si Windows ne trouve pas la DLL dans l’un des répertoires de l’ordre de recherche DLL, cela retournera un échec à l’opération de chargement de DLL. Voici ce qui suit est l’ordre de recherche DLL pour les fonctions LoadLibraryet LoadLibraryEx,qui sont utilisées pour charger dynamiquement des DLL :
-
Répertoire à partir duquel l’application a été chargée
-
Répertoire système
-
Répertoire système 16 bits
-
The Windows directory
-
CWD (Current working directory)
-
Répertoires répertoriés dans la variable d’environnement PATH
Prenons le scénario suivant :
-
Une application charge une DLL sans spécifier le chemin d’accès complet qu’elle attend de trouver dans le cdf de l’application.
-
L’application est entièrement prête à traiter le cas lorsqu’elle ne trouve pas la DLL.
-
L’pirate malveillant connaît ces informations sur l’application et contrôle le CWD.
-
L’pirate malveillant copie sa propre version spécialement conçue de la DLL dans le cdwd. Cela suppose que l’pirate malveillant est autorisé à le faire.
-
Windows dans les répertoires de l’ordre de recherche DLL et trouve la DLL dans le cd-DW de l’application.
Dans ce scénario, la DLL spécialement conçue s’exécute dans l’application et obtient les privilèges de l’utilisateur actuel.LoadLibrary. Nous sommes également conscients que certains développeurs utilisent LoadLibrary pour vérifier si une DLL spécifique est présente afin de déterminer quelle version de Windows est en cours d’exécuter par l’utilisateur. Sachez que cela peut rendre l’application vulnérable. Si la bibliothèque concernée n’existe pas dans la version Windows sur qui l’application est exécutée, un pirate malveillant peut introduire une bibliothèque du même nom dans CWD. Nous vous recommandons vivement de ne pas utiliser cette technique. À la place, utilisez les techniques recommandées décrites dans l’article MSDN, « Obtention de la version du système ». Une application qui charge les plug-ins tiers et qui ne peut pas forcer les plug-ins à utiliser un chemin qualifié pour ses appels LoadLibrary doit appeler SetDllDirectory(« ») pour supprimer CWD, puis appeler SetDllDirectory(« emplacement d’installation du plug-in ») pour ajouter le répertoire d’installation du plug-in au chemin de recherche DLL.
Recommandation Pour éviter cette attaque, les applications peuvent supprimer le répertoire de travail actuel du chemin d’accès de recherche DLL en appelant l’API SetDllDirectory en utilisant une chaîne vide (« »). Si une application dépend du chargement d’une DLL à partir du répertoire actuel, obtenez le répertoire de travail actuel et utilisez-le pour passer dans un chemin complet deAttaques basées sur SearchPath
Il existe une attaque similaire lorsqu’une application utilise l’API SearchPath pour localiser une DLL et charger dynamiquement le chemin d’accès renvoyé par SearchPath. L’ordre de recherche par défaut pour l’API SearchPath est le suivant :
-
Répertoire à partir duquel l’application a été chargée
-
CWD (Current working directory)
-
Répertoire système
-
Répertoire système 16 bits
-
The Windows directory
-
Répertoires répertoriés dans la variable d’environnement PATH
Nous vous déconseillons d’avoir ce modèle, car il n’est pas sécurisé. Nous vous déconseillons d’utiliser la fonction SearchPath comme méthode de localisation d’un fichier .dll si l’utilisation prévue de la sortie est dans un appel à la fonction LoadLibrary. Cela peut entraîner la localisation du mauvais .dll fichier, car l’ordre de recherche de la fonction SearchPath diffère de l’ordre de recherche utilisé par la fonction LoadLibrary. Si vous devez localiser et charger un .dll fichiers, utilisez la fonction LoadLibrary.
ShellExecute et CreateProcess
ShellExecuteet CreateProcesspour charger des exécutables externes. Nous recommandons aux développeurs d’être prudents lorsqu’ils chargent des binaires et de spécifier le chemin d’accès complet. Cela devrait présenter moins de complexité lorsque vous chargez un binaire au lieu d’une bibliothèque.
Des variantes de ces problèmes peuvent également exister lorsque des développeurs appellent des fonctions similaires telles queÉtapes recommandées pour les développeurs de logiciels
Nous recommandons aux développeurs de faire les choses suivantes :
-
Validez leurs applications pour les instances de chargements de bibliothèque non sous-niveau (des exemples sont donnés plus loin dans cet article). Il s’agit des éléments suivants :
-
Utilisation de SearchPath pour identifier l’emplacement d’une bibliothèque ou d’un composant.
-
Utilisation de LoadLibrary pour identifier la version du système d’exploitation.
-
-
Utilisez les chemins complets pour tous les appels vers LoadLibrary, CreateProcess et ShellExecute où vous pouvez.
-
Implémenter les appels vers SetDllDirectory avec une chaîne vide (« ») pour supprimer le répertoire de travail actuel de l’ordre de recherche DLL par défaut dans lequel il est nécessaire. N’ignorez pas que SetDllDirectory affecte l’ensemble du processus. Par conséquent, vous devez faire cela une fois de plus tôt dans l’initialisation du processus, et non avant et après les appels vers LoadLibrary. Étant donné que SetDllDirectory affecte l’ensemble du processus, plusieurs threads d’appel SetDllDirectory avec des valeurs différentes peuvent entraîner un comportement indéfini. De plus, si le processus est conçu pour charger des DLL tiers, un test sera nécessaire pour déterminer si l’établissement d’un paramètre à l’échelle du processus provoquera des incompatibilités. Un problème connu est que lorsqu’une application dépend de Visual Basic pour Applications, un paramètre à l’échelle du processus peut entraîner des incompatibilités.
-
Utilisez la fonction SetSearchPathModepour activer le mode de recherche de processus sécurisé pour le processus. Cela déplace l’annuaire de travail actuel au dernier endroit dans la liste de recherche SearchPath pour la durée de vie du processus.
-
Évitez d’utiliser le chemin SearchPath pour vérifier l’existence d’une DLL sans spécifier un chemin d’accès complet, même si le mode de recherche sans échec est activé, car cela peut toujours entraîner des attaques en préchargement de DLL.
Instructions sur l’identification des chargements de bibliothèques non sous-écures
Dans le code source, les exemples suivants illustrent des chargements de bibliothèque non sous-contrôle :
-
Dans l’exemple de code suivant, l’application recherche « schannel.dll » en utilisant le chemin de recherche le moins sécurisé. Si un pirate malveillant peut placer schannel.dll CWD, il se charge avant même que l’application ne recherche dans les Windows de recherche de la bibliothèque appropriée.
DWORD retval = SearchPath(NULL, "schannel", ".dll", err, result, NULL);
HMODULE handle = LoadLibrary(result); -
Dans l’exemple de code suivant, l’application tente de charger la bibliothèque à partir des emplacements des applications et du système d’exploitation décrits au début de ce document pour l’appel LoadLibrary(). S’il existe un risque que le fichier ne soit pas présent, l’application peut essayer de charger le fichier à partir du répertoire de travail actuel. Ce scénario est légèrement moins dangereux que dans l’exemple précédent. Toutefois, il expose toujours l’utilisateur de l’application au risque si l’environnement n’est pas complètement prévisible.
HMODULE handle = LoadLibrary("schannel.dll");
Voici des exemples de chargements de bibliothèque plus sécurisés et plus précis :
-
Dans l’exemple de code suivant, la bibliothèque est chargée directement à l’aide d’un chemin d’accès complet. Il n’y a aucun risque que l’utilisateur malveillant introduise du code malveillant, sauf s’il possède déjà des autorisations d’écriture sur le répertoire cible de l’application.
HMODULE handle = LoadLibrary("c:\\windows\\system32\\schannel.dll");
http://msdn.microsoft.com/en-us/library/ms724373%28VS.85%29.aspxSHGetFoldnFolderPath
http://msdn.microsoft.com/en-us/library/bb762188%28v=VS.85%29.aspx
-
Dans l’exemple de code suivant, le répertoire de travail actuel est supprimé du chemin de recherche avant d’appeler LoadLibrary. Cela réduit le risque de manière significative, car l’utilisateur malveillant doit contrôler soit le répertoire d’application, le répertoire Windows, soit tous les répertoires spécifiés dans le chemin d’accès de l’utilisateur afin d’utiliser une attaque par préchargement DLL.
SetDllDirectory ("");
HMODULE handle = LoadLibrary("schannel.dll"); -
Sur tous les systèmes qui ont installé la mise à jour de sécurité 963027 (décrite dans MS09-014),le code suivant déplacerait définitivement le code CWD à l’emplacement tout dernier dans l’ordre de recherche. Les appels ultérieurs vers la fonction SetSearchPathMode à partir de ce processus qui tentent de modifier le mode de recherche échoueront.
SetDllDirectory ("");
HMODULE handle = LoadLibrary("schannel.dll"); -
Dans l’exemple de code suivant, le répertoire de travail actuel est supprimé du chemin de recherche avant d’appeler LoadLibrary. Cela réduit le risque de manière significative, car l’utilisateur malveillant doit contrôler soit le répertoire d’application, le répertoire Windows, soit tous les répertoires spécifiés dans le chemin d’accès de l’utilisateur afin d’utiliser une attaque par préchargement DLL.
SetSearchPathMode (BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT );
HMODULE handle = LoadLibrary("schannel.dll");
Utilisation du moniteur de processus pour détecter de façon dynamique les chargements nonécables
Microsoft publie un outil nommé Moniteur de processus. Cet outil permet aux développeurs et aux administrateurs de suivre de près le comportement d’un processus en cours d’exécution. Le Moniteur de processus peut être utilisé pour détecter de façon dynamique si une de vos applications peut être vulnérable à ce type de problème.
-
Pour télécharger le Moniteur de processus, visitez la page web Microsoft suivante :
http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx
-
Essayez de démarrer votre application à l’aide de CWD set to a specific directory. Par exemple, double-cliquez sur un fichier avec une extension dont le poignée de traitement est affecté à votre application.
-
Configurer le moniteur de processus avec les filtres
suivants : -
Si vous touchez un chemin vulnérable, vous verrez quelque chose de similaire au suivant : L’appel vers le partage de fichiers distant pour charger une DLL indique qu’il s’agit d’un programme
vulnérable.
Informations supplémentaires
Pour plus d’informations, consultez les pages web Microsoft suivantes : Ordre de recherche dans la
bibliothèque de liens dynamiqueshttp://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspxDocumentation MSDN sur la fonction SearchPath
http://msdn.microsoft.com/en-us/library/aa365527(VS.85).aspxDocumentation MSDN sur la fonction LoadLibrary
http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspxDocumentation MSDN sur la fonction SetDllDirectory
http://msdn.microsoft.com/en-us/library/ms686203(VS.85).aspxDocumentation MSDN sur la fonction SetSearchPathMode
http://msdn.microsoft.com/en-us/library/dd266735(VS.85).aspxBillet de blog de David Leblanc, ingénieur sécurité principal avec Microsoft Office
http://blogs.msdn.com/b/david_leblanc/archive/2008/02/20/dll-preloading-attacks.aspxBillet de blog d’Andrew AndrewS, de l’équipe d’ingénierie MSRC sur DLL lors du préchargement d’attaques