Konzeption und Implementierung einer zusätzlichen Verschlüsselungsschicht für Skype

Felix Schuster 4. September 2011

Diplomarbeit

Ruhr-Universität Bochum Lehrstuhl für Netz- und Datensicherheit Professor Jörg Schwenk Professor Thorsten Holz Ich danke Prof. Dr. Jörg Schwenk und Dominik Birk für die Betreuung dieser Arbeit. Ebenfalls bedanken möchte ich mich bei Ingrid und Norbert Schuster und Josefin Annemüller für das Korrekturlesen.

2 Erklärung

Ich erkläre, dass das Thema dieser Arbeit nicht identisch ist mit dem Thema einer von mir bereits für eine andere Prüfung eingereichten Arbeit. Ich erkläre weiterhin, dass ich die Arbeit nicht bereits an einer anderen Hochschule zur Erlangung eines akademischen Grades eingereicht habe. Ich versichere, dass ich die Arbeit selbständig verfasst und keine anderen als die angege- benen Quellen benutzt habe. Die Stellen der Arbeit, die anderen Werken dem Wortlaut oder dem Sinn nach entnommen sind, habe ich unter Angabe der Quellen der Entlehnung kenntlich gemacht. Dies gilt sinngemäß auch für gelieferte Zeichnungen, Skizzen, bildliche Darstellungen und dergleichen.

3 Inhaltsverzeichnis

Inhaltsverzeichnis

1 Einleitung 6 1.1 Überblick...... 6 1.2 Vorwort...... 6 1.3 Bereits vorhandene Abhörschutzmaßnahmen und Unsicherheiten...... 8 1.3.1 Aufbau des Skype-Netzwerks und grundlegende Abläufe...... 8 1.3.2 Vertrauen im Skype-Netzwerk...... 11 1.3.3 Man-In-The-Middle Angriff...... 11 1.4 Zielstellung...... 12 1.4.1 Vergleich der Vertrauensmodelle...... 14

2 Mögliche Ansätze zur Verhinderung von Man-In-The-Middle Angriffen 15 2.1 Spezielle Schwierigkeiten bei der Verschlüsselung von Skype-Verbindungen... 15 2.2 Prä Audio-Codec Verschlüsselung...... 16 2.2.1 Skype API...... 18 2.2.2 Bewertung...... 20 2.3 Netzwerkpaketverschlüsselung...... 20 2.3.1 Direkte Eintragung eines lokalen Proxy-Server...... 21 2.3.2 Umleitung von Windows Sockets API Aufrufen...... 22 2.3.3 Zuordnung von Netzwerkpaketen...... 26 2.3.4 Bewertung...... 31

3 Implementierung der Verschlüsselungslösung 33 3.1 Vorgaben und Ziele...... 33 3.1.1 Konzeptionelle Ziele...... 33 3.1.2 Implementierungstechnische Vorgaben...... 34 3.2 Das Programm watchasayin...... 35 3.2.1 Funktionen...... 36 3.2.2 Aufbau und Design...... 40 3.2.3 Das Threading-Modell...... 44 3.2.4 Programmkern und Einstiegsfunktion...... 45 3.3 Verwendung des Component Object Models...... 49 3.4 Basismodul - Surface...... 51 3.4.1 Kommunikation mit anderen watchasayin Instanzen...... 51 3.4.2 Ereignisverarbeitung...... 55

4 Inhaltsverzeichnis

3.5 Manipulationsmodul - Bottom...... 57 3.5.1 Laden der Bottom DLL in den Prozess des Skype-Clients...... 58 3.5.2 Umleiten von Windows Sockets API Funktionen...... 59 3.5.3 Verwendung der Windows Cryptography API...... 60 3.5.4 Identifikation von zu schützenden Verbindungen...... 61 3.5.5 Betriebsmodi der Bottom DLL...... 65 3.5.6 Starten eines COM Servers im Skype-Prozess...... 67 3.6 Kryptographiemodul - Kryptonite...... 68 3.6.1 Wahl der externen Bibliotheken für AKE...... 69 3.6.2 Die libOTR Bibliothek...... 69 3.6.3 Ableitung der Bottom-Sitzungsschlüssel...... 72 3.7 Die fertige Anwendung...... 75 3.7.1 Funktionale Einschränkungen und Fehler...... 76 3.8 Zukünftige Entwicklung...... 77

4 Fazit 78

Literaturverzeichnis 79

Abkürzungsverzeichnis 83

A Anhang 84

5 1. Einleitung

1 Einleitung

1.1 Überblick

Mit dieser Arbeit wird erstmals eine überprüfbar sichere Verschlüsselungslösung für über Skype geführte Telefonate präsentiert. Nach einer einleitenden Beschreibung des Skype-Netzwerks und der Motivation des Vorha- bens werden zwei grundsätzlich unterschiedliche Ansätze zur Erreichung dessen vorgestellt und evaluiert. Anschließend wird im dritten und mit Abstand größten Teil dieser Arbeit die Soft- warelösung beschrieben, welche aufbauend auf einem der beiden zuvor beleuchteten Ansätze entwickelt wurde. Die fertige Anwendung, welche nur in Hinblick auf die Windows entwickelt wurde, lässt sich in ihrer grundlegenden Funktionsweise mit dem bekannten Programm PGP für den verschlüsselten Versand von E-Mail Nachrichten vergleichen: Zwei kommunikationswillige Anwender verifize- ren den kryptographischen Fingerprint des jeweils anderen und können im Anschluss sicher miteinander kommunizieren.

1.2 Vorwort

Es ist wohl unbestritten, dass mit dem rasanten Vordringen des Internets in viele Bereiche des alltäglichen Lebens sich auch die Kommunikationsgewohnheiten der Menschen radikal gewan- delt haben. Wurde das Internet lange Jahre im privaten Bereich vor allem zum Austausch von E-Mails verwendet, entstanden und entstehen im Zuge des als „Web 2.0 Revolution“ bezeich- neten Umbruchs im Netz völlig neue Kommunikationsformen wie zum Beispiel Kurznachrich- tendienste oder soziale Netzwerke. Auch erfahren vermehrt klassische Kommunikationsmedien wie zum Beispiel das Telefon große Konkurrenz durch ihre webbasierten Pendants, die mit reizvollen neuen oder zumindest kostenlosen Funktionen aufwarten. Einer der wohl bekanntes- ten Vertreter dieser neuen Zunft der internetbasierten Kommunikationsdienste ist Skype. Es ist Instant-Messenger, VoIP-Client und Videotelefon in einem und konnte dank einfacher Be- nutzbarkeit und überragender Qualität seit dem Start im Jahre 2003 große Marktanteile von ehemals sehr populären Diensten wie ICQ oder AIM für sich gewinnen. Dabei beschränkt sich Skype schon lange nicht mehr nur auf den klassischen Windows-PC. Neben Varianten für OS X und Linux sind mittlerweile auch kostenlose Apps für alle gängigen Smartphones erhältlich. Die eigentliche Besonderheit von Skype liegt jedoch in der Struktur des zugrunde liegenden

6 1. Einleitung

Netzwerks. Dieses ist, basierend auf der Technologie des mittlerweile eingestellten File-Sharing Dienstes Kazaa, voll auf sogenannte Peer-To-Peer Verbindungen - Direktverbindungen zwischen einzelnen Geräten - ausgelegt. So werden nur für den Vorgang der Anmeldung von Nutzern Server von Skype selbst bereit- gestellt. Alle anderen für das Betreiben der verschiedenen Kerndienste notwendigen Aufgaben werden auf die Endgeräte der Nutzer ausgelagert. Diese spezielle Struktur gepaart mit der Tatsache, dass die Betreiberin Skype Ltd. allgemein bemüht ist technische Details über ihr Produkt geheimzuhalten, wirft natürlich Fragen zur Si- cherheit der übertragenen Daten auf. Können geführte Telefonate abgehört werden? Wird irgendwo gespeichert wer mit wem telefo- niert hat? Wie weiter unten dargelegt wird, hat Skype Ltd., welche nach einer mehrjährigen Zugehörig- keit zum Internetkonzern eBay und einer Phase der Eigenständigkeit kürzlich von Microsoft aufgekauft wurde, in jedem Fall technisch die Möglichkeit Gespräche zwischen zwei Parteien mitzuschneiden. Ob von dieser Möglichkeit auch tatsächlich Gebrauch gemacht wird, steht auf einem anderen Blatt. Unbestritten ist jedoch, dass zumindest Geheimdienste aus aller Welt ein großes Interesse daran haben, über Skype geführte Gespräche abzuhören [46]. Ob Berichte wie [2], die von gebotenen Milliardensummen für eine Hintertür sprechen, ernst zu nehmen sind, sei einmal dahingestellt. Dazu bleibt selbst für den Fall, dass Skype Ltd. als voll vertrauenswürdig und unbestechlich eingestuft werden kann, die durchaus reale Gefahr, dass die Sicherheit von Gesprächen im Skype-Netzwerk durch unbewusste Fehler bei der Implementierung kryptogra- phischer Verfahren gefährdet ist. All diese Unsicherheiten wurden vom Autor bereits in [38] zum Anlass genommen, mögliche Verfahren zu beschreiben und zu evaluieren, mit denen Gespräche und andere Kommunikation über das Skype-Netzwerk abhörsicher geführt werden könnten. Aufbauend darauf wird hier nun eine konkrete und voll funktionsfähige Lösung präsentiert und eingehend beschrieben, die in den letzten Monaten im Rahmen dieser Arbeit programmiert wurde. Um die während der De- signphase jener Lösung getroffenen Entscheidungen besser erörtern zu können, wird auch hier, wie bereits in [38] geschehen, im folgenden Kapitel zunächst ein Überblick über identifizierte mögliche Ansätze zur zusätzlichen Verschlüsselung von Kommunikationssitzungen über Skype gegeben. Bevor die genaue Zielstellung dieser Arbeit formuliert werden kann, sind hier zudem noch einige Aspekte des Skype-Netzwerks und der darin agierenden Parteien genauer zu betrachten.

7 1. Einleitung

1.3 Bereits vorhandene Abhörschutzmaßnahmen und Unsicherheiten

In 2006 wurde auf der IT-Sicherheitskonferenz BlackHat in Las Vegas ein Vortrag von Ingenieu- ren des Unternehmens EADS gehalten [42], der einen tieferen Einblick in die damalige Version der Skype-Clients für Windows und Linux bot. Die Autoren unterstreichen die Vehemenz mit der der Skype-Client für Windows sich gegen jegliche Arten des Reverse Engineerings zur Wehr setzt. Trotzdem kommen sie in ihrem Vortrag zu dem Schluss, dass Kommunikation über Skype, geschützt durch die bekannten und bewährten Algorithmen AES und RSA, vor Abhörversu- chen dritter sicher sei. Jedoch weisen sie auch darauf hin, dass das Unternehmen Skype Ltd. als Betreiberin der notwendigerweise vertrauenswürdigen Certificate Authority (CA) des Dienstes sehr wohl zu sogenannten Man-In-The-Middle Attacken in der Lage ist. Das heißt, wenn das Unternehmen Skype Ltd. ein Interesse daran hat ein Gespräch zwischen zwei Skype-Clients abzuhören, dann ist es dazu auch fähig. Um den genauen Ablauf einer sol- chen Abhöraktion nachvollziehen zu können, ist es notwendig die grundlegenden Abläufe inner- halb des Skype-Netzwerks zu kennen. Diese werden in den folgenden Abschnitten beschrieben.

1.3.1 Aufbau des Skype-Netzwerks und grundlegende Abläufe

Nach [42] verteilen sich sämtliche Akteure innerhalb des Skype-Netzwerks auf die Rollen Node, Supernode, Login Server sowie verschiedene weitere Servertypen1. Während die ersten beiden für gewöhnlich von auf Nutzerendgeräten laufenden Skype-Clients eingenommen werden, wer- den alle anderen vermutlich ausschließlich von einer überschaubaren Anzahl von von Skype Ltd. betriebenen Servern ausgefüllt. Während Nodes normal mit dem Netzwerk verbundene Clients darstellen, handelt es sich bei Supernodes um ehemalige Nodes, die aufgrund der Erfüllung bestimmter Kriterien, wie zum Beispiel dem Vorhandensein einer besonders leistungsfähigen Internetanbindung, mit weiterreichenden Aufgaben innerhalb des Netzwerks bedacht wurden. Die wohl wichtigste dieser Aufgaben stellt das Vermitteln von Gesprächen dar. Will ein Skype- Client in seiner Funktion als Node mit einem anderen Node eine Kommunikationssitzung be- ginnen, so teilt er diesen Wunsch einem ihm bekannten Supernode mit. Ist der fragliche Node aktuell im Netzwerk angemeldet, so erhält der anfragende Node im Normalfall alle Informa- tionen zurückgesandt, die nötig sind, um eine kryptographisch gesicherte Kommunikation mit dem gewünschten Node zu beginnen [42]. Supernodes stellen also eine Art Telefonbuch oder Vermittlungsstelle des Skype-Netzwerks dar. Die Übertragung von Daten zwischen Supernode und Node erfolgt dabei gesichert durch asymmetrische Kryptographie.

1Im Rahmen dieser Arbeit wurde mit Hilfe von Reverse Engineering eine nicht notwendigerweise vollständige Liste der unterschiedlichen Servertypen innerhalb des Skype-Netzwerks aus dem Skype-Client für Windows gewonnen. Auf Seite 84 in Tabelle A.1 sind diese zusammen mit ihren fest kodierten IP-Adressen zu finden.

8 1. Einleitung

Node Skype Ltd.

Node Supernode

Supernode Weitere Server 193.88.6.19 P2P Verbindung

Supernode

Node Login Server Login Server Node 193.88.6.13 194.165.188.79

Client Abbildung 1.1.: Schematischer Aufbau des Skype-Netzwerks nach [42]

Hat ein Node die nötigen Daten für einen Verbindungsaufbau zu einem anderen Node erhalten, so wird zunächst versucht eine P2P Verbindung - also eine Direktverbindung - zwischen beiden aufzubauen. Gelingt dies aufgrund von Netzwerkbegebenheiten wie zum Beispiel bestimmten Firewalleinstellungen nicht, so kann die Hilfe eines dritten, von beiden Parteien erreichbaren, beliebigen Nodes in Anspruch genommen werden [24]. Dieser agiert dann im Stile eines von beiden Parteien sichtbaren Spiegels und leitet für die Kommunikation notwendige Netzwerkpa- kete weiter. Man spricht in diesem Zusammenhang auch von einem „Relay Host“. Bis hierhin funktioniert das Skype-Netzwerk ganz ohne Mitwirken von zentralen Einheiten rein auf P2P Basis. Als grundlegende zentrale Instanzen treten die Login Server nur beim Prozess der Anmeldung von Clients am Skype-Netzwerk auf. Um zu klären, warum diese Server die Grundlage der vertraulichen und authentischen Kommunikation innerhalb des Netzwerks sind und warum es in dem gegebenen Modell zwingend notwendig ist, dass diese Server von Skype Ltd. zentral betrieben werden, muss der Prozess der Anmeldung genauer betrachtet werden.

1.3.1.1 Der Anmeldevorgang im Netzwerk

Die globalen IP-Adressen der Login Server sind in den verschiedenen Clients fest kodiert. Zudem gibt es eine von Skype Ltd. generierte Menge KRSA−keypairs,Skype von n RSA Schlüsselpaaren mit (keyi,pub,Skype, keyi,priv,Skype) ∈ KRSA−keypairs,Skype und 0 ≤ i < n. Zumindest von einer ge-

9 1. Einleitung wissen Untermenge dieser Schlüsselpaare sind in jedem Skype-Client die öffentlichen Schlüssel keyi,pub,Skype ebenfalls fest kodiert. Will sich ein Nutzer nun im Skype-Netzwerk anmelden, so wird nach [42] folgender Vorgang angestoßen: Zunächst berechnet der Skype-Client ein frisches, nur für die anstehende Sitzung gültiges Paar session session aus öffentlichem Schlüssel keypub,u und privatem Schlüssel keypriv,u für RSA mit 1024 Bit langem Modulus. Zudem wird aus dem gegebenen Nutzernamen u zusammen mit dem eingege- 0 benen Passwort p auf bestimmte Art und Weise ein Hashwert h berechnet. Dieser wird dann zusammen mit dem zuvor neu berechneten, eigenen öffentlichen Schlüssel unter Verwendung eines dem Client bekannten öffentlichen Schlüssels keyl,pub,Skype aus KRSA−keypairs,Skype asym- metrisch verschlüsselt und an einen Login Server gesandt. Da dieser natürlich in Kenntnis der geheimen Schlüssel aus KRSA−keypairs,Skype ist, kann der Login Server das erhaltene Datagramm mit Hilfe des passenden keyl,priv,Skype entschlüsseln. Anschließend überprüft der Login Server, 0 ob der erhaltene Hashwert h mit dem für den angefragten Nutzernamen lokal gespeicherten session Hashwert h identisch ist. Ist dies der Fall, so signiert der Login Server das Tupel (u, keypub,u )

über einem geheimen Schlüssel keys,priv,Skype aus KRSA−keypairs,Skype und reicht es, vermutlich zusammen mit der IP-Adresse und dem Netzwerkport unter denen der betreffende Client zu erreichen ist, an die im Netzwerk aktiven Supernodes weiter. Der Client ist damit erfolgreich am Skype-Netzwerk angemeldet und agiert von da an in diesem als gewöhnlicher Node mit der Möglichkeit Kommunikationssitzungen mit anderen Clients aufzubauen.

1.3.1.2 Sitzungsaufbau zwischen zwei angemeldeten Clients

Wollen zwei Nodes u1 und u2 wie bereits oben beschrieben über eine P2P Verbindung mit- einander kommunizieren, so erhalten sie von einer ihnen bekannten Supernode im Netzwerk jeweils das von einem Login Server signierte Tupel ( session) des anderen signkeyi,pub,Skype ui, keypub,ui Node. Mit Hilfe der fest kodierten öffentlichen Schlüssel wird daraufhin auf beiden Seiten die Authentizität des empfangenen Tupels verifiziert. Bei Erfolg überprüfen beide Seiten in einem Challenge-Response Protokoll, ob die jeweils andere Seite tatsächlich im Besitz des passenden privaten Schlüssels session zu dem erhaltenen öffentlichen Schlüssel session ist. keypriv,ui keypub,ui session Anders ausgedrückt: u1 beweist u2 direkt, dass er in Besitz von keypriv,u1 ist und beweist damit im selben Zug indirekt, dass er sich, vorausgesetzt die geheimen Schlüssel aus KRSA−keypairs,Skype sind nur den Login Servern bekannt, mit Hilfe eines gültigen Passworts zuvor am Netzwerk an- gemeldet hat und umgekehrt. Nach dieser Authentisierung bestimmen beide Seiten laut [42] sicher einen gemeinsamen Sitzungsschlüssel für symmetrische Verschlüsselung und kommuni- zieren fortan geschützt miteinander.

10 1. Einleitung

1.3.2 Vertrauen im Skype-Netzwerk

Die beschriebenen Vorgänge zwischen zwei Nodes beim Aufbau einer geschützten Kommuni- kationssitzung stellen einen Authenticated Key-Exchange (AKE) [40] dar, wobei die von Skype Ltd. betriebenen Login Server die Rolle der Certificate Authority übernehmen, indem diese die Korrektheit der an Passwörter gebundenen Identitäten der einzelnen Nodes mit ihrer Signatur der Tupel ( session) bestätigen. Nach [40] ist eine vertrauenswürdige dritte Partei für einen ui, keypub,ui AKE zwingend notwendig, sofern beide Parteien nicht bereits einen geheimen Schlüssel teilen und auch ansonsten nicht auf einen sicheren Kanal zurückgreifen können. Ungeachtet der Details der Abläufe innerhalb des Skype-Netzwerks, die sich unter Umständen seit der Veröffentlichung von [42] in 2006 auch wieder geändert haben könnten, müssen alle Sicherheitsannahmen inner- halb dieses Netzwerks also zwingend auf der Vertrauenswürdigkeit von bestimmten Instanzen, wie den Login Servern und der Sicherheit ihrer kryptographischen Primitiven und den entspre- chenden geheimen Schlüsseln, fußen. Mit Hilfe der Login Server wird hier nach [45] eine Public-Key Infrastructure (PKI) mit einer einzelnen CA realisiert. In [45] werden solche PKIs mit einer einzelnen CA („A single certi- ficate authority“) als nicht zweckmäßig bezeichnet, weil es den Autoren als unwahrscheinlich erscheint, dass ein jeder bereit ist dieser zu vertrauen („[...] it is highly unlikely for everyone to trust the same CA [...] the CA is a single point of failure for the entire system.“). Schlussendlich bedeutet dies, dass sich Sicherheitsziele wie Vertraulichkeit, Authentizität und Integrität dann verletzen lassen, wenn die Instanzen denen vertraut werden muss ein fehlerhaf- tes, fahrlässiges oder gar böswilliges Verhalten an den Tag legen. Wie Skype Ltd. entsprechend dem letzten Fall die Kommunikation zwischen zwei Clients durch einen Man-In-The-Middle Angriff zuverlässig und unbemerkt abhören und manipulieren könnte, wird im Folgenden nach [42] skizziert.

1.3.3 Man-In-The-Middle Angriff

Als Man-In-The-Middle Angriff bezeichnet man gemeinhin das Abhören oder Manipulieren von Kommunikation zwischen zwei Parteien A und B durch eine dritte Partei C, einem Angreifer. Dieser Angreifer fängt dabei alle oder einen Teil der Nachrichten zwischen A und B ab und leitet diese nach der eigenen Auswertung für gewöhnlich, möglicherweise manipuliert, weiter. Nimmt man nun für den Fall des oben beschriebenen Sitzungsaufbaus zwischen zwei Clients einen Angreifer an, der zwar sämtliche Netzwerkpakete zwischen A und B manipulieren und lesen kann, der jedoch keine Gewalt über die Login Server hat, so wird dieser Angreifer trotz seiner Fähigkeiten unter der Annahme, dass die verwendeten kryptographischen Primitiven ausreichend stark sind, nicht in der Lage sein integrale Sicherheitsziele unbemerkt zu verletzen.

11 1. Einleitung

Anders verhält es sich jedoch für das Unternehmen Skype Ltd. selbst oder einen außenste- henden Angreifer der die Certificate Authority des Netzwerks kontrolliert. Ihm ist es mit Hilfe der privaten Schlüssel der Login Server möglich, das oben beschriebene Datagramm ( session) zu fälschen und dort einen öffentlichen Schlüssel session0 ein- signkeyi,pub,Skype ui, keypub,ui keypub,ui zutragen, zu dem ihm der entsprechende private Schlüssel bekannt ist. So ein gefälschtes Data- gramm würde der Angreifer für jeden abzuhörenden Client in den Datenbanken der Supernodes ablegen. Versucht in diesem Szenario dann beispielsweise A ein Telefongespräch mit B aufzu- bauen, so gibt sich der Angreifer C gegenüber A als Teilnehmer B aus und umgekehrt, ohne dass dies die beteiligten Parteien registrieren könnten. Möglich ist dies dadurch, dass C sämtliche session0 über keypub,B verschlüsselten Pakete von A an B öffnet und vor dem Weiterleiten diese über session dem tatsächlichen öffentlichen Schlüssel keypub,B wieder verschlüsselt. Entsprechend verfährt er in die entgegengesetzte Richtung. Für den wahrscheinlichen Fall, dass der Angreifer nicht sämtliche Pakete zwischen A und B abfangen kann, könnte er neben den gefälschten Datagram- men auch IP-Adressen unter seiner Kontrolle anstelle der eigentlichen IP-Adressen von A und B in die Supernodes eintragen lassen. Alternativ könnte er womöglich auch auf einem unbe- stimmten Weg einen Node unter seiner Kontrolle zum Relay Host für das anstehende Gespräch zwischen A und B machen.

1.4 Zielstellung

Die Sicherheit von Verbindungen innerhalb des Skype-Netzwerks hängt unmittelbar von Skype Ltd. und der Sicherheit der von ihr betriebenen Server ab. Abgesehen von der Ausnahme des hauseigenen Audio-Codecs SILK [31] und kleinerer Beispielprogramme, ist sämtliche Software von Skype Ltd. nicht quelloffen. Da sich zudem die verschiedenen aus dem Internet beziehbaren Client-Versionen aktiv gegen Versuche des Reverse Engineerings zur Wehr setzen, bleibt den Nutzern nicht viel, als auch eine sichere Implementierung der verwendeten kryptographischen Algorithmen und Sicherheitsmechanismen wohlwollend anzunehmen. Durch die hohe Markt- durchdringung2 und die bis heute unerreichte Qualität des Dienstes, sowohl in Hinsicht auf die allgemeine Qualität von Sprachverbindungen als auch auf die beeindruckende Fähigkeit von Skype auch schwierigste Netzwerktopologien zu überbrücken, dürfte sich jedoch aufgrund dieser Unsicherheiten kaum ein Anwender dazu durchringen können zu einem überprüfbareren Dienst mit vergleichbarem Angebot zu wechseln. Daher ist es das erklärte Ziel dieser Arbeit, das bestehende Angebot von Skype für den Anwender nachvollziehbar und überprüfbar sicher zu machen. So soll ei- ne quelloffene Anwendung entwickelt werden, die die grundsätzliche Nutzererfahrung während

2Im Januar 2011 waren laut Skype Ltd. zum ersten mal mehr als 28 Millionen Nutzer gleichzeitig im Netzwerk angemeldet [36].

12 1. Einleitung des Benutzens von Skype so wenig wie möglich ändert und nur an den entscheidenden Stellen eingreift. Schon allein aufgrund des sehr großen Aufwands der dafür nötig wäre, soll keine ei- genständige Client Software entwickelt werden. Stattdessen sollen bereits existierende, offizielle Clients in ihrem Verhalten gesteu- ert und funktional erweitert werden. Dadurch kann sich jedoch bei den Sicherheitsannah- men keine komplette Unabhängigkeit von Skype Ltd. ergeben. Den betreffenden Clients von Skype Ltd. wäre weiterhin zumindest so weit zu vertrauen, als dass diese nicht aktiv vertrau- liche Daten wie zum Beispiel kryptographische Schlüssel von einem Endgerät kopieren oder bewusst kryptographische Berechnungen stören. Von außen betrachtet sollen sich Skype-Clients mit einer Verschlüsselungserwei- terung in ihrem Verhalten nicht merklich von herkömmlichen Skype-Clients un- terscheiden. Es soll möglichst keine Auswirkungen auf das Skype-Netzwerk geben. Diese Anforderungen sind alleine schon wichtig, um eine Konfrontation mit Skype Ltd. zu ver- meiden, zudem kann so die Privatsphäre der Anwender geschützt werden. Die zu entwickelnde Anwendung soll einen AKE ohne die Notwendigkeit einer zen- tralen CA ermöglichen und darauf aufbauend zumindest die sichere Übertragung von Gesprächsdaten zwischen zwei Clients durchsetzen. Wie bereits weiter oben er- wähnt, ist nach [40] ein AKE nur dann ohne eine vertrauenswürdige dritte Partei möglich, wenn ein sicherer Kanal zu Verfügung steht. Im Falle von modernen Public-Key basierten AKE Protokollen beschränkt sich die Nutzung eines solchen sicheren Kanals häufig auf den einmaligen und unverfälschten Austausch von so genannten Fingerprints. Ist solch ein krypto- graphischer Fingerabdruck einmal lokal für einen Kontakt gespeichert, so lässt sich dieser in jedem folgenden AKE Protokolllauf dazu verwenden die Identität des Gegenübers eindeutig zu verifizieren. Vorausgesetzt natürlich, der zu dem Fingerprint gehörige Private-Key ist nur diesem Gegenüber bekannt. Praktisch gestaltet sich der hinreichend sichere Austausch weniger kompliziert als es sich viel- leicht zunächst vermuten lässt. So muss nicht etwa sichergestellt werden, dass der fragliche Fingerprint geheim bleibt, sondern nur, dass er unmanipuliert seinen Empfänger erreicht. In den meisten Fällen dürfte es also genügen die im Regelfall nur einige Dutzend Zahlen und Buchstaben langen Zeichenketten einander am Festnetztelefon vorzulesen oder auf der eigenen Homepage zu veröffentlichen, wie es beispielsweise im Falle von sicherer E-Mail Kommunikati- on mittels PGP üblich ist. Auch könnte zum Beispiel ganz allgemein auf die bereits für PGP existierenden Landschaft von öffentlichen Schlüsselservern zurückgegriffen werden. Bei den in den nächsten Kapiteln folgenden Ausführungen zur konkreten Implementierung einer solchen Erweiterung für Skype-Clients wird sich auf 7 und den entsprechen- den Skype-Client betreffende Aspekte beschränkt. Dies ist sowohl der hohen Verbreitung dieses Betriebssystems als auch den Vorlieben des Autors geschuldet.

13 1. Einleitung

Die letztlich zu präsentierende Lösung soll möglichst modular aufgebaut sein, so- dass sich einfach beispielsweise verwendete kryptographische Bibliotheken oder einzelne Protokolle austauschen lassen.

1.4.1 Vergleich der Vertrauensmodelle

