Hacken von ESP32 durch Umgehen der sicheren Boot- und Flash-Verschlüsselung (CVE-2020-13629)

Wir haben eine Studie des Espressif ESP32-Mikrocontrollers auf Widerstandsfähigkeit gegen Angriffe durchgeführt, die mit der Methode durchgeführt wurden, Fehler beim Betrieb von Chips einzuführen (Fehlerinjektion). Wir sind schrittweise dazu übergegangen, Schwachstellen zu finden, die es uns ermöglichen, sichere Boot- und Flash-Verschlüsselungsmechanismen mit nur einem Fehler zu umgehen, der durch ein elektromagnetisches Feld verursacht wird. Darüber hinaus konnten wir nach erfolgreicher Durchführung des Angriffs nicht nur beliebigen Code ausführen, sondern auch die entschlüsselten Flash-Speicherdaten empfangen. Espressif hat diese Sicherheitsanfälligkeit in der CVE-Datenbank unter dem Code CVE-2020-13629 gemeldet







... Beachten Sie beim Lesen des in diesem Artikel beschriebenen Angriffs, dass er für ESP32-Chips der Versionen 0 und 1 gilt. Neuere ESP32-V3 unterstützen die bei diesem Angriff verwendete Funktion zum Deaktivieren des UART-Bootloaders.



UART Bootloader



In ESP32 ist der UART-Bootloader im ROM-Code implementiert. Dies ermöglicht es unter anderem, Programme in einen externen Flash-Speicher zu schreiben. Die Implementierung des UART-Bootloaders als im ROM gespeicherter Code ist eine gängige Lösung. Es ist ziemlich zuverlässig, da ein solcher Code nicht leicht beschädigt werden kann. Wenn diese Funktionalität auf dem im externen Flash-Speicher gespeicherten Code basiert, würde eine Beschädigung dieses Speichers zur vollständigen Inoperabilität des Mikrocontrollers führen.



Normalerweise wird der Zugriff auf solche Funktionen organisiert, wenn der Chip in einem speziellen Modus im Boot-Modus geladen wird. Die Auswahl dieses Modus erfolgt über Kontakt-Jumper (oder Jumper), die vor dem Neustart des Geräts festgelegt wurden. Der ESP32 verwendet hierfür einen Pin G0.



UART Bootloader unterstützt viele interessanteAnweisungen , die zum Lesen / Schreiben von Speicher und Registern und sogar zum Ausführen von Programmen aus dem SRAM verwendet werden können.



▍ Beliebige Codeausführung



UART Loader unterstützt das Laden und Ausführen von beliebigem Code mithilfe eines Befehls load_ram. Das ESP32-SDK enthält alle Tools, die zum Kompilieren von Code erforderlich sind, der vom SRAM ausgeführt werden kann. Das folgende Codefragment gibt beispielsweise eine Zeichenfolge SRAM CODE\nan die serielle Schnittstelle aus.



void __attribute__((noreturn)) call_start_cpu0()
{
    ets_printf("SRAM CODE\n");
    while (1);
}


Mit einem Tool esptool.py, das Teil des ESP32-SDK ist, können kompilierte Binärdateien in SRAM geladen werden. Dann können diese Dateien ausgeführt werden.



esptool.py --chip esp32 --no-stub --port COM3 load_ram code.bin


Interessanterweise kann der UART-Bootloader nicht deaktiviert werden. Daher besteht immer Zugriff darauf, auch wenn der sichere Start und die Verschlüsselung des Flash-Speichers aktiviert sind.



▍ Zusätzliche Sicherheitsmaßnahmen



Wenn keine zusätzlichen Sicherheitsmaßnahmen getroffen werden, macht die ständige Verfügbarkeit des UART-Bootloaders die sicheren Start- und Verschlüsselungsmechanismen des Flash-Speichers offensichtlich praktisch unbrauchbar. Aus diesem Grund hat Espressif zusätzliche Sicherheitsmechanismen implementiert, die auf der eFuse-Technologie basieren.



