Skype Obfuscation Seminar Information Systems Engineering

Die Seite wird erstellt Merle Meißner
 
WEITER LESEN
Skype Obfuscation
       Seminar Information Systems Engineering

                                     Mara Beilin

                                Fachhochschule Aachen
                  Fachbereich Elektrotechnik und Informationstechnik
                          Euperner Straße 70, 52066 Aachen
                        {mara.beilin@alumni.fh-aachen.de}

        Zusammenfassung. Es gibt unterschiedliche Verfahren Software zu
        schützen, die teiwleise auch kombiniert werden können. Diese Ausar-
        beitung stellt einige Verfahren vor und Möglichkeiten wie diese umgan-
        gen werden können. Dabei liegt der Schwerpunkt auf den Techniken die
        Skype, eine Internet-Telefonie-Software des Unternehmens Microsoft, ver-
        wendet.

        Schlüsselwörter: Skype, Obfuscation, Tamper Resistant Software, In-
        tegrity Verification Kernel

1     Einleitung

Um Quelltext einer Software vor Manipulationen oder Reverse Engineering zu
schützen, gibt es die Möglichkeit Obfuscation einzusetzen. Obfuscation bedeutet
in diesem Zusammenhang, dass Programmcode verschleiert wird und somit für
den Menschen schlecht zu lesen und zu verstehen ist, Maschinen diesen aber
mit gleicher Funktionalität und in etwa gleicher Zeit ausführen können. Es gibt
verschiedene Methoden Quelltext zu verschleiern, einige werden in Kapitel 2
erläutert. Des weiteren gibt es die Möglichkeit verschiedene Verfahren (zu de-
nen auch Obfuscation gehört) zu kombinieren, um Tamper Resistant Software
zu erhalten (siehe Kapitel 3), die sich der Beobachtung und der Modifizierung
entzieht, wie in [1] vorgestellt. Wird die Beobachtung erschwert, wird auch das
Reverse Engineering schwierig und wenn vor Modifizierung geschützt wird, lässt
sich die Software nicht ohne weiteres manipulieren.

Der Quelltext von Skype ist nicht öffentlich zugänglich und es werden verschie-
dene Schutzmaßnahmen eingesetzt, die teilweise auf Verfahren für Tamper Resi-
stant Software beruhen, um den Quelltext und die Funktionsweise zu verschlei-
ern. Außerdem sendet Skype regelmäßig teilweise verschlüsselte Daten ins In-
ternet. Da Skype von vielen Benutzern1 weltweit eingesetzt wird, stellt sich die
Frage, ob Skype nicht den Nutzer ausspioniert, d.h. heimlich Daten sammelt und
1
    Im März 2011 waren 30 Millionen Skypenutzer gleichzeitig online [5]
2            Mara Beilin

verschickt oder sogar eine Hintertür hat, die ein sehr gefährlicher Angriffsstart-
punkt sein kann2 3 . Diese Möglichkeiten werden in Kapitel 4 untersucht.

2     Technik und Beispiele für Obfuscation

Es gibt verschiedene Möglichkeiten Obfuscation auf Quellcode anzuwenden. Man
kann das Layout, die Datenstruktur, die Kontrollstrukturen verschleiern oder
bekannte Schwachstellen ausnutzen, siehe Abbildung 1.

              Abb. 1. Vier Anwendungsziele für Obfuscation aus [4, S.2]

   Der folgende Quellcode HelloWorld1 hat genau die gleiche Ausgabe wie
HelloWorld2, was auf den ersten Blick nicht erkennbar ist.

public class HelloWorld1
{
   public static void main(String[] args)
   {
       System.out.println("Hello world!");
   }
}