Notwendige Annahme Skype Skype mit eigener Erweiterung Skype-Clients sind nicht bösartig X X Endgerät ist nicht kompromittiert X X Kryptographische Maßnahmen von Skype Ltd. sind sicher X - Skype CA ist sicher X - Skype CA ist vertrauenswürdig X - Frei wählbare kryptographische Maßnahmen sind sicher - X Zusätzliche quelloffene Software ist sicher - X Zusätzlicher integerer Kanal verfügbar - X (Übertragung von Fingerprints) Tabelle 1.1.: Notwendiges Vertrauen für eine sichere Kommunikation über Skype

Da die Eckpfeiler der zu entwickelnden Anwendung gesteckt sind, lässt sich ohne Kenntnis der genauen Details der eigenen Implementierung bereits ein Vergleich zwischen dem Vertrauens- modell dieser und dem der herkömmlichen Skype-Clients anstellen. Ein solcher Vergleich ist in Tabelle 1.1 abgebildet. Erklärungsbedürftig ist dort womöglich die Zeile für den Eintrag „Endgerät ist nicht kompromittiert“. Diese besagt, dass die Sicherheit bei beiden Varianten zwingend voraussetzt, dass das verwendete Endgerät nicht unter der unbemerkten Kontrolle eines Angreifers steht oder von einem Virus befallen ist. Dass solch eine Gefahr zumindest für Windows-PCs nicht nur theoretischer Natur ist, zeigt die Tatsache, dass der Firma Symantec ein Virus bekannt ist, welcher die unverschlüsselten Audioströme zwischen Skype-Client und Soundkarte abgreift und speichert [4]. Auch ist unter [39] der komplette Quellcode eines Pro- gramms mit identischer Funktionalität erhältlich, das obendrein noch sämtliche gesammelten Sprachdaten an einen beliebigen Rechner im Internet versendet. Auch wenn in beiden Spalten der Vergleichstabelle fünf notwendige Grundannahmen identifi- ziert werden konnten, sind die Annahmen der linken Spalte in jedem Fall als erheblich stärker und schwerer zu überprüfen einzustufen. Dies wird zur Motivation genommen, in den nun anschließenden Kapiteln den Weg zu einer Anwendung mit den Annahmen der rechten Spalte darzulegen.

14 2. Mögliche Ansätze zur Verhinderung von Man-In-The-Middle Angriffen

2 Mögliche Ansätze zur Verhinderung von Man-In-The-Middle An- griffen

Das besagte Ziel dieser Arbeit ist es, den bereits vorhandenen Skype-Client für Windows so zu beeinflussen, dass ein von Skype Ltd. unabhängiger Authenticated Key-Exchange möglich wird. Aufbauend auf diesem soll dann für die Dauer von Gesprächen und womöglich anderer Kommunikation, zusätzlich zur Kryptographieschicht des Protokolls des Skype-Netzwerks, ei- ne weitere, transparente und kontrollierbare symmetrische Verschlüsselungsschicht aufgebaut werden. Dabei soll die Benutzererfahrung und die Qualität des Dienstes selber nicht merklich beeinflusst werden. Ebenso sollen für das Anwenden der Lösung keine System- oder Adminis- trationsrechte nötig sein, sodass sie beispielsweise auch in Internet-Cafés anwendbar bleibt. Die möglichen Ansätze und die sich ergebenden Schwierigkeiten werden in diesem Kapitel be- handelt. Dabei geht es vor allem darum, die Möglichkeiten der Implementierung der sym- metrischen Verschlüsselungsschicht auszuloten. Lässt sich diese erst einmal realisieren, kann der ebenfalls geforderte AKE leicht hinzugefügt werden. Das Hauptaugenmerk liegt auf der Sicherung eines Telefonats zwischen zwei Parteien. Andere über Skype mögliche Kommunika- tionsformen wie beispielsweise Gruppenvideotelefonate bleiben erst einmal außen vor. Sofern nicht anders angemerkt, beziehen sich sämtliche Aussagen in den folgenden Abschnitten auf die Windows Variante des Skype-Clients in der zu Beginn der Niederschrift dieser Arbeit aktuellen Version 5.0.0.152.

2.1 Spezielle Schwierigkeiten bei der Verschlüsselung von Skype-Verbindungen

Als erste Idee für die mögliche Realisierung eines Vorhabens wie dem beschriebenen ergibt sich vermutlich der Weg über ein mögliches Plugin-Interface oder Ähnliches, mit Hilfe dessen Sprachdaten nach der Verarbeitung durch einen Audio-Codec und vor dem Versenden über das Netzwerk abgefangen und verschlüsselt werden könnten. Im Falle von Skype werden jedoch seit einiger Zeit keine Plugins mehr unterstützt und die offizielle API des Programms erlaubt kaum mehr als die Fernsteuerung der Benutzeroberflä- che [32]. Nach Aussagen von Skype Ltd. ist sie vornehmlich dazu gedacht, Drittherstellern die Möglichkeit der Entwicklung von speziell an Skype angepasster Hardware zu geben. Dadurch, dass der Skype-Client sich wie erwähnt aggressiv gegen Versuche des Reverse Engi- neerings wehrt und als nur eine einzelne monolithische .exe Datei von über 20 MB ausgeliefert

15 2. Mögliche Ansätze zur Verhinderung von Man-In-The-Middle Angriffen wird, bleibt kaum mehr, als das Programm zunächst in weiten Teilen als Black Box zu betrach- ten. Grundsätzlich sei zudem angemerkt, dass eine rein auf Reverse Engineering beruhende Lösung, die Teile der ursprünglichen Programmdatei des Clients manipuliert - also ein auf „Patching“ beruhender Ansatz - mit großer Wahrscheinlichkeit nicht den gewünschten Si- cherheitsgewinn liefern könnte. Denn angenommen man fände beispielsweise jene Adressen im Speicher, an denen der Client zur Laufzeit symmetrische Sitzungsschlüssel ablegt und würde diese ebenfalls zur Laufzeit durch sichere Schlüssel austauschen, so bliebe in jedem Fall die Unsi- cherheit, dass der Client unter gewissen Umständen während einer Sitzung auf die Verwendung anderer Schlüssel umschwenken könnte, die beim bis dahin vollzogenen Prozess der Analyse nicht entdeckt wurden. Auch müsste jede neu erscheinende Version eingehend und aufwändig auf neu hinzugekommene Funktionalität hin überprüft werden.

Endgerät A Endgerät B

Skype Clients und Netzwerk

Black Box

NIC NIC

Abbildung 2.1.: Betrachtung von Skype als Black Box

Nach Einschätzung des Autors ergeben sich unter diesen Vorüberlegungen genau zwei Ansatz- punkte für eine zusätzliche Verschlüsselungsschicht für Gespräche über Skype: Da Skype über keine eigenen Treiber verfügt, ist es darauf angewiesen mit dem Windows Betriebssystem zu kommunizieren, um 1.) Audiodaten vom Mikrofon des PCs zu lesen und Audiodaten über die Soundkarte auszugeben und 2.) allgemein Daten über das Netzwerk zu verschicken (siehe auch Abbildung 2.1). An diesen Schnittstellen ist es, ohne genauere Kenntnis der inneren Funktionsweisen von Skype zu haben, möglich, Daten abzugreifen und zu manipu- lieren. Diese beiden Ansätze werden im Folgenden mit Prä Audio-Codec Verschlüsselung und Netzwerkpaketverschlüsselung bezeichnet.

2.2 Prä Audio-Codec Verschlüsselung

Als erster der beiden identifizierten Ansätze soll hier die Möglichkeit diskutiert werden, Audi- odaten vor dem Eingang in den Skype-Client zu verschlüsseln und nach der Ausgabe aus diesem

16 2. Mögliche Ansätze zur Verhinderung von Man-In-The-Middle Angriffen

(und vor der Ausgabe über die Lautsprecher) wieder zu entschlüsseln. Die allergrößte Problematik bei diesem Ansatz ergibt sich durch die Tatsache, dass Skype selbst- verständlich Audiodaten vor dem Versenden über das Netzwerk verlustbehaftet komprimiert und nach deren Empfang diese wieder entsprechend dekomprimiert. Man benötigt also ein Ver- schlüsselungsverfahren, dass zum einen sicher ist und zum anderen ein solches Komprimier- /Dekomprimierglied zuverlässig verkraften kann. Ein solches Verfahren konnte trotz intensiver Recherche nicht gefunden werden und es darf ruhig bezweifelt werden, ob ein solches überhaupt technisch realisierbar ist. Im Falle von Skype wird die Situation dadurch erschwert, dass seit dem Jahre 2009 ein komplexer, auf Sprache optimierter und in mehrjähriger interner Entwick- lungsarbeit bei Skype Ltd. entstandener Audio-Codec namens SILK zum Einsatz kommt [31]. Der Programmcode für diesen Codec ist allerdings öffentlich zugänglich und ließe sich folglich einfach analysieren.

Stellt man die hier ungelöste Problematik der Verschlüsselung eines noch zu komprimieren- den Audiostroms hinten an, so stellt sich bei der in diesem Abschnitt behandelten Thematik als nächstes die Frage, auf welche Art die Audiodaten am besten abgegriffen werden. Die naheliegendste Herangehensweise für so ein Vorhaben ist vermutlich das Programmieren eines speziellen Treibers der sich gegenüber dem Skype-Client als Soundkarte mit Mikrofonein- gang und Lautsprecherausgang ausgibt. Dieser Treiber würde als eine Art Vermittler zwischen der realen Soundkarte des Systems und dem Skype-Client agieren und zunächst einfach sämtli- che Daten und Anfragen weiterreichen. Zur Verschlüsselung eines Telefonats würden dann alle von der realen Soundkarte kommenden Signale vor der Weiterleitung verschlüsselt und ent- sprechend wiederum sämtliche von Skype kommenden Audiosignale vor der Weitergabe an die Soundkarte entschlüsselt. Auch wenn dieser Ansatz auf den ersten Blick als durchaus praktikabel erscheinen mag, so er- weist er sich bei näherer Betrachtung als äußerst unpraktisch. So ist das Programmieren eines Treibers eine komplizierte und teure Aufgabe, die zudem sehr plattformspezifisch ist. Selbst für diverse unterschiedliche Varianten des Windows Betriebssystems1 müssten hier eigenstän- dige Versionen entwickelt werden. Zudem wäre es für solch eine, gewissermaßen in Software implementierte Soundkarte, wohl unmöglich zwischen tatsächlichen Sprachdaten und anderen Audioausgaben des Skype-Clients zu unterscheiden, was zu erheblichen Problemen bei der Syn- chronisation der Entschlüsselung führen dürfte. Eine deutlich günstigere und portablere technische Alternative für die Manipulation von ein- und ausgehenden Audioströmen stellt der Skype-Client selbst bereit. So erlaubt die bereits erwähnte öffentliche API des Skype-Clients unter anderem die Umleitung von sämtlichen Au-

1Windows 7 32 Bit, Windows XP 32 Bit und Windows 7 64 Bit sind beispielsweise alle auf Treiber-Ebene inkompatibel, letzteres verlangt zudem nach offiziell signierten Treibern.

17 2. Mögliche Ansätze zur Verhinderung von Man-In-The-Middle Angriffen dioströmen über frei wählbare lokale Netzwerkports oder Dateien. Genauere Erläuterungen dazu und zur API der Skype-Clients im Allgemeinen werden im Folgenden gegeben.

2.2.1 Skype API

Die Skype-Clients für unterschiedliche Plattformen stellen über eine API Funktionalität für eine automatische, textbasierte Bedienung bereit [32]. So lassen sich beispielsweise mit dem Kommando „SEARCH FRIENDS“ alle gespeicherten Kontakte für den aktuell eingeloggten Account erfragen. Mit dem Befehl „CALL friend0“ ließe sich im Anschluss ein Anruf zu dem Kontakt mit der Kennung friend0 aufbauen. Geantwortet wird von den Skype-Clients ebenfalls in textbasierter Form. Interessant für das gegebene Vorhaben der Manipulation von ein- und ausgehenden Audioströ- men sind primär die folgenden drei Befehle [32]:

ALTER CALL SET_INPUT SOUNDCARD="default" | PORT="port_no" | FILE="FILE_LOCATION"

ALTER CALL SET_OUTPUT SOUNDCARD="default" | PORT="port_no" | FILE="FILE_LOCATION"

ALTER CALL SET_CAPTURE_MIC PORT="port_no" | FILE="FILE_LOCATION"

Mit diesen ist es möglich, für ein bestimmtes Telefonat die Audioein- und ausgänge des Skype- Clients sowie den Mikrofoneingang des Computers auf eine beliebige Soundkarte, Datei oder einen Netzwerkport zu setzen. Dies erlaubt es, die Audioströme so über bestimmte Netzwerk- ports umzuleiten, dass Audiodaten einfach abgegriffen und manipuliert werden können - ohne dass das Programmieren eines Treibers nötig wäre. Eine Skizze des Ansatzes ist in Abbildung 2.2 zu sehen. Es bleibt die Frage, auf welchem Wege solche Befehle und die entsprechenden Antworten mit einem Skype-Client ausgetauscht werden. Unter Windows erfolgt dies über so genannte Window Messages. Diese Art der Kommunikation ist für Anwendungen wie der ge- gebenen eher ungewöhnlich und ist wohl der Tatsache geschuldet, dass Skype Ltd. prinzipiell versucht seine Client-Software abzuschotten. Skype Ltd. selbst stellt für Windows ein Kommandozeilenprogramm namens msgapitest als Programmierbeispiel bereit, welches zur händischen, textbasierten Kommunikation mit einem Sykpe-Client verwendet werden kann [32]. Ein Blick in den in der Programmiersprache C vorlie- genden Quellcode des Programms offenbart, dass das direkte Arbeiten mit der nativen Windows

18 2. Mögliche Ansätze zur Verhinderung von Man-In-The-Middle Angriffen

Port X

Mic-Out

Enck Port Y Skype-Client Audio-In Port Z

Deck Audio-Out Abbildung 2.2.: Umleitung von Audioströmen des Skype-Clients und des Mikrofons über Netzwerk- Ports

API zur Übertragung von Kommandos an einen Skype-Client und zum Empfang der entspre- chenden Antworten durchaus aufwändig ist. Für Windows, Linux und OS X liefert das Open-Source Projekt Skype4Py als Alternative eine objekt- und ereignisorientierte Kapselung für die Kommunikation mit Skype-Clients, die sich auf den drei unterstützten Plattformen einheitlich und komfortabel mit der Skriptsprache Py- thon ansprechen lässt [1]. Skype4Py wurde im Rahmen dieser Arbeit mehrfach für Tests und das Erstellen von Prototypen eingesetzt. Das Skript in Listing A.1 auf Seite 84 demonstriert exemplarisch, wie mit Hilfe von Skype4Py und wenigen Zeilen Programmcode in der Sprache Python ein Telefonat über das Skype- Netzwerk aufgebaut werden kann, wobei die Audioströme wie in Abbildung 2.2 über Netz- werkports umgeleitet werden. In dem gegebenen Beispielskript werden die Platzhalterfunktio- nen encrypt() und decrypt() verwendet, durch die sämtliche Audiodaten vor der Weiterleitung vom Mikrofon an den Client bzw. vom Client zur Audioausgabe durchgeleitet werden. Sollte ein sicheres Verschlüsselungsverfahren speziell für den Codec SILK gefunden werden, so müsste dies nur in der Funktionen encrypt() und decrypt() implementiert werden, um die grundlegende Fragestellung dieser Arbeit zu lösen.

Neben Skype4Py stellt Skype Ltd. selbst für Windows ein COM-Komponente2 namens Sky- pe4COM bereit, die ebenfalls die Kommunikation mit einem Skype-Client über ein objekt- und ereignisorientiertes Interface ermöglicht [32]. Aufgrund dessen, dass sich ActiveX Komponenten

2Bei COM handelt es sich um einen objektorientierten Standard für Interfaces, der vor allem auf Windows- Plattformen Verwendung findet. Auf COM und seine Rolle in dieser Arbeit wird in Abschnitt 3.3 näher eingegangen.

19 2. Mögliche Ansätze zur Verhinderung von Man-In-The-Middle Angriffen sehr gut mit .NET basierten Programmiersprachen wie C# verwenden lassen, fiel bei der weiter unten beschriebenen, endgültigen Implementierungsarbeit die Wahl auf Skype4COM.

2.2.2 Bewertung

Seit der Anfertigung von [38] konnten zu diesem Ansatz keine neuen Erkenntnisse gewonnen werden. So ist dieser Abschnitt auch eher als eine konzentriertere Wiederholung der dort bereits präsentierten Ergebnisse zu sehen, in der abermals gezeigt wurde, dass es ohne Verwendung von speziellen Treibern mit Hilfe der offiziellen Skype API plattformunabhängig realisierbar ist, die ein- und ausgehenden Audioströme eines Skype-Clients abzufangen und zu manipulieren. Weiterhin ungeklärt bleibt jedoch, wie und überhaupt ob es möglich ist, Audiodaten verläss- lich und sicher zu verschlüsseln, die einen verlustbehafteten Audio-Codec durchlaufen. Diese grundlegende Problematik verhindert bis auf Weiteres die Verfolgung dieses Ansatzes. Der große Vorteil dieses Verfahrens wäre in jedem Fall die Tatsache, dass die eigentlichen funk- tionalen Abläufe innerhalb der Client-Software komplett unangetastet blieben, woraus sich eine sehr geringe Fehleranfälligkeit ergäbe. So könnten durch solch einen „High Level“ Ansatz die Eigenheiten des Skype-Netzwerks komplett außer Acht gelassen werden. Zu guter Letzt gesellte sich als Pluspunkt noch die völlige rechtliche Unbedenklichkeit des Ansatzes hinzu, da keinerlei Manipulationen der Programmdatei oder Maßnahmen innerhalb des laufenden Prozesses des Clients durchgeführt werden müssten.

2.3 Netzwerkpaketverschlüsselung

Unter der gegebenen Vorgabe der Betrachtung des Skype-Netzwerks und der darin verbunde- nen Clients als einer gesamtheitlichen Black Box, kann sich neben der im vorangegangenen Abschnitt beschriebenen Prä-Audio-Codec-Verschlüsselung nur ein einziger weiterer Ansatz zur Realisierung einer zusätzlichen Verschlüsselungsschicht ergeben: Die Verschlüsselung von zu versendenden Netzwerkpaketen vor deren tatsächlicher Versendung und umgekehrt die Ent- schlüsselung von erhaltenen Netzwerkpaketen vor der Weiterreichung an den laufenden Skype- Client. Nach dem Schema in Abbildung 2.1 wird in diesem Abschnitt, abstrakt gesprochen, die Möglichkeit der Manipulation der Datenströme zwischen Skype-Client und Netzwerkkarte betrachtet. Gewissermaßen soll also nach Wegen gesucht werden, sämtlichen Netzwerkverkehr des Skype-Clients über einen transparenten, lokalen Proxy-Server bis hierhin ansonsten noch unbestimmter Ausprägung umzuleiten. Dabei soll die Problematik der Identifizierung der unter- schiedlichen Netzwerkpakete zunächst außer Acht gelassen werden. Bis auf weiteres wird davon

20 2. Mögliche Ansätze zur Verhinderung von Man-In-The-Middle Angriffen ausgegangen, es existiere bereits ein Verfahren, welches die ein- und ausgehenden Netzwerk- pakete eines Skype-Clients eindeutig verschiedenen Kommunikationssitzungen zuordnet. Eine tatsächliche Lösung für dieses integrale Problem wird in Abschnitt 2.3.3 präsentiert. Ein wei- teres grundlegendes Problem dieses Ansatzes stellen indirekte Verbindungen über Relay Hosts dar. Ohne eine genaue Kenntnis des Aufbaus unterschiedlicher Skype-Pakete und Protokolle dürfte es kaum möglich sein ausgehende Pakete so zu verschlüsseln, dass diese kein Informati- onsleck darstellen, jedoch von dem betreffenden Relay Host als gültig erkannt und weitergeleitet werden. Diese Problematik wird in dieser Arbeit nicht mehr gelöst, jedoch an gegebenen Stellen noch einmal aufgegriffen werden. Anders als bei der Manipulation von Audioströmen, erweist sich die Skype API beim hier zu betrachtenden alternativen Ansatz als wenig hilfreich. So ist es mit keiner der öffentlich bereitgestellten Funktionen möglich das Verhalten eines Skype-Clients in Bezug auf seine Netz- werkverbindungen zu beeinflussen. Über den Dialog „Optionen“ lässt sich jedoch zur Laufzeit ein Proxy-Server manuell eintragen, über den sämtlicher Netzwerkverkehr abgewickelt werden soll. Diese durchaus vielversprechende Funktion wird im Folgenden weiter begutachtet.

2.3.1 Direkte Eintragung eines lokalen Proxy-Server

Wird zur Laufzeit des Skype-Clients im Dialog für Optionen ein Proxy-Server mit Host und Port eingetragen3, so werden diese Eingaben vom Skype-Client in der Datei shared.xml im Ord- ner für Anwendungsdaten des aktuellen Nutzers gespeichert. Anschließend wird der Nutzer des Clients aufgefordert, diesen zu beenden und erneut zu starten, um die getätigten Änderungen wirksam werden zu lassen. Dies ist jedoch nur möglich, sofern nicht bereits ein Proxy-Server für Skype in der Registry des betreffenden Systems unter der Verwendung von Administrations- rechten eingetragen wurde4. Widersprechen sich die Eintragungen in einer Konfigurationsdatei wie shared.xml und der Registry, so gewichtet ein Skype-Client letzteres immer höher. Es wäre also möglich ein Programm zu entwickeln, welches sich selbstständig als Proxy-Server für den auf dem betreffenden System installierten Skype-Client in die Datei shared.xml einträgt. Typischerweise würde solch ein Programm als Host die „loopback“ IP-Adresse 127.0.0.1 wäh- len und anschließend selbst auf dem angegebenen Port auf eine Verbindung des Skype-Clients warten, um nach dem Erfolgen dieser die geforderte zusätzliche Verschlüsselungsschicht für aus- und eingehende Netzwerkpakete zu realisieren.

3Optional lässt sich zudem noch zwischen den beiden Protokollen SOCKS5 und HTTPS wählen. Daneben kann noch ein Nutzername/Passwort Paar zur Authentisierung eingetragen werden. 4Skype Ltd. stellt für Systemadministratoren ein so genanntes Administrative Template für Gruppenrichtlinien (GPO) bereit [29]. Mit Hilfe dessen lassen sich bestimmte Verhaltensrichtlinien für Skype-Clients innerhalb der Registry auf für mehrere Computer setzen. Neben dem Festlegen eines Proxy-Servers werden auch andere, nicht über die Benutzeroberfläche verfügbare Optionen angeboten, wie beispielsweise der „Run in memory-only Mode“ welcher den Skype-Client daran hindert auf das Dateisystem zuzugreifen.

21 2. Mögliche Ansätze zur Verhinderung von Man-In-The-Middle Angriffen

Obwohl dieser Ansatz als sehr praktikabel und gut implementierbar erscheinen mag, wurde er während der Planungsphase dieser Arbeit wieder verworfen, weil einige Nachteile existieren die, bei den weiter unten besprochenen Ansätzen so nicht zu finden sind. So müsste das als Proxy-Server agierende Programm entweder permanent auf dem betreffenden System laufen oder dafür Sorge tragen, dass die Datei shared.xml ständig aktuell ist. Auch wäre es nicht mög- lich ohne Administrationsrechte einen bereits in der Registry eingetragenen Proxy-Server zu ersetzen. Auf Systemen mit einer restriktiv eingestellten Firewall wäre es zudem unter Umstän- den ebenfalls nicht möglich ohne Administrationsrechte die notwendigen Netzwerkports für den lokalen Proxy-Server zu öffnen. Aufgrund dieser Limitierungen wird im Folgenden ein weiteres Verfahren beschrieben, welches schließlich auch für die konkrete Implementierung gewählt wurde. Dieses mag auf den ersten Blick komplizierter wirken als das soeben vorgestellte, jedoch verfügt es über einige signifikante Vorteile, welche den Mehraufwand lohnend machen.

2.3.2 Umleitung von Windows Sockets API Aufrufen

Verfügt eine Anwendung über keinen eigenen Treiber, so ist es dieser in aller Regel nicht möglich direkt mit den Endgeräten eines Computers zu kommunizieren. Stattdessen stellen moderne Betriebssysteme im Allgemeinen standardisierte Schnittstellen bereit, über welche Program- me beispielsweise Audiodateien abspielen, Bewegungen der Computermaus abfragen oder eben Netzwerkpakete verschicken lassen können ohne tatsächlich Kenntnis über die dahinterstehen- den Hardwarekomponenten zu haben. Das Windows Betriebssystem stellt Programmen für derlei und andere Aufgaben5 die so genannte Windows API bereit. Aus Anwendungssicht stellt sich diese Windows API als Sammlung von Dynamic Link Library (DLL) dar, welche jeweils eine Menge von Funktionen verfügbar machen, die ein bestimmtes Gebiet betreffen. So „ex- portiert“ die DLL Kernel32.dll alle grundlegenden Funktionen des Systems, wie zum Beispiel Dateisystemzugriffe oder das Erstellen von neuen Prozessen, während zum Beispiel User32.dll vornehmlich die Erstellung von GUI-Elementen über Funktionen wie MessageBoxA() ermög- licht. Interessant für das gegebene Vorhaben ist die DLL Ws2_32.dll. Diese stellt sämtliche, die dritte und vierte Schicht des ISO/OSI-Modells [22] betreffende Netzwerkfunktionalität bereit. Abgesehen von der Möglichkeit der direkten Kommunikation mit einschlägigen Systemtreibern wie Afd.sys oder Tcpip.sys [20], gibt es nach Erkenntnissen des Autors für Anwendungen unter Windows keinen anderen Weg neben der Verwendung dieser DLL um auf dem IP-Protokoll

5Tatsächlich wird die Windows API nicht nur für die abstrahierte Kommunikation mit Endgeräten verwendet. Stattdessen wird über diese die gesamte Bandbreite der Funktionen des Betriebssystem den im Userland laufenden Anwendungen zur Verfügung gestellt. Dies beinhaltet zum Beispiel auch sämtliche Funktionen zum Erstellen von GUI-Elementen oder den Heap einer Anwendung betreffende Funktionen.

22 2. Mögliche Ansätze zur Verhinderung von Man-In-The-Middle Angriffen basierende Netzwerkverbindungen - beispielsweise TCP oder UDP Protokollsitzungen - aufzu- bauen. Es sei angemerkt, dass die direkte Kommunikation mit Systemtreibern zur Übertragung von Netzwerkpaketen äußerst unüblich und aufwändig ist (zum Beispiel können Unterschiede zwischen einzelnen Windows Versionen existieren) und hier nur der Vollständigkeit halber er- wähnt wird. Soll ein Programm über das Internet kommunizieren, so kommt es also im Allgemeinen schlicht- weg nicht umhin, die DLL Ws2_32.dll zu verwenden. Folglich müssen auch sämtliche Netz- werkpakete des Skype-Clients Funktionen dieser DLL passieren. Damit ein Programm von einer DLL bereitgestellte Funktionen aufrufen kann, muss die betreffende DLL zur Laufzeit in den Adressraum jenes Programmes geladen werden. Folglich ist im Adressraum sämtlicher Programme, die über Netzwerkfunktionalität der Schichten drei oder vier verfügen, die Datei Ws2_32.dll zur Laufzeit zumindest zu einem bestimmten Zeitpunkt vorzufinden. Um beispiels- weise ein UDP-Paket zu versenden, muss so ein Programm dann nur noch die Funktion send() innerhalb von Ws2_32.dll mit den entsprechenden Parametern aufrufen [12]. Genauso wie hier

Skype-Prozess

Skype-Client

Kernel32.dll, User32.dll, ...

socket( ) send( ) WSASendTo( ) recv( ) Black Box ...

Ws2_32.dll NIC

Abbildung 2.3.: Skype-Prozess mit geladenen System-Dlls allgemein rudimentär beschrieben, stellen sich auch die Abläufe innerhalb des Prozesses des Skype-Clients dar: Schlussendlich wandert sämtlicher ein- und ausgehender Netzwerkverkehr des Skype-Clients durch wenige von Ws2_32.dll bereitgestellter Funktionen (siehe auch Ab- bildung 2.3). Konkret werden folgende API-Funktionen für das Senden und Empfangen von Netzwerkpaketen aufgerufen: send() (TCP) recv() (TCP) sendto() (UDP) recvfrom() (UDP)

23 2. Mögliche Ansätze zur Verhinderung von Man-In-The-Middle Angriffen

Offensichtlich genügt es, diese Funktionen aus Ws2_32.dll innerhalb des Prozesses des Skype-Clients zu ersetzen oder hinreichend zu modifizieren, um die geforder- te Kontrolle über den Netzwerkverkehr zu erhalten. Um solch einen gewissermaßen prozessinternen Proxy-Server zu realisieren, gibt es mehrere bekannte Ansätze auf die hier im einzelnen nicht eingegangen werden soll. Die dabei wohl am weitesten verbreitete Technik nennt sich API Hooking. Diese wird im Folgenden genauer erläutert und findet auch Verwendung in der konkret programmierten Verschlüsselungslösung für Skype. Neben dieser Technik wurde auch die Möglichkeit der Programmierung eines so genannten Layered Service Providers erwogen [8]. Ist solch einer auf einem System installiert, so wird die zugehörige DLL automatisch immer zusätzlich zu Ws2_32.dll in den Adressraum eines Prozesses geladen und erhält Zugriff auf alle eingehenden und ausgehenden Netzwerkpakete. Da somit alle Prozesse mit Netzwerkinteraktion auf einem System betroffen sind, wird diese Technik häufig auch von Firewall-Lösungen unter Windows eingesetzt. Da für die Installation eines Layered Service Providers Administrations- rechte erforderlich sind, wurde der Ansatz hier jedoch wieder verworfen.

