Partager via


Liste de vérification de la sécurité des pilotes

Cet article fournit une liste de vérification de la sécurité pour les développeurs de pilotes afin de réduire le risque de compromission des pilotes. La sécurité du pilote est critique et a un impact direct sur la fiabilité. Lorsque Windows détecte que l’accès à la mémoire incorrect est en cours, il arrête le système d’exploitation et affiche un écran d’erreur bleu. En tant que partenaire Windows, vous devez travailler pour réduire l’impact significatif qu’un pilote défaillant a sur la vie de nos clients.

Pour plus d’informations sur les avantages de la fourniture d’un pilote sécurisé et fiable, consultez guide de sécurité du pilote.

Aperçu de la sécurité des pilotes

Une faille de sécurité est toute faille qui permet à un attaquant de provoquer un dysfonctionnement d’un pilote de telle façon qu’il permet à un attaquant d’obtenir un accès non autorisé, de manipuler le système ou de compromettre les données, ce qui peut entraîner un blocage ou devenir inutilisable. De plus, les vulnérabilités dans le code du pilote peuvent permettre à un attaquant d’accéder au noyau, créant ainsi la possibilité de compromettre l’ensemble du système d’exploitation.

Lorsque la plupart des développeurs travaillent sur leur pilote, leur objectif est de faire fonctionner correctement le pilote, et non de savoir si un attaquant malveillant tentera d’exploiter les vulnérabilités de leur code. Cependant, après la sortie d’un pilote, les attaquants peuvent tenter de détecter et d’identifier les failles de sécurité. Les développeurs doivent prendre en compte ces problèmes lors de la phase de conception et de mise en œuvre afin de minimiser la probabilité de telles vulnérabilités. L’objectif est d’éliminer toutes les failles de sécurité connues avant la sortie du pilote.

La création de pilotes plus sécurisés nécessite la coopération de l’architecte système (réfléchissant consciemment aux menaces potentielles pour le pilote), du développeur mettant en œuvre le code (codant de manière défensive les opérations courantes susceptibles d’être exploitées), et de l’équipe de test (cherchant de manière proactive à trouver les faiblesses et les vulnérabilités). En coordonnant correctement toutes ces activités, la sécurité du pilote est considérablement améliorée.

En plus d’éviter les problèmes associés à une attaque contre un pilote, bon nombre des étapes décrites, telles qu’une utilisation plus précise de la mémoire du noyau, augmenteront la fiabilité de votre pilote. Cela réduit les coûts de support et augmente la satisfaction des clients avec votre produit. Achever les tâches de la liste de vérification ci-dessous aidera à atteindre tous ces objectifs.

Liste de contrôle de sécurité :Complétez la tâche de sécurité décrite dans chacun de ces sujets.

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité.Confirmez qu’un pilote de noyau est nécessaire

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité. Utiliser les frameworks de pilotes

case à cocher non marquée représentant un élément dans la liste de contrôle de sécurité.Gérer le contrôle d’accès des pilotes

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité.Contrôler l’accès aux pilotes logiciels uniquement

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité. Suivez les instructions de codage sécurisé du pilote

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité. Implémentez un code compatible HVCI

case à cocher non marquée représentant un élément dans la liste de contrôle de sécurité.Suivre les meilleures pratiques de code propres à la technologie

Une case à cocher non marquée représentant un élément de la liste de contrôle de sécurité.Ajoutez des annotations SAL à votre code de pilote

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité. Effectuer une révision de code homologue

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité. Effectuez une analyse des menaces

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité. Utiliser CodeQL pour vérifier le code de votre pilote

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité. Utiliser le vérificateur de pilotes pour rechercher les vulnérabilités

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité. Vérifiez le code avec les tests du programme de compatibilité matérielle

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité. Vérifiez les pilotes prêts à être expédiés avec des outils tels que BinSkim et SignTool

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité.Ne pas signer le code du pilote de test de production

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité. Effectuez une signature appropriée des pilotes de version et distribuez votre paquet de pilotes en utilisant Windows Update

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité. Comprendre comment les pilotes sont signalés à l’aide du Centre de création de rapports de pilotes vulnérables et malveillants Microsoft

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité. Passez en revue les ressources de codage sécurisé

case à cocher non marquée représentant un élément dans la liste de contrôle de sécurité. Examiner le résumé des points clés

Confirmez qu’un pilote de noyau est nécessaire

élément de liste de contrôle de sécurité n° 1 :Confirmer qu’un pilote de noyau est requis et qu’une approche à risque moindre, telle que le service Ou l’application Windows, n’est pas une meilleure option.

Les pilotes de noyau résident dans le noyau Windows, et un problème lorsqu’ils s’exécutent dans le noyau expose l’ensemble de ce système d’exploitation. Si une autre option est disponible, elle sera probablement moins coûteuse et moins risquée que la création d’un nouveau pilote de noyau.

Pour plus d’informations sur l’utilisation des pilotes Windows intégrés, consultez Devez-vous écrire un pilote ?.

Pour des informations sur l’utilisation des tâches en arrière-plan, veuillez consulter Prise en charge de votre application avec des tâches d’arrière-plan.

Pour des informations sur l’utilisation des services Windows, veuillez consulter Services.

Utilisez les frameworks de pilotes

Élément de liste de contrôle de sécurité n°2 : Utilisez les frameworks de pilotes pour réduire la taille de votre code et augmenter sa fiabilité et sa sécurité.

Utilisez les Windows Driver Frameworks pour réduire la taille de votre code et augmenter sa fiabilité et sa sécurité. Pour commencer, consultez l’utilisation de WDF pour développer un pilote. Pour plus d’informations sur l’utilisation de l’infrastructure UMDF (User Mode Driver Framework) à risque inférieur, consultez Choix d’un modèle de pilote.

L'écriture d'un ancien modèle de pilote Windows (WDM) est plus fastidieuse, plus coûteuse et implique de recréer le code disponible dans les cadres de pilotes.

