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.

Aperçu de la sécurité des pilotes

Une faille de sécurité est toute faille permettant à un attaquant de provoquer un dysfonctionnement du pilote de manière à faire planter le système ou le rendre 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éduira les coûts de support et augmentera 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 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é.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é.Effectuer une analyse des menaces

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émenter le code compatible HVCI

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité.Suivez les bonnes pratiques en matière de code spécifiques à la technologie

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é.Gérer le contrôle d’accès au pilote

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité.Améliorer la sécurité de l’installation des appareils

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité.Exécuter une signature appropriée du pilote de mise en production

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é.Ajouter 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é.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érifier le code avec BinSkim Binary Analyzer

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité.Vérifier 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é.Passer en revue les techniques et extensions du débogueur

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é.Passer en revue les ressources de codage sécurisées

Case à cocher non marquée représentant un élément de la liste de vérification de la sécurité. Passer en revue 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é #1 : Confirmez qu’un pilote de noyau est nécessaire et qu’une approche à moindre risque, telle qu’un service Windows ou une application, n’est pas une meilleure option.

Les pilotes résident dans le noyau Windows, et tout problème lors de l’exécution dans le noyau expose l’ensemble du 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 intégrés à Windows, veuillez consulter la section 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 des informations sur l’utilisation du framework de pilote en mode utilisateur (UMDF) à moindre risque, consultez Choix d’un modèle de pilote.

Écrire un pilote à l’ancienne Windows Driver Model (WDM) est plus chronophage, coûteux, et implique presque toujours de recréer du code disponible dans les frameworks de pilotes.

Le code source des Windows Driver Framework est open source et disponible sur GitHub. C’est le même code source que celui utilisé pour construire la bibliothèque d’exécution WDF livrée dans Windows 10. Vous pouvez déboguer votre pilote plus efficacement lorsque vous pouvez suivre les interactions entre le pilote et WDF. Téléchargez-le à partir de https://github.com/Microsoft/Windows-Driver-Frameworks.

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

Élément de liste de contrôle de sécurité n° 3 : Si un pilote logiciel uniquement doit être créé, un contrôle d’accès supplémentaire doit être mis en œuvre.

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 logiciel uniquement devait s’exécuter sur un système d’un autre OEM, une instabilité ou des dommages au système pourraient en résulter. 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 rédige un pilote Legacy, ce pilote devrait trouver un autre moyen de vérifier qu’il s’exécute sur un système Fabrikam (par exemple, en examinant la table SMBIOS avant d’activer toute capacité).

Ne signez pas le code de test en production

Élément de liste de contrôle de sécurité n° 4 : 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. Pour plus d’informations sur la signature des pilotes, veuillez consulter La signature du pilote release plus loin dans cet article.

Exemples de comportements dangereux :

  • Fournir la capacité de mapper une mémoire arbitraire du noyau, physique ou de l’appareil en 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 analyse des menaces

Élément de liste de contrôle de sécurité n° 5 : Modifiez un modèle de menaces de pilote existant ou créez un modèle de menaces 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.

Suivez les directives de codage sécurisé des pilotes

Élément de liste de contrôle de sécurité n° 6 : Examinez votre code et supprimez toutes 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. Bon nombre de ces vulnérabilités logicielles connues concernent le suivi strict de l’utilisation de la mémoire pour éviter que d’autres ne surécrivent 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ésumé Pour plus d’informations
METHOD_BUFFERED Recommandé pour la plupart des situtations 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, l’E/S mis en tampon est recommandé car il offre les méthodes de mise en 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, le tampon utilisé par le gestionnaire d’E/S pour l’E/S mis en tampon n’est pas mis à zéro. Ainsi, l’application utilisateur récupère les 200 octets de données d’origine plus les 4K-200 octets de ce qui se trouvait dans le 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

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 à lire ou écrire est contraint à l’index ou à la plage attendue.

Pour plus d’informations et des exemples de code, veuillez consulter la rubrique Fournir la possibilité de lire/écrire des MSR dans les bonnes pratiques de sécurité de développement pour les développeurs de pilotes Windows.

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). Soyez conscient que lorsque le pilote accède au tampon de données utilisateur, l’utilisateur peut simultanément y accéder.

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 peuvent plus être accédées par l’application utilisateur, validez-les et opérez sur les données transmises.

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.

  • Les pilotes de périphériques doivent gérer correctement diverses requêtes E/S en mode utilisateur ainsi que noyau à noyau.

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.

Descripteurs

Objets de périphériques

IRP

