Open Source im professionellen Einsatz
Linux-Magazin 09/2015
© psdesign1, Fotolia

© psdesign1, Fotolia

Kernel- und Treiberprogrammierung mit dem Linux-Kernel – Folge 82

Kern-Technik

,

Viele Linuxer wissen nicht um die Gefährlichkeit von Kernelmodulen, deren Herkunft und Integrität nicht 100-prozentig gesichert ist. Noch weniger bekannt ist, dass sich eigene Systeme mit signierten Kernelmodulen gegen Codemanipulationen schützen lassen – vorausgesetzt man macht es richtig.

1205

Der beste Aufenthaltsort für einen Linux-Trojaner ist ein Kernelmodul. Von dort darf er auf alle Ressourcen zugreifen, Kernelfunktionen auf sich umbiegen und sich optimal vor Enttarnung schützen: Da sein Code mit Kernelprivilegien läuft, kann er Schutzfunktionen wie SE Linux oder Dateisignaturen-Scanner abschalten, Code nachladen und starten, Tasks vor »ps« verbergen oder Netzwerktools beliebige Dinge vorgaukeln. Eine Schadsoftware als Kernelmodul besitzt faktisch mehr Rechte als Root, weshalb der nicht mal mehr auf die Vollständigkeit eines »ls -a« in seinem Homeverzeichnis zu trauen braucht.

Die Gefahr ist nicht nur theoretischer Natur. Es reicht der Tipp in einem Forum, nach dem es gut sei, ein alternatives Repository einzubinden, um irgendein Grafikproblem zu lösen – und schon kommt ein bösartiges Kernelmodul geflogen.

Aber auch reguläre Repositories sind bereits Ziel gelungener Crackerangriffe geworden. Allein die NSA und der GCHQ sollten auch Linuxer gelehrt haben, dass vieles weitaus schlimmer ist als befürchtet. Sicherheit auf einem akzeptablen Niveau ist nur mit Misstrauen herzustellen. Darum: Traue nur dem Code, den du selbst kompiliert hast – besonders wenn die Software mit weitreichenden Privilegien läuft.

Der Linux-Kernel ist seit der Version 3.7 im Jahr 2012 offiziell auf Misstrauen vorbereitet. Linus Torvalds hatte damals signierte Kernelmodule eingeführt, ein Sicherheitskonzept, das Microsoft mit der ersten 64-Bit-Version von Windows Vista schon ins Gespräch gebracht hatte. Aber anders als bei Windows – und zentral für die eigene Sicherheitsstrategie – darf der Linux-User selbst bestimmen, welchen digitalen Unterschriften er vertraut!

Es gibt also Unterschiede: Nur weil ein System signierte Kernelmodule verwendet, ist es nicht gleich sicherer und besser vor Trojanercode geschützt. Das hat der Stuxnet-Angriff auf die iranischen Atomanlagen eindrucksvoll gezeigt. Stuxnet hat sich dank gültiger Signatur als Treiber im Windows-Kernel eingenistet und so an zentraler Stelle die Kontrolle über das System übernommen [1].

An eine gültige Signatur durch Unterwanderung der ausstellenden Instanz zu kommen scheint nicht schwer zu sein – mit politischem Druck oder genug Geld. Alternativ lassen sich Zertifikate auch stehlen. Und da es keinen fehlerfreien Code gibt, hebelt ein Angreifer unter Umständen die Überprüfung auf eine gültige Unterschrift mit einer Zero-Day-Attacke aus. Wer möchte mit Bestimmtheit behaupten, dass sich im Zertifikatsspeicher seines Rechners kein eingeschmuggeltes Zertifikat befindet? Geheimdienste fordern diese schon seit Jahren.

Trumpfkarte Linux