Le code source WDF (Windows Driver Framework) est open source et disponible sur GitHub. Il s’agit du même code source WDF fourni dans Windows. Vous pouvez déboguer votre pilote plus efficacement lorsque vous pouvez suivre les interactions entre le pilote et WDF. Téléchargez-le depuis https://github.com/Microsoft/Windows-Driver-Frameworks.

DMF : Framework de module de pilote

Envisagez l’utilisation du Driver Module Framework (DMF) dans votre projet de pilote. Développé par l’équipe Microsoft Surface, DMF est un framework qui permet la création d’objets WDF appelés modules DMF. Le code de ces modules DMF peut être partagé entre différents pilotes. De plus, DMF fournit une bibliothèque de modules DMF qui ont été développés pour les pilotes et offrent une réutilisation du code pour les tâches telles que la gestion des threads et des E/S. Un module DMF est utilisé pour encapsuler des tâches de pilote en unités plus petites. Chaque module est autonome et possède son propre code, contexte et rappels, ce qui facilite la réutilisation. Pour plus d’informations, consultez Présentation de l’infrastructure de module pilote et de la documentation du site GitHub .

Gérez le contrôle d’accès aux pilotes

Élément de liste de contrôle de sécurité n° 3 : Examinez votre pilote pour vous assurer que vous contrôlez correctement l’accès.

Gestion du contrôle d’accès des pilotes - WDF

Les pilotes doivent s'efforcer d'empêcher les utilisateurs d’avoir un accès inapproprié aux appareils et fichiers d’un ordinateur. Pour empêcher l’accès non autorisé aux appareils et aux fichiers, vous devez :

  • Nommer les objets périphérique uniquement lorsque cela est nécessaire. Les objets d'appareil nommés sont généralement nécessaires uniquement pour des raisons de compatibilité, par exemple si vous disposez d'une application qui s'attend à ouvrir l'appareil à l'aide d'un nom particulier ou si vous utilisez un appareil ou un dispositif de contrôle non PNP. Notez que les pilotes WDF n’ont pas besoin de nommer leur FDO d’appareil PnP pour créer un lien symbolique en utilisant WdfDeviceCreateSymbolicLink.

  • Sécurisez l’accès aux objets et interfaces des appareils.

Afin de permettre aux applications ou autres pilotes WDF d’accéder à votre PDO d’appareil PnP, vous devez utiliser les interfaces d’appareil. Pour plus d’informations, veuillez consulter la section Utilisation des interfaces d’appareils dans le WDK. Une interface d’appareil sert de lien symbolique vers le PDO de la pile de votre appareil.

L'une des meilleures façons de contrôler l'accès au PDO consiste à spécifier une chaîne SDDL dans votre INF. Si la chaîne SDDL n’est pas dans le fichier INF, Windows applique un descripteur de sécurité par défaut. Pour plus d’informations, consultez Sécurisation des objets d’appareil et SDDL pour les objets d’appareil.

Pour plus d’informations sur le contrôle de l’accès, consultez les rubriques suivantes :

Contrôle de l'accès aux dispositifs dans les pilotes KMDF

Noms, descripteurs de sécurité et classes d’appareils - Rendre les objets des appareils accessibles… et SAFE tiré de The NT Insider Newsletter Janvier Février 2017 publié par OSR.

Gestion du contrôle d’accès des pilotes - WDM

Si vous utilisez un pilote WDM et que vous avez utilisé un objet d’appareil nommé, vous pouvez utiliser IoCreateDeviceSecure et spécifier un SDDL pour le sécuriser. Lorsque vous implémentez IoCreateDeviceSecure, spécifiez toujours un GUID de classe personnalisé pour DeviceClassGuid. Vous ne devez pas spécifier un GUID de classe existant ici. Cela pourrait compromettre les paramètres de sécurité ou la compatibilité pour d’autres appareils appartenant à cette classe. Pour plus d’informations, veuillez consulter WdmlibIoCreateDeviceSecure.

Pour plus d’informations, consultez les rubriques suivantes :

Contrôle de l'accès aux appareils

Contrôle de l'accès à l'espace noms des appareils

Modèle de sécurité Windows pour les développeurs de pilotes

Hiérarchie des risques des identificateurs de sécurité (SID)

La section suivante décrit la hiérarchie des risques des SID couramment utilisés dans le code des pilotes. Pour des informations générales sur SDDL, veuillez consulter les section SDDL pour objets périphérique, Chaînes SID et Syntaxe des chaînes SDDL.

Il est important de comprendre que si des appelants de niveau de privilège inférieur sont autorisés à accéder au noyau, le risque de code augmente. Dans ce diagramme de synthèse, le risque augmente à mesure que vous permettez aux SID de niveau de privilège inférieur d’accéder aux fonctionnalités de votre pilote.

SY (System)
     \/
BA (Built-in Administrators)
     \/
LS (Local Service)
     \/
BU (Built-in User)
     \/
AC (Application Container)

En suivant le principe de sécurité de moindre privilège, configurez uniquement le niveau d’accès minimum nécessaire au fonctionnement de votre pilote.

Contrôle granulaire de la sécurité IOCTL de WDM

Un IOCTL (contrôle d’entrée/sortie) dans Windows est un appel système pour les opérations d’entrée/sortie spécifiques à l’appareil. Les IOCTL sont utilisés par les applications pour communiquer avec les pilotes de périphérique, ce qui leur permet d’envoyer des commandes ou de demander des informations à partir du matériel. Pour plus d’informations, consultez Présentation des codes de contrôle d’E/S et exemple de requête d’E/S - Vue d’ensemble.

Pour mieux gérer la sécurité lorsque des IOCTL sont envoyés par des appelants en mode utilisateur, le code du pilote peut inclure la fonction IoValidateDeviceIoControlAccess. Cette fonction permet à un pilote de vérifier les droits d’accès. Lors de la réception d’un IOCTL, un pilote peut appeler IoValidateDeviceIoControlAccess, en spécifiant FILE_READ_ACCESS, FILE_WRITE_ACCESS, ou les deux.