WDF et IRP

Un avantage de l’utilisation de WDF est que les pilotes WDF n’accèdent généralement pas directement aux IRP. 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.

Si vous rédigez un pilote WDM, consultez les conseils suivants.

Gérez correctement les tampons E/S des IRP

Les articles suivants fournissent des informations sur la validation des valeurs d’entrée des 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

Questions de sécurité pour les codes de contrôle d'E/S

Considérez la validation des valeurs associées à un IRP, telles que les adresses et longueurs de tampon.

Si vous choisissez d’utiliser Neither E/S, sachez que contrairement à Read et Write, et contrairement à Buffered E/S et Direct E/S, lors de l’utilisation des IOCTL Neither E/S, les pointeurs et longueurs des tampons 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 à moins qu’il ne prenne réellement en charge et ne traite l’IRP. Pour des informations sur les bonnes manières de gérer les opérations de complétion des IRP, consultez la rubrique Complétion des IRP.

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. Assurez-vous de lire et de 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érez correctement les opérations de nettoyage et de fermeture des 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 requêtes de fermeture arrivent après que toutes les requêtes E/S pour l’objet fichier aient été terminées ou annulées. Pour plus d’informations, consultez les articles suivants :

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.

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.

  • Assurez-vous que les pilotes de périphériques gèrent correctement diverses requêtes E/S en mode utilisateur ainsi que noyau à noyau.

  • Assurez-vous qu’aucun filtre TDI ou LSP n’est installé par le pilote ou les packages logiciels associés lors de l’installation ou de l’utilisation.

Utilisez des fonctions sécurisées

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.

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

Élément de liste de contrôle de sécurité n° 7 : 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 empêcher les utilisateurs d’accéder de manière inappropriée aux appareils et aux 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 des appareils nommés ne sont généralement nécessaires que pour des raisons de compatibilité avec les anciennes versions, par exemple si vous avez une application qui s’attend à ouvrir l’appareil en utilisant un nom particulier ou si vous utilisez un appareil non-PNP/appareil de contrôle. 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 est de spécifier une chaîne SDDL dans votre INF. Si la chaîne SDDL n’est pas dans le fichier INF, Windows appliquera un descripteur de sécurité par défaut. Pour plus d’informations, veuillez consulter les sections Sécurisation des objets périphérique et SDDL pour les objets périphérique.

Pour plus d’informations sur le contrôle d’accès, consultez les articles suivants :

Contrôle de l’accès aux appareils 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 travaillez avec 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 articles suivants :

Contrôle de l'accès aux appareils

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

Modèle de sécurité de 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

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 les articles suivants :

Définition des codes de contrôle d'E/S

Implémentez un code compatible HVCI

Élément de liste de contrôle de sécurité n° 8 : Validez que votre pilote utilise la mémoire de manière à être compatible HVCI.

Utilisation de la mémoire et compatibilité HVCI

HVCI utilise la technologie matérielle et la virtualisation pour isoler la fonction de prise de décision d’intégrité du code (CI) du reste du système d’exploitation. Lors de l’utilisation de la sécurité basée sur la virtualisation pour isoler CI, la seule façon dont la mémoire du noyau peut devenir exécutable est par une vérification CI. Cela signifie que les pages de mémoire du noyau ne peuvent jamais être à la fois écrites 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).

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

Élément de liste de contrôle de sécurité n° 9 : Examinez les conseils spécifiques à la technologie pour votre pilote.

Systèmes de fichiers

Pour plus d’informations sur la sécurité des pilotes de systèmes de fichiers, consultez les articles suivants :

Présentation de 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

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.

Affichage

Pour des informations sur la sécurité des pilotes d’affichage, consultez la rubrique <Contenu en attente>.

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).

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

Élément de liste de contrôle de sécurité #10 : 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 pilote, 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 articles suivants :

Création d'installations d'appareils sécurisées

Lignes directrices pour l'utilisation de SetupAPI

Utilisation des fonctions d'installation des appareils

Rubriques avancées sur l’installation de périphérique et de pilote

Effectuez une révision par les pairs du code

Élément de liste de contrôle de sécurité #11 : Effectuez une révision par les pairs du code pour rechercher des problèmes non détecté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 le personnel approprié pour réviser votre code en interne, envisagez de faire appel à une aide extérieure à cette fin.

Exécutez une signature de pilote de version correcte

Élément de liste de contrôle de sécurité n° 12 : Utilisez le portail partenaire Windows pour signer correctement votre pilote pour distribution.