Signierte Kernelmodule sind so vertrauenswürdig wie der eingesetzte Quellcode und die Zertifikat-ausstellende Instanz (CA, Certification Authority). Genau an dieser Stelle spielt Linux seine Trümpfe aus: Der offene Quellcode, aus dem der eigene Kernel entsteht (Kernel und Binary passen damit zusammen), erlaubt es, auf Hintertüren zu checken.

Von allen Zertifikat-ausstellenden Instanzen ist nur eine einzige vertrauenswürdig – die eigene. Der Fall Diginotar [2] ist nur einer von vielen Vorfällen der letzten Jahre, die die Sinnlosigkeit kommerzieller, zentraler PKIs demonstrierten. Um es klar auszudrücken: Wer heute einer nicht selbst betriebenen PKI den eigenen Rechner ernsthaft anvertraut, hat nichts mehr zu verlieren. Wer jedoch seine Schlüssel und Zertifikate selbst erzeugt und das System eigenständig zusammenbaut, fährt durch signierte Kernelmodule einen erheblichen Sicherheitsvorteil ein.

Ist ein Kernel mit der Option »Module signature verification« übersetzt, verlangt er beim Laden eines Kernelmoduls eine digitale Unterschrift [3]. Ist außerdem die Option »Require modules to be validly signed« ausgewählt, lädt er das Modul nur, wenn die digitale Unterschrift des Moduls mit einer im Kernel hinterlegten Unterschriftenprobe (Zertifikat) übereinstimmt (Abbildung 1). Hat die Konfiguration die Option nicht gesetzt, werden Module ohne digitale Unterschrift oder Module, für die es keine Unterschriftenprobe gibt, zwar geladen, aber als »tainted« , also als "verschmutzt" markiert. Erst wenn das Modul eine für den Kernel nicht identifizierbare Unterschrift trägt, lädt Linux es überhaupt nicht.

Die digitale Unterschrift stellt zudem mit Hilfe eines Hashalgorithmus die Integrität des Moduls sicher. Damit wird nachvollziehbar, ob der Modulcode seit dem Zeitpunkt, an dem er digital unterschrieben wurde, unverändert blieb. Der Schutz der Integrität und der Authentizität kann (muss aber nicht) die Sicherheit erhöhen.

Abbildung 1: In der Kernelkonfiguration wählt der Linuxer signierte Kerneltreiber aus.

Zertifikate im Kernel

Asymmetrisch signierte Kernelmodule brauchen ein Schlüsselpaar, also einen öffentlichen und einen privaten Schlüssel (Abbildung 2). Einerseits sind dann im Betriebssystemkern eine oder mehrere Unterschriftenproben in Zertifikaten hinterlegt. Andererseits unterschreibt der Kernelmodul-Übersetzungsvorgang die Binaries kryptographisch.

Gewöhnlich liegen beide Schlüssel im Kernelquellcode-Verzeichnis als »signing _key.priv« und »signing_key.x509« bereit. Andernfalls generiert Linux das Schlüsselpaar selbstständig mit Hilfe eines Perl-Programms im Linux-Quellcode: »scripts/sign-file« (Abbildung 3). Die Informationen zum Aussteller und zur Verwendung entnimmt das Kernel-Buildsystem der Datei »x509.genkey« . Falls auch die fehlt, legt sie der Kernel ebenfalls an.

Linus Torvalds hatte übrigens im Git-Repository seines Quellcodes vor der Version 4.1 als ausstellende Instanz den Planetendesigner Slartibartfast vom Douglas-Adams-Planeten Magrathea angegeben (»slartibartfast@magrathea.h2g2« ). Jetzt motiviert er eher irdisch mit »unspecified.user@unspecified.company« jeden Kernelbäcker, individuelle Daten vor dem Kompilieren in die Datei »x509.genkey« einzutragen. Insbesondere betrifft dies die Angaben unterhalb des Abschnitts »[ req_distinguished_name ]« .