Dies sind die Bits, die zum Konfigurieren der Sicherheitsparameter verwendet werden und in einem speziellen Speicher gespeichert sind, der häufig als OTP-Speicher (One-Time-Programmable Memory) bezeichnet wird. Bits in einem solchen Speicher können sich nur von 0 auf 1 ändern, jedoch nicht in die entgegengesetzte Richtung. Dies stellt sicher, dass ein Bit, das eine Funktion aktiviert, nie wieder gelöscht wird. Wenn der ESP32 im UART-Bootloader-Modus betrieben wird, werden die folgenden Bits des OTP-Speichers verwendet, um bestimmte Funktionen zu deaktivieren:



  • DISABLE_DL_ENCRYPT: -.
  • DISABLE_DL_DECRYPT: -.
  • DISABLE_DL_CACHE: MMU- -.


Das OTP-Speicherbit interessiert uns am meisten DISABLE_DL_DECRYPT, da es die transparente Entschlüsselung der im Flash-Speicher gespeicherten Daten deaktiviert.



Wenn dieses Bit nicht gesetzt ist, können Sie beim Laden des Mikrocontrollers mit dem UART-Bootloader den einfachen Zugriff auf die im Flash-Speicher gespeicherten Daten organisieren und wie bei normalem Text damit arbeiten.



Wenn dieses Bit gesetzt ist, können im Startmodus mit dem UART-Bootloader nur verschlüsselte Daten aus dem Speicher gelesen werden. Die Flash-Verschlüsselungsfunktion, die vollständig in der Hardware implementiert und für den Prozessor transparent ist, wird nur aktiviert, wenn der ESP32 im normalen Modus gestartet wird.



Bei der Ausführung des Angriffs, von dem wir hier sprechen, werden alle diese Bits auf 1 gesetzt.



SRAM-Daten bleiben nach dem Hot-Reset des Geräts bestehen



Der vom ESP32-Mikrocontroller verwendete SRAM ist weit verbreitet. Das gleiche wird von vielen Chips verwendet. Es wird normalerweise in Verbindung mit ROM verwendet und ist für das Starten des ersten Bootloaders aus dem Flash-Speicher verantwortlich. Ein solcher Speicher ist in den frühen Phasen des Ladens bequem zu verwenden, da vor der Verwendung nichts konfiguriert werden muss.



Erfahrungen aus früheren Untersuchungen zeigen, dass sich die im SRAM gespeicherten Daten erst ändern, wenn sie überschrieben werden oder wenn die Speicherzellen nicht mehr mit Strom versorgt werden. Nach einem Kaltstart (dh einem Ein- / Ausschaltzyklus) des Chips wird der SRAM-Inhalt auf seinen Standardzustand zurückgesetzt. Jeder Chip eines solchen Speichers zeichnet sich durch einen eindeutigen (man könnte sagen halbzufälligen) Zustand der auf die Werte 0 und 1 gesetzten Bits aus.



Nach einem Hot-Neustart kann es jedoch vorkommen, dass die im SRAM gespeicherten Daten unverändert bleiben, wenn der Chip ohne Ausschalten des Geräts neu gestartet wird. Dies ist in der folgenden Abbildung dargestellt.





Auswirkungen von Kalt- (oben) und Heiß- (unten) Neustarts auf den SRAM-Inhalt



Wir haben uns entschlossen herauszufinden, ob das oben Gesagte für den ESP32 zutrifft. Wir haben festgestellt, dass Sie einen Hardware- Watchdog-Timer verwenden können , um einen Soft-Hot-Boot durchzuführen. Sie können diesen Timer mit dem UART-Bootloader auch dann aktivieren, wenn sich der Chip im Boot-Modus befindet. Daher können Sie diesen Mechanismus verwenden, um den ESP32 in den normalen Startmodus zu versetzen.



Unter Verwendung des Testcodes, der in den SRAM geladen und mit dem UART-Bootloader ausgeführt wurde, haben wir festgestellt, dass die Daten im SRAM tatsächlich nach einem vom Watchdog-Timer initiierten Hot-Reset bestehen bleiben. Dies bedeutet, dass wir, nachdem wir aufgezeichnet haben, was wir in SRAM benötigen, den ESP32 wie gewohnt starten können.



Dann stellte sich vor uns die Frage, wie wir das nutzen können.



Der Weg zum Scheitern