2.3.2.1 Windows API Hooking

Die Technik des API Hookings wird sich allgemein häufig zunutze gemacht, wenn unter Win- dows das Verhalten eines Programmes zur Laufzeit verändert oder generisch überprüft werden soll. So überschreiben beispielsweise eine Vielzahl von Anti-Viren-Lösungen die Einstiegspunk- te von API Funktionen der Windows DLLs in jedem neuen Prozess dynamisch mit einer Art Umleitung in ihren eigenen Programmcode - im Jargon „Hook“ genannt - um Programme auf verdächtige Verhaltensmuster hin zu überprüfen [33]. Auch die Firma Microsoft verwen- det solche Hooking Techniken um das Einspielen von Updates im laufenden Systembetrieb zu ermöglichen. Anstatt nur Systemdateien auf der Festplatte zu ändern und anschließend einen Neustart zu fordern, werden die Einstiegspunkte von zu aktualisierenden Funktionen im Ar- beitsspeicher so verändert, dass bei einem Aufruf die Programmausführung automatisch zur fehlerbereinigten Version jener Funktion verzweigt. Im Falle des zu beeinflussenden Skype-Clients bietet die breite Verwendung dieser Technik den Vorteil, dass Skype-Clients sich gegen diese nicht zur Wehr setzen können, sofern die Herstel- lerin Skype Ltd. keine Fehlalarme bei Anti-Viren Produkten oder Inkompatibilitäten riskieren möchte. Im Kontrast zu den ansonsten allgegenwärtigen Abschottungsversuchen des Skype- Clients, lassen sich so auch tatsächlich die Einstiegspunkte von geladenen DLLs zur Laufzeit nach belieben manipulieren. Es bleibt die Frage, auf welchem Wege diese Umleitungen innerhalb des Skype-Prozess installiert werden können. In [25] wird dazu unter anderem eine Vorgehens- weise präsentiert, mit deren Hilfe sich nachträglich beliebige DLLs in einen fremden Prozess laden lassen. So wird es möglich Daten und Kontrollflüsse innerhalb eines Prozesses beinahe

24 2. Mögliche Ansätze zur Verhinderung von Man-In-The-Middle Angriffen beliebig zu verändern - und somit natürlich auch Hooks an Einstiegspunkten zu Windows APIs zu platzieren. Für dieses Platzieren von Hooks in Funktionen stellt die Firma Microsoft eigens ein Softwa- reentwicklungskit (SDK) namens Detours für die Programmiersprache C öffentlich zum Dow- nload bereit [37]. Dieses kann nach der gegebenen Lizenz für den privaten Gebrauch und zu Forschungszwecken kostenlos verwendet werden. Für den kommerziellen Gebrauch sind jedoch Lizenzgebühren vorgesehen. Trotz dieser nicht vollkommen freien Lizenz, wird dieses SDK in der hier noch genauer vorzustellenden Implementierung verwendet. Es ließe sich jedoch vermut- lich auch leicht durch eine freiere Alternative wie [34] ersetzen. Bereits in [38] wurde ein vom

Skype-Prozess

Skype-Client

Kernel32.dll, User32.dll, ...

socket( ) send( ) send( ) WSASendTo( ) recv( ) recv( ) Black Box ...

hook.dll Ws2_32.dll

Kommandos Argumente API-Funktionen

Python Interface

Abbildung 2.4.: Skype-Prozess mit gehookten Funktionen send() und recv() (über Python Inter- face).

Autor entwickeltes Interface für die Sprache Python vorgestellt, welches wie beschrieben eine eigene DLL in einen beliebigen Prozess lädt, um anschließend das Hooken von beliebigen API- Funktionen zu ermöglichen. Python-Skript und DLL kommunizieren dabei über so genannte „Named Pipes“, wobei die Python Seite die Namen abzufangender API-Funktionen und an- dere Kommandos übergibt und anders herum im Falle eines Treffers die an die betreffende API-Funktion übergebenen Argumente erhält. Dieses Interface wurde gerade zu Anfang die- ser Arbeit häufig zum Prototyping und zur Beobachtung des Verhaltens des Skype-Clients zur Laufzeit verwendet - gerade auch in Bezug auf Aufrufe in Ws2_32.dll. Eine schematische Dar- stellung dieser Lösung ist in Abbildung 2.4 zu sehen. Für die Implementierung der eigentlichen Verschlüsselungslösung eignet sich dieses Interface jedoch nicht, da sowohl die Skriptsprache Python als auch die gewählte Architektur sich im Zusammenspiel mit Skype als zu langsam für die Echtzeitverschlüsselung erwiesen hat.

25 2. Mögliche Ansätze zur Verhinderung von Man-In-The-Middle Angriffen

2.3.3 Zuordnung von Netzwerkpaketen

Im vorangegangenen Abschnitt wurde ein Verfahren präsentiert, mit dessen Hilfe sich der Netz- werkverkehr des Skype-Clients lokal beliebig mitschneiden und manipulieren lässt. Da sämtli- cher Verkehr innerhalb des Skype-Netzwerks massiv obfuskiert und in den allermeisten Fällen verschlüsselt ist [42], lassen sich die ein- und ausgehenden Pakete eines Skype-Clients zunächst nicht analysieren und einer bestimmten Sitzung oder Zweck zuordnen. Dies ist jedoch für die geforderte Verschlüsselungslösung unerlässlich, denn schließlich sollen ausnahmslos alle zu einer zu schützenden Kommunikationssitzung gehörenden Netzwerkpakete vor dem endgültigen Ver- senden noch einmal nachvollziehbar sicher verschlüsselt werden und umgekehrt möglichst alle eingehenden Pakete vor dem Weiterleiten an den Skype-Client wieder korrekt entschlüsselt wer- den. Ist eines von beiden nicht gewährleistet, so liefert die zusätzliche Verschlüsselungsschicht keinen Sicherheitsgewinn oder die Interaktion des Skype-Clients mit dem übrigen Netzwerk wird gestört, was zu einem deutlichen Qualitätsverlust für den Anwender führen kann. Im Folgenden werden daher zwei Ansätze zur Klassifizierung des Netzwerkverkehrs eines Skype- Clients zur Laufzeit diskutiert. Beide sind dabei grundverschieden und liefern alleine keine ab- schließende, allumfassende Lösung. Auch wenn zum aktuell vorliegenden Entwicklungsstand der angefertigten Verschlüsselungslösung nur der zweite von beiden zum Einsatz kommt und so zumindest die unbedingte Sicherheit von Telefonaten garantiert, so wäre doch im äußersten Idealfall eine Kombination aus beiden Ansätzen wünschenswert.

2.3.3.1 Deobfuskierung von Netzwerkpaketen

Wie bereits erwähnt, obfuskiert ein Skype-Client sämtlichen Payload6 ausgehender Netzwerk- pakete zusätzlich zu jedweder Verschlüsselung. Nach [42] wird für diese Obfuskierung eine Abwandlung der Stromchiffre RC4 verwendet. Während die eigentliche Schlüsselstromgenerie- rung unangetastet blieb, wurde der initiale Schritt zur dynamischen Berechnung der GF (2)8 → GF (2)8 abbildenden S-Box aus einem theoretisch bis zu 256 Bits langem Schlüssel [44] bewusst so abgewandelt und aufgebläht, dass ein Nachvollziehen - gerade in assemblierter Form - zu ei- nem aufwendigen Prozess wird. Trotz dessen wurde in 2010 mit [35] eine Rekonstruktion dieser abgewandelten Initialisierungsroutine in der Programmiersprache C veröffentlicht, welche aus über 2500 Zeilen Programmcode besteht. Zum Vergleich: Eine Implementierung der Standard- funktion kommt typischerweise mit weniger als zwanzig Zeilen aus. Um die Implementierung aus [35] in der Praxis zur Deobfuskierung von Netzwerkpaketen zum Zwecke der Zuordnung zu Kommunikationssitzungen nutzen zu können, ist es natürlich notwendig, den zur Initialisierung

6Selbstverständlich müssen die Headerinformationen des UDP- bzw. des TCP-Protokolls unangetastet bleiben. Gleiches gilt natürlich auch für das darunterliegende IP-Protokoll.

26 2. Mögliche Ansätze zur Verhinderung von Man-In-The-Middle Angriffen verwendeten Schlüssel zu kennen. Nach [42] aus 2006 wird zur Obfuskierung von Paketen im Skype-Netzwerk sowohl für UDP als auch TCP jeweils ein 32 Bit langer Schlüssel verwendet, welcher sich in beiden Fällen einfach aus im Paket im Klartext enthaltenen Werten berechnen lässt (tatsächlich genügt es im Falle von TCP-Paketen die ersten vier Bytes abzulesen). Ein Paket kann also für sich genommen komplett deobfuskiert werden - eine Kenntnis weiterer Pa- kete oder anderer Informationen ist nicht notwendig. Ob dies zum Zeitpunkt der Niederschrift dieser Arbeit, knapp fünf Jahre später, immer noch der Fall ist, ist unklar. Eigene Erkenntnisse durch Reverse Engineering7 legen zumindest nahe, dass dies nicht mehr uneingeschränkt gilt. Zu einem Test der rekonstruierten Funktionen aus [35] in der Praxis kam es während der Recher- che für diese Arbeit nicht, da eine Verwendung in der eigenen Verschlüsselungslösung aufgrund der mit [35] verbundenen Lizenz im Voraus ausgeschlossen wurde. Diese sieht eine freie Nut- zung ausschließlich für Forschungszwecke vor, was wohl einer Verbreitung eines Programms zur privaten Nutzung widerspricht. Stattdessen wurde selbst mittels Reverse Engineering die modi- fizierte RC4 Initialisierungsfunktion innerhalb der Programmdatei des Skype-Clients lokalisiert und analysiert. Mit Hilfe der so gewonnenen Informationen und dem bereits besprochenen Detours SDK konnte eine DLL entwickelt werden, welche sämtlichen Netzwerkverkehr eines laufenden Skype-Clients mitliest und versucht nach [42] zu deobfuskieren. Es sei betont, dass dabei keine eigene Variante der modifizierten Initialisierungsroutine entwickelt wurde. Stattdes- sen wurde direkt zu der betreffenden Funktion innerhalb des Programmcodes des Skype-Clients gesprungen und die Ergebnisse anschließend ausgewertet und in einer Datei protokolliert (siehe Abbildung 2.5). Ein Auszug des Programmcodes zur Deobfuskierung von Paketen ist in Listing

Skype-Prozess

Skype-Client ... send( ) send( ) recv( ) recv( ) sendto( ) sendto( ) recvfrom( ) recvfrom( ) RC4_Init( ) Ws2_32.dll deob.dll

Logdatei

Abbildung 2.5.: Deobfuskierung und Protokollierung von Netzwerkpaketen.

A.2 auf Seite 87 zu finden. Der vollständige Programmcode der DLL ist auf dem beiliegenden

7Aufgrund des gegebenen Rahmens dieser Arbeit werden die beim Prozess des Reverse Engineerings des Skype- Clients vollzogenen Schritte hier nicht näher erörtert. Es sei nur angemerkt, dass zur Laufzeit ein Abbild des im Speicher entschlüsselten Programmcodes erstellt wurde, welches dann mit Hilfe des Programms IDA Pro weitestgehend statisch analysiert wurde.

27 2. Mögliche Ansätze zur Verhinderung von Man-In-The-Middle Angriffen

Datenträger enthalten. Eine Analyse der so gewonnenen Protokolldateien zeigt, dass zumindest einige TCP Pakete korrekt deobfuskiert werden konnten. So ist mehrfach die Byte-Folge 00 00 00 01 00 00 00 0F zu finden, welche zwar nicht komplett der in [42] beschriebenen entspricht, jedoch mit an Sicherheit grenzender Wahrscheinlichkeit den Fixwert zur Verifizierung einer korrekten Deobfus- kierung darstellt. Bei sämtlichen anderen Paketen konnte durch die reine Analyse im Hexeditor kein Hinweis auf eine korrekte Deobfuskierung gefunden werden. Mangels Zeit und den nur langsam zu erwartenden neuen Erkenntnissen wurde auf eine weitere Analyse mittels Reverse Engineering und Anderem hier verzichtet. Es bleibt jedoch festzuhalten, dass dieser Ansatz durchaus soweit ausgebaut werden könnte, dass zu jedem Paket, handele es sich um TCP oder UDP, anhand von enthaltenen Metadaten der Datentyp und der Empfänger bestimmt werden könnte. Somit ließen sich im Vertrauen auf die Korrektheit jener Metadaten (Stichwort „Skype- Client ist nicht bösartig“, siehe Abschnitt 1.4.1) Pakete wie gewünscht zuordnen. Solche Pakete die ein zu verschlüsselndes Telefonat beträfen, würden verschlüsselt, alle anderen nicht. Es blie- be jedoch das bereits schon zuvor öfter erwähnte Problem, dass unter bestimmten, bis dato unbekannten Umständen ein Skype-Client ein unerwartetes Verhalten an den Tag legen könn- te und so eigentlich zu schützende Informationen ohne zusätzliche Verschlüsselung übertragen würden. Ein möglicher Weg aus dieser Problematik ist das ausschließliche Übertragen von zusätzlich verschlüsselten Paketen während einer entsprechenden Sitzung. Diese Herangehensweise lässt sich jedoch einfacher auf anderem Wege, wie im Folgenden beschrieben, realisieren.

2.3.3.2 Austausch von Verbindungslisten

Da die Zuordnung von Netzwerkpaketen anhand ihres Inhalts im Falle von Skype aufwendig ist und zudem auch dem Ansatz des Betrachtens des Skype-Clients als Black Box widerspricht, soll hier ein weiteres, einfacheres Verfahren vorgestellt werden, mit Hilfe dessen ein- und ausgehende Netzwerkpakete des Skype-Clients unterschiedlichen Sitzungen zugeordnet werden können. Wie bereits dargelegt werden die für eine Kommunikationssitzung notwendigen Daten zwischen zwei Clients im Skype-Netzwerk im Regelfall über P2P Verbindungen ausgetauscht. Folglich ge- nügt es dann die für die jeweilige P2P Verbindung verwendeten IP-Adressen, Protokolle (TCP oder UDP) und Ports zu kennen und die über diese übertragenen Daten zu verschlüsseln, re- spektive zu entschlüsseln, und gegebenenfalls sämtliche anderen Verbindungen temporär zu unterbinden. Die naheliegendste Herangehensweise wäre dabei wohl, dass die Verschlüsselungs- lösungen auf beiden Seiten einer Kommunikationssitzung sicher ihre IP-Adressen austauschen um anschließend an der Sitzung beteiligte Protokolle und Ports zu bestimmen. Dieser Ansatz birgt jedoch mindestens zwei Unklarheiten: 1.) Ist es in den meisten Fällen wohl nicht gegeben,

28 2. Mögliche Ansätze zur Verhinderung von Man-In-The-Middle Angriffen dass ein PC ohne weiteres seine eigene IP-Adresse in Bezug auf das Internet kennt8 und 2.) muss auf irgendeinem Wege vor einer Verschlüsselung eine Verbindung mit dem Partner aufge- baut werden, um beispielsweise die Bereitschaft zur zusätzlichen Verschlüsselung zu erfragen, obwohl dessen IP-Adresse prinzipbedingt noch nicht bekannt sein kann. Bei der Lösung von 2.) ist von Ansätzen wie dem Senden von Erkennungsnachrichten an alle bekannten, mit dem Skype-Client in Verbindung stehenden Hosts abzusehen, da bereits in Ab- schnitt 1.4 festgelegt wurde, dass sich die zusätzliche Verschlüsselungslösung minimal inversiv verhalten - also nicht unnötig auf ihr Vorhandensein im Skype-Netzwerk aufmerksam machen soll. Hier bietet die öffentliche Skype API die Möglichkeit der Kontaktaufnahme mit einem neuen Kommunikationspartner im Einklang mit dieser Vorgabe. So ist es über jene API mög- lich Textnachrichten zu versenden und auf bereits empfangene zur Laufzeit lesend zuzugreifen. Auch kann sich ein Programm im Falle von Ereignissen wie neu ein- oder ausgehender Anrufe benachrichtigen lassen. So ist es möglich, im Falle eines neuen Anrufes, eine Textnachricht an die Gegenseite mit etwa der Aufforderung zur Verschlüsselung des anstehenden Gesprächs und anderen Informationen zu senden. Läuft zu diesem Zeitpunkt auf der Gegenseite dieselbe Ver- schlüsselungslösung, so kann diese entsprechend antworten. Um 1.) - das Problem der Identifizierung von zu verschlüsselnden Verbindungen - zu lösen, sind nun wohl mehrere Herangehensweisen denkbar. Hier soll davon nur eine besprochen werden, nämlich diejenige, die auch schließlich für die Implementierung der eigenen Verschlüsselungslö- sung gewählt wurde. Geht man davon aus, dass sämtlicher Netzwerkverkehr des Skype-Clients mittels Hooking der entsprechenden Funktionen aus Ws2_32.dll überwacht wird, so ist es möglich, eine Liste aller getätigten Verbindungen des Skype-Clients seit dessen Start zu führen. Eine solche Verbindung wird definiert durch IP-Adresse des anderen Hosts, Protokoll sowie ausgehendem und einge- hendem Port. Vermutlich um sich vor einer generischen Erkennung durch Firewalls zu schützen, verwenden unterschiedliche Skype-Client Installationen einen unterschiedlichen festen Port für eingehende TCP und UDP Verbindungen. Wobei anscheinend während des Installationsvorgangs zumin- dest teilweise zufällig ein Wert aus der für Ports möglichen Menge 0, ..., 216 − 1 gewählt wird. Dieser festgelegte eingehende Port ist also bis zu einem gewissen Grad charakteristisch für eine Skype-Client Installation. Es lässt sich jedoch auch einfach über das Optionsmenü des Skype- Clients manuell verändern. Offenbar wird in den Supernodes des Skype-Netzwerks zu jedem angemeldeten Client auch dieser Port vorgehalten, denn wann immer ein Client eine Verbindung zu einem anderen aufzubauen versucht, so geschieht dies zunächst über jenen Port. Für den Fall, dass es aufgrund lokaler Netzwerkbegebenheiten keine Möglichkeit zu einer freien Portwahl

8Heutzutage werden PCs nur noch in den seltensten Fällen über ein Modem direkt mit dem Internet verbunden. In den meisten Fällen befindet sich zwischen Internet und PC noch ein Router.

29 2. Mögliche Ansätze zur Verhinderung von Man-In-The-Middle Angriffen gibt, so versucht Skype über die unverdächtigen Ports 80 (HTTP) und 443 (HTTPS), welche eigentlich für die Übertragung von Webseiten verwendet werden, Verbindungen aufzubauen9. Dieses Verhalten lässt sich ebenfalls über das Optionsmenü abschalten. Neben den fest eingestellten Ports verwenden nach empirischen Untersuchungen Skype-Clients mitunter noch eine kleine Zahl von weiteren Ports, welche wie zufällig für die jeweilige Sitzung gewählt erscheinen. So ergab sich beispielsweise für ein Telefonat zwischen zwei mit dem In- tranet der Ruhr-Universität verbundenen PCs das in Tabelle 2.1 gegebene Bild, welches als exemplarisch angesehen werden kann

Client Charakt. Port Ausgehende Verbindungen A 61213 61213 → 37805, UDP 2397 → 37805, TCP 2398 → 37805, TCP B 37805 37805 → 61213, UDP 37805 → 2397, TCP 37805 → 2398, TCP Tabelle 2.1.: Verbindungen zwischen Client A und Client B im lokalen Netzwerk nach Anruf von B durch A.

Bis zum Zeitpunkt des Gesprächsaufbaus, hatten beide Skype-Clients im konkreten Beispiel noch jeweils rund 20 Verbindungen mit anderen IP-Adressen und Ports aufgebaut (und mög- licherweise auch schon wieder geschlossen). Es ist nicht unüblich, dass die Länge solcher Ver- bindungslisten auch um ein vielfaches höher liegt. Ohne Vorkenntnisse über IP-Adressen oder Ports zu haben, war es in jenem und in jedem der weiteren durchgeführten Tests, sowohl im Inter- als auch Intranet, möglich, nur mit Kenntnis beider Verbindungslisten, die für die Kom- munikation zwischen beiden beteiligten Clients verwendeten P2P Verbindungen eindeutig zu bestimmen. Können zwei Clients ihre Verbindungslisten austauschen, so ist es ihnen also in den meisten Fällen möglich, ohne Kenntnis der eigenen IP-Adresse oder der des Gegenübers, die an ihrer gemeinsamen Kommunikation über das Skype-Netzwerk beteiligten P2P Verbindungen genau zu bestimmen. Entsprechend ist es anschließend möglich die betreffenden Verbindungen zusätzlich zu sichern. Das genaue Vorgehen beim Bestimmen der zwischen zwei Partnern existierenden Verbindungen mit Hilfe besagter Verbindungslisten beider Seiten ist einfach und intuitiv: Kommt ein Paar, bestehend aus eingehendem und ausgehendem Port, aus der Verbindungsliste von Client A in umgekehrter Richtung auch in der Verbindungsliste von Client B vor, so ist davon auszuge- hen, dass diese Ports für eine Direktverbindung zwischen beiden Clients verwendet werden. In der Praxis muss der Austausch solcher Verbindungslisten natürlich kryptographisch gesi-

9Beobachtungen legen nahe, dass häufig Supernodes auf Port 433 auf Verbindungen warten.

30 2. Mögliche Ansätze zur Verhinderung von Man-In-The-Middle Angriffen chert erfolgen und dem Ergebnis kann zudem auch nicht abschließend vertraut werden. So ist es notwendig, während die identifizierten P2P Verbindungen verschlüsselt werden, sämt- liche anderen Verbindungen zu blockieren, um Irrtümern oder dem unvorhergesehenem Ver- halten eines Skype-Clients vorzubeugen. Auch werden natürlich durch einen Austausch von kompletten Verbindungslisten Informationen über Verbindungen zu dritten Parteien innerhalb des Skype-Netzwerks preisgegeben (es sei hier jedoch schon einmal erwähnt, dass zumindest die Übermittlung von konkreten IP-Adressen nicht notwendig ist, anonyme Platzhalter sind hier ausreichend). Zudem dürfte klar sein, dass Verbindungen über Relay Hosts sich in den meisten Fällen wohl nicht eindeutig identifizieren lassen. Trotz dieser Widrigkeiten, wird dieses Verfahren als alleiniges in der eigenen Verschlüsselungs- lösung verwendet. Wie dabei im Detail verfahren wird und welche Protokolle zwischen zwei verschlüsselungswilligen Parteien ablaufen, wird im anschließenden Kapitel eingehend behan- delt.

2.3.4 Bewertung

Im Unterschied zur Prä-Audio-Codec-Verschlüsselung ist die Netzwerkpaketverschlüsselung mit gewöhnlichen symmetrischen und asymmetrischen kryptographischen Algorithmen sowie be- kannten technischen Methoden realisierbar. Daher fiel für die Implementierung der zusätzli- chen Verschlüsselungsschicht auch die Wahl auf diesen Ansatz. Im Speziellen wird dabei eine Kombination aus Windows Sockets API-Hooking und dem beschriebenen Austausch von Ver- bindungslisten zwischen zwei Clients über Textnachrichten angewandt. Wie genau damit die Kommunikation zwischen zwei Teilnehmern über P2P Verbindungen nachvollziehbar gesichert und auf welche kryptographischen Verfahren und Protokolle dabei geeigneter Weise zurück- gegriffen werden kann, wird im folgenden Kapitel adressiert. Unbehandelte Probleme bleiben Kommunikationssitzungen mit mehreren Teilnehmern und die Sicherung von Verbindungen über Relay Hosts. Auch wenn zu letzterem nur sporadische Versuche und Nachforschungen angestellt wurden, ist davon auszugehen, dass sich dieses Problem im Falle der Netzwerkpaket- verschlüsselung nicht ohne die in Abschnitt 2.3.3.1 behandelte Deobfuskierung von ausgehenden Paketen zur Laufzeit lösen lässt. Anders ausgedrückt ist eine Deep Packet Inspection hier wohl unerlässlich. Die eigentlich gewünschte Betrachtungsweise des Skype-Prozesses als Black Box müsste dafür zumindest in Teilen aufgegeben werden. In der alltäglichen Anwendung sollten Verbindungen über Relay Hosts jedoch eher selten vorkommen. Nach Ansicht des Autors ist daher für die Verschlüsselungslösung legitim, diese nicht zu unterstützen, sofern der Nutzer darauf hingewiesen wird, dass beispielsweise das von ihm angestrebte Telefonat nicht zu ver- schlüsseln ist. Was Kommunikationssitzungen mit mehreren Teilnehmern anbetrifft, wurden ebenfalls nur ver-

31 2. Mögliche Ansätze zur Verhinderung von Man-In-The-Middle Angriffen einzelte Versuche durchgeführt. Hier scheinen die noch zu nehmenden Hürden jedoch bedeutend niedriger zu sein als bei Relay Hosts. So ist es durchaus denkbar, dass die ausgewählten Ver- fahren mit minimalen Anpassungen eingesetzt werden könnten. Inwieweit die Manipulation des Verhaltens des Skype-Prozesses durch das Laden einer zusätz- lichen DLL in diesen im Einklang mit dem End-user License Agreement (EULA) von Skype Ltd. steht, scheint nicht eindeutig beurteilbar. So verbietet die EULA neben dem Reverse En- gineering zumindest die Modifizierung und das „Hacking“ der „Skype Software“ [30]. Nach Ansicht des Autors stellt die Umleitung von Funktionsaufrufen in Ws2_32.dll keinen Verstoß dar, da die Integrität des Skype-Clients im Speicher weiterhin gegeben ist. Anders könnte es sich jedoch in Bezug auf die separaten API Terms of Use verhalten. Hier schließt Skype Ltd. jegliche Verwendung der Skype API aus, sofern die Qualität von Anrufen oder die Stabilität der Skype Software beeinflusst wird [28]. Diesen Bestimmungen könnte das beschriebene Unter- binden von ausgehenden Verbindungen während eines gesicherten Telefonats entgegenlaufen. Da in der noch zu präsentierenden Verschlüsselungslösung die Skype API jedoch nicht direkt für diesen Vorgang verwendet und stattdessen nur für das Versenden von Textnachrichten und das Reagieren auf Ereignisse in Anspruch genommen wird, ist ein tatsächlicher Verstoß wohl nicht gegeben. Durch die strenge Modularität der Komponenten können zudem die Einheit zur Manipulation von Verbindungen und die zur Verwendung der Skype API als zwei getrennte Programme betrachtet werden. Kurzum: Die rechtliche Unbedenklichkeit ist nicht eindeutig zu klären, sie scheint aber wahrscheinlich.

32 3. Implementierung der Verschlüsselungslösung

3 Implementierung der Verschlüsselungslösung

Nachdem in den beiden vorangegangenen Kapiteln zunächst die Entwicklung einer zusätzlichen Verschlüsselungslösung für Skype motiviert und anschließend die dafür geeigneten Ansätze identifiziert wurden, werden in diesem Kapitel schließlich die Details der Implementierung der entsprechend im Rahmen dieser Arbeit programmierten Anwendung watchasayin behandelt. Der Fokus soll dabei klar auf der Erläuterung der strukturellen und funktionalen denn auf der technischen Ebene liegen. Wobei auch einzelne technische Lösungsansätze exemplarisch disku- tiert werden. Während der Implementierungsphase wurde von Anfang an großer Wert auf eine ausführliche, standardisierte Kommentierung im XML-Format gelegt [13], sodass die automa- tisierte Erstellung einer Dokumentation möglich war. Diese liegt wie im Allgemeinen üblich nur in Englisch vor. Sie ist auf dem beiliegenden Datenträger zu finden und liefert genauere Einblicke in die konkreten technischen Realisierungen. Daneben befinden sich auf diesem auch der komplette Quellcode der Anwendung sowie eine fertig kompilierte Variante. Bevor die einzelnen Teilkomponenten für sich beleuchtet werden, wird im Folgenden zunächst ein Überblick über die gesamte Anwendung, ihren strukturellen Aufbau und getroffene Desi- gnentscheidungen gegeben.

3.1 Vorgaben und Ziele

Die in den vorherigen Kapiteln allgemein formulierten konzeptionellen Ziele seien hier für die Anwendung watchasayin zunächst noch einmal zentral in konzentrierter Form wiedergegeben. Daneben sollen im Anschluss zudem eine Reihe von teilweise bisher noch nicht besprochenen, die konkrete Implementierung betreffende technische Vorgaben formuliert werden.

3.1.1 Konzeptionelle Ziele

Die Anwendung watchasayin muss folgende Funktionalität und Eigenschaften aufweisen:

