0.13 CSI MacMark: Rootkit mit Thunderbolt Inhaltsverzeichnis

CRIME SCENE DO NOT CROSS        CRIME SCENE DO NOT CROSS        CRIME SCENE DO NOT CROSS        CRIME SCENE DO NOT CROSS        CRIME SCENE DO NOT CROSS        CRIME SCENE DO NOT CROSS        CRIME SCENE DO NOT CROSS        CRIME SCENE DO NOT CROSS

Ich habe ein paar Anmerkungen zum Artikel EFI-Rootkit für Macs demonstriert auf heise Security, um die Sachlage etwas klarer darzustellen.

Ausgangspunkt für den Artikel war der Vortrag "Mac EFI Rootkits" von Snare auf der Black Hat USA 2012. Den Vortrag und die Ausarbeitung hat Snare inzwischen veröffentlicht. Im Forum von MacRumors hat Snare auch nochmal diesbezüglich geantwortet.

Kurz und bündig

Der Angriff von PCI-Geräten auf die Firmware eines Rechners ist nicht neu und wurde vor fünf Jahren bereits auf der Black Hat DC 2007 gegen Windows-PCs und ihr BIOS gezeigt. Auf der Black Hat USA 2012 wurde vorgeführt, wie man dieses Angriffskonzept auch gegen Macs mit EFI einsetzen kann. Neu ist daran hauptsächlich, daß man dank PCI Express (PCIe) als Bestandteil von Thunderbolt nun auch leicht PCI-Geräte außerhalb des Computer-Gehäuses anschließen kann.

Im Detail sieht das so aus:

Es war einmal: BIOS

Wenn man den Rechner anschaltet, dann übernimmt heutzutage als erstes eine Firmware die Kontrolle und bereitet den Start eines Betriebssystem vor, dem sie anschließend die Kontrolle über den Rechner übergibt. Die Firmware besteht entweder aus einem BIOS oder einem EFI. EFI wurde von Intel für die IA-64 (Itanium) Geräte benötigt. Das Whitepaper dazu kam 1998 von Intel-Ingenieur Andrew Fish.

BIOS war ursprünglich der maschinenabhängige Teil von CP/M. Durch Anpassung des BIOS konnte CP/M auf andere Rechner portiert werden. Ein BIOS war also anfangs gar keine Firmware, sondern Software.

Exkurs: CP/M

Ich habe hier noch meinen Apple //c stehen mit einer Z80-Karte darin, mit der ich CP/M benutzt habe, um in dBase II und TURBO Pascal zu programmieren und mit WordStar Texte zu schreiben und mit Multiplan oder VisiCalc Tabellen-Kalkulation zu machen.

Diese Z80-Karte für den Apple //c wurde von Microsoft vertrieben, jedoch von einem Dritthersteller produziert. Und das CP/M hatte Microsoft für diese Karte von Digital Research lizensiert. Also clever vermarktet, aber nichts selbst gemacht.

CP/M auf dem Apple //c

CP/M 2.23 auf einem Apple //c

Multiplan auf dem Apple //c

Multiplan auf einem Apple //c

Multiplan war Microsofts erstes Tabellenkalkulations-Programm, aber nicht das erste seiner Art, denn dies war VisiCalc für den Apple II, das erste Spreadsheet-Programm der Welt, welches den Apple II bei Firmenkunden erfolgreich machte.

TURBO Pascal Start auf dem Apple //c

TURBO Pascal Start auf einem Apple //c

TURBO Pascal Editor auf dem Apple //c

TURBO Pascal Editor auf einem Apple //c

WordStar auf dem Apple //c

WordStar auf einem Apple //c

WordStar wurde für CP/M geschrieben bevor es MS-DOS, geschweige denn MS Word überhaupt gab.

Die erste Version von CP/M wurde von Gary Kildall bereits in den frühen 70ern entwickelt. Jahre bevor "Micro-Soft" 1975 und bevor Apple 1976 gegründet wurden. Er programmierte für den ersten Microprozessor der Welt, den Intel 4004 und den 8008 und entwickelte CP/M für den 8080. Intel kaufte allerdings nur Kildalls Programmiersprache PL/M für den 8080 und hatte 1974 leider noch kein Interesse an CP/M, dem ersten Disk Operating System.