Wir gingen davon aus, dass wir möglicherweise die Tatsache nutzen können, dass Daten nach einem heißen Neustart für einen Angriff im SRAM gespeichert werden. Unser erster Angriff war, dass wir mit dem UART-Bootloader Code in SRAM geschrieben und dann mit dem Watchdog-Timer einen Hot-Neustart des Geräts durchgeführt haben. Wir haben dann einen Absturz gemacht, indem wir ihn ausgeführt haben, während der ROM-Code diesen Code beim normalen Start mit dem Flash-Bootloader-Code überschreibt.



Wir kamen auf diese Idee, nachdem wir den Datenübertragungsprozess im Verlauf früherer Experimente in den Code-Ausführungsprozess umgewandelt hatten . Dann haben wir festgestellt, dass der Chip den Code von der Startadresse aus ausführt, bevor der Bootloader den Kopiervorgang abschließt.



Manchmal muss man es nur versuchen, um etwas zu erreichen ...



▍Code in SRAM geladen und zur Ausführung des Angriffs verwendet



Hier ist der Code, den wir mit dem UART-Bootloader in SRAM geschrieben haben.



#define a "addi a6, a6, 1;"
#define t a a a a a a a a a a
#define h t t t t t t t t t t
#define d h h h h h h h h h h

void __attribute__((noreturn)) call_start_cpu0() {
    uint8_t cmd;

    ets_printf("SRAM CODE\n");

    while (1) {

        cmd = 0;
        uart_rx_one_char(&cmd);

        if(cmd == 'A') {                                    // 1
            *(unsigned int *)(0x3ff4808c) = 0x4001f880;
            *(unsigned int *)(0x3ff48090) = 0x00003a98;
            *(unsigned int *)(0x3ff4808c) = 0xc001f880;
        }
    }

    asm volatile ( d );                                     // 2

    "movi a6, 0x40; slli a6, a6, 24;"                       // 3
    "movi a7, 0x00; slli a7, a7, 16;"
    "xor a6, a6, a7;"
    "movi a7, 0x7c; slli a7, a7, 8;"
    "xor a6, a6, a7;"
    "movi a7, 0xf8;"
    "xor a6, a6, a7;"

    "movi a10, 0x52; callx8  a6;" // R
    "movi a10, 0x61; callx8  a6;" // a            
    "movi a10, 0x65; callx8  a6;" // e               
    "movi a10, 0x6C; callx8  a6;" // l               
    "movi a10, 0x69; callx8  a6;" // i               
    "movi a10, 0x7A; callx8  a6;" // z               
    "movi a10, 0x65; callx8  a6;" // e               
    "movi a10, 0x21; callx8  a6;" // !               
    "movi a10, 0x0a; callx8  a6;" // \n               

    while(1);
}


Dieser Code implementiert Folgendes (die Listenelementnummern entsprechen den in den Kommentaren angegebenen Nummern):



  1. Ein einzelner Befehlsbefehlshandler, der den Watchdog-Timer zurücksetzt.
  2. Ein Analogon NOPbasierend auf Anweisungen addi.
  3. Assemblycode, der eine Zeichenfolge an die serielle Schnittstelle ausgibt Raelize!.


▍Wählen Sie den Zeitpunkt des Angriffs



Wir hatten ein relativ kleines Angriffsfenster zur Verfügung, beginnend mit Fwie in der folgenden Abbildung gezeigt. Wir wussten aus früheren Experimenten, dass der Bootloader-Code zu diesem Zeitpunkt aus dem Flash-Speicher kopiert wird.





Das Angriffsfenster wird durch F dargestellt. Ein



Fehler muss gemacht werden, bevor der SRAM-Inhalt vollständig durch den richtigen Bootloader-Code aus dem Flash-Speicher überschrieben wird.



▍ Angriffszyklus