1. Sichere Verschlüsselung von Gesprächen mit zwei Teilnehmern unter herkömmlichen Be- dingungen (vgl. Kapitel1)

2. Authenticated Key-Exchange zwischen verschlüsselungswilligen Parteien (vgl. Kapitel1)

3. Minimalinversives Verhalten in Bezug auf das Skype-Netzwerk, ein Vorhandensein von watchasayin soll von außen nicht bemerkbar sein (vgl. Kapitel1)

33 3. Implementierung der Verschlüsselungslösung

4. Fingerprintvalidierung durch Nutzer sichert AKE und ersetzt Vertrauen in Certificate Authority von Skype Ltd. (vgl. Kapitel1)

3.1.2 Implementierungstechnische Vorgaben

Bei der Implementierung der oben genannten Funktionen sollen folgende Vorgaben eingehalten werden:

1. Betrachtung des Skype-Client als Black Box soweit möglich (vgl. Kapitel2)

2. Realisierung von bilateraler Kommunikation zwischen watchasayin Instanzen über Text- nachrichten (vgl. Kapitel2)

3. Identifizierung von zu verschlüsselnden Verbindungen über Austausch von Verbindungs- listen (vgl. Kapitel2)

4. Möglichst modularer Aufbau zum einfachen Austausch von Komponenten (vgl. Kapitel1)

5. Kontrolle des Skype-Netzwerkverkehrs über Windows Sockets API Hooking (vgl. Kapi- tel2)

6. Objektorientierte Entwicklung der Kernkomponenten in C#

7. Objektorientierte Entwicklung von nativen Komponenten in C++

8. Kapselung von Skype spezifischem Programmcode, minimale Berührungspunkte zum Skype-Client

9. Kommentierung des Quellcodes mit der Möglichkeit der automatisierten Erstellung einer Dokumentation

10. Integration aller Komponenten in Visual Studio 2010 als einheitliches Projekt

Die Punkte sechs bis zehn werden hier zum ersten Mal aufgeführt. Dabei geben die Punkte sechs und sieben zunächst die Wahl der Programmiersprachen vor. Für die eigentliche Anwendung und ihre grundlegende Logik ist die Programmiersprache C# zu verwenden. In C# entwickelte Anwendungen sind zwar nur bedingt auf andere Plattformen als Windows portierbar1, jedoch stellt C# eine der effektivsten Möglichkeiten der Entwicklung von komplexeren Programmen unter Windows dar und bekommt daher den Vorzug gegenüber Java oder anderen Sprachen.

1Mit Mono existiert ein von der Firma Novell unterstütztes Open-Source Projekt, welches in C# entwickelte Anwendungen auf verschiedenen Plattformen wie Linux oder OS X zum Laufen bringt [43]. Die aktuelle .NET Framework Version 4, für die auch watchasayin entwickelt wurde, wird zum momentanen Zeitpunkt jedoch noch nicht von Mono unterstützt.

34 3. Implementierung der Verschlüsselungslösung

Dies sei zudem noch einmal dadurch gerechtfertigt, dass aufgrund der überragenden Verbrei- tung von Windows dies die ausschließliche Zielplattform dieser Arbeit ist. Da sich mit C# keine nativen Programme für die x86 Architektur entwickeln lassen - sprich Programme die in unmittelbar in vom Prozessor ausführbaren Befehlsfolgen vorliegen - können nicht alle Teile von watchasayin in dieser Sprache entwickelt werden. So ist es beispielsweise für das Hooking von Windows Sockets API Funktionen im Prozess des Skype-Clients beinahe unerlässlich eine in nativem Code vorliegende DLL zu entwickeln. In derartigen Fällen soll ob- jektorientiert in der Sprache C++ programmiert werden. Punkt acht sieht vor, dass die Berührungspunkte mit dem Skype-Client minimal gehalten wer- den und Skype spezifischer Programmcode nur in klar abgetrennten Programmteilen zu finden sein soll. So soll der Arbeitsaufwand für eine mögliche Portierung von watchasayin für andere VoIP Produkte minimal gehalten werden - nur die Skype betreffenden Programmteile müssten neu entwickelt werden. Punkt neun fordert eine derartige Kommentierung des Programmcodes, dass, wie bereits weiter oben erwähnt, die automatisierte Generierung einer technischen Dokumentation möglich wird. Schließlich wird unter 10 die Vorgabe gemacht, dass die gesamte Anwendung mit ihren Teil- komponenten (nach Punkt zwei) in einem einzelnen Visual Studio 2010 Projekt vorliegen soll. So wird der Aufwand der Kompilierung der Anwendung auf ein Minimum beschränkt, womit eine höhere Produktivität während der Entwicklung einhergeht. Visual Studio 2010 stellt nach Ansicht des Autors zudem allgemein die effektivste erhältliche Entwicklungsumgebung für C# dar. Mit diesen Vorgaben und Zielen im Hintergrund werden im folgenden Abschnitt die Funktionen der Anwendung watchasayin und ihr struktureller Aufbau betrachtet.

3.2 Das Programm watchasayin

Das Programm watchasayin realisiert die sichere, von Skype Ltd. unabhängige Verschlüsselung von Telefongesprächen zwischen zwei Skype-Nutzern. Es wurde für Windows 7 mit Hilfe von Microsofts Visual Studio 2010 in den Programmiersprachen C++ und C# entwickelt. Durch Letzteres wird zur Ausführung des Programms das .NET Framework 4.0 benötigt, welches sich kostenlos von Microsoft beziehen lässt. Um eine möglichst breite Verwendung der Anwendung zu unterstützen, ist sämtliche Kommunikation mit dem Anwender in Englisch gehalten.

35 3. Implementierung der Verschlüsselungslösung

Abbildung 3.1.: Screenshot der Anwendung watchasayin während eines verschlüsselten Telefonats mit dem Skype-Nutzer flx224.

3.2.1 Funktionen

Gegenüber dem Anwender präsentiert sich die Anwendung watchasayin mit nur wenigen Funk- tionen. Wird das Programm über die Datei Surface.exe gestartet, so öffnet sich, vorausgesetzt das entsprechende .NET Framework ist installiert, unmittelbar eine grafische Benutzeroberflä- che wie in Abbildung 3.1 zu sehen. Diese informiert mit Hilfe von drei permanent sichtbaren Dialogelementen den Benutzer über den aktuellen Ausführungszustand der Anwendung. Ein- mal gestartet, verrichtet das Programm automatisch seinen Dienst, ohne dass eine Bedienung durch den Anwender erforderlich ist. Eine aktive Interaktion zwischen Nutzer und Programm findet ausschließlich mit Hilfe so ge- nannter Message Boxes statt. Diese kommen zur Anwendung bei einmaligen Aktionen wie dem Erstellen eines neuen privaten Schlüssels (siehe Abbildung 3.2) oder im Fehlerfall. Dabei wird der Nutzer ausschließlich nach seiner Zustimmung zu einer bestimmten anstehenden Aktion befragt. In den folgenden Abschnitten werden die nach außen sichtbaren Funktionen der An- wendung einzeln besprochen. Diese Abschnitte können als kurzes Handbuch verstanden werden, in dem zur Orientierung ein Überblick über das Programm aus Anwendersicht gegeben wird bevor die eigentlichen technischen Details erörtert werden.

36 3. Implementierung der Verschlüsselungslösung

Abbildung 3.2.: Message Box zur Abfrage der Zustimmung des Nutzers zur Erstellung eines neuen privaten Schlüssels.

3.2.1.1 Elemente der grafischen Benutzeroberfläche

Als Oberstes von dreien ist, direkt unter dem Logo, in auffälliger Farbgebung die Anzeige des Fingerprints des geheimen Schlüssels des aktuell angemeldeten Nutzers untergebracht. Die 40- stellige Zeichenkette, welche den Fingerprint repräsentiert, wird angezeigt, sobald watchasayin sich erfolgreich mit dem Prozess eines Skype-Clients verbinden konnte. Diese Anzeige kann sich während einer laufenden Sitzung niemals ändern und soll durch ihre permanente und auffällige Präsenz dem Anwender eine einfache Möglichkeit geben, schnell andere Skype-Teilnehmer mit watchasayin Anwendung über den eigenen Fingerprint zu informieren - wie schon in Abschnitt 1.4 besprochen, beispielsweise über eine verschlüsselte E-Mail oder verbal über ein ungeschütz- tes Skype-Telefonat. Direkt unter der Fingerprintanzeige befindet sich eine so genannte List-View, in welcher dem Anwender in Tabellenform Informationen über aktuell laufende Kommunikationssitzungen ge- geben werden. Für jede aktive, von watchasayin unterstützte Sitzung wird hier eine neue Zeile angelegt, welche nach Beendigung der entsprechenden Sitzung wieder gelöscht wird. Da in der aktuell vorliegenden Version von watchasayin ausschließlich Telefonate mit zwei Teilnehmern unterstützt werden, werden auch nur solche hier angezeigt. Die Tabelle verfügt, wie auch in Abbildung 3.1 zu sehen, über vier Spalten. Dabei ist unter Name der Skype-Name des jeweili- gen Kommunikationspartners gegeben, während in der Spalte Type die Art der Sitzung (zum Beispiel call) angezeigt wird. Während diese beiden für jede unterstützte Sitzungsart angezeigt werden, kommen die beiden letzten Spalten nur bei tatsächlich über watchasayin gesicherte Verbindungen zum Tragen. Unter Status wird dabei der Status der Sitzung in Bezug auf ihre Sicherheit angezeigt. Mögliche Zustände sind hier „secure“ für eine sichere Verbindung sowie „-“ und „insecure“ für eine nicht gesicherte bzw. unsichere Verbindung. Um den Nutzer un- mittelbar auf den Wechsel zwischen zwei Zuständen aufmerksam zu machen, werden im Falle eines solchen unterschiedliche Tonfolgen ausgegeben. Es sei bemerkt, dass ein Wechsel von „se- cure“ nach „insecure“ während eines laufenden Telefonats nicht vorgesehen ist, jedoch im Falle

37 3. Implementierung der Verschlüsselungslösung eines unerwarteten Fehlers in einer Komponente denkbar ist und daher auch dem Nutzer soweit wie möglich kenntlich gemacht werden soll. Im unteren Drittel des Programmfensters ist die Ausgabe für Laufzeitinformationen zu finden. Hier werden dem Nutzer während eines Programmlaufs dynamisch Informationen zu internen Abläufen gegeben. Im normalen Betrieb beschränken sich diese Informationen auf ein Minimum, während im Fehlerfall erweiterte Protokolle des betroffenen Moduls angezeigt werden.

3.2.1.2 Verbindung zu Skype-Client Prozess

Unmittelbar nach ihrem Start sucht die Anwendung nach einer bereits laufenden Instanz ei- nes Skype-Clients. Wird solch eine gefunden, so wird sich, wie in den Abschnitten 3.4 und 3.5 noch genauer dargelegt wird, auf unterschiedliche Arten mit dem Prozess des Skype-Clients verbunden. Konnte keine laufende Instanz des Skype-Clients gefunden werden, so wird versucht eine solche neu zu starten. Nach einer erfolgreichen Verbindung zu einer so implizit gestarte- ten Instanz des Skype-Clients enthält die Ausgabe für Laufzeitinformationen folgende Zeilen (vergleiche auch Abbildung 3.1):

Info: Skype appears not to be running. Trying to start it... Successfully attached to Skype process with id: 1234 Connecting to Skype... Connected.

Soll zum ersten Mal eine Verbindung zwischen einer bestimmten Version von watchasayin und der Skype-Installation auf einem PC für einen bestimmten Nutzer hergestellt werden, so ist es nötig, dass der Anwender diese Verbindung auf Seiten des Skype-Clients bestätigt2. Tut er dies nicht, so verwehrt der Skype-Client der watchasayin Anwendung den Zugriff auf seine öffentliche API und das Programm bricht mit einer Fehlermeldung ab.

3.2.1.3 Verwaltung von privaten Schlüsseln und Fingerprints

Ist die Anwendung watchasayin erst einmal mit einem zu schützenden Skype-Client verbun- den, so werden im nächsten Schritt der private Schlüssel und der zugehörige Fingerprint-Store aus lokalen Dateien geladen, wobei Letzterer einfach eine Liste von bekannten und bereits verifizierten Fingerprints anderer Parteien darstellt. Wie diese Dateien intern aufgebaut sind

2Will sich ein Programm erstmalig mit einem Skype-Client verbinden, so wird in einem gelb hinterlegten Bereich innerhalb des Hauptfensters des Skype-Clients eine entsprechende Frage eingeblendet. Der Nutzer hat dort die Möglichkeit auf „Zulassen“ oder „Nicht zulassen“ zu klicken.

38 3. Implementierung der Verschlüsselungslösung soll nicht weiter betrachtet werden. Hier sei nur festgehalten, dass sämtliche kryptographische Daten im Ordner %AppData%\watchasayin\Kryptonite3 für das gerade angemeldete Windows- Nutzerkonto abgelegt werden. Dabei werden die Dateien zur Speicherung von privatem Schlüssel und Fingerprint-Store entsprechend dem Skype-Kontonamen benannt, für den sie erstellt wur- den. Es ist also möglich, dass die Anwendung watchasayin von mehreren unterschiedlichen Windows- Nutzerkonten auf einem Computer aus verwendet wird, ohne dass kryptographisch sensible Da- ten miteinander geteilt werden müssten. Auch können von ein und demselben Windows-Nutzer unterschiedliche Skype-Konten verwendet werden - die korrekten Dateien werden automatisch geladen und geschrieben. Zudem lassen sich die Dateien ohne Weiteres auf ein anderes Windows System kopieren und dort verwenden. Wird watchasayin von einem Windows-Nutzerkonto zum ersten Mal für ein angemeldetes Skype-Konto gestartet, so sind selbstverständlich noch kein privater Schlüssel oder ein Fingerprint- Store vorhanden. In diesem Fall wird die Zustimmung des Anwenders erfragt, ob diese neu erstellt werden sollen (siehe auch Abbildung 3.2). Wurde ein neuer privater Schlüssel erstellt oder konnte ein bereits vorhandener erfolgreich geladen werden, so wird der zugehörige Fingerprint im Anschluss im oberen Drittel des Anwen- dungsfensters angezeigt. Die Anwendung ist dann bereit auf ein- und ausgehende Telefonate zu reagieren und diese zu verschlüsseln.

3.2.1.4 Verbindungsaufbau mit Gegenseite

Konnte sich die Anwendung zu einem laufenden Skype-Client verbinden und zudem sowohl einen privaten Schlüssel laden oder neu generieren als auch einen Fingerprint-Store laden oder neu erstellen, so können im Anschluss Telefonate verschlüsselt werden. Voraussetzung dafür ist selbstverständlich, dass auch auf der Gegenseite eine voll initialisierte Instanz von watchasayin zu finden ist. Tätigt ein Anwender aus der Benutzeroberfläche von Skype heraus einen neuen Anruf, so wird dies von watchasayin detektiert und wie bereits beschrieben durch einen neuen Eintrag in der Tabelle der Kommunikationssitzungen angezeigt. Im Hintergrund versucht watchasayin mit der Gegenseite Kontakt aufzubauen, um das Vorhandensein einer kompatiblen Anwendung zu erfragen. Antwortet die Gegenseite und signalisiert Bereitschaft zu einer zusätzlichen Verschlüs- selung des gerade angestoßenen Telefonats, so vollziehen beide Seiten einen AKE. Sollte dies zum ersten Mal zwischen beiden Parteien der Fall sein, so müssen im Verlauf des AKE die

3Der Ordner %AppData% fungiert dabei als Platzhalter, der abhängig vom aktuell unter Windows an- gemeldeten Nutzer ist. Unter Windows 7 entspricht dieser für das Nutzerkonto abc123 dem Pfad C:\Users\abc123\AppData \Roaming. Dieser Ordner ist allgemein nur für den entsprechenden Nutzer oder Systemadministratoren zugänglich.

39 3. Implementierung der Verschlüsselungslösung

Anwender auf beiden Seiten den Fingerprint des privaten Schlüssels des jeweils anderen veri- fizieren. Dazu wird auf beiden Seiten eine Message Box wie in Abbildung 3.3 angezeigt. Wird so die Korrektheit eines Fingerprints bestätigt, wird dieser zusammen mit dem zugehörigen Skype-Kontonamen im Fingerprint-Store des aktuell aktiven Nutzers gespeichert. Fortan muss dieser Fingerprint nicht mehr verifiziert werden - alle folgenden AKE finden vollautomatisch statt.

Abbildung 3.3.: Message Box zur einmaligen Verifizierung des Fingerprints der Gegenseite bei einem Telefonat (hier mit dem Skype-Nutzer flx224 ).

3.2.1.5 Logging

Während der Entwicklung von watchasayin wurde auf eine genaue Protokollierung von Vor- gängen innerhalb des Programms geachtet. Um den normalen Anwender nicht zu überfordern, wird in der Release Version von watchasayin nur ein Bruchteil der eigentlich anfallenden Sta- tusmeldungen ausgegeben. In der Debug Version der Anwendung werden sämtliche Ereignisse in den externen Teilmodulen von Bottom und Kryptonite zur Laufzeit in Dateien im Ordner %AppData%\watchasayin geschrieben. Protokolliert werden so unter Anderem die Eckdaten sämtlicher ein- und ausgehender Pakete geschützter Verbindungen.

3.2.2 Aufbau und Design

Die Anwendung watchasayin ist unterteilt in drei große unabhängige Module, welche sich wie- derum ihrerseits, soweit möglich, aus unabhängigen Teilmodulen zusammensetzen. Dazu kommt eine eigenständige grafische Benutzeroberfläche (GUI), welche als zusätzliches viertes Modul an- gesehen werden kann, jedoch ordnungstechnisch auf Programmcodeebene dem Surface-Modul zuzuordnen ist. Die Kommunikation zwischen Modulen und Teilmodulen erfolgt dabei über klar definierte und einheitliche Schnittstellen. So soll eine größtmögliche Flexibilität erreicht

40 3. Implementierung der Verschlüsselungslösung werden, die es anderen Entwicklern oder auch Anwendern erlaubt einzelne Teile mit wenig Auf- wand zu ersetzen. Zum Beispiel könnte es durch das Bekanntwerden neuer Sicherheitsprobleme in einem verwendeten kryptographischen Protokoll notwendig werden dieses auszutauschen. Für die übrigen Komponenten würde sich dadurch nichts ändern, da die Sicht auf die einzelnen Komponenten - wie in [19] gefordert - dem auf eine „Black Box“ entspricht. In Abbildung 3.4 ist der grundlegende schematische Aufbau der watchasayin Anwendung mit den Modulen Surface, Kryptonite und Bottom sowie der grafischen Benutzeroberfläche zu se- hen. Das mit In-Process bezeichnete Teilmodul der Bottom-Komponente enthält dabei vor allem die in Abschnitt 2.3.2 besprochene Funktionalität zur Umleitung von Windows Sockets API Aufrufen innerhalb des Skype-Prozesses. Verschiedene damit verbundene Funktionen wer- den dem Bottom Hauptmodul über Microsofts COM bereitgestellt. Die Aufgabe des Bottom- Moduls im Allgemeinen liegt in der Manipulation des Netzwerkverkehrs eines Skype-Clients und in der Feststellung der für ein Gespräch zu verschlüsselnden Verbindungen (siehe auch Abschnitt 2.3.3). Wie der Name bereits andeutet, ist das Kryptonite-Modul für die Bereit-

Skype-Client

Skype API In-Process Kryptogr.

COM Schnittstelle

Kryptonite Surface Bottom

GUI Abbildung 3.4.: Schematischer Aufbau der watchasayin Anwendung mit den Hauptmodulen Surface, Kryptonite und Bottom sowie der GUI. stellung verschiedener kryptographischer Funktionen verantwortlich. Dies beinhaltet vor allem die kryptographische Sicherung von Kommunikation zwischen zwei watchasayin Instanzen über Skype-Textnachrichten sowie den dafür notwendigen AKE. Die tatsächlichen Implementierun- gen der kryptographischen Algorithmen und Protokolle sind dabei in ein externes Teilmodul - in Abbildung 3.4 mit „Kryptogr.“ bezeichnet - ausgelagert. Auch dieses Teilmodul stellt ent- sprechende Funktionalität seinem Hauptmodul mit Hilfe des COM bereit. Die zentrale Komponente stellt das Surface-Modul dar. Es steht über die Skype API (ebenfalls mit Hilfe von Skype4COM über COM) mit dem zu schützenden Skype-Client in Verbindung und reagiert auf Ereignisse wie dem Empfang einer neuen Textnachricht. Wird ein neues Te- lefonat angestoßen, so ist das Surface-Modul verantwortlich sämtliche Schritte einzuleiten, um eine sichere Kommunikation zu ermöglichen. Daneben besteht die große Hauptaufgabe dar- in, den beiden anderen Modulen Bottom und Kryptonite einen Service zur Kommunikation mit ihren entsprechenden Gegenübern auf der anderen Seite eines Telefonats zu ermöglichen. Das Surface-Modul nimmt in gewisser Weise die Rolle eines Routers ein, indem es eingehen-

41 3. Implementierung der Verschlüsselungslösung de Textnachrichten entsprechend ihres Typs an das vorgesehene Modul weiterleitet, sofern die dafür erforderlichen Sicherheitsbestimmungen erfüllt sind4. In der aktuell vorliegenden Versi- on von watchasayin sind zwei entfernte Bottom-Module so in der Lage ihre Verbindungslisten nach Abschnitt 2.3.3.2 auszutauschen. Dabei besitzt das Bottom-Modul keinerlei Kenntnis dar- über, wie der Austausch tatsächlich realisiert und gesichert wird. Zu übertragene Nachrichten werden an das Surface-Modul übergeben, welches die Nachricht in sein eigenes Protokoll ein- bettet und vor dem Versenden vom Kryptonite-Modul verschlüsseln lässt. Eine schematische Abbildung der Kommunikation zwischen den einzelnen Modulen zweier verschlüsselungswilliger watchasayin Instanzen ist in Abbildung 3.5 gegeben. Jede der drei Kernkomponenten verfügt

Client A

Surface Kryptonite Bottom

Skype Textnachrichten Client B

Kryptonite Bottom Surface

Abbildung 3.5.: Kommunikation zwischen Modulen zweier watchasayin Instanzen.

über eine Schnittstelle zur direkten Interaktion mit dem Anwender. So muss das Kryptonite- Module beispielsweise neu erhaltene Fingerprints vom Anwender bestätigen lassen, während das Bottom-Modul entsprechend informieren muss, sobald eine Verbindung gesichert werden konnte. Im vorliegenden Design werden alle drei Schnittstellen zur Nutzerinteraktion von ein und derselben GUI-Komponente bedient. Stattdessen wäre zum Beispiel auch eine Variante mit Kommandozeilenausgabe denkbar.

3.2.2.1 Struktur des Programmcodes

Entsprechend der konzeptionellen Trennung der Anwendung watchasayin in drei große Module gestaltet sich auch die Ordnung des Programmcodes. Dieser teilt sich in drei einzelne, unab- hängig voneinander kompilierbare Visual Studio 2010 Projekte mit den Namen Surface, Bottom und Kryptonite, welche wiederum alle als Teile in dem Dachprojekt watchasayin enthalten sind. Um die komplette Anwendung zu bauen, genügt es diesen Vorgang einmalig für das watchasayin Dachprojekt anzustoßen.

4Wie noch weiter unten dargelegt wird, werden Nachrichten zum Bottom-Modul ausschließlich dann weiterge- leitet, wenn sowohl die Authentizität als auch die Integrität kryptographisch gesichert ist.

42 3. Implementierung der Verschlüsselungslösung

Anders als man zunächst vermuten könnte, enthält das Surface Projekt auch sämtlichen in C# geschriebenen Programmcode der beiden Module Bottom und Kryptonite, während die Visual Studio Projekte Bottom und Kryptonite nur die externen, in C++ entwickelten Teilmodule enthalten, die auch in Abbildung 3.4 zu sehen sind. Diese beiden Projekte produzieren jeweils eine oder mehrere DLLs, auf welche aus der Hauptanwendung über COM zugegriffen wird. Auf sie wird in den Modul bezogenen Abschnitten näher eingegangen. Diese möglicherweise nicht direkt logisch erscheinende Trennung rührt daher, dass die grundlegende Funktionalität der Module Kryptonite und Bottom in ihren externen Teilmodulen implementiert ist. Der C# Code beider Module kann als Vermittlungsstelle zwischen dem zentralen Surface-Modul und den externen Teilmodulen gesehen werden und ist daher in beiden Fällen im Surface Projekt eingeordnet.

watchasayin

Bottom Surface Kryptonite

Protocol Protocol GUI SkypeSpecific Abbildung 3.6.: Schachtelungen der C# Namespaces in watchasayin (Surface Projekt).

In der Programmiersprache C# ist es notwendig, sämtliche Typen innerhalb von so genann- ten „Namespaces“ zu deklarieren [23]. Es ist üblich, thematisch zusammengehörige Typen wie Klassen und Interfaces in einem Namespace zusammenzufassen. Dabei lassen sich Namespaces auch schachteln. So könnte ein fiktiver Namespace Pflanzen die Namespaces Bäume und Gräser enthalten, welche wiederum Klassen zu konkreten Pflanzenarten enthalten würden. In dieser Weise wurde auch beim Aufbau des Programmcodes im Surface Projekt verfahren. In Abbildung 3.6 ist die Struktur der geschachtelten Namespaces zu sehen. Jeder Namespace enthält dabei mitunter eine Vielzahl von Klassen und Interfaces. Entsprechend der Name- spaces verfügt nur das Surface-Modul über direkt an Skype angepassten Programmcode (auch die externen Teilmodule von Bottom und Kryptonite sind nicht speziell an Skype angepasst). Die dazugehörigen Klassen sind im Namespace SkypeSpecific gekapselt. Sollte watchasayin in Zukunft für eine andere VoIP Anwendung angepasst werden oder Skype beispielsweise seine öf- fentliche API grundlegend ändern, so müsste dieser Namespace ersetzt oder angepasst werden. Die Tatsache, dass das Kryptonite-Modul über keinen eigenen Protokoll Namespace verfügt ist der Begebenheit geschuldet, dass, aus noch zu erläuternden Gründen, hier sämtliche Protokolle im externen Teilmodul implementiert sind.

43 3. Implementierung der Verschlüsselungslösung

3.2.3 Das Threading-Modell

In der Informatik bezeichnet der Ausdruck „Thread“ gemeinhin einen aktiven Ausführungspfad innerhalb eines Programms. Dementsprechend besitzt eine einfache „single-threaded“ Anwen- dung nur einen aktiven Ausführungspfad, während eine „multi-threaded“ Anwendung mehrere parallele aktive Ausführungspfade besitzt. Ein Beispiel für Letzteres ist eine Anwendung, die während einer andauernden Berechnung einen Fortschrittsbalken mit einer Schaltfläche zum Abbrechen des laufenden Berechnungsvorgangs anbietet. Innerhalb einer solchen Anwendung müssen im Regelfall mindestens zwei parallele Threads existieren, einer zum Durchführen besag- ter Berechnung und ein weiterer, der verschiedene für das Anzeigen, Aktualisieren und Abfragen der Benutzeroberfläche notwendige Aufgaben wahrnimmt. Entsprechend handelt es sich auch bei watchasayin um eine Anwendung mit Multi-Threading. Dabei verfügt nach der Initialisierung aller Komponenten jedoch nur die GUI über einen eige- nen Thread. Alle anderen Komponenten sind rein passiv. Erst durch das Eintreten bestimmter Ereignisse werden hier neue Threads erstellt, welche während ihrer Ausführung mehrere Modu- le passieren können und nach dem Abarbeiten bestimmter Aufgaben wieder beendet werden. Dabei kann es durchaus dazu kommen, dass parallel mehrere Threads innerhalb eines Moduls aktiv sind, wodurch an manchen Stellen, wie weiter unten genauer beschrieben, bestimmte pro- grammiertechnische Sicherheitsvorkehrungen zu treffen sind (Stichwort „Race Conditions“). In der Anwendung watchasayin gibt es genau zwei Punkte an denen in Reaktion auf Ereignisse neue Threads entstehen können: Im Bindeglied zwischen Surface-Modul und der Skype API im Falle eines neu eintretenden Ereignisses sowie im In-Process-Teilstück des Bottom-Moduls, nämlich genau dann, wenn ein Thread des Skype-Clients in umgeleitete Funktionen innerhalb von Ws2_32.dll verzweigt. Dadurch, dass das In-Process-Teilmodul, genau wie alle anderen Teilmodule, keine Funktionen in den ihm übergeordneten Modul aufrufen kann, haben neue Threads in diesem Teilmodul keine Auswirkungen auf andere Programmteile. Also kann diese Thread-Quelle bei der allge- meinen Betrachtung vernachlässigt werden. Die Anwendung watchasayin verhält sich also rein passiv und reagiert auf die ihr über die Skype API angezeigten Ereignisse innerhalb des Skype-Clients mit der Erstellung eines jeweils neuen Threads, welcher wiederum das ursächliche Ereignis verarbeitet. Ein typisches Ereignis wäre zum Beispiel der Empfang einer Textnachricht eines entfernten Bottom-Moduls. Der neu induzierte Thread würde dabei innerhalb des Surface-Moduls zunächst prüfen, ob die empfangene Nachricht der Form einer Nachricht des Surface-Protokolls (nähere Erläuterungen weiter unten) entspricht und ob eine Nachricht zwischen Bottom-Modulen im ak- tuellen Protokollschritt zugelassen ist. Träfe beides zu, würde im nächsten Schritt die Nachricht an das Kryptonite-Modul übergeben, wo diese validiert und entschlüsselt würde. Anschließend