La mise en œuvre d’un contrôle granulaire de la sécurité IOCTL ne remplace pas la nécessité de gérer l’accès aux pilotes en utilisant les techniques discutées ci-dessus.

Pour plus d’informations, consultez Définition des codes de contrôle d’E/S et problèmes de sécurité pour les codes de contrôle d’E/S.

Contrôlez l’accès aux pilotes logiciels uniquement

élément de liste de contrôle de sécurité n° 4 :Si un pilote logiciel uniquement sera créé, un contrôle d’accès supplémentaire doit être implémenté.

Les pilotes logiciels uniquement du noyau n’utilisent pas le plug-and-play (PnP) pour être associés à des identifiants matériels spécifiques, et peuvent fonctionner sur n’importe quel PC. Un tel pilote pourrait être utilisé à des fins autres que celle initialement prévue, créant ainsi un vecteur d’attaque.

Étant donné que les pilotes logiciels uniquement du noyau comportent des risques supplémentaires, ils doivent être limités à l’exécution sur du matériel spécifique (par exemple, en utilisant un identifiant PnP unique pour permettre la création d’un pilote PnP, ou en vérifiant la table SMBIOS pour la présence de matériel spécifique).

Par exemple, imaginez que l’OEM Fabrikam souhaite distribuer un pilote permettant une utilité d’overclocking pour leurs systèmes. Si ce pilote uniquement logiciel devait s'exécuter sur un système d’un autre OEM, cela pourrait entraîner une instabilité du système ou des dommages. Les systèmes de Fabrikam devraient inclure un identifiant PnP unique pour permettre la création d’un pilote PnP qui est également mis à jour via Windows Update. Si cela n’est pas possible et que Fabrikam crée un pilote hérité, ce pilote doit trouver une autre méthode pour vérifier qu’il s’exécute sur un système Fabrikam (par exemple, en examinant la table SMBIOS avant d’activer des fonctionnalités).

Suivez les directives de codage sécurisé des pilotes

élément de liste de contrôle de sécurité n° 5 :passez en revue votre code et supprimez les vulnérabilités de code connues.

L’activité principale de la création de pilotes sécurisés consiste à identifier les zones du code nécessitant des modifications pour éviter les vulnérabilités logicielles connues. La plupart de ces vulnérabilités logicielles connues concernent le suivi rigoureux de l'utilisation de la mémoire pour éviter que d'autres éléments n'écrasent ou ne compromettent les emplacements de mémoire utilisés par votre pilote.

Les outils de scan de code tels que CodeQL et les tests spécifiques aux pilotes peuvent être utilisés pour aider à localiser certaines, mais pas toutes, de ces vulnérabilités. Ces outils et tests sont décrits plus loin dans cette rubrique.

Tampons de mémoire

Utilisez la méthode appropriée pour accéder aux tampons de données avec les IOCTL

Une des principales responsabilités d’un pilote Windows est de transférer des données entre les applications en mode utilisateur et les appareils du système. Les trois méthodes d’accès aux tampons de données sont présentées dans le tableau suivant.

Type de tampon IOCTL Récapitulatif Informations supplémentaires
METHOD_BUFFERED Recommandé pour la plupart des situations Utilisation des E/S en mémoire tampon
METHOD_IN_DIRECT ou METHOD_OUT_DIRECT Utilisé dans certains E/S matériels à haute vitesse Utilisation des E/S directes
METHOD_NEITHER À éviter si possible Utilisation des entrées/sorties directes et non tamponnées

En général, les E/S mises en mémoire tampon sont recommandées, car elles fournissent les méthodes de mise en mémoire tampon les plus sécurisées. Mais même en utilisant l’E/S mis en tampon, il existe des risques, tels que les pointeurs intégrés qui doivent être atténués.

Pour plus d’informations sur le travail avec des tampons dans les IOCTL, consultez Méthodes d’accès aux mémoires tampons de données.

Erreurs d’utilisation de l’E/S mis en tampon IOCTL

  • Vérifiez la taille des tampons liés aux IOCTL. Pour plus d’informations, consultez Échec de la vérification de la taille des mémoires tampons.

  • Initialisez correctement les tampons de sortie. Pour plus d’informations, consultez Échec de l’initialisation des mémoires tampons de sortie.

  • Validez correctement les tampons de longueur variable. Pour plus d’informations, consultez Échec de validation des mémoires tampons de longueur variable

  • Lorsque vous utilisez l’E/S mis en tampon, assurez-vous de retourner la longueur correcte pour le OutputBuffer dans le champ Information de la structure IO_STATUS_BLOCK. Ne retournez pas directement la longueur directement à partir d’une requête READ. Par exemple, considérez une situation où les données retournées de l’espace utilisateur indiquent qu’il y a un tampon de 4K. Si le pilote doit en fait ne retourner que 200 octets, mais retourne à la place 4K dans le champ Information, une vulnérabilité de divulgation d’informations s’est produite. Ce problème se produit parce que dans les versions antérieures de Windows, la mémoire tampon utilisée par le Gestionnaire d’E/S pour les E/S mises en mémoire tampon n’est pas zéro. Ainsi, l'application utilisateur récupère les 200 octets d'origine des données, plus les 4K-200 octets restants de ce qui se trouvait dans la mémoire tampon (contenu du pool non paginé). Ce scénario peut se produire avec toutes les utilisations de l’E/S mis en tampon et pas seulement avec les IOCTL.

Erreurs dans l’E/S direct IOCTL

Gérez correctement les tampons de longueur nulle. Pour plus d’informations, consultez Errors in Direct E/S.

Erreurs dans la référence aux adresses de l’espace utilisateur

Le code du pilote doit faire une utilisation correcte de la mémoire

  • Toutes les allocations de pool de pilotes doivent être dans le pool non exécutable (NX). Utiliser des pools de mémoire NX est intrinsèquement plus sécurisé que d’utiliser des pools non paginés (NP) exécutables et offre une meilleure protection contre les attaques de débordement.

  • Pour permettre aux pilotes de prendre en charge la virtualisation HVCI, il y a des exigences de mémoire supplémentaires. Pour plus d’informations, consultez Implémenter le code compatible HVCI plus loin dans cet article.