public class
HelloWorld2{
/*private static
system.out.print
*/public static
void main(Str
ing[] args){S
ystem.o/*ut*/
ut.prin
tln/*&%$*/("He
llo wor
ld!");/*~§$%’’*/}}
2
    Spekulationen um Backdoor in Skype [6]
3
    Skype: Staat hört mit [7]
Skype Obfuscation       3

    Hier wurde das Lesen des Quellcodes mit Hilfe einer Umformatierung und
durch Einfügen von sinnlosen Kommentaren erschwert. Die Änderung aussage-
kräftiger Namen (von Variablen, Methoden, Klassen) wie zum Beispiel anzahl-
Urlaubstage, in beliebige Buchstaben-Zahlen-Kombinationen wie xzy42igfd7 oder
in andere aussagekräftige Namen die aber irreführend sind wie anzahlWerktage-
ProMonat, erschweren das Verstehen des Quellcodes noch weiter.
    Die Datenstruktur kann zum Beispiel verschleiert werden, indem man Ar-
rays verändert. Mehrere Arrays können in eins zusammengefasst, ein Array auf
mehrere aufgeteilt oder die Dimension eines Arrays geändert werden. Andere
Beispiele sind, dass anstatt statischer Daten Prozeduren verwendet werden, die
entsprechende Werte generieren oder Objekte anstatt skalarer Datentypen zu
verwenden.
    Soll die Kontrollstruktur nicht offensichtlich sein, können Pointer, Sprünge
oder bedingte Anweisungen eingesetzt werden, um Verwirrung zu stiften.
    Des Weiteren kann man versuchen Schwachstellen in den Werkzeugen zu fin-
den, die darauf abzielen Obfuscation aufzulösen (Deobfuscation) bzw. in Reverse
Engineering Software und diese dann ausnutzen. Oder man nutzt allgemeine
Probleme der Deobfuscation-Technik.

3     Methoden für Tamper Resistant Software
Eine 100-prozentige Sicherheit kann es nicht geben, aber je höher man den Auf-
wand für den Angreifer macht, desto höher ist die Wahrscheinlichkeit, dass die
Software geschützt bleibt (vor Reverse Engineering und Manipulation). Also
ist die Voraussetzung für Tamper Resistant Software, dass sie nur mit hohem
Aufwand beobachtet oder modifiziert werden kann, siehe [1, S. 320].

3.1   Geheime Komponente
Dazu wird eine geheime Komponente in den Quellcode eingearbeitet und si-
cher gestellt, dass das Finden und Manipulieren dieser Komponente möglichst
schwierig ist. Dafür werden vier Prinzipien miteinander verbunden, siehe [1, S.
320].
   Die geheime Komponente sorgt dafür, dass Code nicht beliebig ausgetauscht
werden kann. Nehmen wir an es gibt keine geheime Komponente, dann könnte
man Codeteile nach Belieben austauschen und es gäbe keine Möglichkeit das
zu erkennen. Ist die geheime Komponente gut im Ablauf der Software verteilt
und versteckt, führen schon kleinste Änderungen am Quellcode dazu, dass die
Manipulation sofort bemerkt wird, da die geheime Komponente verändert wurde.

Verstecken der geheimen Komponente Eine geheime Komponente sollte so
im Quellcode untergebracht sein, dass sie zu keinem Zeitpunkt durch das Ausle-
sen des Speichers gefunden werden kann. Außerdem sollte die geheime Kompo-
nente nie von einer einzelnen Prozedur verwendet werden, da sonst ein Angreifer
bei Ausführung des Codes durch Beobachtung die geheime Komponente sehen
4           Mara Beilin

könnte. Die geheime Komponente sollte in viele Einzelteile aufgeteilt und im
gesamten Code verteilt werden. Die geheime Komponente wird also in Zeit und
Raum versteckt, siehe [1, S. 320].

Obfuscation der verzahnten Elemente Durch eine Verzahnung der einzel-
nen Methoden, wird erreicht, dass entweder der gesamte Code ausgeführt wird
oder garnichts passiert. Dadurch wird verhindert, dass eine Komponente die zum
Beispiel die Integrität überprüft, zuerst fertig ist und Manipulationen an anderen
Komponenten nicht mehr bemerkt.
    Des Weiteren sollte auf den gesamten Ablauf Obfuscation angewendet wer-
den, damit nicht ersichtlich wird, welche Komponente was berechnet. Dies lässt
sich mit selbstver- und entschlüsselndem und selbstmodifizierendem Code errei-
chen, siehe [1, S. 320]. Während ein Codeteil entschlüsselt wird, verschlüsselt
sich ein anderer wieder, so dass immer möglichst wenig Unverschlüsseltes im
Speicher zu finden ist. Gleichzeitig wird ein und der selbe Speicherplatz immer
wieder von unterschiedlichen Programmteilen genutzt und dabei überschrieben.

Individuelle Elemente Um einen Klassenangriff zu vermeiden, also einen An-
griff auf eine Klasse von Software, sollte jede Installation individuelle Elemente
enthalten. Dies kann durch unterschiedliche Codeelemente oder unterschiedliche
Schlüssel geschehen, siehe [1, S. 320].

Vertrauen durch Abhängigkeit Durch Abhängigkeit einzelner Codeelemen-
te, kann sicher gestellt werden, dass keines der anderen Codeelemente mani-
puliert wurde. Die richtige Ausführung eines Codeelements, ist nicht nur von
dem jeweiligen Codeelement selbst abhängig, sondern auch von der korrekten
Ausführung anderer Codeelemente, siehe [1, S. 320].

3.2   Integrity Verification Kernel

Die in Kapitel 3.1 dargestellten Prinzipien jeweils alleine schützen Software nicht
ausreichend vor Reverse Engineering und Manipulation. Ein Integrity Verifica-
tion Kernel (IVK ) wendet alle vier Prinzipien gleichzeitig an. IVKs sind kleine,
manipulationsresisitente Codeteile, die kritische Funktionen ausführen, aus [1,
S. 321].

4     In Skype eingesetzte Maßnahmen und ihre Umgehung

Skype verwendet unterschiedliche Verfahren um den Quelltext und die Funkti-
onsweise vor Beobachtung und Manipulation zu schützen. Einige der Verfahren
wurden in Kapitel 2 und 3 vorgestellt. Dies führt, wie in Kapitel 1 erläutert, zu
verschiedenen Problemen.
Skype Obfuscation       5

Probleme aus der Netzwerksicht Beihnahe alles ist mit Obfuscation ver-
schleiert. In der von Skype verwendeten Peer-to-Peer Architektur gibt es sehr
viele Peers und das Ziel-Peer ist nicht bekannt. Außerdem erzeugt Skype selbst
dann Datenverkehr, wenn es nicht verwendet wird, siehe [3, S. 3].

Probleme aus der Systemsicht Skype enthält viele Schutzmaßnahmen, viel
Anti-Debugging-Technik und viel verschlüsselten Code, siehe [3, S. 3].
    Im folgenden sollen die von Skype eingesetzten Maßnahmen und wie man
diese umgehen kann, vorgestellt werden.

4.1   Binary Packing

Skype verwendet einen eigenen Packer um Programmdateien zu packen und
zu entpacken. Damit man die Programmdateien nicht selber entpacken kann,
sind im Binary einige Bereiche verschlüsselt und im Speicher ist Skype komplett
verschlüsselt, siehe Abbildung 2.

                        Abb. 2. Skype Binary aus [3, S. 9]

     Damit der Speicherinhalt beim Entpacken nicht kopiert werden kann (Dump),
löscht Skype den Quellcode am Anfang der Binary, siehe Abbildung 3. Dann erst
entschlüsselt es verschlüsselten Code und lädt eine eigene Importtabelle, wobei
die Original-Importtabelle überschrieben wird.
6           Mara Beilin

                     Abb. 3. Anti-Dumping Tricks [3, S. 10]

   Um diese Maßnahmen zu umgehen, muss ein eigener Entpacker gebaut wer-
den. Dazu wird der Aufbau des internen Bereichs genau betrachtet, die ver-
schlüsselten Bereiche werden mit den Schlüsseln, die im Binary liegen ent-
schlüsselt, die skype-eigene Importtabelle wird ausgelesen, und aus dieser und
der eigentlichen Importtabelle an einer anderen Stelle eine neue erstellt, wie in
Abbildung 4. Im Anschluss muss noch gepatched werden, um die automatische
Wiederverschlüsselung der einzelnen Bereiche zu verhindern.

                     Abb. 4. Eigener Entpacker aus [3, S. 12]
Skype Obfuscation       7

4.2     Code Integrity Checks

Skype verwendet Code Integrity Checks und überprüft damit, ob der Quellcode
nicht manipuliert wurde. Untersucht man dies genauer, stellt man fest, dass es
da einige interessante Besonderheiten gibt.
    Jeder Checksummen-Prüfer unterscheidet sich von den anderen, (was auf Po-
lymorphie hindeutet) und wird in zufälliger Reihenfolge ausgeführt. Die Check-
summe wird mit unterschiedlichen Operatoren berechnet (Addition, Subtrak-
tion, XOR-Verknüpfung, usw.) und ist in ihrer Länge zufällig. Dabei kann die
finale Checksumme dazu benutzt werden, einen Pointer auf den nächsten ausführ-
baren Codeteil zu generieren. Die Pointerinitialisierung wird durch Berechnun-
gen verschleiert. Die Schleifenschritte haben unterschiedliche Werte und Vorzei-
chen und es werden belanglose Abkürzungen eingefügt, siehe [3, 17].
    Die Checksummen-Prüfer sind zwar polymorph, aber alle enthalten

 –    eine   Pointerinitialisierung,
 –    eine   Schleife,
 –    eine   Suche und
 –    eine   Berechnung.

    Nach diesen Elementen kann man ein selbsterstelltes Skript suchen lassen.
In Skype wurden annnährend 300 solcher Checksummen-Prüfer gefunden, siehe
[3, S. 19].
    Es gibt zwei verschiedene Möglichkeiten an das richtige Ergebnis der Check-
summen zu gelangen. Entweder mit Code-Emulierung oder Parallel-Debugging.

Parallel-Debugging Man könnte einfach Breakpoints auf die Checksummen-
Prüfer setzten, da Software-Breakpoints aber das Ergebnis verändern können,
da sie sich selber auch in den Speicher schreiben, benötigt man Hardware-
Breakpoints. Da diese aber nicht in unbegrenzter Anzahl zur Verfügung stehen,
mischt man einfach beide Verfahren, bzw. lässt sie parallel laufen, siehe [3, S.
20].
    Als erstes werden auf jeden Checksummen-Prüfer in Process 1 Software-
Breakpoints gesetzt und gewartet bis dieser Breakpoint erreicht wird. Dann
setzt man in Process 2 zwei Hardware-Breakpoints, einen vor und einen nach
dem Checksummen-Prüfer und lässt ihn den ersten Breakpoint erreichen. Dort
notiert man den ersten Wert und lässt ihn dann zum zweiten Breakpoint wei-
ter laufen. Nun notiert man erneut den Wert und berechnet aus diesen beiden
die Checksumme. Diese Checksumme verwendet man jetzt im Process 1 und
überspringt den Checksummen-Prüfer. Nun wiederholt man das ganze, bis man
alle Werte zusammengetragen hat, siehe Abbildung 5.
8           Mara Beilin

                     Abb. 5. Parallel-Debugging aus [3, S. 22]

Code-Emulierung Eine andere Möglichkeit ist, alle Checksummen zu berech-
nen, mit Hilfe eines Skripts den Anfang des Checksummen-Prüfers und damit
die Pointer-Initialisierung und das Ende der Schleife zu finden. Dann ersetzt man
die ganze Schleife durch die Vortäuschung der korrekten Checksumme.

4.3   Anti Debugging Technics
Skype versucht sich auch gegen dynamische Angriffe, wie zum Beispiel Debug-
ging, zu wehren. Es erkennt SoftICE, ein Kernel-Mode-Debugger für Micro-
soft Windows und die Checksummen bemerken Software-Breakpoints, wie eben
erläutert. Erkennt Skype einen dynamischen Angriff, wird der Angreifer in die
Irre geführt. Die Register werden zufällig neu angeordnet und es wird auf eine
zufällige Speicherseite gesprungen. Für den Angreifer ist es sehr schwierig sich
erneut zurecht zufinden, da der Befehlszähler nicht mehr auffindbar ist und auch
sonst vieles neu angeordnet wurde.
     In dem man versucht die Stelle zu finden, wo nach einem Angriff auf eine
zufällige Speicherseite verwiesen wird, kann man den Pointer für die aktuelle
Seite finden und einen Hardware-Breakpoint darauf setzen. Dann kann man
diese Stelle überwachen und wenn es soweit ist, den Überwachungscode von
Skype finden und ggf. modifizieren.
     Oder man verwendet einen Debugger, der von Skype nicht erkannt wird
(Stand März 2006), den Rasta Ring 0 Debugger (RR0D).

4.4   Code Obfuscation
In Skype wird jeder Aufruf dynamisch berechnet, was das Verfolgen erschwert.
In der Programmiersprache C würde das zum Beispiel wie folgt aussehen:
Skype Obfuscation     9

if (sin (a) == 42)
{
   do dummy stuff ();
}
go on ();

    Aus [3, 36].
    Dabei muss jede bedingte Anweisung untersucht werden, um dem Verlauf
folgen zu können.
    An manchen Stellen verwendet Skype falsche Exceptions und Fehlermeldun-
gen um Speicheradressen oder Register zu verändern. Das bedeutet, dass alle
Sonderfallbehandlungen genau untersucht werden müssen.
    In einigen Fällen kann man die genau Analye vermeiden, indem Shellcode
eingesetzt wird um die Methoden parasitär zu nutzen.

4.5   Skype im Netzwerk
Skype benutzt Obfuscation für den Netzwerkverkehr. Die Netzwerkdaten werden
mit RC4, einer Stromverschlüsselung, codiert, siehe Abbildung 6. Dabei wird hier
RC4 nur für Obfuscation eingesetzt, nicht um die Vertraulichkeit der Daten zu
schützen.

                    Abb. 6. RC4 Verschlüsselung aus [3, S. 42]

    Der RC4 -Schlüssel besteht aus 80 Bytes, aber es gibt verfahrensbedingt ma-
ximal 232 verschiedene Schlüssel. Brute Force war zu aufwändig, deshalb wurde
in [3, S. 45] Shellcode verwendet, um den Seed zum RC4 -Schlüsselgenerator zu
bekommen.
10           Mara Beilin

5    Fazit

”There is no such thing as tamper-resistant software on a general purpose com-
puter. If your computer can see the instructions, then you can see them too.”
von Bruce Schneier aus [9].
    Obfuscation dient dazu den Aufwand für Softwareanalyse so hoch zu machen,
dass die Ressourcen des Angreifers nicht ausreichen. Da Angreifer immer neue
Möglichkeiten entwickeln, um den Aufwand zur Deobfuscation zu verringern,
so wie die andere Seite immer weitere Techniken entwickelt um den Aufwand
wiederum zu erhöhen, wird es ein ewiges Wettrennen bleiben.
    Um Software best möglichst zu sichern, sollte immer eine Kombination aus
aktuell als sicher geltenden Verfahren genutzt werden. Dazu gehören Obfuscati-
on, Verschlüsselung und Manipulationsdetektion.

Literatur
1. Aucsmith, D.: Tamper Resistant Software: An Implementaion. In Ross J. Ander-
   son, editor, Information Hiding, First International Workshop, pages 317–333, Cam-
   bridge, U.K. Springer-Verlag. Lecture Notes in Computer Science, Vol. 1174 (Mai
   1996)
2. Aucsmith, D., Graunke, G.: Tamper Resistant Methods and Apparatus. US patent
   5,892,899,1999. Assignee: Intel Corporation. (1996)
3. Biondi, P., Desclaux, F.: Silver Needle in the Skype. BlackHat Europe (März 2006)
4. Collberg, C., Thomborson, C., and Low, D.: A Taxonomy of Obfuscating Transfor-
   mations. Technical Report #148, Department of Computer Science, The University
   of Auckland (1997)
5. Parkes, P.: 30 million people online on Skype. http://blogs.skype.com/en/2011/
   03/30_million_people_online.html (März 2011)
6. Sokolov, D.: Spekulationen um Backdoor in Skype. http://www.heise.
   de/security/meldung/Spekulationen-um-Backdoor-in-Skype-189880.html (Ju-
   li 2008)
7. Vetter, U.: Skype: Staat hört mit. http://www.lawblog.de/index.php/archives/
   2010/08/17/skype-staat-hort-mit/
8. Hanácek, P.: Problems of Tamper Resistant Software. ISM 2000, Roznov pod Rad-
   hostem, CZ (2000)
9. Schneier, B.: Zitat auf: http://www.eetimes.com/electronics-news/4036947/
   Update-Intel-ID-protection-scheme-called-insufficient (1999)
Sie können auch lesen