44 3. Implementierung der Verschlüsselungslösung

würde die Ausführung wieder zurück in das Surface-Modul wechseln, welches die entschlüsselte Nachricht schließlich an das Bottom-Modul übergäbe und nach dessen Verarbeitung zum Ende der Thread-Ausführung käme. Die Anwendung watchasayin ist so gestaltet, dass sämtliche Aufrufe, auch solche zu entfernten Teilmodulen über die COM-Schnittstelle, ausschließlich rein synchron erfolgen. Das heißt die Ausführung kann erst fortgesetzt werden, wenn die aufgerufenen Funktion tatsächlich abgear- beitet wurde (anders ausgedrückt erstellt kein logischer Thread einen neue logischen Thread). Während der Planungsphase wurde auch die Verwendung eines asynchronen Modells in Erwä- gung gezogen, bei dem jedes Modul über einen permanenten Thread verfügt und Ereignismel- dungen aktiv untereinander ausgetauscht werden. Das schließlich verwendete synchrone Modell mit zentraler Thread-Quelle wurde vorgezogen, weil es sauberer zu implementieren und in der Praxis weniger fehleranfällig sein dürfte. Tatsäch- lich gibt es jedoch auch den Nachteil, dass auf Ereignisse in Teilmodulen nicht direkt reagiert werden kann. So muss das Bottom-Modul explizit bei seinem In-Process Teilstück erfragen, ob neue Verbindungen vorliegen oder seit der letzten Abfrage neue Fehler aufgetreten sind. Von sicherheitstechnischer Relevanz ist dies jedoch nicht.

3.2.4 Programmkern und Einstiegsfunktion

In den vorangegangenen Abschnitten wurde der modulare Aufbau der Anwendung watchasayin aus unterschiedlichen Blickwinkeln beleuchtet. Wie die einzelnen Module jedoch zur Laufzeit zusammengefügt werden und wie sich konkret ein Modul ersetzen ließe blieb bisher außen vor. Dies soll sich mit diesem Abschnitt ändern, indem die konkreten C# Klassen watchasay- in.Surface.Core und watchasayin.Program näher betrachtet werden. Obwohl beide Klassen jeweils nur knapp auf 100 Zeilen Programmcode kommen, nehmen sie doch eine sehr zentrale Rolle ein und sind für die Gesamtanwendung von besonderer Bedeu- tung. So definiert die Klasse Core die Kernlogik des Surface-Moduls und damit die der gesamten Anwendung. Sie registriert Callback-Funktionen5 für alle Ereignisse von Interesse und reagiert auf diese entsprechend. In Listing 3.1 ist die Callback-Methode der Core Klasse für neue ein- und ausgehende Anrufe zu sehen.