Avant de publier un package de pilotes au public, nous vous recommandons de soumettre le package pour certification. Pour plus d’informations, veuillez consulter les sections Test de performances et de compatibilité, Prise en main du programme matériel, Services de tableau de bord matériel et Attestation pour signer un pilote de noyau pour la version publique.

Utilisez CodeQL pour vérifier le code de votre pilote

Élément de liste de contrôle de sécurité #13 : Utilisez CodeQL pour vérifier les vulnérabilités dans le code de votre 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é avec une plateforme robuste en fait un outil inestimable pour sécuriser le code des pilotes. Pour plus d’informations, consultez CodeQL et le test du logo Static Tools.

Ajoutez des annotations SAL à votre code de pilote

Élément de liste de contrôle de sécurité #14 : Ajoutez 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. https://www.osr.com/blog/2015/02/23/sal-annotations-dont-hate-im-beautiful/

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

Élément de liste de contrôle de sécurité #15 : Utilisez Driver Verifier pour vérifier les vulnérabilités dans le code de votre 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. DV trouve des défauts dans le code du pilote qui pourraient indiquer des bugs potentiels dans les pilotes.

Driver Verifier permet de tester en direct le pilote. Driver Verifier analyse les pilotes en mode noyau Windows et les pilotes graphiques pour détecter les appels ou actions de fonction non autorisés susceptibles d’endommager le système. 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.

Notez que seuls certains types de pilotes sont pris en charge par DV. Pour plus d’informations sur les pilotes que DV peut vérifier, consultez les Pilotes pris en charge. Reportez-vous aux pages suivantes pour des informations sur les tests DV disponibles pour le type de pilote avec lequel vous travaillez.

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 l’analyseur binaire BinSkim

Élément de liste de contrôle de sécurité #16 : Suivez ces étapes pour utiliser BinSkim afin de vérifier que les options de compilation et de construction sont configurées pour minimiser les problèmes de sécurité connus.

Utilisez BinSkim pour examiner les fichiers binaires afin d’identifier les pratiques de codage et de construction qui pourraient potentiellement rendre le 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 le Guide d’utilisationde BinSkim.

Suivez ces étapes pour valider que les options de compilation de sécurité sont correctement configurées dans le code que vous expédiez.

  1. Téléchargez et installez le .NET Core SDK multiplateforme.

  2. Confirmez que Visual Studio est installé. Pour des informations sur le téléchargement et l’installation de Visual Studio, consultez la rubrique Installer Visual Studio.

  3. Il existe plusieurs options pour télécharger BinSkim, comme un package NuGet. Dans cet exemple, nous utiliserons l’option de clonage git pour télécharger depuis ici : https://github.com/microsoft/binskim et l’installer sur un PC Windows 64 bits.

  4. Ouvrez une fenêtre d’invite de commande développeur Visual Studio et créez un répertoire, par exemple C:\binskim-master.

    C:\> Md \binskim-master
    
  5. Déplacez-vous dans ce répertoire que vous venez de créer.

    C:\> Cd \binskim-master
    
  6. Utilisez la commande git clone pour télécharger tous les fichiers nécessaires.

    C:\binskim-master> git clone --recurse-submodules https://github.com/microsoft/binskim.git
    
  7. Déplacez-vous dans le nouveau répertoire binskim créé par la commande clone.

    C:\> Cd \binskim-master\binskim
    
  8. Exécutez BuildAndTest.cmd pour vous assurer que la construction de la version réussit et que tous les tests passent.

    C:\binskim-master\binskim> BuildAndTest.cmd
    
    Welcome to .NET Core 3.1!
    ---------------------
    SDK Version: 3.1.101
    
    ...
    
    C:\binskim-master\binskim\bld\bin\AnyCPU_Release\Publish\netcoreapp2.0\win-x64\BinSkim.Sdk.dll
    1 File(s) copied
    C:\binskim-master\binskim\bld\bin\AnyCPU_Release\Publish\netcoreapp2.0\linux-x64\BinSkim.Sdk.dll
    1 File(s) copied
    
    ...
    
    
  9. Le processus de construction crée un ensemble de répertoires avec les exécutables BinSkim. Déplacez-vous dans le répertoire de sortie de la version win-x64.

    C:\binskim-master\binskim> Cd \binskim-master\bld\bin\AnyCPU_Release\Publish\netcoreapp2.0\win-x64>
    
  10. Affichez l’aide pour l’option d’analyse.

C:\binskim-master\binskim\bld\bin\AnyCPU_Release\Publish\netcoreapp2.0\win-x64> BinSkim help analyze

