1 Punkte von GN⁺ 2024-08-08 | 1 Kommentare | Auf WhatsApp teilen
  • Ein strcpy-Buffer-Overflow bei der Verarbeitung von Gap-Namen in Create-A-Park-Speicherdateien führte zu Speicherdatei- und Netzwerk-Exploits auf mehreren Plattformen, darunter original Xbox, Xbox 360, PS2 und GameCube
  • Die original-Xbox-Version von THPS4 kopierte einen auf 31 Zeichen begrenzten String ohne Bounds-Check in einen 32-Byte-Stack-Buffer, wodurch sich die return address überschreiben ließ; über den Speicherdatei-Header und ein ausführbares Datensegment wurde Shellcode ausgeführt
  • Bei THPS3 beschädigte dieselbe Eingabe nicht den Stack, sondern den Heap, weshalb eine ROP-Chain über einen Custom Allocator und einen vtable-Pfad nötig war; bei den Xbox-Versionen von THUG 1 und 2 war der Gap-Name-Pfad wegen eines Stack Cookie blockiert
  • Im Multiplayer von THPS4 konnte ein bösartiger Host eine Park-Datei an Clients senden und so Remote Code Execution sowie asynchrone Dateiübertragung ausführen; ein während der Übertragung sichtbar gewordener Netzwerk-Memory-Leak wurde innerhalb des Exploits per Hot Patch umgangen
  • Auch in Tony Hawk’s American Wasteland auf der Xbox 360 ist ROP-Ausführung über einen Gap-Name-Overflow möglich; vollständige Hypervisor-Codeausführung gelingt jedoch nur in Kombination mit einem Bug im system call handler des 4548 kernel. Quellcode und gepatchte Speicherdateien wurden auf GitHub veröffentlicht

Ausgangspunkt: Gap-Name und strcpy

  • Auf der Suche nach einem neuen Speicherdatei-Hacking-Bug für die original Xbox im Jahr 2016 gerieten die Custom-Park-Speicherdateien von Tony Hawk’s Pro Skater 4 in den Fokus der Analyse
  • Die Create-A-Park-Funktion von THPS4 erlaubt es Spielern, eigene Skateparks zu bauen und den Sprungbereichen, den sogenannten Gaps, Namen zu geben
    • Ein Gap-Name ist ein benutzerdefinierter String mit maximal 31 Zeichen plus Null-Terminator
    • Wird dieser String mit einer Funktion wie strcpy verarbeitet, kann er zu einem Primitive für Speicherbeschädigung werden
  • Nachdem eine manipulierte Speicherdatei, in der der Gap-Name durch eine lange Wiederholung von 0x41 ersetzt worden war, auf die Xbox kopiert und geladen wurde, stürzte die Konsole ab; der Instruction Pointer stand auf 0x41414141
    • Das ist ein Hinweis darauf, dass der Gap-Name auf den Stack kopiert wurde und dabei bis zur return address überschrieben hat
  • Die Analyse in IDA zeigte, dass das Spiel beim Durchlaufen der Gap-Liste in der Speicherdatei den gap_name aus save_file_gap_data per strcpy in gap_description gapDesc auf dem Stack kopierte
    • Ohne Bounds-Check läuft der Kopiervorgang weiter, bis ein Null-Terminator erreicht wird
    • Diese Spielversion wurde ohne Stack Cookie kompiliert, sodass Stack-Daten und return address überschrieben werden können

original-Xbox-THPS4: Shellcode in einen ausführbaren Bereich verschieben

  • Die original Xbox besitzt zwar keine Hardware-DEP, die wie bei modernen Geräten die Ausführung beliebiger Daten verhindert, doch in späteren Kerneln und Spielen gibt es teilweise Soft DEP
    • Dabei wird die Adresse des Code-Segment-Selectors so geändert, dass nur noch Adressen unterhalb einer bestimmten Grenze ausführbar sind
    • Der Stack und die Heap-Allokation, in der die Speicherdatei liegt, befinden sich außerhalb des ausführbaren Bereichs
  • Das read-write-Datensegment der Spiel-Executable liegt innerhalb des ausführbaren Bereichs; daher wurde die Strategie genutzt, Code dorthin zu kopieren und anschließend auszuführen
  • Der Park-Name liegt im Header der Speicherdatei; wenn der Spieler die Speicherdatei auswählt, werden die ersten 136 Byte des Headers zur Anzeige in der UI in eine Struct im Datensegment der Executable kopiert
    • Der gesamte Header lässt sich zwar nicht beliebig ändern, aber der Platz reicht für einen kleinen memcpy-Stub aus
  • Ablauf des THPS4-Exploits auf der original Xbox
    • Nach dem Laden der Speicherdatei, aber bevor „Start Game“ gedrückt wird, werden die ersten 136 Byte in das Datensegment der Executable kopiert
    • Beim Drücken von „Start Game“ wird der bösartige Gap-Name auf den Stack kopiert und die return address mit der Adresse des Shellcode-Kopier-Stubs überschrieben
    • Beim Rücksprung aus der Funktion springt die Ausführung zum Kopier-Stub, der die große Payload aus dem Speicherdatei-Buffer in das ausführbare Datensegment kopiert
    • Nach dem Kopieren springt er zur Payload und erreicht so beliebige Codeausführung

