Möglichkeiten der Implementierung einer sicheren, zusätzlichen
Transcription
Möglichkeiten der Implementierung einer sicheren, zusätzlichen
Möglichkeiten der Implementierung einer sicheren, zusätzlichen Sprachverschlüsselungsschicht für Skype Seminar Netz- und Datensicherheit (SoSe 2010) Horst Görtz Institut für IT-Sicherheit Ruhr-Universität Bochum Felix Schuster Matr.-Nr:1008006253627 felix.schuster@rub.de 9. Juli 2010 1 Inhaltsverzeichnis I Einleitung 3 1 Das Programm Skype 3 2 Bereits vorhandene Abhörschutzmaßnahmen 3 II Mögliche Ansätze 4 3 Allgemeine Schwierigkeiten 4 4 Pre Audio Codec Verschlüsselung 4.0.1 Skype API . . . . . . . . . . . . . . . . . . . . . . . . . . 4.0.2 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . 5 6 10 5 TCP/UDP Paketverschlüsselung 5.1 Win32 API Hooking . . . . . . . . . . 5.2 Konzept zur Implementierung . . . . . 5.2.1 C# Komponente - GUI . . . . 5.2.2 C/C++ Komponente - hook.dll 5.3 Zusammenfasung . . . . . . . . . . . . 10 11 15 15 16 16 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Teil I Einleitung 1 Das Programm Skype Skype ist zweifelsohne die bekannteste und beliebteste nicht im Browser laufende Anwendung der Web 2.0 Ära. Es ist Instant-Messenger, VoIP-Client und Videotelefon in einem und konnte dank einfacher Benutzbarkeit und überrangender Qualität seit dem Start im Jahre 2003 große Marktanteile von ehemals sehr populären Anwendungen wie ICQ oder AIM für sich gewinnen. Die Besonderheit von Skype liegt in der Struktur des zugrunde liegenden Netzwerkes. Dieses ist, basierend auf der Technologie des mittlerweile eingestellten File-Sharing Dienstes Kazaa, voll auf so genannte Peer-To-Peer Verbindungen Direktverbindungen zwischen einzelnen Computern - ausgelegt. So werden nur für den Vorgang der Anmeldung von Nutzern Server von Skype selbst bereitgestellt. Alle anderen für das Betreiben der verschiedenen Dienste notwendigen Aufgaben werden auf die Endgeräte der Nutzer ausgelagert. Diese spezielle Struktur gepaart mit der Tatsache, dass das Unternehmen Skype, welches mittlerweile zum Internetkonzern eBay gehört, allgemein bemüht ist, technische Details über sein Produkt geheimzuhalten, werfen natürlich Fragen zur Sicherheit der übertragenen Daten auf. Können geführte Telefonate abgehört werden? Wird irgendwo gespeichert wer mit wem telefoniert hat? Unbestritten ist auf jeden Fall, dass Geheimdienste aus aller Welt ein großes Interesse daran haben, über Skype geführte Gespräche abzuhören[4]. Diese Unsicherheiten werden in dieser Arbeit zum Anlass genommen, mögliche Verfahren zu beschreiben und zu evaluieren, mit denen Gespräche über Skype abhörsicher - das heisst geschützt durch sichere Kryptographieverfahren wie AES - geführt werden könnten. Die besondere Herausforderung ist hier durch die ungewöhnlich komplexen Verschleierungsmaßnahmen von Seiten der SkypeClients gegeben. 2 Bereits vorhandene Abhörschutzmaßnahmen In 2006 wurde auf der bekannten IT-Sicherheitskonferenz BlackHat in Las Vegas ein Vortrag von Ingenieuren des Unternehmens EADS gehalten [1], der einen tieferen Einblick in die damalige Version des Skype-Clients für Windows bot. In ihrem Vortrag unterstreichen Philippe Biondi und Fabrice Desclaux die Vehemenz mit der der Skype-Client für Windows sich gegen jegliche Arten des Reverse Engineerings zur Wehr setzt. Trotz dessen kommen die beiden Autoren zu dem Schluss, dass Kommunikation über Skype, geschützt durch die bekannten und bewährten Algorithmen AES und RSA, prinzipiell sicher ist. Jedoch weisen sie auch darauf hin, dass das Unternehmen Skype als Betreiberin der Certificate Authority des Dienstes sehr 3 wohl zu so genannten Man-In-The-Middle Attacken in der Lage ist. Das heisst, wenn das Unternehmen Skype ein Interesse daran hat ein Gespräch zwischen zwei Skype-Clients abzuhören, dann ist es dazu auch fähig. Teil II Mögliche Ansätze Das Ziel ist es, über die bereits vorhandene Verschlüselungsschicht des Protokolls des Skype-Netzwerkes eine weitere, transparente und kontrollierbare Verschlüsselungsschicht zu legen, ohne die Qualität des Dienstes selber merklich zu beeinflussen. Die möglichen Ansätze und die sich ergebenden Schwierigkeiten werden in diesem Kapitel behandelt. Dabei beziehen sich sämtliche Aussagen, sofern nicht gegenteilig angemerkt, auf die Windows Version des Skype-Clients. 3 Allgemeine Schwierigkeiten Als erste Idee für die mögliche Realisierung eines Vorhabens wie dem beschriebenen, ergibt sich natürlich der Weg über ein mögliches Plugin-Interface o.ä. 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[5]. Dadurch, dass Skype sich zudem agressiv gegen Versuche des Reverse Engineerings wehrt und als nur eine einzelne monolithische .exe Datei von über 20MB ausgeliefert wird, bleibt kaum mehr, als das Programm als Black Box zu betrachten. Nach Einschätzung des Autors ergeben sich unter dieser Prämisse genau Abbildung 1: Betrachtung von Skype als Black Box 4 zwei Ansatzpunkte für eine zusätzliche Verschlüsselungsschicht: Da Skype über keine eigenen Treiber verfügt, ist es darauf angewiesen mit dem Windows Betriebssystem zu kommunizieren, um a) Audiodaten vom Mikrofon des PCs zu lesen und Audiodaten über die Soundkarte auszugeben und b) allgemein Daten über das Netzwerk zu verschicken (siehe auch Abbildung 1). An diesen Schnittstellen sollte es, ohne genauere Kenntnis der inneren Funktionsweisen von Skype zu haben, möglich sein, Daten abzugreifen und zu manipulieren. 4 Pre Audio Codec Verschlüsselung Als erster der beiden identifizierten Ansätze, soll hier die Möglichkeit diskutiert werden Audiodaten vor dem Eingang in die Skype-Software zu verschlüsseln und nach der Ausgabe aus dieser (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 selbstverständlich Audiodaten vor dem Versenden über das Netzwerk verlustbehaftet komprimiert und nach dem Empfang wieder entsprechend dekomprimiert. Man benötigt also ein Verschlü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 solch ein Verfahren überhaupt technisch realisierbar ist. Im Falle von Skype kommt noch erschwerend hinzu, dass seit dem Jahre 2009 ein hoch komplexer, auf Sprache optimierter und in jahrelanger Eigenentwicklung entstandener Audio-Codec namens SILK zum Einsatz kommt. Der Programmcode für diesen Codec ist allerdings öffentlich zugänglich und ließe sich folglich einfach analysieren. Ungeachtet der ganz eigenen Problematik die die Verschlüsselung eines noch zu komprimierenden Audiostroms mit sich bringt, stellt sich hier als nächstes natürlich die Frage, auf welche Art die Audiodaten am besten abgegriffen werden. Die nahe liegendste Herangehensweise für so ein Vorhaben ist vermutlich das Programmieren eines speziellen Treibers der sich gegenüber dem Skype-Client als Soundkarte mit Mikrofoneingang und Lautsprecherausgang ausgibt. Dieser Treiber würde als eine Art Vermittler zwischen der realen Soundkarte des Systems und dem Skype-Client agieren und erst einmal einfach sämtliche Daten und Anfragen weiterreichen. Zur Verschlüsselung eines Telefonats würden dann sämtliche von der realen Soundkarte kommenden Signale vor der Weiterleitung verschlüsselt und sämtliche von Skype kommenden Audiosignale vor der Weitergabe an die Soundkarte wieder entschlüsselt. Auch wenn dieser Ansatz auf den ersten Blick als durchaus praktikabel erscheinen mag, so erweist er sich bei näherer Betrachtung als äußerst unpraktisch. So ist erst einmal das Programmieren eines Treibers eine äußerst komplizierte und teure Angelegenheit, die auch noch sehr Plattform spezifisch ist - sollte so eine Software einmal auf ein anderes Betriebssystem wie z.B. Apples OS X 5 portiert werden sollen, so wäre das Schreiben eines komplett neuen Treibers unerlässlich. Zudem wäre es für so eine Software-Soundkarte“ wohl unmöglich ” zwischen tatsächlichen Sprachdaten und anderen Audioausgaben von Skype zu unterscheiden, was zu erheblichen Problemen bei der Synchronisation der Entschlüsselung führen dürfte. Die Lösung liefert hier ein Blick in die Dokumentation der öffentlichen API des Skype-Clients. 4.0.1 Skype API Die Skype-Clients für unterschiedliche Plattformen stellen über eine API Funktionalität für eine automatische, textbasierte Bedienung bereit[5]. So lassen sich beispielsweise mit dem Kommando SEARCH FRIENDS“ alle gespeicher” ten Kontakte für den aktuell eingeloggten Account erfragen und anschließend mit CALL myFriend“ einer dieser Kontakte anrufen. Skype-Clients antworten ” ebenfalls in textbasierter Form. Interessant für das gegebene Vorhaben sind die folgenden drei Befehle[5]: ALTER CALL <id> SET_INPUT SOUNDCARD="default" | PORT="port_no" | FILE="FILE_LOCATION" ALTER CALL <id> SET_OUTPUT SOUNDCARD="default" | PORT="port_no" | FILE="FILE_LOCATION" ALTER CALL <id> SET_CAPTURE_MIC PORT="port_no" | FILE="FILE_LOCATION" Mit ihnen 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 Netzwerk-Port zu setzen. Dadurch ist es möglich die Audioströme so über besimmte Netzwerk-Ports umzuleiten, dass diese einfach abgegriffen und manipuliert werden können - ohne das das Programmieren eines Treibers nötig wird. Eine Skizze des Ansatze ist in Abbildung 2 zu sehen. Es bleibt die Frage, auf welchem Wege solche Befehle und die entsprechenden Antworten mit dem Skype-Client ausgetauscht werden. Unter Windows erfolgt dies über so genannte Window Messages[7]. Diese Art der Kommunikation ist für Anwendungen wie die gegebene eher ungewöhnlich und ist wohl der Tatsache geschuldet, dass Skype prinzipiell versucht seine Client-Software abzuschotten. Um Nachrichten an das Fenster des Skype-Clients senden zu können muss man zunächst wissen welches der womöglich vielen Fenster auf einem Windows Desktop das gesuchte ist. Dazu sendet man eine so genannte Broadcast ” Message“ an sämtliche Fenster und wartet auf eine Anwort des Skype-Clients (Abbildung 3). Danach können textbasierte Kommandos einfach per Windows API SendMessage() [8] direkt an das Skype Fenster gesendet werden. Auf die entsprechenden Antworten von Skype lässt sich danach mit WaitMessage() [9] warten. Das Open-Source Projekt Skype4Py hat es sich zur Aufgabe gemacht, dieses 6 Abbildung 2: Umleitung von Audioströmen des Skype-Clients und des Mikrofons über Netzwerk-Ports Abbildung 3: Identifizierung des Skype Fensters doch recht unhandliche System zu Kapseln und ein einfacheres Interface für die Skriptsprache Python bereitzustellen[10]. Neben Windows ist dieses für OS X und Linux erhältlich und somit quasi plattformunabhängig. Im Rahmen dieser Arbeit wurde zu Demonstrationszwecken ein Python Skript erstellt, dass unter Verwendung von Skype4Py die Audioströme des SkypeClients nach Abbildung 2 so umleitet, dass diese manipuliert werden können: Listing 1: Verschlüsselung des ausgehenden Audiostroms import s y s import Skype4Py import s o c k e t def e n c r y p t ( a u d i o ) : encrypted = ”” #dummy e n c r y p t i o n ! 7 f o r b in a u d i o : e n c r y p t e d += c h r ( ( ord ( b ) ˆ 0xAA)&0xFF) return e n c r y p t e d def OnCall ( c a l l , s t a t u s ) : global C a l l S t a t u s global WavFile global ou tPo rt CallStatus = status print ’ C a l l s t a t u s : ’ + skype . Convert . C a l l S t a t u s T o T e x t ( s t a t u s ) i f ( s t a t u s == Skype4Py . c l s E a r l y M e d i a or s t a t u s == Skype4Py . c l s I n P r o g r e s s ) and ou tPor t != ’ ’ : print ’ Saving v o i c e t o ’ + out Por t c a l l . OutputDevice ( Skype4Py . c a l l I o D e v i c e T y p e P o r t , OutPort ) ou tPor t= ’ ’ i f s t a t u s == Skype4Py . c l s I n P r o g r e s s and micPort != ’ ’ : print ’ Writing mic−i n t o ’ + micPort c a l l . CaptureMicDevice ( Skype4Py . c a l l I o D e v i c e T y p e P o r t , micPort ) i f s t a t u s == Skype4Py . c l s I n P r o g r e s s and i n P o r t != ’ ’ : print ’ Reading v o i c e from ’ + i n P o r t c a l l . I n p u t D e v i c e ( Skype4Py . c a l l I o D e v i c e T y p e P o r t , i n P o r t ) def AttachmentStatusText ( s t a t u s ) : return skype . Convert . AttachmentStatusToText ( s t a t u s ) # This h a n d l e r i s f i r e d when Skype a t t a t c h m e n t s t a t u s c h a n g e s def OnAttach ( s t a t u s ) : print ’ API attachment s t a t u s : ’ + AttachmentStatusText ( s t a t u s ) i f s t a t u s == Skype4Py . a p i A t t a c h A v a i l a b l e : skype . Attach ( ) def OnReply ( v a l u e ) : print ” Reply : ” +v a l u e . Reply def OnCommand( v a l u e ) : print ”Command : ” +v a l u e . Command def O n A p p l i c a t i o n S e n d i n g ( v a l u e ) : print ” A p p l i c a t i o n s e n d i n g : ” +v a l u e 8 #s e t t i n g p o r t s i n P o r t = ” 22042 ” ou tPor t = ” ” micPort =” 22041 ” # C r e a t i n g Skype o b j e c t and a s s i g n i n g e v e n t h a n d l e r s . . skype = Skype4Py . Skype ( ) skype . OnAttachmentStatus = OnAttach skype . O n C a l l S t a t u s = OnCall skype . OnCommand = OnCommand skype . O n A p p l i c a t i o n S e n d i n g = O n A p p l i c a t i o n S e n d i n g # S t a r t i n g Skype i f i t ’ s not running a l r e a d y . . i f not skype . C l i e n t . IsRunning : print ’ S t a r t i n g Skype . . ’ skype . C l i e n t . S t a r t ( ) # A t t a t c h i n g t o Skype . . print ’ Connecting t o Skype . . ’ skype . Attach ( ) print ’ C a l l i n g echo123 ’ callCmd = ”CALL echo123 ” skypeCmd = Skype4Py . skype . Command(Command=callCmd , B l o c k i n g=True ) skype . SendCommand ( skypeCmd ) print skypeCmd . Reply s e r v e r M i c = s o c k e t . s o c k e t ( s o c k e t . AF INET , s o c k e t .SOCK STREAM) s e r v e r M i c . bind ( ( ” ” , 2 2 0 4 1 ) ) s e r v e r I n = s o c k e t . s o c k e t ( s o c k e t . AF INET , s o c k e t .SOCK STREAM) s e r v e r I n . bind ( ( ” ” , 2 2 0 4 2 ) ) serverMic . l i s t e n (1) ( clientMic , address ) = serverMic . accept () serverIn . l i s t e n (1) ( clientIn , address ) = serverIn . accept () print ” g o t c o n n e c t i o n s ” while ( True ) : 9 mic = c l i e n t M i c . r e c v ( 1 0 0 0 ) #e n c r y p t a u d i o stream from mic encryptedMic = e n c r y p t ( mic ) c l i e n t I n . send ( encryptedMic ) Das Skript startet ein Telefonat mit dem immer erreichbaren Skype-Testnutzer echo123 und leitet dabei sämtliche vom Mikrofon des PCs kommende Audiodaten durch die Funktion encrypt() bevor diese an den Skype-Client weitergereicht werden. Es sei angemerkt, dass Teile des Programmcodes aus Beispielskripten des Skype4Py Projektes übernommen wurden. 4.0.2 Zusammenfassung Es wurde gezeigt, dass es ohne Verwendung von speziellen Treibern mit Hilfe des Open Source Projekts Skype4Py plattformunabhängig möglich ist, die ein- und ausgehenden Audioströme des Skype-Clients abzufangen und zu manipulieren. Weiterhin ungeklärt ist jedoch, wie und ob es möglich ist, Audiodaten verlässlich und sicher zu verschlüsseln, die einen verlustbehafteten Audio-Codec durchlaufen. TODO: Voteile 5 Netzwerkpaketverschlüsselung Als zweiter Ansatz zur Verschlüsselung von Telefonaten über das Skype Netzwerk, wurde das Manipulieren von Daten auf Netzwerkpaketebene identifiziert. Anders als beim bereits behandelten Ansatz des Abfangens von Audioströmen, stellt die Skype API jedoch keinerlei Funktionalität betreffend des Netzwerkverkehrs des Skype-Clients bereit. Hier ist also eine andere Herangehensweise notwendig. Um Daten über das Netzwerk verschicken zu können, ist jeder Skype-Client darauf angewiesen diese an das Betriebssystem zu übergeben. Unter Windows führt dafür für kein Programm ein Weg vorbei an der Verwendung der Windows eigenen API-Funktionen. Um diese Verwenden zu können, muss ein Prozess die passenden Dlls wie z.B. kernel32.dll oder user32.dll des Betriebssystem in seinen Adressraum laden und die entsprechenden Funktionen aus diesen aufrufen. Der Kontrollfluss eines Programms verzweigt also in gegen Analyse ungeschützte Dlls des Windows Betriebssystems (sie auch Abbildung 4). Diese Tatsache wird sich allgemein häufig zunutze gemacht, wenn unter Windows das Verhalten eines Programmes (z.B. eines Virus) generisch überprüft oder manipuliert werden soll. So überschreiben beispielsweise eine Vielzahl von Anti-Viren Lösungen die Einstiegspunkte von API-Funktionen der System-Dlls dynamisch mit einer Art Umleitung in ihren eigenen Programmcode - im Fachjargon Hook“ genannt - um ” 10 Abbildung 4: Skype Prozess mit geladenen Windows System-Dlls Programme auf verdächtige Verhaltensmuster hin zu überprüfen. Mit genau dieser Technik ist es auch möglich die Interaktion zwischen SkypeClient und Windows Betriebssystem abzuhören und zu manipulieren. 5.1 Win32 API Hooking Die Best Practice“ zur Umleitung von Aufrufen von Windows-APIs innerhalb ” eines beliebigen Prozesses wird in [11] beschrieben. Wie dort dargelegt, lässt sich unter allen neueren Windows Betriebssystemen mit einem Kniff eine beliebige Dll in jeden Prozess laden. So wird es möglich, Daten und Kontrollflüsse innerhalb eines Prozesses beinahe beliebig zu verändern - und somit auch Hooks an Einstiegspunkten zu Windows-APIs zu platzieren. Eine entsprechende Dll zum hooken“ von API-Funktionen, zusammen mit ei” nem flexliblen Interface für die Skriptsprache Python wurde vom Autor dieser Arbeit bereits für ein früheres Projekt in Grundzügen implementiert. Die Funktionsweise des Ansatzes ist schematisch in Abbildung 5 dargestellt. Nach dem Laden der hook.dll in den Adressraum des Skype-Prozesses nimmt jene Dll über so genannte Named Pipes“ Kontakt mit dem Python-Interface auf ” und wartet auf Anweisungen. Soll nun eine bestimmte API-Funktion gehookt werden, so wird der Einstiegspunkt dieser Funktion mit einem Sprung zu einer bestimmten Funktion in hook.dll überschrieben. Sobald hook.dll so den Aufruf einer API-Funktion registriert, teilt es dies dem Python-Interface mit, wo dann beliebige Aktionen durchgeführt werden können (z.B. Auslesen von Argumenten der gehookten API-Funktion). Für diese Arbeit wurde der Programmcode der Dll und des Interfaces erheblich um Funktionalität erweitert und angepasst. So ist es beispielsweise in der aktuell vorliegenden Version mit den folgenden Zeilen Python-Code möglich, alle 11 Abbildung 5: Python API-Hooking Framework mit Skype Prozess Aufrufe von sämtlichen API-Funktionen der System-Dll WS2 32.dll 1 innerhalb des Skype-Prozesses mitzuschneiden und auszugeben. Listing 2: Mitschneiden von Aufrufen von API-Funktionen aus WS2 32.dll from h o o k C l a s s import h o o k e d P r o c e s s from c t y p e s import ∗ from win32 import ∗ import p e f i l e #. . . kernel32 = windll . kernel32 user32 = windll . user32 def printApiName ( p r o c e s s , apiName , addrRet , a r g s ) : #p r i n t name o f c a l l e d API f u n c t i o n print ”WS2 32.% s ( ) ” % apiName return True process = hookedProcess ( ) #s e t s k y p e . e x e as t a r g e t p r o c e s s . setUp ( ” skype . exe ” , HOOK PATH, PIPE SEND , PIPE RECIEVE) 1 WS2 32.dll stellt unter Windows u.a. sämtliche Standard-C Netzwerkfunktionen wie connect(), send() oder recv() bereit und ist somit hier von besonderem Interesse. 12 #l o a d ws2 32 . d l l pe = p e f i l e . PE( ” c : \ \ Windows\\ system32 \\ ws2 32 . d l l ” ) #i t e r a t e o v e r a l l named e x p o r t s . . . f o r exp in pe .DIRECTORY ENTRY EXPORT. symbols : i f exp . name != None : # . . . and hook them p r o c e s s . hookAPI ( ” ws2 32 . d l l ” , exp . name , 0 , printApiName ) #run Skype p r o c e s s . run ( ) In dem gegebenen Beispielskript wird mit Hilfe des Open-Source Projekts pefile zunächst über alle von WS2 32.dll bereitgestellten API-Funktionen iteriert. Jede vorhandene API-Funktion wird dabei gehookt, wobei als so genannter Callback“ die Python-Funktion printApiName() angeben wird. Dies bewirkt, ” dass der Name jeder aufgerufenen Api-Funktion auf der Konsole ausgegeben wird. So meldet das Skript beispielsweise folgende Aufrufe unmittelbar nach dem Start der Skype.exe: WS2_32.WSAStartup() WS2_32.WahCreateHandleContextTable() WS2_32.WahOpenApcHelper() WS2_32.WahOpenCurrentThread() WS2_32.socket() WS2_32.WahOpenCurrentThread() WS2_32.WSASocketW() WS2_32.WahCreateHandleContextTable() WS2_32.WahInsertHandleContext() WS2_32.WahInsertHandleContext() WS2_32.WahReferenceContextByHandle() WS2_32.ioctlsocket() WS2_32.WSAIoctl() WS2_32.WahReferenceContextByHandle() WS2_32.WahReferenceContextByHandle() WS2_32.setsockopt() WS2_32.WahReferenceContextByHandle() WS2_32.WahReferenceContextByHandle() WS2_32.setsockopt() WS2_32.WahReferenceContextByHandle() WS2_32.WahReferenceContextByHandle() WS2_32.ntohl() WS2_32.htonl() WS2_32.ntohs() WS2_32.htons() WS2_32.bind() 13 WS2_32.WahReferenceContextByHandle() WS2_32.WahReferenceContextByHandle() WS2_32.getsockname() WS2_32.WahReferenceContextByHandle() WS2_32.WahReferenceContextByHandle() WS2_32.ntohl() WS2_32.htonl() WS2_32.ntohs() WS2_32.htons() WS2_32.ntohl() WS2_32.htonl() WS2_32.ntohs() WS2_32.htons() WS2_32.sendto() WS2_32.WahReferenceContextByHandle() WS2_32.WahReferenceContextByHandle() WS2_32.ntohs() WS2_32.htons() WS2_32.socket() WS2_32.ntohl() WS2_32.WSASocketW() WS2_32.htonl() WS2_32.WahInsertHandleContext() WS2_32.ntohs() WS2_32.WahInsertHandleContext() WS2_32.htons() WS2_32.WahReferenceContextByHandle() WS2_32.sendto() WS2_32.WSAIoctl() WS2_32.WahOpenCurrentThread() WS2_32.WahReferenceContextByHandle() ... Lässt man genau dieses Skript während eines Gesprächs mit einem anderen Skype-Teilnehmer laufen, so zeigt sich, dass zum Aufbau einer Verbindung die Socket gebundenen API-Funktionen send() und recv() verwendet werden, um Kontakt mit dem Skype-Client des gewünschten Gesprächspartners aufzunehmen. Sobald jedoch eine Verbindung hergestellt und der Angerufene das Gespräch akzeptiert hat, werden die eigentlichen Gesprächsdaten verbindungslos in einzelnen UDP-Paketen mit Hilfe der API-Funktionen sendto() und recvfrom() gesendet bzw. empfangen[12]. Die Pakete wurden dabei in allen im Rahmen dieser Arbeit durchgeführten Tests direkt und ohne Umwege zwischen den beiden beteiligten Clients hin und her gesandt. Die entsprechenden IP-Adressen konnten aus den an die API-Funktionen sendto() und recvfrom() übergebenen Argumenten direkt entnommen werden. 14 Ebenso konnte ohne Probleme auf die zu sendenden und empfangenen Nutzdaten zugegriffen werden. Es ist also möglich, sämtliche Sprachpakete2 eines Gesprächs an der Schnittstelle zwischen Skype und der Windows-API abzufangen, zu manipulieren und der jeweiligen Empfänger- bzw. Absender IP-Adresse zuzuordnen. Somit kann eine weitere, überprüfbare Verschlüsselungsschicht unter Windows realisiert werden. 5.2 Konzept zur Implementierung Im vorangegangenen Abschnitt wurde gezeigt, dass es möglich ist, Gespräche zwischen zwei Skype-Clients unter Windows gezielt zu verschlüsseln. In diesem Abschnitt sollen dazu ein konkretes Konzept für eine tatsächliche Implementierung entworfen werden. Die Problematik bei der Realisierung der gestellten Aufgabe ist, dass nicht sämtliche über WS2 32.sendto() ausgehende Pakete verschlüsselt werden dürfen. Umgekehrt gilt das Gleiche für über WS2 32.recvfrom() eingehende Pakete. Denn neben den eigentlichen Gesprächsdaten verwendet Skype diese API-Funktionen für eine Vielzahl anderer Kommunikationsaufgaben innerhalb des Skype-Netzwerkes. Sollten dabei die falschen Pakete manipuliert werden, so wäre es sehr wahrscheinlich, dass die Funktionalität des betroffenen Clients eingeschränkt würde. Es ist also unabdingbar, ein- und ausgehende Pakete korrekt in Bezug auf Empfänger/Absender als auch Inhalt zuzuordnen. Letzteres ist ohne Kenntnis der nicht öffentlichen Verschlüsselungsverfahren des Skype-Netzwerkes natürlich nur mit heuristischen Ansätzen möglich. Für die konkrete Implementierung erscheint eine Lösung aus zwei Komponenten am komfortabelsten. Der Aufbau dieser beiden Komponenten wird im Folgenden umrissen. Eine schematische Darstellung ist in Abbildung 6 zu sehen. 5.2.1 C# Komponente - GUI In der Programmiersprache C# ist es besonders einfach grafische Oberflächen für Windows Betriebssysteme zu entwickeln. Entsprechend liegt es nahe, die Benutzeroberfläche der Verschlüsselungslösung mit dieser Sprache zu entwickeln. Hinzu kommt, dass mit Hilfe des Open-Source Projektes Skype4COM, ähnlich wie bei Skype4Py für Python, sehr komfortabel auf die Skype-API zugegriffen werden kann. Mit Hilfe von Skype4COM, soll die C# GUI-Komponente auf ein- und ausgehende Telefonate warten. Trifft eines der beiden Ereignisse ein, so soll eine 2 Diese Sprachpakete wurden zuvor in jedem Fall bereits von Skype verschlüsselt. Ohne genaue Kenntnis des internen Verschlüsselungsverfahren des Skype-Netzwerkes ist es also nicht möglich den eigentlichen Inhalt der Pakete einzusehen. 15 Abbildung 6: Konzept der zu entwickelnden Software Textnachricht an den Gesprächspartner geschickt werden, um zu überprüfen, ob dieser über eine kompatible Verschlüsselungssoftware verfügt. Ist dies der Fall, so sollen beide Seiten zunächst ihre IP-Adressen austauschen (für die spätere Zuordnung von Netzwerkpaketen) und anschließend einen kryptographischen Schlüssel für die anstehende Sitzung vereinbaren. Danach stößt die C# Anwendung die Injezierung einer Dll (hook.dll im Folgenden) zum hooken der beiden API-Funktionen WS2 32.sendto() und WS2 32.recvfrom() in den Prozess der Skype.exe an. Bevor das anstehende Telefonat freigegeben wird, wird hook.dll noch über eine Named Pipe der zu vereinbarte Sitzungschlüssel und die IP-Adresse des Gesprächspartners mitgeteilt. Von diesem Zeitpunkt an, soll hook.dll alle Pakete an diese IP-Adresse mit dem gegebenen Schlüssel verschlüsseln und umgekehrt eingehende Pakete entschlüsseln. 5.2.2 C/C++ Komponente - hook.dll Aus Gesichtspunkten der Verarbeitungsgeschwindigkeit ist es nicht sinnvoll, dass für das Prototyping verwendete Hooking-Framework auch in der fertigen Anwendung zu benutzen. Stattdessen soll besagte hook.dll neu in der Sprache C entwickelt werden, die sich auf das Hooken von WS2 32.sendto() und WS2 32.recvfrom() zur Ver- bzw. Entschlüsselung beschränkt. Als einzige weitere Funktion ist das Lesen von Sitzungsschlüssel und Gesprächspartner-IP von einer Named Pipe zu implementieren. Zur konkreten Realisierung der API-Hooking Funktionalität bietet sich die Verwendung von Microsofts kostenlosem SDK Detours an [13]. Ob zur Ver- bzw. Entschlüsselung am besten eine Strom- oder eine Blockchiffren zu verwenden ist, muss noch geklärt werden. 5.3 Zusammenfasung Es wurde gezeigt, dass es mit Hilfe von API-Hooking unter Windows möglich ist Gespräche zwischen zwei Skype-Clients zu verschlüsseln. Dazu wurde ein 16 konkretes Konzept zur Entwicklung einer entsprechenden Anwendung geliefert. Ungeklärt bleibt die Frage wie Konferenzgespräche zu handhaben sind. Diese wurde in den durchgeführten Versuchen nicht berücksichtigt. Des Weiteren bleibt zu klären wie im Falle des Relaying von Gesprächen zu verfahren ist. Dabei werden nach [2] die Daten eines Gesprächs nicht direkt zwischen den Clients ausgetauscht, sondern über einen dritten Skype-Teilnehmer geleitet. Die zuordnung nach IP-Adressen dürfte hier also erstmal fehlschlagen. Das der Ansatz des API-Hookings auch auf anderen Betriebssystemen als Windows sinnvoll zu implementieren ist zu erwarten, bleibt aber ebenfalls ungeklärt. 17 Literatur [1] Biondi, Desclaux (2006), Silver Needle in the Skype [2] Hayes (2008), Skype: A Practical Security Analysis [3] Microsoft Developer Network, Winsock Reference [Online] http://msdn. microsoft.com/en-us/library/ms741394(VS.85).aspx [4] heise online, Bericht: NSA bietet Milliarden, um Skype abzuhören [Online] http://www.heise.de/newsticker/meldung/ Bericht-NSA-bietet-Milliarden-um-Skype-abzuhoeren-195547. html [5] Skype Public accessories [6] SILK: Super Wideband Audio Codec [Online] http://developer. skype.com/silk [7] Microsoft Developer Network, About Messages and Message Queues [Online] http://msdn.microsoft.com/en-us/library/ ms644927(VS.85).aspx [8] Microsoft Developer Network, SendMessage [Online] http://msdn. microsoft.com/en-us/library/ms644950(VS.85).aspx [9] Microsoft Developer Network, WaitMessage [Online] http://msdn. microsoft.com/en-us/library/ms644956(v=VS.85).aspx API [Online] http://developer.skype.com/ [10] SourceForge, Skype4Py [Online] projects/skype4py/files/ http://sourceforge.net/ [11] Ivo Ivanov, API hooking revealed [Online] http://www.codeproject. com/KB/system/hooksys.aspx [12] Microsoft Developer Network, sendto [Online] http://msdn. microsoft.com/en-us/library/ms740148(VS.85).aspx [13] Microsoft Blogs, detours [Online] http://blogs.msdn.com/b/ junfeng/archive/2006/08/24/720978.aspx 18