 Der nächste Talk heißt On Cover Understand On, Regaining Control of your AMD CPU. Also aus meiner Sicht in die Tage, indem man die CPUs verstehen konnte, schon lange vorbei und alles ist noch mal voll mit geschachtet in Mikroportation. Robert Alexander und Christian, die Vortragenden, haben entdeckt, dass es auf AMD CPUs tatsächlich einen eingebauten Armprozess ergibt, was ich irgendwie ziemlich verrückt finde. Und es enthält tatsächlich seine eigene Firmware. Und ja, ich bitte um Applaus und freue mich da drauf zu hören, was das so für Konsequenzen hat für uns. Okay, danke. Also bevor wir mit dem Thema anfangen, eine kurze Vorstellungsrunde. Das ist Christian, das ist Alex und ich bin Robert. Und der Grund, warum wir hier zu dritt stehen, ist, dass ich Doktorand an der Technischen Universität Berlin bin. Und Anfang 2008 habe ich mehr die sogenannte Secure Encrypted Virtualization Technologie von AMD angeschaut. Das ist Technik, die im einen, also Entschuldigung, gab es eine kurze Unterbrechung. Genau, Christian hat daran in seiner Masterarbeit gearbeitet und wir schauen uns jetzt an, was wir dabei entdeckt haben. Also fangen wir an mit dem ersten Teil der Präsentation, in dem es darum geht, ein komplett unbekanntes Subsystem zu reverseingenieren. Als wir mit unserer Forschung angefangen haben, mussten wir herausfinden, was denn der AMD Secure Prozessor, früher hieß der mal PSP Prozessor, eigentlich so genau macht. Das ist ein eingebetteter Prozessor, der in euren CPUs drin ist, sowohl in Desktop als auch Server-CPUs. Es ist ein ARM Cortex A5 Prozessor und ist seit ca. 2013 da drin. Darauf läuft ein sogenanntes sicheres Betriebssystem, also unser Kernel. Und es ist tatsächlich komplett proprietär und dokumentiert. Es gibt also Zugriff auf einen sicheren externen Speicher, hauptsächlich für seine Firmware und ein bisschen Daten und stellt der CPU hauptsächlich Krypto-Funktionalität bereit, zum Beispiel für Schlüsse-Generierung anderer Aufgaben in dieser Hinsicht. Es wird zum Beispiel auch für Secure Boot verwendet, eine sichere Boot-Technologie und agiert als ein Vertrauensanker in dieser Vertrauenskette. So, also das klingt ja gut, es macht mehr Sicherheit, es muss ja gut sein. Und euch fällt vielleicht schon auf, dass es Ähnlichkeiten zur Intermanagement Engine hat, wo wir genau auf dieser Bühne vor drei Stunden schon was drüber gehört haben. Also schauen wir uns mal ein paar Anwendungsfälle an. Dafür müssen wir uns erstmal über Vertrauen unterhalten. Die eine Art von Vertrauen, die am D-Adressieren möchte, ist bei Virtualisierung, dass man als Kunde bei einem Cloud-Anbieter dem Cloud-Anbieter nicht vertrauen muss, um da Code auszuführen. Die PSP-CPU agiert dabei also als eine entfernte, aber trotzdem vertrauenswürdige Instanz für den Kunden und verspricht dabei, dass man dem Hypervisor oder den Administratoren bei dem Cloud-Provider nicht vertrauen muss. Die andere Art von Vertrauen, die mit dem PSP-Code-Prozessor kommt, ist noch was ganz anderes. Das ist jetzt gerade erst im Linnungskönnel. Angefangen wird zu Supporten. Das funktioniert so, dass der PSP als eine Blackbox fungiert, der dem von einer anderen dritten Partei vertraut werden kann, zum Beispiel einem Content-Anbieter wie Netflix. Und das ermöglicht dann zum Beispiel, dass, obwohl der Content-Anbieter dem Hausbetriebste nicht vertraut, trotzdem der PSP-CPU-Funktionalität vertraut werden kann. Also, der PSP führt aber Code aus, dem wir nicht vertrauen können. Okay, was man hier sehen kann, ist ein klassisches Server-Mutterboard. Und ich habe hier jetzt mal drei Teile markiert, die für das Hochfahren des Systems relevant sind. Dazu gehört der Hauptprozessor, die Festplatte und der sogenannte SPI-Flash. Dieser SPI-Flash ist ein simples Speichermedium, das zum Hochfahren verfügbar ist. So, der Hauptprozessor wird also als erstes das BIOS vom SPI-Flash laden und erst später beim Hochfahren, wenn die nötigen Treiber schon verfügbar sind, kann die CPU die Festplatte auf die Festplatte zugreifen. So, wie wir jetzt von einem DS-vermarktungsfolien gesehen haben, gibt es in dieser CPU jetzt eine PSP. Die ist ein Teil der CPU und bootet, startet tatsächlich vor der CPU, vor der fertigen Initialisierung. Und als erstes wird also die sogenannte PSP-Firmware geladen und erst danach wird der klassische Boot mit dem BIOS und dem Betriebssystem gestartet. So, wo kommt diese PSP-Firmware also her? Also, das BIOS wird ja auf dem vorhin erwähnten SPI-Flash gespeichert und da sind all die Daten und der Code drin, die benutzt werden während des normalen Starts und ist arrangiert nach der UEFI-Standard-Spezifikation. So, jetzt können wir gerne mal in ein UEFI-Update von Supermicro reinkommen. So, hier sieht man jetzt ein Screenshot von dem Open Source UEFI-Tool, womit man UEFI-Images pasen kann und angucken kann. Da kann man zum Beispiel sehen, wie groß dieses Image ist, in diesem Fall 16 MB. Das ist relativ normal für ein typisches SPI-Flash und man kann hier verschiedene Volumes, also Partitionen, sehen. Außerdem kann man hier sogenannte Paddings sehen, non-empty Paddings. Das sind Freiräume, die nicht Teil des offiziellen UEFI-Standards sind, aber das sind trotzdem Daten. Die können wir aber mit dem offiziellen Standard also nicht pausen. Also, lass uns ein anderes Werkzeug benutzen. Das kennen wahrscheinlich einige von euch, das nennt sich Binwalk. Das ist ein Kommando-Zeilen-Werkzeug, um Firmwares von Electronic und Updates zu inspizieren. Und da können wir jetzt mal gucken, was für Instruktionen wir in dieser Binary finden können. So, und da sehen wir jetzt hier im zweiten Block, dass da InterX86 Anweisungen drin sind. Das ist was wir erwartet haben. Das ist ja ein BIOS Update für ein X86-System. Entsprechend werden da Instruktionen sein. Was uns mehr wundert, sind diese ARM Instruktionen, die wahrscheinlich irgendwas mit der PSP-Sfirma zu tun haben. Und was wir gesehen haben, indem wir diese Bytes im Hex-Editor angestarrt haben, für eine sehr lange Zeit, ist das sogenannte Firmware-Datei-System von der PSP. Und da gibt es eine Art Ordner-System. Das fängt an mit einem bestimmten String, der in diesem Fall Dollar-PSP ist. Dann kommt eine Check-Summe, dann kommt eine Längenangabe und dann ein unbekanntes Feld. Und dann, in jeder Zeile, die man in diesem String zeigt, sehen kann, haben wir einen Eintrag in dieser Directory, in diesem Ordner. Und jeder Eintrag hat ein Typ und eine Größe und Adresse und solche Informationen. Und dann das letzte Stück von einem Ordner ist ein spezieller Eintrag, der zu einem weiteren Ordner zeigt. Da wird also dieser Ordner weitergeführt. Und jeder dieser Einträge zeigt auf eine Art Datei. Eine Datei hat wahrscheinlich einen Körper und eventuell einen Kopfteil und eventuell eine Signatur. So, jetzt brauchen wir also einen zuverlässigen Ansatzpunkt, um dieses Datei-System zu analysieren. Und damit fangen wir an bei der Firmware Entry Table. Da ist eine bestimmte Beizquenz drin, die uns zeigt, wo im UEFI Image bestimmte interessante Punkte sind. Diese Sachen sind tatsächlich dokumentiert im Quellcode von dem Quelloffenen-Corbol-Projekt, was sehr nützlich war für unsere Nachforschung. So, um jetzt all dieses Wissen nützlich zu machen, haben wir das PSP Tool entwickelt. Das ist eine Kommando-Zahlenanwendung, die fähig ist, die AMD Firmware UEFI Updates analysieren kann. Und in der Ausgabe kann man sehen, dass zum Beispiel hier die verschiedenen Dateisystemen, Strukturen sind. Da kann man verschiedene Versionen sehen, wie zum Beispiel Firmware-Bootloader und verschiedene Versionen. Da kann man sogar herausfinden, ob die komprimiert sind, ob die signiert sind, ob die verifiziert sind über eine Signatur. Und dann, da am Ende kann man sogar noch sehen, dass der letzte Eintrag von dieser Directory dann wieder auf eine nächste zeigt, die auch gepost werden kann. So, damit ihr euch das angucken könnt, was auf eure AMD CPU läuft, könnt ihr das PSP Tool einfach so auf GitHub finden und gerne ausprobieren. Also, der PSP führt Code, aus dem wir nicht kennen, das haben wir jetzt ein bisschen aufgehoben. Und jetzt geht es eben noch darum, dass wir uns noch beschäftigen müssen, ob wir denn die Firmware auch anpassen können, dass in unseren eigenen Code ausführt. Dafür haben wir tatsächlich mit Hardware rumgespielt und etwas spezifischer mit einem SPI-Programmierer, um beliebige UEFI Images, die wir uns ausgedacht haben, auf den SPI-Flash draufzubringen. Zum Beispiel konnten wir das originale UEFI Image nehmen und da drinnen ein Bit verändern, dann haben wir versucht, das System zu booten und das halt in den allermeisten Fällen nicht geklappt. Das war eben nicht ausreichend, weil wir eben nur die Benärausgabe von diesen Experimenten hatten, also wussten nur, ob es geht oder nicht geht. Deswegen haben wir dann einen Logic Analyzer genutzt, das sieht man hier auf dem Bild, das ist ein Elektronikinstrument, mit dem man aufnehmen kann, welche Daten durch die logischen Datenleitung fließen. Und das war sehr hilfreich, weil wir damit aufzeichnet konnten, was zwischen dem SPI-Flash und dem Supermicrobot abgelaufen ist. Wenn wir uns hier also jetzt so eine Aufnahme anschauen von so einem Bootprozess, dann können wir jetzt quasi sehr viel genau herausfinden, was da eigentlich los abgeht. Was wir hier zum Beispiel sehen, ist ein Lesekommando definiert durch SPI 3, es liest die Adresse E2000 und der Flash antwortet dann mit den Daten an dieser Adresse. Es könnte man sagen, dass die Daten tatsächlich nicht so interessant sind, weil es ja das ist, was sie sowieso kontrollieren. Also was uns tatsächlich interessiert hat, war die Reihenfolge und das Timing dieser einzelnen Zugriffe. Und um das ein bisschen besser zu visualisieren, haben wir PSP Trace geschrieben, das nimmt so eine SPI Aufnahme von dem Logic Analyzer und korreliert das mit den Aufnahmen von dem PSP Tool Programm, das wir eben vorgestellt haben. Und dann bekommen wir hier eine Auflistung der verschiedenen Komponenten des PSPs und welche Reihenfolge, die zugegriffen wurden. Und ja, was wir das lernen können, schauen wir uns gleich nochmal an. Auch das haben wir wieder quäl-offen verfügbar gemacht. Wenn ihr an der Hardware interessiert seid, dann könnt ihr unseren Talk vom Camp anschauen. Aus dem Sommer dieses Jahres werden tatsächlich eine Ryzen Pro CPU zur Verfügung und haben ein Lenovo ThinkPad verwendet. Also das wäre vielleicht für Experimente zu Hause besser geeignet. Ich möchte jetzt noch zwei weitere Erkenntnisse mit euch teilen, die wir in unseren Experimenten erlangt haben. Zunächst einmal zur kryptografischen Absicherung der Dateien. Die Dateien werden abgesichert durch eine Signatur im Header und durch eine Signatur. Und ein Feld im Header enthält den Publiki, den man braucht und den öffentlichen Schlüssel immer braucht, um diese Signatur zu verifizieren. In dem Firmware-Datei-System sind tatsächlich mehrere Schlüsse. Und diese ganzen Schlüsse sind signiert vom AMD-Root-Publici, also dem Hauptschlüssel. Und da haben wir herausgefunden, dass, wenn wir das vom Flash laden, dass es dann mit einem Hash im Nullesbauenspeicher des PSPs verglichen wird zur Verifikation, dass der Root-Publici immer noch derselbe ist. Also schauen wir uns jetzt mal die Boot Prozedur an vom PSP. Wir haben einen Bootloader auf dem Chip, der da fest reingebrannt ist, und einen... So, jetzt sehen wir uns mal das Output von dem PSP-Trace-Programm näher an. Die ersten paar Lesezugriffe sind für die Firmware-Eintrags-Tabelle. Da wird dann also von dem Bootloader die PSP Directory gelesen. Dann wird ein Publiki gelesen, dann wird der verifiziert. Der wird also verglichen mit einem Hash, der im reinen Lesespeicher ist. Dann wird der PSP-Firmware-Bootloader gelesen und der wird dann wieder mit dem Publiki verifiziert. Als nächstes in der Boot Trace sehen wir ein Delay. Das liegt an ein bisschen Initialisierung in der PSP. Dann werden mehr Directories geladen und dann werden noch ein paar Applikationen geladen und auch verifiziert. Mit diesem groben Überblick der Startprozedur gebe ich euch an Alex weiter. Okay, jetzt, wo wir also die Basis von dieser Firmware analysiert haben, wollen wir natürlich etwas tiefer verstehen, was genau das jetzt macht, wie funktioniert diese Firmware, wie ist die PSP überhaupt aufgebaut, welche Hardware wird zur Verfügung gestellt und wie können wir damit arbeiten. Also, wir machen mal kurz eine Übersicht darüber, wie AMD seine Prozessoren strukturiert. Wir haben hier also einen kleinen X86-Kern, der zwei SMT-Threads mit simultanem Multithreading ausführen kann. Davon haben wir vier, die in einem Kernkomplex zusammengefasst werden. Von diesen Komplexen haben wir jetzt vielleicht mehrere, die auf einen CCD, einen Core-Complex-Di oder auch einen Chipplet zusammengefasst werden. Von diesen Chips hat man wahrscheinlich sogar auch mehrere auf seiner CPU. Innerhalb diesen CCXen sind jeweils zwei Speicherkontroller, da sind die PCI-Linien und andere Interface-Möglichkeiten, um mit anderen CPUs zu kommunizieren. Und in unserem Setup vorhin hatten wir ein zwei Sockelsystem mit zwei CPUs. Jede von diesen CPUs hatte vier CCDs. Und jetzt haben wir also nicht nur eine PSP in diesem ganzen System, sondern wir haben also bis zu acht PSPs. Jede von diesen PSPs führt eigenen Code aus und das sogar bevor alle X86-Kerne irgendwas ausgeführt haben. AMD nennt die PSP auf CCD0 die Master-PSP und alle anderen sind Slave-PSPs. Der Master initialisiert den Start des gesamten Systems und die Slaves antworten also nur auf Anfragen des der Haupt-PSP. Jede von diesen PSPs ist aber identisch. Da sie 32-bit ARM-Kerne sind, haben sie ein 32-bit Speicher-Layout. Die ersten 256 Kilobytes davon sind SRAM. Als erstes wird der Bootloader außerhalb dieses Chips lesen und innerhalb des SRAMs speichern, um ihn dann auszuführen. In diesem Firma Bootloader wird man auch die Seitentabellen haben für die Speicher-Management-Einheit und dieser Code ist dann noch getrennt in einen Kernel-Modus und in einen User-Modus. Die letzte Seite, die man hier sehen kann, ist die Bootrom-Service-Page. Da sind noch ein paar Infos über die PSP drin. Also wie viele Sockel man hat, wie welche CCD-ID man gerade hat und ein paar andere kleine Informationen wie die Nummer der Sockel und wird später nochmal interessant. Dann wird der Off-Jet-Bootloader ein paar Applikationen laden. Die werden im User-Modus ausgeführt, die rufen Code und Daten auf und enthalten auch den Stack-Speicher. Das wird in der ersten Start-up-Prozedur gemacht und wird dann später, wenn das System im Host-Modus läuft, On-Demand nachgeladen. Den Rest des Speichers müssen wir füllen mit MMIO. Also der kryptografische Co-Prozessor hat Hardware-Register, die man über den Speicher zugreifen kann und da ist außerdem noch jede Menge von denen keine Ahnung hat. Also der Start-Prozess jetzt im Detail, da hat Chris euch ja schon einen Überblick gegeben und jetzt gucken wir das mal etwas näher an. Also auf dem Chip haben wir jetzt erstmal ein Bootloader, der den Bootloader von außerhalb des Chips laden und ausführt. Dann wird der außerhalb des Chips Bootloader die Apps laden und ausführen und dann werden da verschiedene Stufen ausgeführt, von denen wir nicht so viel Ahnung haben, aber wir haben sie benannt nach dem, wie sie in der Beine auch ungefähr benannt waren. Dann wird die Bootstraping-Phase ausgeführt und das ist tatsächlich nicht nur eine Binary, die aufgerufen wird, sondern da werden tatsächlich eine Host-Binary, die dann wieder andere Binary laden und die werden dann nachgeladen und alle nacheinander ausgeführt. Das sind hier diese ABL 1 bis 5 und die werden entsprechend nacheinander ausgeführt. Dann später, wenn die PSP geladen wird, dann wird eventuell eine bestimmte SEV Funktionalität aufgerufen und erst dann werden z.B. bestimmte Apps erst ausgeführt. Weil wir ein Interface zwischen User-Modus und Kernel-Modus haben, muss man natürlich noch kommunizieren können zwischen den beiden Bootloadern. Dazu benutzen wir den SV-Zau-Sys-Calls. Insgesamt haben wir in der Firmware 76-Sys-Calls gefunden. 30 davon haben wir größtenteils rausgefunden. Da kann man z.B. Einträge aus den Flash laden und solche Dinge. 18-20 sind ungefähr zurückingeniert. Da gibt es ein paar CCP-Operationen, um Kies zu refizieren mit AES z.B. und es gibt etwas genauere kompliziertere Funktionen, um mit anderen PSPs zu kommunizieren. Und dann haben wir 18-Sys-Calls, von denen wir noch keine Ahnung haben, weil sie überhaupt nicht aufgerufen wurden bzw. wir wissen, dass sie irgendwo aufgerufen werden. Aber wir können noch nicht sagen, wie. Dann gibt es noch das System Management Network. Das habt ihr vielleicht schon mal auf den Folien gesehen. Da kann man auch nach Google, SMN, das gängige Kürzel. Da findet man eigentlich recht wenige Informationen, weder von AMD noch irgendwo sonst wo. Es gibt so ein bisschen Kotum-Linungskörnel, um die Temperatursensoren auszulesen, aber das war es eigentlich. Das ist tatsächlich ein verstecktes Kontrollnetzwerk innerhalb der CPU. Jedes Hardware-Teil drinnen ist damit verbunden und wird verwendet vom PSP, um eben die verschiedenen Hardware-Blockets zu kontrollieren während dem Boden. Der PSP greift darauf zu über MMIO. Und dann haben wir eben noch diesen UMC, diesen Memory Controller und den SMU Memory Unit. Dann haben wir noch den X86 Kern und dann noch ein paar andere Sachen, die wir noch nicht reverse-engineered haben. Und die hängen alle an diesem Netzwerk. Und um eben auf dieses Netzwerk zuzugreifen, meppt der PSP eben einen Teil dieses Netzwerk-Adress-Raums in seinen eigenen Adressraum, kann dann damit arbeiten. Wenn er fertig ist, anmäppt er den wieder. Und da haben wir eben so genannte Memory Protection Slots, Speicherschutzbereiche gefunden, die der PSP benutzt, um bestimmte Speichelbereiche den regulären X86 Kern wegzunehmen. Da gibt es dann eben entsprechende Register für, um das an- und auszuschalten, die Ranges, die Bereiche zu konfigurieren, etc. Der interessante Teil hierbei ist, dass der X86 Kern nur erlesen wird, wenn alle Bits auf 1 gesetzt wird in diesem Teil. Das wird zum Beispiel für den UE-Fee-Modus benötigt oder für das Secure Encrypted Virtualization-Feature von AMD. Was wir dann gemacht haben, ist, dass wir einfach mal Strings über alle Module aufgerufen haben und damit tatsächlich sehr viele interessante Debugstrings gefunden, also Debug-Ausgaben. Als wir uns das dann eben in dem Disassembly angeschaut haben, haben wir herausgefunden, dass die allermeisten Debug-Ausgaben sind, die bei einem ganz bestimmten SVC-Coll, nämlich Nummer 6, aufgerufen werden. Das Problem ist nur, dass in der offiziell freigegebenen Firmware dieser System-Coll gar nicht implementiert sind. Also es ist offensichtlich irgendwas mit dem Debug-Images zu tun. Aber da kamen wir nicht dran. Das Problem ist, dass wir auch in dieser Phase noch keinen X86-Speicher verfügbar haben, indem wir das irgendwie zwischendspeichern könnten, um es besser zu analysieren. Aber wir haben ja den SPI-Flash und glücklicherweise hat das Schreiben auf diesen SPI-Flash, das war auf dem Bus sichtbar, obwohl es dann tatsächlich nicht auf dem SPI geschrieben wurde. Das konnten wir dann eben auch aufzeichnen. Schon uns das später nochmal genauer an. Wir gehen jetzt erstmal davon aus, dass wir Code auf dem PSP ausführen können und bauen dann unseren eigenen Händler für den SVC-6-Coll rein und schreiben dann die Daten, die uns interessieren auf den SPI-Bus raus, filtern den restlichen Datenverkehr auf dem SPI-Bus und bekommen dann eben ein Log, ein Log-Datei, das sogenannte PSP-Log, und das sieht man hier. Das hier gerade durch scrollt. Das ist das ganz initiale Buten des PSPs. Es ist tatsächlich mehrere Megabytes lang und das sind wir jetzt nicht durch alles durchgegangen. Da ist bestimmt viel interessantes Zeug drin, was wir noch gar nicht genau wissen. Also, vielen Dank. So, der nächste Schritt war also jetzt mal zu erforschen, was ist jetzt der hier versteckte Teil von diesem Systemmanagement-Netzwerk. Statt jetzt die ganze Zeit neue Fünge mal zu schreiben und die, was mal wieder zu debuggen, was extrem aufwendig wäre, haben wir also unser eigenes System eingerichtet, wo wir dynamisch die x86 Kerne des Systems benutzen können, um in das Systemmanagement-Netzwerk reinzuschreiben. Dazu haben wir die SEV-App ersetzt mit einem Stub, die Primitives zur Verfügung stellt, über die wir dann Adressen schreiben können und Systemcalls ausführen und auch PSP-Speicherlesen und schreiben können. Und da die PSP als ein separates PCIe-Divise für den x86 Prozessor zur Verfügung gestellt wird, können wir einfach einen normalen Linux-Kerneltreiber benutzen und dafür einen Userspace-Drapper für einen neuen Treiber schreiben und konnten so ganz einfach mit einer Python-Stelle dynamisch die PSP kontrollieren, indem wir diese verschiedenen Sub-Komponenten steuern. Hier in diesem Code Snippet kann man also zum Beispiel sehen, was wir benutzt haben, um herauszufinden, wie diese Memory Protection Slots funktionieren. Da rufen hier verschiedene SMN-Syscall-Handler auf und schreiben an verschiedenen Speicher. Und das machen wir für alle PSPs im System. Das heißt, die Master-PSP kann alle diese Requests auch weiterführen an die Slave-PSPs. Das nächste, was wir machen wollten, ist, dass wir auch die CPP-App raus analysieren wollten, eine DSCV-App. Und da wir unseren PSP-Stub ja schon am Laufen hatten und den noch nicht teilen wollten, mussten wir eine andere Methode dafür finden und haben deswegen den PSP-Emulator entwickelt. Und mit diesem Lipp-PSP-Proxy, den wir entwickelt haben, können wir jetzt die Anforderungen an die SCV weiterleiten. Der PSP-Emulator kann im Moment die größten Teile simulieren, aber ist noch nicht fertig und wir sind dann auch in der aktiven Entwicklung. So, was es also macht, ist, dass das AMD SCV-Tool, das den Host Managed und die Schlüssel und Zertifikate auf dem System verweitet, die werden wieder dann an unseren PSP-Emulator weitergeschickt, der auf der Unicorn-Engine läuft und alle Hardware-Sachen, die wir noch nicht emulieren können, die werden eigentlich tatsächlich heruntergeleitet und wenn das fertig ist, dann kommt das wieder zurück an das AMD SCV-Tool und so können wir manche der Anforderungen der Instruktion erfolgreich ausführen bisher. Was man hier sehen kann, ist ein kurzer Ausschnitt von einer der AMD Abläufe. Da sieht man, dass wir einen CPC-Request gemacht haben und da ist eine Menge noch unbekanntes Zeug, aber das wird uns auf jeden Fall in der weiteren Entwicklung helfen. Außer der normalen Codausführung wollen wir in der Zukunft auch Funktionalität hinzufügen, die im Moment nur auf der Epic Server-Plattform von AMD verfügbar ist, wie zum Beispiel sichere virtuelle Maschinen. Wir wissen aber noch nicht, wie gut der Hardware-Support da ist oder ob das nur eine Firma-Beschränkung ist. Da sind wir noch am Forschen. Falls ihr interessiert seid, der Code ist hier auf unserem Github-Repository, der wird bald verfügbar gemacht. Wir haben da verschiedene Repositories zur Verfügung. Ihr habt schon verschiedene gesehen. Wir sind alle verfügbar. Und wir haben da den PSP-Emulator, wir haben das PSP-Apps-Repository, wenn ihr euren eigenen PSP-Apps schreiben wollt und weiteres. Damit wollen wir weitergeben an Robert, der euch erklären wird, wie wir die Codausführung auf der PSP erreicht haben. Okay. Also alles, wo Alex drüber geredet hat, dafür brauchen wir Codausführung. Es kommt gerade kein Ton an. Oh, Mikro. Besser. Okay. Also dieser Teil, um den PSP zu übernehmen, ist auch wieder in zwei Teile geteilt. Christian hat uns ja schon erklärt, wie die Firmware aussieht und wie der SPI-Flesche aussieht und wie wir das kontrollieren können. Weil das eben etwas ist, dass wir physisch kontrollieren und auf das wir flaschen können, was wir wollen. So, wie soll das nochmal auswerten? Auf dem SPI-Flesche ist das Verzeichnis mit den Headern und den Einträgen, also den Entries. Und ein Entry besteht aus ID, Adresse und Größe. Wir hatten uns Dateien angeschaut. Das heißt, ein Entry kann z.B. sie auf eine Datei beziehen. Und dann haben wir noch secondary directories, also zwei Folgeverzeichnisse, wo es dann eben weitergeht mit dem aktuellen Verzeichnis. So. Die Dateien können wir nicht direkt manipulieren, denn sie sind ja über die Signatur-Integritätsgeschützt und das System würde dann sofort reboten. Was wir aber manipulieren können, sind die Verzeichnisse, denn die sind nicht direkt geschützt. Speziell, was wir machen können, ist, dass wir zusätzliche Einträge da rein bauen können, die vielleicht auf dieselben Dateien zeigen oder so. Es ist nicht so wichtig. Wir können aber auch Einträge löschen oder wir können Einträge verändern. Also können wir z.B. diese Referenz auf so ein secondary directory verändern. Und da können wir z.B. die Größe anpassen und die z.B. kleiner machen und können das Verzeichnis so aussehen lassen, als ob es kleiner wäre, obwohl wir gar nicht die einzelnen Einträge löschen. Und beim Buten gibt es eben dieses PSP-Verzeichnis, über das Christian schon geredet hat. Das wird dabei eben ausgelesen und das enthält z.B. den AMD Public Key, der wird verwendet, um alle SCV Anwendungen, die geladen werden, zu validieren. Und dann gibt es noch das zweite Verzeichnis, die Inhalte drinnen ist gerade nicht so wichtig. Der On Ship Bootloader setzt also diese Bootroom Service Page auf, die Alex schon erklärt hat. Und diese Page enthält eben eine Kopie der Einträge des ersten Verzeichnisses. Was er auch kopieren wird, ist nochmal der AMD Public Key, den er auf die Bootroom Service Page kopiert. Und das wird nur gemacht, wenn dieser Public Key-Datei auch tatsächlich verifiziert wurde vorher. So, und von nun an wird eben die Inhalte dieser Bootroom Service Page genutzt, um Anwendungen zu validieren. Der On Ship Bootloader nutzt dann später diese Bootroom Service Page um dann wieder neue Einträge nachzuladen und diese zu erweitern. Und er kennt schon irgendwie, wo das hingeht, was könnte jetzt möglicherweise schiefgehen. Also, wir haben hier halt nur einen Eintrag, wir haben hier Platz für 64 Einträge. Und wenn wir da mehr Einträge reinschreiben, dann treffen wir irgendwann auf den AMD Public Key. Und das heißt, der On Ship Bootloader sollte doch am besten schon überprüfen, dass wir maximal 64 Einträge kopieren. Und hier sehen wir so eine Funktion. Und, ja, da würden wir irgendwie so was erwarten. Wenn wir bei mehr als 64 Einträgen ist, dann kopieren wir nichts. Das Problem ist nur, dass diese Zahl sich auf die Einträge in einem zweiten Sekundärverzeichnis bezieht. Und da drin gibt es schon Einträge. Das heißt, was wir tatsächlich mit dieser Überprüfung durchsetzen, ist, dass, was auch immer wir dann auch hinten dranhängen, vielen 64 Einträgen sind, aber da könnten da eben schon der AMD Public Key drin sein. Und das bedeutet, dass wir also unseren eigenen Public Key in die Verzeichnungsstruktur des Firmwärterteilsystems platzieren. Und was dann der Bootloader macht, ist dann eben genau die, den Public Key-Kopieren, den wir da platziert haben. Okay, also was bedeutet das jetzt für uns? Alles dieses Lesen findet statt, bevor die erste Applikation geladen wird. Und das bedeutet, dass wir jetzt kontrollieren, wie die allererste Applikation geladen wird und können ihren Inhalt kontrollieren. Und von da aus können wir dann alles andere und auch den Userland-Teil von diesem Prozessor kontrollieren. Kommen wir jetzt also zum nächsten Teil. Das natürliche nächste Ziel ist, dass wir im Userland-Code ausführen können. Wir wollen aber natürlich auch den Kernel-Mode bekommen. Wie können wir den Kernel-Mode übernennen? Lassen Sie mal gucken, wie der Aufteilung zwischen Kernel- und User-Mode überhaupt stattfindet. Wenn wir jetzt den virtuellen Adressraum angucken, dann sieht man, dass es einen festen Abschnitt gibt zwischen dem Kernelspeicher und dem User-Mode-Speicher. Unsere Applikation, die wir kontrollieren, kann natürlich versuchen, den Kernelspeicher auf den Kernelspeicher zuzugreifen, aber die Memory-Management-Unit wird das verhindern. Also, lassen Sie mal gucken, wie das überhaupt zur Zeit funktioniert. Die Bootloader-Komponente, wenn wir spezifizieren, was jetzt genau die Privilegien sind, dann sehen wir, dass der Code und die Daten liegen vom Kernel. Und der Code und die Directories, die werden halt analysiert und gelesen. Die Struktur ist genauso wie wir das von vorhin kennen. Und die Einträge hier spielen wieder nicht wirklich eine Rolle. Was wir also machen können während des Starts, wird der Bootloader diese Einträge in die Datensektion vom Kernel speichern. Da wird zum Beispiel, so könnte das in C aussehen, so ähnlich wie mit einem Kopie aus, da wird das Ziel angegeben, wo hin kopiert wird. Wir brauchen eine Quelle, von der kopiert wird. Und die haben wir ja schon kontrolliert. Das ist natürlich ganz gut. Und man muss auch noch eine Größe übergeben. Wo bekommen wir diese Größe her? Na ja, das steht ja in den Einträgen drin. Wie groß die nächste Directorie sein wird. Aber die gehört ja auch uns. Das können wir auch kontrollieren. So, wir haben also eine vorgegebene Kopieoperation mit Daten, die wir vorgeben können, mit einer Größe, die wir vorgeben können. Das ist ein sehr altes Meme. Und ich glaube, das passt, weil dieser Bug ist so alt und einfach zu verhindern. Aber für uns ist es natürlich, kommt das sehr gelegen. Das heißt, alles, was hier rot ist, können wir jetzt kontrollieren. Das Ding ist, wie man sieht, der Code ist leider immer noch nicht ein Teil dessen, was wir kontrollieren können. Das könnte hier dann so liegen, was für uns interessant ist, was wir überschreiben können. Das Ding ist, da sind die Page-Tabellen. Die Page-Tabellen sind Teil der Datensektion, im privilegierten Teil des virtuellen Speichers. Das heißt, wieder, was wir machen können, ist, dass wir unsere eigenen Page-Tabels da reinsprechen, die Daten werden kopiert und überschreiben die Page-Tabellen. Und wenn wir das jetzt genauer angucken im virtuellen Speicherübersicht, dann werden unsere Speichertabellen den virtuellen Speicher etwas anders definieren und sagen einfach, der komplette Speicher ist nutzbar beschreibbar. Und das heißt, jede Applikation kann jetzt den privilegierten Speicher bearbeiten und gerne auch den Bootloader überschreiben. Dafür müssten wir natürlich alles einmal reimplimentieren, aber wir können jetzt das sichere Betriebssystem patchen. Also das bedeutet, dass das Pausen von diesem Verzeichnis schon passiert, bevor die Anwendung läuft. Dann kontrollieren wir die erste Anwendung, die übernimmt dann den Bootloader und von da an haben wir dann einfach alles. Also diese ganzen Probleme wurden behoben und die wurden tatsächlich behoben, bevor wir sie überhaupt entdeckt haben. Das heißt, wir sind wahrscheinlich gar nicht die Ersten, die sie entdeckt haben. Wenn Sie sich vielleicht, manche von Euch erinnern, dann gab es eine Webseite AMD Flores. Sie haben nicht so viele technische Details präsentiert. Vielleicht haben sie irgendwas Ähnliches wie das hier gefunden. Ich weiß es nicht. Aber es ist für uns gar nicht so wichtig, denn der PSP implementiert gar keine Verhindernung von Rollbacks auf ältere Firmware-Images. Und das heißt, wir können einfach unsere CPU downgraden auf ältere Firmware und dann unseren Angriff starten. Und das, was wir also gemacht haben, ist, dass wir das auf einem Epic Naples, also 10-1-pro-selben-Service-Themen, zwei Anwendungen gebracht haben. Und man kann das nicht direkt auf jedem AMD-System anwenden, weil der Bootloader mit einem Key, mit einem Schlüssel signiert wurde, der speziell für diese Epic Naples-CPUs vorgesehen war. Aber wir gehen davon aus, dass man zumindest für die Ryzen-CPUs der ersten Generation das wahrscheinlich auch machen kann, wenn wir da auch so ein Key, glauben wir, gesehen haben. Und für den Rest wissen wir es nicht. Vielleicht gibt es da endlich Probleme. Aber da haben wir keine Informationen zu. Die Frage ist jetzt, ist das jetzt wirklich ein Sicherheitsproblem? Also natürlich ist es irgendwie eins, aber für wen denn genau? Denn alles, was wir gemacht haben, braucht physischen Zugriff auf das Gerät. Also wenn es mein Laptop wäre, dann wäre ich jetzt persönlich nicht so sehr besorgt. Aber es gibt Situationen, in denen das ein Problem sein kann. Zum Beispiel, wenn man sich auf Secure Boot verlassen muss, denn der PSP ist der erste Prozessor beim Boot. Und wenn der kompromittiert wurde, ist alles andere auch kompromittiert. Christian hat schon erklärt, dass AMD plant den Secure Encrypted Realization Environment, den PSP als Trusted Execution Environment zu nutzen. Und das ist natürlich auch schlecht, wenn der kompromittiert wurde. Und dann zum letzten Teil gibt es noch die Secure Encrypted Virtualization Technologie von AMD, die auch davon abhängt, dass der PSP nicht kompromittiert ist. Darüber haben wir auch ein Paper publiziert. Das könnt ihr dann nachlesen. Das ist hier unten verlinkt. Aber für uns ist das erstmal nur eine gute Gelegenheit, um mehr Einsicht in die Funktionsweise des PSP zu bekommen. Und das ermöglicht uns noch mehr Forschung über die anderen Subsysteme der AMD CPUs. Zum Beispiel, dass der PSP dafür zuständig ist, die SMU-Firmware zu laden oder Code im SSM-Code auszuführen. Das ist der Ring-2, also ein höher privilegierter Modus, als der, in dem der Kern läuft. Und mit dem PSP hat man eben Zugruf auf diesen Code, kann den, ja, ersetzen, analysieren oder so. Und der PSP ist dafür zuständig, den ganzen Rest vom X86-Boot zu starten, zum Beispiel eben das UEFI. Gut, vielen Dank, das war's. Dieser Talk wurde übersetzt vom C3-Lingo. Man kann uns Feedback hinterlassen oft auf Twitter unter ad C3-Lingo unter dem Hashtag C3T. Übersetzt wurde von mir, Oscar und Problem. Und jetzt kommen wir zu den Fragen. Mikrofon Nummer 1. Grund, warum die Page-Tabellen am Ende des Datensemians sind. Hm, ich glaube nicht. Also, man muss ja irgendwo hin tun und, ja. Also, ich habe echt keine Ahnung. Der Signal Engel hat eine Frage. Ja, die Frage geht an den ersten Präsentanten. Hattet ihr Zugruf auf den SPI-Modator und habt ihr geguckt, ob es da Time of Use-Attacken gab zur Verfügung? Also ja, das hatten, nein, wir hatten Zugrufe auf verschiedene Tools, aber so eine Attacker, so eine Time of Checkers, so eine Time of Use-Attacken war nicht wirklich nötig, um die Attacken anzuwenden, die wir zahlenwährenden gebracht haben. Und wir sehen da jetzt auch gerade keine Möglichkeit, dass so eine Talk to Attacker zahlen werden zu bringen. Okay, ein Mikrofon 5. Okay, ich habe mich gefragt, ob wenn man das Blutraum anguckt, ja, natürlich. Also, die Sache ist, dass wir den Code für das Blutraum nicht im Blutraum finden können, nachdem wir unsere Attacker durchgeführt haben. Also, wahrscheinlich ist der Blutraumcode gar nicht da, was es natürlich dann schwierig macht, das zu analysieren. Wir haben versucht, die Verzeichnungsgrößen zu manipulieren, also ein paar einfache Möglichkeiten zu finden, was irgendwie verdächtig wäre. Ein Mikrofon 2. Danke für eure Nachforschungen. Ihr habt wirklich sehr schöne große Macht über das System. Habt ihr Pläne, eine eigene, minimale PSP firmware zu erstellen, die das System zwar funktionieren lässt, aber ohne den ganzen unbekannten, unvertrauten Code? Also, ich würde es jetzt nicht unbedingt Pläne nennen. Also, natürlich gibt es Ideen, das zu machen, aber manches von der Funktionalität, die man von AMD braucht, ist tatsächlich nicht optional. Also, das wo Alex zum Beispiel darüber geredet hat, da ist zum Beispiel das DRAM Training drin und ohne das gibt es einfach keinen Zugriff auf den Hauptspeicher das ist eine 80 Kern und nicht funktionieren und ohne Zugriff auf die Handbücher, das alles neu zu implementieren, das ist ziemlich schwierig. Also, ich gehe nicht davon aus, dass es so bald möglich sein wird. Jetzt, also besonders bezogen auf den Management Engine Cleaner für Interest Prozessoren, der ja die Management Engine zum Beispiel kleiner macht. Also, die AMD-Firmware ist tatsächlich relativ dünn oder schmal. Also, wenn wir mal schauen könnten, wäre die SEV-Firmware, die eben erst auf Nachfrage nachgeladen wird und man kann das tatsächlich abschalten, indem man einfach ein Bit in dieser Datei umstellt. Das System wurde zwar immer noch irgendwie buten, aber wenn es dann anfängt, die SEV-Technologie zu initialisieren, würde der Körner dann sagen, es funktioniert nicht und dann werden wir das abgeschaltet. Okay, die letzte Frage ist funktioniert die PSP irgendwie im Code? Also, wir sehen nicht, dass es irgendwie ein Micro-Code zusammenhängt. Okay, Mikrofon 3, okay, erstmal Danke für den tollen Talk. Ich habe eine Frage. Habt ihr vielleicht irgendwas Böses oder potenziell Böses im Code gefunden? Was und was es macht? Nein, soweit noch nicht. Wir haben jetzt noch nichts gefunden, was für eine Attacke oder so was genutzt ist, was der PSP vielleicht machen könnte, wäre PCA Express-Geräte zuzugreifen. Aber also, wir haben Code dafür gefunden, aber wir haben noch nicht sicher, ob er auch wirklich tatsächlich genutzt wird. Das liegt vielleicht daran, dass der PSP auch auf Grafikkarten von AMD zum Einsatz kommt. Aber bisher sieht das alles relativ sauber aus im Vergleich zur Internetmanagement Engine. Okay, eine Frage aus dem Internet. Ist der AMD Publici ein RSA 256-Bit Schlüssel? Es ist tatsächlich ein RSA-Ki, aber es ist für die erste Generation EPIC ein 2048-Bit Schlüssel und für die späteren Generation 4096-Bit. Mikrofon 2, es scheint mir als wäre das Verhindern von den Flächen von alten verwundbaren Filmwares ist wahrscheinlich relativ wichtig für Dinge wie verschlüsselte, sichere Virtualisierung. Könnt ihr mir sagen, wie schwierig es ist für AMD, das Backrolling von Filmwares zu verbieten? Also technisch gesehen ist das zum Beispiel bei mobilen Geräten so, dass da einfach schon von der VR eingebaut wird, aber das in Redespektive da hineinzubauen ist relativ schwierig, weil da eben der On-Chip und Off-Chip-Kontroller zusammenspielen müssen, um diese Funktion zu erreichen. Also da ist zum Beispiel die Stelle, die sich anschaut, ob die Firmware-Version zusammenpassen oder nicht, und dadurch, dass man eben nicht den On-Chip-Boot-Rom anpassen kann über ein Software-Update, damit nicht anpassen. Wenn ihr unser Paper anschaut, dann sieht man zum Beispiel auch, dass das ziemlich schlecht ist für die SCV-Technologie, weil es eben einzelne Schlüsse gibt, die genutzt werden können, um SCV-Gäste anzugreifen. Okay, danke. Nächste Frage. Habt ihr analysiert, wie die API zum Stichkern funktioniert? Habt ihr da irgendwas gefunden, was eventuell angegriffen werden kann, ohne dass man irgendwas neu flaschen muss, dass man direkt aus der x86-Umgebung auf die PSP zugreifen kann? Also wir haben versucht, da für notwendigen Code zu finden, um mit x86 zu arbeiten. Und wir haben da auch einen Code gefunden, der nach der Systeminselisierung für Anwendung kommt. Aber ansonsten haben wir da noch nichts gefunden. Und wir haben uns auch eigentlich andere Sachen geguckt, zum Beispiel den Speicherkontroller und hatten jetzt nicht so sehr Fokus auf das x86-Interface. Das BIOS kann mit dem PSP kommunizieren über ein sogenanntes Mailbox-Register, das im x86 MemoryMap.io-Adressraum sichtbar ist. Dann zum Beispiel den PSP sagen, das hier ist mein Systemmanagement-Mund. Speichelbereich bitte schützt den. Aber ansonsten können wir noch nichts finden. Okay, Mikrofon 4. Ist es richtig, dass eure Arbeit 100% Open Source-Filmware für die PSP erlaubt? Und wenn ja, habt ihr überhaupt schon Coreboot kontaktiert, damit es 100% Open Source gibt? Also 100% Open Source. Also in Hinblick auf den PSP gibt es halt diesen On-Chip-Boot-Rom, den wir nicht ersetzen können. Also der ist definitiv closed-source und dann ist eben noch der Code, der durch den Off-Chip-Boat-Loader läuft, bis der erste Exploit kommt, der nicht Open Source ist. Ab dem Zeitpunkt könnte man den PSP komplett übernehmen mit dem eigenen Code, aber man müsste eben einen Haufen Funktionalität neu implementieren ohne irgendwelchen Doku. Und das ist technisch schon irgendwie möglich, aber praktisch wahrscheinlich. Bin ich wenigstens sicher. Okay, die nächste Frage aus dem Internet. Ist es möglich, die PSP-Filmware aus Linux und BSD zu sperren mit speziellen Bootflags? Sorry, was zu sperren? Die PSP zu sperren? Also was Robert ja schon gesagt hat, ist, dass man eben ein Bit im SPI Flash umkippen kann und wenn es dann eben zur Systeminitialisierung kommt, dann wird nicht die SEV App ausgeführt, weil es da eben bei der Signatur dann nicht mehr stimmt und bei das Interface, wo das jetzt genau passiert, konnten wir jetzt nicht wirklich finden. Okay, Microphone 2 habt ihr versucht irgendwelche Superkräfte der PSP zu aktivieren, zum Beispiel JTAG oder spezielle Spannungen eventuell für die CPU? Also es gibt so ein paar Anwendungen, die bestimmt das Trings haben, zum Beispiel Debug-Anlog, das klingt erstmal interessant, aber JTAG also ich meine, wo wir das jetzt genau an den ankommen auf den PSP, du müsst ja irgendwie eine Verbindung zu diesen PSP haben, jetzt gibt's natürlich PSP Debug in Support bei Intel, also könnte man das jetzt irgendwie durchreichen, aber ich hab irgendwie den Verdacht, dass diese Debug Anlog App ja dazu führt, dass man einen Debug-Modus aktivieren kann, mit dem man dann etwas anderes bekommt, aber das haben wir uns noch nicht genau angeschaut. Okay, also ich bin jetzt wirklich kein Anwalt, aber könnte AMD in irgendeiner Weise euch daran hindern, dass ihr das macht, was ihr macht? Wahrscheinlich nicht, keine Ahnung, sehen wir mal. Und also wie ich vorher schon gesagt hab, wir sind dieses Initial entdeckt haben, es geht nicht wirklich um diese Probleme, für mich sind diese Probleme ein netter Weg eine tiefere Einsicht in die Funktionsweise PSP zu bekommen, aber es geht jetzt nicht primär um die Security-Probleme, also das heißt, wenn AMD irgendwie ein Verklagen wollen würde, dann hätten sie das wahrscheinlich schon getan, vielleicht haben sie es auch, ich weiß es nicht. Okay, noch eine Frage Wie lange hat es für euch gedauert, alle diese Sachen reverse zu engenieren und zu analysieren? Puh, also am Anfang 2018 hat Christian mit seiner Master thesis angefangen und hat da sehr viel Zeit darauf verwendet ausfinden, wie dieses Firmware-Datei-System funktioniert und wie der Bootprozess funktioniert und der PSP Trace und PSP Tool eben um besser zu verstehen, wie die Komponenten der Firmware funktionieren und Alex hat dann im Mai dieses Jahr angefangen und also wir arbeiten noch immer daran der Emulator als wir verstanden hatten, wie dann der PSP so gut funktioniert, dann war der Emulator relativ einfach aber es hat nicht so viel Zeit gebraucht um den zu entwickeln, aber es ist natürlich viel Vorarbeit passiert. Okay, gibt es noch eine Frage? Ah ja, noch eine aus dem Internet habt ihr versucht die PSP irgendwie kaputt zu glitchen, indem man die Spannungen an den verschiedenen Pins variiert? Also ich finde unser Ansatz ist ein bisschen einfach, aber wir haben es eigentlich haben wir es gar nicht ausprobiert. Ja, ich sehe da jetzt keine weiteren Fragen und bitte nochmal um Applaus. Amit verabschiedet sich aus.