Hardware-Fuzzing: Hintertüren und Fehler in CPUs aufspüren

Ein Prozessor-Fuzzer analysiert Hardware, der man normalerweise blind vertrauen muss. In ersten Testläufen wurde er bei nahezu allen Architekturen fündig und spürte etwa undokumentierte CPU-Befehle auf. Sandsifter ist kostenlos und frei verfügbar; der Autor hilft sogar bei der Analyse.

In Pocket speichern vorlesen Druckansicht 117 Kommentare lesen
Hardware-Fuzzing: Hintertüren und Fehler in CPUs aufspüren

(Bild: Domas)

Lesezeit: 5 Min.
Inhaltsverzeichnis

CPUs sind praktisch Black Boxes. Bei dem was sie tun, vertrauen wir komplett auf die Dokumentation des Herstellers. Dabei ist durchaus bekannt, dass CPUs undokumentierte und sogar versteckte Funktionen aufweisen. Auch CPU-Bugs wurden bereits aufgedeckt; man denke etwa an den FDIV-Bug der Pentium-CPUs, der für Schlagzeilen sorgte. Trotzdem nehmen wir an, dass CPUs wirklich das – und nur das – tun, was wir ihnen auftragen.

Dieses Vertrauen ist auch aus der Not geboren, dass man – anders als bei Software, wo es eine Vielzahl von Analyse-Tools und Techniken gibt – bei einer CPU kaum hinter die Kulissen schauen kann. Der Sicherheitsexperte Chris Domas will diese Situation ändern. Er stellt einen x86-Prozessor-Fuzzer vor, der systematisch die möglichen Byte-Kombinationen für Maschinenbefehle durchprobiert und dabei Auffälligkeiten wie undokumentierte Befehle oder Abweichungen von der Dokumentation registriert.

Die größte Herausforderung ist dabei die Anzahl der möglichen Befehle. Theoretisch können x86-Instruktionen bis zu 15 Byte lang sein, was etwa 1.3x1036 mögliche Kombinationen ergibt. Das ist viel mehr als man sinnvoll testen kann. Domas, in der Hacker-Community unter seinem Handle xoreaxeaxeax unterwegs, hat deshalb ein Verfahren erarbeitet, seine Suche auf die sinnvollen Kombinationen zu beschränken.

Im unteren Teil des Fensters notiert der CPU-Fuzzer Sandsifter die gefunden Auffälligkeiten wie undokumentierte Funktionen oder Bugs.

Dazu ermittelt er vorab die jeweilige Länge einer Instruktion. Im wesentlichen beruht das darauf, die Bytes eines Maschinenbefehls an der Grenze zweier Speicher-Seiten abzulegen. Davon ist nur die erste als ausführbar markiert; die zweite hingegen legt Domas als nicht ausführbar fest. Liegt ein Teil des Befehls auf der zweiten Seite, erzeugt die Speicherverwaltung beim Versuch, den Befehl zur Ausführung zu bringen, eine charakteristischen Fehler. Also schiebt Domas den Maschinenbefehl byteweise nach "links", bis er ihn ausführen kann.

Mit der Information, wie lang die gefundenen Maschinenbefehle sind, konnte Domas die Zahl der sinnvollen Byte-Kombinationen auf etwa 100 Millionen reduzieren. Das kann ein von ihm entwickelter Hardware-Fuzzer namens Sandsifter innerhalb eines Tages abarbeiten. Sandsifter lässt die CPU, auf der er läuft, alle Befehle ausführen und fängt dabei alle möglichen Fehlerzustände ab. Erzeugt die CPU keine "invalid opcode exception" (#UD), weiß man, dass der Befehl existiert. Ob er dokumentiert ist, ermittelt er mit Hilfe eines Disassemblers wie Capstone. Kennt der den Befehl nicht, handelt es sich entweder um einen undokumentierten Befehl oder einen Fehler. Beidem muss man weiter nachgehen, um zu ermitteln, was wirklich Sache ist.

Bei seinen bisherigen Testläufen hat Domas bereits undokumentierte Befehle in der Intel Core i7-4650U CPU, im AMD Athlon (Geode NX1500) und im VIA Nano U3500 aufgedeckt. Neben haufenweise Fehlern in der Dokumentation und den eingesetzten Disassemblern hat Domas auch einige Hardware-Bugs gefunden und dokumentiert. Einer davon hat es besonders in sich: Dumas hat auf einem CPU-Typ einen Befehl aufgespürt, den er sehr ausdrucksstark mit "halt and catch fire" beschreibt.

Das Ausführen dieses Befehls führt laut Dumas dazu, dass der Prozessor die Arbeit komplett einstellt. Ob und wie sich die Hardware wieder davon erholt, lässt sich der Beschreibung nicht entnehmen. Besonders kritisch dabei: Ein Aufruf dieses Befehls erfordert keine besonderen Rechte; jedes Programm kann das Problem auslösen. Das wäre seit etwa 20 Jahren der erste gefundene DoS-Angriff auf Prozessor-Ebene, erklärt Dumas. Damals sorgte der F00F-Bug des Pentiums für Schlagzeilen. Da der Sicherheitsforscher derzeit noch mit dem Hersteller bespricht, wie man am besten damit umgeht, nennt er derzeit noch keine Details oder welche Systeme konkret betroffen sind.

Kernstück der Arbeit ist der CPU-Fuzzer Sandsifter, den Domas der Allgemeinheit auf Github bereit stellt. Mehr Details zur Vorgehensweise liefern die Folien des Black-Hat-Talks "Breaking the x86 ISA" und ein Whitepaper zum technischen Hintergrund. Damit kann im Prinzip jede(r) ihr/sein eigenes System auf Auffälligkeiten untersuchen. Darüber hinaus bietet der Forscher an, Log-Files von Sandsifter-Läufen zu analysieren. Diese Protokolle enthalten außer den Informationen zur CPU (Hersteller, Typ, Version) keine persönlichen Daten. Dumas Hoffnung ist, dass man auf diesem Weg Licht in einen bisher viel zu wenig untersuchten Bereich unserer IT-Infrastruktur bringen kann.

Interessant in diesem Kontext ist übrigens auch ein aktuelles Paper von Forschern der Ruhr Uni Bochum. In Reverse Engineering x86 Processor Microcode dokumentiert das Team rund um Thorsten Holz, dass es durchaus möglich ist, etwa eine AMD-CPU nachträglich zu trojanisieren. Sie implementierten dazu eine Malware in AMDs Microcode und schleusten diesen über die bislang undokumentierten Microcode-Update-Funktionen der AMD K8- und K10-CPUs erfolgreich ein. Dabei programmierten sie den x86-Befehl div ebx so um, dass er bei bestimmten Werten für Dividend und Divisor zusätzliche Aktionen ausführte. Eine solche Umprogrammierung ließe sich auch durch Fuzzing kaum aufspüren. (ju)