Ein Exklusiv-Service von www.evo
Transcrição
Ein Exklusiv-Service von www.evo
Ein Exklusiv-Service von www.evo-x.de Übersetzung Original-Artikel: http://xbox-linux.sourceforge.net/articles.php?aid=2003189065649 Technische Analyse des 007 Agent im Kreuzfeuer SaveGame Hack vom 9. Juli 2003 Einführung Der 007:AUF (Anm.d.Übersetzers: AUF = Agent under fire; englischer Titel von: 007 Agent im Kreuzfeuer) SaveGame Hack wurde am 29. März 2003 mit viel Skepsis (der 1. April war nicht weit) veröffentlicht. Ich nahm an, dass der Hack realistisch sei, und so kann ich jetzt die Details der Funktionsweise enthüllen. Der Entwickler des Hacks hat nie die Funktionsweise offengelegt, und viele Anstrengungen wurden unternommen, um eine Analyse des Hacks zu erschweren. Wie auch immer, nach ein paar Analysen war die Funktionsweise schon wenige Tage nach dem Erscheinen des Hacks bekannt. Die Information wurde vertraulich behandelt, doch jetzt, nachdem eine Person namens free-x den Secret Key (AdÜ: nicht der RC4 Key der XBOX, sondern der Key des 007:AUF Games, s.u.) und eine nicht mehr verhüllte Version (für Mechassault) auf xboxhacker.net veröffentlicht hat, scheint der richtige Zeitpunkt gekommen zu sein, die Funktionsweise des originalen Hacks zu veröffentlichen. Bitte beachten Sie, das es keine Garantie gibt, dass alle Informationen in diesem Dokument korrekt sind. Es handelt sich um eine Analyse zur Weiterbildung. Ebenso soll diese Erklärung dazu dienen, die Restriktion des Hacks auf Xbox Linux Live Plugin System aufzuheben. Mit Hilfe dieser Informationen können andere Linux Programme auf einer ungemoddeten Xbox ausgeführt werden. Damit kann man vollständig mit Linux arbeiten, ohne die Garantie zu verlieren. Diese Erklärung ist nur für die Entwicklung von allgemeiner Software unter der Sect. 1201(f) Reverse Engineering exception of the DMCA (AdÜ: Amerikanisches Urheberrecht, die deutsche Fassung wird z.Z. für mitte August erwartet und regelt ähnliche Verfahren zum Schutze von Werken gegen Disassemblierung (Rückübersetzungen des binären Codes in Quell-Code)). So, hier nun die lange erwartet Funktionsweise: Zuerst, der Kerl, der den Hack entwickelt hat, ist sehr clever vorgegangen. Es gibt viele Sackgassen und trickreiche Fallen den Hack so aussehen zu lassen, als würde er Sachen tun, die er überhaupt nicht macht. Eine Anmerkung vorweg. SaveGames werden von dem Spiel grundsätzlich signiert. Das bedeutet, dass keine Änderung gemacht werden können, ohne das SaveGame neu zu signieren. Dies ist allerdings Grundlage einer anderen Diskussion und es sieht so aus, das Tools entwickelt wurden, die diese Arbeit übernehmen können. (AdÜ: ein Tool ist z.B. das xbedump Tool, geschrieben für Windows PCs). Ein Exklusiv-Service von www.evo-x.de Original-Artikel: http://xbox-linux.sourceforge.net/articles.php?aid=2003189065649 Jetzt geht’s aber los: Der buffer overflow (AdÜ: Pufferüberlauf) Der buffer overflow scheint den Profile Name des SaveGames zum Überlauf zu bringen. Dieser beginnt ab dem Offset 0x28. Man sieht dort eine lange Zeichenkette mit 0xFFs. In den nachfolgenden Mustern (nach den 0xFFs) findet man die Kette E7 FF 2B (AdÜ: hexadezimale Werte, das 0x wurde zur besseren Übersichtlichkeit weg gelassen) an 4 versch. Stellen. Diese sind nicht Abhängig von einander. Es handelt sich um die Adresse, die der buffer overflow überschreibt und von der dann das Programm ausgeführt wird.(AdÜ: sog. Einsprungstelle des Hacks) Nur die letzte Stelle ist wichtig, ich vermute, die anderen Stellen dienen nur dazu, ein "schöneres" Muster zu erzeugen. Lügen, Täuschungen und Tricks Der Rest des Hack unternimmt alles nur mögliche, um sich selber zu verstecken. Es gibt zwei wesentliche Komponenten des Verkleidungsspiels: den "fake" Hack und das JPEG Image vom Tux. Zuerst der "fake" Hack: er startet ab dem Offset 0xD00 im SaveGame. Wenn man das SaveGame disassembliert, wird man leicht davon überzeugt sein, dass hier wirklich interessanter Code beginnt. Es sieht aus, als ob die eigene Adresse geladen, das write protection im Speicher abgeschaltet, der Kernel gepatched und XLaunchNewImage aufgerufen wird. Es gibt eine Verzweigungslogik, die vorgibt den Kernel auf versch. Weise in Abhängigkeit des Wertes in der Speicherstelle 0x8001FFFF zu patchen. Die Patches arbeiten in der Weise, wie es auch einige Modchips tun, einige sogar mit den gleichen Offsets. Der Path zur linux.xbe findet man ebenfalls unter dem Offset 0xFD5. Der Code sieht bei erster Durchsicht sehr plausibel aus. Allerdings fallen bei näherer Betrachtung einige Inkonsistenzen auf. Erstens, der Wert an der Speicherstelle 0x8001FFFF passt zu keinem bekannten Kernel, den ich ihrgend wie auch nur kenne. Zweitens sind einige Kernel-Patches nur Müll, denn sie machen absolut keinen Sinn. Drittens gibt es keinen Aufruf von IoCreateSymbolicLink vor dem Aufruf von XLaunchNewImage. XLaunchNewImage überprüft und stellt sicher, das der Path zur ausführbaren XBE nach 'D:' verweist, um zu vermeiden, dass Applikationen von der Platte geladen werden, sondern nur vom DVD-ROM Laufwerk. Ohne \Device\Harddisk0\Partition1 mit Hilfe von IoCreateSymbolicLink nach 'D:' zu mappen, gibt es für den Kernel keinen Weg, die default.xbe wie angegeben zu finden. An zweiter Stelle ist das Tux JPEG. Es beginnt ab dem Offset 0x1080 im SaveGame als JPEG Image. Das ist offensichtlich durch den Text JFIF welcher in allen JPEG Headern vorkommt. Wenn Sie den Block extrahieren erhalten Sie ein kleines Bild vom Tux. Sieht also nach einer harmlosen Zugabe eines Linux Fanatikers aus. Es ist typisch für "Linuxer" solche Sachen überall zu verteilen. In der Realität jedoch, ist der wahre Hack verschlüsselt und in diesem Image gespeichert. Diese Art der Datenspeicherung in Bildern bezeichnet man als Steganographie. Es stört nicht weiter, dass die Daten im Header und nicht im Bild selber gespeichert werden. Es ist nicht unabwegig. Wir werden in ein paar Augenblicken zum Inhalt der verstecken Daten zurück kommen. Ein Exklusiv-Service von www.evo-x.de Original-Artikel: http://xbox-linux.sourceforge.net/articles.php?aid=2003189065649 Handhabung versch. Game Versionen Nach dem wir nun realisiert haben, das der Hack ein fake ist, werden wir rausfinden, was wirklich passiert. Wir wissen, das der overflow uns an die Stelle 0x2BFFE7 im Speicher bringt, so das wir rausfinden sollten, was dort passiert. Nun, wenn wir das SaveGame betrachten, gibt es dort 4 kleine Assemblerschnipsel verteilt über das SaveGame, welche alle zur gleichen Position, relativ zu deren Position im SaveGame, springen. Die Offsets sind: 0xCF, 0x5EF, 0x90F und 0x101F. Die Schnipsel haben folgende Form (hier das Beispiel am Offset 0x5EF): Opcodes: 31C0 2D40F5D3FF 50 C3 Assembly: xor eax,eax sub eax,FFD3F540 push eax ret Comment: ; set eax to 0 ; eax = 0x2C0AC0 ; oush the value of eax to the call stack ; return Dieses Code-Schnipsel führt einen Jump nach 0x2C0AC0 aus. Abhängig von der Spiel-Version ist die Position des SaveGame an unterschiedlichen Speicherstellen zu finden. In jeder gefunden Version befindet sich eine der vier oben erwähnten Offsets an der Speicherstelle 0x2BFFE7. Wenn wir im obigen Beispiel beachten, das die Differenz zwischen 0x2C0AC0 und 0x2BFFE7 gleich 0xAD9 ist, müssen wir nur 0xAD9 zu 0x5EF (Offset des Beispiel Code-Schnipsels) addieren und erhalten den realen Einstiegspunkt für den Hack welcher 0x10C8 ist. Ein Exklusiv-Service von www.evo-x.de Original-Artikel: http://xbox-linux.sourceforge.net/articles.php?aid=2003189065649 Der Entschlüsselungs- Algorithmus Von der Position 0x10C8 beginnt der Code im Bereich des "fake" Hacks umher zu springen. Er stellt einen Entschlüsselungs-Algorithmus dar. Wenn man allen Sprüngen im gesamten Bereich folgt, landet man schlussendlich bei folgendem Assembler-Code: Opcodes: B2EA E89DFDFFFF 5E 89D5 31C9 89F7 B1AA B501 31C0 B2C3 B6F8 0FCA B20F B623 52 89E2 90 90 89F2 AC 30C8 00C8 30C8 31E8 AA E29F FFE2 Assembly: Comment: mov dl, EA call 0xE6C pop esi ; esi = 0x10CF mov ebp, edx xor ecx, ecx mov edi, esi mov cl, 0xAA mov ch, 0x01 ; ecx = 0x1AA xor eax, eax mov dl, 0xC3 mov dh, 0xF8 bswap edx mov dl, 0x0F mov dh, 0x23 ; mov edx, 0xC3F8230F push edx mov edx, esp nop nop ; call edx?? See below mov edx, esi decrypt_loop: lodsb xor al, cl add al, cl xor al, cl xor eax, ebp stosb loop decrypt_loop ; while ecx > 0 jmp edx ; jmp 0x10CF Hier als C: for (ecx = 0x1AA; ecx; ecx--, ptr++) *ptr = (unsigned char) ((((*ptr ^ ecx) + ecx) ^ ecx) ^ 0xEA); Der Start ist am Offset 0x10CF im SaveGame und entschlüsselt 0x1AA Bytes mit dem simplen Algorithmus. Diese Sektion stellen die versteckten Daten im Tux Image dar. Es ist der "echte" Hack. Wenn die Daten entschlüsselt sind wird das Programm in der entschlüsselten Sektion fortgesetzt. Ein Exklusiv-Service von www.evo-x.de Original-Artikel: http://xbox-linux.sourceforge.net/articles.php?aid=2003189065649 Etwas ungewöhnlich sind die beiden NOP Opcodes. Es sieht so aus, als ob sie vorher "call edx" enthielten, welches dann als Ergebnis "mov dr7,eax" und "ret" ist und dient zum disablen aller gesetzten breakpoints. Anmerkung; wenn Sie "verschlüsseln" wollen, müssen Sie folgendes in C programmieren: for (ecx = 0x1AA; ecx; ecx--, ptr++) *ptr = (unsigned char) ((((*ptr ^ 0xEA) ^ ecx) - ecx) ^ ecx); Ein Exklusiv-Service von www.evo-x.de Original-Artikel: http://xbox-linux.sourceforge.net/articles.php?aid=2003189065649 Der echte Hack Jetzt liegt der entschlüsselte Code vor und wir können sehen, was er wirklich tut. Erst jetzt macht die Disassemblierung Sinn. Hier ist er .... (Alle calls und Offsets sind relativ zu 0x10CF im SaveGame) Opcodes: Assembly: Comment: E800000000 5D call 00000005 pop ebp ; 0x00000005 81ED05000000 sub ebp, 00000005 ; ebp = 0x10CF BF000020C0 mov edi, C0200000 B900100000 mov ecx, 00001000 8B07 mov eax, dword ptr [edi] 2500FFFFFF and eax, FFFFFF00 0D63000000 or eax, 00000063 8907 mov dword ptr [edi], eax 81C704000000 add edi, 00000004 49 dec ecx 75E9 jne 00000016 BE00000080 mov esi, 80000000 AD lodsd 81EE03000000 sub esi, 00000003 ; 0x00000016 ; turn off WP ; 0x00000032 3DBD1B4BA4 cmp eax, A44B1BBD 75F2 jne 00000032 8176FFD68BD72D xor dword ptr [esi-01], 2DD78BD6 8D8533010000 898546010000 8D853B010000 898537010000 8D854E010000 898577010000 8D8556010000 898552010000 lea eax, dword mov dword ptr lea eax, dword mov dword ptr lea eax, dword mov dword ptr lea eax, dword mov dword ptr 8DBDF7000000 8DB503010000 A1F0F62B00 3D56657273 742A 81C60C000000 A130FF2B00 3D56657273 7418 81C60C000000 A110FA2B00 3D56657273 7406 81C60C000000 A5 lea edi, dword ptr [ebp+000000F7] lea esi, dword ptr [ebp+00000103] mov eax, dword ptr [002BF6F0] cmp eax, 73726556 je 000000B9 add esi, 0000000C mov eax, dword ptr [002BFF30] cmp eax, 73726556 je 000000B9 add esi, 0000000C mov eax, dword ptr [002BFA10] cmp eax, 73726556 je 000000B9 add esi, 0000000C movsd ; scan RAM for public key ; modify last 4 bytes of public key ptr [ebp+00000133] [ebp+00000146], eax ptr [ebp+0000013B] [ebp+00000137], eax ptr [ebp+0000014E] [ebp+00000177], eax ptr [ebp+00000156] [ebp+00000152], eax ; Version checking ; Version checking ; Version checking ; 0x000000B9 Ein Exklusiv-Service von www.evo-x.de Original-Artikel: http://xbox-linux.sourceforge.net/articles.php?aid=2003189065649 A5 A5 8D8533010000 50 3E8B9DFF000000 FF13 movsd movsd lea eax, dword ptr [ebp+00000133] push eax mov ebx, dword ptr ds:[ebp+000000FF] call dword ptr [ebx] 8D854E010000 50 8D8533010000 50 3E8B9DFB000000 FF13 lea eax, dword ptr [ebp+0000014E] push eax lea eax, dword ptr [ebp+00000133] push eax mov ebx, dword ptr ds:[ebp+000000FB] call dword ptr [ebx] 6800000000 8D857F010000 push 00000000 lea eax, dword ptr [ebp+0000017F] 50 push eax FF95F7000000 call dword ptr [ebp+000000F7] ; param 1 = "D:\UDATA\4541000d\000000000000\default.xbe" ; call XLaunchNewImage EBFE jmp 000000F5 ; infinite loop ; param 1 = "\??\D:" ; call IoDeleteSymbolicLink ; param 2 = "\Device\Harddisk0\Partition1" ; param 1 = "\??\D:" ; call IoCreateSymbolicLink ; param 2 = NULL Wie man sieht, ermittelt der Hack zuerst seine eigene Startadresse, damit er Pointer auf ParameterStrukturen und Strings aufbauen kann. Anschließend schaltet er die write-protecten des Kernel-Speichers aus. In der Folge scannt er den Speicher nach den 4 letzten Bytes des Public-Keyes. Hat er sie gefunden, modifiziert er diese 4 Bytes. Dann ermittelt er die relative Adresse der Puffer-Pointer innerhalb der ANSI_STRING Struktur, um diese in den Funktionen zu verwenden. Anschließend checkt er den Versions-String des SaveGame an versch. Speicherpositionen um die Position von XlaunchNewImage zu erhalten. Es folgt ein Aufruf von IoDeleteSymbolicLink um das Mapping von ‚D:’ zu lösen, gefolgt von IoCreateSymbolicLink um das Mapping mit der Partition, die das SaveGame enthält, wieder aufzubauen. Zum Schluss folgt der Aufruf von XlaunchNewImage mit dem Path zur neuen XBE. Ein Exklusiv-Service von www.evo-x.de Original-Artikel: http://xbox-linux.sourceforge.net/articles.php?aid=2003189065649 Der neue Public Key Im obigen Code können wir sehen, dass die letzen 4 Bytes des Public-Keys mit 2DD78BD6 xor’ed werden. Es ist klar, das diese Nummer nicht durch Zufall gewählt wurde. Wenn der Public-Key einmal in dieser Weise behandelt worden ist, erhält man einen Public-Key der einfach in Faktoren zerlegt werden kann. Er ist jetzt durch 3 teilbar. Dadurch kann einfach die andere Primzahl ermittelt und dann auf den verwendeten Secret-Key geschlossen werden. Ich überlasse es dem Leser diese Aufgabe als Übung durchzuführen. Viel Spaß ... und lang lebe Linux! © 2003 Anonymous Original-Artikel: http://xbox-linux.sourceforge.net/articles.php?aid=2003189065649 Ein Exklusiv-Service von www.evo-x.de Ein Exklusiv-Service von www.evo-x.de Original-Artikel: http://xbox-linux.sourceforge.net/articles.php?aid=2003189065649