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