In jedem unserer Experimente haben wir die folgenden Schritte ausgeführt, um zu überprüfen, ob die Angriffsidee funktioniert. Die erfolgreiche Organisation des Fehlers sollte zur Ausgabe an die serielle Leitungsschnittstelle geführt haben Raelize!.



  • Setzen Sie den Pin auf G0niedrig und führen Sie einen Kaltstart durch, um in den UART-Bootloader-Modus zu gelangen.
  • Verwenden eines Befehls load_ramzum Ausführen von Angriffscode aus dem SRAM.
  • Sendet das Programm Azum Hot-Neustart und zur Rückkehr zum normalen Startmodus.
  • Organisation eines Fehlers beim Kopieren des Bootloaders aus dem Flash-Speicher unter Verwendung des Codes aus dem ROM.


▍Ergebnisse



Nachdem wir dieses Experiment über einen Tag lang durchgeführt hatten, nachdem wir es über eine Million Mal durchgeführt hatten, waren wir immer noch nicht erfolgreich.



▍ Unerwartetes Ergebnis



Trotz der Tatsache, dass es uns nicht gelungen ist, das zu erreichen, was wir wollten, fanden wir bei der Analyse der Ergebnisse der Experimente etwas Unerwartetes.



In einem Experiment meldete die serielle Schnittstelle Daten, die darauf hinwiesen, dass ein Fehler zu einer Ausnahme führte IllegalInstruction(ungültige Anweisung). So sah es aus:



ets Jun  8 2016 00:22:57
rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0008,len:4
load:0x3fff000c,len:3220
load:0x40078000,len:4816
load:0x40080400,len:18640
entry 0x40080740
Fatal exception (0): IllegalInstruction
epc1=0x661b661b, epc2=0x00000000, epc3=0x00000000, 
excvaddr=0x00000000, depc=0x00000000


Beim Versuch, einen Chipfehler zu verursachen, treten diese Ausnahmen häufig auf. Gleiches gilt für den ESP32. Für die meisten dieser Ausnahmen wird das Register PCauf den erwarteten Wert gesetzt (dh die richtige Adresse befindet sich dort). Es kommt selten vor, dass PCeine so interessante Bedeutung auftaucht.



Die Ausnahme wird IllegalInstructionausgelöst, weil an der Adresse 0x661b661bkeine korrekte Anweisung vorhanden ist. Wir haben entschieden, dass dieser Wert PCvon irgendwo im Register kommen muss und dass er selbst dort nicht erscheinen kann.



Auf der Suche nach einer Erklärung haben wir den Code analysiert, den wir in SRAM geladen haben. Durch das Anzeigen des Binärcodes, von dem ein Ausschnitt unten gezeigt wird, konnten wir schnell die Antwort auf unsere Frage finden. Es ist nämlich leicht, die Bedeutung hier zu finden0x661b661b... Es wird durch zwei Anweisungen dargestellt addi a6, a6, 1, mit deren Hilfe das Analogon im Code implementiert wird NOP.



00000000  e9 02 02 10 28 04 08 40  ee 00 00 00 00 00 00 00  |....(..@........|
00000010  00 00 00 00 00 00 00 01  00 00 ff 3f 0c 00 00 00  |...........?....|
00000020  53 52 41 4d 20 43 4f 44  45 0a 00 00 00 04 08 40  |SRAM CODE......@|
00000030  50 09 00 00 00 00 ff 3f  04 04 fe 3f 4d 04 08 40  |P......?...?M..@|
00000040  00 04 fe 3f 8c 80 f4 3f  90 80 f4 3f 98 3a 00 00  |...?...?...?.:..|
00000050  80 f8 01 c0 54 7d 00 40  d0 92 00 40 36 61 00 a1  |....T}.@...@6a..|
00000060  f5 ff 81 fc ff e0 08 00  0c 08 82 41 00 ad 01 81  |...........A....|
00000070  fa ff e0 08 00 82 01 00  4c 19 97 98 1f 81 ef ff  |........L.......|
00000080  91 ee ff 89 09 91 ee ff  89 09 91 f0 ff 81 ee ff  |................|
00000090  99 08 91 ef ff 81 eb ff  99 08 86 f2 ff 5c a9 97  |.............\..|
000000a0  98 c5 1b 66 1b 66 1b 66  1b 66 1b 66 1b 66 3e 0c  |...f.f.f.f.f.f>.|
000000b0  1b 66 1b 66 1b 66 1b 66  1b 66 1b 66 1b 66 1b 66  |.f.f.f.f.f.f.f.f|
000000c0  1b 66 1b 66 1b 66 1b 66  1b 66 1b 66 1b 66 1b 66  |.f.f.f.f.f.f.f.f|
000000d0  1b 66 1b 66 1b 66 1b 66  1b 66 1b 66 1b 66 1b 66  |.f.f.f.f.f.f.f.f|
...
00000330  1b 66 1b 66 1b 66 1b 66  1b 66 1b 66 1b 66 1b 66  |.f.f.f.f.f.f.f.f|
00000340  1b 66 1b 66 1b 66 1b 66  1b 66 1b 66 1b 66 1b 66  |.f.f.f.f.f.f.f.f|
00000350  1b 66 1b 66 1b 66 1b 66  1b 66 1b 66 1b 66 1b 66  |.f.f.f.f.f.f.f.f|