Signatur-Bypass und habibi key

  • Nachdem auf der original Xbox Codeausführung erreicht wurde, müssen die Signaturprüfungen deaktiviert und eine unsigned executable gestartet werden
  • Die Payload basiert auf der Payload einer bestehenden Speicherdatei des Softmod-Installers für 007 Agent Under Fire
    • Sie findet Kernel-Funktionen und Datenadressen sowie die Adresse des RSA public key, der für die Signaturprüfung von Executables verwendet wird
    • Sie deaktiviert den Write Protection im Machine State Register und patcht den RSA public key auf den habibi key
    • Sie startet eine in der Speicherdatei enthaltene Hilfs-Executable; während der Tests wurde eine nyan cat-Executable verwendet
  • Das habibi key pair ist ein RSA-Schlüsselpaar, das vermutlich Anfang der 2000er von einer original-Xbox-Linux-Hacking-Gruppe erstellt wurde
    • Statt die RSA-Signaturprüfung des Kernels selbst bedingungslos bestehen zu lassen, ersetzten sie den public key durch ihren eigenen Schlüssel, um einen Linux-Loader auszuführen
    • Damit sollte verhindert werden, dass über diese Speicherdatei pirated content gestartet wird; später veröffentlichten jedoch andere Gruppen Exploit-Dateien zur Installation persistenter Hacks
  • Auffällig ist, dass sich der Modulus des habibi public key nur um 4 Byte vom Microsoft-RSA-Public-Key unterscheidet
    • Es scheint, als müsste der Exponent auf 3 geändert werden, doch bestehende Shellcode-Payloads ändern den Exponenten nicht
    • Wie genau das funktioniert, ist nicht sicher bekannt
  • Die habibi-key-Methode wurde wegen ihrer Kompatibilität mit mehreren Xbox-Kernel-Versionen gewählt
    • Um die Signaturprüfungsfunktion so zu patchen, dass sie immer true zurückgibt, wäre ein Instruction-Pattern-Matching für jede Kernel-Version nötig
    • Beim habibi key genügt ein 4-Byte-Patch in leicht auffindbarem Speicher

Variantenanalyse: THPS3, THUG, THAW

  • Tony Hawk’s Pro Skater 3

    • Auch THPS3 hatte Create-A-Park und Gap Names, stürzte aber nicht direkt nach dem Laden einer bösartigen Speicherdatei ab
    • Im Spiel konnte man skaten; die Konsole stürzte erst ab, wenn „quit game“ ausgewählt wurde
    • Der Gap Name wurde nicht auf den Stack, sondern auf den Heap kopiert, und der Overflow überschreibt den Allocation Header der nächsten Heap-Allokation
    • Wenn die nächste Allocation freigegeben wird, führen die Pointer im Header zu einer vtable mit einem Cleanup-Routine-Function-Pointer
    • THPS3 kopierte den Speicherdatei-Header anders als THPS4 nicht in ein ausführbares Datensegment, und auch die Speicherdatei-Daten lagen in nicht ausführbarem Heap-Speicher
    • Durch Überschreiben des pAllocOwner-Pointers wird kontrolliert, von wo der Cleanup-Function-Pointer geladen wird; per Stack Pivot wird eine ROP chain im Speicher der Speicherdatei verwendet
    • Die ROP chain kopiert mit nur wenigen Gadgets Shellcode aus dem Heap in ein ausführbares Datensegment und springt dorthin
    • Danach führt sie wie der generische „hack xbox kernel“-Payload für THPS4 den Habibi-Key-Patch aus und startet unsigned Executables
  • Tony Hawk’s Underground 1 & 2

    • Beim Fuzzing des Gap Names in THUG kam es statt einer Access Violation zu einem Full Bug Check mit der Meldung Buffer overrun detected!
    • In der ausführbaren Datei ist ein Stack-Cookie-Check vorhanden
    • Ein Stack Cookie ist ein zufälliger Wert, der vor der Return Address liegt; vor der Rückkehr aus der Funktion wird geprüft, ob sich der Wert geändert hat
    • Um die Return Address zu überschreiben, müsste man den Cookie-Wert kennen, doch im Gap-Name-Pfad gibt es keine Möglichkeit, ihn zu leaken
    • Hinter dem Gap-Name-Buffer und vor dem Stack Cookie lagen zwar Variablen, die sich korrumpieren ließen, sie wurden aber unmittelbar danach vom Spielcode überschrieben und waren für einen Exploit nicht nützlich
    • SEH Exploitation wurde ebenfalls geprüft, aber im verbleibenden Code vor dem Stack-Cookie-Check gibt es keine Möglichkeit, eine Exception auszulösen, und zu diesem Zeitpunkt ist auch kein Exception Handler registriert, der die SEH chain durchläuft
    • Auch THUG2 ist in der Xbox-Version aus denselben Gründen nicht per Gap-Name-basiertem Exploit angreifbar
    • Es gibt jedoch andere strcpy-Bugs sowie Heap-basierte Bugs, die exploitierbar sind
    • Die PlayStation-2-, PC- und vermutlich auch die GameCube-Version wurden ohne Stack Cookie kompiliert und sind über den Gap-Name-Buffer exploitierbar
  • Tony Hawk’s American Wasteland

    • Da THAW nach THUG 1 und 2 erschien, war mit Stack Cookies zu rechnen, doch die Xbox-Version wurde ohne Stack Cookies kompiliert
    • Sie war für einen Gap-Name-Buffer-Overflow anfällig, und der Exploit ist nahezu identisch zu THPS4 aufgebaut