Vulnérabilités TOCTOU

Il existe une vulnérabilité potentielle de vérification de l’heure à l’utilisation de l’heure (TOCTOU) lors de l’utilisation de l’E/S direct (pour les IOCTL ou pour Read/Write). N’oubliez pas que, lorsque le pilote accède à la mémoire tampon de données utilisateur, l’application utilisateur peut accéder simultanément au même tampon de données.

Pour gérer ce risque, copiez tous les paramètres devant être validés à partir du tampon de données utilisateur vers une mémoire accessible uniquement en mode noyau (comme la pile ou le pool). Ensuite, une fois que les données ne sont pas accessibles par l’application utilisateur, validez et utilisez les données transmises.

Lectures et écritures de MSR (model-specific register)

Les intrinsics du compilateur, tels que __readmsr et __writemsr, peuvent être utilisés pour accéder aux registres spécifiques au modèle. Si cet accès est requis, le pilote doit toujours vérifier que le registre dans lequel lire ou écrire est limité à l’index ou à la plage attendu.

Pour plus d’informations et des exemples de code, veuillez consulter la section Fournir la possibilité de lire/écrire les MSR dans Bonnes pratiques pour restreindre les comportements à privilèges élevés dans les pilotes en mode noyau.

Poignées

Objets de l’appareil

Plans de ressources intégrés (IRPs)

Les paquets de demandes d’E/S Windows sont utilisés pour communiquer les demandes d’E/S entre le système d’exploitation et les pilotes en mode noyau, encapsulant toutes les informations nécessaires dans le paquet. Les IRPs facilitent le transfert asynchrone, la synchronisation et la gestion des erreurs, ce qui garantit une communication efficace et fiable avec des périphériques matériels. Pour plus d'informations, consultez Paquets de requêtes d'E/S et Vue d'ensemble du modèle d'E/S Windows.

WDF et IRP

L’un des avantages de l’utilisation de WDF est que les pilotes WDF n’accèdent généralement pas directement aux IRPs. Par exemple, le framework convertit les IRP WDM représentant les opérations de contrôle de lecture, d’écriture et de périphérique en objets de requête du framework que KMDF/UMDF reçoit dans les files d’attente E/S. Dans la mesure du possible, l’utilisation de WDF est fortement recommandée.

Si vous devez écrire un pilote WDM, passez en revue les instructions suivantes.

Gérez correctement les tampons E/S des IRP

Passez en revue ces rubriques qui expliquent comment valider les valeurs d’entrée IRP :

DispatchReadWrite utilisant des E/S tamponnées

Erreurs dans les E/S en mémoire tampon

DispatchReadWrite utilisant des E/S directes

Erreurs dans les E/S directes

Validez les valeurs associées à un IRP, telles que les adresses de mémoire tampon et les longueurs.

Si vous avez choisi d'utiliser le mode Neither I/O, sachez que, contrairement à la lecture et à l'écriture, et contrairement aux E/S mises en mémoire tampon et aux E/S directes, lorsque vous utilisez le mode Neither I/O avec IOCTL, les pointeurs de mémoire tampon et les longueurs ne sont pas validés par le gestionnaire d'E/S.

Gérez correctement les opérations de complétion des IRP

Un pilote ne doit jamais terminer un IRP avec une valeur de statut de STATUS_SUCCESS sauf s’il supporte et traite effectivement l’IRP. Pour plus d'informations sur les méthodes appropriées pour gérer les opérations de finalisation des IRP, consultez : Fin des IRPs.

Gérez l’état en attente des IRP du pilote

Le pilote doit marquer l’IRP comme étant en attente avant de sauvegarder l’IRP, et devrait envisager d’inclure à la fois l’appel à IoMarkIrpPending et l’affectation dans une séquence imbriquée. Pour plus d’informations, consultez la rubrique Échec de la vérification de l’état d’un pilote et Conservation des IRPs entrants lorsqu’un appareil est suspendu.

Gérez correctement les opérations d’annulation des IRP

Les opérations d’annulation peuvent être difficiles à coder correctement car elles s’exécutent généralement de manière asynchrone. Les problèmes dans le code qui gère les opérations d’annulation peuvent passer inaperçus pendant longtemps, car ce code n’est généralement pas exécuté fréquemment dans un système en cours d’exécution. Veillez à lire et à comprendre toutes les informations fournies sous Annulation des IRPs. Portez une attention particulière à la Synchronisation de l’annulation d’une IRP et aux Points à prendre en compte lors de l’annulation d’IRP.

Une méthode recommandée pour minimiser les problèmes de synchronisation associés aux opérations d’annulation est de mettre en œuvre une File d’attente IRP sécurisée contre les annulations.

Gérer correctement les opérations de nettoyage et de fermeture de l'IRP

Assurez-vous de comprendre la différence entre les requêtes IRP_MJ_CLEANUP et IRP_MJ_CLOSE. Les requêtes de nettoyage arrivent après qu’une application ait fermé tous les handles sur un objet fichier, mais parfois avant que toutes les requêtes E/S aient été terminées. Les demandes de fermeture arrivent après que toutes les demandes d’E/S pour le fichier ont été terminées ou annulées. Pour plus d’informations, consultez les rubriques suivantes :

Routines DispatchCreate, DispatchClose et DispatchCreateClose

Routines DispatchCleanup

Erreurs dans la gestion des opérations de nettoyage et de fermeture

Pour plus d’informations sur la gestion correcte des IRP, consultez la rubrique Erreurs supplémentaires dans la gestion des IRP.

Utilisez des fonctions sécurisées

Autres problèmes de sécurité

  • Utilisez un verrou ou une séquence interverrouillée pour éviter les conditions de course. Pour plus d’informations, consultez la section Erreurs dans un environnement multiprocesseur.

  • Vérifiez qu’aucun filtre TDI (Network Transport Driver Interface) ou les fournisseurs de services en couches (LSP) ne sont installés par le pilote ou les packages logiciels associés pendant l’installation ou l’utilisation. Utilisez plutôt des API modernes, telles que la Windows Filtering Platform (WFP) .