Wir haben mit diesen Anweisungen einen "Wackelraum" vorbereitet, der sie auf ähnliche Weise verwendet, wie Befehlssequenzen NOPhäufig in Exploits verwendet werden, um die Codeausführung bis zur Verwendung zu verzögern. Wir haben nicht erwartet, dass diese Anweisungen im Register landen PC.



Aber wir waren natürlich nicht dagegen. Wir haben beschlossen, Daten aus dem SRAM PCwährend eines Absturzes in ein Register zu laden, der verursacht wurde, als Daten aus dem Flash-Speicher mithilfe von ROM-Code kopiert wurden.



Wir stellten schnell fest, dass wir nun alle Zutaten hatten, um einen Angriff vorzubereiten, der sichere Boot- und Flash-Verschlüsselungssysteme mit einem einzigen Fehler umgehen würde. Hier haben wir die Erfahrungen aus der Ausführung des zuvor beschriebenen Angriffs genutztals wir es geschafft haben, die Kontrolle über das Register zu bekommen PC.



Weg zum Erfolg



Bei diesem Angriff haben wir den größten Teil des Codes verwendet, der zuvor mit dem UART-Bootloader in SRAM geladen wurde. Aus diesem Code wurden nur Befehle zum Ausgeben von Zeichen an die serielle Schnittstelle entfernt, da unser Ziel nun darin bestand, das Register PCauf den Wert zu setzen , den wir benötigten, dh die Möglichkeit zu erhalten, das System zu steuern.



#define a "addi a6, a6, 1;"
#define t a a a a a a a a a a
#define h t t t t t t t t t t
#define d h h h h h h h h h h

void __attribute__((noreturn)) call_start_cpu0() {
    uint8_t cmd;
   
    ets_printf("SRAM CODE\n");

    while (1) {

        cmd = 0;
        uart_rx_one_char(&cmd);

        if(cmd == 'A') {
            *(unsigned int *)(0x3ff4808c) = 0x4001f880;
            *(unsigned int *)(0x3ff48090) = 0x00003a98;
            *(unsigned int *)(0x3ff4808c) = 0xc001f880;
        }
    }

    asm volatile ( d );

    while(1);
}


Nach dem Kompilieren dieses Codes haben wir die Anweisungen direkt in ihrer Binärversion durch addieine Adresse ersetzt 0x4005a980. An dieser Adresse befindet sich eine Funktion im ROM, die Daten an die serielle Schnittstelle ausgibt. Ein erfolgreicher Aufruf dieser Funktion würde uns über einen erfolgreichen Angriff informieren.



Wir haben uns darauf vorbereitet, Fehler zu behandeln, die mit den Ursachen der Ausnahme in einem früheren Experiment übereinstimmen IllegalInstruction. Nach einer Weile entdeckten wir den erfolgreichen Abschluss mehrerer Experimente, um die PCangegebene Adresse in das Register zu laden . Die PCFallkontrolle bedeutet höchstwahrscheinlich, dass wir beliebigen Code ausführen können.



»Warum ist das möglich?



Der Titel dieses Abschnitts enthält eine gute Frage, die nicht einfach zu beantworten ist.



Leider haben wir keine klare Antwort. Wir haben sicherlich nicht erwartet, dass Datenmanipulationen eine Registerkontrolle ermöglichen PC. Wir haben mehrere Erklärungen dafür, aber wir können nicht mit absoluter Sicherheit behaupten, dass eine davon wahr ist.