THPS4-Netzwerk-RCE: Clients ohne Speicherdatei hacken

  • Da der Speicherdatei-Exploit eine Memory Card erforderte, wurde als Angriffsfläche mit niedrigerer Einstiegshürde ein Multiplayer-LAN-Spiel gewählt
    • Wenn ein mit Create-A-Park erstellter Park im LAN-Multiplayer genutzt wird, sendet der Host die Speicherdatei über das Netzwerk, und der Client lädt sie
    • Daraus entstand die Annahme, dass sich durch das Senden einer bösartigen Park-Datei die Client-Konsole hacken lässt
  • Damit der Host sich nicht selbst hackt, wurde die Spiel-Executable geändert, um den strcpy-Bug zu blockieren; außerdem wurde ein Code Segment für zusätzliche Funktionen hinzugefügt
  • Anfangs konnte sich der Client mit dem Host verbinden und normal skaten, doch der Payload wurde nicht ausgeführt, und auch der Buffer Overflow wurde nicht getriggert
    • Die Park-File-Daten im Client-Speicher waren gegenüber der Exploit-Datei verändert
    • Der Host lud das Park File, speicherte es anschließend aus dem Speicher heraus erneut und sendete das Ergebnis an den Client, wodurch die Exploit-Daten beschädigt wurden
  • Nachdem dieser Function Call per NOP deaktiviert wurde, empfing der Client die bösartige Park-Datei, wurde kompromittiert, und die LED-Farbe änderte sich
  • Im Netzwerkpfad wird der Speicherdatei-Header nicht in das Datensegment kopiert, daher lässt sich der Shellcode-Copy-Stub des lokalen THPS4-Exploits nicht verwenden
    • Stattdessen wird ähnlich wie bei THPS3 eine ROP chain genutzt, um Shellcode in ausführbaren Speicher zu kopieren

Fund des THUG-Quellcodes und Nutzung des Netzwerkcodes

  • Ein zusätzlicher Payload als Executable musste über das Netzwerk an den Client übertragen werden, doch anders als beim lokalen Speicherdatei-Exploit konnte man nicht einfach Dateien zusammen in den Save-Game-Ordner legen
  • Auch Methoden, ein Executable von einer gebrannten CD oder einer lokalen Netzwerkadresse zu laden, wurden geprüft, aber nicht übernommen
    • Die Xbox-Winsock-Implementierung nutzt standardmäßig eine Secure Socket Connection, sodass die Xbox-Security-Layer in einem Python-Script hätte nachgebildet werden müssen
  • Bei der Suche nach Material zu Park-Save-Files führte eine Suche nach dem String Sk4Ed_Dead zu einem thug-Repository auf GitHub
    • Es stellte sich nicht als Homebrew-Tool heraus, sondern als vollständiger Spiel-Quellcode von Tony Hawk’s Underground
    • Es war zwar nicht THPS4 selbst, aber die Codebasis war ähnlich genug, um sie für Networking-Code und das Schreiben von Hooks zu nutzen
  • Im Quellcode fanden sich der Park-File-Loading-Code und die exakte Zeile mit dem strcpy-Bug
    • Durch Rekonstruktion der Visual-Studio-Project-Datei und das Beheben einiger Compiler Errors ließ sich ein ausführbarer Build mit den finalen Game Assets erstellen
    • Der Code scheint nicht vollständig identisch mit der finalen Version zu sein, kommt ihr aber sehr nahe
  • Das Ziel verschob sich von einer einfachen RCE hin zu einem Ansatz, bei dem auf der Konsole, die einem Match beitritt, still RCE erlangt, die Ausführung von unsigned Code ermöglicht und anschließend während des Spiels ein zusätzliches Executable übertragen wird

Wiederherstellung der Ausführung und asynchrone Dateiübertragung

  • Damit die Payload-Übertragung weiterlaufen kann, während der Client das Spiel weiterspielt, muss nach der Ausführung des Shellcodes der Ausführungsfluss des Spiels wiederhergestellt werden
  • Die ROP chain wurde so geändert, dass sie vor dem Stack Pivot den bisherigen Stack Pointer speichert und ihn nach der Ausführung des Shellcodes später wiederherstellt
    • Anschließend kopiert sie den Shellcode in ausführbaren Speicher und springt dorthin
  • Das Networking-System des Spiels ist so aufgebaut, dass Message IDs und Handler Functions registriert werden und bei einer eingehenden Nachricht der zur ID passende Handler aufgerufen wird
  • Mit einer ungenutzten Message ID wurde ein einfaches Dateiübertragungsprotokoll implementiert
    • Wenn der Client beitritt, sendet er MSG_ID_PAYLOAD_REQUEST an den Host und startet damit die Übertragung
    • Der Host sendet die Payload-Daten in MSG_ID_PAYLOAD_DATA-Nachrichten
    • Wenn der Client PAYLOAD_MSG_ID_END empfängt, ist die Übertragung abgeschlossen