Kildall schrieb CP/M auf einer PDP-10 von Digital Equipment in seiner eigenen Programmiersprache PL/M. Den PL/M-Compiler schrieb er in FORTRAN auf der PDP-10, weil er noch keinen 8080 zur Verfügung hatte. Er schrieb Programme auf dem PDP-10 Minicomputer, die den Microprozessor 8080 simulierten und ihm so die Entwicklung von CP/M ermöglichten. CP/M wurde fertig, bevor die Ziel-Hardware, ein sogenannter Microcomputer, verfügbar war. Microcomputer sind das, was wir heute als Heimrechner oder Personal Computer bezeichnen würden.

Das Betriebssystem der PDP-10, TOPS-10, war auch Anlaß für einige Konventionen, die in CP/M übernommen wurden, beispielsweise für Datei- und Gerätenamen. CP/M hatte 8.3 Dateinamen und Laufwerksbuchstaben und Kommandos wie DIR, die man heute noch kennt.

Nachdem Apple mit dem Apple II seit 1977 Erfolg hatte, beschloß IBM 1980 ebenfalls in den Markt einzusteigen. IBM sprach deshalb auch mit Kildall, der (Intergalactic) Digital Research gegründet hatte, um CP/M zu vermarkten. Aufgrund unglücklicher Umstände ergab sich jedoch keine Zusammenarbeit. IBM sprach zeitgleich auch mit Microsoft, die damals noch kein Betriebssystem im Angebot hatten, sondern nur Programmiersprachen, bezüglich BASIC für IBMs geplanten PC. Microsoft versprach dann auch, ein Betriebssystem an IBM zu liefern, hatte jedoch noch keines.

Zu dieser Zeit wartete Seattle Computer Products (SCP) für seinen 8086-basierten Computer auf CP/M-86 von Digital Research, was nicht schnell genug für ihren Geschmack geliefert werden konnte. Also heuerten sie Tim Patterson an, der einen CP/M-Clone schreiben sollte, den er QDOS nannte, kurz für Quick and Dirty OS. Ein naheliegender Name aufgrund der Zeitnot. Dieses QDOS zeigte SCP Microsoft, weil Microsoft BASIC an die Maschine von SCP anpassen sollte. Und so fand Microsoft ein passendes Betriebssystem, als sie eines für IBM brauchten. Microsoft kaufte für 50.000 USD die Rechte, QDOS weiterzuverkaufen, von SCP. Allerdings sagten sie ihnen nicht, daß sie es für IBM lizensieren wollten. Außerdem stellte Microsoft Patterson ein, um QDOS an IBMs Maschine anzupassen. Die QDOS-Version, die mit dem IBM-PC ausgeliefert wurde, nannten sie dann PC-DOS. Microsoft wurde auch erlaubt, QDOS getrennt vom PC zu verkaufen als MS-DOS. Aus Digital Researchs CP/M-86 für den IBM PC wurde später DR-DOS.

Und so kam es, daß sämtliche DOS-Versionen von CP/M abstammen und viele Eigenschaften, vom 8.3-Dateiname bis zur Benennung der Laufwerke mit Buchstaben wie A:, B:, C: und diverse Kommdozeilen-Befehle geerbt wurden.

Angriff per PCI auf die Firmware

Der Angriff funktioniert mit jedem PCI-Gerät, das ein Option-ROM hat und während des Rechnerstarts mit dem Computer verbunden ist. PCI-Express funktionieren erst recht und Thunderbolt-Geräte ebenfalls, da Thunderbolt DisplayPort mit PCI-Express vereint. Normalerweise befinden sich PCI-Geräte im Gehäuse des Rechners. Mit Thunderbolt wird nun aber ein PCI-Anschluß nach außen geführt, so daß man externe PCI-Geräte benutzen kann. Den Rechner nicht erst öffnen zu müssen, vereinfacht den Angriff.

