Checkliste zur Treibersicherheit
Dieser Artikel enthält eine Prüfliste zur Treibersicherheit, die für Treiberentwickler konzipiert wurde, um das Risiko der Kompromittierung von Treibern zu verringern. Die Treibersicherheit ist kritisch und wirkt sich direkt auf die Zuverlässigkeit aus. Wenn Windows erkennt, dass ein falscher Speicherzugriff stattfindet, wird das Betriebssystem heruntergefahren und ein blauer Fehlerbildschirm angezeigt. Als Windows-Partner müssen Sie daran arbeiten, die erheblichen Auswirkungen zu reduzieren, die ein fehlerhafter Treiber auf das Leben unserer Kunden hat.
Weitere Informationen zu den Vorteilen der Bereitstellung eines sicheren und zuverlässigen Treibers finden Sie unter Treibersicherheitsleitfaden.
Übersicht über Treibersicherheit
Ein Sicherheitsfehler ist jeder Fehler, der es einem Angreifer ermöglicht, eine Fehlfunktion eines Treibers so zu verursachen, dass ein Angreifer nicht autorisierten Zugriff erhält, das System manipuliert oder Daten kompromittiert, was dazu führt, dass das System abstürzt oder unbrauchbar wird. Darüber hinaus können Sicherheitsrisiken im Treibercode es einem Angreifer ermöglichen, Zugriff auf den Kernel zu erhalten, wodurch die Möglichkeit entsteht, das gesamte Betriebssystem zu gefährden.
Die meisten Entwickler konzentrieren sich bei der Arbeit an ihrem Treiber darauf, dass der Treiber ordnungsgemäß funktioniert, und nicht darauf, ob ein böswilliger Angreifer versucht, Sicherheitsrisiken innerhalb ihres Codes auszunutzen. Nachdem ein Treiber veröffentlicht wurde, können Angreifer jedoch versuchen, ihn auf Sicherheitsfehler zu testen und diese zu identifizieren. Entwickler müssen diese Probleme während der Entwicklungs- und Implementierungsphase berücksichtigen, um die Wahrscheinlichkeit solcher Sicherheitsrisiken zu minimieren. Ziel ist es, alle bekannten Sicherheitsfehler zu beseitigen, bevor der Treiber veröffentlicht wird.
Die Entwicklung sicherer Treiber erfordert die Zusammenarbeit von Systemarchitekten, die potenzielle Bedrohungen für den Treiber bewusst berücksichtigen, Entwicklern, die den Code implementieren und gängige Operationen defensiv codieren, die Quelle von Exploits sein können, und Testteams, die proaktiv versuchen, Schwachstellen und Sicherheitsrisiken zu finden. Durch eine ordnungsgemäße Koordinierung all dieser Aktivitäten wird die Sicherheit des Treibers erheblich verbessert.
Neben der Vermeidung der Probleme, die mit einem Angriff auf einen Treiber verbunden sind, erhöhen viele der beschriebenen Schritte, wie eine genauere Verwendung des Kernelspeichers, die Zuverlässigkeit Ihres Treibers. Dies reduziert Supportkosten und erhöht die Kundenzufriedenheit mit Ihrem Produkt. Das Ausführen der Aufgaben in der nachstehenden Checkliste trägt dazu bei, all diese Ziele zu erreichen.
Sicherheits-Checkliste:Erledigen Sie die in jedem dieser Themen beschriebenen Sicherheitsaufgaben.
Bestätigen, dass ein Kerneltreiber erforderlich ist
Verwenden der Treiberframeworks
Verwalten der Treiberzugriffssteuerung
Steuern des Zugriffs auf reine Softwaretreiber
Befolgen von Richtlinien für sicheres Codieren von Treibern
Implementieren von HVCI-kompatiblem Code
den bewährten Methoden für technologiespezifischen Code folgen
SAL-Anmerkungen zu Ihrem Treibercode hinzufügen
Durchführen einer Peer-Codeüberprüfung
Durchführen einer Bedrohungsanalyse
Verwenden Sie CodeQL, um Ihren Treibercode zu überprüfen
Verwenden Sie den Treiberüberprüfer, um auf Sicherheitsrisiken zu prüfen.
Überprüfen von Code mit den Tests des Hardwarekompatibilitätsprogramms
Überprüfen Sie die Bereitschaft zur Auslieferung von Treibern mit Tools wie BinSkim und SignTool
Testtreibercode nicht in der Produktion signieren
Überprüfung sicherer Codierungsressourcen
Überprüfen der Zusammenfassung der wichtigsten Erkenntnisse
Bestätigen, dass ein Kerneltreiber erforderlich ist
Sicherheitsprüflistenelement Nr. 1:Bestätigen Sie, dass ein Kerneltreiber erforderlich ist und dass ein niedrigerer Risikoansatz, z. B. Windows-Dienst oder -App, keine bessere Option ist.
Kerneltreiber befinden sich im Windows-Kernel, und ein Problem bei der Ausführung im Kernel kann das gesamte Betriebssystem gefährden. Falls eine andere Option verfügbar ist, ist sie wahrscheinlich kostengünstiger und mit weniger Risiken verbunden als das Erstellen eines neuen Kerneltreibers.
Weitere Informationen zur Verwendung der integrierten Windows-Treiber finden Sie unter Müssen Sie einen Treiber schreiben?.
Informationen zur Verwendung von Hintergrundaufgaben finden Sie unter Unterstützung Ihrer App durch Hintergrundaufgaben.
Informationen zur Verwendung von Windows-Diensten finden Sie unter Dienste.
Verwenden der Treiberframeworks
Sicherheits-Checkliste Punkt 2:Nutzen Sie die Frameworks für Treiber, um den Umfang Ihres Codes zu reduzieren und seine Zuverlässigkeit und Sicherheit zu erhöhen.
Verwenden Sie Windows-Treiberframeworks , um die Größe Ihres Codes zu verringern und die Zuverlässigkeit und Sicherheit zu erhöhen. Erste Schritte finden Sie unter Verwendung von WDF zum Entwickeln eines Treibers. Informationen zur Verwendung des risikoärmeren Benutzermodustreiber-Frameworks (UMDF) finden Sie unter Auswählen eines Treibermodells.
Das Schreiben eines altmodischen Windows-Treibermodells (Windows Driver Model, WDM) Treiber ist zeitaufwändiger, kostspieliger und umfasst das Neustellen von Code, der in den Treiberframeworks verfügbar ist.
Der WDF-Quellcode (Windows Driver Framework) ist Open Source und ist auf GitHub verfügbar. Dies ist der gleiche WDF-Quellcode, der in Windows enthalten ist. Sie können den Treiber effektiver debuggen, wenn Sie die Interaktionen zwischen dem Treiber und WDF verfolgen können. Laden Sie es hier herunter: https://github.com/Microsoft/Windows-Driver-Frameworks.
DMF – Treibermodul-Framework
Berücksichtigen Sie die Verwendung des Driver Module Framework (DMF) in Ihrem Treiberprojekt. Das vom Microsoft Surface-Team entwickelte DMF ist ein Framework, das die Erstellung von WDF-Objekten ermöglicht, die als DMF-Module bezeichnet werden. Der Code für diese DMF-Module kann zwischen verschiedenen Treibern gemeinsam genutzt werden. Darüber hinaus bietet DMF eine Bibliothek von DMF-Modulen, die für Treiber entwickelt wurden, und ermöglichen Code-Wiederverwendung für Aufgaben wie Thread- und E/A-Verwaltung. Ein DMF-Modul wird verwendet, um Treiberaufgaben in kleinere Einheiten zu kapseln. Jedes Modul ist eigenständig und verfügt über eigenen Code, Kontext und Rückrufe, wodurch die Wiederverwendung vereinfacht wird. Weitere Informationen finden Sie unter Einführung in das Driver Module Framework und der GitHub-Site-Dokumentation.
Verwalten der Steuerung des Treiberzugriffs
Sicherheitsprüflistenelement Nr. 3:Überprüfen Sie Ihren Treiber, um sicherzustellen, dass Sie den Zugriff ordnungsgemäß steuern.
Verwalten der Steuerung des Treiberzugriffs – WDF
Treiber müssen verhindern, dass Benutzer unberechtigterweise auf die Geräte und Dateien eines Computers zugreifen. Um nicht autorisierten Zugriff auf Geräte und Dateien zu verhindern, müssen Sie:
Geräteobjekte nur bei Bedarf benennen. Benannte Geräteobjekte sind in der Regel nur aus Legacy-Gründen erforderlich, z. B. wenn Sie über eine Anwendung verfügen, die erwartet, dass das Gerät mit einem bestimmten Namen geöffnet wird, oder wenn Sie ein nicht-PNP-Gerät/Steuerungsgerät verwenden. Beachten Sie, dass WDF-Treiber ihre PnP-Geräte-FDO nicht benennen müssen, um eine symbolische Verknüpfung mit WdfDeviceCreateSymbolicLink zu erstellen.
Sicherer Zugriff auf Geräteobjekte und Schnittstellen.
Damit Anwendungen oder andere WDF-Treiber auf Ihr PnP-Geräte-PDO zugreifen können, sollten Sie Geräteschnittstellen verwenden. Weitere Informationen finden Sie unter Geräteschnittstellen verwenden. Eine Geräteschnittstelle dient als symbolische Verknüpfung mit dem PDO Ihres Gerätestapels.
Eine der besseren Methoden zum Steuern des Zugriffs auf die PDO besteht darin, eine SDDL-Zeichenfolge in Ihrem INF anzugeben. Wenn die SDDL-Zeichenfolge nicht in der INF-Datei enthalten ist, wendet Windows einen Standardsicherheitsdeskriptor an. Weitere Informationen finden Sie unter Sichern von Geräteobjekten und SDDL für Geräteobjekte.
Weitere Informationen zum Steuern des Zugriffs finden Sie in den folgenden Themen:
Kontrolle des Zugriffs auf Geräte in KMDF-Treibern
Namen, Sicherheitsdeskriptoren und Geräteklassen – Erstellen barrierefreier Geräteobjekte... and SAFE aus dem Januar 2017 NT Insider Newsletter veröffentlicht von OSR.
Verwalten der Steuerung des Treiberzugriffs – WDM
Wenn Sie mit einem WDM-Treiber arbeiten und ein benanntes Geräteobjekt verwendet haben, können Sie IoCreateDeviceSecure verwenden und eine SDDL zum Sichern angeben. Wenn Sie IoCreateDeviceSecure implementieren, geben Sie immer eine benutzerdefinierte Klassen-GUID für DeviceClassGuid an. Sie sollten hier keine vorhandene Klassen-GUID angeben. Dies hätte das Potenzial, Sicherheitseinstellungen oder Kompatibilität für andere Geräte, die zu dieser Klasse gehören, zu beeinträchtigen. Weitere Informationen finden Sie unter WdmlibIoCreateDeviceSecure.
Weitere Informationen finden Sie in den folgenden Themen:
Steuern des Geräte-Namespace-Zugriffs
Windows-Sicherheitsmodell für Entwickler von Treibern
Sicherheits-IDs (SIDs)-Risikohierarchie
Im folgenden Abschnitt wird die Risikohierarchie der allgemeinen SIDs beschrieben, die im Treibercode verwendet werden. Allgemeine Informationen zu SDDL finden Sie unter SDDL für Geräteobjekte, SID-Zeichenfolgen und SDDL-Zeichenfolgensyntax.
Es ist wichtig zu verstehen, dass, wenn Aufrufer mit geringeren Privilegien auf den Kernel zugreifen dürfen, das Coderisiko erhöht wird. In diesem Zusammenfassungsdiagramm erhöht sich das Risiko, wenn Sie SIDs mit niedrigeren Berechtigungen Zugriff auf Ihre Treiberfunktionalität gewähren.
SY (System)
\/
BA (Built-in Administrators)
\/
LS (Local Service)
\/
BU (Built-in User)
\/
AC (Application Container)
Konfigurieren Sie nach dem allgemeinen Sicherheitsprinzip der geringsten Rechte nur die Mindestzugriffsebene, die für die Funktion des Treibers erforderlich ist.
WDM Granular IOCTL-Sicherheitskontrolle
Ein IOCTL (Input/Output Control) in Windows ist ein Systemaufruf für gerätespezifische Eingabe-/Ausgabevorgänge. IOCTLs werden von Anwendungen verwendet, um mit Gerätetreibern zu kommunizieren, sodass sie Befehle senden oder Informationen von der Hardware anfordern können. Weitere Informationen finden Sie unter Einführung in E/A-Steuerungscodes und Beispiel-E/A-Anforderung – Eine Übersicht.
Um die Sicherheit weiter zu verwalten, wenn IOCTLs von Benutzermodus-Aufrufern gesendet werden, kann der Treibercode die IoValidateDeviceIoControlAccess-Funktion enthalten. Mit dieser Funktion kann ein Treiber Zugriffsrechte überprüfen. Wenn ein IOCTL empfangen wird, kann ein Treiber IoValidateDeviceIoControlAccess aufrufen und FILE_READ_ACCESS, FILE_WRITE_ACCESS oder beides angeben.
Die Implementierung präziser IOCTL-Sicherheitskontrollen ersetzt nicht die Notwendigkeit, den Treiberzugriff mithilfe der oben beschriebenen Techniken zu verwalten.
Weitere Informationen finden Sie unter Definieren von E/A-Steuerungscodes und Sicherheitsprobleme für E/A-Steuerungscodes.
Steuern des Zugriffs auf reine Softwaretreiber
Sicherheitsprüflistenelement Nr. 4:Wenn ein nur softwaregeschützter Treiber erstellt werden soll, muss zusätzliche Zugriffssteuerung implementiert werden.
Nur-Software-Kerneltreiber verwenden kein Plug-and-Play (PnP), um bestimmten Hardware-IDs zugeordnet zu werden und können auf jedem PC ausgeführt werden. Ein solcher Treiber könnte für andere Zwecke als die ursprünglich beabsichtigten verwendet werden, wodurch ein Angriffsvektor erstellt wird.
Da Nur-Software-Kerneltreiber zusätzliche Risiken enthalten, müssen sie auf bestimmte Hardware beschränkt sein (z. B. mithilfe einer eindeutigen PnP-ID zum Aktivieren der Erstellung eines PnP-Treibers oder durch Überprüfen der SMBIOS-Tabelle auf das Vorhandensein bestimmter Hardware).
Stellen Sie sich beispielsweise vor, OEM Fabrikam möchte einen Treiber verteilen, der eine Übertaktungshilfsprogramm für ihre Systeme ermöglicht. Wenn dieser reine Softwaretreiber auf einem System von einem anderen OEM ausgeführt werden sollte, kann dies zu Systeminstabilität oder Beschädigung führen. Fabrikam-Systeme sollten eine eindeutige PnP-ID enthalten, um die Erstellung eines PnP-Treibers zu ermöglichen, der auch über Windows Update aktualisierbar ist. Wenn dies nicht möglich ist und Fabrikam einen Legacy-Treiber entwickelt, sollte dieser Treiber eine andere Methode finden, um zu überprüfen, ob er auf einem Fabrikam-System ausgeführt wird (z. B. durch Untersuchung der SMBIOS-Tabelle, bevor Funktionen aktiviert werden).
Befolgen Sie die Richtlinien zur sicheren Programmierung von Treibern.
Sicherheitsprüflistenelement Nr. 5:Überprüfen Sie Ihren Code, und entfernen Sie alle bekannten Coderisiken.
Die Kernaktivität beim Erstellen sicherer Treiber besteht darin, Bereiche im Code zu identifizieren, die geändert werden müssen, um bekannte Softwarerisiken zu vermeiden. Viele dieser bekannten Softwarerisiken befassen sich mit der strikten Verfolgung der Verwendung des Speichers, um Probleme mit anderen zu vermeiden, die überschreiben oder anderweitig die von Ihrem Treiber verwendeten Speicherspeicherorte gefährden.
Code-Scanning-Tools wie CodeQL und treiberspezifische Tests können verwendet werden, um einige, aber nicht alle dieser Schwachstellen zu finden. Diese Tools und Tests werden weiter unten in diesem Thema beschrieben.
Arbeitsspeicherpuffer
Überprüfen Sie immer die Größe der Eingabe- und Ausgabepuffer, um sicherzustellen, dass die Puffer alle angeforderten Daten enthalten können. Weitere Informationen finden Sie unter Fehler beim Überprüfen der Größe von Puffern.
Initialisieren Sie alle Ausgabepuffer ordnungsgemäß mit Nullen, bevor Sie sie an den Aufrufer zurückgeben. Weitere Informationen finden Sie unter Fehler beim Initialisieren von Ausgabepuffern.
Überprüfen Sie Puffer mit variabler Länge. Weitere Informationen finden Sie unter Fehler beim Überprüfen von Puffern mit variabler Länge. Weitere Informationen zum Arbeiten mit Puffern und zum Verwenden von ProbeForRead zur Überprüfung der Adresse eines Puffers finden Sie unter Pufferbehandlung.
Verwenden Sie die geeignete Methode für den Zugriff auf Datenpuffer mit IOCTLs
Eine der Hauptaufgaben eines Windows-Treibers ist das Übertragen von Daten zwischen Benutzermodusanwendungen und den Geräten eines Systems. Die drei Methoden für den Zugriff auf Datenpuffer sind in der folgenden Tabelle dargestellt.
IOCTL-Puffertyp | Zusammenfassung | Weitere Informationen |
---|---|---|
METHOD_BUFFERED | Empfohlen für die meisten Situationen | Verwenden von gepufferten E/A-Vorgängen |
METHOD_IN_DIRECT oder METHOD_OUT_DIRECT | Wird in einigen Hochgeschwindigkeits-HW-E/A-Vorgängen verwendet | Verwenden der direkten E/A-Vorgänge |
METHOD_NEITHER | Nach Möglichkeit vermeiden | Verwenden weder gepufferter noch direkter E/A |
Im Allgemeinen wird gepufferte E/A empfohlen, da sie die sichersten Puffermethoden bereitstellt. Aber auch bei der Verwendung von gepufferten E/A-Vorgängen bestehen Risiken, z. B. eingebettete Zeiger, die entschärft werden müssen.
Weitere Informationen zum Arbeiten mit Puffern in IOCTLs finden Sie unter Methoden für den Zugriff auf Datenpuffer.
Fehler bei Verwendung von IOCTL gepufferten E/A
Überprüfen Sie die Größe der IOCTL-bezogenen Puffer. Weitere Informationen finden Sie unter Fehler beim Überprüfen der Größe von Puffern.
Initialisieren Sie die Ausgabepuffer richtig. Weitere Informationen finden Sie unter Fehler beim Initialisieren von Ausgabepuffern.
Überprüfen Sie Puffer mit variabler Länge ordnungsgemäß. Weitere Informationen finden Sie unter Fehler beim Überprüfen von Puffern mit variabler Länge.
Achten Sie bei Der Verwendung von gepufferten E/A-Vorgängen darauf, die richtige Länge für den OutputBuffer im Strukturinformationsfeld IO_STATUS_BLOCK zurückzugeben. Geben Sie die Länge nicht nur direkt aus einer READ-Anforderung zurück. Nehmen wir beispielsweise eine Situation, in der die zurückgegebenen Daten aus dem Benutzerbereich angeben, dass ein 4K-Puffer vorhanden ist. Wenn der Treiber tatsächlich nur 200 Byte zurückgeben soll, aber stattdessen nur 4K im Informationsfeld zurückgibt, ist eine Sicherheitslücke zur Offenlegung von Informationen aufgetreten. Dieses Problem tritt auf, da in früheren Versionen von Windows der Puffer, den der E/A-Manager für gepufferte E/A verwendet, nicht null ist. Daher erhält die Benutzer-App die ursprünglichen 200 Byte von Daten plus 4K-200 Bytes aller Elemente im Puffer (nicht ausgelagerte Poolinhalte). Dieses Szenario kann bei allen Verwendungen von gepufferten E/A und nicht nur bei IOCTLs auftreten.
Fehler in direkten IOCTL E/A-Vorgängen
Korrekte Behandlung von Puffern mit Null-Länge. Weitere Informationen finden Sie unter Fehler in direkten E/A-Vorgängen.
Fehler beim Verweisen auf Benutzerraumadressen
Überprüfen von Zeigern, die in gepufferten E/A-Anforderungen eingebettet sind. Weitere Informationen finden Sie unter Fehler beim Verweisen auf Benutzerraumadressen.
Überprüfen Sie alle Adressen im Benutzerbereich, bevor Sie versuchen, sie zu verwenden, mithilfe von APIs wie ProbeForRead-.
Der Treibercode muss den Arbeitsspeicher korrekt verwenden.
Alle Treiberpoolzuweisungen müssen sich im nicht-ausführbaren Pool (NX) befinden. Die Verwendung von NX-Speicherpools ist inhärent sicherer als die Verwendung von ausführbaren nicht ausgelagerten Pools (NP) und bietet einen besseren Schutz vor Überlaufangriffen.
Um Treibern die Unterstützung der HVCI-Virtualisierung zu ermöglichen, gibt es zusätzliche Speicheranforderungen. Weitere Informationen finden Sie unter Implementieren von HVCI-kompatiblem Code weiter unten in diesem Artikel.
TOCTOU-Sicherheitsrisiken
Es gibt eine potenziellen Sicherheitsanfälligkeit beim Zeitpunkt der Überprüfung gegenüber der Verwendungszeit (time of check to time of use, TOCTOU) bei Verwendung direkter E/A-Vorgänge (für IOCTLs oder für Lese-/Schreibzugriff). Seien Sie sich bewusst, dass, während der Treiber auf den Benutzerdatenpuffer zugreift, die benutzende App gleichzeitig auf denselben Datenpuffer zugreifen kann.
Um dieses Risiko zu verwalten, kopieren Sie alle Parameter, die vom Benutzerdatenpuffer zur Überprüfung in den Speicher kopiert werden müssen, auf den ausschließlich über den Kernelmodus zugegriffen werden kann (z. B. Stapel oder Pool). Sobald der Zugriff auf die Daten von der Benutzeranwendung nicht möglich ist, überprüfen Sie die Daten, und arbeiten Sie dann mit den daten, die übergeben wurden.
MSR-modellspezifische Registerlese- und Schreibvorgänge
Compiler-Intrinsiken, wie __readmsr und __writemsr, können für den Zugriff auf die modellspezifischen Register verwendet werden. Wenn dieser Zugriff erforderlich ist, muss der Treiber immer überprüfen, ob das Register zum Lesen oder Schreiben auf den erwarteten Index oder Bereich beschränkt ist.
Weitere Informationen und Code-Beispiele finden Sie unter Bereitstellen der Möglichkeit, MSRs zu lesen/schreiben in Bewährte Verfahren zur Einschränkung von hochprivilegiertem Verhalten in Kernel-Modus-Treibern.
Ziehpunkte
- Überprüfen Sie Handles, die zwischen Benutzermodus und Kernelmodusspeicher übergeben werden. Weitere Informationen finden Sie unter Handle-Verwaltung and Fehler bei der Validierung von Objekt-Handles.
Geräteobjekte
Sichere Geräteobjekte. Weitere Informationen finden Sie unter Sichern von Geräteobjekten.
Geräteobjekte überprüfen. Weitere Informationen finden Sie unter Fehler bei der Validierung von Geräteobjekten.
IRPs
Windows-E/A-Anforderungspakete (IRPs) werden verwendet, um E/A-Anforderungen zwischen betriebssystem- und Kernelmodustreibern zu kommunizieren und alle erforderlichen Informationen im Paket zu kapseln. IRPs erleichtern die asynchrone Datenübertragung, Synchronisierung und Fehlerbehandlung, um eine effiziente und zuverlässige Kommunikation mit Hardwaregeräten sicherzustellen. Weitere Informationen finden Sie unter I/O Request Packets und Überblick über das Windows I/O-Modell.
WDF und IRPs
Ein Vorteil der Verwendung von WDF besteht darin, dass WDF-Treiber in der Regel nicht direkt auf IRPs zugreifen. Beispielsweise konvertiert das Framework die WDM IRPs, die Lese-, Schreib- und Geräte-E/A-Steuerungsvorgänge darstellen, in Framework-Anforderungsobjekte, die KMDF/UMDF in E/A-Warteschlangen empfangen. Wann immer möglich, wird die Verwendung von WDF dringend empfohlen.
Wenn Sie einen WDM-Treiber schreiben müssen, lesen Sie die folgenden Anleitungen.
Ordnungsgemäße Verwaltung von IRP-E/A-Puffern
Lesen Sie die folgenden Themen, in denen beschrieben wird, wie IRP-Eingabewerte überprüft werden:
DispatchReadWrite mit gepufferten E/A-Vorgängen
Fehler in gepufferten E/A-Vorgängen
DispatchReadWrite mit direkten E/A-Vorgängen
Fehler in direkten E/A-Vorgängen
Überprüfen Sie Werte, die einem IRP zugeordnet sind, z. B. Pufferadressen und -längen.
Wenn Sie sich für die Verwendung von „Keine E/A“ entschieden haben, sollten Sie beachten, dass im Gegensatz zu Lesen und Schreiben und im Gegensatz zu Gepufferte E/A und Direkte E/A bei der Verwendung von Keine E/A-IOCTL die Pufferzeiger und -längen nicht vom E/A-Manager validiert werden.
Ordnungsgemäße Verarbeitung von IRP-Vervollständigungsvorgängen
Ein Treiber darf niemals ein IRP mit einem Statuswert von STATUS_SUCCESS
abschließen, es sei denn, er unterstützt und verarbeitet das IRP. Informationen zu den richtigen Methoden zum Behandeln von IRP-Vervollständigungsvorgängen finden Sie unter Abschließen von IRPs.
Verwalten des ausstehenden Zustands von Treiber-IRP
Der Treiber sollte das ausstehende IRP markieren, bevor das IRP gespeichert wird, und er sollte sowohl den Aufruf von IoMarkIrpPending als auch die Zuordnung in einer Interlocked-Sequenz einschließen. Weitere Informationen finden Sie unter Fehler beim Überprüfen des Zustands eines Treibers und anhalten eingehender IRPs, wenn ein Gerät angehalten wird.
Ordnungsgemäßes Behandeln von IRP-Abbruchvorgängen
Abbruchvorgänge können schwierig sein, ordnungsgemäß zu codieren, da sie in der Regel asynchron ausgeführt werden. Probleme im Code, der Abbruchvorgänge behandelt, können lange unbemerkt bleiben, da dieser Code in der Regel nicht häufig in einem laufenden System ausgeführt wird. Lesen und verstehen Sie alle Informationen, die unter IRPs abbrechen bereitgestellt werden. Achten Sie besonders auf die Synchronisierung von IRP-Abbrüchen und Punkte, die beim Abbrechen von IRPs berücksichtigt werden sollten.
Eine empfohlene Möglichkeit, um die Synchronisierungsprobleme zu minimieren, die mit Abbruchvorgängen verbunden sind, besteht darin, eine abbruchsichere IRP-Warteschlange zu implementieren.
Ordnungsgemäße Behandlung von IRP-Bereinigungs- und Schließvorgängen
Achten Sie darauf, dass Sie den Unterschied zwischen den Anforderungen IRP_MJ_CLEANUP und IRP_MJ_CLOSE verstehen. Bereinigungsanforderungen treffen ein, nachdem eine Anwendung alle Handles für ein Dateiobjekt schließt, aber manchmal bevor alle E/A-Anforderungen abgeschlossen wurden. Schließanforderungen treffen ein, nachdem alle E/A-Anforderungen für das Dateiobjekt abgeschlossen oder abgebrochen wurden. Weitere Informationen finden Sie in den folgenden Themen:
DispatchCreate-, DispatchClose- und DispatchCreateClose-Routinen
Fehler beim Behandeln von Bereinigungs- und Schließvorgängen
Weitere Informationen zum ordnungsgemäßen Behandeln von IRPs finden Sie unter Zusätzliche Fehler beim Behandeln von IRPs.
Sichere Funktionen nutzen
Sichere String-Funktionen nutzen. Weitere Informationen finden Sie unter Verwendung von sicheren String-Funktionen.
Sichere arithmetische Funktionen nutzen. Weitere Informationen finden Sie unter Safe Integer Library Routines.
Sichere Konvertierungsfunktionen nutzen. Weitere Informationen finden Sie unter Zusammenfassung der Kernel-Mode sicheren Ganzzahlfunktionen.
Andere Sicherheitsprobleme
Verwenden Sie eine Sperre oder eine Interlocked-Sequenz, um Racebedingungen zu verhindern. Weitere Informationen finden Sie unter Fehler in einer Multiprozessorumgebung.
Stellen Sie sicher, dass während der Installation oder Verwendung keine TDI-Filter (Network Transport Driver Interface) oder LSPs (Layered Service Providers) vom Treiber oder den zugehörigen Softwarepaketen installiert werden. Verwenden Sie stattdessen moderne APIs, z. B. die Windows-Filterplattform (WFP) .
Zusätzliche Coderisiken
Zusätzlich zu den möglichen Sicherheitsrisiken, die hier behandelt werden, enthält dieser Artikel zusätzliche Informationen zur Verbesserung der Sicherheit des Kernelmodustreibercodes: Erstellen von zuverlässigen Kernelmodustreibern.
Weitere Informationen zur sicheren C- und C++-Codierung finden Sie unter Sichere Codierungsressourcen am Ende dieses Artikels.
Implementieren von HVCI-kompatiblem Code
Sicherheitsprüflistenelement Nr. 6:Überprüfen, ob Ihr Treiber Arbeitsspeicher verwendet, damit er HVCI-kompatibel ist.
Speicherintegrität und HVCI-Kompatibilität
Speicherintegrität, auch als hypervisorgeschützte Codeintegrität (Hypervisor protected Code Integrity, HVCI) bezeichnet, verwendet Hardwaretechnologie und Virtualisierung, um die Entscheidungsfindungsfunktion (Code Integrity, CI) vom rest des Betriebssystems zu isolieren. Wenn virtualisierungsbasierte Sicherheit zum Isolieren von CI verwendet wird, kann der Kernelspeicher nur durch eine CI-Überprüfung ausführbar werden. Dies bedeutet, dass Kernelspeicherseiten niemals gleichzeitig beschreibbar und ausführbar (W+X) sein können und dass ausführbarer Code nicht direkt modifiziert werden kann.
Um HVCI-kompatiblen Code zu implementieren, stellen Sie sicher, dass ihr Treibercode folgendes ausführt:
- Aktiviert NX standardmäßig
- Verwendet NX-APIs/Flags für die Speicherzuweisung (NonPagedPoolNx)
- Verwendet keine Abschnitte, die sowohl beschreibbar als auch ausführbar sind
- Versucht nicht, den ausführbaren Systemspeicher direkt zu ändern
- Verwendet keinen dynamischen Code im Kernel
- Datendateien werden nicht als ausführbare Dateien geladen.
- Die Abschnittsausrichtung ist ein Vielfaches von 0x1000 (PAGE_SIZE). Zum Beispiel, DRIVER_ALIGNMENT=0x1000
Weitere Informationen zur Verwendung des Tools und einer Liste mit inkompatiblen Speicheraufrufen finden Sie unter Implementieren von HVCI-kompatiblem Code.
Weitere Informationen zum zugehörigen Systemgrundlagen-Sicherheitstest finden Sie unter HyperVisor Code Integrity Readiness Test und Hypervisor-Protected Code Integrity (HVCI).
Verbessern der Geräteinstallationssicherheit
Sicherheitscheckliste Punk 7:Überprüfen Sie die Anleitung zur Erstellung und Installation von Treibern, um sicherzustellen, dass Sie die bewährten Verfahren einhalten.
Wenn Sie den Code erstellen, der Das Treiberpaket installiert, müssen Sie sicherstellen, dass die Installation Ihres Geräts immer sicher ausgeführt wird. Eine sichere Geräteinstallation ist dadurch gekennzeichnet, dass sie Folgendes umfasst:
- Schränkt den Zugriff auf das Gerät und die zugehörigen Geräteschnittstellenklassen ein
- Schränkt den Zugriff auf die Treiberdienste, die für das Gerät erstellt wurden, ein
- Schützt Treiberdateien vor Änderung oder Löschung
- Beschränkt den Zugriff auf die Registrierungseinträge des Geräts
- Beschränkt den Zugriff auf die WMI-Klassen des Geräts
- Verwendet SetupAPI-Funktionen ordnungsgemäß
Weitere Informationen finden Sie in den folgenden Themen:
Das Erstellen sicherer Geräteinstallationen
Richtlinien für die Verwendung von SetupAPI
Verwenden von Geräteinstallationsfunktionen
Erweiterte Themen zur Geräte- und Treiberinstallation
Befolgen von bewährten Methoden für technologiespezifischen Code
Sicherheitsprüflistenelement Nr. 8:Überprüfen Sie die folgenden technologiespezifischen Anleitungen für Ihren Treiber.
Dateisysteme
Weitere Informationen zur Sicherheit des Dateisystemtreibers finden Sie in den folgenden Themen:
Einführung in die Sicherheit von Dateisystemen
Sicherheitsprobleme bei Dateisystemen
Sicherheitsfunktionen für Dateisysteme
Koexistenz mit anderen Dateisystem-Filtertreibern
Microsoft Virus Initiative
Die Microsoft Virus Initiative (MVI) hilft Organisationen, die Sicherheitslösungen zu verbessern, auf die sich unsere Kunden verlassen, um sie sicher zu halten. Microsoft bietet Tools, Ressourcen und Wissen, um bessere Erfahrungen mit hoher Leistung, Zuverlässigkeit und Kompatibilität zu unterstützen. Microsoft arbeitet mit MVI-Partnern zusammen, um sichere Bereitstellungsmethoden (Safe Deployment Practices, SDP) zu definieren und zu befolgen, um die Sicherheit und Resilienz unserer gegenseitigen Kunden zu unterstützen.
Wenn Sie ein Antivirenanbieter sind, lesen Sie Microsoft Virus Initiative, um zu erfahren, wie Sie MVI beitreten, um weitere Unterstützung bei der Softwarebereitstellung zu erhalten. Informationen dazu, wie Sicherheitsanbieter die integrierten Sicherheitsfunktionen von Windows für erhöhte Sicherheit und Zuverlässigkeit besser nutzen können, finden Sie unter bewährten Methoden für die Integration und Verwaltung von Sicherheitstools.
NDIS – Netzwerk
Informationen zur NDIS-Treibersicherheit finden Sie unter Sicherheitsprobleme für Netzwerktreiber.
Drucker
Informationen zur Sicherheit von Druckertreibern finden Sie unter Sicherheitsüberlegungen zu V4-Druckertreibern.
Sicherheitsprobleme bei Windows Image Acquisition (WIA)-Treibern
Informationen zur WIA-Sicherheit finden Sie unter Sicherheitsprobleme bei Windows Image Acquisition (WIA)-Treibern.
Fügen Sie SAL-Anmerkungen zu Ihrem Treiber-Code hinzu.
Sicherheitsprüflistenelement Nr. 9:Fügen Sie Ihrem Treibercode SAL-Anmerkungen hinzu.
Die Quellcodeanmerkungssprache (Source-Code Annotation Language, SAL) bietet eine Reihe von Anmerkungen, mit denen Sie beschreiben können, wie eine Funktion ihre Parameter verwendet, welche Annahmen sie darüber macht und welche Garantien sie bei ihrer Beendigung gibt. Die Anmerkungen sind in der Headerdatei sal.h
definiert. Visual Studio-Codeanalyse für C++ verwendet SAL-Anmerkungen, um die Analyse von Funktionen zu ändern. Weitere Informationen zur Entwicklung von SAL 2.0 für Windows-Treiber finden Sie unter SAL 2.0 Annotationen für Windows-Treiber und Verwenden von SAL-Annotationen zur Reduzierung von C/C++-Codefehlern.
Allgemeine Informationen zu SAL finden Sie in diesem Artikel, der über OSR zur Verfügung steht. SAL Anmerkungen: Hass mich nicht, weil ich schön bin
Durchführen einer Peer-Codeüberprüfung
Sicherheitsprüflistenelement Nr. 10: Durchführen einer Peer-Codeüberprüfung, um nach Problemen zu suchen, die von den anderen Tools und Prozessen nicht angezeigt werden
Suchen Sie kompetente Codeprüfer, um Probleme zu finden, die Sie möglicherweise übersehen haben. Eine zweites Paar Augen wird häufig Probleme sehen, die Sie möglicherweise übersehen haben.
Wenn Sie nicht über geeignete Mitarbeiter verfügen, um Ihren Code intern zu überprüfen, sollten Sie externe Hilfe zu diesem Zweck in Betracht ziehen.
Durchführen einer Bedrohungsanalyse
Sicherheitsprüflistenelement Nr. 11:Entweder ein vorhandenes Treiber-Bedrohungsmodell ändern oder ein benutzerdefiniertes Bedrohungsmodell für Ihren Treiber erstellen.
Unter Berücksichtigung der Sicherheit besteht eine übliche Vorgehensweise darin, spezifische Bedrohungsmodelle zu erstellen, die versuchen, die Arten von möglichen Angriffen zu beschreiben. Diese Technik ist beim Entwerfen eines Treibers nützlich, da er den Entwickler zwingt, potenzielle Angriffsvektoren für einen Treiber im Voraus zu berücksichtigen. Nachdem der Identifizierung potenzieller Bedrohungen, kann ein Treiberentwickler dann Mittel zur Verteidigung gegen diese Bedrohungen in Betracht ziehen, um die Gesamtsicherheit der Treiberkomponente zu stärken.
Dieser Artikel enthält treiberspezifische Anleitungen zum Erstellen eines einfachen Bedrohungsmodells: Bedrohungsmodellierung für Treiber. Der Artikel enthält ein Beispiel für ein Bedrohungsmodelldiagramm für Treiber, das als Ausgangspunkt für Ihren Treiber verwendet werden kann.
Bewährte Methoden für den Security Development Lifecycle (SDL) und zugehörige Tools können von IHVs und OEMs verwendet werden, um die Sicherheit ihrer Produkte zu verbessern. Weitere Informationen finden Sie unter SDL-Empfehlungen für OEMs.
Verwenden Sie CodeQL, um Ihren Treibercode zu überprüfen.
Sicherheitsprüflistenelement Nr. 12:Verwenden von CodeQL zum Überprüfen auf Sicherheitsrisiken im Treibercode.
CodeQL, von GitHub, ist ein Semantikcodeanalysemodul, und die Kombination einer umfangreichen Suite von Sicherheitsabfragen zusammen mit einer robusten Plattform macht es zu einem wertvollen Tool zum Sichern von Treibercode. Weitere Informationen finden Sie unter CodeQL und dem Logotest für statische Tools.
Verwenden Sie Driver Verifier, um nach Schwachstellen zu suchen.
Sicherheitsprüflistenelement Nr. 13:Verwenden der Treiberüberprüfung, um auf Sicherheitsrisiken im Treibercode zu überprüfen.
Treiberüberprüfung (Driver Verifier, DV) verwendet eine Reihe von Schnittstellenregeln und ein Modell des Betriebssystems, um zu ermitteln, ob der Treiber ordnungsgemäß mit dem Windows-Betriebssystem interagiert. Driver Verifier findet Fehler im Treibercode, die auf potenzielle Fehler in Treibern verweisen könnten.
DV ermöglicht live-Tests des Treibers. Driver Verifier überwacht Treiber und Grafiktreiber im Windows-Kernelmodus und Grafiktreiber, um unzulässige Funktionsaufrufe oder Aktionen zu erkennen, die das System beschädigen könnten. Ein angefügter Debugger ermöglicht die Anzeige von Betriebssystem- und Treibercodeausführung in Echtzeit. Das Treiber-Überprüfungsprogramm kann Windows-Treiber einer Vielzahl von Belastungen und Tests aussetzen, um fehlerhaftes Verhalten zu erkennen. Weitere Informationen finden Sie unter Treiberüberprüfung.
Treiberverifier funktioniert sowohl mit WDM- als auch mit KMDF-Treibern. Einzelheiten darüber, was überprüft werden kann, finden Sie in den folgenden Themen.
Weitere Informationen zu den Treibern, mit denen Driver Verifier arbeiten kann, finden Sie unter DDI Compliance Rules und Supported Drivers. Weitere Prüfregeln für bestimmte Treibertypen finden Sie unter:
- Regeln für NDIS-Treiber
- Regeln für Storport-Treiber
- Regeln für Audiotreiber
- Regeln für AVStream-Treiber
Um sich mit DV vertraut zu machen, können Sie einen der Beispieltreiber verwenden (z. B. das empfohlene Toasterbeispiel: https://github.com/Microsoft/Windows-driver-samples/tree/main/general/toaster/toastDrv/kmdf/func/featured).
Überprüfen Sie den Code mit den Tests des Hardwarekompatibilitätsprogramms.
Sicherheitsprüflistenelement Nr. 14:Verwenden Sie die Tests des sicherheitsbezogenen Hardwarekompatibilitätsprogramms, um auf Sicherheitsprobleme zu überprüfen.
Das Hardwarekompatibilitätsprogramm enthält Sicherheitstests, die verwendet werden können, um nach Coderisiken zu suchen. Das Windows-Hardwarekompatibilitätsprogramm nutzt die Tests im Windows Hardware Lab Kit (HLK). Die HLK Device Fundamentals-Tests können in der Befehlszeile verwendet werden, um Treibercode auszuführen und nach Schwächen zu suchen. Allgemeine Informationen zu den Device Fundamentals Tests und zum Hardwarekompatibilitätsprogramm finden Sie unter Windows Hardware Lab Kit.
Die folgenden Tests sind Beispieltests, die hilfreich sein können, um Treibercode auf einige Verhaltensweisen zu überprüfen, die mit codebedingten Sicherheitsrisiken zusammenhängen:
DF – Fuzz – Zufälliger IOCTL-Test (Zuverlässigkeit)
DF – Fuzz – Test zum Öffnen von Sub (Zuverlässigkeit)
DF – Fuzz – FSCTL-Test auf Puffer mit Länge null (Zuverlässigkeit)
DF – Fuzz – Zufälliger FSCTL-Test (Zuverlässigkeit)
DF – Fuzz – Sonstiger API-Test (Zuverlässigkeit)
Sie können auch die Kernelsynchronisierungsverzögerung verwenden, die in der Treiberüberprüfung enthalten ist.
Bei CHAOS-Tests (Concurrent Hardware and Operating System, Hardware und Betriebssystem gleichzeitig) werden verschiedene PnP-Treibertests, Gerätetreiber-Fuzz-Tests und Tests des Stromversorgungssystems gleichzeitig ausgeführt. Weitere Informationen finden Sie unter CHAOS Tests (Device Fundamentals).
Die Device Fundamentals Penetration-Tests führen verschiedene Arten von Eingabeangriffen durch, die eine kritische Komponente von Sicherheitstests sind. Angriffs- und Penetrationstests können dabei helfen, Sicherheitsrisiken in Softwareschnittstellen zu identifizieren. Weitere Informationen finden Sie unter Penetration Tests (Device Fundamentals).
Verwenden Sie Device Guard – Compliance Test zusammen mit den anderen in diesem Artikel beschriebenen Tools, um zu bestätigen, dass Ihr Treiber HVCI-kompatibel ist.
Benutzerdefinierte und domänenspezifische Testtools
Erwägen Sie die Entwicklung benutzerdefinierter domänenspezifischer Sicherheitstests. Um zusätzliche Tests zu entwickeln, sammeln Sie Eingaben von den ursprünglichen Designern der Software sowie von unabhängigen Entwicklungsressourcen, die mit dem spezifischen Typ des zu entwickelnden Treibers vertraut sind, und von einer oder mehreren Personen, die mit der Analyse und Verhinderung von Sicherheitsangriffen vertraut sind.
Überprüfen Sie die Bereitschaft zur Auslieferung von Treibern mit Tools wie BinSkim und SignTool
Sicherheitsprüflistenelement Nr. 15:Kompilierten Code mit den Tools wie BinSkim und SignTool überprüfen, bevor es in das Partner Center hochgeladen wird.
Verwenden Sie Tools wie BinSkim und SignTool, um binärdateien zu untersuchen, um kompilierten Code zu überprüfen, bevor er in das Partner Center hochgeladen wird, um mithilfe von Windows Update verteilt zu werden. Wenn Tools zum Überprüfen kompilierter Binärdateien vorhanden sind, bevor sie zur Verteilung übermittelt werden, wird eine weitere Schutzebene hinzugefügt.
BinSkim
BinSkim kann Codierungs- und Erstellungsmethoden identifizieren, die eine Binärdatei potenziell anfällig machen können. BinSkim sucht nach:
- Verwendung veralteter Compilertoolsätze – Binärdateien sollten nach Möglichkeit anhand der neuesten Compilertoolsätze kompiliert werden, um die Verwendung der aktuellen Compilerebene und der vom Betriebssystem bereitgestellten Sicherheitsminderungen zu maximieren.
- Unsichere Kompilierungseinstellungen – Binärdateien sollten mit den sichersten Einstellungen kompiliert werden, um unter anderem vom Betriebssystem bereitgestellte Sicherheitsminderungen zu ermöglichen und Berichte über Compilerfehler und umsetzbare Warnungen zu maximieren.
- Signaturprobleme – Signierte Binärdateien sollten mit kryptografisch starken Algorithmen signiert werden.
BinSkim ist ein Open Source-Tool und generiert Ausgabedateien, die das Format Static Analysis Results Interchange (SARIF) verwenden. BinSkim ersetzt das ehemalige BinScope-Tool .
Weitere Informationen über BinSkim finden Sie unter BinSkim zur Überprüfung von Binärdateien verwenden und in der BinSkim-Anleitung.
SignTool
Verwenden Sie SignTool, um freigegebene Treiberdateien zu überprüfen. Weitere Informationen finden Sie unter Überprüfung der Signatur einer Release-Signed Treiberdatei und Überprüfung der Signatur einer Katalogdatei, die mit einem kommerziellen Freigabezertifikat signiert wurde.
Testcode nicht in der Produktion signieren
Sicherheitsprüflistenelement Nr. 16: Entwicklung, Testen und Herstellung des Kerneltreibercodes nicht als Produktionscode signieren.
Kerneltreibercode, der für Entwicklung, Tests oder Herstellung verwendet wird, kann gefährliche Funktionen enthalten, die ein Sicherheitsrisiko darstellen. Dieser gefährliche Code sollte niemals mit einem Zertifikat signiert werden, das von Windows als vertrauenswürdig eingestuft wird. Der richtige Vorgang zum Ausführen von gefährlichem Treibercode besteht darin, UEFI Secure Boot zu deaktivieren, BCD „TESTSIGNING“ zu aktivieren und den Entwicklungs-, Test- und Herstellungscode mithilfe eines nicht vertrauenswürdigen Zertifikats zu signieren (z. B. eines von makecert.exe).
Code, der von einem vertrauenswürdigen Software Publishers Certificate (SPC) oder Windows Hardware Quality Labs (WHQL) Signatur signiert ist, darf die Umgehung von Windows-Codeintegritäts- und Sicherheitstechnologien nicht unterstützen. Bevor Code von einer vertrauenswürdigen SPC- oder WHQL-Signatur signiert wird, stellen Sie zunächst sicher, dass er den Richtlinien zum Erstellen von zuverlässigen Kernelmodustreibern entspricht. Darüber hinaus darf der Code keine gefährlichen Verhaltensweisen enthalten, die unten beschrieben werden.
Beispiele für gefährliches Verhalten sind die folgenden:
- Bietet die Möglichkeit, beliebigen Kernel-, physischen oder Gerätespeicher dem Benutzermodus zuzuordnen.
- Bietet die Möglichkeit, beliebigen Kernel-, physischen oder Gerätespeicher zu lesen oder zu schreiben, einschließlich Porteingabe/-Ausgabe (E/A).
- Bereitstellen des Zugriffs auf Speicher, der die Windows-Zugriffssteuerung umgeht.
- Die Möglichkeit bereitstellen, Hardware oder Firmware zu ändern, die der Treiber nicht verwalten soll, da er dafür nicht entwickelt wurde.
Signieren Sie Ihren Releasetreiber korrekt und verteilen Sie Ihr Treiberpaket über Windows Update
Sicherheitsprüflistenelement Nr. 17:Verwenden Sie das Windows-Partnerportal, um Ihr Treiberpaket zu übermitteln, um über Windows Update signiert und verteilt zu werden.
Bevor Sie ein Treiberpaket für die Öffentlichkeit freigeben, übermitteln Sie das Paket zur Zertifizierung. Weitere Informationen finden Sie unter Test zur Leistung und Kompatibilität und Einstieg in das Hardware-Programm.
Die Verwendung von Windows Update wird dringend für die Verteilung von Treiberpaketen empfohlen. Windows Update bietet ein robustes, sicheres, global skaliertes und regulatorisches kompatibles Verteilungssystem, das zum Bereitstellen von Treiberupdates verwendet werden sollte. Weitere Informationen finden Sie unter Verteilen eines Treiberpakets.
Nutzen Sie den schrittweisen Rollout und das Treiber-Flighting im Partner Center für Windows-Hardware, um Ihr Treiberpaket innerhalb definierter Windows Insider-Ringe zu verteilen und gleichzeitig eine automatische Überwachung und Bewertung zu gewährleisten. Überwachen Sie den Rollout des Treibers anhand der Microsoft Treiber Messungen, wie z. B. Prozent der Maschinen ohne Kernel Mode Crash, um die Qualität zu erhalten.
Eine Beschreibung der Methoden für die sichere Softwarebereitstellung finden Sie in der CISA-sicheren Softwarebereitstellung: Wie Softwarehersteller zuverlässigkeit für Kundensicherstellen können.
Verstehen, wie Treiber mithilfe des Microsoft Vulnerable and Malicious Driver Reporting Center gemeldet werden
Sicherheitsprüflistenelement Nr. 18: Verstehen, wie Treiber mithilfe des Microsoft Vulnerable and Malicious Driver Reporting Center gemeldet werden
Jeder kann einen fragwürdigen Treiber über das Microsoft Vulnerable and Malicious Driver Reporting Centerübermitteln. In diesem Blogeintrag finden Sie Informationen dazu, wie Treiber zur Analyse übermittelt werden – Verbessern Sie die Kernelsicherheit mit dem neuen Microsoft-Zentrum für die Meldung von verwundbaren und bösartigen Treibern
Das Reporting Center kann Windows-Treiber scannen und analysieren, die für x86- und x64-Architekturen erstellt wurden. Anfällige und böswillige gescannte Treiber durch das Vulnerable Driver-Team von Microsoft zur Analyse und Untersuchung gekennzeichnet. Nachdem anfällige Treiber bestätigt wurden, wird eine entsprechende Benachrichtigung gesendet, und sie werden der Blockliste für anfällige Treiber hinzugefügt. Weitere Informationen hierzu finden Sie unter Von Microsoft empfohlene Treiberblockregeln. Diese Regeln werden standardmäßig auf Geräte mit hypervisorgeschützter Codeintegrität (HVCI) und Windows 10 im S-Modus angewendet.
Überprüfen von Ressourcen für sicheres Codieren
Sicherheits-Checkliste Punkt 19:Lesen Sie diese Ressourcen, um Ihr Verständnis für die bewährten Verfahren zur sicheren Codierung zu erweitern, die für Entwickler von Treibern gelten.
NIST bekannte Software-Sicherheitsrisikodatenbank
Die National Vulnerability Database (NVD) ist ein durchsuchbares Repository sicherheitsrelevanter Softwarefehler, einschließlich Windows-Treibern.
NIST-Sicherheitsrisikodatenbank durchsuchen
National Vulnerability Database Overview
Sichere Codierungsstandards
Carnegie Mellon University SEI CERT - C Coding Standard: Regeln für die Entwicklung sicherer, zuverlässiger und sicherer Systeme (PDF).
MITRE – Schwachstellen, die vom CERT C Secure Coding Standard behandelt werden
Organisationen für sicheres Codieren
Internetsicherheits- und Infrastruktursicherheitsagentur (CISA)
SAFECode – https://safecode.org/
Carnegie Mellon University SEI CERT
OSR
OSR bietet Training für die Treiberentwicklung und Beratungsleistungen an. In diesen Artikeln aus dem OSR-Newsletter werden Treibersicherheitsprobleme hervorgehoben.
Sie müssen sich schützen – im Treiber & Gerätesicherheit
Sperren von Treibern – ein Überblick über die Techniken
Meltdown und Spectre: Was ist mit Treibern?
Fallstudie zu Treiberrisiken
Sicherheit der Software-Lieferkette und Software Bill of Materials (SBOMs)
Die Initiative für Integrität, Transparenz und Vertrauen in der Lieferkette (SCITT)
Erstellung von Software-Stücklisten (SBOMs) mit SPDX bei Microsoft
Microsoft macht sein Tool zur Erstellung von Software-Stücklisten (SBOM) als Open Source verfügbar
Bücher
24 Tödliche Sünden der Softwaresicherheit: Programmierfehler und Wie man sie von Michael Howard, David LeBlanc und John Viega beheben kann
Sichere Software entwickeln, zweite Auflage, Michael Howard und David LeBlanc
The Art of Software Security Assessment: Identifizieren und Verhindern von Software-Schwachstellen, Mark Dowd, John McDonald und Justin Schuh
Secure Coding in C und C++ (SEI Series in Software Engineering) 2. Auflage, Robert C. Seacord
Programmierung des Microsoft Windows-Treibermodells (2. Auflage), Walter Oney
Entwickeln von Treibern mit der Windows Driver Foundation (Entwicklerreferenz), Penny Orwick und Guy Smith
Training
Windows-Treiberschulungen stehen von Anbietern wie den folgenden zur Verfügung:
Schulungen zum sicheren Codieren sind online aus einer Vielzahl von Quellen verfügbar. Beispielsweise ist dieser Kurs auf Coursera verfügbar:
Identifizierung von Sicherheitsschwachstellen in der C/C++ Programmierung.
SAFECode bietet auch kostenlose Schulungen an:
Professionelle Zertifizierung
CERT bietet eine Secure Coding Professional-Zertifizierung an.
Zusammenfassung der wichtigsten Erkenntnisse
Treibersicherheit ist ein komplexes Unterfangen, das viele Elemente enthält, aber hier sind einige der wichtigsten Punkte:
Treiber befinden sich im Windows-Kernel, und ein Problem beim Ausführen im Kernel kann das gesamte Betriebssystem gefährden. Achten Sie daher besonders auf die Sicherheit der Treiber und entwickeln Sie ein sicheres Design.
Anwenden des Prinzips der geringsten Rechte:
a. Verwenden Sie eine strenge SDDL-Zeichenfolge, um den Zugriff auf den Treiber einzuschränken
b. Weitere Einschränkung einzelner IOCTL-Elemente
Erstellen Sie ein Bedrohungsmodell, um Angriffsvektoren zu identifizieren, und überlegen Sie, ob alles etwas eingeschränkt werden kann.
Seien Sie vorsichtig im Hinblick auf eingebettete Zeiger, die vom Benutzermodus aus übergeben werden. Sie müssen überprüft werden, auf sie muss von innerhalb des Try-Except-Vorgangs zugegriffen werden, und sie sind anfällig für ToCToU-Probleme, es sei denn, der Wert des Puffers wird erfasst und verglichen.
Wenn Sie unsicher sind, verwenden Sie METHOD_BUFFERED als IOCTL-Puffermethode.
Verwenden Sie Codescan-Dienstprogramme wie CodeQL, um nach bekannten Coderisiken zu suchen und identifizierte Probleme zu beheben.
Suchen Sie kompetente Codeprüfer, um Probleme zu finden, die Sie möglicherweise übersehen haben.
Verwenden Sie Treiberprüfer, und testen Sie Ihren Treiber mit mehreren Eingaben, einschließlich Ausnahmefällen.