Area41 2024 - Ein Rückblick
Michael Schneider
So machen Sie Kernel Mode Code Signing
Neulich wollte ich Code im Kernel-Mode unter Windows ausführen lassen und habe dabei gelernt, welche Voraussetzungen dazu notwendig sind und wo Fallstricke lauern. Darum geht es in diesem Labs über eine Einführung in das Thema Code-Signing für Windows Kernel-Mode.
Das Betriebssystem Microsoft Windows unterscheidet zwischen User Space und System Space respektive Kernel Space. Im User Space werden normale Anwendungen betrieben, die keinen direkten Zugriff auf interne oder sensitive Betriebssystem-Ressourcen haben. Code, der im Kernel Space ausgeführt wird, hat mehr Zugriffe und direkten Einfluss auf das Betriebssystem, sei dies bezüglich Stabilität oder Sicherheit des Systems. Dementsprechend sind Anforderungen für Code im Kernel Space höher.
Mit der Veröffentlichung von Windows Vista 64-Bit erforderte Microsoft Signaturen, um Code im Kernel Space zu laden. Mit Windows 8 war es zusätzlich notwendig, dass Treiber-Pakete ebenfalls signiert werden. Und mit Windows 10 erforderte Microsoft, dass neue Treiber durch das Windows Hardware Dev Center signiert werden müssen.
Mit der Signatur eines Treibers wird einerseits die Integrität der Software sichergestellt, da eine Veränderung des Treibers dazu führt, dass die vorhandene Signatur ungültig wird. Andererseits kann damit die Herkunft der Software bestimmt werden. Denn durch die Registrierung für das Hardware Dev Center kann Microsoft zumindest nachvollziehen, von welchem Account die Software stammt. Zudem ist eine der Teilnahmebedingungen der Einsatz eines Extended-Validation-Code-Signing-Zertifikats, kurz EV-CS-Zertifikat.
Für die Ausstellung eines EV-CS-Zertifikat führt eine Certificate Authority (CA) eine detaillierte Prüfung des Antragstellers im Ausstellungsprozess durch. Wenn ein Zertifikat für eine Firma beantragt wird, müssen öffentlich überprüfbare Angaben über die Firma, wie korrekte Anschrift, offizielle Telefonnummer sowie die verantwortlichen Personen für die Signierung von Software angegeben werden. Es findet eine telefonische Verifikation der verantwortlichen Personen statt. Das EV-Code-Signing-Zertifikat wird nach erfolgreichen Prüfung auf den Namen der Firma aus- und auf einem USB-Token zugestellt.
Im Bereich von EV-Zertifikate für Webseiten findet derzeit eine Diskussion über deren Daseinszweck statt. Der Security-Researcher Troy Hunt erklärte diese im Blog-Artikel Extended Validation Certificates are (Really, Really) Dead als nicht mehr zeitgemäss und meint, dass diese durch freie Lösungen ersetzt werden können. Für Kernel-Mode-Code-Signing besteht jedoch keine Alternative, da der Einsatz von EV-CS-Zertifikaten durch Microsoft verlangt wird.
Zurück zu den Anforderungen der verschiedenen Windows-Versionen. Die Driver Signing Policy von Microsoft schreibt vor, dass für Windows 7 64-Bit, Windows 8 und Windows 10 bis Version 1511 ein Treiber mit SHA1 signiert sein muss und das verwendete Zertifikat muss von einer CA stammen, die sich auf der Cross-Certificate List von Microsoft befindet. Für Windows 10 Version 1607 bis 1709 ist als Signaturalgorithmus SHA1 oder SHA2 zugelassen und ab Windows 10 Version 1803 und höher ist nur noch SHA2 erlaubt. Zudem muss die Signatur von einer Microsoft Root Authority stammen. Das heisst, eine neue Installation von Windows 10 Version 1607 lädt keine neuen Kernel-Treiber mehr, die nicht durch das Hardware Dev Center signiert wurden.
Diese Änderungen wurden im Blog-Artikel Driver Signing changes in Windows 10, version 1607 ausführlich beschrieben. Um die Abwärtskompatibilität beizubehalten und damit nicht alle Treiber neu signiert werden müssen, wurden Ausnahmen definiert:
Dies führt dazu, dass alle neuen Treiber für aktuelle Windows 10 Versionen mit einem EV-CS-Zertifikat signiert sein, dann durch das Windows Hardware Developer Center validiert werden und anschliessend durch Microsoft signiert werden müssen.
Microsoft bietet ein umfangreiches Windows Driver Signing Tutorial an, das unter anderem beschreibt, wie eine Test-Signatur durchgeführt werden kann. Dabei muss aber das Betriebssystem in einen speziellen Modus gestartet werden, sodass die Option Driver Signature Enforcement für diese Session deaktiviert wird. Danach kann ein eigenes Zertifikat erstellt, Treiber damit signiert und geladen werden. Diese Schritte können für erste Gehversuche und Tests nützlich sein. Eine Nutzung von selbstsignierten Treibern ist jedoch auf fremden Maschinen mit aktuellen Windows-Versionen nicht möglich.
Für die Signatur von Treiber wird das Windows Driver Kit (WDK) benötigt. Das wichtigste Werkzeug des WDK ist dabei SignTool. Damit werden Treiber signiert und können verifiziert werden. Microsoft rät davon ab für die Signatur eine Zertifikatsdatei (PFX) zu verwenden, sondern empfiehlt das Zertifikat in den Certificate Store des Betriebssystems zu importieren und dann den Signaturvorgang durchzuführen. Zudem wird ein EV-CS-Zertifikat auf einem USB-Token bzw. einer Smartcard zugestellt und nicht als PFX-Datei.
Der Befehl, um einen Treiber in der einfachsten Form zu signieren, lautet:
signtool.exe sign /v /n "SubjectName" DriverFile.sys
Beim Parameter /n
handelt es sich um den Common Name des Zertifikats. Damit ein Treiber aber auch im Kernel Mode geladen werden kann, ist die Verwendung eines Zertifikats einer Cross-Signed-CA notwendig. Dabei kann auf der Cross-Certificate List das passende Zertifikat der CA heruntergeladen werden. Mit dem Parameter /ac
wird dieses Zertifikat entsprechend eingebunden:
signtool.exe sign /v /n "SubjectName" /ac CrossSignedCARoot.cer DriverFile.sys
Für Windows 10 muss ein Treiber mit SHA2 signiert werden. Ebenso sollte der Treiber einen Timestamp der Signatur enthalten. Dabei kann ein Timestamp-Server der jeweiligen CA genutzt werden:
signtool.exe sign /v /n "SubjectName" /ac CrossSignedCARoot.cer /fd sha256 /td sha256 /tr http://timestamp.example.com/rfc3161 DriverFile.sys
Treiber, die auf diesem Weg signiert wurden, können unter Windows 7, 8 und früheren Version von Windows 10 eingesetzt werden.
Für die Verifizierung einer Signatur wird wiederum die Anwendung signtool.exe
eingesetzt. Dabei wird bei der Verifizierung zwischen den Parametern /pa
für Validierung der Plug-and-Play-Treiber (PnP) sowie /kp
für Kernel Mode-Treiber unterschieden.
signtool.exe verify /pa /v DriverFile.sys
signtool.exe verify /kp /v DriverFile.sys
Die folgenden Fehler können bei der Verifizierung auftreten:
The signing certificate is not valid for the requested usage
: Es braucht ein EV-CS-Zertifikat, andere Zertifikate werden für den Kernel Mode nicht akzeptiertThe provided cross certificate would not be present in the certificate chain
: Das heruntergeladene Zertifikat der Cross-Certificate List stimmt nicht mit der Zertifikat-Chain überein, das passende Root-Zertifikat muss ausgewählt werdenA certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider
: Meldung unter Windows 10 ab Version 1607, wenn der Treiber mittels Cross-Certificate signiert wurde, aber nicht vom Hardware Dev CenterDie Zertifikat-Chain eines Zertifikats kann mittels certutil.exe
geprüft werden. Damit verfügen Pentester nun über einen legitimen Grund certutil
auf einem Client auszuführen:
certutil.exe -dump Certificate.cer
Nach gut zwei Wochen, inklusive der Wartezeit bis die Verifizierung des EV-CS-Zertifikat-Antrags abgeschlossen war und der USB-Token zugestellt wurde, sowie einigen gescheiterten Versuche mit selbstsignierten und normalen CS-Zertifikaten und dem Lesen von Microsoft-Dokumenten, habe ich es geschafft einen Treiber so zu signieren, dass dieser von Windows im Kernel Mode geladen wurde. Dieser Beitrag soll anderen helfen, dieses Ziel einfacher und schneller zu erreichen – Feedback und Erfahrungsaustausch sind gerne willkommen.
Unsere Spezialisten kontaktieren Sie gern!
Michael Schneider
Michael Schneider
Michael Schneider
Michael Schneider
Unsere Spezialisten kontaktieren Sie gern!