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