Jede physikalische PCI-Komponente kann mehrere PCI-Funktionen haben. Eine PCI-Funktion ist eine einzelne eigenständige Funktion wie beispielsweise ein Graphikadapter. PCI-Komponenten mit mehr als einer Funktion sind Multi-Funktions-Geräte. Wenn nun die Firmware, also ein BIOS oder EFI, den Rechner vorbereitet, dann scannt sie auch den PCI-Bus. Bus ist nicht das Ding auf der Straße, sondern ein Bidirectional Universal Switch. Die Firmware untersucht beim Start des Rechners, welche Geräte und Funktionen am PCI-Bus verfügbar sind. Damit die Firmware das erkennen kann, müssen sich die Geräte an die PCI-Spezifikation halten und jede PCI-Funktion eine Gruppe von vorgeschriebenen Konfigurations-Registern bereitstellen. Diese können benutzt werden, um den Gerätetyp und den Hersteller zu bestimmen, und, um festzustellen, ob ein Expansion-ROM (Option-ROM) vorhanden ist oder nicht.

Wenn das PCI-Gerät ein Option-ROM hat, dann enthält dieses zusätzlichen Code, der unter anderem von der Firmware benötigt wird, um das PCI-Gerät zu initialisieren. Außerdem ist er noch für den gerätespezifischen Selbst-Test und das Behandeln der nötigen Interrupts zuständig. Im Option-ROM des PCI-Gerätes liegt also ein Geräte-Treiber für die Firmware. Nicht zu verwechseln mit Gerätetreibern für das später zu ladende Betriebssystem. So ein EFI-DXE-Driver wird zum Beispiel benötigt, wenn man ein PCI-Gerät ansprechen muß, bevor das Betriebssystem gestartet wird. Das ist insbesondere der Fall, wenn der Betriebssystem-Kernel von so einem PCI-Gerät geladen werden soll. Das PCI-Gerät kann eine Platte sein, die über Thunderbolt angeschlossen wird.

Legt man nun in so einem PCI-Option-ROM böswilligen Code ab, kann man damit das Betriebssystem manipulieren, bevor es gestartet wird.

Firmware-Paßwort abgreifen

Wenn der PCI-Treiber vom Option-ROM des PCI-Gerätes (Thunderbolt-Adapter) geladen wurde, kann er die Firmware ergänzen und verändern. Eine Möglichkeit besteht darin, das Simple Text Input Protocol der Firmware abzufangen, indem man den Pointer auf die ReadKeyStroke()-Funktion so verändert, daß er auf eine andere Implementierung zeigt, und zwar die, die man vom Option-ROM geladen hat. Diese Funktion bekommt jeden Tastendruck mitgeteilt. Geschickterweise ruft die neue Implementation am Schluß noch das Original auf, damit alles wie gewohnt weiterläuft.

Kernel verändern

Kurz nachdem der Kernel vom entsprechendem Bootloader geladen, aber noch nicht gestartet wurde, wird auf allen EFI-Treibern die Funktion ExitBootServices() aufgerufen, die den EFI-Treibern die Gelegenheit zum Aufräumen gibt, bevor der Kernel die Kontrolle übernimmt. In dieser Funktion hat der bösartige EFI-Treiber dann aber auch die Gelegenheit, den noch nicht gestarteten Kernel zu verändern. Dazu wird man eine Kernel-Initialisierungs-Funktion manipulieren, damit sie den Payload, den man an anderer Stelle im Kernel speicherte, lädt. Dieser initiale Payload kann dann noch mehr Code nachladen, auch über das Netzwerk, und den Kernel noch weiter verändern und ein Rootkit installieren.

Booten von anderen Laufwerken

Für den Angreifer ist beim Thunderbolt-Szenario angenehm, daß er dank externem PCI-Anschluß kein anderes Boot-Volume benutzen muß, denn es genügt, ein PCI-Gerät mit Option-ROM während des Rechnerstarts angeschlossen zu haben. Man muß nicht vom PCI-Gerät des Angreifers booten.