Vulnérabilités de code supplémentaires

En plus des vulnérabilités possibles couvertes ici, cet article fournit des informations supplémentaires sur l’amélioration de la sécurité du code des pilotes en mode noyau : Création de pilotes fiables en mode noyau.

Pour des informations supplémentaires sur le codage sécurisé en C et C++, consultez la section Ressources de codage sécurisées à la fin de cet article.

Implémentez un code compatible HVCI

élément n° 6 de la liste de contrôle de sécurité :Vérifiez que votre pilote utilise la mémoire pour être compatible avec HVCI.

Intégrité de la mémoire et compatibilité HVCI

L’intégrité de la mémoire, également appelée Intégrité du code protégée par Hyperviseur (HVCI) utilise la technologie matérielle et la virtualisation pour isoler la fonction décisionnaire d’intégrité du code (CI) du reste du système d’exploitation. Lorsque vous utilisez la sécurité basée sur la virtualisation pour isoler l'IC, la mémoire du noyau ne peut devenir exécutable qu'à travers une vérification de l'IC. Cela signifie que les pages de mémoire du noyau ne peuvent jamais être à la fois modifiables (écriture) et exécutables (W+X), et que le code exécutable ne peut pas être modifié directement.

Pour implémenter un code compatible HVCI, assurez-vous que le code de votre pilote fait ce qui suit :

  • Opte pour NX par défaut
  • Utilise les API/indicateurs NX pour l’allocation de mémoire (NonPagedPoolNx)
  • N’utilise pas de sections à la fois écrites et exécutables
  • Ne tente pas de modifier directement la mémoire système exécutable
  • N’utilise pas de code dynamique dans le noyau
  • Ne charge pas de fichiers de données en tant qu’exécutables
  • L’alignement des sections est un multiple de 0x1000 (PAGE_SIZE). Par exemple, DRIVER_ALIGNMENT=0x1000

Pour plus d’informations sur l’utilisation de l’outil et une liste des appels de mémoire incompatibles, veuillez consulter la section Implémenter le code compatible HVCI.

Pour plus d’informations sur le test de sécurité des fondamentaux du système, veuillez consulter les section Test de préparation de l’intégrité du code HyperVisor et Intégrité du code protégé par hyperviseur (HVCI).

Améliorez la sécurité de l’installation des appareils

Élément de liste de contrôle de sécurité #7 :Examinez les directives de création et d’installation des fichiers INF des pilotes pour vous assurer que vous suivez les bonnes pratiques.

Lorsque vous créez le code qui installe votre package de pilotes, vous devez vous assurer que l’installation de votre appareil sera toujours effectuée de manière sécurisée. Une installation sécurisée de l’appareil :

  • Limite l’accès à l’appareil et à ses classes d’interface d’appareil
  • Limite l’accès aux services de pilotes créés pour l’appareil
  • Protège les fichiers de pilotes contre la modification ou la suppression
  • Limite l’accès aux entrées de registre de l’appareil
  • Limite l’accès aux classes WMI de l’appareil
  • Utilise correctement les fonctions SetupAPI

Pour plus d’informations, consultez les rubriques suivantes :

Création d’installations sécurisées de dispositifs

Lignes directrices pour l'utilisation de SetupAPI

Utilisation des fonctions d'installation des appareils

Rubriques avancées sur l'installation de périphériques et des pilotes

Suivez les bonnes pratiques de code spécifiques à la technologie

élément de liste de contrôle de sécurité n° 8 :passez en revue les directives spécifiques à la technologie suivantes pour votre pilote.

Systèmes de fichiers

Pour plus d’informations, sur la sécurité des pilotes du système de fichiers, consultez les rubriques suivantes :

Introduction à la sécurité des systèmes de fichiers

Problèmes de sécurité du système de fichiers

Fonctionnalités de sécurité pour les systèmes de fichiers

Coexistence avec d’autres pilotes de filtre de système de fichiers

Microsoft Virus Initiative

Microsoft Virus Initiative (MVI) aide les organisations à améliorer les solutions de sécurité dont nos clients s’appuient pour les protéger. Microsoft fournit des outils, des ressources et des connaissances pour prendre en charge de meilleures expériences avec des performances, une fiabilité et une compatibilité optimales. Microsoft collabore avec les partenaires MVI pour définir et suivre les pratiques de déploiement sécurisé (SDP) pour prendre en charge la sécurité et la résilience de nos clients mutuels.

Si vous êtes un fournisseur antivirus, consultez Microsoft Virus Initiative pour savoir comment rejoindre MVI pour obtenir plus d’aide sur le déploiement de logiciels. Pour plus d’informations sur la façon dont les fournisseurs de sécurité peuvent mieux tirer parti des fonctionnalités de sécurité intégrées de Windows pour renforcer la sécurité et la fiabilité, consultez meilleures pratiques de sécurité Windows pour l’intégration et la gestion des outils de sécurité.

NDIS - Mise en réseau

Pour des informations sur la sécurité des pilotes NDIS, veuillez consulter la section Problèmes de sécurité pour les pilotes réseau.

Imprimantes

Pour des informations relatives à la sécurité des pilotes d’imprimante, veuillez consulter la section Considérations relatives à la sécurité du pilote d’imprimante V4.

Problèmes de sécurité pour les pilotes d’acquisition d’images Windows (WIA)

Pour des informations sur la sécurité WIA, consultez la section Problèmes de sécurité pour les pilotes WIA (Windows Image Acquisition).

Ajoutez des annotations SAL à votre code de pilote

élément de liste de contrôle de sécurité n° 9 :Ajouter des annotations SAL à votre code de pilote.

Le langage d’annotation du code source (SAL) fournit un ensemble d’annotations que vous pouvez utiliser pour décrire comment une fonction utilise ses paramètres, les hypothèses qu’elle fait à leur sujet et les garanties qu’elle donne lorsqu’elle se termine. Les annotations sont définies dans le fichier d’en-tête sal.h. L’analyse de code Visual Studio pour C++ utilise les annotations SAL pour modifier son analyse des fonctions. Pour plus d’informations sur SAL 2.0 pour le développement de pilotes Windows, consultez les section Annotations SAL 2.0 pour les pilotes Windows et Utilisation des annotations SAL pour réduire les défauts de code C/C++.