15 Jahre altes Memory Leak und Hot Patch

  • Während der Dateiübertragung stürzte die Client-Konsole durch eine Null-Pointer-Dereference ab
  • Der Network-Data-Allocator gab NULL zurück, und die freien Bytes im Networking-Memory-Pool fielen auf 0
  • Im THUG-Quellcode gab es Code, der den Message-Data-Buffer freigibt, doch im ausgelieferten THPS4-Build war dieser Fix nicht enthalten
    • Der p_data-Buffer von stream_desc wurde nicht bei jeder Nachricht freigegeben, sodass der Networking-Memory-Pool erschöpft wurde
    • Im normalen Multiplayer-Spiel fiel das möglicherweise nicht auf, solange man nicht lange in einer Sitzung blieb
  • Der Exploit hookt den Client-Code und hot-patcht ihn so, dass der p_desc->p_data-Buffer mit der richtigen Free Function freigegeben wird
  • Nach dem Hot Patch gelang die Dateiübertragung zwischen Host- und Client-Konsole, und der Client führte das nyan-cat-Executable aus
    • Mit einer Tunneling-App wurde derselbe Exploit auch remote auf der Konsole eines Freundes in einer anderen Region getestet

Ablauf des finalen Exploits über das ursprüngliche Xbox-Netzwerk

  • Der Client verbindet sich mit einer bösartigen Host-Konsole und empfängt über das Netzwerk eine „Hack Xbox“-Park-Datei
  • Beim Parsen der Park-Datei auf dem Client tritt ein Buffer Overflow auf; die Return Address auf dem Stack wird überschrieben und eine ROP Chain startet
  • Die ROP Chain kopiert die vollständige Shellcode-Payload in einen ausführbaren Speicherbereich und springt dorthin
  • Der Shellcode richtet die nötigen Hooks und Patches ein und spawnt den Player im Match, bevor er zur Spielausführung zurückkehrt
  • Während der Player im Spiel skatet, sendet der Host eine ausführbare Datei an den Client, die auf der HDD des Clients gespeichert wird
  • Nach Abschluss der Dateiübertragung patcht der Shellcode den Client-Kernel so, dass er den Habibi-Key verwendet, und bootet die übertragene sekundäre Executable
  • Wenn die LED-Farbe nicht geändert wird, bemerkt der Nutzer den Fortschritt kaum, bis plötzlich eine andere Anwendung bootet

Xbox 360: THAW und 4548-Kernel

  • Auch Tony Hawk’s American Wasteland für Xbox 360 ist anfällig für einen Gap-Name-Buffer-Overflow
  • Ziel war es, die Konsole auf einer neueren Kernel-Version zu exploiten, was ohne neuen Hypervisor-Bug jedoch nicht möglich war
  • Stattdessen ließ sich durch die Kombination des strcpy-Bugs in THAW mit dem bestehenden System-Call-Handler-Bug im 4548-Kernel der erste Software-only-Exploit für die Xbox 360 bauen
  • Der bisherige King-Kong-Hack der Xbox 360 nutzte eine modifizierte Shader-Datei, um einen Arbitrary Write in den Kernel-Speicher auszuführen und den System-Call-Handler-Bug auszunutzen
    • Für diese Methode musste man die Konsole öffnen und die Firmware des DVD-Laufwerks modifizieren, um eine modifizierte King-Kong-Disc verwenden zu können
    • Ein Game-Save-Bug kann ein anderer Entry Point sein, um eine ROP Chain zu starten

Signaturen von Xbox-360-Speicherständen und die Rolle von Entwicklungskonsolen

  • Xbox-360-Game-Save-Dateien werden mit einem pro Konsole eindeutigen RSA-Schlüsselpaar signiert
    • Im Key Store jeder Konsole befindet sich der kryptografische Schlüssel, der zum Signieren von Game Saves verwendet wird
  • Dass ein Speicherstand auf einer anderen Konsole verifiziert werden kann, liegt daran, dass der öffentliche RSA-Schlüssel im Save-File-Header enthalten ist
    • Dieser Public Key selbst ist mit einem anderen RSA-Schlüsselpaar signiert, das nur Microsoft besitzt
    • Man kann nicht einfach irgendeinen Public Key in den Header einfügen und die Prüfung bestehen
  • Um eine beliebig modifizierte Save-Datei auf einer anderen Konsole zu verwenden, braucht man den entschlüsselten Key Store irgendeiner Xbox-360-Konsole
  • Ausgangspunkt des Xbox-360-Hackings waren geleakte Development Consoles und SDKs
    • Da der ausführbare Code verschlüsselt war, konnte man keine Bugs finden, ohne den Code von außen inspizieren zu können
    • Development Console und SDK lieferten die nötigen Informationen für die Entschlüsselung von Executable Code sowie für Reverse Engineering von Boot Chain, Hypervisor und Game Code