Wenn jedoch kein Firmware-Paßwort gesetzt ist, kann man auch von anderen Volumes booten. Bootet man von einem USB-Flash-Drive, wird dort jedoch kein EFI-DXE-Driver gesucht, weil es kein PCI-Gerät ist, und demzufolge wird auch kein dort irgendwo abgelegter EFI-DXE-Driver geladen. Die EFI-DXE-Driver werden vom EFI geladen, bevor einer der Bootloader gewählt und ausgeführt wird, um das jeweilige Betriebssystem zu laden.

Möchte man die Firmware über USB infizieren, genügt im Gegensatz zu Thunderbolt das bloße Vorhandensein beim Booten nicht: Man muß direkt vom bösartigen Volume booten, aber auch das reicht nicht aus, weil EFI keine EFI-Treiber per USB sucht und lädt. Darum muß man sich anders behelfen: Man lädt den EFI-Treiber nicht automatisch wie bei PCI, sondern händisch. Also nicht vollautomatisch durch das normale EFI-Verhalten selbst während der Plattform-Initialsierung im Driver Execution Environment (DXE), sondern erst später im Transient System Load (TSL), wenn ein Bootloader den Kernel vorbereitet, durch einen zusätzlichen Bootloader.

Dazu ersetzt man den Bootloader auf dem USB-Volume durch einen eigenen Bootloader, der einen EFI-DXE-Driver vom USB-Volume lädt und anschließend den originalen Bootloader startet. Bootloader laden normalerweise keine EFI-Treiber, weil das zu dem Zeitpunkt zu spät wäre für die Aufgabe, die ein EFI-Treiber hat: Er soll ja EFI den Zugriff auf ein PCI-Gerät oder ähnliches erst ermöglichen, um anschließend ein auf diesem Gerät befindlichen Bootloader zu starten. Wenn das Gerät aber schon zugreifbar ist, braucht man keinen EFI-Treiber mehr. Darum ist das zu späte Laden des EFI-Treibers, was auch noch an falscher Stelle passiert, eigentlich völlig unsinnig, außer daß man sich für ExitBootServices() registrieren kann und dann, wie oben auch, den Kernel modifziziert.

Die Nachteile sind in dieser Variante, daß man zusätzlich einen passenden Bootloader schreiben muß und ein entsprechendes Start-Volume vorbereiten muß damit. Ferner ist es ein viel auffälligerer Angriff, wenn der Rechner nicht vom originalen System, sondern einer anderen Platte gebootet wurde. Das Angriffsmedium kann man nämlich danach nicht einfach wieder abziehen und verschwinden. Dazu müßte der Bootloader der externen Platte das interne System starten. Viel einfacher ist es mit Thunderbolt: Beim Hochfahren anschließen, danach abziehen und weglaufen.

Schutz

Wenn ein Firmware-Paßwort gesetzt ist, kann das Booten von anderen Laufwerken verhindert werden, insbesondere, wenn beim Gerät die RAM-Bestückung unveränderbar ist. Ein Angriff über PCI auf die Firmware kann dadurch aber nicht verhindert werden. Denkbar wäre jedoch, daß später einmal nur signierte EFI-DXE-Driver von der Firmware geladen werden.

Die EFI-Firmware der Macs selbst ist signiert und ungültige Änderungen daran quittiert der Mac mit S.O.S.-Warntönen und verweigert dann das Booten. Snare machte selbst diese Erfahrung und mußte danach mühsam EFI wieder in den Originalzustand versetzen, um seinen Mac, ein älteres Modell, wieder starten zu können. Bei neueren Modellen wird ein EFI-Update, das die Signatur-Prüfung nicht besteht, erst gar nicht installiert. Siehe dazu diese Tweets mit Snare.

Kritik am Artikel

Autor des Artikels ist Uli Ries. In der Vergangenheit hatten wir schon öfters mal unterschiedliche Standpunkte bei Apple-Themen. Dieses Mal fand ich einige Stellen – nennen wir es – zu mißverständlich. Gleich am Anfang hatte ich das Gefühl, daß nicht einmal die zentralen Begriffe klar sind:

EFI Bios