Eine Erklärung ist, dass während eines Fehlers beide Operanden des Befehls ldrzum Laden des Werts verwendet werden a0. Dies ähnelt dem, was wir bei diesem Angriff gesehen haben, bei dem wir PCdurch Ändern der Daten die indirekte Kontrolle über das Register erlangt haben .



Darüber hinaus ist es möglich, dass der im ROM gespeicherte Code Funktionen implementiert, die zum Erfolg dieses Angriffs beitragen. Mit anderen Worten, aufgrund eines Fehlers können wir den richtigen Code aus dem ROM ausführen, was dazu führt, dass die Daten aus dem SRAM in das Register geladen werden PC.



Um herauszufinden, was genau uns diesen Angriff ermöglicht hat, müssen wir mehr Nachforschungen anstellen. Wenn Sie die Angelegenheit jedoch mit den Augen von jemandem betrachten, der sich entschlossen hat, den Chip zu hacken, verfügen wir über genügend Wissen, um einen Exploit zu erstellen, der auf der Möglichkeit basiert, das Register zu beeinflussen PC.



Extrahieren Sie den Inhalt des Flash-Speichers als einfachen Text



Wir können in das Register schreiben, PCwas wir wollen, aber wir können den Inhalt des Flash-Speichers noch nicht als einfachen Text abrufen. Daher wurde beschlossen, die UART-Bootloader-Funktionen zu nutzen.



Wir haben uns nämlich entschlossen, direkt zum UART-Bootloader zu wechseln, während sich der Chip im normalen Boot-Modus befindet. Um diesen Angriff auszuführen, haben wir die Anweisungen addiim in den RAM geladenen Code neu geschrieben und stattdessen die Startadresse ( 0x40007a19) des UART-Bootloader-Codes verwendet .



Der UART-Bootloader gibt die unten gezeigte Zeile an die serielle Schnittstelle aus. Wir können diese Tatsache nutzen, um den Erfolg eines Angriffs zu bestimmen.



waiting for download\n"


Sobald ein solches Experiment erfolgreich ist, können wir es einfach verwenden esptool.py, um den Befehl auszuführen read_memund auf die Klartextdaten im Flash-Speicher zuzugreifen. Der folgende Befehl liest beispielsweise 4 Bytes aus dem externen Flash-Adressraum ( 0x3f400000).



esptool.py --no-stub --before no_reset --after no_reset read_mem 0x3f400000


Leider hat ein solcher Befehl nicht funktioniert. Aus irgendeinem Grund sah die Antwort des Prozessors so aus 0xbad00bad, dass wir versuchen, Daten aus nicht zugewiesenem Speicher zu lesen.



esptool.py v2.8
Serial port COM8
Connecting....
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Crystal is 40MHz
MAC: 24:6f:28:24:75:08
Enabling default SPI flash mode...
0x3f400000 = 0xbad00bad
Staying in bootloader.


Wir haben festgestellt, dass zu Beginn des UART-Bootloaders ziemlich viele Einstellungen vorgenommen werden. Wir gingen davon aus, dass diese Einstellungen auch die MMU beeinflussen könnten.



Um etwas anderes auszuprobieren, haben wir uns entschlossen, direkt zum Befehlshandler des UART ( 0x40007a4e) - Bootloaders selbst zu wechseln . Sobald wir im Handler sind, können wir den Befehl unabhängig read_memdirekt an die serielle Schnittstelle senden :



target.write(b'\xc0\x00\x0a\x04\x00\x00\x00\x00\x00\x00\x00\x40\x3f\xc0')


Wenn Sie direkt zum Handler gehen, wird die Zeile, die nach dem Aufrufen des UART-Bootloaders angezeigt wird (dh - waiting for download\n), leider nicht angezeigt. Aus diesem Grund verlieren wir eine einfache und bequeme Möglichkeit, erfolgreiche Experimente zu identifizieren. Infolgedessen haben wir beschlossen, den obigen Befehl in allen Experimenten zu senden, unabhängig davon, ob sie erfolgreich waren oder nicht. Wir haben ein sehr kurzes serielles Timeout verwendet, um das mit diesem Timeout verbundene zusätzliche Timeout zu minimieren, das fast immer auftritt.