4548-System-Call-Handler-Bug

  • Die Xbox 360 hat einen Hypervisor Real Mode und einen Kernel Mode
    • Der Hypervisor Real Mode ist der am stärksten privilegierte Modus
    • Im Kernel Mode laufen OS und Spiel
  • Neben dem L2-Cache der CPU befindet sich eine Kryptografieeinheit, die für Memory Encryption und Hashing zuständig ist
    • Im Kernel Mode erscheinen Hypervisor-Pages als encrypted + hashed; überschreibt man sie beliebig, hält die Konsole beim Zugriff durch den Hypervisor an
  • Im Real Mode werden die oberen 32 Bit einer 64-Bit-Physical-Address zur Steuerung von Encryption und Hashing verwendet
    • Durch Anwendung der Maske 0x80000000.00000000 ist Speicherzugriff unter Umgehung von Encryption und Hashing möglich
    • An Stellen, an denen der Kernel Mode dem Hypervisor eine Physical Address übergeben kann, müssen die oberen 32 Bit unbedingt gecleart werden
  • Der normale System-Call-Handler verschiebt den System-Call-Ordinal mit der Instruktion slwi um 2 Bit nach links und verwirft die oberen 32 Bit des Ergebnisses, sodass nur ein 32-Bit-Offset verwendet wird
  • Der System-Call-Handler des 4548-Kernels verwendet statt slwi sldi
    • Da sldi mit 64 Bit arbeitet, fließen auch die oberen 32 Bit von r0 in die Berechnung des Table-Index-Offsets ein
    • Der Ordinal-Range-Check wird nur auf die unteren 32 Bit von r0 angewendet
    • Beispielsweise passiert 0x20000000.0000003F den Range Check und erzeugt zugleich den Offset 0x80000000.000000FC, wodurch ungeschützter Speicherzugriff ausgelöst werden kann
  • Diese Änderung wird eher als wahrscheinlicher Compiler-Bug eingeschätzt denn als absichtliche Änderung durch einen Entwickler

Aufbau des Xbox-360-Exploits

  • Wenn man im Kernel Mode die verschlüsselte Hypervisor-Memory-View überschreibt, hält die Konsole normalerweise an. Bringt man den System-Call-Handler jedoch dazu, einen Function Pointer von einer Adresse zu lesen, bei der das obere Protection-Bit gesetzt ist, kann er den überschriebenen Wert ohne Fault lesen.
  • Ablauf des Exploits
    • Shellcode in den Speicher laden und die Physical Address ermitteln
    • Eine Variable des Kernel Memory Managers ändern, sodass die verschlüsselte Hypervisor-Memory-View als beschreibbarer Address Range sichtbar wird
    • Den Hypervisor-System-Call-Function-Pointer mit der Adresse der Instruction Sequence mtctr r4; bctr überschreiben
    • In r0 die bösartige Ordinal schreiben und in r4 den Wert ablegen, der entsteht, wenn die Shellcode-Physical-Address mit der Maske 0x80000000.00000000 per OR verknüpft wird
    • Die System-Call-Instruction ausführen, damit der Hypervisor den überschriebenen Function Pointer liest und über mtctr r4; bctr zum Shellcode springt
  • Der THAW-Savefile-Exploit verwendet eine PowerPC-ROP-Chain
    • Das IDA-Plugin Ida-Sploiter wurde angepasst, um die Suche nach PowerPC-Gadgets zu unterstützen
    • Der gesamte Exploit besteht aus 24 ROP-Gadgets
  • Gesamtablauf von THAW auf der Xbox 360
    • Per Gap-Name-Buffer-Overflow die Return Address mit dem ersten ROP-Gadget überschreiben
    • Den Stack Pointer auf die ROP-Chain im Save Buffer pivotieren
    • Mit MmAllocatePhysicalMemoryEx Physical Memory für den Hypervisor-Shellcode allozieren
    • Den Shellcode mit memcpy kopieren und mit MmGetPhysicalAddress die Physical Address ermitteln
    • Die verschlüsselte Hypervisor-Memory-View beschreibbar mappen
    • Die System-Call-Function-Address mit der Sequence mtctr r4; bctr überschreiben
    • Mit der bösartigen System-Call-Ordinal und der Shellcode-Physical-Address syscall ausführen
    • Nach Erlangen von Hypervisor-Code-Execution die LED-Farbe ändern und den RSA-Signature-Check für Executables patchen
    • Zur Kernel-Mode-ROP-Chain zurückkehren, mit ObCreateSymbolicLink den HDD-Ordner mappen und mit XLaunchNewImage eine unsignierte sekundäre Payload ausführen
  • Mit dieser Methode lässt sich über den strcpy-Bug in THAW auf jeder Xbox-360-OS-Version ROP-Ausführung erreichen; vollständige Hypervisor-Code-Execution ist jedoch nur mit dem 4548-Kernel möglich
    • Wird ein neuer Hypervisor-Bug gefunden, kann er mit diesem Entry Point kombiniert und auch auf neuere Kernel-Versionen angewendet werden

