SEMINARARBEIT Exploit Generatoren und Obfuscation Tools (1)

Werbung
SEMINARARBEIT
im Studiengang Informationsmanagement und Computersicherheit
Lehrveranstaltung AK Informationsmanagement und –Sicherheit 1
Exploit Generatoren und Obfuscation Tools (1)
Ausgeführt von:
Hermann Wagner, BSc
Jovica Zuljic-Suljuzovic, BSc
Marko Buczolich, BSc
Begutachter: Ing. Thomas Mandl
Wien, 08.02.2015
(1410303021)
(1410303028)
(1410303018)
Kurzfassung
Um Antivirensoftware und Intrusion Detection Systeme zu täuschen verwenden MalwareHersteller diverse Verschleierungstechniken (Obfuscation), damit ihre Schadprogramme und
deren Kommunikation nach außen unentdeckt bleiben. So wird zum Beispiel DatenKomprimierung oder Verschlüsselung bei zu übermittelnden Daten verwendet, um Daten
unbemerkt an Intrusion Detection Systemen und Paketfiltern vorbei zu schleusen und um die
signaturbasierte Erkennung von Schadsoftware von Antivirensoftware zu umgehen.
In dieser Arbeit werden die verschiedenen Verschleierungstechniken genannt und diese
erläutert. Ziel ist es, dem Leser zu vermitteln wie einfach es ist einen frei verfügbaren und
bekannten Exploit (der von allen gängigen Virenherstellern erkannt wird) zu nehmen, diesen
mit Obfuscation-Techniken zu verändern und ihn anschließend unbemerkt von der
Antivirensoftware zu downloaden und auszuführen. Dazu wurde in einem Proof-of-Concept
genau dieses Szenario konstruiert und die Ergebnisse in dieser Arbeit dokumentiert. Zu den
Ergebnissen gehören sowohl die detaillierte Vorgehensweise, als auch Angaben über
verwendete Tools, benötigter Zeitaufwand und benötigtes Know-How. Basierend auf den
Ergebnissen folgt eine Einschätzung der Bedrohung und eine Betrachtung und Bewertung
von möglichen Gegenmaßnahmen.
2
Inhaltsverzeichnis
1
Einleitung ............................................................................................................... 4
1.1
Motivation .............................................................................................................. 4
1.2
Vorgehensweise und Gliederung ........................................................................... 4
2
Theoretischer Hintergrund ..................................................................................... 6
2.1
Exploits .................................................................................................................. 6
2.2
Code Obfuscation .................................................................................................15
2.2.1
Obfuscator ............................................................................................................15
2.2.2
Obfuscation in verschiedenen Programmiersprachen ...........................................17
2.2.3
Packer ..................................................................................................................34
2.2.4
Virtualisierung .......................................................................................................36
2.2.5
Deobfuscation .......................................................................................................37
2.3
3
Malware vs. Antivirus ............................................................................................37
Proof of Concept ...................................................................................................48
3.1
Vorgehensweise ...................................................................................................48
3.2
Durchführung ........................................................................................................49
3.3
Ergebnisse ............................................................................................................60
4
Gegenmaßnahmen ...............................................................................................61
4.1
Verbreitung von Malware ......................................................................................61
4.2
Verteidigungsmaßnahmen ....................................................................................63
5
Zusammenfassung ...............................................................................................72
6
Future Work ..........................................................................................................73
Literaturverzeichnis ..............................................................................................................74
Abbildungsverzeichnis ..........................................................................................................79
Tabellenverzeichnis ..............................................................................................................80
3
1 Einleitung
1.1 Motivation
Nach einer Malware-Infektion stellt sich oft für die Betroffenen die Frage wie es die
Schadsoftware auf ihr System geschafft hat, obwohl sie ihre Software immer upgedatet und
eine angesehene und aktuelle Antivirensoftware installiert haben. Vor allem für
Systemadministratoren und IT-Verantwortliche kann so ein Vorfall eine sehr unangenehme
Situation darstellen, wenn sie dem Management erklären müssen wieso ihre teuren
Sicherheitsvorkehrungen, wie Firewalls, Intrusion Detection Systeme und Virenscanner nicht
Alarm geschlagen haben. Die Antwort ist, dass die Hersteller von Exploits und Malware
diverse Verschleierungstechniken (Obfuscation) einsetzen damit ihre Schadprogramme und
deren Kommunikation nach außen unentdeckt bleiben. So wird zum Beispiel DatenKomprimierung oder Verschlüsselung bei zu übermittelnden Daten verwendet, um Daten
unbemerkt an Intrusion Detection Systemen und Firewalls vorbei zu schleusen.
Verschlüsselung und Komprimierung der Malware selbst kann weiters dazu verwendet
werden um die signaturbasierte Erkennung von Schadsoftware von Antivirensoftware zu
umgehen. Neben den beiden bereits erwähnten Techniken gibt es noch einige weitere
Maßnahmen, die verwendet werden. Die Hersteller von Antivirussoftware versuchen
natürlich ihre Erkennungsmechanismen zu verbessern, es hat jedoch den Anschein als seien
die Blackhats ihnen immer einen Schritt voraus.
Basierend auf dem oben genannten Problem werden in dieser Arbeit die verschiedenen
Techniken betrachtet, welche moderne Malware benutzt um unentdeckt zu bleiben. In einem
Proof of Concept wird anschließend gezeigt wie einfach es ist Exploits und Malware für ein
bestimmtes Programm zu finden und herunterzuladen und mit Obfuscation Techniken so zu
verändern, dass diese anschließend unbemerkt von Antivirensoftware ausgeführt werden
können. Um nachvollziehen zu können wie diese Obfuscatoren und Exploits funktionieren
werden zuerst die theoretischen Grundladen erläutert. Zuletzt wird natürlich auch noch auf
mögliche Gegenmaßnahmen eingegangen.
1.2 Vorgehensweise und Gliederung
Ausgehend von der Problemstellung und den Zielen gliedert sich die Arbeit wie folgt:

Kapitel 2 – Theoretischer Hintergrund
Die Arbeit ist so ausgelegt, dass sie auch für NICHT-Security-Experten gut lesbar
und nachvollziehbar ist. Daher orientiert sich das erste Kapitel an den Grundlagen zu
Exploits, Code Obfuscation, Malware und Virenschutzsoftware und richtet sich vor
allem an Leser die zwar aus der Informatik kommen, aber deren täglich Brot nicht die
IT-Sicherheit darstellt. Für Penetration Tester, Malware-Programmierer und AntivirusEntwickler dürfte das zweite Kapitel bloß eine Auffrischung ihres Wissens darstellen.
4

Kapitel 3 – Proof of Concept
Dieses Kapitel erläutert Schritt für Schritt wie eine vorhandene und den
Antivirenherstellern bekannte Malware mit Obfuscation Tools so verändert werden
kann, dass diese durch einen umfassenden Virenscan (zum Beispiel auf VirusTotal
oder Anubis) nicht mehr erkannt wird.

Kapitel 4 – Gegenmaßnahmen
Um den Leser nicht mit der Erkenntnis zurückzulassen, dass die Abwehr eines
gezielten Angriffes ohnehin nicht möglich ist, werden im Kapitel 5 mögliche
Gegenmaßnahmen unter die Lupe genommen und erläutert.
5
2 Theoretischer Hintergrund
In diesem Kapitel werden Exploits, Code Obfuscation, Malware und Virenschutzsoftware
behandelt.
Die Recherche über die theoretischen Grundlagen hat auch den Einstieg der Autoren in
diese Thematik dargestellt.
2.1 Exploits
Unter einem Exploit versteht man die Möglichkeit systematisch Schwachstellen in
Programmen auszunutzen. Das systematische Ausnutzen wird dabei mit Hilfe eines speziell
dafür angefertigten Programms oder Skripts bewerkstelligt, dem Exploit. Als Schwachstellen
werden Sicherheitslücken (engl. vulnerabilities) und Fehlfunktionen (engl. bugs) bezeichnet,
die bei der Entwicklung des Systems nicht berücksichtigt, übersehen, fälschlicherweise oder
auch absichtlich (z.B. backdoor) implementiert wurden.
Ziel eines Exploits ist



sich Zugang zu Ressourcen zu verschaffen für die der Angreifer (Hacker) keine
Berechtigung besitzt,
das Erlangen von Privilegien,
das System zu beeinträchtigen (zum Beispiel: Denial of Service).
[1], [2]
Sicherheitsexperten bzw. Sicherheitsforscher (Whitehat Hacker), die eine Schwachstelle
finden, bedienen sich aber ebenso Exploits um Sicherheitslücken aufzuzeigen und zu
dokumentieren. Dabei hat es sich eingebürgert, dass der Entdecker einer ausnutzbaren
Schwachstelle auch gleich einen Exploit für diese schreibt und somit dem SoftwareHersteller und Benutzern der Software beweisen kann, dass die Schwachstelle auch
tatsächlich ausnutzbar ist (engl. Proof of Concept). Umstritten ist weiterhin die Frage ob
gefundene Schwachstellen und Exploits veröffentlicht werden sollen oder nicht. Aktuell geht
die Tendenz in Richtung Veröffentlichung, da es den Anschein hat, dass die „Bad Guys“
ohnehin immer einen Schritt voraus sind und die gefundenen Fehler und Schwachstellen
zum Teil schon kennen und auch ausnutzen. Zusätzlich wird durch die Verheimlichung von
gefundenen Schwachstellen nur das falsche Gefühl von vorhandener Security gestärkt.
Unterschieden werden muss jedoch auch im Falle einer Veröffentlichung, in welcher Art der
Whitehat den Exploit veröffentlicht:
Responsible Disclosure
Sehr häufig werden dem Hersteller Fristen gesetzt, innerhalb welcher er auf die Meldung des
Problems reagieren muss. Google setzt sich zum Beispiel für diese Vorgehensweise stark
ein und hilft den betroffenen Unternehmen mitunter auch die Lücken zu schließen. Obwohl
das Projekt schon länger am Laufen ist, hat Google es erst im Juli 2014 mit dem Namen
6
„Project Zero“ offiziell vorgestellt. Ziel ist es, das Internet zu einem sichereren Ort zu machen
indem Software-Fehler von (speziell dafür angeheuerten) Experten gefunden und
veröffentlicht werden. [3]
Dabei verfolgt Google den Ansatz, dass der betroffene Hersteller innerhalb von 60 Tagen
einen Bugfix beziehungsweise ein Update zur Verfügung stellen muss. Sobald die Frist
abgelaufen ist oder der Hersteller das Problem gelöst hat, veröffentlichen die
Sicherheitsexperten von Google den Exploit. Sollte die Schwachstelle bereits aktiv
ausgenutzt werden, so verkürzt Google die Schonfrist bis zur Veröffentlichung auf 7 Tage.
Die Webseite auf der Google Details zu den gefundenen Schwachstellen veröffentlicht, ist
unter folgendem Link zu finden: http://googleprojectzero.blogspot.de/
[4], [5], [6]
Full Disclosure
Als Full Disclosure wird die Praktik bezeichnet, die Analyse von Softwareschwachstellen so
früh wie möglich und ohne Einschränkungen der Öffentlichkeit zur Verfügung zu stellen. Der
Zweck dahinter ist, dass die möglichen Opfer einer Schwachstelle so bald wie möglich
darüber Bescheid wissen, um Gegenmaßnahmen, wie zum Beispiel das Abschalten
beziehungsweise Umstellen eines Services oder das Verwenden eines anderen Services,
gegen bevorstehende Angriffe ergreifen zu können. Es gibt einige sehr bekannte Vertreter
von Full Disclosure, zum Beispiel Bruce Schneier, die darauf verweisen, dass „Security by
Obscurity“ noch nie der richtige Weg für bessere Security war.
Und obwohl Google ein Vertreter von Responsible Disclosure ist, kann man bei ihrer 7 Tage
Schonfrist bei Gefahr in Verzug, eigentlich von Full Disclosure sprechen. Weiters haben sich
auch schon diverse Experten aus dem Hause Google den ein oder anderen Full Disclosure
erlaubt (siehe [4]).
Die Veröffentlichungen von Vulnerabilities und Exploits werden meist in den Blogs der
Sicherheitsexperten als auch unter anderem auf folgenden Webseiten durchgeführt:




http://www.securityfocus.com/,
http://seclists.org/fulldisclosure,
https://cve.mitre.org/,
http://www.cvedetails.com/
Bug-Bounty
Bug-Bounty-Programme sind Aufforderungen von Softwareentwicklern (meist Webapplikationen) an die Community gefundene Bugs und Schwachstellen im System zu
melden. Im Gegenzug dafür erhält der Finder Anerkennung und eine kleine
Aufwandsentschädigung. Kann die Schwachstelle für einen Exploit benutzt werden, so fällt
der Finderlohn natürlich entsprechend höher aus. Die Applikationsentwickler können so die
Community dazu verwenden Probleme zu erkennen und dann in weiterer Folge diese
frühzeitig beheben, bevor jemand sie für böswillige Zwecke verwendet. Zu bekannten
Vertretern von Bug Bounty Programmen zählen Facebook, Yahoo! und Google. Inzwischen
gibt es auch schon Webseiten, die zwischen den Unternehmen und Researchern als
7
Vermittlungsstelle dienen (z.B. https://hackerone.com/, https://bugcrowd.com/). Auf diesen
Webseiten hat man auch einen guten Einblick wie viele Software-Bugs gefunden werden und
wie schnell die Unternehmen auf gemeldete Fehler und Schwachstellen reagieren.
Sicherheitsfirmen, Malware Hersteller & Bundestrojaner
Die wohl lukrativste Möglichkeit für Sicherheitsforscher Geld zu verdienen ist das
Geheimhalten der Schwachstelle vor dem Hersteller und der anschließende Verkauf von
Exploits an Geheimdienste und andere Organisationen. Hier sind vor allem Exploits für weit
verbreitete Programme wie Browser oder PDF-Reader sehr gefragt und können um bis zu
100.000 US-Dollar pro Schwachstelle verkauft werden.
So hat zum Beispiel die NSA alleine im Jahr 2013 mehr als 25 Millionen US-Dollar für den
Kauf von noch unbekannten Exploits (0-day-Exploits) ausgegeben, obwohl die großen ITUnternehmen wie Microsoft und Apple dem Geheimdienst bestimmte Schwachstellen
ohnehin schon vor der Veröffentlichung der Software Updates mit den Bugfixes bekannt
geben. [7]
Auch das Bundesamt für Sicherheit in der Informationstechnik (BSI) in Deutschland hatte in
den Jahren 2011 bis 2014 einen Vertrag mit der französischen Firma Vupen und hat von
dieser Berichte über Schwachstellen als auch Exploits bezogen [8]. Doch nicht nur das BSI
macht dubiose Geschäfte mit Malware-Herstellern. Auch der deutsche Bundesnachrichtendienst (BND) hat laut dem Nachrichtenmagazin „Der Spiegel“ vor, Zero Day Exploits zu
kaufen. Zwischen 2015 und 2020 stehen dem BND 4.5 Millionen Euro dafür zur Verfügung.
Ziel ist es „künftig auf Augenhöhe mit führenden westlichen Nachrichtendiensten
kooperieren“ zu können. [9]
Bekannte Vertreter solcher „Sicherheitsfirmen“ sind zum Beispiel Vupen (Frankreich),
Gamma Group (United Kingdom) und FinFisher (Deutschland). Laut Dokumenten von
WikiLeaks soll es weltweit an die 100 Unternehmen geben, die sich auf elektronische
Überwachung spezialisiert haben und ihre Programme und Know-How an die
Höchstbietenden verkaufen.
Im April 2013 wurde auf der Website von Citizen Lab ein Report mit dem Namen „For Their
Eyes Only: The Commercialization of Digital Spying“ veröffentlicht, in dem eine Analyse der
FinFisher Suite zu finden ist. Daraus geht hervor, dass in mehr als 36 Ländern FinFisher
Command & Control Server zu finden sind (darunter auch Österreich) und sich die Spyware
unter anderem als Mozilla Firefox tarnen kann. [10]
Im August und September 2014 haben sowohl Wikileaks als auch ein Hacker auf Twitter
geheime Dokumente und Software-Programme von FinFisher veröffentlicht. Dazu gehört
auch eine Kundenliste, die unter anderem folgende Kunden aufführt: „Slovakia, Mongolia,
Qatar State Security, South Africa, Bahrain, Pakistan, Estonia, Vietnam, Australia NSW
Police, Belgium, Nigeria, Netherlands KLPD, PCS Security in Singapore, Bangladesh, Secret
Services of Hungary, Italy and Bosnia & Herzegovina Intelligence“.Die Software als auch
Dokumente sind unter nachfolgenden Verweisen zum Download verfügbar. [11] [12] [13] [14]
8
Rein rechtlich gesehen liegt dieser gesamte Markt in einer Grauzone, die jedoch sehr stark
von den Regierungen und Geheimdiensten gefördert wird. Im Endeffekt geht das Ganze auf
die Kosten der Bürger und Unternehmen, denn dadurch, dass die Lücken geheim gehalten
werden, können diese natürlich auch von jedem anderen Hacker ausgenutzt werden. Als
weitere Gefahr für Unternehmen kommt hinzu, dass die Spionagesoftware natürlich auch an
gut zahlende Kundschaft aus der Industrie verkauft wird und daher zur Industriespionage
verwendet werden wird. Solche zielgerichteten Angriffe auf die IT-Infrastruktur und geheimen
Daten von Unternehmen und Behörden werden als Advanced Persistent Threat (APT)
bezeichnet. Ziel sind meist Unternehmen die einen Technologievorsprung gegenüber der
Konkurrenz aufweisen. Spätestens seit bekannt werden des Computerwurms Stuxnet ist
weltweit bekannt, dass solche Angriffe aber auch zur Sabotage von Industrieanlagen
verwendet werden und erheblichen Schaden anrichten können.
http://de.wikipedia.org/wiki/Stuxnet
Exploits Arten
Bis jetzt wurde erklärt was Exploits überhaupt sind, wer sie erstellt, wer sie verwendet, wo
man sie findet und wie sie eingesetzt werden. Nun wird es Zeit ein wenig näher auf die
verschiedenen Arten von Exploits einzugehen. In der Praxis wird zwischen folgenden
Exploits unterschieden:

Lokale Exploits – Ein lokaler Exploit versteckt sich hinter einer harmlos
aussehenden Datei (z.B. „Angebot.pdf“, „Urlaubsfoto1.jpg“, „Ausarbeitung.docx“) und
versucht Sicherheitslücken in dem Programm auszunutzen mit dem die Datei vom
Benutzer geöffnet wird (z.B Adobe PDF Reader, Windows Fotoanzeige, MS Word).
Der Exploit ist dabei der Code der die Schwachstelle ausnutzt und der Payload ist die
Aktion, die durch Ausnutzen der Sicherheitslücke ausgeführt wird, wie zum Beispiel
das Starten einer Reverse Shell. Der Angriff kann zum Beispiel über das Senden
einer Mail mit Anhang oder eine präparierte Webseite erfolgen.

Remote-Exploits – Ein Remote-Exploit nutzt Schwachstellen in Netzwerksoftware
aus. Das heißt, es werden bestimmte Datenströme mit einer bestimmten IP-Adresse
und Port-Nummer an einen Host oder Server gesendet, was zu einem Fehler in der
Netzwerksoftware des Computers führt, die an diesem Port Daten entgegennimmt
(zB. SLmail 5.5 Mailserver, Port 110 [POP3], Bufferüberlauf beim PASS Kommando).

DoS-Exploits – Denial of Service Exploits überlasten die Anwendung und/oder
bringen sie zum Absturz. Es erfolgt jedoch keine Ausführung von Schadcode.

SQL-Injection-Exploits – Beziehen sich auf Webanwendungen mit SQL-Datenbank.
Es werden Anfragen an die Webanwendung so gestellt, dass von der SQLDatenbank Daten zurückkommen, auf denen normalerweise weder Lese- noch
Schreibzugriff bestünde. Nimmt eine Webanwendung beispielsweise in einem
9
Formular Login-Daten entgegen und validiert diese nicht entsprechend, so kann ein
Angreifer sich mittels SQL-Injection dennoch erfolgreich einloggen.

Zero-Day-Exploits – Als 0-Day wird ein Exploit bezeichnet, der eingesetzt wird bevor
es für die ausgenützte Schwachstelle einen Patch als Gegenmaßnahme gibt. Es
bleibt den Entwicklern also keine Zeit um die Benutzer der Software vor Angriffen zu
schützen. Zero-Day-Exploits werden von Blackhats meist geheim gehalten, damit die
Schwachstellen möglichst lange unbemerkt ausgenutzt werden können. Wie weiter
oben schon erwähnt, kann diese Art von Exploit dem Finder auch sehr viel Geld
einbringen, da insbesondere auch staatliche Einrichtungen bereit sind eine Menge
Geld dafür zu investieren.
[1]
Exploit Beispiel anhand eines Buffer Overflow
Sehr oft basieren Exploits darauf, dass ein Computer nicht zwischen Programmcode und
Daten unterscheidet (Von-Neumann-Architektur). Bei einem Buffer Overflow wird zum
Beispiel vom Angreifer gezielt Code in einen nicht für Code vorgesehenen Speicherbereich
geschrieben, um eine Anwendung dadurch manipulieren zu können oder seinen eigenen
Code zur Ausführung zu bringen.
Das Nachfolgende soll anhand eines sehr einfachen Beispiels zeigen, wie ein Exploit anhand
eines Buffer-Überlaufs funktioniert.
Programmbeschreibung
Das Beispiel (geschrieben in C) soll folgende Funktions-Aufruf-Reihenfolge vorweisen:
main() -> receice() -> strcpy()
In der main()-Funktion wird die receive()-Funktion aufgerufen. Die receive()-Funktion allokiert
Speicher am Stack für zwei Strings (Character-Arrays) mit den Namen var1 und var2, wobei
sich ein Fehler eingeschlichen hat und das var1-Array größer sein kann als das var2-Array.
Anschließend wird var1 von einer beliebigen anderen Funktion mit Daten gefüllt (zum
Beispiel von einem Stream Socket oder einer Benutzereingabe). Nun benötigt das
Programm jedoch eine Kopie der Daten in var1 auf var2. Dazu wird die strcpy()-Funktion
aufgerufen und beide Arrays werden als Zeiger übergeben. Danach werden die Daten in
irgendeiner Form von der receive()-Funktion weiterverarbeitet.
Das Problem
Für jede der 3 aufgerufenen Funktionen (main, receive und strcpy) wird am Stack ein
eigenes Stackframe angelegt. Jedes dieser Stackframes enthält die Übergabeparameter, die
Rücksprungadresse und den vorherigen Framepointer.
Das erste Bild zeigt den Stack unter der Annahme, dass das var1-Array folgende Daten
enthält: „AAAAAAAAAAA…AAAABBBBDDDDEEEEEEEE…..EEEE“, wie er aussieht wenn
das Programm gerade mitten in der strcpy() – Funktion ist, und anfängt die Zeichen von var1
10
auf var2 zu kopieren (in der Abbildung wurden erst 8 Bytes kopiert). Da der Buffer, auf den
kopiert werden soll, die lokale Variable var2 der receive()-Funktion ist und der strcpy()Funktion nur die Anfangsadresse des char-Arrays übergeben wird, schreibt die strcpy()Funktion die Zeichen direkt in den dafür reservierten Bereich im Stackframe der receive()Funktion.
1
2
Abbildung 1: Darstellung eines Buffer Overflow
3
Der zweite Schritt zeigt den Stack und die
Registerwerte im Moment in dem die
strcpy()-Funktion gerade verlassen wird. Am
Stack sind bereits die abgelegten Werte des
Stackframes der receive()-Funktion und der
main()-Funktion überschrieben. Das heißt,
dass die strcpy()-Funktion zwar normal
returned, jedoch in der receive()-Funktion
schon mit falschen Stackwerte gerechnet
wird, falls nach dem strcpy()-Funktionsaufruf
noch Operationen mit lokalen Variablen der
receive()-Funktion durchgeführt werden.
Im dritten Bild, also beim Verlassen der
receive()-Funktion, kommt es dann zum Programmabbruch, da beim Verlassen mit ret, nicht
die ursprünglich abgelegte Rücksprungadresse in den EIP geladen wird, sondern die
Adresse 0xBBBB, auf die das Programm keinen Zugriff hat.
In diesem Beispiel wird auf die Rücksprungadresse nur der Wert 0xBBBB geschrieben. Ein
Exploit-Entwickler würde stattdessen eine gültige Sprungadresse an dieser Stelle platzieren.
11
So könnte er sich zum Beispiel aus einer Windows-DLL die Adresse eines ‚JMP ESP‘ (=
Springe zum Stackpointer) Befehls heraussuchen und auf diese Adresse verweisen. Anstatt
des Rücksprungs in die main()-Funktion würde dann nach der receive()-Funktion ein Sprung
in die Windows-DLL erfolgen und der Befehl ‚JMP ESP‘ ausgeführt werden. Dies führt dazu,
dass der nächste Befehl der ins Instruktionsregister (EIP) geladen wird, von der Stelle im
Speicher genommen wird, auf die der ESP zeigt. In diesem Beispiel wäre dies der Wert
0xDDDD (siehe Schritt in der Abbildung 3). Steht an dieser Stelle nun nicht 0xDDDD,
sondern ein gültiger CPU-Befehl, so wird dieser von der CPU interpretiert und ausgeführt.
Nach der Ausführung des Befehls wird dann der EIP um eine Adresse erhöht und würde den
nächste Befehl vom Stack ausführen (hier: 0xEEEE), usw. Das heißt, in einem richtigen
Exploit würde also anstatt 0xDDDD, gefolgt von mehreren 0xEEEE, der Payload (Shellcode)
am Stack stehen, der somit von der CPU ausgeführt wird.
Dies ist eine vereinfachte Darstellung, wie ein Exploit einen Stack Overflow ausnutzen kann,
um auf einem System dieselben Rechte zu bekommen wie die, die das angegriffene
Programm hat. Wird das Programm unter Windows zum Beispiel als Dienstprozess vom
Benutzer SYSTEM ausgeführt, so wird auch der Payload mit SYSTEM-Rechten ausgeführt,
welche sogar noch eine Ebene über den Administrator-Rechten angesiedelt sind.
Hat der ausgenutzte Prozess nur Benutzer-Rechte, so kann der Angreifer in weiterer Folge
mit Hilfe von Privilege Escalation versuchen Administrator-Rechte zu erlangen.
Damit dieser Beispiel-Exploit so funktionieren kann, wurde zum leichteren Verständnis
angenommen, dass beim angegriffenen Programm weder Data Execution Prevention
(DEP) noch Address Space Layout Randomization (ASLR) aktiviert wurden, die beide
Gegenmaßnahmen für Bufferüberläufe darstellen und diese deutlich erschweren.
Wie kann man einen Exploit finden?
Im Grunde gibt es drei Wege um an einen Exploit für ein bestimmtes Programm,
Betriebssystem oder Webseite zu kommen: Entweder man sucht in den diversen
Datenbanken im Internet nach einem bereits bekannten Exploit, oder man findet und schreibt
selbst einen neuen Exploit, oder man verwendet ein sogenanntes Exploit Kit.
Einen Exploit downloaden
Dieser Weg stellt definitiv die einfachere Möglichkeit dar. Wie schon erwähnt stehen auf
diversen Webseiten (z.B. http://www.securityfocus.com/, http://seclists.org/fulldisclosure,
http://www.exploit-db.com, http://secunia.com, http://1337day.com) sowohl Vulnerabilities als
auch Exploits (falls es dazu schon welche gibt) zur Verfügung. Die Suche kann entweder
über den Hersteller, das Produkt oder die CVE Nummer (Common Vulnerabilities and
Exposures) durchgeführt werden. CVE ist dabei ein Standard für eine einheitliche
Namenskonvention für Sicherheitslücken und Schwachstellen in Computersystemen.
Dadurch wird die Mehrfachbenennung von verschiedenen Unternehmen für gleiche
12
Schwachstellen ausgeschlossen und es ist ein reibungsloser Informationsaustausch
zwischen verschiedenen Datenbanken möglich. Die Verwaltung der CVE übernimmt die
MITRE Cooperation in Zusammenarbeit mit Behörden, Sicherheitsunternehmen, Experten
und Bildungseinrichtungen.
Hat man erst einmal einen Exploit für das entsprechende Programm gefunden, so sind meist
noch kleine Anpassungen notwendig, damit der Exploit auch von einem selbst verwendet
werden kann. So muss man den Shellcode (also den Payload), sowie die IP-Adressen (des
Ziels und seine eigene) anpassen und eventuell noch ein paar weitere Kleinigkeiten, damit
man den Payload am Zielsystem zum Laufen bekommt. Die Anpassungsnotwendigkeit
kommt natürlich daher, dass die zur Verfügung gestellten Exploits meist nur zum Proof of
Concept dienen und nicht die Einladung zur Begehung von Straftaten sein sollen.
Ein Hauptproblem ist, dass wenn ein Exploit einen Buffer Overflow ausnutzt (meistens der
Fall), der Exploit-Entwickler mit Sprungadressen arbeiten muss um seinen im Datenspeicher
(Stack oder Heap) abgelegten Payload zur Ausführung bringen zu können. Ändert sich nun
aber das Zielsystem ein wenig (z.B. andere Windows-Version, andere Sprache, …) so
ändern sich auch sehr wahrscheinlich die Speicheradressen (auf ASLR soll an dieser Stelle
gar nicht eingegangen werden) und schon funktioniert der Code am Zielsystem nicht mehr.
Als Folge muss für jede Plattform auf der das anfällige Programm läuft, aufs Neue der
Exploit angepasst und getestet werden. An dieser Stelle sei schon einmal das Metasploit
Framework erwähnt. Dieses Framework erleichtert dem Exploit-Entwickler und -Verwender
das Handwerk gehörig. Es ist in erster Linie eine Sammlung von Exploits, die aber zwischen
dem eigentlichen Code für den Angriff (dem Exploit) der speziell für eine Sicherheitslücke
geschrieben wurde und dem Shellcode (also dem Payload) der dann nach dem Ausnutzen
der Sicherheitslücke zur Ausführung kommt. Aktuell enthält das Framework in der Version
4.11 an die 1400 Exploits und 350 Payloads die frei zur Verfügung stehen. All diese Exploits
und Payloads aus der Metasploit-Datenbank kann man mit wenigen Befehlen konfigurieren
und direkt an ein angegebenes Ziel senden. Und will man einen ganz neuen Exploit aus
einer der zuvor erwähnten Datenbanken verwenden, kann man dies gleich mit Hilfe des
Metasploit Framesworks machen und braucht sich nicht einmal um den Payload kümmern.
Zusätzlich kann der neu erstellte Exploit auch den Rest der Community zur Verfügung
gestellt werden.
Einen neuen Exploit erstellen
Um einen neuen und gänzlich unbekannten Exploit zu finden und zu erstellen wird
wesentlich mehr Know-How und Aufwand benötigt, als bei der einfachen Verwendung eines
bereits existierenden Exploits.
Dennoch lohnt sich der Aufwand für einen Hacker sehr oft, da er im Endeffekt einen ZeroDay-Exploit erstellt, sollte er eine zuvor unbekannte Schwachstelle entdecken. Und wie
schon erwähnt wurde, kann ein Zero-Day-Exploit einiges wert sein, vor allem wenn er in
einer sehr häufig installierten Desktop-Anwendung gefunden wird.
13
Wie ein Exploit im Detail erstellt wird und auf dessen detaillierte Funktionsweise können die
Autoren in dieser Arbeit leider nicht eingehen, da Exploits einerseits nicht das primäre
Thema der Arbeit darstellten und andererseits der Umfang einer genauen Beschreibung über
die Erstellung von Exploits ein ganzes Buch füllen würde. Deshalb sei an dieser Stelle der
Vollständigkeit halber an frei verfügbare Literatur zu diesem Thema verwiesen: [15], [16],
[17].
Obwohl die Verwendung von bereits vorhandenen Exploits sicher die einfachere Methode ist
um einen Exploit einzusetzen, hat sie einen entscheidenden Nachteil gegenüber einem
selbst erstellten Exploit: der Exploit ist bereits bekannt und es gibt höchstwahrscheinlich
schon Updates des Herstellers dagegen. Das heißt, besonders bei Servern wird man geringe
Chancen haben, auf einen nicht gepatchten zu stoßen. Bei normalen Client-PCs sieht es da
schon ein wenig besser aus, da nicht alle Benutzer ihre Applikationen immer up-to-date
halten. Auch veraltete Betriebssysteme wie Windows XP, die wesentlich weniger
Schutzmechanismen als neue Systeme aufweisen, sind noch weit verbreitet und spielen
dem Angreifer natürlich in die Hände.
Zusammenfassung
Exploits stellen eine sehr gute Möglichkeit dar um unbemerkt von Benutzer und
Antivirussoftware in ein System einzudringen und dieses zu übernehmen. Dazu werden
Fehler und Schwachstellen in Programmen ausgenutzt die auf dem angegriffenen Host
installiert sind. Der Vorteil von Exploits liegt darin, dass das Opfer nicht irgendeine
ausführbare Datei (zB. exe, jar oder Batch-Datei) auf seinen System öffnen muss, damit die
Malware ihn infizieren kann, sondern es kann lediglich ein unscheinbar wirkender EmailAnhang, wie zum Beispiel eine modifizierte Excel-, Word-, Pdf- oder Bilddatei geöffnet
werden um das System zu infizieren. Noch einfacher geht es, wenn der Webbrowser oder
eines der darin verwendeten Plugins (zB. Flash-Player, Java) eine Schwachstelle haben.
Dann genügt ein sogenannter Drive-By-Download um das System wiederum unbemerkt zu
infizieren, während der Benutzer auf einer unscheinbaren Webseite surft. Um direkt auf
einen Web-Server zu gelangen sind Exploits ohnehin fast die einzige Möglichkeit, da es am
Server meist keine unvorsichtigen Benutzer gibt, die einfach so mit Malware befallene
ausführbare Dateien öffnen. Hier werden meist direkt Netzwerkprogramme angegriffen oder
es wird sich Zugang über Code-Injection in den Web-Applikationen verschafft.
Aus diesen Gründen machen heutzutage laut einer Studie vom Unternehmen Malwarebytes,
Exploit-basierte Angriffe mehr als 90% der Gefahren aus, die auf die Benutzer von
Computersystemen zukommen. [18]
Gegenmaßnahmen gegen solche Angriffe sind zum einen regelmäßige Softwareupdates und
zum anderen gibt es Programme wie Microsoft EMET und Malwarebytes ANTI-EXPLOIT, die
einen zusätzlichen Schutz mit verschiedenen Techniken wie Data Execution Prevetion
14
(DEP), SEHOP (Structured Exception Handler Overwrite Protection) und ASLR (Address
Space Layout Randomization) versprechen. Diese werden im Kapitel Gegenmaßnahmen
genauer behandelt.
Zur Vollständigkeit sei hier noch erwähnt, dass nicht alle Exploits dazu genutzt werden um
unbefugt in ein System einzudringen. Auch das Jailbreaking (zum Beispiel eines Apple
Smartphones) wird mit Hilfe von Exploits durchgeführt. Das Ziel dabei ist es jedoch, einen
Nutzen für den Smartphone-Besitzer zu generieren, da zusätzliche (gesperrte) Funktionen
dadurch freigeschaltet werden können.
2.2 Code Obfuscation
Code Obfuscation (engl. „Verschleierung“) bezieht sich auf die Transformation von
Programmcode. Ziel ist es, die Ermittlung der Semantik und der Funktionalität eines
Programms zu erschweren, jedoch dessen Funktionalität zu erhalten. Dabei kann die
Verschleierung auf die Verwirrung von Maschine als auch Mensch abzielen. Prinzipiell kann
Obfuscation auf zwei Bestandteile eines Programms angewandt werden:


Kontrollfluss
Auf den chronologischen und kausalen Ablauf des Programms (Sprungpunkte,
Verzweigungen, Ausführungsreihenfolge der Anweisungen).
Datenstrukturen
Die Umkehr von Obfuscation wird als Code De-Obfuscation bezeichnet. Je höher der
Aufwand für die De-Obfuscation ist, desto besser ist die Güte der Obfuscation.
Dieses Kapitel gibt einen Überblick über die verschiedensten Obfuscation-Techniken und
erklärt kurz wie diese funktionieren.
2.2.1 Obfuscator
Ein Obfuscator (Deutsch: Quelltextverschleierer) dient dazu, wie der Name schon sagt, den
Quelltext oder Maschinencode von Programmen zu verschleiern. Meist verfolgt die
Verschleierung das Ziel ein Programm vor Reverse Engineering oder Manipulation zu
schützen. Dies wird dadurch erreicht, dass der gut lesbare, kommentierte und
nachvollziehbare Source Code von Obfuscatoren so verändert wird, dass er für Menschen
nur mehr sehr schwer und mit großem Aufwand lesbar ist. Dabei ist es jedoch wichtig, dass
nach der Verschleierung der Code einerseits noch dieselbe Funktionalität wie der
Originaltext hat und andererseits auch noch gleich schnell beziehungsweise nur
unwesentlich langsamer als der ursprüngliche Code ausgeführt werden kann. Je nach
verwendeter Technik erzeugt der Verschleierungsvorgang längeren oder kürzeren Source
Code und führt daher zu mehr oder weniger Speicherverbrauch. Zum Beispiel können
15
Variablen entweder durch viel längere, zufällige Zeichenfolgen ersetzt werden, oder auch
durch ganz kurze Zeichenfolgen.
Nachfolgend sind einige Beispiele für Methoden von Code Obfuscation aufgelistet:
 Verwenden von äquivalenten Formeln und konstante Transformationen
Anstatt zu einem Register die Zahl 10 zu addieren, wird die Operation in zwei Schritte
aufgeteilt und zuerst die Zahl 15 addiert um danach wiederum 5 zu subtrahieren.
 Umordnen von Anweisungen
Verändern der Reihenfolge von Anweisungen ohne das Programm selbst zu
beeinflussen. Zum Beispiel können die Übergabeparameter bei Funktionen oft in
willkürlicher Reihenfolge angegeben werden.
 Variablensubstitution (Symbol Renaming)
Umbenennen von Bezeichnern (Variablen, Funktionen, Methoden, Klassen, …). So
kann zum Beispiel nachfolgende Variablendeklaration wie folgt verändert werden:
var Postleitzahl;
 var lasjfkasjfuewfkjas;
(Mehr Speicherverbrauch)
 var a;
(Weniger Speicherverbrauch)
Wie weiter unten noch gezeigt wird, ist eine gute Variante davon, so viele Bezeichner wie
möglich mit demselben Namen zu versehen.
 Entfernen von Einrückungen und Zeilenumbrüchen
function NewObject(prefix) {
if(prefix === “test”){
alert(„This is a test!“);
}else{
alert(“This is not a test!”);
}
}
↓
function NewObject(prefix){if(prefix === “test”){alert(„This is a
test!“);}else{alert(“This is not a test!”);}}
 Bedingte Anweisungen und Sprünge
Zum Beispiel Vergleiche und Bedingungen, die stets ‚true‘ beziehungsweise ‚false‘
ergeben, Links oder Pointer.
 Spaghetti Code (Control Flow Obfuscation)
Die Control Flow Obfuscation hat das Ziel, das Programm so umzustrukturieren, dass es
unmöglich wird daraus gut geformten Source Code zu dekompilieren. Das führt
wiederum dazu, dass für den Menschen das Programm viel schwieriger zu verstehen ist.
Die meisten Obfuscatoren bewerkstelligen dies, indem zum Beispiel anstatt
Funktionsaufrufen, Returns, Schleifen und Abfragen immer gotos verwendet werden.
16
 Aufruf von Subroutinen
Im Prinzip kann jede einzelne Anweisung auch durch eine Subroutine (Funktion) ersetzt
werden.
 Einfügen von Leercode
Zwischen den eigentlichen Anweisungen wird überflüssiger Code eingefügt. Dieser trägt
nichts zur eigentlichen Funktionalität des Programms bei und führt lediglich triviale und
irrelevante Berechnungen durch.
 Verschlüsselung (Ressource/String/Assembly Encryption)
Verschlüsselung wird zur Tarnung von einzelnen Bytes oder Strings eingesetzt, welche
zum Beispiel hardcodiert im Code abgelegt sind. (zB: Passwörter).
 Mischen von Funktionen
Alternierende Schreibweise der Anweisungen zweier Funktionen um die Grenzen
zwischen den Funktionen verschwimmen zu lassen.
 Spalten von Variablen
Umstrukturierung von Arrays
 ein eindimensionales Array  Aufspaltung in mehrere eindimensionale Arrays
 ein eindimensionales Array  Ausweitung in ein mehrdimensionales Array
 ein mehrdimensionales Array  Schrumpfen in ein eindimensionales Array
 zwei oder mehrere eindimensionale Arrays  Zusammenführung zu einem
eindimensionalen Array
 Anti-Debugs
Spezielle Routinen welche eine Ausführung durch einen Debugger erkennen und das
Programm daraufhin frühzeitig beenden. Dazu wird beispielsweise der Speicher nach
Suchstrings diverser Debugger gescannt.
 Anti Decompiler/Disassembler
Verändern des kompilierten Codes, sodass dieser von bestimmten Decompilern oder
Disassemblern nicht verarbeitet werden kann.
[19], [20], [21]
2.2.2 Obfuscation in verschiedenen Programmiersprachen
Interpretiert vs. kompiliert
Es gibt verschiedene Möglichkeiten um aus Quelltext ein auf der CPU ausführbares
Programm zu erstellen. Bevor Programmiersprachen wie Java und C# bekannt wurden, gab
es im Endeffekt 2 Möglichkeiten: Den Quellcode zu kompilieren oder zu interpretieren. So
werden Sprachen wie C, C++, Fortran und Pascal fast immer direkt in Maschinencode
kompiliert, während der Quellcode von Sprachen wie Basic, VBScript, JavaScript, Perl, PHP,
17
Ruby und Python normalerweise von einem sogenannten Interpreter interpretiert werden.
Ganz grundsätzlich ist eine Programmiersprache nicht an eine Implementierung und damit
Art der Ausführung gebunden. Für mehrere Sprachen existieren daher verschiedenartige
Implementierungen. Zum Beispiel ist die Sprache C zwar stark auf eine Kompilierung
ausgelegt, jedoch existieren auch C-Interpreter wie CINT und Ch. [22]
Nachfolgend werden kurz die Methoden wie aus Quelltext ein Prozess entsteht und deren
Unterschiede zueinander vorgestellt:
Compiler
(1) Schreiben/Bearbeiten des Quelltextes
(2) Kompilieren der Quelltext-Dateien in Maschinencode-Dateien
(3) Verknüpfen der Maschinencode-Dateien mittels dem Linker in eine ausführbare Datei
(zB: .exe, elf-File)
(4) Ausführen oder debuggen der ausführbaren Datei  Prozess
Maschinencode-Dateien enthalten Instruktionen die direkt von der CPU verstanden werden
können. Daher müssen sie für jeden Prozessor, der einen anderen Instruktionssatz besitzt,
extra mit einem für diesen Prozessor passenden Compiler kompiliert werden. Der Grund
dafür, dass es meist pro Quelltextdatei eine Maschinencode-Datei gibt und dadurch viele
Maschinencode-Dateien erst zu einer gemeinsamen ausführbaren Datei gelinkt werden
müssen, ist die Effizienz: Dadurch müssen bei jeder Änderung nur die geänderten
Quellcodedateien neu kompiliert werden und die nicht geänderten Module können einfach
erneut genutzt werden. Dieses Vorgehen wird auch als „Make“ bezeichnet, während das
Kompilieren des gesamten Source Codes als „Build“ oder „Rebuild“ bezeichnet wird.
Der Linkvorgang selbst ist dabei ein technisch sehr komplexer Prozess bei dem die
Funktionsaufrufe zwischen den verschiedenen Maschinencode-Dateien aufgelöst werden,
die Speicherpositionen für die Variablen zugewiesen werden und der gesamte Code
schließlich in den Speicher als fertiges Programm abgelegt wird. [23]
Interpreter
(1) Schreiben/Bearbeiten des Quelltextes
(2) Ausführen oder Debuggen der Quelltext-Datei
Diese Vorgehensweise führt natürlich sehr viel schneller zu einer Programmausführung
nachdem der Programmierer Änderungen am Souce Code vorgenommen hat, da vor der
Ausführung der Code nicht kompiliert und gelinkt werden muss. Natürlich führt das wiederum
zum Nachteil, dass die Programmausführung selbst 5 bis 10 mal langsamer erfolgt, da bei
jeder Programmausführung zur Laufzeit jede Quelltextzeile zuerst vom Interpreter gelesen,
interpretiert, analysiert und ausgeführt werden muss. [23]
18
Just in Time Compiler
Ein Kompromiss zwischen reiner Kompilierung und Interpretierung sind sogenannte Just in
Time Compiler (JIT). Dabei wird das Programm, wie beim Interpreter, erst zur Laufzeit
übersetzt, dafür aber gleich wie beim Compiler direkt in Maschinensprache. Der bereits
kompilierte Maschinencode wird dabei während der Programmausführung zwischengespeichert, wodurch mehrfach aufgerufene Programmteile nur einmal übersetzt werden
müssen. Weiters ist eine bessere Optimierung des Programmes möglich, als bei einem
reinen Interpreter. Ein Nachteil der Kompilierung ist jedoch, dass JIT-Compiler gleich wie
normale Compiler für jede Rechnerarchitektur eigens implementiert werden müssen.
Bytecode Interpreter
Bei einem Bytecode Interpreter wird der Quelltext schon vorab in einen einfacheren
Zwischencode (Bytecode, Intermediate Language) übersetzt, um dann schneller von einem
Interpreter (= Process Virtual Machine) ausgeführt werden zu können. Die Intermediate
Language ist dabei unabhängig von der zugrunde liegenden Hardware auf der das
Programm ausgeführt wird. Dadurch können Programme sehr leicht zwischen verschiedenen
Prozessorarchitekturen portiert werden, solange es einen Interpreter für diese Architektur
gibt.
Meist werden Bytecode Interpreter zusammen
mit Just in Time Kompilierung eingesetzt, um
die Ausführungsgeschwindigkeit zu erhöhen.
Bekannte Beispiele für Process Virtual
Machines sind die Java Virtual Machine (JVM)
und die Common Language Runtime (CLR),
auf welcher das .NET Framework aufbaut. Das
heißt also, dass Programmiersprachen wie
Java und C# beide einen Bytecode Interpreter
als auch einen Just in Time Compiler für die
Ausführung von Programmen verwenden und
daher der Quellcode in einen zweistufigen
Prozess übersetzt wird. Dadurch dass sowohl
Java als auch C# verschiedene Techniken zur
Steigerung der Ausführungsgeschwindigkeit
anwenden, werden die Programme beider
Abbildung 2: Common Language Infrastructure (CLI) [27]
Programmiersprachen beinahe mit derselben
Geschwindigkeit ausgeführt wie Programme in rein kompilierten Sprachen [22].
19
Compiled Languages (C, C++, Objective-C, Fortran, …)
Native kompilierte Sprachen wie C und C++, bei denen der Compiler aus dem Source Code
direkt Maschinensprache erzeugt, sind per Default nur sehr schwierig bis gar nicht vernünftig
zu dekompilieren (von Maschinen-,/Objectcode in Hochsprachen Source Code). Im
Gegensatz dazu ist das Disassemblieren, bei dem binäre Maschinenbefehle, in für
Menschen lesbaren Assembler Code umgewandelt wird, meist keine große Herausforderung
und wird sogar von den meisten Debuggern, wie zum Beispiel GCC, zur Verfügung gestellt.
Aus diesem Grund verwenden Code-Analysten meist Assemblercode um ein Reverse
Engineering zu betreiben. Dadurch, dass Assembler-Programme um einiges schwieriger zu
lesen sind und sowohl Bezeichner als auch Kommentare im generierten Assemblercode
fehlen, stellt sich das Reverse Engineering bei solchen Programmen als sehr zeitaufwändig
heraus.
Aufgrund des aufwändigen Reverse Engineerings besteht häufig kein Bedarf gesonderte
Maßnahmen wie Obfuscation zu treffen, um das Reverse Engineering von Programmen zu
verhindern. Nur bei Kopierschutz- oder Lizenzmechanismen findet man oft Obfuscation
Maßnahmen (siehe zum Beispiel StarForce) wie Verschlüsselung, damit es schwieriger wird
diese zu umgehen.
Prinzipiell ist bei kompilierten Sprachen zu unterscheiden, zu welchem Zweck und zu
welchem Zeitpunkt die Obfuscation – Techniken verwendet werden:

Source Code Obfuscation – Verschleiern des eigentlichen Hochsprachen
Programm Codes. Diese Technik kann bei kompilierten Sprachen sehr hilfreich sein,
wenn der Software Quellcode an andere (Unternehmen) weitergegeben werden
muss, diese jedoch nicht nachvollziehen können sollen, was der Code genau macht,
beziehungsweise die Gefahr besteht, dass geistiges Eigentum gestohlen werden
könnte. Dies kann zum Beispiel bei Cross-Plattform-Software der Fall sein, da es in
solchen Fällen sinnvoll ist, dass der Kunde den Build auf seinen Plattformen selbst
durchführt. Wie weiter unten noch ersichtlich ist, ist die Source Code Obfuscation für
Sprachen die in Bytecode übersetzt werden, die einzige Möglichkeit ihr Verhalten zu
verschleiern.
Ein Obfuscated C-Source Code kann zum Beispiel wie in Abbildung 3 und Abbildung 4
aussehen. Der abgebildete C-Code wurde mit dem Tool Stunnix C++ Obfuscator [24]
verschleiert, welches von Unternehmen wie DELL, Siemens, Bosch, Broadcom, NEC,
usw. verwendet wird. Weiter Beispiele für C/C++ Obfuscatoren wären der StarForce
C++ Obfuscator und der Mangle-It C++ Obfuscator. Alle drei angeführten Tools sind
kommerzielle Produkte. Da die Obfuscation von C/C++ Quellcode nur das Layout des
Source Codes verändert, jedoch kaum Auswirkungen auf den Output vom Compiler
hat (Maschinencode von Abbildung 3 und Abbildung 4 ist derselbe), machen Source
Code Obfuscatoren nur im kommerziellen Bereich Sinn. Daher scheint es auch keine
Open Source Projekte in diese Richtung zu geben.
20
Abbildung 3: Einfaches C++ Beispiel mit einer globalen Variable und zwei Funktionen,
die auf diese globale Variable zugreifen [24]
Abbildung 4: Verschleierter C++ Code.
Alle Symbole wurden durch MD5 Hashes ersetzt; Kommentare, Zeilenumbrüche und Einrückungen
wurden entfernt; Literale wurden kodiert [24]
Es gibt jährlich den sogenannten „International Obfuscated C Contest“, bei dem die
besten von Hand kodierten, verschleierten C Programme gesucht werden. Die
überaus interessanten Programme können in [25] bewundert werden.

Binary Obfuscation after Compilation – Verschleiern der Programmfunktion
nachdem das Programm kompiliert wurde. Diese Technik hat den Vorteil, dass man
direkt mit dem Binary arbeiten kann und sich alle Änderungen direkt auswirken. Der
Compiler kann also nicht zusätzlich (redundant) eingefügte oder veränderte Codeteile
wieder entfernen. Im Gegensatz zur Source Code Obfuscation wird bei dieser
Technik versucht den Maschinencode zu verschleiern. Der Nachteil dabei ist, dass
dazu meist Tools von anderen Herstellern verwendet werden müssen, da in-house
das Know-How dazu fehlt. Dabei ist dann jedoch wiederum unbekannt, wie diese
zugekauften Obfuscatoren genau funktionieren und ob diese nicht durch Fehler zu
ungewünschten Nebenwirkungen führen. Bei frei verfügbaren Obfuscatoren besteht
zusätzlich die Gefahr, dass nicht nur Verschleierung des eigenen Codes betrieben
wird, sondern zusätzlich auch noch gleich ein Trojaner in die eigene Software
mitreingepackt wird.
21
Beispiele für einen „Obfuscator after Compilation“ ist das Open Source Programm
Obfuscator-LLVM (https://github.com/obfuscator-llvm/obfuscator/wiki), welcher auf
der LLVM Compiler Suite aufsetzt. Andere Beispiele sind sogenannte Runtime
Packer, auf die in diesem Kapitel noch näher eingegangen wird.

Binary Obfuscation from the Top Down – Dieser Ansatz verfolgt schon bei der
Programmierung das Ziel den Hochsprachencode so zu schreiben, dass der
Compiler beinahe unlesbaren Code erzeugt. Der Vorteil dabei ist, dass es für den
Programmierer leichter nachvollziehbar wird, wie der Code verschleiert wird und dass
immer andere Methoden verwendet werden können. Das Problem dabei ist, dass es
passieren kann, dass der Compiler den extra eingefügten Verschleierungscode
einfach wegoptimiert. Denn standardmäßig wird vom Compiler zum Beispiel Code
optimiert, der
o nicht durchlaufen wird (z.B. Verzweigungen),
MOV
XOR
CMP
JNE
EAX,949
EAX,310
EAX,0
z0r
z0r:
XOR EAX,310
PUSH EAX
o
MOV EAX,949
XOR EAX,310
XOR EAX,310
PUSH EAX
XOR EAX,949
LEAVE
RETN
MOV EAX,949
PUSH EAX
der sich gegenseitig aufhebt
XOR EAX,310
XOR EAX,310
o
dessen Berechnungen nicht mehr weiter gebraucht werden
MOV EAX,949
MOV EBX,310
MOV ECX,213
XOR EAX,EBX
ADD EBX,EAX
SUB EAX,EAX
PUSH EBX
PUSH EAX
MOV EAX,949
MOV EBX,310
XOR EAX,EBX
ADD EBX,EAX
SUB EAX,EAX
PUSH EBX
PUSH EAX
22
o
welcher aus mehrere Berechnungen hintereinander mit derselben Variable
besteht
int x;
x = 7;
x <<= 2;
x *= 2;
x -= 12;
x +=(x*x)<< 2;
printf("%d\n",x);
PUSH 1E6C
PUSH “%d\n”
CALL $PRINTFSUB
Umgangen kann die Wegoptimierung des Compilers zum Beispiel im C, C++ und C#
mithilfe des Schlüsselwortes volatile. Wird dieses Schlüsselwort vor Variablen
verwendet, so darf der Compiler Berechnungen mit dieser Variable nicht optimieren.
Hier also noch einmal das Beispiel von oberhalb:
volatile int x;
x = 7;
x <<= 2;
x *= 2;
x -= 12;
x +=(x*x)<< 2;
printf("%d\n",x);
MOV [ESP],7
SHL [ESP],2
MOV EAX,[ESP]
ADD EAX,EAX
MOV [ESP],EAX
ADD [ESP],-0C
MOV ECX,[ESP]
MOV EDX,[ESP]
MOV EAX,[ESP]
IMUL ECX,EDX
...
Die Berechnungen der volatile Variable x werden also nicht optimiert, was zu
redundanten Code im Assembly führt. Ein ähnliches Ergebnis liefert der Compiler bei
der Verwendung von Zufallszahlen. Da er diese zur Compile-Time nicht vorhersagen
kann, ist es dem Compiler auch nicht möglich Code-Abschnitte, die mit Zufallszahlen
zu tun haben, zu vereinfachen. Dazu folgendes Beispiel:
int a=7, b=2, c=8, d=9;
if(a+b+c*d > 0)
{
puts(“yes”);
exit(0);
}
puts(“no”);
PUSH
CALL
PUSH
CALL
“yes”
$PUTS
0
$EXIT
23
int a,b,c,d;
srand(time(0));
a=rand()+1;b=rand()+1;
c=rand()+1;d=rand()+1;
if(a+b+c*d > 0)
{
puts(“yes”);
exit(0);
}
puts(“no”);
...
TEST EAX,EAX
JLE SHORT :NO
PUSH “yes”
CALL $PUTS
PUSH 0
CALL $EXIT
NO: PUSH “no”
CALL $PUTS
Auch durch diese Technik kann das Assembly mit vielen zusätzlichen Berechnungen
erweitert und unnötig kompliziert gemacht werden.
Eine weitere gute Methode es dem Reverse Engineer schwer zu machen ist das
absichtliche Triggern einer Exception und anschließend mit der Programmausführung
in der abgefangenen Exception weiterzumachen:
try{
volatile int trigger = 20;
doThisAndThat();
/* trigger divide-by-zero exception */
trigger=trigger/(trigger-trigger);
neverExecutes();
} catch(...) {
proceedWithExecution();
}
Eine weitere Technik namens „Control Flow Flattening“ bezieht sich auf die grafische
Repräsentation eines Programmablaufs in einem Programmgraphen (wie es zum
Beispiel der Disassembler IDAPro bietet). Normalerweise ist in so einem Graphen ein
Top-Down-Ablauf, mit der Main-Funktion
int x=2;
als Einstiegspunkt, zu erkennen. Das
sw:
„Flattening“ zielt jedoch darauf ab, die
switch(x) {
einzelnen Funktionen bzw. Codecase 0: doThat();
Abschnitte „auszuwalzen“ und die
x = 1;
gesamte Funktionalität von zentraler
goto sw;
Stelle aus zu steuern anstelle eines Topcase 1: doMore();
Down-Ablaufs.
Dazu
kann
unter
break;
anderem die Switch-Case-Anweisung
case 2: doThis();
verwendet
werden
um
die
x = 0;
goto sw;
}
24
verschiedenen Funktionen aufzurufen (siehe rechts).
Das Ergebnis des Flattenings zeigen die nächsten beiden Abbildungen:
Abbildung 5: Control Flow Flattening Schema (übernommen aus [26])
Abbildung 6: Control Flow Flattening in Aktion (übernommen aus [26])
Die
hier
vorgestellten
Methoden:
volatile
Variablen,
Zufallszahlen,
Programmausführung in Exceptions und Flattening sind alles Methoden um den
25
Programmablauf zu verändern, mit dem Ziel diesen vor dem Reverse Engineer zu
verschleiern (Control Flow Obfuscation). Doch nicht nur der Ablauf selbst, sondern
auch die Programmdaten können vor dem Kompilieren der Anwendung verschleiert
werden (Data Obfuscation). Um die Daten (wie Strings
volatile int x;
und Literale) dann zur Laufzeit verwenden zu können,
x = 7;
müssen diese auch zur Laufzeit wieder „entschleiert“
x <<= 2;
werden. Eine der beliebtesten Data Obfuscation
x *= 2;
Techniken ist die Verschlüsselung, aber es gibt
x -= 12;
natürlich auch noch andere Möglichkeiten. Eine davon
x +=(x*x)<< 2;
ist das schon gezeigte volatile Beispiel (siehe rechts),
printf("%d\n",x);
bei dem der Wert der Variable x verschleiert wird.
Daten können in weiterer Folge auch aggregiert werden. Hier ein Beispiel:
char aggr[7] = “fboaor”;
char foo[3], bar[3];
int i;
for (i=0; i<3; ++i) {
foo[i] = aggr[i*2];
bar[i] = aggr[i*2+1];
}
/* foo = “foo” / bar = “bar” */
Externe Bibliotheksaufrufe für API-Funktionen wie printf() oder execv() werden in
einem Assembly in einer speziell dafür vorgesehenen Tabelle gespeichert (Windows:
Import Address Table (IAT), Linux: Procedure Linkage Table (PLT)). Diese externen
Bibliotheksaufrufe verraten einiges über den Funktionsumfang eines Programmes
und werden daher bei einer sogenannten „Dead Code Analysis“, also einer Analyse
des Programms ohne das dieses ausgeführt wird, meist automatisch analysiert und
ausgewertet (Beispiel: VirusTotal.com).
Um eine solche Analyse der Bibliotheksaufrufe zu verhindern, kann der
Programmierer dafür sorgen, dass diese nicht in der PLT/IAT eingetragen werden,
sondern erst zur Laufzeit dynamisch geladen werden. Dafür gibt es die System Calls
LoadLibrary() & GetProcAddress() unter Windows und dlopen() & dlsym() unter Linux.
Nachfolgend der Beispielcode für Windows:
26
#include
#include
#include
#include
<stdio.h>
<stdlib.h>
<string.h>
<windows.h>
typedef int(*PUTS_T)(const char *);
int main (int argc, char *argv[]){
/* MSVCR90 will already be loaded, so this is simply for example */
PUTS_T putsFunc = (PUTS_T)GetProcAddress(LoadLibrary(L"MSVCR90.DLL"),"puts");
putsFunc("mysterious!");
return 0;
}
Mit Hilfe von LoadLibrary() wird die MSVCR90.DLL in den Adressbereich des
aktuellen Prozesses geladen und der Handle auf das Modul als Rückgabewert
geliefert. Das Handle auf die DLL und der Funktionsname werden im nächsten Schritt
der GetProcAddress() Funktion übergeben, die dann die Adresse der angegebenen
Funktion (oder Variablen) zurückliefert. Diese Adresse wird im Funktionszeiger mit
dem Namen putsFunc gespeichert und kann nun in weiterer Folge für Aufrufe der
Funktion puts verwendet werden.
Aus den gezeigten Beispielen geht hervor, dass Data Obfuscation zwar eine
wirksame Maßnahme gegen eine „Dead Code Analysis“ darstellt, jedoch die LiveCode-Analyse nur begrenzt erschwert. Das liegt daran, dass zur Laufzeit ja zu einem
gewissen Zeitpunkt mit den richtigen Werten gerechnet werden muss bzw. die Strings
im Klartext vorliegen müssen.
Die meisten hier gezeigten Methoden zur „Binary Obfuscation before Compilation“
wurden von Taylor Sean auf der Defcon 17 im Jahre 2009 gezeigt [26].
Bytecode Compiled Languages (.NET, Java)
Java und .NET Programme sind verglichen mit kompilierten Sprachen sehr einfach zu
disassemblen beziehungsweise Reverse Engineering von den ausführbaren (exe, dll, jar,
class) Dateien ist sehr einfach. Denn im Gegensatz zu nativen Maschinencode, wie er zum
Beispiel beim C-Compiler rausfällt, enthält der Intermediate Bytecode alle ursprünglich
verwendeten Bezeichner (zB. Variablen- & Funktionsnamen), sodass ein Decompiler
beinahe den exakten Source Code wiederherstellen kann. Das einzige was der Decompiler
nicht wiederherstellen kann sind Kommentare.
Die Konsequenz davon ist, dass bei kommerziellen Programmen, die in .NET oder Java
erstellt wurden, die Gefahr besteht, dass Programmteile und Algorithmen abgeschaut und
nachgebaut werden können oder der Programmcode erweitert und angepasst werden kann.
27
Selbst bei unternehmensinternen Programmen entstehen dadurch Gefahren. So könnten
zum Beispiel Datenbankpasswörter herausgefunden oder SQL-Abfragen manipuliert werden.
Auch das Ausfindig machen von Schwachstellen ist sehr viel einfacher, da der Angreifer mit
Quellcode arbeiten kann, anstatt sich mühsam mit Assembler-Code herumzuschlagen.
Hinzu kommt, dass Disassembler für .NET und Java für jedermann frei und zum Teil als
Freeware oder Open Source verfügbar sind:
.NET
Java
Microsoft MSIL disassembler (ILDASM)
.NET Reflector
ILSpy
The Java Class File Disassembler (javap)
Java Decompiler (JD)
DJ Java Decompiler
Tabelle 1: Beispiele für .NET und Java Disassembler/Decompiler
Die nachfolgende Abbildung zeigt das mit .NET geschriebene Programm Fiddler2 im
dekompilierten Zustand. Es ist schön zu sehen, dass alle Bezeichner (Namespaces,
Klassennamen, Funktionsnamen und Variablennamen) noch erhalten sind.
Abbildung 7: .NET Programm Fiddler2 dekompiliert mittels ILSpy
Code Obfuscation Tools
Um nun das Reverse Engineering und die daraus resultierenden Gefahren zu verhindern,
werden bei Programmiersprachen, in denen zu Bytecode kompiliert wird, sehr häufig Code
Obfuscation Tools verwendet. Diese versprechen meist, dass durch die Anwendung der
Obfuscation das Reverse Engineering der Programme mindestens genauso schwer wird, wie
es bei nativen Applikationen, wie C oder Cobal der Fall ist.
Als Ergebnis auf die starke Nachfrage gibt es natürlich für beide Sprachen ausreichend
Obfuscatoren. Beispiele für .NET sind die Tools Agile.NET, Dotfuscator, ConfuserEx und
28
Obfuscar, wobei es sich bei den ersten beiden um kommerzielle Produkte handelt, während
ConfuserEx und Obfuscar Open-Source Tools sind. Beim Dotfuscator ist erwähnenswert,
dass dieser bereits als Lite-Edition in Visual Studio integriert ist.
Eine ausführliche Übersicht mit Vergleich der angebotenen Obfuscation-Techniken von mehr
als 10 .NET Obfuscatoren ist auf Wikipedia unter folgendem Link zu finden:
https://en.wikipedia.org/wiki/List_of_obfuscators_for_.NET
Auch für die Programmiersprache Java gibt es eine Vielzahl an Obfuscatoren, zum Beispiel
ProGuard (Open Source), DexGuard (Android, kommerziell), Allatori Java Obfuscator
(kommerziell), JODE (Open Source), Excelsior JET Evaluation (kommerziell) und
Klassmaster (kommerziell). Eine Übersicht über die verschiedenen Java Obfuscatoren ist
unter folgendem Link einsehbar:
http://proguard.sourceforge.net/alternatives.html
In Android Studio ist ProGuard sogar standardmäßig in die Build-Umgebung integriert und
wird nach vorheriger Aktivierung automatisch gestartet sobald eine Applikation im „Release
Mode“ erstellt wird.
.NET Obfuscation Beispiele
Eine von Preemptive Solutions (dem Hersteller von DotFuscator) patentierte Technik ist die
sogenannte „Overload Induction“. Diese Technik macht nichts anderes als Variablen- und
Funktionsnamen zu verändern. Dabei macht sie sich aber zu Nutze, dass derselbe Identifier
für Klassen und Methoden verwendet werden kann, solange diese verschiedene Signaturen
haben. Weiters können auch Variablen denselben Namen haben, sofern diese sich in
verschiedenen Namespaces befinden. DotFuscator nutzt diese beiden Features um so viele
Funktions-, Klassen- und Variablennamen wie möglich in den Buchstaben ‚a‘ bzw. ‚b‘ zu
ändern. Dadurch können bis zu 33% aller im Code enthaltenen Bezeichner zu ‚a‘ und weitere
10% zu ‚b‘ umbenannt werden, was das Reverse Engineering des verschleierten Bytecodes
extrem schwer macht. Hier ein Beispiel:
private void CalcPayroll(SpecialList employeeGroup)
{
while (employeeGroup.HasMore()) {
employee = employeeGroup.GetNext(true);
employee.updateSalary();
DistributeCheck(employee);
}
}
private void a(a b) {
while (b.a()) {
a = b.a(true);
a.a();
a(a);
}
}
Beim Vergleich der beiden Codesnippets geht zwar klar hervor, dass beide dieselbe Logik
implementiert haben, jedoch ist es ungeheuer schwer nachzuvollziehen was genau der
rechte Codeteil macht beziehungsweise welche Objekte, Eigenschaften und Methoden
29
verwendet und aufgerufen werden. Als zusätzliches Feature wird dadurch auch noch die
Codegröße signifikant geschrumpft.
Ähnlich wie bei kompilierten Sprachen wird auch bei Sprachen, die in Bytecode kompiliert
werden, Control-flow Obfuscation angewandt um Disassembler (in diesem Fall den
Menschen) zu täuschen. Dabei werden beispielsweise goto Statements in den Bytecode
eingebaut, sodass die ursprüngliche Instruktionssequenz zwar in performanter Art
ausführgeführt wird, dies aber mit einem hin und her Springen gemacht wird, dass es sehr
schwer wird dem Logikfluss zu folgen:
// Code Snippet copyright 2000, Microsoft Corp, from WordCount.cs
public int CompareTo(Object o) {
int n = occurrences - ((WordOccurrence)o).occurrences;
if (n == 0) {
n = String.Compare(word, ((WordOccurrence)o).word;
}
return (n);
}
Disassemblierter Bytecode ohne Code Obfuscation
public virtual int a(object A_0) {
int local0;
int local1;
local0 = this.a - (c) A_0.a;
if (local0 != 0)
goto i0;
goto i1;
while (true) {
return local1;
i0: local1 = local0;
}
i1: local0 = System.String.Compare(this.b, (c) A_0.b);
goto i0;
}
Derselbe disassemblierte Bytecode mit Control-Flow Obfuscation
Die Funktion macht zwar noch exakt dasselbe wie die Funktion oberhalb, jedoch durch die
beiden Sprungbefehle, der zusätzlichen lokalen Variable und der falschen Endlosschleife
wird selbst die Funktionalität dieser sehr kleinen Funktion, die im Endeffekt nur aus einer
Subtraktion, einer Abfrage und einem Vergleich besteht, sehr schwer lesbar. Hat man nun
30
eine große Routine und keinen Vergleichscode zur Verfügung, so wird das Verstehen des
Codes zu einer sehr zeitaufwändigen Aufgabe. Natürlich generiert diese Technik ein wenig
Overhead und aufgrund der Komplexität kann es schon bei der Programmierung selbst viel
einfacher zu Fehlern kommen. Bei zeitkritischen Funktionen sollte man deshalb dieses
Feature eventuell deaktivieren oder entsprechende Tests durchführen.
Weiters werden natürlich auch Data Obfuscation Techniken wie „String Encryption“
verwendet, um das Auslesen von String Literalen, wie Bibliothekaufrufen, SQL-Befehlen und
Passwörtern zu verhindern. [27], [28]
Java Obfuscation Beispiel
Abbildung 8: links: Java Quellcode | rechts: Dekompilierter Java Quellcode
Wie in der Abbildung oberhalb zu sehen ist, können auch in Java bloß die Kommentare vom
Decompiler nicht zurückgewonnen werden, der Rest kann rekonstruiert werden. Das heißt
auch hier kommen die Entwickler eines kommerziellen Programms um einen Obfuscator, wie
zum Beispiel ProGuard, nicht herum.
Das mit dem ProGuard verschleierte (aber nicht geschrumpfte oder optimierte) und mit Java
Decompiler dekompilierte Programm sieht dann folgendermaßen aus:
31
Abbildung 9: Dekompilierter Java Quellcode, der mit ProGuard obfuscated wurde
Auch Android Apps sind in Java geschrieben und werden in Bytecode übersetzt. Und auch
bei Android werden die einzelnen Quellcode-Dateien (.java) in .class-Datei übersetzt. Doch
anderes als gewöhnlich werden die .class-Dateien nicht in einem .jar-Archiv
zusammengefasst und bei der Ausführung zur Laufzeit von der Java Virtual Machine (JVM)
kompiliert, sondern sie werden in sogenannte .dex (Dalvik Executable) Bytecodedateien
übersetzt, welche speziell für mobile Geräte optimiert sind. Die Dalvik Executables werden
dann in einer .apk-Archivdatei zusammengefasst und können anschließend auf ein Android
Gerät übertragen werden. [29]
Bis zur Android Version 5.0 „Lollipop“ wurden am mobilen Endgerät die .apk-Dateien bzw.
.dex-Dateien bei der Installation der App in .odex-Dateien (Optimized Dalvik Executable)
umgewandelt, um dann bei der Ausführung der App von einer Process Virtual Machine
namens Dalvik mittels Just-in-Time (JIT) Kompilierung in Maschinencode übersetzt zu
werden. [30]
Mit der Version 5.0 wurde nun ein Application Runtime Environment mit den Namen „Android
Runtime“ eingeführt, welches die .dex-Dateien nicht in .odex Dateien umwandelt und dann
Just-in-Time kompiliert, sondern eine Ahead-of-time (AOT) Kompilierung bei der Installation
der App durchführt und eine ELF-Datei erstellt. [31]
Doch egal ob nun JIT oder AOT bei Android verwendet wird, am mobilen Endgerät landet in
beiden Fällen der Java Bytecode in Form der apk-Datei. Das heißt, dass auch bei Android
Apps in jedem Fall Obfuscation eingesetzt werden muss, wenn man Funktionalität und
Algorithmen vor neugierigen Dritten schützen möchte.
32
Interpreted Languages / Skriptsprachen (JavaScript, Python, Perl)
Bei interpretierten Sprachen kann direkt die Quellcode-Datei ausgeführt werden. Das ist
natürlich sehr bequem, führt im Gegenzug aber auch zu Performance-Einbußen und
bedeutet, dass bei der Weitergabe von Programmen immer der gesamte Quelltext
weitergegeben werden muss. Aus diesem Grund gilt für Skriptsprachen prinzipiell dasselbe
wie bei der Weitergabe von C-Sourcecode oder bei der Weitergabe von Bytecodedateien:
Ohne zusätzliche Obfuscation können Dritte Einblick in die Algorithmen haben. Aus diesem
Grund gibt es für Sprachen wie JavaScript, Python und Perl eine ganze Menge an
Obfuscatoren. Stellvertretend für Skriptsprachen wird in dieser Arbeit JavaScript behandelt,
da sie als Programmiersprache des WWW sehr weit verbreitet ist.
Anmerkung zu Python: Programmiersprachen wie Python, bei denen auf Klammern und
Semikolon verzichtet wird und stattdessen die Programmstruktur mit Hilfe von Einrückungen
bewerkstelligt wird, sind nur sehr schwer gut zu verschleiern, da die Struktur und
Einrückungen ja auch im verschleierten Code noch beibehalten werden müssen!
Javascript
Javascript wurde ursprünglich entwickelt um Webseiten dynamisch zu manipulieren (Inhalte
verändern, nachladen oder generieren) und ist als ECMAScript im ECMA-262 Standard
spezifiziert. Heutzutage wird JavaScript zwar auch außerhalb des Browsers verwendet
(Server, Apps, Spiele), jedoch liegt der Hauptanwendungsbereich noch immer bei
Webseiten. [32]
Minification und Kompression
Auch für JavaScript-Programme besteht häufig die Anforderung die Funktionalität und die
Algorithmen des Codes vor unbefugten Zugriffen zu schützen. Noch häufiger steht bei
JavaScript jedoch die Anforderung im Vordergrund, möglichst wenige Ressourcen in Form
von Speicherbedarf zu verbrauchen, da die Webseite mit dem zugehörigen Skript ja über
das Internet übertragen wird und sich die Ladezeit proportional zur Downloadmenge erhöht.
Aus diesem Grund gibt es die sogenannte „Minification“, bei der unnötige Zeichen wie
Leerzeichen, Zeilenumbrüche, Kommentare und lange Bezeichner entfernt beziehungsweise
ersetzt werden, ohne die Funktionalität des Programms zu beeinflussen. Minification ist
prinzipiell zwar bei so ziemlich jeder Programmiersprache anwendbar, jedoch ist sie vor
allem bei interpretierten Sprachen und bei im Internet übertragenen Quelldateien sehr
hilfreich.
Im Gegensatz zu einem komprimierten Programm kann ein minimiertes Programm direkt
interpretiert werden und muss nicht vorher noch zur Laufzeit dekomprimiert werden. Tools,
die fertigen bzw. kompilierten Programmcode komprimieren und anschließend vorne beim
Programm eine Routine anfügen, die das Programm zur Laufzeit dekomprimiert, nennt man
Runtime Packer. Sowohl Minification als auch Komprimierung haben das Ziel den
(JavaScript) Code zu optimieren. Aus diesem Grund gibt es in der Praxis natürlich auch
33
Tools die den Quellcode zuerst mittels Minification minimieren, um ihn anschließend mittels
eines Packers zu komprimieren. Obwohl einige JavaScript-Optimierungstools im Namen die
Wörter Packer oder Compressor tragen, führen diese Tools meist keine wirkliche
Kompression durch, sondern nur einfache Minification. [33]
Nachfolgend einige Beispiele für gängige JavaScript Minification Tools:






JSMin
Packer
Closure Compiler
Microsoft Ajax Minifier
YUI Compressor
UglifyJS
http://crockford.com/javascript/jsmin
http://dean.edwards.name/packer/
http://closure-compiler.appspot.com/home
http://ajaxmin.codeplex.com/
http://yui.github.io/yuicompressor/
http://marijnhaverbeke.nl/uglifyjs
Obfuscation
Minification kann zwar als eine Art der Obfuscation angesehen werden, jedoch meint man
mit Obfuscation meist zusätzliche Funktionalitäten, wie Kompression und Verschlüsselung.
Weiters ist es bei der Verschleierung von Code durchaus auch möglich, dass zusätzlicher
(sinnloser) Code in die Anwendung eingefügt wird und diese dadurch zum Original wächst.
Bei der Minification ist natürlich das Ziel die Anwendung so klein wie möglich zu machen.
Nachfolgend einige Beispiele für gängige JavaScript Obfuscation Tools:



JScrambler
JavaScript Obfuscator
JS Packer
https://jscrambler.com/en/
http://javascriptobfuscator.com/
http://packer.50x.eu/
2.2.3 Packer
Der Begriff Packer bzw. Runtime Packer wurde in dieser Arbeit bis jetzt schon einige Male
erwähnt. In diesem Abschnitt wird nun genauer erläutert wie diese funktionieren und was mit
ihnen erreicht werden soll.
Ganz allgemein ist ein Packer ein Programm mit dem Software/Programme komprimiert
und/oder
verschlüsselt
werden
können.
Dabei
kommen
häufig
gängige
Kompressionsverfahren wie ZIP, CAB und RAR aber auch selbst geschriebene Verfahren
zum Einsatz und ohne dass man den verwendeten Algorithmus kennt, kann man die Daten
nicht wieder entpacken. Auf den ersten Blick sieht es also so aus als würden sich Runtime
Packer nicht von „normalen“ Kompressionstools wie WinZip, WinRar, 7-ZIP, gzip, usw.
unterscheiden. Doch es gibt einen signifikanten Unterschied: Bei gewöhnlichen
Kompressionstools müssen eine oder mehrere Dateien im komprimierten Zustand zuerst
wieder mit Hilfe desselben oder einem ähnlichen Tool dekomprimiert werden um die Dateien
verwenden zu können. Bei „gepackten“ Programmen können die Programme jedoch direkt
34
ausgeführt werden, ohne dass ein externes Tool fürs Dekomprimieren verwendet werden
muss. Das funktioniert deshalb weil Packer-Programme, nachdem sie ein Programm
komprimiert haben, die Dekomprimierungsroutine direkt vorne in das Programm einfügen.
Beim Programmstart wird dann diese Routine als erstes ausgeführt. Sie entpackt das
komprimierte Programm zur Laufzeit und springt dann zum ersten Befehl des ursprünglichen
Programms. Somit kann das Programm ganz normal ausgeführt werden. Lediglich beim
Programmstart ist mit einer leichten Verzögerung gegenüber dem Original zu rechnen, da
zuerst die Dekomprimierung stattfindet.
Statt oder zusätzlich zur Komprimierung kann natürlich auch Verschlüsselung eingesetzt
werden. Das Schema ist dasselbe.
Ein Packer kann bei interpretierten, kompilierten als auch semi-kompilierten (Bytecode)
Sprachen angewandt werden. Wichtig ist dabei nur, dass die Routine zum Dekomprimieren
in der entsprechenden Sprache vorliegt (Maschinencode, Bytecode oder in der
Skriptsprache, z.B. in JavaScript).
Meist werden Packer als externe Tools verwendet um ein Programm nach der Fertigstellung
zu komprimieren, dies ist aber nicht zwingend. Die Dekomprimierungsroutine kann auch
schon bei der Programmierung des Programms in dieses als fester Bestandteil integriert
werden. So können zum Beispiel ganz bestimmte Codeteile komprimiert werden, während
der Rest dekomprimiert bleibt. [34],
Schwächen und Gegenmaßnahmen
Runtime Packer bieten zwar prinzipiell eine gute Möglichkeit für Deobfuscation, weisen aber
eine entscheidende Schwäche auf: Selbst wenn ein Packer eine Software mit dem
robustesten kryptographischen Algorithmen verschlüsselt, früher oder später muss die
komprimierte und/oder verschlüsselte Applikation entpackt/entschlüsselt werden, damit die
CPU das Programm ausführen kann. Und genau das ist der Zeitpunkt bei dem das Reverse
Engineering normalerweise startet. Der Analyst macht einfach einen Speicher-Dump der
dekomprimierten/entschlüsselten Anwendung und speichert diesen auf der Festplatte. Somit
kann er die Originalsoftware analysieren und muss sich nicht mit den Schutzmechanismen
befassen. [34]
Vor der Dekomprimierung kann der Algorithmus als mögliche Gegenmaßnahme zusätzlich
prüfen ob er in einer virtuellen Maschine oder einem Debugger läuft bzw. ob am System ein
Disassembler läuft. Wird er fündig so bricht er die Dekomprimierung ab oder dekomprimiert
einen harmlosen Codeteil um den Reverse Engineer zu täuschen.
Weiters ist es natürlich möglich mehrere Komprimierungen bzw. Verschlüsselungsvorgänge
hintereinander zu vollziehen. Diese Technik wird häufig von Malware verwendet um die
Detektion und das Reverse Engineering möglichst schwierig zu machen. Während im Jahre
2006 über 92% der gesamten Malware mittels eines Packers komprimiert war [35], sind es
2014 nur mehr um die 60% [36].
35
Beispiele für Packer
Es gibt eine Vielzahl an verschiedenen Runtime Packern. Unter shadowserver.org ist eine
Statistik verfügbar, die die beliebtesten bzw. meist gebräuchlichen Packer zeigt:
https://www.shadowserver.org/wiki/pmwiki.php/Stats/PackerStatistics
Der bekannteste und am häufigsten verwendete Packer ist UPX (ultimate packer for
executables). UPX eignet sich besonders zur Komprimierung von Linux-ELF (32- und 64Bit), DOS-EXE (16- und 32-Bit), Windows-PE (EXE und DLL) oder auch TOS-Dateien. Er
unterstützt aber auch eine ganze Reihe von weiteren Formaten.
UPX (unverändert) bietet jedoch keinen guten Schutz gegen Reverse-Engineering, da sich
die UPX-gepackten Programme durch UPX selbst wieder entpacken lassen. Unveränderte
UPX-gepackte Programme werden auch häufig von Antivirenprogrammen als solche erkannt
und dekomprimiert. [37]
Weitere Beispiele für Packer sind ASProtect, PECompact oder Morphine. Eine ausführliche
Liste von Runtime Packers kann auf Wikipedia eingesehen werden:
https://en.wikipedia.org/wiki/Executable_compression
2.2.4 Virtualisierung
Auch virtuelle Maschinen können zum Schutz von Software vor Reverse Engineering
eingesetzt werden. Im Bereich Software-Schutz und Obfuscation ist eine virtuelle Maschine
eine Softwarekomponente, die einen Prozessor emuliert. Aus diesem Grund wird auch
manchmal der Begriff virtueller Prozessor verwendet. Dieser virtuelle Prozessor besitzt
seinen eigenen Instruktionssatz und kann Programme ausführen, welche in einem speziellen
Bytecode kompiliert wurden. Der Prozessor muss dazu in das Programm integriert werden,
damit dieses dann auch ausgeführt werden kann. Um einen möglichst guten SoftwareSchutz zu erzielen, ist die virtuelle Maschine folglich möglichst komplex aufgebaut, zum
Beispiel kann sie auf einer exotischen Architektur basieren. Um die Komplexität weiter zu
erhöhen, können für ein Programm auch mehrere virtuelle Prozessoren verwendet werden.
Das kann entweder horizontal, also verschiedene Teile der ausführbaren Datei werden auf
verschiedenen virtuellen Prozessoren ausgeführt, oder auch vertikal, also indem eine
virtuelle Maschine in einer anderen virtuellen Maschine läuft, implementiert werden. [38] [39]
Diese Art von Obfuscation wird unter anderem von kommerziellen Tools wie VMProtect,
Themida, StarForce und SecureROM eingesetzt. Darüber hinaus gibt es auch mehrere
Malware-Programme, die ihre eigene virtuelle Maschine verwenden um ihren Schadcode vor
Antivirensoftware zu schützen.
36
2.2.5 Deobfuscation
Als logische Konsequenz auf Obfuscation Tools, sind natürlich Deobfuscation Tools
entstanden, die versuchen verschleierten Code wiederum zu entschleiern. Viele dieser Tools
sind vor allem auch für Malware-Analysen von großer Bedeutung. Die vielen verschiedenen
Deobfuscation Tools und Unpacker verdeutlichen noch einmal, dass wir es bei Obfuscation
und Software Protection mit Security by Obscurity zu tun haben und die Verschleierung zwar
eine zusätzliche Hürde beim Reverse Engineering darstellt und dieses aufwändig und
zeitintensiv macht, jedoch kann früher oder später jede noch so ausgeklügelte Methode
umgangen bzw. rückgängig gemacht werden.
Auf die genauen Techniken, die die Deobfuscatoren verwenden wird in dieser Arbeit nicht
eingegangen. Dennoch sind hier einige
.NET
de4dot
iMPROVE .NET Deobfuscator
Javascript
JSUnpack
JavaScript Deobfuscator
JSDetox
Binary Unpacking & Packer Erkennung
PEiD
ExeScan
RDG Packer Detector
PE.Explorer
Devirtualization
VMProtect Ultra Unpacker
Themida - Winlicense Ultra Unpacker
2.3 Malware vs. Antivirus
Malware ist die Kurzform für „malicious software“ (deutsch: Schadprogramm) und bezeichnet
Software, die mit dem Ziel programmiert wurde, um auf dem installierten Hostsystem vom
Benutzer unerwünschte und/oder schädliche Funktionen durchzuführen. Dazu gehört zum
Beispiel das Manipulieren, Löschen oder Übermitteln von Daten, wie Dokumente,
Passwörter und elektronische Nachrichten, sowie das außer Gefecht setzen eines Systems
(Denial of Service). Diese Schadfunktionen werden dabei gewöhnlich im Hintergrund
37
ausgeführt und sollen vorm Benutzer bzw. Systembetreiber verborgen bleiben. Zusätzlich
lässt sich Malware meist auch nicht mit gebräuchlichen Mitteln deinstallieren, da sich diese
an verschiedenen Stellen und so tief im System verankert, dass meist voll funktionsfähige
Schadcodeteile auch nach einer vermeintlichen Installation noch ihre Funktionen ausführen.
[40]
Malware Typen
Wie aus dieser Definition hervorgeht ist Malware ein Oberbegriff und kann in folgende Typen
unterteilt werden:
Malwaretype
Beschreibung
Virus
Ein Virus benötigt ein Wirtprogramm zur Ausführung seiner Befehle. Er
kann sich reproduzieren & mit Hilfe des Benutzers verbreiten. Dazu legt
der Virus Kopien von sich selbst in einem Speicherbereich (Programme,
Datenträger und Dokumente) der seine Befehlssequenz noch nicht enthält
(Infektion). Werden diese Daten von einem System auf ein anderes
gesendet bzw. kopiert, so wird dadurch auch der Virus übertragen.
Aus der Definition geht hervor, dass ein Virus sich nicht selbständig
ausführen kann. Er wird ausgeführt, sobald die infizierte Datei vom
Benutzer geöffnet wird. Nachdem der Virus seinen schadhafte Code
ausgeführt hat, führt er meist noch die Funktion aus, die der Benutzer
eigentlich getriggert hat, indem er an die Stelle der Datei springt, die
ursprünglich der Startpunkt der Ausführung war. Dadurch bleibt er vom
Benutzer unerkannt.
Beispiel: Sobig Virus
Worm
Ein Computerwurm ist ein eigenständiges Programm welches sich
reproduzieren und über Computernetzwerke verbreiten kann. Durch die
Unabhängigkeit von einem Wirt, kann sich ein Wurm wesentlich schneller
verbreiten als ein Virus.
Beispiele: Internet-Wurm, ILOVEYOU-Wurm, Lovesan-Wurm
Trojan Horse
Ein Programm, welches sich wie ein trojanisches Pferd verhält, bietet dem
Benutzer Funktionalitäten die dieser benötigt bzw. Vertrauen erwecken,
ergänzt diese jedoch durch versteckte Schad-Funktionen. Der Benutzer
wird also getäuscht. Häufig entfalten Trojaner ihren Schadfunktionen erst
nach Verstreichen eines gewissen Zeitraums oder bei Eintreten eines
gewissen Ereignisses.
Beispiele: Häufig verstecken sich hinter Freeware, Raubkopien, Keygens
und Anhängen in Emails Trojaner.
Ransomware
Setz sich aus den Begriffen Malware und Ransom (Lösegeld) zusammen
und beschreibt Software, die nach dem Eindringen auf einem fremden
Rechner, dessen Daten auf der Festplatte zu verschlüsselt bzw. den
38
Zugriff auf den Rechner verhindert. Für die Entschlüsselung wird dann in
weiterer Folge ein Lösegeld eingefordert, das über OnlineZahlungssysteme eingezahlt werden muss.
Spyware
Ist ein Programm, welches Informationen über die Benutzer eines Systems
sammelt (Passwörter, Email, Dokumente, Tastatureingaben, …) und diese
über das Internet an Dritte weiterleitet. Diese Daten werden dann
entweder verkauft oder für weitere Angriffe verwendet. Spyware wird
häufig als Trojaner mit einem anderen nützlichen Programm mitinstalliert
und bleibt auch nach der Deinstallation des nützlichen Programms noch
auf dem Rechner.
Adware
Adware ist im Prinzip dasselbe wie Spyware, nur das die Schadfunktionen
nicht Passwörter oder Dokumente stehlen, sondern Funktionen ausführen,
die entweder Werbung zeigen oder das Nutzerverhalten in Bezug auf
Werbung oder Marktforschung ausspionieren.
Scareware
Scareware versucht den System-Benutzer zu verunsichern und ihn dazu
zu verleiten entweder ein schädliches Programm zu installieren oder Geld
für ein eigentlich unnützes Programm zu bezahlen.
Beispiel: Falsche Warnmeldung über einen Virenbefall, der nur mittels
eines kostenpflichtigen Programms entfernt werden kann.
Rogueware
Bezeichnet falsche Sicherheitssoftware, die dem Benutzer nur vorgaukelt
vermeintliche Schadprogramme zu deinstallieren. Die Rogueware ist dabei
entweder kostenpflichtig oder installiert ein Schadprogramm während es
die Entfernung von Schadsoftware vortäuscht.
Tabelle 2: Malware Typen
In der Praxis verschwimmen die oben angeführten Ausprägungen von Malware immer
häufiger, da die Entwickler natürlich versuchen so viele Funktionen wie möglich in ihre
Schadprogramme zu packen. So gibt es zum Beispiel Würmer, die als Ransomware
fungieren oder Viren, die Spyware-Funktionalitäten aufweisen. Meist lässt sich grob
unterscheiden ob es sich um ein Virus, einen Wurm oder einen Trojaner handelt, da diese 3
Arten unterschiedliche Verbreitungsstrategien vorweisen. Natürlich können aber auch diese
kombiniert werden.
[40], [41], [42]
Malware vs. Antivirus – Das „Katz und Maus“ Spiel
Es gibt verschiedene Wege sich vor den diversen Malware-Arten zu schützen, wie zum
Beispiel Rechtebeschränkung, Deaktivierung von Autostartfunktionalitäten, Quarantäne und
Isolierung, die allesamt präventive Maßnahmen darstellen. Am häufigsten werden jedoch
Virenscanner bzw. Antivirus Programme eingesetzt um sich vor Malware zu schützen (der
39
Name „Antivirus“ ist ein wenig irreführend). Diese verwenden unter anderem eine Musterbzw. Signaturerkennung um eine bereits bekannte Malware zu erkennen und dessen
Ausführung zu verhindern. Dazu muss die entsprechende Malware zuerst einmalig von den
Analysten eingefangen und auf Schadfunktionen analysiert werden. Werden diese gefunden,
so wird ein charakteristischer Teil des Schadprogramms hergenommen und in einer
Signaturdatenbank gespeichert. Diese Datenbank wird an die einzelnen AntivirusProgramme regelmäßig als Update versendet. Die sogenannte Scanengine des Antivirus
führt dann bei den am System vorhandenen Dateien bzw. bei Programmen die gestartet
werden einen Bitmustervergleich mit der Signaturdatenbank durch und kann somit Kopien
der Malware ausfindig machen.
Diese einfache Erklärung für Signaturerkennung von Malware ist natürlich nicht mehr ganz
100% „State of the Art“ und wurde bereits Anfang der 90er Jahre verwendet.
Die Entwickler von Malware versuchen natürlich diese Art der Signaturerkennung zu
umgehen und reagieren darauf mit Verschleierungstechniken, so wie sie im vorherigen
Abschnitt vorgestellt wurden. Ziel ist es den Schadcode so zu konstruieren, dass er
möglichst schwer von einem Antivirusprogramm erkannt werden kann. Dadurch wird die
Wahrscheinlichkeit höher, dass möglichst viele Systeme von der Malware befallen werden
können und diese möglichst lange unentdeckt bleibt.
Zur besseren Verständnis folgt ein einfaches Beispiel wie Signaturerkennung bei JavaScript
funktioniert. Der nachfolgende Code ist nur ein kleiner Teil eines Exploits mit dem die
„execCommand Use After Free Vulnerability - CVE-2012-4969“ ausgenutzt werden kann und
wurde aus [43] übernommen.
Diese 3 Zeilen (5 – 7) JavaScript werden von den Antivirus-Programmen GData, Ad-Aware,
BitDefender, Emsisoft, F-Secure, MicroWorld-eScan und nProtect verwendet um den Exploit
als Malware zu identifizieren. Aus diesem Grund wird die HTML-Datei von diesen Scannern
als bösartig eingestuft, obwohl sie eigentlich gar nichts macht.
40
Abbildung 10: VirusTotal.com Scanergebnis des JavaScript-Codes von oberhalb
Wie können die 3 Zeilen nun abgeändert werden, sodass diese nicht mehr als bösartig
erkannt werden? Ganz einfach: Anstatt das window-Objekt in Zeile 6 direkt zu verwenden,
wird dieses zuerst auf eine neu angelegte Variable w gespeichert:
Nun folgt wieder der Test auf virusTotal.com: Kein Virenscanner erkennt den Code mehr als
bösartig.
Abbildung 11: VirusTotal.com Scanergebnis des abgeänderten JavaScript-Codes von oberhalb
41
Nachfolgend werden verschiedene Techniken und Vorgehensweisen von Malware
aufgelistet, die dabei helfen sollen unentdeckt zu bleiben. Weiters wird auf die jeweiligen
Gegenmittel der Antivirus – Hersteller eingegangen:

Self-Encryption and Self-Decryption.
Viren verschlüsseln und entschlüsseln bzw. komprimieren und dekomprimieren ihren
Code um diesen vor einer direkten Prüfung des Codes zu verbergen. Dabei werden
entweder mehrere Verschlüsselungsvorgänge verwendet oder zufällig erstellte
Schlüssel, damit jede neue Kopie des Virus anders aussieht obwohl derselbe Code als
Klartext-Basis verwendet wird und auf der CPU auch weiterhin derselbe Code
ausgeführt wird. Im Kapitel Code Obfuscation wurden schon Programme vorgestellt, die
eine solche Funktionalität implementiert haben: Runtime Packer. Laut einer
Untersuchung von mehr als 6 Millionen Malware-Samples [36] ist UPX nach wie vor der
beliebteste Packer für Malware (~20%). Die meisten Packer sind jedoch malwarespezifisch und können keinem verfügbaren Packer zugeordnet werden (~60%)
Diese Technik erschwert nicht nur die Signaturerkennung (diese ändert sich ja zum
größten Teil bei jeder Kopie), sondern vor allem auch das Reverse Engineering bei der
Analyse der Malware. Da sowohl Entschlüsselungsfunktion (Decryptor Stub) als auch
Entschlüsselungsschlüssel (Secret Key) in der Malware enthalten sein müssen ist es
jedoch dennoch möglich durch eine statische Codeanalyse (also ohne Ausführung des
Programms) den eigentlichen Code zu extrahieren um diesen analysieren zu können.
Weiters kann die Funktion zum Entschlüsseln selbst nicht verschlüsselt werden. Das
ermöglicht wiederum den AV-Herstellern charakteristische Signaturen für den Decryptor
Stub zu erstellen und nach diesem in den Dateien zu suchen.

Oligomorphism.
Der nächste logische Schritt der Virenhersteller ist daher zu versuchen den Decryptor
Stub so zu verändern, dass dieser per Signatur-Check nicht erkannt wird. Daher wird bei
jeder Kopie der Malware nicht nur der Verschlüsselungsschlüssel geändert, sondern
zusätzlich auch der Entschlüsselungsvorgang. Das kann im einfachsten Fall das
zufällige Auswählen von mehreren (hunderten) vorgefertigten Decryptor Stubs sein. Da
diese Anzahl nicht allzu groß ist, ist es jedoch meist immer noch möglich die Malware
mittels Signaturerkennung zu identifizieren. Dazu müssen die Analysten nur von allen
möglichen Stubs eine Signatur entnehmen und all diese in die AV-Datenbank
einpflegen. Eine weitere Methode zur Erkennung eines Oligomorphen Dekryptors wäre
es eine Signatur für jede mögliche Codezeile zu erstellen und diese Signaturen in allen
möglichen Kombinationen aneinanderzureihen. [44]
42

Polymorphism.
Eine polymorphe Malware verändert bei jeder Kopie von sich selbst ihre gesamten zu
Grunde liegenden Befehle, ohne die Funktionalität der Software zu verändern. Dies wird
mit Hilfe einer sogenannten „Polymorphic Engine“ gemacht und dabei ist
Verschlüsselung wiederum die herkömmlichste Art um Polymorphie zu implementieren.
Im Gegensatz zur oligomorphen Malware heißt dass, das der Decryptior Stub nicht aus
einer Vorauswahl von möglichen Stubs ausgewählt wird, sondern dass fast keine Kopie
der anderen gleicht.
Das nachfolgende Beispiel wurde direkt vom unterhalb zitierten Wikipedia-Artikel
übernommen. Dabei handelt es sich zwar nicht um einen wirklichen polymorphen Code,
jedoch gibt es eine Vorstellung davon, wie man es bewerkstelligt den Decryptor Stub bei
jeder Kopie der Malware zu mutieren.
In diesem Beispiel wird die Mutation über die Variable C bewerkstelligt. Da diese
Variable in die Entschlüsselung nicht miteingeht, ist ihr Wert im gesamten
Entschlüsselungscode eigentlich egal. Das heißt die Zeilen 4, 8, 11,12 und 15 können
fast nach Belieben geändert werden, solange der L-Operant das C bleibt. Ja noch mehr
sogar: Es können auf den Basiscode für die Entschlüsselung (Zeilen: 3, 5, 6, 7, 9, 10,
13, 14, 16, 17, 18) so ziemlich alle schon in dieser Arbeit erläuterten Obfuscation
Methoden angewandt werden um den Decryption Stub bei jeder Malware-Kopie aufs
Neue abzuändern.
In der Zeile 0 – 2 befindet sich in diesem Beispiel der verschlüsselte Payload. In diesem
sind die eigentlichen Schadfunktionen, der Code zum Verbreiten der Malware, sowie der
Code zum Kopieren und Verschlüsseln der Malware und zum Mutieren des Decryption
Stubs enthalten.
Im verschleierten Decryption Stub (Zeile 3 – 18) wird nichts anderes gemacht als auf der
Variable A die Startadresse der verschlüsselten Payload zu speichern und danach
mittels einer Schleife über alle Speicheradressen zu iterieren und für jede Adresse eine
XOR-Operation mit dem symmetrischen Schlüssel durchzuführen bis das Ende des
verschlüsselten Codes erreicht wurde. Sobald dies der Fall ist wird die Schleife
verlassen und mittels eines Sprungbefehls an den Beginn des nun entschlüsselten Code
verzweigt.
43
0:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
...
lots of encrypted code
...
Decryption_Code:
C = C + 1
A = Encrypted
Loop:
B = *A
C = 3214 * A
B = B XOR CryptoKey
*A = B
C = 1
C = A + B
A = A + 1
GOTO Loop IF NOT A = Decryption_Code
C = C^2
GOTO Start_of_Encrypted_Code
CryptoKey:
some_random_number
Eine vergleichsweise einfache Methode um Polymorphie bei den Malware-Instanzen
sicherzustellen ist die sogenannte serverseitige Polymorphie. Dabei wird die Malware
über einen Webserver verbreitet, der neben der Infektion von Rechnern auch gleich die
Malware automatisiert abändert (durch Packer, andere Verschlüsselungsparameter,
Obfuscation), sodass jede Malware-Instanz wirkt als wäre sie einzigartig. In diesem Fall
muss sich die Malware-Instanz selbst nicht reproduzieren und benötigt selbst keinen
Code zum Verschleiern der Kopien. Dadurch wird die Malware schlanker und muss
weniger verdächtige Funktionen durchführen, die sie als Schadprogramm identifizieren
könnten.
Eine polymorphe Malware zu erkennen ist aus oben genannten Gründen daher schon
nicht mehr ganz so einfach mittels Signaturerkennung zu bewerkstelligen. Der Grund
dafür ist einfach, dass sich die gesamte Befehlssequenz der Malware bei jeder Kopie
verändert und somit keine Instanz der anderen gleicht. Es müssen also andere Ansätze
gefunden werden:

Statische Analyse durch “Unpacking”
Die zu überprüfende Datei wird analysiert und bei Feststellung von
Komprimierung bzw. Verschlüsselung (zb. durch erhöhte Entropie) wird
analysiert ob ein dem AV-Programm bekannter Packer verwendet wurde. Ist dies
der Fall, so wird versucht die Malware zu dekomprimieren / entschlüsseln um
anschließend eine statische Analyse, zum Beispiel mit Hilfe von Signaturen,
durchführen zu können.
44

Laufzeit-komprimierte Dateien als gefährlich einstufen
Funktioniert das Entpacken einer laufzeitgepackten Anwendung nicht, so
verwenden einige Antivirus die Strategie diese Datei einfach als gefährlich
einzustufen und diese vorerst an der Ausführung zu hindern. Der Benutzer erhält
eine Warnung und kann entscheiden ob er das Programm ausführen möchte
oder nicht. Der Nachteil bei dieser Strategie ist, dass es durchaus auch legitime
Verwendungszwecke für Packer gibt und der Benutzer öfters mit False-Negative
Meldungen konfrontiert wird.

Dynamische Analyse durch Emulation und Signaturen
Die zu überprüfende Datei wird in einer sicheren, virtuellen Umgebung (Sandbox)
ausgeführt und darauf gewartet, dass die Malware den Schadcode entpackt um
diesen auszuführen. Nun kann wiederum mit Hilfe von Signaturen geprüft werden
ob es sich um eine bekannte Malware handelt. Das Problem bei dieser Methode
ist die Geschwindigkeit. Außerdem verwenden Malware-Hersteller Methoden um
zu erkennen ob ihre Software in einer virtuellen Umgebung ausgeführt wird.
Dynamische Analyse wird auch als dynamische Heuristik bezeichnet, da das
Verhalten der Malware auf verdächtige Funktionen hin untersucht wird.
[45]

Metamorphism.
Auf Grund des Blockierens von komprimierten/verschlüsselten Anwendungen und der
dynamischen Analyse von Anwendungen in einer virtuellen Umgebung geht das Spiel in
die nächste Runde. Polymorphe Techniken sind zwar nach wie vor State of the Art und
weit verbreitet, jedoch gibt es eine weitere Variante jede Malware-Instanz anders
aussehen zu lassen, und das ganz ohne Komprimierung oder Verschlüsselung zu
verwenden. Dazu wird Metamorphie verwendet. Ganz allgemein fertigt ein metamorpher
Code ein logisches Äquivalent von sich selbst an (wie eine Quine), jedoch mit
modifizierten Source- bzw. Maschinencode. Eine Malware, die sich diese Technik zu
Nutze macht, verwendet also die schon bereits in dieser Arbeit behandelten Methoden
der (Code) Obfuscation um jede Instanz anders aussehen zu lassen. Ein sehr einfaches
Beispiel wurde dafür schon beim Decryptor Stub bei polymorpher Malware gezeigt. Wird
„Code Obfuscation bevor Compilation“ verwendet, so muss das logische Äquivalent
auch noch neu übersetzt werden. Durch diese Methode können meist bessere
Ergebnisse erzielt werden als beim verschleiern des Maschinencodes. Da bei
polymorphen Code die polymorphe Engine verschlüsselt wird, bleibt diese immer gleich
bei jeder Malware-Instanz. Bei metamorpher Malware muss sich wirklich der gesamte
ausführbare Code der Malware ändern und daher wird auch das Aussehen der
metamorphen Engine immer wieder abgeändert.
45
Zu den Mutationsmethoden zählen folgende Techniken:

Austauschen der verwendeten Register

Ändern des "Control Flow" und Umordnen von Anweisungen

Austauschen der Maschinen Befehle in äquivalente andere

Verwenden von äquivalenten Formeln und konstante Transformationen

Einfügen von Leercode (Dead Code Insertion)

Aufruf von Subroutinen
Der Zperm Virus verwendet zum Beispiel das „Umordnen von Anweisungen“ und
„Einfügen von Sprungbefehlen“ um Metamophie zu gewährleisten:
Abbildung 12: Zperm: Metamorphie mittels umordnen von Instruktionen und einfügen von Jump Statements [46]
Eine weitere Form einer metamorphen Malware ist ein Executable, welches in der Lage
ist auf zwei oder mehreren Betriebssystemen (zB. Windows und GNU/Linux) ausgeführt
zu werden und Schaden anzurichten. Bewerkstelligt wird dies, indem die Datei einfach
mehrere Malware-Varianten in sich trägt. Wichtig ist dabei, dass der Startcode der
Malware so programmiert wurde, dass dieser in korrekten Maschinencode, für alle ZielPlattformen auf denen er ausgeführt werden soll, kompiliert werden kann.
Gegen eine Metamorphe Malware kommt man weder mit Signaturprüfung noch mit
Emulation und anschließender Signaturprüfung an. Jedoch kann das Antivirus mithilfe
von statischen und dynamischen Heuristiken versuchen die Malware zu erkennen. Bei
statischen Heuristiken wird zum Beispiel nach spezifischen API-Aufrufen und
Entschlüsselungs-Funktionen gesucht. Bei dynamischen Heuristiken wird das Programm
emuliert ausgeführt und verdächtiges Verhalten, wie zum Beispiel das Manipulieren von
Systemdateien, detektiert. Durch Heuristiken kann prinzipiell auf gänzlich neue Malware
gefunden werden. Das Problem dabei ist nur die relativ hohe false-positive und falsenegativ Rate.
Eine weitere Methode ist die Detektion nach dem Hidden Markov Model (HMM), welches
in dieser Arbeit nicht genauer erläutert wird. Einen Überblick kann man sich hier
verschaffen: [47].
[48]
46
Da die vorgestellten Techniken Polymorphie und Metamorphie nicht ganz einfach zu
implementieren sind, verwenden die meisten Malware-Autoren einfach existierende
Lösungen um ihren Schadcode vor Entdeckung zu schützen. Häufig werden auch
„Metamorphic Virus Generation Toolkits“ verwendet, mit denen sich metamorphe Viren per
Mausklick erstellen lassen.
Weitere Techniken um unerkannt zu bleiben

Stealth.
Schon die ersten Viren hatten Techniken implementiert um sich zu tarnen und eine
Entdeckung zu vermeiden. Zu diesen Techniken gehören zum Beispiel:
 Änderungsdatum der infizierten Datei nicht verändern
 Sich selbst im Speicher verstecken
 Betriebssystemtabellen so verändern, dass die Dateigrößen der infizierten Dateien
sich nicht verändern
 Kopien von infizierten Dateien anlegen, übernehmen von Systemfunktionen fürs
lesen von Dateien und/oder Festplattensektoren um Virenscanner auf die Kopien
der Dateien umzuleiten
Um dennoch zu erkennen ob eine (Betriebssystem-) Datei geändert wurde werden
Hashwerte und/oder kryptografische Signaturen verwendet.

Armoring.
Armoring bezeichnet Techniken, die dazu verwendet werden um die Analyse von
Malware durch AV-Software oder Menschen, durch Debugging, Disassemblierung,
Dekompilierung, De-Obfuscation, usw. zu verhindern (Anti-VM, Anti-Disassembly, AntiDebugging). Wird zum Beispiel eine virtuelle Umgebung oder ein Debugger erkannt, so
wird ein anderer (harmloser) Teil der Malware extrahiert und nicht der Schadcode. Eine
kleine Einführung in die verwendeten Techniken ist in [49] zu finden.
[50]
47
3 Proof of Concept
Basierend auf den eben theoretisch beschriebenen Techniken zur Verschleierung von
Schadsoftware, werden diese in einem praktischen Versuchsaufbau auf Ihre Wirkungsweise
und Funktionalität überprüft. Dabei werden die verwendeten Tools unter den Aspekten
Detektionsrate, Zeitaufwand und Schwierigkeit untersucht.
3.1 Vorgehensweise
Für die Umsetzung der Tests wurde eine virtuelle Maschine (VM) mit dem Betriebssystem
Windows XP Professionell Service Pack3 aufgesetzt und sämtliche verfügbare Windows
Updates installiert. Danach wurden mehrere freie Antiviren-Software-Produkte auf der VM,
zur Überprüfung der Schadsoftware, installiert:




Avast Free Antivirus, Version 2015.10.0.2208, Virendatenbankversion 150202-0
Avira Free Antivirus, Version 14.0.7.468, Virendefinitionsdatei 8.11.206.130
AVG AntiVirus Free, Version 2015.0.5645, Virendatenbankversion 4253/9042
Kaspersky Anti-Virus, Version 15.0.1.415 (b), Database release date: 2.2.2015
Anschließend wurden die bereits öffentlich bekannten Binaries des ZeuS Trojaners von
https://zeustracker.abuse.ch/downloads/zeusbinaries.zip heruntergeladen. Diese werden zur
Überprüfung der File-Scans der oben angegeben Antiviren-Produkte verwendet.
Um nun die erwähnten Zeus-Executables vor den Viren-Scannern zu verschleiern, bedient
man sich sogenannter Packer oder auch Crypter. Diese ermöglichen eine Verschlüsselung
der Software, sodass diese nicht mehr disassembliert werden kann und somit auch von den
Anti-Viren-Lösungen analysiert werden kann. Aus der zahllosen Menge wurde das Produkt
„Yoda’s Crypter“ in der Version 1.03.3 ausgewählt, um die ZeuS-Binaries zu verschleiern
und das Ergebnis mittels der Anti-Viren-File-Scans zu überprüfen.
Eine andere Möglichkeit der Verschleierung stellt die Code Obfuscation bereits zum
Zeitpunkt der Erstellung der Assemblys aus dem Source Code oder aus den fertigen
Assemblys. Solche Code Obfuscation Tools sind meist auf eine bestimmte Umgebung zum
Beispiel .Net Framework oder Java zugeschnitten und bieten den Vorteile, dass der Source
Code selbst dermaßen verschleiert wird, sodass eine Code Analyse enorm erschwert bzw.
sogar unmöglich gemacht wird. Eine solche Funktionalität bietet beispielsweise das Produkt
„Smart Assembly“, welche .Net Applikationen verschleiern kann. Zu diesem Zweck wurde
Microsoft Visual C# 2010 Express installiert und der Source Code bzw. das Assembly des
Keyloggers „AvesoftKeylogger“ verwendet, um diesen mit „Smart Assembly 6“ zu
verschleiern und erneut mittels der Anti-Viren-File-Scans zu überprüfen.
48
3.2 Durchführung
Als erstes wurde die ZeuS-Bot-Binary mit Hilfe des Tools „Yoda’s Protector“ gepackt und
mittels der installierten Anti-Virus Produkte überprüft.
Abbildung 13: Obfuscation des ZeuS-Bot mittels yoda’s Protector v1.03.3
Aus dem Executable zeusbin.ex0 wurde also das komprimierte zeusbin_packed.ex0 erstellt.
Zusätzlich wurden, wie auf der Abbildung oberhalb zu sehen ist, noch diverse weitere
Schutzmechanismen angewandt:

Schutz gegen Kernel Mode Debugging mittels SoftICE

Schutz der Checksumme

Schutz vor dem Umlenken der API Aufrufe zwecks Reverse Engineering

Schutz vor Anti-Dumping

Entfernen Import Informationen

Entfernen der .reloc Sektion aus dem PE Header

Entfernen der Debug Informationen

Entfernen des MS-DOS Header
Im zweiten Schritte werden nun die beiden ausführbaren Dateien jeweils nacheinander
mittels verschiedener Virenscanner überprüft. Durch diese Vorgehensweise ist sichergestellt,
dass beide Executables mit denselben Virendatenbanken verglichen werden. Die
Die folgenden 4 Screenshots zeigen, dass alle 4 Antiviren-Produkte den originalen ZeusTrojaner erkennen:
49
Abbildung 14: avast! Prüfergebnis des originalen ZeuS-Bots
Abbildung 15: AVG Prüfergebnis des originalen ZeuS-Bots
Abbildung 16 & 17: Avira & Kaspersky Prüfergebnis des originalen ZeuS-Bots
Eine Analyse des Zeus-Bots unter www.virustotal.com liefert ebenfalls ein eindeutiges
Ergebnis. So gut wie alle Virenscanner erkennen die ausführbare Datei als Virues.
50
Abbildung 18: VirusTotal Prüfergebnis des originalen ZeuS-Bots
Im Gegensatz dazu wird die mittels „Yoda’s Protector“ gepackte .exe nur von Avira Antivir als
gepacktes Executable erkannt und als kritisch eingestuft. Die übrigen Virenscanner erkennen
keine Bedrohung.
Abbildung 19: avast! Prüfergebnis des verschleierten ZeuS-Bots
Abbildung 20: AVG Prüfergebnis des verschleierten ZeuS-Bots
Abbildung 21 & 22: Avira & Kaspersky Prüfergebnis des verschleierten ZeuS-Bots
51
Beim Virus-Scan unter virustotal.com erkennen nur 14 von 57 Scannern das Executable als
Bedrohung und selbst diese können nur feststellen, dass es sich um eine gepackte
Applikation handelt, aber nicht was diese beinhaltet.
Abbildung 23: VirusTotal Prüfergebnis des verschleierten ZeuS-Bots
Bytecode Obfuscation Beispiel (.NET)
Mittels der Code Obfuscation auf Bytecode Ebene für .Net-Anwendungen lassen sich
zahlreiche weitere Einstellungen treffen, als im Vergleich zur reinen Verschleierung mittels
einer Packer-Software. Das Tool „Smart Assembly 6“ bietet beispielsweise Möglichkeiten zur
Signierung, automatischen Fehlerberichterstattung, Berichterstattung der Funktionsnutzung,
Migration von Abhängigkeiten, Pruning (Entfernung von nicht benötigten Information z.B:
Metadaten, Namen von Events, Eigenschaften, …), dynamischen Umbenennung von
Klassen- und Methodennamen, Änderung des Programmablaufes, externe Methodenaufrufe
über einen Proxy, Verschlüsselung der Ressourcen und Strings, etc.
52
Abbildung 24: Smart Assembly GUI (.NET Obfuscator)
Mit Hilfe des Tools „Smart Assembly“ wurde nun ein in .NET programmierter Keylogger
verschleiert.
Bei der Analyse des ursprünglichen und neu generierten Assemblies mittels des ILSpy .NetDisassemblers erkennt man (wie schon im Grundlagen Kapitel erläutert), dass sich die
ursprüngliche Version vollständig analysieren und lesen lässt.
Abbildung 25: Mit ILSpy disassembelter original Bytecode des Keyloggers
53
Im Vergleich dazu, ist aus der neu generierten Version des Keyloggers nur schwer
Information herauszulesen. Außerdem erkennt man, dass der Programmablauf am Beispiel
der appendLogFile – Funktion wesentlich verändert wurde.
Abbildung 26: Mit ILSpy disassembelter verschleierter Bytecode des Keyloggers
Als weitere Alternative wurde der Keylogger mittels des ConfuserEx v0.4.0 verschleiert.
Abbildung 27: ConfuserEx v0.4.0 GUI
Neben der Auswahl des zur verschleiernden Executables (siehe Abbildung 27) bietet der
ConfuserEx nur die Möglichkeit der Auswahl eines Packers. Wie in Abbildung 28 dargestellt,
lassen sich damit keine detaillierteren Einstellungen wählen.
54
Abbildung 28: Einstellungen des ConfuserEx
Nachdem der Keylogger mit zwei verschiedenen Tools verschleiert wurde, wurden alle 3
ausführbaren Dateien durch die verschiedenen Virenscanner gejagt. Hier das Ergebnis:
Avast erkennt bei der Überprüfung des ursprünglichen Keyloggers als auch bei der mittels
„Smart Assembly 6“ durchgeführten Überprüfung eine Bedrohung.
Abbildung 29: Avast-Virenscan des originalen Keyloggers
Abbildung 30: Avast-Virenscan des mit Smart Assembly 6 verschleierten Keyloggers
55
Bei der Überprüfung des mit ConfuserEx-verschleierten Executables kann Avast jedoch
keine Bedrohung feststellen.
Abbildung 31: Avast-Virenscan des mit ConfuserEx verschleierten Keyloggers
AVG AntiVirus hingegen stuft sowohl den die ursprüngliche als auch beide verschleierten
Varianten als Bedrohung ein.
Abbildung 32: AVG-Virenscan des originalen Keyloggers
Abbildung 33: AVG-Virenscan des mit Smart Assembly 6 verschleierten Keyloggers
56
Abbildung 34: AVG-Virenscan des mit ConfuserEx verschleierten Keyloggers
Im Gegensatz dazu erkennen weder die Anti-Viren-Lösungen von Avira noch Kaspersky eine
Bedrohung hinter dem verschleierten Keylogger-Varianten. Nur die ursprüngliche
Executable-Version wird als Bedrohung erkannt.
Abbildung 35 & 36: Avira-Scan des originalen (li.) und des mit Smart Assembly 6 verschleierten (re.) Keyloggers
Abbildung 37: Avira-Virenscan des mit ConfuserEx verschleierten Keyloggers
57
Abbildung 38: Kaspersky-Virenscan des originalen Keyloggers
Abbildung 39: Kaspersky-Virenscan des Smart Assembly 6 Keyloggers
Abbildung 40: Kaspersky-Virenscan des ConfuserEx Keyloggers
Bei der Überprüfung mittels virustotal.com wird der originale Keylogger bei 29 von 56
Virenscannern zumindest als Bedrohung erkannt. Bei den meisten Scans wird auch richtig
erkannt, um welche Art der Bedrohung es sich handelt. (siehe Abbildung 41)
58
Abbildung 41: Virustotal-Virenscan des originalen Keyloggers
Nach der Verschleierung mittels „Smart Assembly 6“ wird der Keylogger nur noch von 9
Virenscannern als Bedrohung eingestuft. Allerdings wird auch nicht mehr erkannt, um welche
Bedrohung es sich genau handelt. (siehe Abbildung 42)
Abbildung 42: Virustotal-Virenscan des mit Smart Assembly 6 veschleierten Keyloggers
59
Ein ähnliches Bild erkennt man in der Abbildung 43 bei der Überprüfung der mittels
ConfuserEx-verschleierten Variante des Keyloggers.
Abbildung 43: Virustotal-Virenscan des mit ConfuserEx verschleierten Keyloggers
3.3 Ergebnisse
Grundsätzlich ermöglichen sowohl die Verwendung von Cryptern/Packern als auch von
Obfuscation Tools die Möglichkeit den Inhalt zu verbergen und eine Analyse zu erschweren.
Die Detektionsrate beider Techniken ist dabei abhängig vom verwendeten Produkt als auch
von der eingesetzten Anti-Viren-Software. Ob eine verschleierte Anwendung als Bedrohung
eingestuft wird oder nicht hängt davon ab, wie die Anti-Viren-Software gepackte
Anwendungen behandelt. Eine detailliertere Analyse welcher Typ oder noch genauer welche
Anwendung gepackt wurde ist meist nicht umgesetzt.
Der Zeitaufwand um solche Tools einzusetzen ist sehr gering. Den meisten Aufwand hat
man mit der Suche nach einer entsprechenden Lösung und einer eventuellen
Einrichtungszeit. Sobald man diese Initialarbeiten erledigt hat und weiß welche Tools sich für
welche Anwendungsgebiete am besten eignen, beschränkt sich der Zeitaufwand auf einige
wenige Mausklicks.
Die Schwierigkeit bei der Verwendung der Tools hängt stark vom Umfang der
mitgebrauchten Funktionen ab. Packer und Crypter lassen sich beispielsweise kinderleicht
bedienen. Dabei müssen meist nur eine Eingabedatei, eine Ausgabedatei und einige wenige
Parameter gewählt werden, um bereits ansehnliche Ergebnisse zu gewinnen. Will man
spezielle Java oder .Net Funktionalitäten verschleiern oder zusätzliche Features nutzen, ist
eine gewisse Basis nötig.
60
4 Gegenmaßnahmen
Bevor auf die Verteidigungsmechanismen eingegangen wird, soll zuerst noch erläutert
werden wie sich Malware heutzutage hauptsächlich verbreitet und wie gut neue Malware von
Antivirus Programmen erkannt werden kann.
4.1 Verbreitung von Malware
Basierend auf dem Paper „The modern Malware Review“ des Unternehmens Palo Alto
Networks aus dem Jahre 2013 [51], bei dem 68.047 Malware Samples (die direkt von
Firewalls von Unternehmen stammen) untersucht wurden, ging hervor, dass 68% der
Malware über Web-Browsing und 25% der Malware über Email übertragen werden. Von
allen Malware Samples, die bei den Unternehmensfirewalls aufschlugen, wurden rund 40%
(26.363 Samples) nicht von den 6 führenden Antivirus erkannt. Auffallend dabei ist, dass
90% von diesen 26.363 nicht erkannten Malware Samples über Web-Browsing übertragen
wurden, während jedoch nur 2% der unerkannten Samples von Emails stammen.
Abbildung 44: Malware Verbreitungsmethoden und zugehörige Erkennungsraten von AVs [51]
Und noch ein weiterer signifikanter Unterschied zwischen Web-Browsing und Email
Infektionen wird in dem Paper dargelegt: Die, von den 6 führenden AVs unentdeckten
Samples, wurden einen Monat lang täglich neu von den Scan Engines der AVs gescannt um
festzustellen wie lange es dauert bis die Samples von der Antivirussoftware erkannt werden.
Dabei wurde festgestellt, dass Malware, die sich per Email verbreitet im Durchschnitt
innerhalb von 5 Tagen erkannt wird, während Malware, die sich anderweitig verbreitet (Web
Browsing, Web Applikationen, File Sharing, …) im Durchschnitt 20 Tage lang unentdeckt
bleibt. Dabei gab es aber auch etliche Samples die innerhalb des Testzeitraums, von einem
Monat, gar nicht von den AVs erkannt wurde.
Erklären lässt sich der Unterschied bei den Detektionsraten zwischen den beiden
Infektionsmethoden Web-basiert und Email-basiert folgend:
61
1. Web-Browsing und Web-basierte Applikationen sind Echtzeit-Anwendungen,
während es bei Emails meist keinen Unterschied macht ob die Mails innerhalb von
einer Sekunde oder einer halben Minute vom Webserver zum Empfänger
weitergeleitet werden. Das heißt also während bei Mails am Server dem AVProgrammen genügend Zeit bleibt um die einzelnen Dateien zu analysieren, müssen
bei Web-basierden Anwendungen die Detektion und Entscheidungen innerhalb
kürzester Zeit von statten gehen.
2. Der zweite und schwerwiegendere Grund ist, dass sich Malware, die über Webbasierte Anwendungen verteilt wird, die sich serverseitige Polymorphie zu Nutze
machen kann. Das heißt einfach, dass der Server die Malware automatisiert abändert
(durch Packer, andere Verschlüsselungsparameter, Obfuscation), sodass jede
Malware-Instanz wirkt als wäre sie einzigartig. Dadurch werden viele
verschiedenartige Malware-Samples erstellt, was die Wahrscheinlichkeit deutlich
verringert, dass ein Sample von einem AV-Hersteller eingefangen wird und dieser
eine Signatur vom dem Sample erstellen kann um seine Kunden zu schützen.
Untersucht wurde weiters aus welchen Quellen die Malware stammt, die am längsten
unbekannt bleibt und am zielgerichtetsten ist. Dabei vielen vor alle Filesharing Webseiten,
wie 4shared, dropbox, netload, rapdishare, ... und Social Media, wie facebook, instagram,
teachertube, … auf, aber auch das File Transfer Protocol ist in dieser Kategorie stark
vertreten. So wurden 94% aller FTP-Samples nur ein einziges Mal eingefangen und 95% der
FTP-Samples wurden nicht von den AV-Programmen erkannt. Es scheint also als würde
FTP intensiv für sogenannte „high sophisticated attacks“, also hoch komplexe und
zielgerichtete Angriffe auf Unternehmen (z.B. zur Industriespionage), verwendet werden.
Abbildung 45: Zeitraum, wie lange Malware unentdeckt bleibt, aufgeschlüsselt auf die Infektionsquellen [51]
62
4.2 Verteidigungsmaßnahmen
Die Verteidigungsmaßnahmen gegen herkömmliche Malware und zielgerichtete (Industrie-)
Spionage (Advanced Persistent Threat, APT) können unterteilt in präventive Maßnahmen
und solchen zur nachträglichen Detektion. Dabei wirken vor allem Anti-Exploit Techniken als
präventive Maßnahmen als äußert interessant. Nachfolgende Sicherheitsmaßnahmen
wurden durch ein Brain-Storming der Autoren erhoben und um die Vorschläge aus dem „The
modern Malware Review“ [51] erweitert (diese sind gekennzeichnet).
Präventiv
 Antivirus (AV)
Obwohl in dieser Arbeit gezeigt wurde wie einfach es ist verschiedene AV-Scanner
auszutricksen und erwähnt wurde, dass rund 40% der sich im Umlauf befindlichen
(neuen) Malware nicht erkannt wird, stellt ein Antivirus einen Basisschutz dar und
sollte auf jedem Rechner installiert sein. Mit der Auswahl des besten Antivirus
beschäftigen sich mehrere Webseiten (zB. http://www.av-test.org/), wobei sehr oft ein
Kompromiss aus Geschwindigkeit und Detektionsrate getroffen werden muss.
Für Unternehmen ist es wiederum wichtig, dass die AV-Software von zentraler Stelle
aus gesteuert und mit Updates der Virendatenbanken versorgt werden kann. Weiters
soll es den Mitarbeitern nicht möglich sein können den Antivirus deaktivieren zu
können.
 Firewalls und Intrusion Prevention Systeme (IPS)
Auch eine Firewall gehört ähnlich wie das Antivirus zum präventiven Basisschutz
eines Unternehmens. Welche Firewall(s) und Firewall-Architektur auch immer
verwendet werden, wichtig ist, dass die Konfiguration von Experten vorgenommen
und regelmäßig überprüft wird.
Mit einem IPS kann zusätzlich der Netzwerk-Traffic auf verdächtiges Verhalten hin
untersucht werden und kann bei einer Detektion den verdächtigen Datenstrom
blockieren. Die Erkennung erfolgt dabei signaturbasiert, mittels Detektion von
statistischen Anomalien (zB. wenn plötzlich ein neues Protokoll im Netzwerk
verwendet wird) und mittels zustandsbehafteter Analyse von Protokollen.
Die Autoren empfehlen auf jeden Fall auch eine Next Generation Firewall zu
verwenden (Applikationsfilter mit Deep Packet Inspection und IPS integriert) um
erkennen zu können ob ein Protokoll und freigegebener Port (zB. 80, 443, …) von
einer Malware für bösartige Zwecke missbraucht wird.
 Anti-Exploit Techniken
Wie schon behandelt geschehen die häufigsten Infektionen entweder über Emails
oder über Web Browsing. Damit die Infektion jedoch wirklich von statten geht, muss
63
der Schadcode erst ausgeführt werden. Das heißt, dem Opfer einfach eine Exe- oder
Jar-Datei zu senden reicht nicht aus um seinen Rechner schon zu infizieren. Der
Empfänger muss erst die ausführbare starten damit der Schadcode seine Wirkung
entfalten kann. Dasselbe gilt natürlich auch für ausführbare Dateien aus dem Internet.
Als Gegenmaßnahmen werden ausführbare Dateien meist von einem Anhangfilter
des Mailservers aus den Emails entfernt. Weiters wissen die meisten Mitarbeiter,
dass sie eine Exe-Datei, die sie per Email erhalten oder die einfach beim Öffnen
einer Seite heruntergeladen wird, nicht öffnen sondern löschen sollten. Natürlich
sollten diese von der IT-Abteilung des Unternehmens auch entsprechend geschult
werden.
Eine Möglichkeit wäre nun zu versuchen den Benutzer zu täuschen. Das kann
einerseits dadurch gemacht werden, dass der ausführbaren Datei besondere Namen
gegeben werden, wie „Geheime Dokumente“ oder „AngryBirdsForPC“, die zur
Ausführung verleiten sollen, oder andererseits durch Trojaner. Ein Mitarbeiter sucht
zum Beispiel nach einem PDF-To-Word Konverter und wird im Internet auf einer
vertrauenswürdig aussehenden Seite fündig. Er lädt sich diesen herunter, installiert
diesen (dafür werden natürlich Admin-Rechte angefordert ) und verwendet ihn.
Dieser funktioniert zwar einwandfrei, was er aber nicht mitbekommt ist, dass im
Hintergrund sich schon eine Malware auf seinem PC eingenistet hat.
Die dritte Möglichkeit sind Exploits. Diese wurden bereits ausführlich in diesem
Dokument behandelt. Der Vorteil dabei ist, dass die Malware nicht in einer
ausführbaren Datei implementiert ist, sondern sich in einer unscheinbaren Datei
(PDF, Word, Excel, HTML, Flash, …) verstecken kann. Dabei ist es sehr oft nicht
einmal notwendig, dass der Benutzer die Datei aktiv öffnet. Hat dieser zum Beispiel
den Flash Player aktiviert und dieser hat eine ungepatchte Vulnerabilität und er surft
eine präparierte Webseite an, so kann diese ein verstecktes Flash-Video abspielen
und die Schwachstelle ausnutzen ohne dass der User überhaupt mitbekommt das die
Webseite seinen Flash-Player verwendet hat. Und laut der bereits in Kapitel 2.1
erwähnten Studie von Malwarebytes [18], basieren heutzutage bereits 90% aller
Angriffe auf Exploits. Das Problem dabei: Antivirus-Programme können meist erst
dann eingreifen, wenn eine Schachstelle in einem Programm bereits ausgenutzt
wurde und der Exploit Payload (also die Malware) auf den Computer übertragen
wurde. Aus diesem Grund gibt es sogenannte Anti-Exploit Programme, die
versprechen, dass Schwachstellen in Programmen (wie zB. ein Buffer-Overflow) von
Exploits nicht mehr ausgenützt werden können. Dabei gibt es mehrere verschiedene
Programme, die verschiedene Techniken verwenden:
 Microsoft’s Enhanced Mitigation Experience Toolkit (EMET)
Verwendet verschiedene Techniken, wie DEP, ASLR, SEHOP, HeapSpray,
Null page Allocations, EAF, Basic ROP mitigations um es Exploits schwerer
zu machen stabil auf mehreren, verschiedenen System zu laufen.
64
Abbildung 46: GUI von MS EMET
Die Features von EMET müssen explizit für jedes gewünschte Programm
aktiviert werden. Dabei gestaltet sich die Verwendung des Tools als sehr
einfach und intuitiv. Um einen Prozess zu schützen muss man einfach nur
einen Rechtsklick auf diesen machen und auf „Configure Process“ klicken.
Per Default werden dann gleich alle möglichen Schutzmechanismen für den
Prozess aktiviert (nach Neustart des Systems):
65
Abbildung 47: App – Sicherheitsmechanismus – Matrix von EMET
Obendrauf ist EMET auch noch kostenlos verfügbar.
Doch EMET hat auch ein paar Schwachstellen:


Kein Schutz mehr wenn diese Techniken umgangen werden können.

Kein Schutz gegen Java Exploits (Sandbox Escape)

Techniken sind zu generisch

Bypass ist unter Umständen möglich

Konflikte mit älteren Applikationen
Invincea
o
Verwundbare und fehlanfällige Programme laufen in einer Sandbox


Exploits können am Zielsystem keinen Schaden anrichten
Bei einer Infektion wird einfach der Container beendet und damit auch
der Exploit-Payload
Benutzer müssen sich daran gewöhnen und geschult werden wie sie
mit dem Browser umzugehen haben



Teuer (mehr als 45$ pro Benutzer)
Malwarebytes ANTI Exploit
Verwendet eine 3-Schichten Architektur:
 Layer3: Applikationsverhalten & Applikationsüberwachung
 Layer2: Malicious Memory Blocker  Verhindert Payload-Ausführung am
Heap, Stack
 Layer1: OS Bypass Protection Ähnlich wie EMET + zusätzliche Techniken
66







Austausch zwischen den Layern
Schutz gegen APTs
Proaktive Techniken, kein Whitelisting, Sandboxing, Signaturen, VMs
Nur 3MB groß und kompatibel mit alten Betriebssystemen
Keine Benutzerinteraktion bzw. Management notwendig
Kann alle möglichen Applikationen schützen
Auch als Free-Edition für alle Browser + Add-ons und Java erhältlich
In diesem Test [52] von PC Security Labs vom August 2014 kann verglichen werden
wie MS EMET und Malwarebytes Anti Exploit in Vergleich zu den Top-Virenscannern
bei der Erkennung und dem Schutz vor Exploit abgeschnitten haben. Dabei konnte
das Tool Anti Exploit Premium als Testsieger beachtliche 93,1% aller Exploits
erkennen und eine Infektion verhindern. Doch auch Norton Internet Security (81%),
MS EMET (74,1%), Kaspersky Internet Security (72,4%), avast! Internet Security
(72,4%) und ESET Smart Security (70,7%) erreichten noch gute Ergebnisse.
Zusammengefasst kann gesagt werden, dass Anti-Exploit Tools eine sehr gute
Gegenmaßnahme gegen Exploits und somit gegen eine Malware-Infektion darstellen.
Auch die Antivirus-Hersteller wie Kaspersky und Norton haben in ihren Internet
Security Produkten bereits Anti-Exploit Techniken integriert. Diese können
zusammen mit dem Antivirus erworben werden und stellen somit einen guten
Basisschutz dar. Nachteilig an dem Konzept ist, dass eine solche Software einen
zusätzlichen Layer einführt, der in die Trusted Computing Base mitaufgenommen
werden muss, die Komplexität des Systems weiter erhöht und eine weitere
Angriffsmöglichkeit darstellt, falls sich Fehler bei der Erstellung des Anti-ExploitToolkits eingeschlichen haben.
 Zentrale Softwareverwaltung, Software Updates und deaktivieren/deinstallieren
von fehlerbehafteter Software
Mitarbeiter im Unternehmen sollten sich nicht nach Belieben Software herunterladen
und installieren können. Die verwendeten Programme sollten zuerst von den ITExperten eingehend geprüft werden auf bekannte Schwachstellen oder zusätzliche
Schädliche Funktionalitäten (Trojaner). Nach der Prüfung eines Programms wird
dieses den Mitarbeitern über ein sogenanntes Software Deployment Tool zur
Verfügung gestellt. Über dieses Tool kann die IT-Abteilung dann weiters regelmäßige
Updates der verwendeten Software auf allen Rechnern einspielen und Software, die
als unsicher gilt deaktivieren bzw. deinstallieren. So könnte zum Beispiel der Adobe
Flash Player vorübergehend deaktiviert werden, wenn wieder einmal ein (oder
mehrere) Zero Day Exploits für diesen gefunden werden.
Eine besondere Gefahr stellt Software dar, die von Mitarbeitern des Unternehmens
selbst programmiert wurde und den anderen Mitarbeitern auf Unternehmensservern
67
zur Verfügung gestellt wird. Diese umgeht damit die Software Deployment Lösung
und die IT-Abteilung weiß oftmals nicht einmal, welches verschiedenen selbst
geschriebenen Programme auf den Rechnern der Mitarbeiter installiert sind. Das
Problem dabei ist, dass diese Software oft nicht mit Bedacht auf Sicherheitsaspekte
programmiert und nur nebenbei und mit möglichst wenig Aufwand (als Prototyp)
erstellt wurde. Auch Updates können keine erwartet werden. Dient die Software dazu
um auf Datenbanken zuzugreifen, so müssen Mitarbeiter oft ihre Credentials dem
Tool zur Verfügung stellen, wobei niemand Einblick hat was genau die Software mit
den Passwörtern macht (zum Beispiel in Plaintext irgendwo ablegen). Weiters
können Fehler in der Software zu schwerwiegenden Konsequenzen führen, wenn
zum Beispiel wichtige Datensätze unbeabsichtigter Weise gelöscht werden.
Aus diesen Gründen sollte unternehmensintern programmierte Software auch immer
mit der IT Abteilung abgestimmt werden und ebenfalls über das zentrale Software
Deployment Tool verteilt werden.
Eine weitere gute Möglichkeit ist es den Mitarbeitern Zugriff auf virtuelle Maschinen
zu geben, die auf Unternehmensservern gehostet werden (zB: Citrix XenDesktop)
und alle benötigten Programme bereits installiert haben. Auf diese Art und Weise
kann auch sichergestellt werden, dass geheime Dokumente nicht auf Laptops landen,
sondern in den virtuellen Maschinen am Unternehmensserver. Auch der externe
Zugriff über eine mobile Internetverbindung und ein VPN können somit perfomanter
sein, da die Daten nicht auf den Laptop heruntergeladen werden müssen und der
Laptop nur als graphische Oberfläche dient.
 Verwenden von VPNs
Firmen-Notebooks sollten sich mit dem Internet nur über ein verschlüsseltes VPN
verbinden können. Dadurch wird sichergestellt, dass der gesamte Internet-Traffic für
Dritte nicht einsehbar über Unternehmens-Server läuft und der Traffic wiederum von
IDS, IPS, Next-Generation Firewalls und weiterer Sicherheitssoftware geprüft werden
kann.
 Rechte Einschränkungen
Jeder Mitarbeiter sollte ein Benutzerkonto ohne Administrator-Rechte besitzen.
Dadurch wird verhindert, dass Malware bei einer Infektion sofort Admin-Rechte hat.
Wie schon im vorherigen Punkt erwähnt sollte Software automatisiert über eine
Software Deployment Lösung (zB: WPKG) installiert und upgedatet werden, welches
auf jeden Rechner Systemrechte besitzt. Es gibt auch die Möglichkeit bestimmten
Benutzern temporär (zum Beispiel für eine Stunde) Administratorrechte zu
gewährleisten.
68
Weiters sollte sich ein Mitarbeiter natürlich nicht nach Belieben im
Unternehmensnetzwerk „bewegen“ können und auf jeden Server im Netzwerk Zugriff
haben.
Auch das Recht Dateien auf einem Computer im Netzwerk freizugeben sollte nicht
erlaubt werden. Dies ist vor allem kritisch, wenn Mitarbeiter sich mit externe WLANs
verbinden.
Oft kommt es auch vor, dass bei Rechnern, die von mehreren Benutzern gemeinsam
verwendet werden (zum Beispiel in einem Labor oder auf speziellen Testrechnern)
von den Mitarbeitern ein „Gemeinschaftskonto“ angefordert wird, bei dem jeder
Mitarbeiter die Credentials kennt und somit problemlos die Session eines anderen
übernehmen kann. Hintergrund dafür ist oft einfach nur Bequemlichkeit, da es zum
Beispiel vorkommt, dass mehrere Personen abwechselnd denselben Rechner
verwenden müssen oder jemand sich schlichtweg vergisst aus zu loggen. Da
dadurch jedoch jegliche Möglichkeit verloren geht nachzuvollziehen welcher
Mitarbeiter was im Netzwerk gemacht hat sollte dies strikt untersagt werden. So
könnten solche Benutzerkonten und Rechner zum Beispiel Ausgangspunkt für interne
Angriffe sein oder dazu dienen per Key-Logger die Credentials anderer Mitarbeiter zu
sammeln, wenn diese sich zum Beispiel auf Datenbanken oder auf Webseiten
einloggen.
 URL und Content Blocking
Wie schon im vorherigen Kapitel erläutert, ist die Nummer 1 Infektionsquelle das
Web-Browsing.

Blockieren von Webseiten, die bekannt dafür sind, dass Malware über diese
verteilt wird, wie zum Beispiel File-Sharing Webseiten, Pornographische
Webseiten, Hacking Webseiten, …

Blockieren des Downloads von ausführbaren Dateien

Blockieren des Senden und Empfangen von ausführbaren Dateien in Emails
 Zugriffsrechte auf unbekannte, neu registrierte und dynamische DNS Domänen
einschränken [51]
Laut [51] verbinden sich 33% der Malware Samples entweder zu einer neu
registrierten Domäne oder verwenden dynamisches DNS oder Fast Flux. Aus diesem
Grund sollte für solche Domänen härtere Sicherheitskontrollen und Zugriffsrechte
gesetzt werden, wie zum Beispiel das Verbieten des Downloads von ausführbaren
Dateien, blockieren von HTTP-Post-Requests oder das Entschlüsseln von SSL
Traffic um diesen inspizieren zu können.
69
 Email Traffic nur auf den Unternehmens Email-Server erlauben [51]
Laut [51] verwenden 20% der Malware Samples direkte Email-Verbindungen über
das Netzwerk ohne einen Mailserver zu verwenden (siehe zum Beispiel das Tool
„sendMail“). Aus diesem Grund sollten die Firewall-Policies so eingestellt sein, dass
die Email-Protokolle nur von und zum Email-Server übermittelt werden dürfen und
der direkte Email-Verkehr mit dem Internet blockiert wird.
 Kontrollen für Web-Applikationen mit denen Dateien übertragen werden können
[51]
Unternehmen sollten die möglichen Angriffspunkte mit Hilfe von Benutzer- und
Applikationskontrollen möglichst gering halten. So sind beispielsweise Http-Proxies
gängige Quellen für Malware. Es sollte also sichergestellt werden, dass nur die
Unternehmens-Proxy-Server von den Benutzern verwendet werden können und nicht
eigene Web-Proxies mit denen die Sicherheitsrichtlinien des Unternehmens
umgangen werden können. Bei Social Media können zum Beispiel die
Dateiübertragungsmechanismen stark eingeschränkt werden, damit Malware über
diese Quellen nicht so einfach ins Firmennetzwerk gelangen kann.
 Mitarbeiter sensibilisieren und Ausgabe von Security-Richtlinien
Mitarbeiter, egal welcher Art (mit technischem Hintergrund, aus dem Management, IT
Neuling, …) sind die Benutzer des Systems und damit meist auch der Grund, dass
Malware überhaupt den Weg ins Unternehmensnetzwerk schafft. Aus diesem Grund
gehören Mitarbeiter geschult und sensibilisiert auf die möglichen IT Bedrohungen
inklusive Social Engineering. Den Autoren gefällt die Idee gut, einer zentralen,
unternehmensinternen Webseite, auf der Security-Richtlinien und Verhaltensweisen
in verdächtigen Situationen beschrieben werden und fürs Unternehmen wichtige
Security-News von den Sicherheitsexperten im Unternehmen gepostet werden.
Weiters sollte es die Möglichkeit eines öffentlichen Pinboards geben, auf der
Mitarbeiter Fragen hinterlassen können und alle anderen Besucher der Seite die
entsprechenden Antworten zu sehen bekommen.
Zu den Sicherheitsrichtlinien können zum Beispiel folgende Punkte gehören:

Kein verwenden von (unbekannten) USB-Geräten

Sichere Passwörter (zB. Anfangsbuchstaben eines Satzes mit mehr als 10
Worten) verwenden und diese nirgendwo aufschreiben

Kein Öffnen eines unbekannten Email-Anhangs

Kein Surfen auf verdächtigen Webseiten – Aufklärung was verdächtige
Webseiten sind

Kein Download von ausführbaren Programmen (jar, exe, com, bat, …)

Computer immer Sperren, wenn nicht am Platz

Laptops am Abend versperren und nicht im Fahrzeug sichtbar liegen lassen
70
Detektion
 Verwenden von Anti-Malware-Technologien im Netzwerk [51]
Bisher wurden Anti-Malware-Technologien vorwiegend am Desktop eingesetzt. Da
durch die Verlagerung der Infektionsmethoden auf Web-basierte Anwendungen,
Echtzeit-anforderungen an die Detektion von Malware hinzukommen, müssen neue
Ansätze gefunden werden um Malware schneller zu erkennen und zu blockieren.
Dies kann zentral auf Servern auf Netzwerk-Ebene gemacht werden. NextGeneration Firewalls und Intrusion Detection Systeme (IDS) gehören zu dieser
Kategorie.
 Erstellen und ständiges überarbeiten einer soliden Ausgangsbasis (Referenz)
[51]
Sehr oft zeigt Malware ein anormales Verhalten. Dieses kann als Referenz verwendet
werden um neuartige und unerkannte Malware im Netzwerk sehr schnell als solche
zu identifizieren.
 Untersuchen und beseitigen von „unknown Traffic“ [51]
Einer der größten Gemeinsamkeiten von verschiedener Malware ist die Verwendung
von „customized“ oder „unknown“ Traffic. So werden sehr häufig „well-known“ Ports
und Protokolle für die Schadprogramm-Zwecke angepasst (zB. http, DNS, Instant
Messaging und Remote Desktop Protokolle, usw.). Mit Hilfe einer Next-Generation
Firewall kann ein solcher angepasster oder unbekannter Traffic relativ einfach
identifiziert werden. Schon beim Erstellen der Ausgangsbasis im Netzwerk, sollte
jeglicher unbekannter oder angepasster Traffic identifiziert und analysiert werden. Auf
diese Art und Weise kann neuer unbekannter Netzwerk-Traffic sehr schnell analysiert
und neue Malware identifiziert werden.
 Für Antivirus unbekannte Malware erwarten und identifizieren [51]
Durch Methoden wie serverseitige Polymorphie gibt es immer häufiger MalwareSamples die von Antivirus-Programmen nicht erkannt werden können. Um
festzustellen ob unbekannte Dateien bösartiger Natur sind müssen diese in einer
gesicherten Umgebung ausgeführt und die eventuell implementierte Wartezeit der
Malware abgewartet werden. Es wird an dieser Stelle ein automatischer
Mechanismus gebraucht, der in große Netzwerke implementiert werden kann um
festzustellen ob sich die Datei schädlich verhält.
71
5 Zusammenfassung
In dieser Arbeit wurden verschiedene Code Obfuscation Techniken wie Komprimierung,
Verschlüsselung, Virtualisierung, Data Obfuscation und Control Flow Obfuscation gezeigt
und erläutert. Basierend darauf wurde darauf eingegangen welche dieser Techniken sich
moderne Malware zu Nutze macht und wie Antivirus-Programme versuchen trotz der
Verschleierungstechniken Viren zu erkennen. Für die Autoren war dabei erschreckend, dass
Techniken, wie Polymorphie und Metamorphie eigentlich schon in den frühen 90er Jahren
von Malware eingesetzt wurden und aktuell (Jänner 2015) noch immer verwendet werden
können um AV-Programme auszutricksen.
Diese theoretische Recherche wurde im Proof of Concept überprüft, indem zwei
verschiedene Malware-Programme mit Hilfe von frei verfügbaren Obfuscation Tools
verschleiert und einer anschließenden Antivirus-Prüfung unterzogen wurden. Das Ergebnis
war dabei, aus Sicht eines böswilligen Angreifers, gut. Denn die Verschleierungstechniken
konnten einfach mittels weniger Mausklicks ausgeführt werden und zeigten eine gute
Wirkung gegen die meisten AV-Programme. Bestätigt wird dies umso mehr durch diverse
Studien (wie zum Beispiel in [51]), aus denen hervorgeht, dass 40% der sich im Umlauf
befindlichen Malware Samples nicht von den 6 Top AV-Programmen erkannt werden (weder
durch Signaturen noch durch Heuristiken) und es um die 20 Tage dauert bis diese Malware
Samples dann endlich detektiert werden können (sofern die Anzahl der infizierten Hosts groß
genug ist). Für die Autoren ist diese Tatsache vor allem in Bezug auf gezielte Angriffe auf
einzelne Unternehmen (Industriespionage) kritisch. Denn da anscheinend die AV-Heuristiken
Malware nicht sehr gut erkennen können und AV-Signaturen nur effektiv sind, wenn das
spezifische Malware-Sample vom AV-Hersteller eingefangen wird, sind Antivirus-Programme
gegen gezielte Angriffe machtlos. Der Angreifer muss nur eine bereits bekannte Malware
bzw. ein Exploit Kit hernehmen, diese mit frei verfügbaren Tools verschleiern und die
Malware entweder über einen Exploit, Email, USB-Stick oder sonstigen Weg auf einen
Firmenrechner bringen. Da es sich bei der verschleierter Malware um ein Einzelstück handelt
ist die Wahrscheinlichkeit einer Erkennung mittels einem AV-Programm gleich Null. Von dem
infizierten Rechner aus, können dann weitere Angriffe gegen die unternehmensinterne
Infrastruktur (z.B. Portscan) durchgeführt werden.
Um zu zeigen, dass es durchaus möglich ist erfolgreich gezielte Angriffe abzuwehren,
wurden abschließend mehrere präventive als auch erkennende Maßnahmen angeführt.
Diese verdeutlichen, auf welche vielsichtige Art und Weise sich Unternehmen vor Angriffen
schützen müssen um ein akzeptables Level an IT-Sicherheit gewährleisten zu können. Ob
diese Maßnahmen wirksam vor Industriespionage schützen, hängt letztendlich von den
ausführenden und kontrollierenden IT-Experten und den Mitarbeitern des Unternehmens ab.
Denn der Mensch und sein Streben nach Einfachheit und Komfort ist und bleibt für die
Autoren die größte Schwachstelle im Punkto IT-Sicherheit.
72
6 Future Work
Während in dieser Arbeit stark der Fokus auf Code Obfuscation gelegt wurde, sollen in der
nächsten Arbeit (im 2. Semester des Masterstudiengangs Informationsmanagement und
Computersicherheit) Exploit Generatoren wie zum Beispiel Angler EK, Styx Ek, RIG Ek,
Magnitude Ek, usw. in Vordergrund stehen. Diese könnten mit Bezug auf Funktionalität und
Effektivität miteinander verglichen werden.
Vorschlag der Autoren wäre es, als praktischen Teil eine Webseite zu hosten (eventuell
offline ), die einen solchen Exploit Generator nutzt um in Rechner einzudringen und
bösartige Software darauf zu installieren. Dabei soll die Malware zuvor mit Hilfe von
serverseitiger Polymorphie oder serverseitiger Metamorphie verschleiert werden, sodass
jeder Besucher der Webseite mit einer individuellen Instanz der Malware infiziert wird.
73
Literaturverzeichnis
[1] „Wikipedia (Exploits),“ Wikimedia Foundation Inc, [Online]. Available:
https://de.wikipedia.org/wiki/Exploit. [Zugriff am 20 12 2014].
[2] „people4.net,“ people4.net GmbH, [Online]. Available: http://www.people4.net/was-bedeutetder-begriff-exploit. [Zugriff am 20 12 2014].
[3] C. Evans, „Project Zero,“ Google, 15 07 2014. [Online]. Available:
http://googleonlinesecurity.blogspot.co.at/2014/07/announcing-project-zero.html. [Zugriff am
20 12 2014].
[4] R. Eikenberg, „Heise Security,“ Heise Zeitschriften Verlag GmbH & Co. KG, 04 06 2013.
[Online]. Available: http://www.heise.de/security/meldung/Google-Forscher-veroeffentlichtZero-Day-Exploit-fuer-Windows-1875749.html. [Zugriff am 27 12 2014].
[5] R. Eikenberg, „Heise Security,“ 13 5 2013. [Online]. Available:
http://www.heise.de/security/meldung/Google-verkuerzt-Schonfrist-fuer-Herstellerverwundbarer-Software-1873727.html. [Zugriff am 15 12 2014].
[6] „Wikipedia (Responsible Disclosure),“ [Online]. Available:
https://en.wikipedia.org/wiki/Responsible_disclosure. [Zugriff am 15 12 27].
[7] B. Fung, „The Washington Post,“ 31 August 2013. [Online]. Available:
http://www.washingtonpost.com/blogs/the-switch/wp/2013/08/31/the-nsa-hacks-othercountries-by-buying-millions-of-dollars-worth-of-computer-vulnerabilities/. [Zugriff am 20 12
2014].
[8] A. Meister, „Netzpolitik,“ 15 Dezember 2014. [Online]. Available:
https://netzpolitik.org/2014/vupen-threat-protection-wir-veroeffentlichen-den-vertrag-mit-demdas-bsi-sicherheitsluecken-und-exploits-kauft/. [Zugriff am 21 Dezember 2014].
[9] „Der Spiegel,“ 09 November 2014. [Online]. Available:
http://www.spiegel.de/spiegel/vorab/bnd-will-informationen-ueber-softwaresicherheitsluecken-einkaufen-a-1001771.html. [Zugriff am 27 Dezember 2014].
[10] B. M. C. G. &. J. S.-R. Morgan Marquis-Boire, „CitizenLab,“ 30 April 2013. [Online]. Available:
https://citizenlab.org/2013/04/for-their-eyes-only-2/. [Zugriff am 20 Dezember 2014].
[11] „Twitter,“ 08 August 2014. [Online]. Available: https://twitter.com/gammagrouppr. [Zugriff am
22 Dezember 2014].
74
[12] „Wikileaks,“ 15 September 2014. [Online]. Available: https://wikileaks.org/spyfiles4/index.html.
[Zugriff am 22 Dezember 2014].
[13] A. Meister, „Netzpolitik,“ 05 August 2014. [Online]. Available:
https://netzpolitik.org/2014/gamma-finfisher-twitter-account-veroeffentlicht-interne-dokumenteueber-weltweit-eingesetzten-staatstrojaner/. [Zugriff am 22 Dezember 2014].
[14] A. Meister, „Netzpolitik,“ 06 August 2014. [Online]. Available:
https://netzpolitik.org/2014/gamma-finfisher-gehackt-werbe-videos-von-exploits-und-quelltextvon-finfly-web-veroeffentlicht/. [Zugriff am 22 Dezember 2014].
[15] C. Team, „Corelan Team,“ 19 Juli 2009. [Online]. Available:
https://www.corelan.be/index.php/2009/07/19/exploit-writing-tutorial-part-1-stack-basedoverflows/. [Zugriff am 25 Dezember 2014].
[16] D. Hoelzer, „Cyber Defense,“ [Online]. Available: http://www.cyberdefense.org/Blog/files/e6fb7327cb615688f90fc07656a3880d-28.html. [Zugriff am 25
Dezember 2014].
[17] O. Security, „Offensive Security - Metasploid Unleashed,“ 2014. [Online]. Available:
http://www.offensive-security.com/metasploit-unleashed/Main_Page. [Zugriff am 25
Dezember 2014].
[18] „Youtube (Malware Bytes Webinar),“ 4 August 2014. [Online]. Available:
https://www.youtube.com/watch?v=fRxRp2x_jNU. [Zugriff am 30 Jänner 2015].
[19] „ssware,“ LogicNP Software, [Online]. Available: http://www.ssware.com/articles/protect-andobfuscate-your-dotnet-code-against-reverse-engineering-using-crypto-obfuscator.htm. [Zugriff
am 02 Jänner 2015].
[20] „Wikipedia (Obfuscator),“ [Online]. Available: https://de.wikipedia.org/wiki/Obfuscator. [Zugriff
am 02 Jänner 2015].
[21] „Wikipedia (Obfuscation),“ [Online]. Available: https://en.wikipedia.org/wiki/Obfuscation.
[Zugriff am Jänner 02 2015].
[22] „Wikipedia (Interpreter),“ [Online]. Available: https://de.wikipedia.org/wiki/Interpreter. [Zugriff
am 01 Jänner 2015].
[23] D. Bolton, „About Tech,“ [Online]. Available:
http://cplus.about.com/od/introductiontoprogramming/a/compinterp.htm. [Zugriff am 01 Jänner
2015].
75
[24] „Stunnix,“ [Online]. Available: http://www.stunnix.com/prod/cxxo/newsample.shtml. [Zugriff am
02 Jänner 2015].
[25] „University of Florida,“ [Online]. Available:
https://www.cise.ufl.edu/~manuel/obfuscate/obfuscate.html. [Zugriff am 05 Jänner 2015].
[26] S. Taylor, „Defcon 17 (Binary Obfuscation),“ August 2009. [Online]. Available:
https://www.defcon.org/images/defcon-17/dc-17-presentations/defcon-17-sean_taylorbinary_obfuscation.pdf. [Zugriff am 20 Jänner 2015].
[27] A. Binstock, „Destination.NET,“ 06 März 2003. [Online]. Available:
http://web.archive.org/web/20080420165109/http://www.devx.com/microsoftISV/Article/11351.
[Zugriff am 01 Jänner 2015].
[28] mdownen, „MSDN Blogs,“ Microsoft, 26 Mai 2005. [Online]. Available:
http://blogs.msdn.com/b/clrsecurity/archive/2005/05/26/422440.aspx. [Zugriff am 02 Jänner
2015].
[29] „Wikipedia (Android Lollipop),“ [Online]. Available:
https://en.wikipedia.org/wiki/Android_Lollipop. [Zugriff am 02 Februar 2015].
[30] „Wikipedia (Dalvik),“ [Online]. Available:
https://en.wikipedia.org/wiki/Dalvik_%28software%29. [Zugriff am 02 Februar 2015].
[31] „Wikipedia (Android Runtime),“ [Online]. Available:
https://en.wikipedia.org/wiki/Android_Runtime. [Zugriff am 02 Februar 2015].
[32] „Wikipedia (JavaScript),“ [Online]. Available: https://de.wikipedia.org/wiki/JavaScript. [Zugriff
am 2015 Jänner 26].
[33] „Wikipedia (Minification),“ [Online]. Available:
https://en.wikipedia.org/wiki/Minification_%28programming%29. [Zugriff am Jänner 28 2015].
[34] R. Abrams, „WeLiveSecurity (Packers),“ 27 October 2008. [Online]. Available:
http://www.welivesecurity.com/2008/10/27/an-introduction-to-packers/. [Zugriff am 20 Jänner
2015].
[35] M. M. Tom Brosch, „Black Hat Briefings (Runtime Packers),“ AV-Test GmbH, 2006. [Online].
Available: https://www.blackhat.com/presentations/bh-usa-06/BH-US-06-Morgenstern.pdf.
[Zugriff am 15 Jänner 2015].
[36] R. R. B. Gabriel Negreira Barbosa, „Black Hat USA 2014,“ 2014. [Online]. [Zugriff am 25
76
Jänner 2015].
[37] „Wikipedia (UPX),“ [Online]. Available: https://de.wikipedia.org/wiki/UPX. [Zugriff am 20
Jänner 2015].
[38] Y. G. &. A. Gazet, „metasm (08),“ 2008. [Online]. Available:
http://metasm.cr0.org/docs/sstic08-metasm-jcv.pdf. [Zugriff am 20 Jänner 2015].
[39] Y. G. &. A. Gazet, „metasm (09),“ 2009. [Online]. Available:
http://metasm.cr0.org/docs/sstic09-metasm-jcv.pdf. [Zugriff am 20 Jänner 2015].
[40] „Wikipedia (Schadprogramm),“ [Online]. Available:
https://de.wikipedia.org/wiki/Schadprogramm. [Zugriff am 25 Jänner 2015].
[41] C. Eckert, Oldenbourg Wissenschaftsverlag GmbH, 2013. [Online].
[42] L. Böhne, 28 Jänner 2008. [Online]. Available:
http://2012.hack.lu/archive/2009/PandorasBochs.pdf. [Zugriff am 01 Februar 2015].
[43] W. Chen, „Rapid 7,“ 05 Jänner 2014. [Online]. Available:
https://community.rapid7.com/community/metasploit/blog/2014/01/05/a-cat-and-mouse-gamebetween-exploits-and-antivirus. [Zugriff am 30 Jänner 2015].
[44] „Wikipedia (Oligomorphic Code),“ [Online]. Available:
https://en.wikipedia.org/wiki/Oligomorphic_code. [Zugriff am 30 Jänner 2015].
[45] „Wikipedia (Polymorphic Code),“ [Online]. Available:
https://en.wikipedia.org/wiki/Polymorphic_code. [Zugriff am 25 Jänner 2015].
[46] P. Szor, The art of computer virus research and defence, Symantec Press, 2005.
[47] „Wikipedia (Hidden Markov Model),“ [Online]. Available:
https://de.wikipedia.org/wiki/Hidden_Markov_Model. [Zugriff am 15 Jänner 2015].
[48] „Wikipedia (Metamorphic Code),“ [Online]. Available:
https://en.wikipedia.org/wiki/Metamorphic_code. [Zugriff am 15 Jänner 2015].
[49] D12d0x34X, „INFOSEC Institute,“ [Online]. Available:
http://resources.infosecinstitute.com/anti-debugging-and-anti-vm-techniques-and-antiemulation/. [Zugriff am 06 Februar 2015].
[50] „ITLaw,“ [Online]. Available: http://itlaw.wikia.com/wiki/Virus_obfuscation_techniques. [Zugriff
77
am 01 Jänner 2015].
[51] „Palo Alto Networks,“ 2013. [Online]. Available:
http://media.paloaltonetworks.com/documents/The-Modern-Malware-Review-March-2013.pdf.
[Zugriff am 09 Jänner 2015].
[52] „Malwarebytes Anti Exploit,“ PC SECURITY LABS, August 2014. [Online]. Available:
http://static-cdn.malwarebytes.org/assets/datasheets/2015-02-06/RCEMitigations.pdf. [Zugriff
am 30 Jänner 2015].
[53] „Wikipedia (.NET Framework),“ [Online]. Available:
https://en.wikipedia.org/wiki/.NET_Framework. [Zugriff am 2015 Jänner 01].
78
Abbildungsverzeichnis
Abbildung 1: Darstellung eines Buffer Overflow ..................................................................11
Abbildung 2: Common Language Infrastructure (CLI) [27] ..................................................19
Abbildung 3: Einfaches C++ Beispiel mit einer globalen Variable und zwei Funktionen, .....21
Abbildung 4: Verschleierter C++ Code. ..............................................................................21
Abbildung 5: Control Flow Flattening Schema (übernommen aus [26]) ..............................25
Abbildung 6: Control Flow Flattening in Aktion (übernommen aus [26]) ..............................25
Abbildung 7: .NET Programm Fiddler2 dekompiliert mittels ILSpy ......................................28
Abbildung 8: links: Java Quellcode | rechts: Dekompilierter Java Quellcode ......................31
Abbildung 9: Dekompilierter Java Quellcode, der mit ProGuard obfuscated wurde ............32
Abbildung 10: VirusTotal.com Scanergebnis des JavaScript-Codes von oberhalb .............41
Abbildung 11: VirusTotal.com Scanergebnis des abgeänderten JavaScript-Codes von
oberhalb ...............................................................................................................................41
Abbildung 12: Zperm: Metamorphie mittels umordnen von Instruktionen und einfügen von
Jump Statements [46] ..........................................................................................................46
Abbildung 13: Obfuscation des ZeuS-Bot mittels yoda’s Protector v1.03.3 .........................49
Abbildung 14: avast! Prüfergebnis des originalen ZeuS-Bots .............................................50
Abbildung 15: AVG Prüfergebnis des originalen ZeuS-Bots ...............................................50
Abbildung 16 & 17: Avira & Kaspersky Prüfergebnis des originalen ZeuS-Bots ..................50
Abbildung 18: VirusTotal Prüfergebnis des originalen ZeuS-Bots .......................................51
Abbildung 19: avast! Prüfergebnis des verschleierten ZeuS-Bots .......................................51
Abbildung 20: AVG Prüfergebnis des verschleierten ZeuS-Bots .........................................51
Abbildung 21 & 22: Avira & Kaspersky Prüfergebnis des verschleierten ZeuS-Bots ...........51
Abbildung 23: VirusTotal Prüfergebnis des verschleierten ZeuS-Bots ................................52
Abbildung 24: Smart Assembly GUI (.NET Obfuscator) ......................................................53
Abbildung 25: Mit ILSpy disassembelter original Bytecode des Keyloggers ........................53
Abbildung 26: Mit ILSpy disassembelter verschleierter Bytecode des Keyloggers ..............54
Abbildung 27: ConfuserEx v0.4.0 GUI ................................................................................54
Abbildung 28: Einstellungen des ConfuserEx .....................................................................55
Abbildung 29: Avast-Virenscan des originalen Keyloggers .................................................55
Abbildung 30: Avast-Virenscan des mit Smart Assembly 6 verschleierten Keyloggers .......55
Abbildung 31: Avast-Virenscan des mit ConfuserEx verschleierten Keyloggers..................56
Abbildung 32: AVG-Virenscan des originalen Keyloggers ..................................................56
Abbildung 33: AVG-Virenscan des mit Smart Assembly 6 verschleierten Keyloggers .........56
Abbildung 34: AVG-Virenscan des mit ConfuserEx verschleierten Keyloggers ...................57
Abbildung 35 & 36: Avira-Scan des originalen (li.) und des mit Smart Assembly 6
verschleierten (re.) Keyloggers .............................................................................................57
Abbildung 37: Avira-Virenscan des mit ConfuserEx verschleierten Keyloggers ..................57
Abbildung 38: Kaspersky-Virenscan des originalen Keyloggers .........................................58
79
Abbildung 39: Kaspersky-Virenscan des Smart Assembly 6 Keyloggers ............................58
Abbildung 40: Kaspersky-Virenscan des ConfuserEx Keyloggers ......................................58
Abbildung 41: Virustotal-Virenscan des originalen Keyloggers ...........................................59
Abbildung 42: Virustotal-Virenscan des mit Smart Assembly 6 veschleierten Keyloggers ..59
Abbildung 43: Virustotal-Virenscan des mit ConfuserEx verschleierten Keyloggers ...........60
Abbildung 44: Malware Verbreitungsmethoden und zugehörige Erkennungsraten von AVs
[51] .......................................................................................................................................61
Abbildung 45: Zeitraum, wie lange Malware unentdeckt bleibt, aufgeschlüsselt auf die
Infektionsquellen [51] ...........................................................................................................62
Abbildung 46: GUI von MS EMET ......................................................................................65
Abbildung 47: App – Sicherheitsmechanismus – Matrix von EMET ....................................66
Tabellenverzeichnis
Tabelle 1: Beispiele für .NET und Java Disassembler/Decompiler .......................................28
Tabelle 2: Malware Typen ...................................................................................................39
80
Zugehörige Unterlagen
Herunterladen