BinSkim PE/MSIL Analysis Driver 1.6.0.0

--sympath                      Symbols path value, e.g., SRV*http://msdl.microsoft.com/download/symbols or Cache*d:\symbols;Srv*http://symweb. See
                              https://learn.microsoft.com/windows-hardware/drivers/debugger/advanced-symsrv-use for syntax information. Note that BinSkim will clear the
                              _NT_SYMBOL_PATH environment variable at runtime. Use this argument for symbol information instead.

--local-symbol-directories     A set of semicolon-delimited local directory paths that will be examined when attempting to locate PDBs.

-o, --output                   File path to which analysis output will be written.

--verbose                      Emit verbose output. The resulting comprehensive report is designed to provide appropriate evidence for compliance scenarios.

...

Définir le chemin des symboles

Si vous compilez tout le code que vous analysez sur la même machine sur laquelle vous exécutez BinSkim, vous n’avez généralement pas besoin de définir le chemin des symboles. En effet, vos fichiers de symboles sont disponibles sur la boîte locale où vous avez compilé. Si vous utilisez un système de compilation plus complexe, ou redirigez vos symboles vers un autre emplacement (pas à côté du binaire compilé), utilisez --local-symbol-directories pour ajouter ces emplacements à la recherche des fichiers de symboles. Si votre code fait référence à un binaire compilé qui ne fait pas partie de votre code, le sympath du débogueur Windows peut être utilisé pour récupérer les symboles afin de vérifier la sécurité de ces dépendances de code. Si vous trouvez un problème dans ces dépendances, vous ne pourrez peut-être pas les corriger. Mais il peut être utile d’être conscient de tout risque de sécurité possible que vous acceptez en prenant ces dépendances.

Conseil

Lors de l’ajout d’un chemin de symboles (qui référence un serveur de symboles en réseau), ajoutez un emplacement de cache local pour spécifier un chemin local pour mettre en cache les symboles. Ne pas faire cela peut compromettre considérablement les performances de BinSkim. L’exemple suivant spécifie un cache local à d:\symbols. --sympath Cache*d:\symbols;Srv*http://symweb Pour plus d’informations sur les chemins d’accès aux symboles, consultez Chemin d’accès aux symboles pour les débogueurs Windows.

  1. Exécutez la commande suivante pour analyser un binaire de pilote compilé. Mettez à jour le chemin cible pour pointer vers votre fichier .sys de pilote compilé.

    C:\binskim-master\binskim\bld\bin\AnyCPU_Release\Publish\netcoreapp2.0\win-x64> BinSkim analyze "C:\Samples\KMDF_Echo_Driver\echo.sys"
    
  2. Pour des informations supplémentaires, ajoutez l’option verbose comme ceci.

    C:\binskim-master\binskim\bld\bin\AnyCPU_Release\Publish\netcoreapp2.0\win-x64> BinSkim analyze "C:\Samples\KMDF_Echo_Driver\osrusbfx2.sys" --verbose
    

    Remarque

    L’option --verbose produira des résultats explicites de réussite/échec pour chaque vérification. Si vous ne fournissez pas verbose, vous ne verrez que les défauts détectés par BinSkim. L’option --verbose n’est généralement pas recommandée pour les systèmes d’automatisation réels en raison de l’augmentation de la taille des fichiers journaux et parce qu’elle rend plus difficile la détection des échecs individuels lorsqu’ils se produisent, car ils seront intégrés au milieu d’un grand nombre de résultats de réussite.

  3. Examinez la sortie de la commande pour rechercher d’éventuels problèmes. Cet exemple de sortie montre trois tests qui ont réussi. Des informations supplémentaires sur les règles, telles que BA2002, sont disponibles dans le Guide d’utilisation de BinSkim.

    Analyzing...
    Analyzing 'osrusbfx2.sys'...
    ...
    
    C:\Samples\KMDF_Echo_Driver\osrusbfx2.sys\Debug\osrusbfx2.sys: pass BA2002: 'osrusbfx2.sys' does not incorporate any known vulnerable dependencies, as configured by current policy.
    C:\Samples\KMDF_Echo_Driver\Debug\osrusbfx2.sys: pass BA2005: 'osrusbfx2.sys' is not known to be an obsolete binary that is vulnerable to one or more security problems.
    C:\Samples\KMDF_Echo_Driver\osrusbfx2.sys: pass BA2006: All linked modules of 'osrusbfx2.sys' generated by the Microsoft front-end satisfy configured policy (compiler minimum version 17.0.65501.17013).
    
  4. Cette sortie montre que le test BA3001 n’est pas exécuté car l’outil indique que le pilote n’est pas un binaire ELF.

    ...
    C:\Samples\KMDF_Echo_Driver\Debug\osrusbfx2.sys: notapplicable BA3001: 'osrusbfx2.sys' was not evaluated for check 'EnablePositionIndependentExecutable' as the analysis is not relevant based on observed metadata: image is not an ELF binary.
    
  5. Cette sortie montre une erreur pour le test BA2007.

    ...
    
    C:\Samples\KMDF_Echo_Driver\Debug\osrusbfx2.sys: error BA2007: 'osrusbfx2.sys' disables compiler warning(s) which are required by policy.
    A compiler warning is typically required if it has a high likelihood of flagging memory corruption, information disclosure, or double-free vulnerabilities.
    To resolve this issue, enable the indicated warning(s) by removing /Wxxxx switches (where xxxx is a warning id indicated here) from your command line, and resolve any warnings subsequently raised during compilation.
    