Pour des informations générales sur SAL, reportez-vous à cet article disponible chez OSR. SAL Annotations : Ne me déteste pas parce que je suis belle

Effectuer une révision de code par les pairs

élément de liste de contrôle de sécurité #10 :Effectuer une révision de code homologue pour rechercher les problèmes non exposés par les autres outils et processus

Recherchez des réviseurs de code compétents pour identifier les problèmes que vous pourriez avoir manqués. Un deuxième regard peut souvent identifier des problèmes que vous avez négligés.

Si vous n’avez pas de personnel approprié pour passer en revue votre code en interne, envisagez d’engager de l’aide extérieure à cet effet.

Effectuez une analyse des menaces

élément de liste de contrôle de sécurité n° 11 :modifier un modèle de menace de pilote existant ou créer un modèle de menace personnalisé pour votre pilote.

En matière de sécurité, une méthodologie courante consiste à créer des modèles de menaces spécifiques qui tentent de décrire les types d’attaques possibles. Cette technique est utile lors de la conception d’un pilote car elle oblige le développeur à considérer les vecteurs d’attaque potentiels contre un pilote à l’avance. Après avoir identifié les menaces potentielles, un développeur de pilote peut alors envisager des moyens de se défendre contre ces menaces afin de renforcer la sécurité globale du composant pilote.

Cet article fournit des conseils spécifiques aux pilotes pour créer un modèle de menaces léger : Modélisation des menaces pour les pilotes. L’article fournit un diagramme de modèle de menaces de pilote exemple pouvant être utilisé comme point de départ pour votre pilote.

Diagramme de flux de données illustrant un pilote en mode noyau hypothétique.

Les bonnes pratiques du Security Development Lifecycle (SDL) et les outils associés peuvent être utilisés par les IHVs et les OEMs pour améliorer la sécurité de leurs produits. Pour plus d’informations, consultez SDL recommendations for OEMs.

Utilisez CodeQL pour vérifier le code de votre pilote

élément de liste de contrôle de sécurité n° 12 :Utiliser CodeQL pour rechercher les vulnérabilités dans votre code de pilote.

CodeQL, par GitHub, est un moteur d’analyse de code sémantique et la combinaison d’une suite étendue de requêtes de sécurité, ainsi qu’une plateforme robuste, constituent un outil précieux pour sécuriser le code du pilote. Pour plus d’informations, consultez CodeQL et le test du logo Static Tools.

Utilisez Driver Verifier pour vérifier les vulnérabilités

élément de liste de contrôle de sécurité n° 13 :Utiliser le vérificateur de pilote pour vérifier les vulnérabilités dans votre code de pilote.

Driver Verifier utilise un ensemble de règles d’interface et un modèle du système d’exploitation pour déterminer si le pilote interagit correctement avec le système d’exploitation Windows. L'outil de vérification des pilotes détecte des défauts dans le code du pilote qui pourraient indiquer la présence de bogues potentiels.

Driver Verifier permet de tester en direct le pilote. Le Driver Verifier surveille les pilotes en mode noyau de Windows et les pilotes graphiques pour détecter les appels de fonction ou actions illégales susceptibles de corrompre le système. Un débogueur attaché permet d’afficher en temps réel l’exécution du code du système d’exploitation et du pilote. Driver Verifier peut soumettre les pilotes Windows à une variété de stress et de tests pour détecter un comportement incorrect. Pour plus d’informations, consultez Type de débogage.

Le pilote Verifer fonctionne avec les pilotes WDM et KMDF. Pour connaître les détails de ce qu’il peut vérifier, consultez les rubriques suivantes.

Pour plus d'informations sur les pilotes que Driver Verifier peut utiliser, consultez Règles de Conformité DDI et Pilotes Pris en Charge. Pour connaître les règles de vérificateur supplémentaires pour des types spécifiques de pilotes, consultez :