1 p r i v a t e void onNewCall(string callerHandle , int id, bool outgoing) 2 { 3 lock(activeCalls) 4 {

5Als Callback-Funktionen werden Funktionen bezeichnet, die an andere Funktionen als Parameter überge- ben werden, damit diese zum Beispiel im Falle eines bestimmten Ereignisses aufgerufen werden. Der so eine Funktion als Parameter übergebende Aufrufer einer anderen Funktion erhält also gewissermaßen einen „Rückruf“.

45 3. Implementierung der Verschlüsselungslösung

5 //check if there is already an ongoing call with the given handle 6 i f (activeCalls .ContainsKey(callerHandle)) 7 { 8 return ; 9 } 10 11 //notify the GUI 12 ui.addSession(callerHandle, TSession.call); 13 14 //create new Bottom, Kryptonite and SurfaceComm instances 15 ISurfaceCommunicationSpecific surfaceCommInstance = 16 surfaceComm.getSpecificInstance(callerHandle); 17 18 IBottomExternalCommunicationSpecific bottomInstance = 19 bottom.getSpecificInstance(callerHandle); 20 21 IKryptoniteExternalCommunicationSpecific kryptoniteInstance = 22 kryptonite.getSpecificInstance(callerHandle); 23 24 //create new call object 25 CallSession callSession = new CallSession(callerHandle, id, 26 surfaceCommInstance, kryptoniteInstance, bottomInstance); 27 28 //if this side started the call, start the Surface protocol. 29 i f (outgoing == true) 30 { 31 callSession.start(); 32 } 33 activeCalls.Add(callerHandle, callSession); 34 } 35 }

Listing 3.1: C# Programmcode des Callbacks onNewCall() der Klasse watchasayin.Surface.Core

Diese veranlasst zunächst für jeden neuen Anruf das Hinzufügen eines entsprechenden Eintrags in die Liste der aktiven Kommunikationssitzungen der GUI. Im Anschluss werden in den Zeilen 14 bis 22 drei neue, an den speziellen Anruf gebundene Instanzen der Module SurfaceComm, Bottom und Kryptonite durch Aufruf der entsprechenden „Fabrikmethoden“ (vgl. [3] Seite 846) angefordert. Dabei liefert eine solche Instanz der SurfaceComm Komponente die Möglichkeit das Surface-Protokoll ausschließlich mit dem gegebenen Partner auszuführen ohne Kenntnis der darunter befindlichen Schichten. Dass in dem gegebenen Fall sämtliche Surface-Protokoll Sit- zungen parallel über entsprechend zu sortierende Skype-Textnachrichten abgewickelt werden, bleibt verborgen. Gleiches gilt auch für die beiden anderen Instanzen, welche in ihren Protokol- len ebenfalls ausschließlich mit dem festgelegten Partner kommunizieren und dabei wiederum unbewusst das Surface-Protokoll als Transportmedium nutzen. Wie genau dieses geschichtete Modell aussieht wird in Abschnitt 3.4.1.2 erläutert. In Zeile 25 werden die drei neu erstellten Instanzen anschließend zu einem neuen Objekt der Klasse CallSession zusammengefügt, welches fortan über die gesamte Lebensdauer den gegebe- nen Anruf repräsentiert. Der Konstruktor der Klasse CallSession setzt die erhaltenen gebunde-

46 3. Implementierung der Verschlüsselungslösung nen Instanzen dabei so zusammen, dass das SurfaceComm Objekt als Kommunikationsanbieter für die beiden anderen Objekte installiert wird. Handelt es sich bei betreffendem Telefonat um ein ausgehendes, so wird in Zeile 31 schließlich der Start des Surface-Protokolls angestoßen. Dies hat im ersten Schritt nur das Senden einer Syn Nachricht zur Folge, worauf die watchasayin Anwendung des Angerufenen - für den Fall, dass diese gewillt ist eine verschlüsselte Sitzung zu starten - mit einem Ack antwortet. Nach Abschnitt 3.2.3 wird eine solche Antwort jedoch nicht mehr vom aktuellen Thread verarbeitet, sondern von einem durch das Ereignis einer neu eintreffenden Nachricht neu erstellten Thread. Folglich wird hier auch auf keine eintreffenden Nachrichten gewartet. Abschließend wird in Zeile 33 das erstellte CallSession Objekt unter dem Namen des Kommu- nikationspartners intern gespeichert. Das in Zeile drei zu findende Schlüsselwort lock, welches mit geschweiften Klammern sämtliche Anweisungen der Methode umschließt, schützt vor einer Dateninkonsistenz. Diese könnte ent- stehen, wenn zwei oder mehr unterschiedliche Threads gleichzeitig auf dem Objekt activeCalls arbeiteten. Der Gebrauch von lock verhindert hier unter anderem, dass die Methode onNew- Call() von mehr als einem Thread gleichzeitig betreten wird. Es handelt sich hier also um einen Schutzmechanismus wie er schon in Abschnitt 3.2.3 erwähnt wurde. Neben der Methode onNewCall() besitzt die Klasse Core unter anderem noch das passende Ge- genstück - die Methode onEndCall(). Diese wird, wie der Name bereits andeutet, im Falle der Beendigung eines Telefonats aufgerufen und ist für die Rückabwicklung der mit dem Telefonat verbundenen internen Datenstrukturen zuständig. Bei der Entwicklung der Klasse Core - und

IKryptoniteExternalCommunication IEventDispatcher IBottomExternalCommunication ISurfaceCommunication IUserOutput

Core Klasse

Abbildung 3.7.: Schema der polymorphen Klasse watchasayin.Surface.Core mit den fünf die Basis- konfiguration definierenden Schnittstellen. im Übrigen auch wann immer sinnvoll und möglich bei anderen Klassen - wurde „maximaler Polymorphismus“ (vgl. [3] Seite 995) angestrebt. So sind die konkreten Klassen der in Listing 3.1 verwendeten Objekte surfaceComm, bottom und kryptonite sowie ui allesamt der Klasse Core nicht bekannt. So erwartet der Konstruktor dieser Klasse insgesamt fünf Objekte, welche bestimmten Interfaces genügen müssen (siehe Listing 3.2). public Core(IUserOutput ui , IEventDispatcher eventDispatcher , ISurfaceCommunication surfaceComm, IKryptoniteExternalCommunication kryptonite , IBottomExternalCommunication bottom) {

47 3. Implementierung der Verschlüsselungslösung

this.ui = ui; this .eventDispatcher = eventDispatcher; this .surfaceComm = surfaceComm; this.kryptonite = kryptonite; this .bottom = bottom; //[...] }

Listing 3.2: Abgekürzter C# Programmcode des Konstruktors der Klasse watchasayin.Surface.Core

Somit wird es möglich, dass die Klasse selbst keinerlei Berührungspunkte mit Skype besitzt. Die fünf bei der Erstellung des zentralen Core-Objekts übergebenen Objekte be- stimmen die Basiskonfiguration der watchasayin Anwendung. Hier ließe sich beispiels- weise ein ISurfaceCommunication entsprechendes Objekt übergeben, welches nicht auf Skype- Textnachrichten, sondern auf gewöhnlichen TCP/IP Verbindungen beruht. Die Erstellung des zentralen Core Objekts selbst übernimmt die Klasse Program. Diese ent- hält mit ihrer statischen Methode Main() den Startpunkt der watchasayin Anwendung. Dort werden alle fünf an den Core-Konstruktor zu übergebenden Objekte erstellt und damit die angesprochene Basiskonfiguration festgelegt. So wird beispielsweise in der aktuell vorliegenden Ausprägung der watchasayin Anwendung ein Bottom-Modul, welches innerhalb des Prozesses des Skype-Clients mit Windows Sockets API Hooking arbeitet, wie folgt erstellt, bevor es an den Konstruktor der Core Klasse weitergereicht wird:

Bottom. InProcess bottomInProcess = new Bottom. InProcess(form , pathBottom , NAME_SKYPE, CLASSNAME_SKYPE, pathSkype , t r u e ) ;

Der Konstruktor der Klasse InProcess erhält als Argumente drei Skype spezifische Zeichenket- ten (unter Anderem den Pfad der Datei Skype.exe), mit deren Hilfe er eine DLL in den Prozess eines laufenden Skype-Clients laden oder diesen neu starten kann. Hier wäre es auch möglich, Zeichenketten mit der Beschreibung eines anderen Programmes anzugeben. Interessanter ist wohl jedoch die Möglichkeit ein Objekt einer völlig anderen Klasse zu erstellen, welche auch das Interface IBottomExternalCommunication implementiert. Sollte sich beispielsweise in Zukunft dazu entschieden werden den in Abschnitt 2.3.1 vorgestellten Ansatz der Netzwerkpaketver- schlüsselung mit Hilfe eines lokalen Proxy-Servers zu realisieren, so müsste nur diese Stelle im

Programmcode geändert werden - etwa nach: Bottom.LocalProxy bottom = new Bottom.LocalProxy(form, ... );. Die grundlegenden Zusammenhänge zwischen den einzelnen Modulen sollten hiermit geklärt sein. In weiter unten folgenden Abschnitten werden die entsprechenden Module einzeln be- trachtet, wobei insbesondere ein genauerer Blick auf die eigens entworfenen Protokolle geworfen wird.

48 3. Implementierung der Verschlüsselungslösung

3.3 Verwendung des Component Object Models

Das (COM) ist ein objektorientierter Standard, welcher die plattform- und programmiersprachenunabhängige Interaktion zwischen Softwarekomponenten ermöglichen soll [9]. Mit Hilfe des COM wird dabei nie das „Wie“, sondern ausschließlich das „Was“ definiert. Anders als beispielsweise bei der Einbindung einer DLL, müssen Dinge wie unterschiedliche Calling-Conventions6 aufgrund unterschiedlicher Programmiersprachen nicht beachtet werden. Das COM wurde von der Firma Microsoft erstmals im Jahre 1993 für die damals aktuelle Windows Version 3.1 veröffentlicht und erfuhr seitdem eine große Unterstützung gerade auch, aber nicht nur durch Entwickler auf Windows Plattformen [5]. Eine der für den Endanwender wohl bekanntesten Anwendungen von COM sind die so genannten ActiveX Controls, welche seit vielen Jahren die funktionale Erweiterung des Internet Explorers erlauben. Direkt aus Websei- ten heraus können durch diese ActiveX Controls bereitgestellte Klassenmethoden aufgerufen werden, ohne das Details der tatsächlichen Implementierung berücksichtigt werden müssten. Dass ActiveX Controls für den Internet Explorer lange Zeit eine sehr großes Sicherheitsrisiko darstellten, sei hier nur am Rande erwähnt. Genauso wie die Verbreitung von ActiveX Controls, scheint auch die Verwendung von COM im Allgemeinen in den letzten Jahren zurückzugehen. Trotz dessen wurde sich für den Implementie- rungsteil dieser Arbeit dazu entschieden, für die Kommunikation zwischen in den Sprachen C# und C++ geschriebenen Modulen ganz auf COM zu setzen. Dies liegt darin begründet, dass die Verwendung von COM, nach Ansicht des Autors, die beste Art der Einbindung von in C++ programmierten, in nativem Assemblercode vorliegenden Klassen in einem in C# geschrie- benem Programm darstellt. So ermöglicht es die verwendete Entwicklungsumgebung Visual Studio 2010 aus in C# geschriebenem Programmcode auf über COM bereitgestellte Klassen und deren Objekte, welche sich tatsächlich möglicherweise sogar in einem anderen Prozess be- finden, so zuzugreifen, als wären diese lokal im eigenen Code definiert. Dazu genügt es, eine ein COM-Interface beschreibende DLL als Referenz einem C# Projekt hinzuzufügen. Sämtliche für das anschließende Ansprechen dieses Interfaces notwendigen Informationen werden auto- matisch aus solch einer DLL extrahiert. Fügt man beispielsweise so die Datei Skype4COM.dll einem Projekt hinzu, so ist es im Anschluss mit folgendem einfachen C# Code möglich, ei- ne Skype-Textnachricht mit dem Inhalt „Beispielnachricht“ an den Nutzer „Beispielnutzer“ zu versenden: using SKYPE4COMLib; //[...]

6Für native kompilierte Programme existiert eine Reihe von nicht vollständig standardisierten Konventionen zum Aufruf von Funktionen. Als Beispiel seien hier die bekanntesten stdcall und cdecl genannt, die sich im Allgemeinen darin unterscheiden, dass bei letzterem der Aufrufer einer Funktion selbst wieder sämtliche Argumente vom Stack zu entfernen hat.

49 3. Implementierung der Verschlüsselungslösung

s t at i c class Example { const int SKYPE_PROTOCOL_VERSION = 8 ;

s t at i c void Main ( ) { //Erstellen eines neuen Skype Objekts skype = new Skype(); //Herstellen einer Verbindung zum Skype−C l i e n t skype . Attach (SKYPE_PROTOCOL_VERSION) ; //Senden einer Nachricht skype.SendMessage("Beispielnutzer" , "Beispielnachricht"); } }

Listing 3.3: Beispielprogramm zum Senden einer Textnachricht über das Skype-Netzwerk.

Zur Laufzeit des in Listing 3.3 gegebenen Programms würde die Skype4COM DLL als so ge- nannter „In-Process Server“ in den eigenen Prozess geladen und stünde ausschließlich innerhalb diesem zur Verfügung. Neben der Realisierung als In-Process Server gibt es beim herkömmlichen COM noch die Möglichkeit der Erstellung eines „Out-Of-Process Servers“, welcher nach [9] als eigenständig ausführbare Datei (EXE) vorliegen muss. Wie der Name bereits sagt, laufen solche Out-Of-Process-Server nicht in den Prozessen in denen sie verwendet werden, sondern stellen eigenständige Programme dar, welche bei Bedarf gestartet werden und zentral Anfragen ande- rer Prozesse bedienen. Aus Sicht eines C# Entwicklers macht es keinen Unterschied, ob eine Klasse von einem In-Prozess- oder einem Out-Of-Process-Server bereitgestellt wird. Der Pro- grammcode in Listing 3.3 könnte unverändert auch im zweiten Fall verwendet werden. Beiden Servertypen gemein ist, dass sie die von ihnen angebotenen Klassen in der Windows-Registry unter einem weltweit einzigartigen „Class-Identifier“ (CLSID) von 128 Bit Länge eintragen. In solch einem Eintrag wird unter Anderem angegeben, um welchen Servertyp es sich handelt, wo die das Interface näher beschreibende Programmdatei zu finden ist und welches Threading- Modell verwendet wird (single-threaded oder multi-threaded). Die beiden externen Teilmodule der watchasayin Komponenten Bottom und Kryptonite stellen, wie bereits erwähnt, ihre Funktionalität dem Hauptmodul mittels COM bereit. Während es sich beim Kryptonite-Modul dabei auf einen In-Process Server zurückgegriffen wird, ist dies beim Bottom-Modul selbstverständlich nicht möglich, da dort das externe Teilmodul zwingend im Prozess des zu schützenden Skype-Clients zu laufen hat. Folglich wird hier ein Out-Of-Process- Server verwendet, welcher innerhalb des Skype-Prozesses gestartet wird. Innerhalb des C++ Codes der beiden Module wird für die Implementierung von nach außen bereitzustellenden Klassen Microsofts Active Template Library (ATL) [7] verwendet. ATL-Klassen lassen sich mit Hilfe von Visual Studio mit wenigen Mausklicks erstellen, wobei die Entwicklungsumgebung alle nötigen Schritte zur Exportierung dieser automatisch übernimmt. Durch eine entsprechen- de Konfiguration des watchasayin Projekts lassen sich so erstellte C++ Klassen unmittelbar

50 3. Implementierung der Verschlüsselungslösung danach im C# Programmcode verwenden. Das manuelle Bereitstellen von Klassen über COM ohne die Verwendung von ATL und den Hilfsfunktionen von Visual Studio wäre vermutlich recht aufwändig und unkomfortabel. Jedoch gibt es auch beim hier gewählten Weg einige Schwierigkeiten, die die Entwicklung von ATL- Klassen im Vergleich zur Entwicklung von normalen C++ Klassen aufwändiger machen. So können keine beliebigen Datentypen7 an Methoden über COM übergeben und andersherum auch nicht zurückgegeben werden. Welche Funktionalität die externen Teilmodule konkret über COM bereitstellen wird in den Abschnitten 3.5 und 3.6 besprochen.

3.4 Basismodul - Surface

Das Surface-Modul stellt aus struktureller Sicht den Kern der Anwendung watchasayin dar - was nicht nur daran festzumachen ist, dass es die im Vorangegangenen besprochene Klasse Core enthält. Es ist Bindeglied zwischen allen anderen Modulen und erfüllt vor allem drei Aufgaben: Die Verarbeitung von Skype bezogenen Ereignissen, die Bereitstellung eines Mediums für die Kommunikation mit anderen watchasayin Instanzen sowie die Bereitstellung einer Schnittstel- le zur Interaktion mit dem Nutzer (hier als GUI realisiert). Diese drei Aufgaben werden im Folgenden eingehender betrachtet

3.4.1 Kommunikation mit anderen watchasayin Instanzen

Wie in Abschnitt 3.1.2 als Vorgabe für die Implementierung gegeben, verwenden Surface- Module auf unterschiedlichen PCs zur bilateralen Kommunikation Skype-Textnachrichten. Dies ist, wie bereits in Abschnitt 2.3.3.2 dargelegt, vorteilhaft, da für diese Art der Kommunikation allein der Skype-Nutzernamen des Empfängers bekannt sein muss und so sämtliche Skype- Clients, mit denen ein Telefonat ansteht, in jedem Fall erreicht werden können. Die Aufgabe des Surface-Moduls besteht dabei ausschließlich darin, die Bereitschaft einer an- deren watchasayin Instanz zur Verschlüsselung eines Telefonats zu erfragen und im positiven Fall anschließend mit Hilfe des Kryptonite-Moduls einen sicheren Kommunikationskanal für das Bottom-Modul zu realisieren. Um den dafür notwendigen AKE mit der Gegenseite ausfüh- ren zu können, greift das Kryptonite-Modul auch auf den vom Surface-Modul bereitgestellten Kommunikationskanal zurück. Ist der AKE vollzogen, wird fortan sämtliche Surface Kommuni-

7Eine Liste der unterstützten Datentypen und ihren jeweiligen Entsprechungen in den Sprachen C# und C++ ist in [10] gegeben.

51 3. Implementierung der Verschlüsselungslösung kation mit dem entsprechenden Partner hinsichtlich der Authentizität, Integrität und Freshness gesichert.

3.4.1.1 Technische Realisierung und grundlegendes Modell

Das Senden8 von Textnachrichten an einen beliebigen Empfänger innerhalb des Skype-Netzwerks ist über die Skype API und somit einfach mit Hilfe von Skype4COM möglich. Skype-Textnach- richten können nach eigenen Untersuchungen beinahe unbegrenzte Längen annehmen (über zehntausend Zeichen sind möglich). Dabei wird anscheinend zumindest der volle UTF-16 Un- icode Zeichensatz unterstützt [17], was die direkte Übertragung von Daten ohne größere For- matierungen ermöglichen könnte9. Anders als der noch aus der Frühzeit der Datenverarbeitung stammende ASCII Zeichensatz, enthalten die Unicode Zeichensätze eine Vielzahl an nicht rö- mischen Schriftzeichen - zum Beispiel aus den asiatischen und arabischen Sprachräumen. Der Einfachheit halber wurde sich jedoch dafür entschieden, auf die sich aus der Unterstützung des Unicode Zeichensatzes ergebenden Möglichkeiten zunächst zu verzichten und stattdessen nur auf eine Untermenge des beschränkteren ASCII Standards zurückzugreifen. So haben sämtliche Protokollnachrichten der watchasayin Anwendung die Form von XML- Dokumenten [21]. Wobei in der aktuellen Implementierung das Kodierungsverfahren Base64 [26] für die Übertragung von Binärdaten eingesetzt wird. Die Grundidee hinter diesem Verfah- ren besteht darin, Binärdaten mit den 64 Zeichen aus dem Alphabet {a − z, A − Z, 0 − 9, +,/} abzubilden. Entsprechend werden pro übertragenem Zeichen von jeweils 8 Bits effektiv nur 6 Bits an Daten übertragen. Eine Nachricht des Surface-Protokolls entspricht immer einer der beiden folgenden Formen:

[Nutzdaten]

Bei einer Nachricht des Surface-Protokolls handelt es sich also erst einmal um ein XML- Dokument mit nur einer Ebene. Dabei gibt das Attribut type des Elements srfmsg den Typ der Nachricht an. in Tabelle 3.1 sind alle möglichen Typen des Surface-Protokolls aufgelistet. Eine genauere Erklärung der Bedeutung der einzelnen Nachrichtentypen schließt an diesen Abschnitt an. 8Gleiches gilt auch für den Empfang. Dieser wird jedoch von der allgemeinen Ereignisverarbeitung abgewickelt und wird daher erst weiter unten explizit betrachtet. 9Eine unmittelbare Übertragung von Daten in den Unicode Zeichensatz und zurück ist hier wohl nicht möglich, da in den UTF Zeichensätzen einige nicht anzeigbare Steuerzeichen existieren.

52 3. Implementierung der Verschlüsselungslösung

Typ-Nr. Name Bedeutung Nutzdaten 0 Bottom2Bottom Bottom Nachricht enthalten X 1 Kryptonite2Kryptonite Kryptonite Nachricht enthalten X 2 Syn Aufforderung zum Start einer - Surface-Protokollsitzung 3 Ack Bestätigung von Aufforderung nach 2 - 4 Nack Ablehnung der Aufforderung nach 2 - 5 Closing Schließung der Sitzung - Tabelle 3.1.: Mögliche Typen von Nachrichten im Surface-Protokoll.

Trotz einer Vielzahl von Versuchen konnte während der Implementierung dieser Anwendung kein Weg gefunden werden, um Nachrichten des Surface-Protokolls vor dem Anwender mit- tels der Skype API zu verbergen. Dementsprechend kann ein watchasayin Nutzer als erstes nach dem Anstoß eines neuen Telefonats den automatischen Versand folgender Nachricht im entsprechenden Chatfenster seines Skype-Clients beobachten:

Ohne den Abschnitten 3.5 und 3.6 schon zu viel vorwegnehmen zu wollen, sei hier zum Vergleich schon einmal eine typische Surface-Protokoll Nachricht des Typs Bottom2Bottom gegeben:

?OTR:AAIKAAAAwGtkFEnwqmm2MCqSN5MynhrlFF4Mr o0l+ewBTPAUxdvMkZpRBWFTFAsRVDFLXRucLkbziJb JlbdGcr63/5iYLtOIZnTvaNb2SqcXlkVaJ7dRhbgPoy 7c0Ju4gCBi2WTJmxeCrP7Okt0euxkqF1hEWkw2O3zWP 4l4wrqSXJbHiS1joFVRlGvPGLlR2JZMl8blW9G4/Jze ukUxuJbgfx63ss2MkxyMGgN1nSNJk9zoyOD7eIhVmoa/ eLSo+LoQFG9KSg==.

Hier ist in den Nutzdaten die bereits angesprochene Kodierung mit Hilfe des Base64-Verfahrens zu sehen. Dekodierte man diese Nutzdaten, so erhielte man in diesem Fall zunächst nicht auswertbare, durch das Kryptonite-Modul verschlüsselte Daten. Entschlüsselte man diese wie- derum, so erhielte man schlussendlich folgende XML konforme, eingebettete Nachricht des Bottom-Protokolls:

53 3. Implementierung der Verschlüsselungslösung

Ein ähnliches Bild ergäbe für eine Nachricht des Surface-Protokolls vom Typ Kryptonite2- Kryptonite. Die Nachrichten der Protokolle der Kryptonite und Bottom-Module werden also in (hier nicht näher zu spezifizierender) verschlüsselter Form in Nachrichten des Surface-Protokolls eingebettet. Danach lässt sich, in Anlehnung an das ISO/OSI-Modell, zur Illustration der Be- ziehungen der Protokolle der drei Module zueinander ein Schichtenmodell skizzieren. Dieses Schichtenmodell ist in Abbildung 3.8 dargestellt.

Kryptonite-Proto. Bottom-Protokoll

Kryptonite-Verschlüsselung

Surface-Protokoll

Skype-Textnachrichten

TCP, UDP

Abbildung 3.8.: Veranschaulichung der Beziehung zwischen den Protokollen der Module Surface, Bottom und Kryptonite in Anlehnung an das ISO/OSI-Modell.

Wie dort zu sehen, findet sämtliche Kommunikation des Bottom-Protokolls verschlüsselt statt, während beim Kryptonite-Protokoll prinzipbedingt auch teilweise unverschlüsselt kommuniziert wird.

3.4.1.2 Das Surface-Protokoll

Im vorangegangenen Abschnitt wurden bereits viele Aspekte des Surface-Protokolls angespro- chen, ohne dass jedoch eine tatsächliche Spezifikation gegeben wurde. Dies soll hier geschehen. In Abbildung 3.9 ist dafür zunächst das Aktivitätsdiagramm (vgl. [3] Seite 335) eines Teil- nehmers des Surface-Protokolls gegeben. In der Programmcodedatei SurfaceProtocol.cs wurde dieses Aktivitätsdiagramm mit Hilfe einer State-Machine (deutsch „Zustandsautomat“ vgl. [3] Seite 332) programmiertechnisch umgesetzt. Dabei besteht die einzige Abweichung zur in Ab- bildung 3.9 gegebenen Spezifikation in dem Fehlen eines Versionsabgleichs im Übergang vom Zustand Start in den Zustand Session Confirmed. Die Verwendung einer State-Machine zur Abbildung des Protokolls wurde gewählt, da so garan- tiert werden kann, dass sich das an einer Protokollsitzung teilnehmende Surface-Modul immer in einem klar definierten Zustand befindet. Konkret implementiert ist besagte State-Machine in

54 3. Implementierung der Verschlüsselungslösung der abstrakten10 Klasse watchasayin.Surface.Protocol.Session von welcher indirekt zum Beispiel die Klasse CallSession abgeleitet ist, welche bereits in Listing 3.1 zu sehen war. In Aktivitäts- diagrammen finden Zustandsübergänge in den meisten Fällen in Reaktion auf neu eintretende Ereignisse statt. Dies ist in dem in Abbildung 3.9 gegebenen nicht anders. Dort gibt es mit dem Zustand Session Confirmed nur einen einzigen, der automatisch in einen folgenden Zustand übergeht. Alle anderen Zustandsübergänge werden entweder durch den Empfang von Nachrich- ten des Surface-Protokolls nach Tabelle 3.1 oder durch Methodenaufrufe von außen angestoßen. Der Ablauf einer Sitzung des Surface-Protokolls gestaltet sich nach dem gegebenen Aktivitäts- diagramm recht einfach. So sendet die anrufende Seite zunächst eine Nachricht des Typs Syn um die Bereitschaft der Gegenseite zur Teilnahme an einer Sitzung zu erfragen. Antwortet die Gegenseite mit einer Nachricht des Typs Ack, so gehen beide Teilnehmer in den Zustand Sessi- on Confirmed über, welchen sie direkt wieder verlassen, um entweder einen AKE mit Hilfe des Kryptonite-Modules vorzunehmen oder, sofern bereits ein sicherer Kanal zur Verfügung steht, in den Zustand Routing überzugehen. Dieser Zustand wird bis zum Ende des zu verschlüsseln- den Telefonats nicht mehr verlassen. Das Surface-Modul agiert in diesem als Router welcher über einen sicheren Kanal erhaltene Nachrichten an die anderen beiden Module weiterleitet. In der aktuellen Implementierung wird der Protokolllauf automatisch beendet, sobald eine Seite eine Nachricht eines für den aktuellen Zustand nicht vorgesehenen Typs erhält. Dieses Verhalten könnte mit einem Sicherheitsrisiko verbunden sein. Genauere Untersuchungen müssen hier an- gestellt werden. Eine einfache Änderung des Verhaltens hin zum Ignorieren einer unerwarteten Nachricht wäre einfach zu bewerkstelligen.

3.4.2 Ereignisverarbeitung

Wie bereits in Abschnitt 3.2.4 besprochen, erwartet der Konstruktor der Klasse watchasay- in.Surface.Core als Argumente fünf Objekte, deren Klassen jeweils verschiedenen Interfaces genügen müssen. Als einziges dieser Interfaces wurde watchasayin.Surface.IEventHandler bis- her nicht für sich betrachtet. Soll eine Klasse diese Schnittstelle erfüllen, so muss sie nach außen drei manipulierbare Listen von Methoden verfügbar machen. Wird eine Methode zu einer dieser Listen hinzugefügt, so wird diese im Falle des Eintretens des die Liste betreffenden Ereignisses aufgerufen. Dabei existiert für die folgenden Ereignisse jeweils eine Liste.

1. Empfang einer Textnachricht

2. Beginn eines neuen Telefonats

10Unter einer abstrakten Klasse versteht man eine Klasse, von welcher nicht unmittelbar Objekte erzeugt werden können. Typischerweise definiert eine solche Klasse virtuelle Methoden mit Platzhaltercharakter, welche von dieser Klasse erbenden Klassen implementiert werden müssen. Von solchen die virtuellen Methoden implementierenden Klassen können dann Objekte erstellt werden.

55 3. Implementierung der Verschlüsselungslösung

Abbildung 3.9.: Aktivitätsdiagramm des Surface-Protokolls.

56 3. Implementierung der Verschlüsselungslösung

3. Beendigung eines Telefonats

Bei einer das Interface IEventHandler implementierenden Klasse können also durch Hinzufü- gen zu einer dieser Listen mehrere Verarbeitungsmethoden für ein Ereignis registriert werden. Dabei ist jeweils mit Hilfe eines „Delegaten“ (vgl. [23] Seite 215) vorgegeben, welche Art von Parametern und Rückgabewert eine zu registrierende Methode aufweisen muss. Die Signatur einer Callback-Methode für das Ereignis eines neu beginnenden Telefonats muss beispielsweise der Form void DCallStartedHandler(string participantHandle, int id, bool outgoing) entsprechen. Solch eine regis- trierte Methode würde im Falle jedes neuen Anrufs den Nutzernamen des anderen Teilnehmers, die Identifizierungsnummer des Telefonats sowie ein die Richtung des Telefonats angebenden bool’schen Wert übergeben bekommen. Genauso verhält es sich auch mit der bereits besprochenen Methode onNewCall aus Listing 3.1. Diese wird im Konstruktor der Klasse Core mit folgendem Aufruf als Verarbeitungsmethode für neue Anrufe registriert. eventDispatcher . callStartedHandlers .Add(onNewCall);

Das Objekt eventDispatcher wird an den Konstruktor der Klasse Core als Teil der Basiskonfi- guration übergeben. In der aktuellen Ausprägung der watchasayin Anwendung handelt es sich dabei konkret um ein Objekt der Klasse watchasayin.Surface.SkypeSpecific.APIEventHandler, welche mit Hilfe von Skype4COM wiederum eigene Callback-Methoden für zwei Ereignisse nach der Skype API Spezifikation registriert. Bei den beiden Ereignissen handelt es sich um die Sta- tusänderung von zum einen einer Textnachricht und zum anderen eines Telefonats. Ändert sich beispielsweise der Status eines Telefonats von routing zu ringing11 so wird aus Skype4COM mit einem neuen Thread die entsprechende Callback-Methode des APIEventHandler Objekts aufge- rufen, wo dann wiederum die einzelnen registrierten Verarbeitungsmethoden für neue Telefonate aufgerufen werden (zum Beispiel die Methode onNewCall). Analog verhält es sich mit Text- nachrichten. Als Verfeinerung der Aussagen in Abschnitt 3.2.3 lässt sich hier also sagen, dass die beiden mittels Skype4Com registrierten Callback-Methoden der Klasse APIEventHandler die einzige Thread-Quelle sind.

3.5 Manipulationsmodul - Bottom

Genaugenommen handelt es sich bei Bottom nur um die in C++ entwickelte, im gleichnami- gen Visual Studio Projekt implementierte DLL Bottom.dll, welche innerhalb des Prozesses des

11Die Statusänderung von routing zu ringing zeigt an, dass die Verbindungsaufnahme zu einem anderen Skype- Client zwecks eines Telefonats erfolgreich war. Dies wird als Beginn eines neuen Telefonats übersetzt. An- dersherum wird eine Statusänderung hin zu einem der folgenden Zustände als Beendigung eines Telefonats interpretiert: missed, finished, refused, canceled.

57 3. Implementierung der Verschlüsselungslösung

Skype-Clients ein- und ausgehende Netzwerkpakete auswertet und manipuliert. Funktional ge- hört jedoch auch der im C# Namespace watchasayin.Bottom des Visual Studio Projekts Surface enthaltene Programmcode dazu. Jene Klassen sorgen zum einen dafür, dass die besagte DLL in den Prozess des Skype-Clients geladen wird und liefern diesem Teilmodul zum anderen eine Liste von zu verschlüsselnden Netzwerkverbindungen. In diesem Abschnitt werden sowohl den C++ als auch den C# Programmcode betreffende Aspekte näher beleuchtet und die Interaktion zwischen beiden erläutert. Dabei liegt ein be- sonderes Augenmerk auf der Spezifikation des bis hierhin bereits mehrfach erwähnten Bottom- Protokolls. Als Teil seiner Basiskonfiguration erwartet der Konstruktor der beschriebenen Core-Klasse ein Objekt einer Klasse, welche das Interface IBottomExternalCommunication implementiert. In der aktuellen Version der Anwendung watchasayin wird hier ein Objekt der Klasse watchasay- in.Bottom.InProcess übergeben, welche wie im Folgenden beschrieben zunächst das Laden der Bottom DLL in den Prozess des Skype-Clients anstößt.

3.5.1 Laden der Bottom DLL in den Prozess des Skype-Clients

Zum Laden einer DLL in einen fremden Prozess beschreibt, wie bereits in Kapitel2 erwähnt, [25] den allgemein wohl bekanntesten und gebräuchlichsten Ansatz. Kurz umrissen und in je- dem Fall nicht vollständig stellt sich jener Ansatz wie folgt dar: Mit der Windows API Funktion CreateRemoteThread() lässt sich, vorausgesetzt man verfügt über die nötigen Zugriffsrechte, ein neuer Thread in einem anderen Prozess erstellen. Dazu übergibt man an diese Funktion unter anderem die Startadresse einer Funktion im Adressraum des anderen Prozesses an dem die Ausführung beginnen, sowie genau ein Argument, das an diese Funktion übergeben werden soll. Hier kann man sich die Tatsache zunutze machen, dass die Windows API Funktion LoadLibrary() genau ein Argument erwartet - nämlich den Da- teipfad einer in den aktuellen Prozess zu ladenden DLL. Dadurch, dass LoadLibrary() während einer Windowssitzung in jedem Prozess an derselben Adresse zu finden ist, ist natürlich auch die Adresse dieser Funktion innerhalb des Zielprozesses bekannt. Dem folgend, wird aus dem C# Teil des Bottom-Moduls mit Hilfe von CreateRemoteThread() die Windows API Funktion LoadLibrary() innerhalb des Prozesses des Skype-Clients aufgerufen und dabei der Pfad der Datei Bottom.dll übergeben, welche im Anschluss automatisch geladen wird. Unter anderem immer dann, wenn eine DLL neu in den Adressraum eines Prozesses geladen wurde, wird ih- re Einstiegsfunktion DllMain() aufgerufen. Das heißt, es lässt sich beliebiger Code ausführen, was im Falle der Anwendung watchasayin zum Umleiten von bestimmten Funktionen aus der Windows Sockets API und zum Starten eines COM-Servers genutzt wird. Beides wird in den hieran anschließenden Abschnitten genauer betrachtet.

58 3. Implementierung der Verschlüsselungslösung

Bevor das Laden der Datei Bottom.dll jedoch tatsächlich möglich ist, muss natürlich der ge- naue Zielprozess identifiziert worden sein. Dazu gibt es unterschiedliche Ansätze. Hier konnte mittels Reverse Engineering herausgefunden werden, dass der Skype-Client immer zu Beginn seiner Ausführung eine so genannte „Window Class“ [11] mit dem charakteristischen Namen VideoDeviceMngr registriert. Mit Hilfe dieses Wissens kann unter Verwendung der Windows API Funktion FindWindow() der Prozess des Skype-Clients hinreichend genau identifiziert wer- den. Wird dieser während der Initialisierung des Bottom-Moduls nicht gefunden, so wird ein solcher im pausierten Zustand neu gestartet und erst nach dem erfolgreichen Laden der Bot- tom DLL zur normalen Ausführung freigegeben. So kann erreicht werden, dass der betreffende Skype-Client von Anfang an in seinem Netzwerkverhalten überwacht wird.

3.5.2 Umleiten von Windows Sockets API Funktionen

Nachdem die Bottom DLL erfolgreich in einen Prozess geladen wurde, installiert sie mit Hil- fe des bereits erwähnten SDK Detours von Microsoft Hooks in sämtlichen Windows Sockets API Funktionen, die zum Versenden bzw. Empfangen von Netzwerkpaketen verwendet wer- den können. Eine Liste dieser Funktionen ist in Tabelle 3.2 zu sehen. Nach Einschätzung des

Name Versand Empfang Zweck der Umleitung send X - Auswertung sendto X - Auswertung WSASend X - Auswertung WSASendTo X - Auswertung ConnectEx X - Blockierung WSAConnect X - Blockierung WSASendDisconnect X - Blockierung WSASendMsg X - Blockierung TransmitFile X - Blockierung TransmitPackets X - Blockierung recv - X Auswertung recvfrom - X Auswertung WSARecv - X Auswertung WSASRecvFrom - X Auswertung Tabelle 3.2.: Umgeleitete Windows Sockets API Funktionen.

Autors sind in dieser Tabelle sämtliche Windows Sockets API Funktionen enthalten, die zum Versenden von TCP oder UDP Paketen verwendet werden könnnen. Obwohl viele von diesen wohl nicht vom Skype-Client genutzt werden, werden diese zumindest geblockt, damit keine möglicherweise zu schützenden Informationen ungesichert auf das Netzwerk gegeben werden

59 3. Implementierung der Verschlüsselungslösung können. Sollte ein Skype-Client eine dieser geblockten Funktionen verwenden, so wird ein posi- tiver Ausgang der Operation angezeigt, das betreffende Paket jedoch nicht an die tatsächliche API Funktion weitergereicht. Nur die Umleitungen der vier API Funktionen send(), sendto(), recv() und recvfrom() sowie deren WSA-Varianten12 nehmen eine Auswertung der sie passie- renden Netzwerkpakete vor und manipulieren diese gegebenenfalls. Dabei werden zunächst einmal sämtliche ein- und ausgehenden Verbindungen protokolliert. Dies ermöglicht die Erstellung von Verbindungslisten nach Abschnitt 2.3.3.2. Im Anschluss wird so- wohl bei ein- als auch ausgehenden Paketen geprüft, ob diese zu einer Verbindung einer aktuell zu schützenden Sitzung gehören. Ist dies der Fall, so werden eingehende Pakete vor der Weiter- leitung an Skype entschlüsselt und umgekehrt ausgehende Pakete vor der Weiterleitung an die tatsächlichen Socket Funktionen verschlüsselt. Der ganze Vorgang ist noch einmal schematisch in Abbildung 3.10 dargestellt. Wie dabei das Ver- bzw. Entschlüsselungsglied konkret realisiert idw okt API Sockets Windows send Auswer- Verschlüs- b APIs tung selung

Skype-Client recv Entschlüs- Auswer- b b APIs selung tung

Abbildung 3.10.: Schema der Verarbeitung von ein- und ausgehenden Netzwerkpaketen des Skype- Clients. ist, wird im folgenden Abschnitt behandelt.

3.5.3 Verwendung der Windows Cryptography API

Zur Ver- und Entschlüsselung von Netzwerkpaketen von zu einer zu schützenden Sitzung gehö- renden Verbindungen verwendet die Bottom DLL in ihrer aktuellen Konfiguration den symme- trischen Kryptographiealgorithmus AES. Dabei wird auf die von der Windows Cryptography API bereitgestellte Implementierung zurückgegriffen [6]. Im Speziellen kommt dabei der Cryp- tographic Service Provider (CSP) PROV_RSA_AES zum Einsatz. Durch die Auswahl eines CSPs legt eine Applikation fest, welche kryptographischen Algorithmen die Funktionalität der

12Bei den mit dem Zusatz „WSA“ versehenen Varianten der bekannten BSD-Socketfunktionen handelt es sich um funktional erweiterte Versionen, welche nur auf Windows Systemen zur Verfügung stehen.

60 3. Implementierung der Verschlüsselungslösung

Windows Cryptography API implementieren sollen. PROV_RSA_AES stellt dabei gewisser- maßen den grundlegenden CSP dar und greift auf bewährte und wohl bekannte Algorithmen wie RSA sowie eben den hier für die symmetrische Verschlüsselung verwendeten AES zurück. Der Einsatz eines anderen CSP in einer zukünftigen Version wäre durchaus denkbar, so stellen beispielsweise Smartcard Hersteller für gewöhnlich eigene CSPs bereit (auch wenn der Einsatz einer Smartcard in der aktuellen Architektur im Bottom-Modul wenig Sinn macht). Der gewähl- te CSP verwendet AES mit 128 Bit Schlüsselstärke im Cipher-Block-Chaining (CBC) Modus, wobei zudem ein Padding13 nach dem in [27] beschriebenen PBES2 Verschlüsselungsverfahren des PKCS #5 v2.0 Standards der Firma RSA Laboratories zum Einsatz kommt. Um Netzwerkpakete jedoch tatsächlich verschlüsseln zu können, muss die Bottom DLL natür- lich zunächst einmal Kenntnis darüber haben, welche Verbindungen im Einzelnen zu verschlüs- seln und - ganz profan - welche kryptographischen Sitzungsschlüssel dabei zu verwenden sind. Diese Informationen erhält das externe Teilmodul über seine über COM bereitgestellte Klasse HookingEngine von dem in C# geschriebenen Programmteil des Bottom-Moduls. Die Klasse HookingEngine erlaubt dabei das Erstellen mehrerer paralleler, verschlüsselter Sitzungen mit jeweils mehreren Verbindungen. Die Sitzungsschlüssel erhält Bottom vom Surface-Modul, welches diese wiederum vom Kryptonite- Modul bezieht, wo sie jeweils das Ergebnis eines AKE darstellen. Welche Verbindungen zu einer Sitzung gehören, wird im Bottom-Modul selbst bestimmt. Wie genau, wird im Folgenden Abschnitt dargelegt.

3.5.4 Identifikation von zu schützenden Verbindungen

Das Bottom-Protokoll realisiert die Identifikation von Direktverbindungen über IP basierte Pro- tokolle zwischen zwei Skype-Clients. Dazu wird das in Abschnitt 2.3.3.2 beschriebene Verfahren des Austauschs von jenen beiden Verbindungslisten (ein- und ausgehend) verwendet, die die externe Bottom DLL innerhalb des Prozesses eines Skype-Clients anfertigt. Mittels der bereits erwähnten Klasse HookingEngine ist es aus dem in C# geschriebenen Teil des Bottom-Moduls möglich, diese Verbindungslisten mit einem Methodenaufruf abzufragen. Es sei hier noch einmal wiederholt, dass eine Verbindung, eingehend als auch ausgehend, durch vier Werte eindeutig charakterisiert wird:

1. IP-Adresse des anderen Hosts

2. Quellnetzwerkport

3. Zielnetzwerkport

13Unter „Padding“ versteht man das Ergänzen eines Klartexts vor dem Verschlüsseln um klar definierte Zeichen oder Bits. So kann einfach und effektiv verhindert werden, dass Dritte Chiffrate manipulieren oder fälschen.

61 3. Implementierung der Verschlüsselungslösung

4. Zugrundeliegendes Protokoll (z.B. TCP oder UDP)

Eine Verbindungsliste besteht aus einer beliebigen Anzahl solcher unterschiedlicher Verbindun- gen. Erhält das Bottom-Modul einer laufenden watchasayin-Instanz die Anweisung ein Gespräch mit einem anderen Skype-Teilnehmer zu verschlüsseln, so versucht dieses, mit dem Bottom-Modul jenes Teilnehmers Kontakt aufzunehmen. Wird solch ein Kontaktversuch angenommen, wird eine Reihe von weiteren Schritten ausgeführt: Zunächst tauschen beide Bottom-Module ihre

Client A eingehend ausgehend (maskiert)

122.31.142.131 | 37893 | 61213 | UDP X | 61213 | 37893 | UDP 180.0.47.144 | 43334 | 61213 | UDP Y | 61213 | 43334 | UDP ...... Client B

192.168.100.252 | 37805 | 1406 | TCP Z | 37805 | 1406 | TCP 192.168.100.252 | 37805 | 1407 | TCP Z | 37805 | 1407 | TCP 192.168.100.252 | 37805 | 61213 | UDP Z | 37805 | 61213 | UDP

ausgehend eingehend (maskiert)

122.31.142.131 | 61213 | 37893 | UDP X | 37893 | 61213 | UDP 180.0.47.144 | 61213 | 43334 | UDP ... Y | 43334 | 61213 | UDP...

192.168.100.252 | 1406 | 37805 | TCP Z | 1406 | 37805 | TCP 192.168.100.252 | 1407 | 37805 | TCP Z | 1407 | 37805 | TCP 192.168.100.252 | 61213 | 37805 | UDP Z | 61213 | 37805 | UDP

Abbildung 3.11.: Auswertung von Verbindungslisten auf Seiten von Client A. Dieser kann eindeutig die IP-Adresse 192.168.100.252 dem Platzhalter Z zuordnen. kompletten Listen für eingehende und ausgehende Verbindungen aus. Um dabei jedoch nicht unnötig Informationen preiszugeben, werden diese Verbindungslisten vor dem Versenden dahin- gehend manipuliert, dass IP-Adressen durch Platzhalter ersetzt werden. Anschließend werden auf beiden Seiten die empfangenen Verbindungslisten der anderen Seite mit den eigenen ver- glichen. Entsprechen dabei Verbindungen in der eigenen Ausgangsliste exakt Verbindungen in der erhaltenen Eingangsliste und umgekehrt, so wird davon ausgegangen, dass es sich bei die- sen Verbindungen um diejenigen Verbindungen handelt, die von Skype für die zu schützende Sitzung verwendet werden (siehe auch Abbildung 3.11). Im Normalfall sollte hierbei auf beiden Seiten jeweils nur eine mögliche IP-Adresse für den anderen Host in Frage kommen. Ist dies nicht der Fall, so wird der gesamte Vorgang abgebrochen. Andernfalls werden die Listen der identifizierten beteiligten Verbindungen im Anschluss wiederum ausgetauscht, wobei erneut IP- Adressen durch Platzhalter ersetzt werden. Stellt sich dabei heraus, dass beide Bottom-Module dieselben zu schützenden Verbindungen identifizieren konnten, so wird dies abschließend einan- der bestätigt und mit der Verschlüsselung der Zielsitzung begonnen. Dies ist der grundlegende

62 3. Implementierung der Verschlüsselungslösung

Ablauf einer Sitzung des Bottom-Protokolls. Genau wie auch schon für das Surface-Protokoll geschehen, wird im folgenden Abschnitt eine explizite Definition des Bottom-Protokolls mit Hilfe einer State-Machine gegeben.

3.5.4.1 Das Bottom-Protokoll

Nachrichten des Bottom-Protokolls entsprechen in ihrer Form weitestgehend denen des Surface- Protokolls (so erben auch die Klassen SurfaceMessage und BottomMessage beide von der ab- strakten Klasse WSMessage) - auch bei ihnen handelt es sich um XML-Dokumente mit ei- nem einzigen Element, in dem das Attribut type den Typ der Nachricht angibt. Im Falle des Bottom-Protokolls trägt dieses Element die Bezeichnung btmmsg. Die unterschiedlichen mög- lichen Nachrichtentypen sind in Tabelle 3.3 aufgeführt. Wie diese wiederum in einem Proto-

Typ-Nr. Name Bedeutung Nutzdaten 0 RequestConnections Anforderung von Verbindungslisten, X Übersendung eigener Verbindungsl. 1 MyConnections Übersendung von Verbindungslisten X 2 Matches Übersendung von gefundenen X Verbindungspaaren 3 Confirm Bestätigung der erhaltenen - Verbindungspaare 4 Abort Abbruch - Tabelle 3.3.: Mögliche Typen von Nachrichten im Bottom-Protokoll. kolllauf verwendet werden, ist in Abbildung 3.12 anhand eines Aktivitätsdiagramms definiert. Wie auch schon beim Surface-Protokoll, wurde dieses Aktivitätsdiagramm bei der Implemen- tierung des Bottom-Moduls als State-Machine mittels einer abstrakten Klasse umgesetzt. Bei dieser Klasse handelt es sich um watchasayin.Bottom.Protocol, von welcher die konkrete Klasse Bottom.SessionExternalComm des Objekts bottomInstance aus Listing 3.1 (Callback-Methode der Core Klasse) abgeleitet ist. Anders als beim Surface-Protokoll, kann eine Bottom-Protokollsitzung nach Abbildung 3.12 nicht beliebig viele Nachrichten umfassen. So kann ein Teilnehmer des Protokolls maximal sechs aufeinander folgende Zustände einnehmen, ohne dass es die Möglichkeit gibt einen Zu- stand nach dem Verlassen ein zweites Mal zu erreichen. Das Protokoll beginnt damit, dass bei den gebundenen Bottom-Instanzen einer Sitzung auf beiden Seiten die Verschlüsselung angestoßen wird (wobei auch der bereits erwähnte symme- trische Sitzungsschlüssel übergeben wird). In der aktuellen Implementierung sendet daraufhin die Seite des Anrufenden, als primärer Akteur, eine Nachricht des Typs RequestConnections,

63 3. Implementierung der Verschlüsselungslösung

Abbildung 3.12.: Aktivitätsdiagramm des Bottom-Protokolls.

64 3. Implementierung der Verschlüsselungslösung in der bereits die beiden maskierten Verbindungslisten dieser Seite enthalten sind. Ist die an- dere Seite bereit am anstehenden Protokolllauf teilzunehmen - was in der Regel der Fall sein sollte, denn immerhin wurden bis hierhin schon erfolgreich die Protokolle der Module Sur- face und Kryptonite inklusive AKE durchgeführt, so antwortet diese mit einer MyConnections Nachricht, welche die eigenen Verbindungslisten enthält. Danach befinden sich beide Seiten im Durchgangszustand Find Matches. Von dort an stellt sich der Ablauf der restlichen Sitzung so dar, wie bereits in Abschnitt 3.5.4 beschrieben.

3.5.5 Betriebsmodi der Bottom DLL

Für das externe Teilmodul der Bottom-Komponente sind drei Betriebsmodi vorgesehen. Bei diesen handelt es sich um: Very Loose, Loose und Tight. Jeder Modus sieht ein bestimmtes Verhalten des externen Teilmoduls in Bezug auf das Blockieren oder Weiterleiten von unver- schlüsselten Verbindungen während ein oder mehrere zu schützende Kommunikationssitzungen aktiv sind vor. Der Modus Very Loose bietet dabei ein Höchstmaß an Benutzerfreundlichkeit und nur ein geringeres Maß an absoluter Sicherheit, während Tight weniger von Ersterem bietet, dafür aber, im Vertrauen auf die zugrundeliegenden kryptographischen Verfahren und Imple- mentierungen, als abschließend überprüfbar sicher angesehen werden kann. Der Modus Loose stellt einen Mittelweg zwischen beiden dar, ist jedoch in der aktuellen Version der Bottom DLL nicht implementiert. Allen drei Modi ist gemein, dass sie erst nach der in Abschnitt 3.5.4 beschriebenen Bestimmung von zu verschlüsselnden Verbindungen zum Tragen kommen, dann wenn tatsächlich Netzwerk- pakete ver- und entschlüsselt werden. Befindet sich die im Prozess des Skype-Clients laufende Bottom DLL im Very Loose Modus, so werden ausschließlich die identifizierten Verbindungen einer zu schützenden Kommunikations- sitzung beachtet. Andere Verbindungen können vom Skype-Client weiterhin ungestört verwen- det und zudem beliebig viele neue aufgebaut werden. Ist jedoch eine solche neue Verbindung ähnlich zu einer bereits bestehenden Verbindung einer zu sichernden Sitzung, so wird die neue Verbindung dieser Sitzung hinzugefügt und fortan entsprechend verschlüsselt. Eine Verbindung wird genau dann ähnlich zu einer anderen Verbindung angesehen, wenn diese sich nur entweder im ein - oder ausgehenden Netzwerkport oder im Protokoll unterscheiden. Für den Anwender hat dieser Modus den Vorteil, dass er auch während eines laufenden geschütz- ten Gesprächs Kontakt mit anderen Skype-Nutzern neu aufnehmen kann und auch dauerhaft im Netzwerk erreichbar bleibt. Aufgrund der schwachen Sicherheit die dieser Modus bietet, sollte von seiner Verwendung jedoch abgesehen werden. Der nicht implementierte Loose Modus entspricht dem gerade beschriebenen Very Loose Modus mit der Ausnahme, dass, sobald mindestens eine verschlüsselte Kommunikationssitzung läuft,

65 3. Implementierung der Verschlüsselungslösung keine neuen unverschlüsselten Verbindungen von Seiten des Skype-Clients aufgebaut werden dürfen, wobei wie beim Very Loose Modus auch neue Verbindungen auf ihre Ähnlichkeit zu bestehenden zu verschlüsselnden Verbindungen überprüft und gegebenenfalls einer gesicher- ten Sitzung hinzugefügt werden. Dieser Modus kann solange als sicher angesehen werden, wie der Skype-Client keine ein zu schützendes Gespräch betreffenden Daten neben dem eigentli- chen Empfänger auch noch an einen dritten Host weiterleitet, zu welchem der Skype-Client bereits vor dem betreffenden Gespräch Kontakt hatte. Nach Ansicht des Autors könnte solch ein Szenario in zwei Fällen eintreten: Zum einen, wenn der Skype-Client aktiv ein böswilliges Verhalten an den Tag legt und zum anderen, wenn auf die Dienste eines Relay Hosts zurück- gegriffen wird, obwohl beim Austausch der Verbindungslisten eine Direktverbindung erkannt wurde (dies könnte beispielsweise der Fall sein, wenn ein Angreifer aktiv für passende Einträge in den Verbindungslisten auf beiden Seiten sorgt). Da auch gerade Letzteres nicht auszuschlie- ßen ist, sollte auch dieser Modus nicht bei mittleren oder hohen Sicherheitsanforderungen zum Einsatz kommen. Für den Anwender liefert dieser Modus jedoch den Vorteil, dass beispielsweise auch unverschlüsselte Textnachrichten während eines verschlüsselten Telefonats weiterhin ver- sendet werden können. Aufgrund der Schwächen der bis hierhin beschriebenen Modi in Bezug auf ihre Sicherheit dürf- te es kaum verwundern, dass aktuell Tight als einziger Modus zum Einsatz kommt. Dieser sieht eine Blockierung aller unverschlüsselten Verbindungen des Skype-Clients vor, während eine verschlüsselte Kommunikationssitzung aktiv ist, erlaubt jedoch auch die dynamische Er- weiterung von geschützten Sitzungen um neue ähnliche Verbindungen. Dies hat den großen Vorteil, dass zu schützende Daten niemals unverschlüsselt versendet werden können. Wobei es natürlich denkbar ist, dass ein Skype-Client Daten zu einem Gespräch zwischenspeichert und nach dessen Beendigung diese Daten versteckt weitergibt. Geht man jedoch von solch einem ho- hen Maß an aktivem böswilligem Verhalten aus, so lässt sich eine beinahe unbegrenzte Anzahl von möglichen Bedrohungsszenarien konstruieren (vom Auslesen kryptographischer Schlüssel aus dem Speicher bis hin zum Installieren eines Rootkits). Deshalb wurde bereits in Abschnitt 1.4.1 Vergleich der Vertrauensmodelle festgelegt, dass dem Skype-Client bis zu einem gewissen Maß vertraut werden muss. Trotz dessen ließe sich theoretisch auch ein Modus Very Tight spe- zifizieren, der sämtliche Dateisystemsinteraktion des Skype-Clients während eines geschützten Gesprächs unterbindet und nach Beendigung dessen auch den Client selbst beendet14. Der klare Nachteil des Tight Modus für den Anwender liegt in der Tatsache, dass er während eines ver- schlüsselten Telefonats keine Verbindung mehr zum Rest des Skype-Netzwerks hat und somit beispielsweise in den Kontaktlisten anderer als nicht verfügbar markiert wird. Bei früheren Version der watchasayin Anwendung wurden sämtliche im Tight Modus geschütz-

14Solch ein Verhalten kann ein Anwender auch manuell selbst erreichen, indem er Skype-Client und watchasayin Anwendung in einer virtuellen Maschine ausführt und diese während eines laufenden geschützten Gesprächs im Tight Modus zurücksetzt.

66 3. Implementierung der Verschlüsselungslösung ten Telefonate von Seiten des Skype-Clients nach rund 20 Sekunden mit dem Verweis auf eine fehlende Internetverbindung abgebrochen. Dieser Problematik konnte damit begegnet werden, dass die Windows API Funktion GetTickCount(), welche die Anzahl der vergangenen Millise- kunden seit dem Systemstart zurückgibt, im Skype-Prozess mittels API Hooking dahingehend manipuliert wird, dass während eines andauernden zu schützenden Gesprächs stets der glei- che Wert zurückgegeben wird. Somit vergeht aus Sicht des Skype-Clients während eines sol- chen keinerlei Zeit mehr, wodurch dieses niemals aufgrund einer fehlenden Internetverbindung abgebrochen wird. Diese Methode ist natürlich etwas grob und führt auch tatsächlich zu ei- nem falschen Aufbau von Teilen der Benutzeroberfläche des Skype-Clients, wenn das Anhalten von GetTickCount() zu früh nach dem Beginn eines Telefonats einsetzt (aktuell wird deshalb zunächst fünf Sekunden gewartet). Dies könnte in Zukunft dadurch verbessert werden, dass die Rückgabe von GetTickCount() nur für bestimmte, die Netzwerkverbindungen betreffenden Threads des Skype-Clients manipuliert wird.

3.5.6 Starten eines COM Servers im Skype-Prozess

Das externe Teilmodul der Bottom-Komponente stellt als Out-Of-Process-Server aus dem Pro- zess des Skype-Clients heraus COM-Klassen bereit. Dies widerspricht jedoch der in Abschnitt 3.3 zitierten Aussage, dass ein Out-Of-Process-Server in Form einer EXE Datei vorliegen muss. Denn das externe Teilmodul von Bottom muss zwingend als DLL vorliegen15, damit es von der erwähnten Windows API Funktion LoadLibrary() akzeptiert und in den Zielprozess gela- den werden kann. Bei einer Datei kann es sich jedoch nur entweder um eine EXE oder um eine DLL handeln. Es werden also zwei Anforderungen an das externe Teilmodul gestellt, die sich gegenseitig ausschließen. Dementsprechend ist es mit Hilfe der verwendeten ATL in Visual Studio 2010 auch nur möglich eines von beiden zu erstellen. Ohne ATL wäre es, nur mit Hilfe der nativen Windows API für COM, durchaus möglich einen Out-Of-Process-Server manuell zu erstellen. Jedoch müsste dann auf eine Vielzahl der von Visual Studio 2010 bereitgestellten Komfortfunktionen in Bezug auf die Erstellung und Verwendung von COM-Klassen verzichtet werden. Im Rahmen dieser Arbeit wurde einiger Aufwand darauf verwendet dieses Problem zu lösen. Dabei wurden vor allem mit Hilfe des Programms Process Monitor die Vorgänge während des Verbindens einer C# Anwendung zu einem Out-Of-Process-Server beobachtet und analysiert. Danach stellt sich dieser Vorgang vereinfacht wie folgt dar: Soll eine C# Anwendung mit einem Out-Of-Process-Server kommunizieren, so sucht diese zu- nächst in der Registry unter der entsprechenden CLSID nach dem Dateipfad der zum jenem

15Um genau zu sein, muss im Header der im Portable Executable (PE)) Format vorliegenden Datei das entspre- chende „Flag“ gesetzt sein.

67 3. Implementierung der Verschlüsselungslösung

Server gehörigen EXE. Ist dies erfolgreich, so wird im Anschluss auf diese Datei zugegriffen, wobei der Eintrag „TYPELIB“ aus dem Resource Directory16 gelesen wird. In diesem sind sämtliche Informationen, wie zum Beispiel die Typen von Argumenten und Rückgabewerten vorhanden, die benötigt werden, um die über COM bereitgestellten Klassen des Servers ver- wenden zu können. Ist auch dieser Schritt erfolgreich, so wird, falls noch nicht geschehen, die EXE des Out-Of-Process-Servers gestartet und schließlich eine Verbindung aufgebaut. Dieser Prozess schlägt für mit Hilfe von ATL erstellte DLLs an mehreren Punkten fehl. So tragen sich diese automatisch als In-Process-Server innerhalb der Registry ein, was den uner- wünschten Effekt hat, dass die C# Anwendung die betreffende DLL in ihren eigenen Prozess lädt und mit ihr dort lokal kommuniziert. Dies lässt sich natürlich leicht beheben, indem man die betreffenden Registry Einträge ändert. Anders verhält es sich jedoch mit dem Einlesen der Typeninformationen aus der Programmdatei. Dieser Vorgang wird von Seiten des C# Pro- gramms immer dann frühzeitig abgebrochen, wenn die betreffende Datei nicht als ATL EXE erstellt wurde. Hier wurden verschiedene Ansätze erdacht und evaluiert, um hier auch eine mit ATL erstellte DLL verwenden zu können. Schlussendlich führte das Hinzufügen einer sim- plen Anweisung im Quellcode der DLL zum Erfolg: #undef _WINDLL am Anfang der Datei stdafx.h. Dies bewirkt, dass der Compiler den darauf folgenden Programmcode nicht mehr in Hinblick auf die Verwendung innerhalb einer DLL kompiliert.

3.6 Kryptographiemodul - Kryptonite

Der Sicherheitsgewinn den die Anwendung watchasayin liefert, basiert einzig und allein auf einem zusätzlichen, von Skype Ltd. unabhängigen Authenticated Key-Exchange, bei dem der Anwender selbst entscheidet, welchen öffentlichen Schlüsseln zu vertrauen ist. Die Durchfüh- rung dieses AKE obliegt dem als letztem von dreien hier zu besprechenden Modul Kryptonite. Neben dieser integralen Aufgabe des Aushandelns eines sicheren Sitzungsschlüssels zur Verwen- dung im Bottom-Modul, muss es zudem Nachrichten des Surface-Protokolls kryptographisch sichern - beides für beliebig viele parallele Sitzungen. Welchen Schnittstellen ein Kryptonite- Modul dabei aufweisen muss ist im Interface IKryptoniteExternalCommunication festgelegt. Ein Objekt einer diesem Interface entsprechenden Klasse erwartet die Klasse Core als Teil ihrer Basiskonfiguration. In der vorliegenden Version der Anwendung watchasayin wird hier die Klasse Kryptonite.Shared- Library verwendet, welche selbst über keinerlei eigene kryptographische Implementierungen verfügt, sondern stattdessen über eine festgelegte COM-Schnittstelle die externe DLL Krypto-

16Beinahe jede ausführbare Datei unter Windows enthält ein Resource Directory. Dort werden neben Infor- mationen zu möglicherweise bereitgestellten COM-Klassen „Ressourcen“ des Programms wie zum Beispiel Bilder oder Icons gespeichert.

68 3. Implementierung der Verschlüsselungslösung nite.dll als In-Process-Server einbindet. Diese DLL ist wiederum nur als Adapter ausgelegt und bindet ihrerseits erst diejenigen DLLs ein, welche die eigentlichen kryptographischen Algorith- men und Protokolle enthalten. Sie kann als Übersetzerin zwischen dem Kryptonite-Modul und den externen Bibliotheken gesehen werden.

3.6.1 Wahl der externen Bibliotheken für AKE

Natürlich gibt es eine Reihe von Open-Source Bibliotheken, welche für die Erfüllung der beiden genannten Aufgaben in Betracht gezogen werden könnten. Während der Planungsphase dieser Arbeit wurden aber vor allem zwei davon evaluiert: GnuPG 2.0.16 und libOTR 3.2.0. Bei GnuPG handelt es sich um eine freie und quelloffene Variante der weit verbreiteten und bewährten E-Mail Verschlüsselungslösung PGP, während libOTR ausschließlich zur Verschlüs- selung von Textnachrichten entwickelt wurde und die technische Grundlage einer Reihe von Verschlüsselungsplugins für Instant-Messaging Programme wie Pidgin oder AIM bildet. Hier wird auch direkt der jeweils größte Vorteil jeder Variante klar: Während GnuPG über eine brei- tere Anwenderbasis verfügen dürfte und man auf die bereits bestehende PKI17 zurückgreifen könnte, wurde libOTR explizit für die Verschlüsselung von Textnachrichten entwickelt. Bei der alleinigen Betrachtung dieser Eigenschaften könnte man vermutlich geneigt sein, GnuPG als ausführende Bibliothek zu wählen. Tatsächlich fiel während der Planungsphase dieser Arbeit jedoch die Wahl auf libOTR, da diese über Vorteile aus Implementierungssicht verfügt. So lässt sich die Bibliothek mit etwas Aufwand unter Linux als DLL für Windows kompilieren, wel- che die gesamte Fülle der öffentlichen libOTR Funktionen exportiert. Im Gegensatz dazu ist GnuPG zwar bereits fertig kompiliert für Windows erhältlich, jedoch nicht als DLL, sondern als Sammlung von EXE-Dateien welche sich über Kommandozeilenparameter steuern lassen. Zwar wäre es durchaus möglich, diese aus der Kryptonite DLL anzusprechen, jedoch erscheint dies bei weitem uneleganter als das Einbinden einer einzigen DLL.

3.6.2 Die libOTR Bibliothek

Die libOTR Bibliothek implementiert aktuell das Off-The-Record Messaging (OTR) Proto- koll in den Versionen 1 und 2, wobei ersteres sicherheitsrelevante Schwächen aufweist und nur noch aus Gründen der Abwärtskompatibilität enthalten ist [15]. In watchasayin kommt daher auch ausschließlich die überarbeitete Version 2 zum Einsatz. Dabei werden Textnachrichten des

17Für GnuPG respektive PGP existiert ein System von Servern, bei denen die Inhaber von E-Mail Adressen ihre öffentlichen Schlüssel hinterlegen können. Möchte man mit einer neuen Person Kontakt aufnehmen, so wird typischerweise bei diesen Servern der öffentliche Schlüssel von dieser Person erfragt.

69 3. Implementierung der Verschlüsselungslösung

Surface-Protokolls direkt mit Hilfe der libOTR im Einklang mit dem entsprechenden Proto- koll verschlüsselt, während die Sitzungsschlüssel des Bottom-Moduls aus Kurzeitschlüsseln des OTR-Protokolls abgeleitet werden. Neben den herkömmlichen Sicherheitsfunktionen Encryption und Authentication, wie sie zum Beispiel bei PGP zu finden sind, bietet das OTR-Protokoll noch zwei zusätzliche, weniger be- kannte: Deniability und Perfect Forward Secrecy. Die Autoren des Protokolls schreiben diesen beiden eine so große Wichtigkeit für die Verschlüsselung von Textnachrichten zu, dass sie ihre ursprüngliche, das Protokoll beschreibende Veröffentlichung mit „Off-the-Record Communica- tion, or, Why Not To Use PGP“ [16] betitelten. Unter „Perfect Forward Secrecy“ versteht man allgemein die Eigenschaft eines Protokolls, dass einmal verschlüsselte Nachrichten einer Sitzung auch dann sicher vor Zugriffen dritter bleiben, wenn die privaten Schlüssel einer oder beider beteiligten Parteien (im Fall der Anwendung wat- chasayin entspricht dies den Dateien im Ordner %AppData%\watchasayin\Kryptonite) kompro- mittiert oder Kurzeitschlüssel einer anderen Sitzung bekannt werden. Diese Eigenschaft besitzt bereits das bekannte Diffie–Hellman Protokoll [40], welches auch im OTR-Protokoll der Version 2, sowohl als Teil des SIGMA Protokolls [41] als auch eigenständig, eine große Rolle spielt. Die Besonderheit des OTR-Protokolls in Bezug auf Perfect Forward Secrecy besteht darin, dass, im Anschluss an einen erfolgreichen AKE mittels SIGMA Protokoll, mit je einem Paar von ausge- tauschten Textnachrichten auch ein neuer Schlüsseltausch nach dem Diffie-Hellman Protokoll stattfindet (in [16] wird dies mit: „[...] Alice and Bob re-key as frequently as possible“ beschrie- ben), wobei sämtliche alte Kurzzeitschlüssel vernichtet, das heißt im Speicher überschrieben werden. So wird mit Hilfe der besagten Perfect Forward Secrecy Eigenschaft des Diffie-Hellman Protokolls erreicht, dass selbst durch die Kompromittierung sämtlicher aktueller kryptographi- scher Schlüssel nur jeweils eine bis maximal eine handvoll18 von vorangegangenen Nachrichten entschlüsselt werden können. Natürlich ist das reine Diffie-Hellman Protokoll anfällig gegen Man-In-The-Middle Attacken. Daher wird die Authentizität sämtlicher ausgetauschter Daten im OTR-Protokoll immer mittels eines Message Authenticaion Codes19 (MAC) gesichert. Die Schlüssel zur Erstellung und Überprüfung dieser MACs werden dabei immer mittels Hashing aus den aktuellen Kurzzeitschlüsseln abgeleitet. Die Sicherheit jedes neuen Kurzeitschlüssels wird also durch den jeweils vorangegangenen Kurzeitschlüssel garantiert, wobei am Anfang

18Nach [16] werden die Daten für den nächsten Schlüsseltausch an verschlüsselte Textnachrichten angehängt, welche von einem Nutzer zum anderen geschickt werden. Schickt während einer Konversation ein Nutzer nun eine Folge von Nachrichten, während der keine Antwort des anderen kommt, so kann natürlich kein neuer Schlüssel vereinbart werden, was zur Folge hat, dass mehrere Nachrichten mit demselben Schlüssel verschlüsselt werden. Dieser Problematik begegnet das OTR-Protokoll indem nach einer bestimmten Anzahl von empfangenen Nachrichten eine Seite antworten muss - zur Not mit einer leeren Nachricht. 19MACs bilden in der Kryptographie das symmetrische Gegenstück zu den asymmetrischen Signaturen. Zwei Parteien müssen dabei über ein gemeinsames Geheimnis verfügen, welches dann in einer symmetrischen kryptographischen Operation so eingesetzt wird, dass eindeutig bewiesen wird, dass eine Partei Kenntnis über dieses Geheimnis hat.

70 3. Implementierung der Verschlüsselungslösung dieser Kette der initiale AKE nach dem SIGMA Protokoll mit der vertrauensgebenden Fin- gerprintüberprüfung durch den Nutzer zu finden ist. Es sei hier kurz angemerkt, dass das OTR-Protokoll in Version 2 auch die Möglichkeit bietet ganz auf eine Fingerprintüberprüfung zu verzichten. An dessen Stelle tritt dann das „Socialist Millionaires’ Protocol“ [41], bei dem beide Nutzer über ein gemeinsames, geheimes Passwort verfügen müssen. Auch wenn dies wohl einen höheren Bedienkomfort bietet, kommt jenes Verfahren aufgrund des zusätzlichen Ent- wicklungsaufwands in der Anwendung watchasayin nicht zum Einsatz. „Deniability“ bezeichnet die Möglichkeit beider Protokollteilnehmer, sämtliche Verantwortung für den Inhalt von gesendeten Nachrichten gegenüber dritten abstreiten zu können, auch und gerade dann, wenn geheime Schlüssel kompromittiert wurden. Dies wird durch zwei Mechanis- men innerhalb des Protokolls möglich:

1. Repudiability (Abstreitbarkeit)

2. Forgeability (Möglichkeit des Erstellens)

Unter Ersterem verstehen die Autoren die Protokolleigenschaft, dass außerhalb des initialen AKE die Authentizität einzelner Nachrichten nicht durch kryptographische Signaturen, son- dern durch MACs angezeigt wird, deren Schlüssel nach Verwendung veröffentlicht werden. Wie bereits erwähnt, werden die für die Erstellung dieser MACs notwendigen Schlüssel mittels Ha- shing, also dem Anwenden einer kryptographisch sicheren Einwegfunktion, von den eigentlichen Kurzzeitschlüsseln abgeleitet. Ist eine Partei in Besitz eines solchen MAC-Schlüssels so kann sie also neue MACs ausstellen und alte verifizieren, sie kann jedoch nicht den Inhalt von verschlüs- selten Nachrichten lesen. Aus diesem Grund werden die zu einem Kurzzeitschlüssel gehörigen MAC-Schlüssel bewusst im Klartext an eine über das Netzwerk zu übertragende Textnachricht angehängt, sobald jener Kurzzeitschlüssel seine Gültigkeit verloren hat und durch einen neuen Kurzzeitschlüssel ersetzt wird. Beide Teilnehmer eines OTR-Protokolllaufs können also immer gegenüber dritten Parteien plausibel vorgeben, niemals eine gegebene Nachricht gesendet zu haben, da im Nachhinein theoretisch einjeder einen gültigen MAC für eine beliebige Nachricht anfertigen kann. Unter „Forgeability“ wird nach [16] eine stärkere Eigenschaft mit ähnlichen Zielen verstanden. Diese soll das sinnvolle Modifizieren von chiffriertem Klartext ermöglichen - auch ohne die Kenntnis des zugehörigen Schlüssels. So soll eine an einer OTR Sitzung teilnehmende Partei nach deren Ende in der Lage sein, den gesamten Inhalt oder Teile dessen einer jeglichen von ihr gesendeten Nachricht als Fälschung abzutun. Diese Eigenschaft wird im OTR-Protokoll einfach durch die Verwendung einer Stromchiffre zur Verschlüsselung von Textnachrichten realisiert. Anders als bei Blockchiffren, erlauben Stromchiffren das Ändern einzelner Bits im Klartext eines Chiffrats. Kann eine dritte Partei also den Inhalt einer Nachricht raten, so kann diese

71 3. Implementierung der Verschlüsselungslösung auch ohne Kenntnis eines geheimen Schlüssels den Inhalt beliebig verändern. Während eines OTR-Protokolllaufs werden die beiden teilnehmenden Parteien durch die besagten MACs vor einem Angriff dieser Art geschützt. So nachvollziehbar und sinnvoll die bis hierhin beschriebenen speziellen Eigenschaften des OTR- Protokolls auch sein mögen, sie sind in der Sprachverschlüsselung der Anwendung watchasayin nur noch teilweise vorhanden. Dies ist der bereits erwähnten Ableitung der Sitzungsschlüssel des Bottom-Moduls sowie dem strukturellen Aufbau der Anwendung geschuldet. Beides soll im Folgenden erörtert werden.

3.6.3 Ableitung der Bottom-Sitzungsschlüssel

Wie bereits dargelegt, ist das Kryptonite-Modul verantwortlich für jede zu verschlüsselnde Kommunikationssitzung einen sicheren, symmetrischen kryptographischen Schlüssel zu liefern. Dazu bedient es sich in der aktuellen Ausprägung der Kurzeitschlüssel der aktuellen OTR- Protokollsitzung, die zur Sicherung der Surface Textnachrichten angestoßen wurde. Weiter oben wurde bereits beschrieben, dass beide Teilnehmer einer OTR-Protokollsitzung - im Folgenden Alice und Bob - mit jedem Paar von ausgetauschten verschlüsselten Textnachrichten einen neuen Schlüsseltausch nach dem Diffie-Hellman Protokoll vollziehen. So wird zu Beginn einer Sitzung ein Generator g einer Gruppe Zp gewählt, wobei es sich bei p um eine 1536 Bit

Primzahl handelt. Mit jeder neuen Nachricht wählt Alice ein xi ∈ Zp−1 mit mindestens 320 Bit und hängt gxi an die zu sendende Nachricht an. Mit der nächsten Antwortnachricht wählt

yi Bob ebenso ein yi ∈ Zp−1 mit mindestens 320 Bit und sendet g zurück. Anschließend können xiyi beide Seiten si = g berechnen und besitzen somit ein neues gemeinsames Geheimnis (die Authentizität wird dabei natürlich mit Hilfe der beschriebenen MACs garantiert). Bis hierhin handelt es sich um das Diffie-Hellman Protokoll in der so genannten Lehrbuchvariante. Von dem nur Alice und Bob bekannten Wert si leiten beide im OTR-Protokoll im Anschluss zwei symmetrische Kurzzeitschlüssel für den AES Algorithmus mit jeweils einer Länge von 128 Bit ab:

ci = σ(HashSHA−1(0x01|MPI(si))) 0 ci = σ(HashSHA−1(0x02|MPI(si)))

72 3. Implementierung der Verschlüsselungslösung mit

σ : GF (2)256 → GF (2)128 n MPI : Zp → GF (2) , n ∈ N, n ≥ 5

Dabei kürzt die Abbildung σ die 256 Bit lange Ausgabe des SHA-1 Hashalgorithmus auf 128 Bit durch einfaches Abtrennen, während MPI eine ganze Zahl auf eine Abfolge von Bytes mit vorangestellter Längenangabe abbildet [15]. Anschließend wird bestimmt, welche Seite von beiden das „high“ bzw. das „low“ Ende ist. Dazu werden die beiden öffentlich bekannten Werte gxi und gyi verglichen. Ist gxi größer, so ist in diesem Fall Alice das „high“ Ende. Gleiches gilt umgekehrt für gyi und Bob. Das „high“ Ende verwendet den Schlüssel ci zum Verschlüsseln der i-ten Textnachricht die es an das „low“ Ende 0 sendet und umgekehrt ci zum Entschlüsseln der i-ten Textnachricht die es vom „low“ Ende erhält. Das „low“ Ende verfährt entsprechend entgegengesetzt. Der AES Algorithmus wird dabei im Counter-Mode (CTR) eingesetzt, was diesen einen Schlüsselstrom gleich dem einer Stromchiffre erzeugen lässt und somit die bereits dargelegte Sicherheitsfunktion Forgeability des OTR-Protokolls ermöglicht. Natürlich funktioniert das Verfahren wie hier beschrieben nur in einer ideellen Konversation in der auf eine Nachricht von Alice immer direkt auch eine Antwort von Bob folgt. Da dies in der realen Anwendung nicht der Fall ist, werden im OTR-Protokoll auf beiden Seiten immer mehrere Schlüssel vorgehalten. Die tatsächlichen Abläufe stellen sich also etwas aufwändiger dar als hier beschrieben. Dies ist für die folgende Betrachtung jedoch unerheblich. Wird ein neuer Sitzungsschlüssel k für die Netzwerkpaketverschlüsselung zwischen zwei Bottom- Modulen beim Kryptonite-Modul angefordert, so wird dieser wie folgt aus dem aktuellen Kurz- zeitschlüssel ci der OTR-Protokollsitzung abgeleitet:

128 ksession = DecAES128,CT R(t, kOT R,i), t = 0

Wobei es sich bei t um eine Konstante handelt, die nur aus Null-Bytes besteht. Der Sitzungs- schlüssel k entspricht also 128 Bits aus der Ausgabe der Entschlüsselungsfunktion20 des AES

Algorithmus im CTR-Betrieb für den Kurzzeitschlüssel ci. Der Schlüssel k kann nur als sicher angesehen werden, solange derselbe Schlüsselstrom nicht auch für die Verschlüsselung von Nach- richten eingesetzt wird. Dies wird von der von libOTR verwendeten Kryptographiebibliothek libgcrypt automatisch gewährleistet.

20Da der AES Algorithmus im CTR Modus betrieben wird, handelt es sich bei der Ver- und der Entschlüsselung um identische Funktionen. Dass hier die Entschlüsselungsfunktion verwendet wird, ist also reiner Zufall und nicht von sicherheitsrelevanter Bedeutung.

73 3. Implementierung der Verschlüsselungslösung

3.6.3.1 Sicherheit des abgeleiteten Sitzungsschlüssels

Die soeben erläuterte Ableitung eines kryptographischen Schlüssels aus einem Kurzzeitschlüs- sel zur externen Verwendung ist im OTR-Protokoll im Allgemeinen und in der libOTR im Speziellen nicht vorgesehen. Tatsächlich wird dadurch und durch die anschließende Verwen- dung des Schlüssels im Bottom-Modul die in Abschnitt 3.6.2 beschriebenen Sicherheitsfunktion des OTR-Protokolls Deniability unterwandert. Die beiden grundlegenden Sicherheitsfunktionen Encryption und Authentication, welche auch das PGP Protokoll bietet, bleiben jedoch vollstän- dig für die Verschlüsselung von Skype-Telefonaten erhalten, während Perfect Forward Secrecy nur noch in etwas abgeschwächter Form weiterhin gilt. Dies ist genau zwei Eigenschaften der in Abschnitt 3.5.3 beschriebenen Implementierung der Verschlüsselung von Netzwerkpaketen innerhalb des Bottom-Moduls geschuldet: Die herkömm- liche Verwendung von AES als Blockchiffre im CBC Modus mit Padding nach PKCS #5 sowie der Verzicht auf die fortwährende Neuvereinbarung von kryptographischen Schlüsseln wie es im OTR-Protokoll der Fall ist. So realisiert Erstere zwar direkt Encryption und Authentication aufbauend auf einem Vertrauen in die Sicherheit der zugehörigen OTR-Protokollsitzung, verhindert jedoch die Möglichkeit der sinnvollen Manipulation von verschlüsseltem Klartext durch dritte, was unmittelbar die Funk- tion Forgeability zunichtemacht. Repudiability ist im selben Zug auch nicht mehr gegeben, da jede der beiden Parteien durch das Anfertigen korrekt verschlüsselter Netzwerkpakete dauer- haft beweist im Besitz des entsprechenden Sitzungsschlüssels k zu sein und im Umkehrschluss im Nachhinein die Herkunft eines Pakets eindeutig festzustellen ist. Die nicht fortwährende Neuvereinbarung von Sitzungsschlüsseln führt dazu, dass, einmal in Besitz des geheimen Sitzungsschlüssels k, ein Angreifer sämtliche Netzwerkpakete zwischen zwei Bottom-Modulen entschlüsseln und so möglicherweise ein komplettes geschütztes Tele- fonat entschlüsseln kann - anstelle von nur einer bis wenigen Textnachrichten im Falle des OTR-Protokolls. Die Sicherheit anderer Sitzungen wären von solch einer Kompromittierung natürlich nicht betroffen. Auch gilt weiterhin, dass eine Kompromittierung der privaten Schlüs- sel aus dem Ordner %AppData%\watchasayin\Kryptonite die Vertraulichkeit bereits geführter oder laufender Konversationen in keinster Weise beeinträchtigt. Perfect Forward Secrecy bleibt also mit der Einschränkung erhalten, dass ein Verlust des Sitzungsschlüssels k die Kompromit- tierung einer kompletten Kommunikationssitzung - auch rückwirkend - zur Folge hat. Neben diesen Verlusten von Sicherheitsfunktionen ergibt sich aus der Verwendung einer Block- chiffre anstelle einer Stromchiffre jedoch auch ein zusätzlicher Sicherheitsgewinn aus anderer Richtung. So wird in [14] ein Seitenkanalangriff auf mit Stromchiffren verschlüsselte VoIP- Verbindungen vorgestellt, welcher anhand der unterschiedlichen Längen von gesendeten UDP Paketen Teile des Inhalts einer Konversation rekonstruiert - nach Angaben der Autoren mit

74 3. Implementierung der Verschlüsselungslösung einer Erfolgswahrscheinlichkeit von 50% bis 90% für bestimmte Ausdrücke und Satzglieder. Die Autoren betrachten dabei vor allem den Speex21 [47] Audio-Codec, welcher Pakete von insgesamt 21 unterschiedlichen Längen produziert [14]. Werden diese Pakete vor dem Versand über das Netzwerk mit Hilfe einer Stromchiffre verschlüsselt, so entsprechen die Längen der verschlüsselten Pakete in aller Regel denen der unverschlüsselten Pakete. Ob Skype für seine eigene Verschlüsselung den AES Algorithmus auch als Stromchiffre einsetzt und so anfällig für diese Art von Attacke wäre, konnte nicht abschließend geklärt werden. Fest steht jedoch, dass Skype-Clients während eines Telefonats eine Vielzahl von Paketen unterschiedlicher Länge verschicken. Während eines einfachen Testlaufs wurden hier 70 verschiedenartige gezählt. Im Gegensatz zu dieser Zahl und derer des Speex Codecs treten während eines durch watchasayin geschützten Gesprächs nur vergleichsweise wenige unterschiedliche Paketlängen auf - typischer- weise 16, 32, 48, 64, 96, 112 und 128 Byte. Dies ist natürlich das Resultat der Verwendung des AES Algorithmus als Blockchiffre, wobei Daten vor dem Verschlüsseln künstlich so aufge- füllt werden müssen, dass ihre Länge ein Vielfaches von 16 Byte beträgt. Selbstverständlich wird durch solches Padding der Overhead der zu übertragenden Daten weiter erhöht. Nach [14] stellt Padding eine wirksame Maßnahme gegen den vorgestellten Angriff dar. Hier wäre es in Zukunft auch leicht möglich sämtliche zu verschlüsselnden Pakete auf ein Vielfaches von bei- spielsweise 128 Byte aufzufüllen, um so die Anzahl unterschiedlicher Paketlängen noch weiter zu reduzieren.

3.7 Die fertige Anwendung

Die fertige Anwendung watchasayin wird in Form der Dateien Surface.exe, Kryptonite.dll, libotr- 2.dll, libgcrypt-11.dll und libgpg-error-0.dll ausgeliefert, wobei die Datei Bottom.dll erst zur Laufzeit geschrieben wird und in Surface.exe enthalten ist. Es bedarf keiner expliziten Instal- lation - das Programm ist direkt lauffähig. Die Funktionen der Anwendung wie sie sich dem Endanwender präsentieren wurden bereits in Abschnitt 3.2 dargelegt. Dabei werden, bis auf die im Folgenden beschriebene Ausnahme, sämtliche in Abschnitt 3.1 definierten Vorgaben und Ziele erfüllt. In Zielstellung 3.) wird gefor- dert, dass das Vorhandensein einer laufenden watchasayin Instanz von außen nicht bemerkbar sein soll. Dies gilt für die fertige Anwendung nur in eingeschränkter Form. So ist es möglich, durch den Versand einer SYN Nachricht des Surface-Protokolls in Kombination mit einem An- ruf über das Skype-Netzwerk direkt zu überprüfen, ob auf Seiten des betreffenden Clients eine watchasayin Instanz aktiv ist. Daneben kann eine gänzlich passive Partei mit der Fähigkeit

21Der Speex Audio-Codec wurde in früheren Versionen ebenfalls von Skype eingesetzt. Auch heutzutage ist dieser immer noch im Skype-Client für Windows zu finden - vermutlich aus Gründen der Abwärtskompati- bilität.

75 3. Implementierung der Verschlüsselungslösung des Abhörens des Netzwerkverkehrs eines Skype-Clients anhand von Paketlängen mit großer Sicherheit durch watchasayin geschützte Telefonate registrieren. Dies wird durch den Einsatz einer Blockchiffre im Bottom-Modul möglich, was bewirkt, dass während eines geschützten Te- lefonats nur Netzwerkpakete versendet werden, deren Längen ein vielfaches von 16 betragen. Daneben sind dem Autor noch eine kleinere Menge von funktionalen Einschränkungen und Fehlern bekannt, welche bei der Verwendung von watchasayin auftreten können. Diese werden im folgenden Abschnitt kurz dargelegt.

3.7.1 Funktionale Einschränkungen und Fehler

Die größte Einschränkung der watchasayin Anwendung stellt wohl ihre Unfähigkeit des Ver- schlüsselns von über Relay Hosts geführten Gesprächen dar. Die Gründe dafür sind dem generel- len Funktionsprinzip der Anwendung geschuldet und wurden bereits in Abschnitt 2.3 erörtert. Für den Anwender stellt dies jedoch zumindest im weiter oben beschriebenen Tight Betriebsmo- dus kein Sicherheitsrisiko dar, da niemals unverschlüsselte Daten während der Dauer eines zu schützenden Gesprächs über das Netzwerk versendet werden. In den allermeisten Fällen dürfte die Anwendung watchasayin zudem erkennen, dass ein zu schützendes Gespräch nicht über eine Direktverbindung geführt wird und den Anwender darauf hinweisen. Zudem sei hier angemerkt, dass nach Einschätzungen des Autors Relay Hosts nur sehr selten im Skype-Netzwerk zum Ein- satz kommen. Um über Relay Hosts geführte Gespräche in zukünftigen Versionen unterstützen zu können, scheint es unerlässlich zunächst tiefere Erkenntnisse über den Aufbau von Paketen wie sie von Skype-Clients versendet werden zu gewinnen. Mit Hilfe solcher, vermutlich nur durch Reverse Engineering zu erlangender Erkenntnisse sollte es möglich sein, Pakete nur so teilweise zusätzlich zu verschlüsseln und zu manipulieren (man denke hier an Checksums), dass sie von einem Relay Host als gültig erkannt und entsprechend weitergeleitet werden. Jedoch birgt jede nicht vollständige Verschlüsselung von Netzwerkpaketen die Gefahr, dass eigentlich zu schützende Daten doch unverschlüsselt übertragen werden. Daneben kam es während Testläufen in wenigen Fällen zu der Situation, dass bei dem in Ab- schnitt 3.5.4 beschriebenen Austausch von Verbindungslisten die zu dem jeweils zu schützen- den Gespräch gehörenden Verbindungen nicht eindeutig identifiziert werden konnten, woraufhin stets die entsprechende Sitzung abgebrochen und der Anwender auf den Umstand hingewiesen wurde. In allen Fällen kam dabei neben der korrekten noch eine weitere, falsche IP-Adresse für den anderen Skype-Client in Frage. Hier könnte die Entwicklung in Zukunft dahin weitergehen, dass im Falle eines solchen Konflikts entweder erweiterte Heuristiken angewandt (zum Beispiel könnte die IP-Adresse mit der zuletzt kommuniziert wurde gewählt werden) oder bestimmte Netzwerkpakete an alle in Frage kommenden Kandidaten gesendet werden, was jedoch besagter Zielstellung 3.) weiter entgegenlaufen würde.

76 3. Implementierung der Verschlüsselungslösung

Als kleinerer Fehler wurde bei Testläufen festgestellt, dass es der Anwendung watchasayin aus unbekannten Umständen teilweise nicht möglich ist, sich mittels COM zur öffentlichen API eines Skype-Clients zu verbinden. In solchen Fällen konnte mittels eines Neustarts beider Pro- gramme Abhilfe geschaffen werden. Häufiger wurde beobachtet, dass Skype-Clients Textnachrichten des Surface-Protokolls nicht zustellten und somit ein AKE unmöglich wurde. Trotz intensiver Nachforschungsbemühungen konnte die Ursache hierfür nicht gefunden werden. In der Praxis konnte jedoch oft dadurch Abhilfe geschaffen werden, dass manuell eine Textnachricht an den entsprechenden Partner ge- sendet wurde, worauf im Anschluss wieder sämtliche Nachrichten des Surface-Protokolls ihren vorgesehenen Empfänger erreichten. Der letzte hier aufzuführende bekannte Fehler stellt nur eine Unannehmlichkeit für den Benutzer dar: Wird watchasayin beendet, so stürzt kurze Zeit später auch der Prozess des Skype-Clients ab mit dem es verbunden war. In den Versuch der Behebung dieses Fehler wurde nur wenig Zeit investiert, es ist davon auszugehen, dass dieser sich relativ leicht beheben ließe. Keinen Fehler im eigentlichen Sinne stellt die prinzipbedingte Tatsache dar, dass sobald ein Telefonat zwischen zwei Parteien gesichert, auch sämtlicher anderer Verkehr zwischen beiden Parteien verschlüsselt wird. Dies betrifft zum Beispiel Textnachricht genauso wie beispielsweise ein nachträglich zugeschaltetes Videobild.

3.8 Zukünftige Entwicklung

Bei der zukünftigen Entwicklung der Anwendung watchasayin sollte vor der Implementierung neuer Funktionen das Hauptaugenmerk auf der Beseitigung der im vorangegangenen Abschnitt beschriebenen Fehler und Einschränkungen liegen, wobei deren Priorität bereits durch die dort gewählte Reihenfolge gegeben ist. Funktional wäre auf kurze Sicht eine explizite Unterstützung von sämtlicher Kommunikation zwischen zwei Parteien über Skype wünschenswert. Als großes langfristiges Ziel ist die Sicherung von Kommunikationssitzungen mit mehreren Teilnehmern anzustreben. Hier besteht in jedem Fall Potenzial für die Anwendung von Protokollen mit asymmetrischer Gruppenschlüsselvereinbarung [18]. Bevor die Software schließlich als Open- Source Projekt veröffentlicht werden könnte, müsste in jedem Fall die Bibliothek Detours aus den bereits angesprochenen lizenzrechtlichen Gründen ersetzt werden.

77 4. Fazit

4 Fazit

Das Ziel, eine überprüfbare und sichere Verschlüsselungserweiterung für die Telefoniefunkti- on des Programms Skype für Windows zu implementieren, wurde erreicht. Dabei wurde die Funktionstüchtigkeit der erarbeiteten Ansätze nicht nur anhand von so genannten Proof Of Concepts - minimalen, nur grundlegend funktionsfähigen Programmen oder Versuchsaufbau- ten - demonstriert. Stattdessen bietet das praktische Ergebnis dieser Arbeit, die Anwendung watchasayin, alle für den tatsächlichen Praxiseinsatz nötigen Funktionen. Die Bedienung wur- de dabei bewusst einfach gehalten, sodass ein möglichst geringer Mehraufwand im Vergleich zu dem Führen eines ungeschützten Telefonats entsteht. Im Normalfall sollten zwei zusätzliche Mausklicks ausreichen um sich der Authenzität, Integrität und Vertraulichkeit eines über Skype geführten Telefonats sicher sein zu können, ohne einer dritten Partei, wie beispielsweise Skype Ltd. oder ihre neue Eigentümerin Microsoft Corp., grundlegend vertrauen zu müssen. Als ungelöstes Problem bleibt auch nach Abschluss dieser Arbeit die Sicherung von indirekten, über eigentlich unbeteiligte Knoten im Skype-Netzwerk geleiteten Gesprächen. Diese Art von Gesprächen ist jedoch der Ausnahmefall und werden von Skype selbst nur als letztes Mittel zur Überwindung von Firewall-Restriktionen oder komplizierten Netzwerktopologien eingesetzt.

78 Literaturverzeichnis

Literaturverzeichnis

[1] awahlig. Skype4Py 1.0, Februar 2011. http://sourceforge.net/projects/skype4py/ files.

[2] Daniel Bachfeld. Bericht: NSA bietet Milliarden, um Skype abzuhören. heise online, Februar 2009. http://www.heise.de/newsticker/meldung/ Bericht-NSA-bietet-Milliarden-um-Skype-abzuhoeren-195547.html.

[3] Helmut Balzert. Lehrbuch der Software-Technik - Software-Entwicklung, 2. Auflage. Spek- trum Akademischer Verlag, Heidelberg, Berlin, 2001.

[4] Symantec Official Blog. Trojan.Peskyspy—Listening in on your Conversations. Symantec Corporation, August 2009. http://www.symantec.com/connect/blogs/ trojanpeskyspy-listening-your-conversations.

[5] Don Box. Essential COM. Addison Wesley Longman, 1998.

[6] Microsoft Corporation. The Cryptography API, or How to Keep a Secret, August 1996. http://msdn.microsoft.com/en-us/library/ms867086.aspx.

[7] Microsoft Corporation. ATL Library Reference - ATL Concepts, April 2011. http:// msdn.microsoft.com/en-us/library/3ax346b7(VS.80).aspx.

[8] Microsoft Corporation. Categorizing Layered Service Providers and Applications, März 2011. http://msdn.microsoft.com/en-us/library/bb513664(VS.85).aspx.

[9] Microsoft Corporation. Component Object Model Guide, April 2011. http://msdn. microsoft.com/en-us/library/ms690156(VS.85).aspx.

[10] Microsoft Corporation. .NET Framework 4 - COM Data Types, April 2011. http://msdn. microsoft.com/en-us/library/ms690156(VS.85).aspx.

[11] Microsoft Corporation. Window Classes, April 2011. http://msdn.microsoft.com/ en-us/library/ms632596(VS.85).aspx.

[12] Microsoft Corporation. Reference, Februar 2011. http://msdn.microsoft.com/ en-us/library/ms741394(VS.85).aspx.

[13] Microsoft Corporation. XML Documentation Comments (C# Programming Guide), März 2011. http://msdn.microsoft.com/en-us/library/b2s063f7(VS.80).aspx.

79 Literaturverzeichnis

[14] Charles V. Wright et al. Spot me if you can: Uncovering spoken phrases in encrypted VoIP conversations. Johns Hopkins University, Baltimore, USA, Juli 2008.

[15] Ian Goldberg et al. Off-the-Record Messaging Protocol version 2. http://www. cypherpunks.ca/otr/Protocol-v2-3.1.0.html.

[16] Ian Goldberg et al. Off-the-Record Communication, or, Why Not To Use PGP. Washing- ton, Oktober 2004. WPES.

[17] Julie D. Allen et al. The Unicode Standard - Version 6.0 – Core Specification. The Unicode Consortium, Mountain View, CA, 2011. http://www.unicode.org/versions/Unicode6.0.0/.

[18] Qianhong Wu et al. Asymmetric Group Key Agreement. In ADVANCES IN CRYPTO- LOGY - EUROCRYPT 2009.

[19] Rebecca Wirfs-Brock et al. Designing Object-Oriented Software. Prentice-Hall, 1990.

[20] Russinovich et al. Windows Internals 5th Edition. Microsoft Press, Redmond, 2009.

[21] Tim Bray et al. Extensible Markup Language (XML) 1.0 (Fourth Edition). W3C, Septem- ber 2006. http://www.w3.org/TR/2006/REC-xml-20060816/.

[22] International Organization for Standardization. ISO/IEC 7498-1, Information Technology - Open Systems Interconnection - Basic Reference Model: The Basic Model. Juni 1996.

[23] Dirk Frischalowski. Visual C# 2005. Addison Wesley, Pearson Studium, München, 2006.

[24] Bert Hayes. Skype: A Practical Security Analysis. SANS Institute, Oktober 2008.

[25] Ivo Ivanov. API Hooking Revealed, Dezember 2002. http://www.codeproject.com/KB/ system/hooksys.aspx.

[26] S. Josefsson. The Base16, Base32, and Base64 Data Encodings (RFC 3548), Juli 2003. http://tools.ietf.org/html/rfc3548.

[27] RSA Laboratories. PKCS #5 v2.0: Password-Based Cryptography Standard, März 1999. ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-5v2/pkcs5v2-0.pdf.

[28] Skype Ltd. API Terms of Use, September 2008. http://www.skype.com/intl/en-us/ legal/terms/api/.

[29] Skype Ltd. Guide for Network Administrators v2.2, 2008. download.skype.com/share/ security/network-admin-guide-version2.2.pdf.

80 Literaturverzeichnis

[30] Skype Ltd. End User License Agreement, Januar 2011. http://www.skype.com/intl/ en-us/legal/eula/.

[31] Skype Ltd. SILK: Super Wideband Audio Codec, Februar 2011. http://developer. skype.com/silk/.

[32] Skype Ltd. Skype Public API, Februar 2011. http://developer.skype.com/ accessories/.

[33] Sophos Ltd. Sophos Endpoint Security and Control and . September 2010. http://www.sophos.com/support/knowledgebase/article/112099.html.

[34] Jan Newger. N-CodeHook, November 2009. http://www.newgre.net/ncodehook.

[35] Sean O’Neil. Skype Library RC4 v1.109, 2010. http://cryptolib.com/ciphers/skype/.

[36] Peter Parkes. 28 million people online on Skype, Januar 2011. http://blogs.skype.com/ en/2011/01/28_million_people_online.html.

[37] Microsoft Research. Detours, Februar 2011. http://research.microsoft.com/en-us/ projects/detours.

[38] Felix Schuster. Möglichkeiten der Implementierung einer sicheren, zusätzlichen Sprach- verschlüsselungsschicht für Skype. In Seminar Netz- und Datensicherheit. Prof. Schwenk, Ruhr-Universität Bochum, Juni 2010.

[39] Ruben U. Skype trojan sourcecode available for download., August 2009. http://www. megapanzer.com/source-code/#skypetrojan.

[40] Ahmad-Reza Sadeghi und Biljana Cubaleska. Skript Vorlesung Systemsicherheit I. Ruhr- Universität Bochum, 2010.

[41] Ian Goldberg und Chris Alexander. Improved User Authentication in Off-The-Record Messaging. Alexandria, USA, Oktober 2007. WPES.

[42] Philippe Biondi und Fabrice Desclaux. Silver Needle in the Skype. Amsterdam, Mai 2006. BlackHat Europe.

[43] Mono Project und Novell. About Mono, April 2011. http://www.mono-project.com/ About.

[44] K. Kaukonen und R. Thayer. A Stream Cipher Encryption Algorithm "Arcfour" (Internet-Draft), Juli 1999. http://www.mozilla.org/projects/security/pki/nss/ draft-kaukonen-cipher-arcfour-03.txt.

81 Literaturverzeichnis

[45] Jonathan Katz und Yehuda Lindell. Introduction to Modern Cryptography. Chapman & Hall/CRC, Boca Raton, USA, 2008.

[46] Andrea Wilkens. Bericht: Europäische Strafermittler wollen VoIP-Gespräche abhö- ren können. heise online, Februar 2009. http://www.heise.de/netze/meldung/ Europaeische-Strafermittler-wollen-VoIP-Gespraeche-abhoeren-koennen-199362. html.

[47] Xiph.Org. Speex: A Free Codec For Free Speech. http://www.speex.org/.

82 Literaturverzeichnis

Abkürzungsverzeichnis

AKE ...... Engl. Authenticated Key-Exchange, authentischer und sicherer Austausch kryptographischer Schlüssel API ...... Engl. Application Programming Interface, Programmierschnittstelle ATL ...... Engl. Active Template Library CBC ...... Engl. Cipher-Block-Chaining (Mode), ein Operationsmodus für Blockchiffren CLSID ...... Engl. Class-Identifier, weltweit einzigartige Identifikationsnummer einer COM Klasse COM ...... Engl. Component Object Model CSP ...... Engl. Cryptographic Service Provider CTR ...... Engl. Counter-Mode, Betriebsmodus für Blockchiffren der diese zu Strom- chiffren werden lässt DLL ...... Engl. Dynamic Link Libraries, dynamisch zu ladende Programmbibliothek EULA ...... Engl. End User License Agreement, Nutzungsbedingungen für den Anwender einer Software GPO ...... Engl. Group Policy Objects, Gruppenrichtlinien GUI ...... Engl. Graphical User Interface, Grafische benutzeroberfläche MAC ...... Engl. Message Authenticaion Codes, symmetrisches Verfahren zur krypt. Au- thentisierung von Nachrichten OTR ...... Engl. Off-The-Record Messaging, kryptographisches Protokoll P2P ...... Engl. Peer-To-Peer, Ende-Zu-Ende PE ...... Engl. Portable Executable, Format ausführbarer Dateien unter Windows PKI ...... Engl. Public-Key Infrastructure SDK ...... Engl. Software Development Kit, Softwareentwicklungskit

83 A. Anhang

A Anhang

Servername Fest kodierte Adressen Hinweis Supernodes 193.88.6.19:33033 Permanente Supernodes von Skype Ltd. 194.165.188.82:33033 195.46.253.211:33033 204.9.163.143:33033 Login Server 193.88.6.13:33033 194.165.188.79:33033 195.46.253.219:33033 Event Server 193.88.8.59:12350 194.165.188.76:12350 212.8.163.76:12350 Search Server 194.165.188.85:12350 SSP Server 194.165.188.92:10100 Vermutlich für Kleintransaktionen 195.46.253.217:10100 Pic Server 195.46.253.205:12351 Vermutlich für Bilder Upgrade Notification S. 194.165.188.89:33033 212.187.172.43:33033 195.46.253.200:33033 212.8.163.113:33033 SIP Server 195.215.8.140:23456 Vermutlich Gateways zu SIP VoIP 212.72.49.155:23456 SMS Server 193.88.8.59:12350 Vermutlich Gateways zum versenden von SMS 194.165.188.76:12350 Partner Query GW S. 194.165.188.77:12350 DynCon Server 204.9.163.211:12350 130.117.72.100:12350 Stats Server 194.165.188.93:13392 195.46.253.218:13392 Presence Server 204.9.163.214:12350 Griffin Server 213.146.188.10:12350 213.146.188.11:12350 213.146.188.12:12350 213.146.188.13:12350 Tabelle A.1.: Servertypen und fest kodierte IP-Adressen im Skype-Client Version 5.0.0.152 für Win- dows

import sys import Skype4Py import s o c k e t

#Platzhalter Verschluesselungsfunktion def encrypt(audio):

84 A. Anhang

encrypted = "" for b in audio : #XOR encrypted += chr(ord(b)^0xAA) return encrypted

#Platzhalter Entschluesselungsfunktion def decrypt(audio): decrypted = "" for b in audio : #XOR decrypted += chr(ord(b)^0xAA) return decrypted

#Platzhalter Audioausgabe def play(audio): print audio

#Funktion wird fuer jede Statusänderung eines Anrufs aufgerufen def OnCall(call , status): global outPort global inPort global micPort

#Ueberpruefung ob es sich um neuen Anruf handelt i f status == Skype4Py. clsInProgress :

#Umleitung der Audiostroeme ueber Netzwerkports print ’Wrting␣outgoing␣voice␣to␣’ + outPort call .OutputDevice( Skype4Py.callIoDeviceTypePort , outPort)

print ’Writing␣mic−in␣to␣’ + micPort call .CaptureMicDevice(Skype4Py.callIoDeviceTypePort , micPort)

print ’Reading␣incoming␣voice␣from␣’ + inPort call .InputDevice( Skype4Py.callIoDeviceTypePort , inPort )

i f __name__ == "__main__" : i f len(sys.argv) != 5: print "Usage␣%s␣[ callee ]␣[audio−in␣port]␣[audio−out␣port]␣\ [mic␣port]" % sys.argv[0] sys . e x i t ( )

callee = sys.argv[1] inPort = sys.argv[2] outPort = sys.argv[3] micPort = sys.argv[4]

skype = Skype4Py.Skype()

#Setzen des Callbacks fuer Telefonate skype.OnCallStatus = OnCall

#Starten von Skype i f not skype. Client .IsRunning: print "Starting␣Skype."

85 A. Anhang

skype.Client.Start()

#Verbinden zu Skype print "Connecting␣to␣Skype. " skype.Attach()

#Erzeugung Anrufkommando callCmd = "CALL␣" + callee

#Absetzen des Anrufkommandos skypeCmd = Skype4Py . skype .Command(Command=callCmd , Blocking=True) skype . SendCommand( skypeCmd )

############################

#Oeffnen der Ports fuer Audioumleitung serverMic = socket . socket(socket .AF_INET, socket .SOCK_STREAM) serverMic.bind(("" , int(micPort)))

serverAudioIn = socket . socket(socket .AF_INET, socket .SOCK_STREAM) serverAudioIn.bind(("" , int(inPort)))

serverAudioOut = socket . socket(socket .AF_INET, socket .SOCK_STREAM) serverAudioOut.bind(("" , int(outPort)))

#Warten auf Verbindung von Skype an Netzwerkports serverMic. listen(1) (clientMic , address) = serverMic.accept()

serverAudioIn. listen (1) (clientAudioIn , address) = serverAudioIn.accept()

serverAudioOut. listen (1) (clientAudioOut , address) = serverAudioOut.accept() print "Got␣connections ."

###############################

#Dauerhaftes Verarbeiten der Audiostroeme while ( True ) : #Einlesen des Audiostroms vom Mikrofon mic = clientMic.recv(1000) #Verschluesseln des eingelesen Audiostroms encryptedMic = encrypt(mic) #Weiterreichen des verschluesselten Audiostroms an Skype clientAudioIn .send(encryptedMic)

#Einlesen des empfangenen Audiostroms audioOut = clientAudioOut.recv(1000) #Entschluesseln des empfangenen Audiostroms decryptedAudioOut = decrypt(audioOut) #Ausgabe des Audiostroms play(decryptedAudioOut)

Listing A.1: Beispielskript zur Umleitung von Audioströmen mit Platzhaltern für kryptographische Funktionen. Angelehnt an Programmierbeispiele des Skype4Py Projekts.

86 A. Anhang

#include " crc32 . h "

//Standard RC4 Context struct RC4_CONTEXT{ unsigned char S [ 2 5 6 ] ; unsigned char i ; unsigned char j ; };

//Headerformate einfacher TCP und UDP Pakete #pragma pack(push, 1) struct SKYPE_UDP_PACKET_TYPE0 { unsigned short i d ; union { /∗∗ Feld kann wohl beliebig lang werden. Einfachster Fall: 1−Byte Flag welches verwendete Obfuskierungsart angibt. ∗∗/ unsigned char dynInts [ ] ; unsigned char f l a g ; }; unsigned int i v 0 ; unsigned int crc32 ; unsigned char payload [ ] ; }; struct SKYPE_TCP_PACKET { unsigned int seed ; /∗∗ Obfuskierter Fixwert der Form: 00 00 00 01 00 00 00 0F ?? ∗∗/ unsigned char characteristic [10]; unsigned char payload [ ] ; }; struct SKYPE_UDP_PACKET_CHARACTERISTIC { unsigned int sr cI P ; unsigned int dstIP ; //ID des Pakets (Null−e r w e i t e r t ) unsigned int zxID ; }; #pragma pack ( pop )

//Adressen RC4 Funktionen (v5.0.0.152) #define ADDR_STD_RC4 0x0060A8B0 #define ADDR_CUSTOM_INIT_RC4 0x007969C0 void ( __stdcall ∗ custom_rc4_init)() = ( void ( __stdcall ∗ ) ( ) ) ADDR_CUSTOM_INIT_RC4; void ( __stdcall ∗ std_rc4)() = ( void ( __stdcall ∗ ) ( ) ) ADDR_STD_RC4;

/∗∗

87 A. Anhang

Wrapper Funktionen ∗∗/ void skypeRC4Init (RC4_CONTEXT∗ pContext , const unsigned int iv , const unsigned int f l a g 0 , const unsigned char∗ pArray , const unsigned int l e n ) { __asm { push eax mov eax , l e n push eax mov eax, pArray push eax mov eax, flag0 push eax mov eax, pContext push eax mov eax , i v }

custom_rc4_init ();

__asm { pop eax } } void skypeRC4 (RC4_CONTEXT∗ pContext , unsigned char∗ pData , const unsigned int l e n ) { __asm { push eax push e s i mov eax , l e n push eax mov eax, pData mov esi , pContext }

std_rc4 ( ) ;

__asm { pop e s i pop eax } }

/∗∗ Funktionen zur Paketdeobfuskierung ∗∗/ bool skypeUDPDecrpytRC4 (SKYPE_UDP_PACKET_TYPE0∗ packet , const int len , const unsigned int srcIP , const unsigned int dstIP ) { //Flag sollte niemals ungerade sein i f ( ( packet−>flag % 2) == 1) {

88 A. Anhang

return f a l s e ; }

RC4_CONTEXT context ; SKYPE_UDP_PACKET_CHARACTERISTIC pc ;

pc.srcIP = srcIP; pc.dstIP = dstIP; pc.zxID = packet−>i d ;

//Berechne 32−Bit Schlüssel/Initialisierungsvektor unsigned int i v ; iv = chksum_crc32(( unsigned char∗)&pc , s i z e of (SKYPE_UDP_PACKET_CHARACTERISTIC) ) ^ packet−>i v 0 ;

//Initialisiere S−Box skypeRC4Init(&context , iv , (packet−>flag / 2), NULL, NULL);

//Entschlüssle Paket skypeRC4(&context , ( unsigned char∗)&( packet−>payload ) , len−s i z e of (SKYPE_UDP_PACKET_TYPE0) ) ;

return t r u e ; }

bool skypeTCPDecrpytRC4 (SKYPE_TCP_PACKET∗ packet , const int l e n ) { i f ( len<=s i z e of (SKYPE_TCP_PACKET) ) return f a l s e ;

RC4_CONTEXT context ;

//Initialisiere S−Box skypeRC4Init(&context , ntohl(packet−>seed), 0, NULL, NULL); //Entschlüssle Fixwert skypeRC4(&context , ( unsigned char∗)&( packet−>characteristic [0]) , s i z e of ( packet−>characteristic ));

//Reinitialisiere S−Box skypeRC4Init(&context , ntohl(packet−>seed), 0, NULL, NULL); //Entschlüssle restliches Paket skypeRC4(&context , ( unsigned char∗)&( packet−>payload ) , len−s i z e of (SKYPE_TCP_PACKET) ) ;

return t r u e ; }

Listing A.2: Programmcode zur Deobfuskierung von Skype Netzwerkpaketen zur Laufzeit (Hooking und Logging fehlen).

89