Veröffentlichung 2024 und Portierungen auf weitere Plattformen

  • 2024 wurden die Tony-Hawk-Exploits aufbereitet und veröffentlicht
  • Derselbe strcpy-Bug existiert in 5 Iterationen der Tony-Hawk-Reihe sowie auf mehreren Konsolen- und Handheld-Plattformen
  • PlayStation 2

    • Der THPS4-Network-RCE-Exploit wurde auf die PlayStation-2-Version portiert
    • Mit PCSX2 oder einer anderen Konsole und lediglich einer THPS4-Disc kann man die Konsole über das Network hacken
    • Der Exploit überträgt uLaunchElf über das Network und führt es nach Abschluss der Übertragung aus
    • Anschließend kann man von anderen Medien wie einem USB-Stick den FreeMcBoot- oder FreeHDBoot-Installer laden
    • Der PS2-Savegame-Exploit ist weniger nützlich
    • Wenn man Dateien auf eine Memory Card kopieren kann, kann man FreeMcBoot direkt installieren
    • Eine FreeMcBoot-Memory-Card kann man für 15 Dollar bei Amazon kaufen, oder auf einer Phat-Konsole mit Network Adapter FreeHDBoot verwenden
  • GameCube

    • Der THPS4-Savegame-Exploit wurde auf die GameCube-Version portiert
    • Network-RCE oder andere Savegame-Exploit-Versionen wurden nicht portiert
    • Dateien auf eine GameCube-Memory-Card zu kopieren ist nicht trivial, und Memory Cards mit vorgehacktem Savefile wurden auf eBay für über 50 Dollar verkauft
    • Die GameCube-Version des Tony-Hawk-Spiels hat keinen Network Support, daher lässt sich der Network-Exploit auch mit Network Adapter nicht nutzen
    • Da es bereits mehrere Game-Save-Exploits gibt und keinen persistenten Software-Hack, entscheiden sich viele Nutzer für einen Modchip
  • Windows

    • Auch für THUG PRO wurde ein Game-Save-Exploit erstellt, und vor 7 Jahren wurde ein Bug Report eingereicht, doch damals bestand kein Interesse an einer Behebung
    • Da der Exploit unter Windows keinen Mehrwert bietet, wird er nicht veröffentlicht
    • Die Tony-Hawk-Spiele für PC enthalten denselben strcpy-Bug und sind exploitable
    • Es gibt außerdem einen anderen über Network Play ausnutzbaren strcpy-Bug
    • Es wird empfohlen, ASLR zu erzwingen und das Spiel nicht als Administrator auszuführen

Veröffentlichte Materialien

  • Der vollständige Source Code und die gepatchten Game-Save-Files sind auf GitHub veröffentlicht
  • Ein einzelner strcpy-Bug führte auf mehreren Plattformen zu Savefile-Exploits, Network-RCE und einem software-only Exploit-Entry-Point für die Xbox 360