Wer möchte, kompiliert in den Kernel gleich mehrere Unterschriftenproben ein. Dazu legt er die Zertifikate in das Linux-Quellcodeverzeichnis. Sie müssen die Datei-Erweiterung ».x509« tragen und vom Typ X.509 sein [4]. Den Versuch, Unterschriften nach dem Microsoft-Standard Authenticode [5] zu erlauben, hat Linus Torvalds vor einiger Zeit kategorisch abgelehnt. Der Superuser kann durch Aufruf von »cat /proc/keys« prüfen, welche Zertifikate sich im Kernel befinden (Abbildung 4).

Der Kernel sortiert seine Schlüssel über Schlüsselbünde, so genannte Keyrings. Auch ist es möglich, nachträglich über das Programm »keyctl« weitere Schlüssel dem Kernel hinzuzufügen:

keyctl padd asymmetric "" System-Keyring-ID < Keyfile

Zu beachten ist die Randbedingung, dass der zu importierende Schlüssel mit einem bereits im Kernel befindlichen Schlüssel unterschrieben sein muss. Zudem ist es möglich, Schlüssel aus einem Hardware-Store zur Prüfung von Modul-Integrität und Authentizität heranzuziehen.

Um Kernelmodule zu signieren, braucht man die Kernelquellen. Wer sie nicht per »git« , sondern über http://www.kernel.org lädt, überprüft unbedingt die digitale Unterschrift zum Kernelquellcode! Die Unterschriftenprobe (Zertifikat) von Linus Torvalds respektive von Greg Kroah-Hartmann gibt es über das Kommando »gpg --recv-keys« . Dann packt man das Archiv aus.

Für Produktivsysteme ist die Art des Kernelbezugs natürlich ungünstig, da sie am Paketmanagement vorbei passiert. Daraus erwächst auf Dauer ein Problem: Mit dem nächsten Kernel-Sicherheitsupdate kommt ein neuer Binärkernel ohne Signatur aus dem Repository der Distribution, der die selbst hergestellte Version außer Kraft setzt. Wer seinem Paketmanagement das untersagt, um der Nutznießer signierter Module zu bleiben, betreibt sein System mit mehr und mehr ungestopften Sicherheitslöchern.

Zwei Wege führen aus diesem Dilemma: Entweder baut sich der Admin eine Toolchain, die stets aktuelle Kernelquellen ins System holt und sie entsprechend der gleich folgenden Beschreibung automatisch übersetzt. Oder der Verantwortliche benutzt die Distributions-offiziellen Kernelquellen in Paketform.

Abbildung 2: Beteiligte Komponenten und die Abläufe für den signierter Kernelcode.
Abbildung 3: Das Kernel-Buildsystem erstellt das Schlüsselpaar selbstständig.
Abbildung 4: Mit sign-file bekommen Kernelmodule eine Unterschrift.

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 4 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Kern-Technik

    Secure Boot erwartet einen digital unterschriebenen Kernel. Eigene Module und Treiber von Drittanbietern lassen sich allerdings nur mit Nachhilfe laden. Außerdem hat Microsoft die Finger im Spiel.

  • Trusted Boot

    Gut ausgestattete Mainboards bringen meist Trusted-Computing-Chips mit, die Benutzer und Betriebssysteme aber nur selten nutzen. Der Linux-Kernel beherrscht die Technik und ermöglicht mit Trusted Grub eine weitreichende Vertrauenskette – zumindest theoretisch.

  • Fedora in Version 18 veröffentlicht

    Nach mehrfachen Verschiebungen des Release-Termins wurde heute die Linux-Distribution Fedora 18 veröffentlicht.

  • Debian bringt Update für Lenny

    Für die neue stabile Debian-Version 5.0 ist über Ostern ein erstes Update erschienen.

  • Kmod 11 schickt Wait-Option in Rente

    Kmod, eine Sammlung von Tools für Linux-Kernelmodule, ist in Version 11 verfügbar.

comments powered by Disqus

Stellenmarkt

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.