Pour vous familiariser avec DV, vous pouvez utiliser l’un des pilotes d’exemple (par exemple, l’échantillon de toaster en vedette : https://github.com/Microsoft/Windows-driver-samples/tree/main/general/toaster/toastDrv/kmdf/func/featured).

Vérifiez le code avec les tests du programme de compatibilité matérielle

élément de liste de contrôle de sécurité n° 14 :Utiliser les tests du programme de compatibilité matérielle associés à la sécurité pour vérifier les problèmes de sécurité.

Le programme de compatibilité matérielle comprend des tests liés à la sécurité qui peuvent être utilisés pour rechercher des vulnérabilités dans le code. Le programme de compatibilité matérielle Windows utilise les tests du Windows Hardware Lab Kit (HLK). Les tests de fondamentaux des appareils HLK peuvent être utilisés en ligne de commande pour exercer le code du pilote et rechercher des faiblesses. Pour des informations générales sur les tests des fondamentaux des appareils et le programme de compatibilité matérielle, consultez Windows Hardware Lab Kit.

Les tests suivants sont des exemples de tests pouvant être utiles pour vérifier le code du pilote pour certains comportements associés aux vulnérabilités du code :

DF - Test IOCTL aléatoire fuzz (Fiabilité)

DF - Test Fuzz sous-ouverture (Fiabilité)

DF - Test FSCTL de la mémoire tampon de longueur nulle Fuzz (Fiabilité)

DF - Test FSCTL aléatoire fuzz (Fiabilité)

DF - Test de l’API Fuzz Misc (Fiabilité)

Vous pouvez également utiliser le délai de synchronisation du noyau inclus avec Driver Verifier.

Les tests CHAOS (Concurrent Hardware and Operating System) exécutent divers tests de pilotes PnP, tests de fuzzing de pilotes d’appareil et tests de système d’alimentation simultanément. Pour plus d’informations, consultez Les Tests CHAOS (Principes de base de l’appareil).

Les tests de pénétration des fondamentaux des appareils effectuent diverses formes d’attaques d’entrée, qui sont un élément critique des tests de sécurité. Les tests d’attaque et de pénétration peuvent aider à identifier les vulnérabilités dans les interfaces logicielles. Pour plus d’informations, consultez Les Tests de pénétration (Principes de base de l’appareil).

Utilisez le Device Guard - Compliance Test, ainsi que les autres outils décrits dans cet article, pour confirmer que votre pilote est compatible HVCI.

Outils de test personnalisés et spécifiques au domaine

Envisagez de développer des tests de sécurité personnalisés spécifiques au domaine. Pour développer des tests supplémentaires, recueillez les commentaires des concepteurs originaux du logiciel, ainsi que des ressources de développement non liées familières avec le type spécifique de pilote en cours de développement, et une ou plusieurs personnes familières avec l’analyse et la prévention des intrusions de sécurité.

Vérifiez les pilotes prêts à être expédiés avec des outils tels que BinSkim et SignTool

élément de liste de contrôle de sécurité n° 15 :Vérifier le code compilé avec les outils tels que BinSkim et SignTool avant son chargement dans l’Espace partenaires.

Utilisez des outils tels que BinSkim et SignTool pour examiner les fichiers binaires pour vérifier le code compilé avant son chargement dans l’Espace partenaires à distribuer à l’aide de Windows Update. Avoir des outils en place pour vérifier les fichiers binaires compilés, avant qu’ils ne soient soumis à la distribution, ajoute une autre couche de protection.

BinSkim

BinSkim peut identifier les pratiques de codage et de création qui peuvent potentiellement rendre le fichier binaire vulnérable. BinSkim vérifie :

  • L’utilisation d’ensembles d’outils de compilation obsolètes - Les binaires doivent être compilés avec les ensembles d’outils de compilation les plus récents possibles pour maximiser l’utilisation des atténuations de sécurité au niveau du compilateur et du système d’exploitation.
  • Paramètres de compilation non sécurisés - Les binaires doivent être compilés avec les paramètres les plus sécurisés possibles pour activer les atténuations de sécurité fournies par le système d’exploitation, maximiser les erreurs de compilateur et les rapports d’avertissements exploitables, entre autres.
  • Problèmes de signature - Les binaires signés doivent être signés avec des algorithmes cryptographiquement forts.

BinSkim est un outil open source et génère des fichiers de sortie qui utilisent le format (SARIF). BinSkim remplace l’ancien outil BinScope.

Pour plus d'informations sur BinSkim, consultez Utiliser BinSkim pour vérifier les binaires et le guide utilisateur de BinSkim .

SignTool

Utilisez SignTool pour vérifier les fichiers de pilotes signés pour la version. Pour plus d'informations, consultez Vérification de la signature d'un fichier de pilote Release-Signed et Vérification de la signature d'un fichier catalogue signé par un certificat de mise en production commercial.

Ne signez pas le code de test en production

Élément de liste de contrôle de sécurité n° 16 : Ne signez pas le code de développement, de test et de fabrication des pilotes de noyau en production.

Le code des pilotes de noyau utilisé pour le développement, les tests ou la fabrication peut inclure des capacités dangereuses posant un risque de sécurité. Ce code dangereux ne doit jamais être signé avec un certificat de confiance par Windows. Le mécanisme correct pour exécuter du code de pilote dangereux est de désactiver UEFI Secure Boot, d’activer le BCD "TESTSIGNING", et de signer le code de développement, de test et de fabrication à l’aide d’un certificat non approuvé (par exemple, un généré par makecert.exe).

Le code signé par un certificat de l’éditeur de logiciels de confiance (SPC) ou une signature des Windows Hardware Quality Labs (WHQL) ne doit pas permettre de contourner les technologies d’intégrité et de sécurité du code Windows. Avant que le code ne soit signé par un SPC de confiance ou une signature WHQL, assurez-vous d’abord qu’il est conforme aux directives de Création de pilotes en mode noyau fiable De plus, le code ne doit contenir aucun comportement dangereux, décrit ci-dessous.

Exemples de comportements dangereux :

  • Fournir la possibilité de mapper de manière arbitraire la mémoire du noyau, physique ou d’un appareil au mode utilisateur.
  • Fournir la capacité de lire ou d’écrire une mémoire arbitraire du noyau, physique ou de l’appareil, y compris l’entrée/sortie de port (E/S).
  • Fournir un accès au stockage contournant le contrôle d’accès Windows.
  • Fournir la capacité de modifier le matériel ou le firmware que le pilote n’était pas conçu pour gérer.

Effectuez une signature appropriée des pilotes de version et distribuez votre paquet de pilotes en utilisant Windows Update

Élément n°17 de la liste de contrôle de sécurité :Utilisez le portail partenaire Windows pour soumettre votre paquet de pilotes afin qu’il soit signé et distribué via Windows Update.

Avant de publier un package de pilotes au public, vous soumettez le package à des fins de certification. Pour plus d’informations, consultez Test de performances et de compatibilité et Prise en main du programme matériel.

L’utilisation de Windows Update est fortement recommandée pour la distribution des packages de pilotes. Windows Update fournit un système de distribution robuste, sécurisé, globalement mis à l’échelle mondiale et conforme à la réglementation qui doit être utilisé pour fournir des mises à jour de pilotes. Pour plus d’informations, veuillez consulter la section Distribution d’un package de pilotes.

Utilisez un déploiement progressif et la distribution de versions d’évaluation de pilotes dans le Centre Partenaire pour le Matériel Windows pour distribuer votre paquet de pilotes au sein des cercles Windows Insider définis, tout en fournissant une surveillance et une évaluation automatiques. Surveillez le déploiement du pilote en utilisant les mesures de pilotes Microsoft, telles que Pourcentage de machines sans plantage en mode noyau pour maintenir la qualité.

Pour obtenir une description des pratiques de déploiement de logiciels sécurisés, reportez-vous au document CISA "Déploiement sûr de logiciels : Comment les fabricants de logiciels peuvent garantir la fiabilité pour les clients".

Comprendre comment les pilotes sont signalés en utilisant le Centre de rapports de pilotes vulnérables et malveillants Microsoft

Élément n°18 de la liste de contrôle de sécurité : Comprenez comment les pilotes sont signalés en utilisant le Centre de rapport des pilotes vulnérables et malveillants de Microsoft

Tout le monde peut soumettre un pilote suspect au Centre de signalement des pilotes vulnérables et malveillants de Microsoft. Reportez-vous à cet article de blog pour des informations sur la soumission des pilotes pour analyse - Améliorer la sécurité du noyau avec le nouveau Centre de création de rapports de pilotes vulnérables et malveillants Microsoft

Le Centre de rapports peut analyser et examiner les pilotes Windows créés pour les architectures x86 et x64. Les pilotes vulnérables et malveillants scannés sont signalés pour analyse et investigation par l’équipe des pilotes vulnérables de Microsoft. Après confirmation des pilotes vulnérables, une notification appropriée est effectuée, ils sont ajoutés à la liste de blocage des pilotes vulnérables. Pour plus d’informations sur cela, consultez les règles de bloc de pilotes recommandées par Microsoft. Ces règles sont appliquées par défaut aux appareils dotés de l’intégrité du code protégée par l’hyperviseur (HVCI) et Windows 10 en mode S.

Passez en revue les ressources de codage sécurisé

Élément de liste de contrôle de sécurité #19 :Passez en revue ces ressources pour approfondir votre compréhension des bonnes pratiques de codage sécurisé applicables aux développeurs de pilotes.

Base de données de vulnérabilité logicielle connue de NIST

La base de données de vulnérabilité nationale (NVD) est un référentiel pouvant faire l’objet d’une recherche de failles logicielles liées à la sécurité, y compris les pilotes Windows.

Recherche dans la base de données de vulnérabilité NIST

Vue d’ensemble de la base de données des vulnérabilités nationales

Normes de codage sécurisées

Carnegie Mellon University SEI CERT - Norme de codage C : Règles pour développer des systèmes sûrs, fiables et sécurisés (PDF).

MITRE - Faiblesses abordées par le standard de codage sécurisé CERT C

Organismes de codage sécurisé

Agence de cybersécurité et de sécurité des infrastructures (CISA)

Ressources CISA

SAFECode - https://safecode.org/

Carnegie Mellon University SEI CERT

OSR

OSR fournit des services de formation et de conseil au développement de pilotes. Ces articles de la newsletter OSR mettent en évidence les problèmes de sécurité des pilotes.

Noms, descripteurs de sécurité et classes d’appareils - Rendre les objets des appareils accessibles… et SAFE

You’ve Gotta Use Protection -- Inside Driver & Device Security

Locking Down Drivers - A Survey of Techniques

Meltdown et Spectre : Qu’en est-il des pilotes ?

Étude de cas de vulnérabilité des pilotes

De l’alerte à la vulnérabilité des pilotes : l’enquête de Microsoft Defender ATP révèle une faille d’élévation de privilèges

Sécurité de la chaîne d’approvisionnement logicielle et facturation de logiciels (SBOMs)

l’initiative d’intégrité de la chaîne d’approvisionnement, de transparence et de confiance (SCITT)

Génération de listes de matériaux logiciels (SBOMs) avec SPDX chez Microsoft

Microsoft publie en open source son outil de génération de la nomenclature des logiciels (SBOM)

Livres

24 Péchés mortels de sécurité logicielle : failles de programmation et comment les corriger par Michael Howard, David LeBlanc et John Viega

Rédaction de logiciels sécurisés Deuxième Édition, Michael Howard et David LeBlanc

L’art de l’évaluation de la sécurité logicielle : identification et prévention des vulnérabilités logicielles, Mark Dowd, John McDonald et Justin Schuh

Codage sécurisé en C et C++ (Série SEI en ingénierie logicielle) 2e Édition, Robert C. Seacord

Programmation du modèle de pilote Microsoft Windows (2e Édition), Walter Oney

Développement de pilotes avec la Windows Driver Foundation (Référence du développeur), Penny Orwick et Guy Smith

Formation

Une formation en salle sur les pilotes Windows est disponible auprès de fournisseurs tels que les suivants :

Une formation en ligne sur le codage sécurisé est disponible auprès de diverses sources. Par exemple, ce cours est disponible sur Coursera :

Identifier les vulnérabilités de sécurité dans la programmation C/C++.

SAFECode propose également une formation gratuite :

SAFECode.org/training

Certification Professionnelle

Le CERT propose une Certification Professionnelle en Codage Sécurisé.

Résumé des points clés

La sécurité des pilotes est une entreprise complexe comprenant de nombreux éléments, mais voici quelques points clés à considérer :

  • Les pilotes résident dans le noyau Windows, et rencontrer un problème lors de l'exécution dans le noyau expose l'ensemble du système d'exploitation. En raison de cela, portez une attention particulière à la sécurité des pilotes et concevez en tenant compte de la sécurité.

  • Appliquez le principe du moindre privilège :

    a. Utilisez une chaîne SDDL stricte pour restreindre l’accès au pilote.

    b. Restreignez davantage les IOCTL individuels.

  • Créez un modèle de menace pour identifier les vecteurs d’attaque et considérez si quelque chose peut être encore restreint.

  • Soyez prudent avec les pointeurs intégrés provenant du mode utilisateur. Ils doivent être sondés, accédés dans un bloc try except, et ils sont sujets aux problèmes de vérification d’état (ToCToU) à moins que la valeur du buffer ne soit capturée et comparée.

  • Si vous n’êtes pas sûr, utilisez METHOD_BUFFERED comme méthode de mise en mémoire tampon IOCTL.

  • Utilisez des utilitaires d’analyse de code tels que CodeQL pour rechercher des vulnérabilités de code connues et corriger les problèmes identifiés.

  • Recherchez des réviseurs de code compétents pour identifier les problèmes que vous pourriez avoir manqués.

  • Utilisez des vérificateurs de pilotes et testez votre pilote avec de multiples entrées, y compris les cas limites.