1 Kommentare

 
GN⁺ 2024-08-08
Meinungen auf Hacker News
  • Das Interessantere am Habibi-Key ist, dass sich der Modulus des öffentlichen Schlüssels nur um 4 Byte vom öffentlichen RSA-Schlüssel von Microsoft unterscheidet.
    Eine zufällige 2048-Bit-Ganzzahl hat eine durchaus nicht vernachlässigbare Chance, trivial faktorisierbar zu sein; die tatsächliche Wahrscheinlichkeit kenne ich nicht, aber grob könnte man sie auf etwa 2^-32 schätzen.
    Vermutlich wurde Code verwendet, der 4 Byte des öffentlichen Modulus zufällig ändert oder inkrementiert, dann etwa 1 Millisekunde lang eine Faktorisierung versucht und bei Erfolg anhält.
    Dadurch ist es wahrscheinlich, dass der resultierende öffentliche Modulus viele kleine Faktoren hat. Ein RSA-Modulus ist normalerweise exakt das Produkt zweier Primzahlen, aber solange er teilerfremd zu e ist, funktioniert die Mathematik auch mit mehr Faktoren weiterhin.

    • Man kann mit einer zufälligen 2048-Bit-Ganzzahl beginnen und die unteren Bytes so ändern, dass sie durch 3 teilbar ist. Da man nur mit dem öffentlichen Schlüssel arbeitet, ist das einfach; wenn der öffentliche Schlüssel durch 3 teilbar ist, kann man mit Fermats kleinem Satz die meisten möglichen Kandidaten für den privaten Schlüssel überspringen, wodurch der nötige Rechenaufwand um mehrere Größenordnungen sinkt.
      Wenn man Glück hat und die RSA-Implementierung exakt zwei Primfaktoren verwendet, dann weiß man bereits, dass ein Faktor 3 ist, und muss den öffentlichen Schlüssel nur durch 3 teilen, um den anderen Primfaktor zu erhalten.
      Laut Wikipedia besteht die Struktur eines öffentlichen RSA-Schlüssels darin, dass N eine große Semiprimzahl ist und e zu φ(N) teilerfremd sein muss; wer N faktorisiert, kann den privaten Schlüssel erhalten. Im Kontext des Xbox-Hacks bedeutet das: Wenn man N durch die Primzahl 3 teilbar macht, ist die andere Primzahl N/3, also hat man faktisch die Faktorisierung geschafft.
      Der Code zum Signieren mit dem Habibi-Key steht unter https://github.com/XboxDev/xbedump/blob/b8cd5cd0f8b1cbc4e64f.... Er ersetzt die letzten 4 Byte durch 0x89, 0x9c, 0x90, 0x6b, teilt dann durch 3 und erzeugt mit diesem Wert einen passenden privaten Schlüssel.
    • Eine Arbeit, die ich mitverfasst habe, behandelt genau dieses Problem. Thema war, ob man zu einem beschädigten realen öffentlichen Schlüssel, auch hier einem 2048-Bit-Schlüssel, einen privaten Schlüssel erzeugen kann.
      Die Anwendung bestand darin, per Rowhammer einen öffentlichen Schlüssel zu beschädigen und dann dessen Faktorisierung zu nutzen, um einen neuen zugehörigen privaten Schlüssel zu erstellen. Das funktionierte bei SSH- und GPG-Schlüsseln; für die Praxistauglichkeit wurden Annahmen getroffen, etwa dass man den Inhalt der Speicherseite kennt, auf der der Schlüssel liegt.
      Die empirischen Erfolgsraten in Abhängigkeit von der verfügbaren Rechenzeit stehen in Figure 7, die analytische Behandlung in Abschnitt 3 und die Beschreibung der konkreten Methode in Abschnitt 4.4.
      https://www.usenix.org/system/files/conference/usenixsecurit...
    • Die Wahrscheinlichkeit ist viel, viel, viel größer als 2^-32. Man muss nur durch kleine Primzahlen teilen, solange es geht, und auf den verbleibenden Wert einen schnellen Primzahltest wie Miller–Rabin anwenden.
      Wenn man zum Beispiel durch alle Primzahlen von 2 bis 499 teilt und, falls der Wert 1 wird, Erfolg meldet, andernfalls Miller–Rabin 20-mal ausführt, brauchte es auf meinem System nur etwa 100 Versuche, um eine zufällige 2048-Bit-Ganzzahl vollständig zu faktorisieren.
    • Implementierungen des chinesischen Restsatzes schlagen fehl, wenn es wiederholte Faktoren gibt.
  • Es ist schwer auszudrücken, wie absurd beeindruckend diese Leistung ist.
    Eine Xbox 360 über den Namen eines Parks in einem Tony-Hawk-Spiel zu softmodden und dabei sogar eine 24-stufige ROP-Chain zu verwenden, ist schon bemerkenswert.
    Dazu die kurze Trauerrede auf den Hypervisor, die knappe und praktische Analyse und das sofort naheliegende x360-Botnet – das fühlt sich an wie der ultimative Treffer direkt in die Xbox-360-Nostalgie.

  • Die Stelle „wenn wir Glück haben, ist es strcpy“ ist lustig. Eigentlich hätte es strncpy sein sollen, und Tony Hawk, der für sein Eintreten für Schutzausrüstung bekannt ist, hätte vermutlich lieber mit einer sichereren String-Kopie in Verbindung gebracht werden wollen.

    • Der richtige Ansatz ist, memcpy zu verwenden und die Größe sowohl des Zielpuffers als auch des Quellpuffers zu kennen.
      Wenn die Quelle nicht ins Ziel passt, braucht es anwendungsspezifische Behandlung: ob Abschneiden erlaubt ist, ob der gesamte Vorgang abgebrochen werden muss oder ob der Zielpuffer neu alloziert werden soll. strncpy macht fast immer das Falsche.
    • strncpy ist nicht sicherer. Wenn n erreicht wird, erzeugt es nämlich einen nicht terminierten String.
      Grundsätzlich sollte man strncpy fast nie verwenden; es ist für Felder fester Größe gedacht, etwa struct dirent { unsigned short inode; char name[14]; };.
      Selbst in solchen Fällen sollten Padding-Bytes häufiger Leerzeichen statt nul sein, und strncpy hätte nie in die Standardbibliothek aufgenommen werden sollen.
    • Bei Windows-C/C++-Entwicklung kann man die strsafe.h-Funktionen verwenden (https://learn.microsoft.com/en-us/windows/win32/api/strsafe/).
      Beim Arbeiten mit C/C++ waren sie einfacher zu verwenden als die Standard-C-Funktionen; sie behandelten häufige Fehlerfälle wie zu kleine Puffer oder Integer-Overflows, und alle Funktionen gaben Fehlercodes zurück, sodass die Fehlerprüfung ebenfalls einfach war.
      In diesem Fall wären StringCchCopyW() oder StringCbCopyW() eine bessere Wahl als strcpy.
    • Ich habe einmal gelesen, dass Tony Hawk früher mit dem Auto unterwegs war und, wenn er Skateboarder sah, „mach einen Ollie“ rief; wenn sie es schafften, gab er ihnen einen neuen Helm.
  • Es ist etwas schade, dass dieser Exploit auch auf THUG PRO anwendbar ist.
    Die Wettbewerbsszene der Tony-Hawk-Reihe ist, abgesehen von der kurzen Ausnahme des THPS1+2-Remakes, seit fast 20 Jahren praktisch tot, und dieser Mod wird bis heute gespielt.
    Der Mod selbst ist inzwischen ebenfalls über 10 Jahre alt, und die ursprünglichen Entwickler scheinen weg zu sein, was erklärt, warum niemand das Problem beheben wollte, als Ryan es gemeldet hat. Aber jetzt ist der Mod wegen des Risikos einer vollständigen Übernahme des PCs schwer nutzbar geworden.
    Hoffentlich erreicht dieser Artikel jemanden, der bereit ist, den Mod zu patchen.

    • Das klingt so interessant, dass ich es ausprobiert hätte, wenn ich Zeit gehabt hätte. Als ich früher Zeit hatte, habe ich den THUG1-Quellcode einmal unter Windows nahezu spielbar gemacht.
      Dieser Quellcode war nur für die Konsolenversionen gedacht, und die Annahme, ihn für Windows zu kompilieren, bezog sich auf Tools, nicht auf Xbox Windows, weshalb sich vieles völlig anders verhielt.
  • Was vor dem Text „So what's the habibi key?“ wie ein Abschnitts-Header-Icon aussieht, ist tatsächlich ein aufklappbarer HTML-details-Bereich; wer interessiert ist, sollte also darauf klicken.
    Was mich wundert: Wenn die Geschichte stimmt, dass der Habibi-Key exklusiv in der Linux-Konsolen-Community verwendet wurde, um die Nutzung von Raubkopien zu verhindern, wo, wann und wie wurde dann der zugehörige private Schlüssel veröffentlicht oder geleakt?
    Der Autor hat die 4-Byte-Differenz zwischen dem Microsoft-Key und dem Habibi-Key gepatcht und damit eine „unsignierte“ ausführbare Datei ausgeführt – tatsächlich eine mit dem privaten Habibi-Key signierte –, also scheint er den privaten Schlüssel eindeutig in die Hände bekommen zu haben.

    • Der Habibi-Key wird erzeugt, indem man den Microsoft-Key so patcht, dass er durch 3 teilbar ist; daher ist seine Faktorisierung in der Praxis sehr einfach.
      Der private Schlüssel lässt sich trivial aus dem öffentlichen Schlüssel rekonstruieren, es gab also eigentlich nichts, was veröffentlicht oder geleakt werden musste.
      Im Grunde war das ein kleines Kryptografie-CTF, das ursprünglich im Savegame-Hack von 007: Agent Under Fire vergraben war, und dieser Savegame-Hack selbst war ebenfalls ziemlich stark obfuskiert und kam einem CTF nahe. Es scheint sowohl die Absicht gegeben zu haben, Raubkopierern eins auszuwischen, als auch eine Herausforderung an andere Reverse Engineers.
  • Wirklich großartig. Ich habe ein wenig PSX-Decompilation gemacht, und dort gibt es viele ähnliche Dinge.
    Interessanterweise wird etwas wie memmove aus der SDK-Bibliothek[0] gelinkt, aber strcpy ist eine vom BIOS bereitgestellte Funktion.
    In späteren SDK-Versionen konnte man das auf eine Bibliotheksversion patchen, aber selbst 1997 war das noch nicht der Fall.
    0 - https://github.com/Xeeynamo/sotn-decomp/blob/master/src/main...

    • Ich würde gern Reimplementierungen alter Konsolenspiele in C+SDL2 und OpenGL 2.1 sehen.
      Da N64-Spiele inzwischen per Decompiler auf den PC portiert werden, macht das Hoffnung.
      Man könnte einwenden: „Für diese Spiele gab es doch bereits PC-Versionen“, aber wenn man ein N64-Spiel neu kompiliert und Effekte durch reine Texturen oder einfachere Effekte statt Shader ersetzt, kann es praktisch überall laufen, sogar auf langsamen Geräten wie günstigen Netbooks von 2009.
      Es gibt auch einen Port von Super Mario 64 auf die 3DFX-API. Spiele, die komplex auf den N64-Framebuffer zugreifen, bräuchten wohl OpenGL 3.3, um diesen Microcode nachzuahmen; wenn die Engine auf Hardware ab Pentium III aber ohnehin sehr schnell läuft, wäre es nicht schwer, den Rest mit GL-2.1-Beschleunigung laufen zu lassen und nur Teile in Software zu emulieren.
  • Ich habe schon viele Exploit-Analysen dieser Art in verschiedensten Formen gelesen, und es würde mich freuen, noch 100 weitere zu lesen.

  • Das wirkt wie ein gutes Beispiel für eine falsche Sicherheitsdenkweise in der Konsolenentwicklung.
    Der Gedanke „Speicherdaten können nur wir verwenden, also müssen wir nur das parsen, was wir selbst geschrieben haben“ ist im Konsolenbereich verbreitet, aber grundlegend falsch, weil Menschen künstlich erzeugte Speicherdaten vorbereiten können.
    Unabhängig davon sollten Konsolen ihre Nutzer nicht als Feinde behandeln; wenn sie es aber trotzdem tun, müssen auch die Spiele eine dazu passende Sicherheitsdenkweise haben.

    • Inzwischen ist das in gewissem Maß Realität geworden. Heutige Konsolen verschlüsseln und signieren Savegames alle, binden sie an Accounts, und die meisten – bei Xbox weiß ich es nicht – verhindern, dass Savegames anderswohin als auf die Konsole und in den kostenpflichtigen Cloud-Speicher kopiert werden.
    • Bei einem normalen Computer würde ich der Aussage „Konsolen sollten ihre Nutzer nicht als Feinde behandeln“ zu 100 % zustimmen, aber bei Konsolen fühlt es sich etwas anders an.
      Ich weiß nicht, wie man Cheating in Online-Spielen verhindern soll, wenn man nicht einschränkt, was Nutzer tun können.
  • Zu Tony Hawks Verteidigung: Er ist Profi-Skater, kein Sicherheitsanalyst.
    Die begrenzte Zeit, die er Ende der 90er und Anfang der 2000er vor einer Tastatur verbrachte, wurde wohl nicht dafür genutzt, Buffer Overruns zu auditieren, sondern dafür, den 900 McTwist in einer bald ikonischen Spieleserie natürlich wirken zu lassen.

  • Ich hatte jetzt die Gelegenheit, eine Legende aus meiner Kindheit zu überprüfen. War Tony Hawk derjenige, der als Erster einen 720 geschafft hat?

    • Laut https://en.wikipedia.org/wiki/Aerial_(skateboarding) heißt es: „Der 720, also ein Trick mit zwei vollständigen Drehungen in der Luft, ist einer der seltensten Tricks im Skateboarding; Tony Hawk gelang er 1985 als Erstem, und er war nicht geplant.“
      Wahrscheinlich ist damit „der erste dokumentierte“ gemeint, aber wenn ihn schon jemand vorher geschafft hätte, hätte diese Person vermutlich damit geprahlt; und wer dazu in der Lage gewesen wäre, wäre ohnehin wahrscheinlich ein Profi-Skater gewesen.