Nach einer Weile sahen wir die Ergebnisse der ersten erfolgreichen Experimente!



Ergebnis



In diesem Artikel haben wir einen Angriff auf ESP32 beschrieben, bei dem wir die sicheren Start- und Verschlüsselungssysteme des Flash-Speichers umgehen und nur einen Fehler im Mikrocontroller verursachen. Darüber hinaus haben wir eine während des Angriffs ausgenutzte Sicherheitsanfälligkeit verwendet, um den Inhalt des verschlüsselten Flash-Speichers im Klartext zu extrahieren.



Wir können FIRM verwenden , um diesen Angriff zu überwinden .





Angriffsfortschritt



Hier finden Sie eine kurze Beschreibung der Vorgänge in den verschiedenen Schritten des obigen Angriffs:



  1. Aktivieren (Auswahl der Werkzeuge zur Durchführung eines Angriffs) - hier wird der FI- Komplex des Riscure Inspector verwendet .
  2. Injizieren (Attack) - Ein elektromagnetischer Effekt wird auf den untersuchten Mikrocontroller ausgeübt.
  3. Glitch ( ) — , (, , ).
  4. Fault ( ) — , , , . , - .
  5. Exploit ( ) — UART , SRAM, . UART PC read_mem.
  6. Goal ( ) — - .


Interessanterweise hängt der Erfolg dieses Angriffs von zwei Schwächen des ESP32 ab. Die erste Schwäche ist, dass der UART-Bootloader nicht deaktiviert werden kann. Dadurch ist es immer verfügbar. Die zweite Schwäche ist die Persistenz der Daten im SRAM nach einem Hot-Reset des Geräts. Dies ermöglicht die Verwendung des UART-Bootloaders, um den SRAM mit beliebigen Daten zu füllen.



In einem Informationsbericht , der dem Angriff bezeichnet, berichtet das Unternehmen Espressif , dass neuere Versionen ESP32 es Mechanismen gibt , die ein solcher Angriff unmöglich machen.



Alle eingebetteten Standardsysteme sind anfällig für Angriffe auf Geräteunterbrechungen. Daher ist es nicht verwunderlich, dass der ESP32-Mikrocontroller auch für Seitenkanalangriffe anfällig ist. Chips wie diese sind einfach nicht dafür ausgelegt, solchen Angriffen standzuhalten. Dies bedeutet jedoch nicht, dass solche Angriffe kein Risiko bergen.



Unsere Forschung hat gezeigt, dass das Ausnutzen der Schwächen des Chips erfolgreiche Angriffe ermöglicht, die zu Fehlern führen. Die meisten Angriffe, die aus Open Source gelernt werden können, verwenden traditionelle Ansätze, bei denen der Schwerpunkt auf der Umgehung von Überprüfungen liegt. Wir haben nicht sehr viele Berichte über Angriffe wie den von uns beschriebenen gesehen.



Wir sind zuversichtlich, dass das volle Potenzial solcher Angriffe noch nicht vollständig ausgeschöpft ist. Bis vor kurzem haben die meisten Forscher nur Methoden untersucht, um den Betrieb von Chips zu stören (Schritte Aktivieren, Injizieren, Glitch). Wir sind jedoch noch weiter gegangen und haben die Möglichkeit in Betracht gezogen, nach einem Fehler mit einem anfälligen Chip zu arbeiten (Schritte Fehler, Exploit, Ziel).





Forschung bis 2020 und nach 2020



Wir sind zuversichtlich, dass der kreative Einsatz neuer Chipfehlermodelle zu einer Zunahme von Angriffsmethoden führen wird, die interessante Strategien zur Ausnutzung von Schwachstellen verwenden, um eine Vielzahl von Zielen zu erreichen.



Wenn Sie sich für das in diesem Material angesprochene Thema interessieren, dann hier , hier und hier - andere Materialien, die dem Studium des ESP32 gewidmet sind.



Haben Sie in der Praxis festgestellt, dass Geräte mit ähnlichen Methoden wie in diesem Artikel beschrieben gehackt wurden?










All Articles