Es ist entweder EFI oder BIOS, aber ein "EFI-Bios" gibt es nicht. In diesem Fall wäre EFI korrekt. EFI ist kein BIOS. EFI und BIOS sind beide eine Firmware, aber EFI ist eine wesentlich mächtigere Firmware.

Snare ist es gelungen, einen Gerätetreiber auf dem Adapter abzulegen, der automatisch beim Neustart des Rechners geladen wird

"Gerätetreiber" ist falsch, weil man dabei an einen Gerätetreiber des Betriebssystems denkt. Tatsächlich ist es aber ein EFI DXE Driver.

"Gelungen" ist auch mißverständlich, weil es sich hierbei um keinen Hack handelt, sondern um ganz normales, dokumentiertes EFI-Verhalten: EFI lädt seine DXE Driver von allen notwendigen Orten, unter anderem aus den Option-ROMs der angeschlossenen PCIe-Geräten. So ein EFI-DXE-Driver kann EFI die Hardware verfügbar machen, damit man danach das Boot-Volume wählen kann und dergleichen, oder böse sein und beispielsweise den noch nicht laufenden Betriebssystem-Kernel verändern.

Bei angestecktem Dongle zeigte der Mac beim Booten als Beweis

Es ist kein "Dongle", sondern ein "Thunderbolt to Gigabit Ethernet Adapter", dessen Erweiterungs-ROM mit einem "bösen" EFI-DXE-Driver bespielt wurde. Man könnte auch keine EFI-DXE-Driver auf einen "Dongle" aufspielen. Es gibt keinen Dongle, der einen EFI-DXE-Driver im Option-ROM hält, welcher im Preboot-Prozeß geladen wird, schon allein weil Dongle keine PCI-Geräte sind, sondern über die vom IBM-PC bekannten alten seriellen (RS-232) oder parallelen Schnittstellen (DB25, IEEE 1284) oder, im modernen Fall, über USB angeschlossen werden. Dongle werden auch nicht im Preboot-Prozeß benötigt und auch nicht einmal im Bootprozeß, sondern allein von einem davon abhängigem Programm. Ein Dongle wird eingesetzt, um ein Programm unkopierbar zu machen, weil man Hardware so schwierig kopieren kann. Die Firmware interessiert sich nicht für Dongle.

Man mag jetzt einwenden, daß umgangsprachlich jedes Ding, was man in den Rechner steckt, von manchen Leuten als Dongle bezeichnet wird. Aber auch für all diese Steckdinger interessiert sich die Firmware in diesem Angriffsszenario nicht, solange es keine PCI-Geräte sind. Und wenn das eingesteckte PCI-Gerät kein Option-ROM mit EFI-Treiber darauf hat, ist es für diesen Angriff nicht geeignet. Es ist also total irreführend, hier von einem Dongle zu sprechen.

Der von Snare programmierte Treiber kann nicht nur den Schadcode laden, der zum Modifizieren des Kernels dient

Der EFI-DXE-Driver ist selbst der Schadcode, der den Kernel verändert. Der veränderte Kernel kann dann zusätzlichen Schadcode nachladen.

Eine Lösung für das Problem lässt sich aufgrund der technischen Möglichkeiten von Thunderbolt jedoch nicht so leicht umsetzen.

Das hat nichts mit Thunderbolt zu tun, sondern damit, daß man signierte EFI-DXE-Driver verwenden müßte und nur solche von registrierten Herstellern ausführt. Sowas geht nicht in ein paar Monaten, sondern muß mit Hardware-Drittherstellern abgestimmt umgesetzt werden.

Im Gegensatz zu USB und Firewire verhindert ein Firmware-Paßwort bei PCIe das Laden von EFI-DXE-Treibern nicht. Das Problem ist also weniger Thunderbolt insgesamt, sondern der PCIe-Teil.

Nachtrag

Ende 2016 gab es Neuerungen, die das Problem grundsätzlich lösen. Siehe Mac Boot-Prozeß: Option ROMs entschärft.

Valid XHTML 1.0!

Besucherzähler


Latest Update: 05. January 2017 at 15:08h (german time)
Link: osx.realmacmark.de/osx_thunderbolt_rootkit.php