Pour activer ces avertissements dans Visual Studio, sous C/C++ dans les pages de propriétés du projet, supprimez les valeurs que vous ne souhaitez pas exclure dans Désactiver des avertissements spécifiques.

Capture d’écran de la boîte de dialogue pour désactiver les avertissements spécifiques dans Visual Studio 2019.

Les options de compilation par défaut dans Visual Studio pour les projets de pilotes peuvent désactiver des avertissements tels que les suivants. Ces avertissements seront signalés par BinSkim.

C4603 - « nom » : la macro n’est pas définie ou la définition est différente après l’utilisation de l’en-tête pré-compilé

C4627 - « description » : ignoré lors de la recherche de l’utilisation de l’en-tête pré-compilé

C4986 - « déclaration » : la spécification d’exception ne correspond pas à la déclaration précédente

Pour plus d’informations sur les avertissements du compilateur, consultez la section Avertissements du compilateur par version du compilateur.

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

Élément de liste de contrôle de sécurité n° 17 : Utilisez les tests de sécurité du programme de compatibilité matérielle 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é.

Passez en revue les techniques et extensions de débogueur

Élément de liste de contrôle de sécurité n° 18 : Passez en revue ces outils de débogueur et envisagez leur utilisation dans votre flux de travail de débogage de développement.

L’extension !acl formate et affiche le contenu d’une liste de contrôle d’accès (ACL). Pour plus d’informations, consultez la section Détermination de la liste de contrôle d’accès d’un objet et !acl.

L’extension !token affiche une vue mise en forme d’un objet de jeton de sécurité. Pour plus d’informations, consultez la section !token.

L’extension !tokenfields affiche les noms et les décalages des champs dans l’objet de jeton d’accès (la structure TOKEN). Pour plus d’informations, consultez la section !tokenfields.

L’extension !sid affiche l’identificateur de sécurité (SID) à l’adresse spécifiée. Pour plus d’informations, consultez !sym.

La commande !sd affiche le descripteur de sécurité à l’adresse spécifiée. Pour plus d’informations, consultez !sd.

Centre de création de rapports de pilotes vulnérables et malveillants 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 signalement peut analyser et scanner les pilotes Windows conçus 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.

Passez en revue ces ressources pour en savoir plus sur la sécurité des pilotes

Lignes directrices pour le codage sécurisé en mode noyau

Création de pilotes fiables en mode noyau

Organismes de codage sécurisé

Carnegie Mellon University SEI CERT

Carnegie Mellon University SEI CERT C Coding Standard: Rules for Developing Safe, Reliable, and Secure Systems (Édition 2016).

MITRE - Weaknesses Addressed by the CERT C Secure Coding Standard

Building Security In Maturity Model (BSIMM) - https://www.bsimm.com/

SAFECode - https://safecode.org/

Ressources CISA

OSR

OSR fournit des services de formation et de conseil en 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 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

Livres

Les 24 péchés mortels de la sécurité logicielle : les erreurs de programmation et comment les corriger par Michael Howard, David LeBlanc et John Viega

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

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 : identifier et prévenir les vulnérabilités logicielles, Mark Dowd et John McDonald

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 :

Identification des 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 avoir un problème lors de l’exécution dans le noyau expose l’ensemble du système d’exploitation. Pour cette raison, portez une attention particulière à la sécurité des pilotes et concevez avec la sécurité à l’esprit.

  • 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 de balayage de code pour rechercher les vulnérabilités de code connues et remédiez à tous 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.