War diese Seite hilfreich?
Ihr Feedback ist uns wichtig. Teilen Sie uns Ihre Meinung mit.
Weiteres Feedback?
1500 verbleibende Zeichen
Wie lassen sich Netzwerkprotokolle von Grund auf sicher gestalten?
Collapse the table of content
Expand the table of content

Wie lassen sich Netzwerkprotokolle von Grund auf sicher gestalten?

Veröffentlicht: 04. Sep 2006
Von Mark Pustilnik und Andrew Roths

Stellen Sie sich vor, Sie sollen ein neues Kommunikationsprotokoll erstellen: Wie gehen Sie vor, um es sicher und zuverlässig zu gestalten? Da eine umfassende Antwort auf diese Frage sicherlich Bände füllen würde, werden wir uns hier auf einige der üblichsten Szenarios und Probleme konzentrieren.

Viele der dabei behandelten Themen betreffen nicht nur Netzwerke. Sie gelten auch für jede Software mit eingebundenen Sicherheitsfunktionen, wie Verschlüsselung von Dateien oder Zugriffssteuerung. Prinzipien zur Softwaresicherheit sind Technologie-unabhängig und haben meist einen recht universellen Charakter.

Was genau ist ein Protokoll? Wikipedia definiert es als „Regel, welche das Format, den Inhalt, die Bedeutung und die Reihenfolge gesendeter Nachrichten zwischen verschiedenen Instanzen festlegt“. Eine Protokolldefinition enthält Beschreibungen zum Statusmechanismus an beiden Kommunikationsenden, exakte Festlegungen zum Nachrichtenformat, zu kryptografischen Algorithmen, zur Byte-Reihenfolge (Endianness), Portnummern und unzählige weitere Details zu Syntax, Semantik und Synchronisation. Und jeder Aspekt einer Protokolldefinition ist ein potenzielles Ziel für bösartige Angriffe. Sie werden einige Beispiele für Angriffe auf Protokolle und die sich daraus ergebenen Regeln kennen lernen, die Ihnen beim eigenständigen Entwerfen und Implementieren von Protokollen nützlich sein werden.

Auf dieser Seite

 Erst entwerfen, dann entwickeln
 Sicherheitsgarantien festlegen
 Annahmen stets hinterfragen
 Man-in-the-Middle-Angriffe
 Unangebrachtes Vertrauen
 Versionskontrolle vorbereiten
 Schlussbemerkung
 Die Autoren

Erst entwerfen, dann entwickeln

Dieser Grundsatz sollte allgemein gültig sein, wird aber in der Praxis permanent missachtet. Auch die beste Implementierung kann Fehler im Entwurf nicht verbergen. Und während sich für Implementierungsprobleme meist recht schnell Lösungen finden lassen, können Entwurfsfehler dazu führen, dass fast die gesamte Implementierung überarbeitet werden muss. Die Kosten für einen Neuentwurf können auch bei eigenständigen Anwendungen beträchtlich sein. Sie können nahezu katastrophale Ausmaße annehmen, wenn eine Anwendung verteilt ist, und über Client- und Server-Komponenten verfügt, die dem gleichen Entwurf folgen müssen.

Protokolle sind wie die meiste Software für eine große Verbreitung bestimmt, aber sie müssen für eine weitere Herausforderung gerüstet sein. Die gleichzeitige Aktualisierung aller von einem Protokoll abhängigen Elemente ist kaum möglich. Stattdessen muss ein Protokoll normalerweise mit einer Versionsangabe versehen werden, und neue Implementierungen müssen auch ältere Versionen unterstützen können. Dadurch verläuft die Beseitigung von Entwurfsfehlern langsam und mühsam, sodass die Kunden damit deutlich länger zu kämpfen haben als mit Implementierungsfehlern. Besonders kompliziert kann es werden, wenn ein Protokoll mit Software interoperabel sein muss, die von anderen Entwicklern geschrieben wurde, deren Version Sie nicht steuern können. Ein berühmt-berüchtigtes Beispiel für Schwierigkeiten beim Auslöschen alter Protokolle ist NTLM 1.0. Es wurde vor über 10 Jahren eingeführt, seine Schwächen sind schon lange bekannt, aber es hält sich hartnäckig. Trotz eindeutiger Bemühung seitens Microsoft, NTLM 1.0 auszumustern, dauerte dieses Vorhaben mehrere Jahre und umfasste mehrere Betriebssystemversionen. Windows Vista wird das erste Betriebssystem von Microsoft sein, bei dem NTLM 1.0 in der Standardeinstellung deaktiviert ist. Weiter unten in diesem Artikel finden Sie einen Abschnitt darüber, wie Sie Ihre Protokolle für die Versionskontrolle vorbereiten können.

Sicherheitsgarantien festlegen

Sicherheitssoftware hat vor allem mit Sicherheitsgarantien zu tun. Welchen Sicherheitsschutz versprechen Sie für Ihr Endprodukt? Diese Frage mag trivial oder zu allgemein erscheinen, aber indem man sie umfassend und korrekt beantwortet, kommt man direkt zu solideren Entwürfen und gezielteren Tests am fertigen Produkt. Wenn Ihre Firma ein kommerzielles Produkt entwickelt, ist auch unbedingt davon abzuraten, dessen Fähigkeiten zu hoch zu jubeln. Wenn Sie die tatsächlich erreichbaren Sicherheitsgarantien kennen, können Sie es vermeiden, Versprechen zu geben, die das Produkt dann überhaupt nicht halten kann.

Die Softwareanbieter stehen heute in dem schlechten Ruf, ihre Sicherheitsgarantien unzuverlässig zu erläutern. Stellen Sie sich vor, Sie sollen die Sicherheit von Datensicherungssoftware bewerten. Eine der Anforderungen in diesem Rahmen könnte die Diebstahlsicherheit der Sicherungskopien sein. Ist das Versprechen „Ihre Daten sind kennwortgeschützt“ wirklich eine Garantie für ein gutes Produkt? Wie wird das Kennwort geschützt? Werden die Daten überhaupt verschlüsselt? Wenn ja, wie leistungsstark sind die kryptografischen Algorithmen? Bevor Sie Ihre Sicherheitsgarantien den Kunden erklären können, müssen Sie sich erst einmal selbst im Klaren darüber sein, was Ihr Produkt eigentlich leistet. Im eben beschriebenen Fall würde eine gute Sicherheitsgarantie wie folgt klingen: „Der Kennwortschutz stellt sicher, dass Ihre Daten ohne Kenntnis des Kennworts innerhalb eines längeren Zeitraums nicht zugänglich gemacht werden können; allerdings nur, wenn Sie ein gutes Kennwort gewählt haben.“ Leider werden Sie solche Aussagen heutzutage kaum sehen.

Selbst die Sicherheitsgarantien technisch ausgereifter Protokolle können und sollten angezweifelt werden. Ein Beispiel hierfür ist Kerberos. Die Sicherheit von Kerberos beruht zum Teil auf einer leistungsstarken Verschlüsselungssuite, die über den Client mit dem Kerberos-Schlüsselverteilungscenter (KDC) kommuniziert. Wenn Sie kein Kerberos-Experte sind, wissen Sie möglicherweise nicht, wie dies vonstatten geht. Sie tippen vielleicht (mit Recht), dass der Client und das KDC unterschiedliche, einander überlappende Suites mit kryptografischen Protokollen unterstützen. In diesem Licht könnte man eine in etwa so lautende Sicherheitsgarantie erwarten: „Die beiden Parteien werden die bestmöglichste Verschlüsselungssuite aushandeln.“ Wenn also sowohl Client als auch KDC 40-Bit-RC4 und 168-Bit-3DES unterstützen, wird die stärkere 3DES-Verschlüsselung gewinnen.

In der Praxis sieht das folgendermaßen aus. Zuerst sendet der Client eine Liste mit von ihm unterstützten Verschlüsselungssuites an das KDC. Das KDC durchsucht diese Liste und wählt die stärkste vom KDC unterstützte Verschlüsselungssuite aus und wendet sie an.

Oberflächlich gesehen wurde das Ziel erreicht. Bei näherer Betrachtung wird allerdings der Fehler sichtbar: Der Entwickler hat vergessen, dass ein aktiver Man-in-the-Middle-Angreifer die vom Client an das KDC gesendeten Daten ändern könnte. Dabei könnte dann eine Liste mit Verschlüsselungssuites an das KDC gesendet werden, die überhaupt keinen Manipulationsschutz vorsieht. Somit kann der Angreifer bis auf die schwächste Verschlüsselungssuite alle Elemente von der Liste streichen. Der schwächste Algorithmus könnte 40-Bit-RC4 sei, ein Schlüssel, der mit modernen Desktop-Computern innerhalb von 24-48 Stunden per Brute Force geknackt werden kann.

Die korrekte Sicherheitsgarantie bei der Vermittlung von Verschlüsselungssuiten in Kerberos unterscheidet sich daher von der zuvor angenommenen. Sie lautet: „Die beiden Parteien handeln eine Verschlüsselungssuite aus, die nicht schwächer als die schwächste vom Client an das KDC gesendete Option ist.“ Wenn die Sicherheitsgarantie auf diese Weise formuliert wird, können entsprechende Sicherheitsvorkehrungen am Client getroffen werden. Ohne das Protokoll zu ändern, kann der Client aufgefordert werden, nur Verschlüsselungssuites zu senden, die stark genug sind.

Die folgenden Sicherheitsgarantien sollten für technisch ausgereifte Protokolle gelten:

  • Es muss verhindert werden, dass ein Kommunikationspartner andere Partner (Server, Clients, Zwischenknoten usw.) negativ beeinflussen (oder angreifen) kann.

  • Für Man-in-the-Middle-Angreifer sollte es nicht möglich sein, die Kommunikation abzuhören oder die Kommunikationsinhalte so zu ändern, dass dadurch die Sicherheit gefährdet wird.

  • Der Zugriff eines authentifizierten Kommunikationspartners muss auf den Bereich beschränkt bleiben, für den dieser Partner autorisiert ist.

Das sind Garantien auf einer sehr hohen Ebene, die in der Praxis noch weiter aufgegliedert werden müssten, so weit, dass jeder einzelne Aspekt der Kommunikation abgedeckt wird.

Wie Sie sehen, kann die Festlegung von Sicherheitsgarantien ein komplexer und langwieriger Prozess sein. Natürlich sind einige Vereinfachungen möglich. So sollten Sie zum Beispiel bei Sicherheitsanalysen nicht zwischen aktiv bösartigen, manipulierten, falsch konfigurierten oder defekten Knoten unterscheiden. Alle Arten von abweichendem Verhalten können durch einen Angreifer verursacht werden und sollten daher auch so behandelt werden. Zu oft gibt es stark aufgegliederte Sicherheitsgarantien, die deutlich verkürzt werden können.

Annahmen stets hinterfragen

Die Sicherheitsanalyse im Entwurfsstadium beginnt für jede Software mit dem Hinterfragen der Annahmen der Entwickler. Hacker sind darin besonders gut. Wenn Sie sicher gehen wollen, dass Ihr Entwurf einer solchen Überprüfung standhält, müssen Sie diese Analyse selbst durchführen. Planen Sie sie noch in die Entwurfsphase ein, dann können Sie unsichere Aspekte entdecken und ändern, ohne sich Sorgen um die Abwärtskompatibilität machen zu müssen oder Ihren guten Ruf in Gefahr zu bringen. Mit Beginn der Implementierung verlieren Sie nach und nach diesen Vorteil. Sobald das Produkt ausgeliefert wird, ist Ihre Chance vorbei.

Das sind einige der Annahmen, die Softwareentwickler häufig in Gefahr bringen. Erstens: Eine neue Sicherheitstechnologie baut stets auf anderen Technologien oder Protokollen auf, ohne dass genau überprüft wird, welche Sicherheitsgarantien diese geben. Wahrscheinlich entwerfen Sie Ihr Protokoll nicht von Grund auf. Sie setzen wohl eher eine Lösung aus verschiedenen Blöcken zusammen: Kommunikationswege, Verschlüsselungsgrundlagen, Authentifizierungsalgorithmen usw. Eine Voraussetzung für das Definieren Ihrer eigenen Sicherheitsgarantien ist die genaue Kenntnis der Sicherheitsgarantien, die die Technologien geben, auf die Sie Ihren Entwurf aufbauen. Wissenslücken auf diesem Gebiet können schnell zu Rissen und Einschränkungen in Ihren eigenen Garantien führen. Auf einem wackeligen Fundament kann man nicht gut bauen.

Jede Informationsquelle, auf deren Grundlage Ihre Anwendung Entscheidungen über die Vertrauenswürdigkeit trifft, muss sorgfältig überprüft und von Grund auf verstanden werden. Ein Beispiel dafür ist das DNS-Protokoll, das zur Auflösung der Netzwerknamen verwendet wird. DNS hat keine eigenen Sicherheitsfunktionen und liefert keine Sicherheitserklärungen zu den IP-Adressen, die während der Namensauflösung zurückgegeben werden. Eine IP-Adresse kann die des gewünschten Hosts sein, oder aber die eines möglichen Angreifers, der darauf wartet, zuzuschlagen. Bei einem Entwurf unter Verwendung von DNS muss diese fehlende Sicherheitsgarantie mit bedacht werden. Eine mögliche Lösung wäre es, eine TLS/SSL-Sitzung mit der aufgelösten Adresse einzurichten. Auf diese Weise muss der Computer an der aufgelösten Adresse ein Zertifikat mit einer Signatur vorweisen, die im vertrauenswürdigen Stammspeicher des Sendercomputers abgelegt ist. Dadurch wird normalerweise sichergestellt, dass die Identität des Servers von einer vertrauenswürdigen Zertifizierungsstelle bestätigt ist.

Als weiteres Beispiel kann man die Sicherheitsgarantien heranziehen, von denen Sie abhängig sind, wenn Sie ein Authentifizierungsprotokoll nutzen. Jedes Authentifizierungsprotokoll beinhaltet einen Nachrichtenaustausch zwischen Client und Server. Neben der Bestätigung der Client-Identität für den Server hat ein gutes Authentifizierungsprotokoll noch mindestens drei weitere Eigenschaften. Erstens werden die Anmeldeinformationen des Clients an keinen der Server weitergegeben, für den sich der Client authentifiziert bzw. an keinen möglichen Lauscher, der die Kommunikation abhört. Zweitens ist der Nachrichtenaustausch gegen Wiedergabe gesichert (sodass der Mitschnitt eines Datenaustauschs von einem potenziellen Angreifer nicht dafür verwendet werden kann, den Client beim nächsten Austausch zu täuschen). Drittens ermöglicht das Protokoll es dem Client und dem Server, einen geheimen Sitzungsschlüssel zu erzeugen, der zum Signieren und Verschlüsseln verwendet und somit zur Absicherung der Kommunikation werden kann (dazu später mehr). Dieser Sitzungsschlüssel muss so gestaltet sein, dass ihn ein Angreifer mit vollem Zugriff auf alle zwischen Client und Server gesendeten Nachrichten nicht ableiten kann.

Die am häufigsten von Windows® verwendeten Authentifizierungsprotokolle (Digest, NTLM und Kerberos) haben alle diese Eigenschaften (siehe Abbildung 1). Und reicht das? Die Antwort darauf ist nicht ganz einfach.

Ein etwas komplizierteres Beispiel ist das NTLM-Authentifizierungsprotokoll. NTLM wurde dafür entwickelt, die Authentizität eines Clients gegenüber einem Server zu überprüfen. Es enthält keine Authentifizierung des Servers zurück an den Client. Das bedeutet, dass NTLM nicht über eine gegenseitige Authentifizierung verfügt (siehe letzte Reihe in Abbildung 1). Das kann katastrophale Folgen haben, wenn der Client nicht so aufgebaut ist, dass er dieser fehlenden Sicherheitsgarantie Rechnung trägt.

Es gibt zahlreiche Sicherheitsschwächen, die mit dem Fehlen der gegenseitigen Authentifizierung zusammen hängen. Was, wenn der Client ausführbare Dateien öffnet, die vom Server geschickt wurden? Was, wenn der Client nach erfolgreicher Authentifizierung gegenüber dem Server vertrauliche Informationen, wie z. B. Kreditkartennummern oder Formulare mit personenbezogenen Informationen (Personally Identifiable Information, PII), an den Server sendet? Normalerweise löst man dieses Problem durch die Verwendung sicherer Übertragungswege, wie z. B. SSL, ein Übertragungsmechanismus, der dem Client die Authentizität des Servers garantiert und den gesamten Datenverkehr gegen Lauscher und Manipulation schützt.

Sie müssen sich klar machen, dass Sie keine Sicherheitsgarantien zu Ihrem Entwurf machen können, bevor Sie sich nicht genau mit den Sicherheitsgarantien aller Protokolle, Technologien und Funktionen vertraut gemacht haben, die er nutzt.

Man-in-the-Middle-Angriffe

Man kann sich fast nie sicher sein, dass der Datenverkehr vor Man-in-the-Middle-Angriffen sicher ist, da es unglaublich viele Möglichkeiten für Angreifer gibt, sich in einen fremden Kommunikationskanal einzuschleusen. Die Folgen können sehr ernst sein. Sie haben bereits erfahren, wie ein Man-in-the-Middle-Angriff in Kerberos dafür sorgen kann, dass eine gefährlich schwache Verschlüsselungssuite ausgehandelt wird. Aufgrund des unsicheren Aufbaus der älteren IETF-Protokolle (Internet Engineering Task Force) sind Angriffe wie ARP-Eindringversuche (Address Resolution-Protokoll) oder DNS-Spoofing umfangreich dokumentiert, einfach auszuführen und in vielen Umgebungen durchaus effektiv. Als Alternative kann ein Netzwerk einen bösartigen DHCP-Server enthalten, der das Standard-Gateway aller verfügbaren Clients auf einen bösartigen Router einstellt. Auch ohne einen Angreifer im lokalen Subnetz kann man nicht wirklich sicher sein, dass alle Router, die den Datenverkehr zwischen zwei Computern weiterleiten, zu 100 % gegen Angreifer geschützt sind und nur im Interesse des Benutzers arbeiten. Das gilt besonders, wenn einige dieser Router von unterschiedlichen Unternehmen oder Regierungen (!) betrieben werden. Zudem sind die meisten Netzwerke nicht gegen simple, physikalische Veränderungen immun – oder wissen Sie ganz genau, wohin das Ethernet-Kabel an der Rückseite Ihres Geräts führt? Diese Liste ist längst nicht vollständig.

Diese Annahme ist oft dort sichtbar, wo Protokolle nach der Authentifizierung den Datenverkehr nicht verschlüsseln oder signieren. Unter diesen Bedingungen kann ein Angreifer warten, bis eine Authentifizierung abgeschlossen ist, und dann die folgenden Daten beobachten oder sogar ändern. In vielen Fällen ist es dem Angreifer so auch möglich, als der authentifizierte Benutzer zu agieren.

Viele Protokolle senden nach der Authentifizierung den gesamten Datenverkehr in unverschlüsselter Form: E-Mail-Protokolle wie IMAP und POP3 sind gute Beispiele dafür. Eine gängige Lösung ist es, den gesamten Datenverkehr über einen sicheren Übertragungsweg zu leiten (IPsec oder SSL/TLS). Auf diese Weise kann der Angreifer den Datenverkehr nicht überwachen, und jeder Änderungsversuch wird vom Empfänger erkannt.

Was kann man noch gegen solche Angriffe unternehmen? Ein leistungsstarkes Authentifizierungsprotokoll (wie Kerberos und, in geringerem Maße, NTLM) ermöglicht es den Kommunikationspartnern, einen gemeinsamen Sitzungsschlüssel als Teil der Authentifizierung auszuhandeln. Dieser gemeinsame Schlüssel kann dann zweifach genutzt werden: Zur Erhaltung der Integrität (Signieren der Nachrichten und damit Verhinderung von Manipulation) und zum Schutz der Daten (Verschlüsselung des Datenverkehrs, Abwehr von Lauschern). Wie bereits erwähnt, bietet ein technisch ausgereiftes Authentifizierungsprotokoll eine eigene Sicherheitsgarantie: Der „Mann in der Mitte“ wird nicht in der Lage sein, an den gemeinsamen Sitzungsschlüssel zu kommen. Dieser geheime Schlüssels ist es, was die gesamte Kommunikation schützt – Verwenden Sie ihn!

Die Implementierung von Integrität und Datenschutz muss nicht kompliziert sein. Wenn Sie SSPI (Security Service Provider Interface) für die Authentifizierung nutzen, können sie mit nur wenigen Schritten eingebaut werden.

Schritt 1: Client und Server so konfigurieren, dass Integrität und Datenschutz angefordert werden. Auf der Client-Seite wird dies durch Einfügen von zwei Flags beim Aufrufen von InitializeSecurityContext erreicht. ISC_REQ_INTEGRITY und ISC_REQ_CONFIDENTIALITY müssen zum Parameter fContextReq hinzugefügt werden. Auch auf der Server-Seite müssen zwei Flags eingefügt werden. Der Parameter ist auch hier fContextReq, aber diesmal geht es um die Funktion AcceptSecurityContext. Bei den beiden Flags handelt es sich hier um ASC_REQ_INTEGRITY und ASC_REQ_CONFIDENTIALITY. Es ist wichtig, dass sowohl Client als auch Server diese Flags verwenden. SSPI ist ein vom Übertragungsweg unabhängiger Authentifizierungsmechanismus, stellt also keine Verbindung zwischen einer Authentifizierung und dem Protokoll her, das diese Authentifizierung durchführt.

Stellen Sie sich jetzt zwei Protokolle vor, die beide SSPI verwenden und Datenschutz verhandeln. Bei Protokoll A fordert der Client Datenschutz an, aber der Server nicht. Bei Protokoll B ist die Sache umgekehrt: Der Server fordert Datenschutz, aber der Client nicht. Oberflächlich betrachtet sieht alles gut aus; alle Verbindungen sollten zumindest auf einer Seite Datenschutz anfordern. Leider kann ein Angreifer tatsächlich diese Situation ausnutzen, indem er einen protokollübergreifenden Angriff durchführt.

Er würde zwei Verbindungen herstellen: Eine mit einem Protokoll B-Client und eine mit einem Protokoll A-Server. Sobald die Verbindungen stehen, würde jede eine SSPI-Authentifizierung mit dem Angreifer versuchen. Der Angreifer muss sich darüber keine Sorgen machen, weil SSPI nicht an ein bestimmtes Protokoll gebunden ist. Er könnte SSPI-Daten aus einem Protokoll entnehmen und in das andere einspeisen. Tut der Angreifer dies mehrmals, erhält er eine erfolgreiche Authentifizierung für beide Verbindungen erhalten. Dieser Angriff ist in Abbildung 2 dargestellt.

Abbildung 2: Protokollübergreifender Angriff
Abbildung 2 : Protokollübergreifender Angriff

Leider hat weder der Client noch der Server in dieser Authentifizierung Datenschutz angefordert. Der Angreifer kann nun zwei unverschlüsselte Verbindungen angreifen. Wenn sowohl Client als auch Server Datenschutz anforderten, hätten beide Protokolle diesen Zustand vermeiden können. Und auch wenn dieser Fehler bei zwei Protokollen vorkommen muss, kann die Sicherheit aller anderen Protokolle kaum garantiert werden. Es ist viel besser, wenn Sie sich Ihre Sicherheit selbst garantieren.

Schritt 2: Überprüfen, ob Integrität/Datenschutz erfolgreich verhandelt wurden. Es ist nicht garantiert, dass die von Ihnen im vorhergehenden Schritt angeforderten Attribute während der Authentifizierung auch erfolgreich verhandelt wurden. Um zu überprüfen, ob die Verhandlung erfolgreich war, müssen Sie den Parameter pfContextAttr prüfen, der von InitializeSecurityContext und AcceptSecurityContext zurückgegeben wird. Überprüfen Sie dabei, ob die im Parameter fContextReq eingestellten Flags auch immer noch im Parameter pfContextAttr vorhanden sind. Wenn etwas fehlt, wurde das entsprechende Flag nicht erfolgreich verhandelt. Die Kommunikation darf nicht fortgeführt werden, bis nicht beide Kommunikationspartner die jeweils geforderte Qualität des Schutzes erhalten.

Schritt 3: Daten signieren und verschlüsseln. Auch wenn Integrität und Datenschutz erfolgreich verhandelt wurden, sind die Daten nicht automatisch geschützt. Dazu müssen Sie die zu schützenden Daten eine der beiden Funktionen durchlaufen lassen. Zum Signieren ist es die Funktion MakeSignature. Zum Verschlüsseln ist es die Funktion EncryptMessage. Unabhängig davon, welche Funktion Sie verwenden, achten Sie immer besonders auf den Parameter fQOP, der die gewünschte Qualität des Schutzes festlegt. Die akzeptablen Werte hängen vom zugrunde liegenden Authentifizierungsprotokoll ab. Manchmal kann sogar ein Wert ausgewählt werden, der überhaupt keinen Schutz anbietet. Ein Beispiel dafür ist das Flag SECQOP_WRAP_NO_ENCRYPT, das in der Funktion EncryptMessage bei Kerberos-Authentifizierungen zur Verfügung steht. Wird dieses Flag verwendet, verschlüsselt es die Daten, die die Funktion EncryptMessage durchlaufen, nicht.

Wenn Sie den verhandelten Sitzungsschlüssel zur Sicherung der Nachrichten verwenden, wird ein Angriff gegen das NTLM-Authentifizierungsprotokoll abgeschwächt. Zum Teil aufgrund der fehlenden gegenseitigen Authentifizierung ist NTLM nicht sicher, wenn ein Angriff durch einen bösartigen Server vorliegt. Der Server kann dann als Proxy fungieren und leitet Authentifizierungsnachrichten sowie die Antworten an einen anderen Server weiter. Dieses Phänomen wird Weiterleitungsangriff (Forwarding Attack) genannt. Wenn nach der Authentifizierung kein Sitzungsschlüssel zum Schutz der Nachrichten verwendet wird, kann der bösartige Server als Client des Zielservers fungieren.

Ein solcher Angriff (siehe Abbildung 3) zielt häufig auf Unternehmensnetzwerke ab, wo die Mitarbeiter arglos Links zu Intranet-Dateien nutzen, die ihnen von Kollegen zugesandt wurden. Der Angriff beginnt, indem ein Angreifer (der bösartige Server) eine Locknachricht an den Client sendet, z. B. eine Aufforderung, eine interessante Datei von dem bösartigen Server herunterzuladen. Um die Datei zu erhalten, muss sich der Client gegenüber dem bösartigen Server authentifizieren, der vorgibt, nur NTLM zu unterstützen. Der bösartige Server übernimmt dann alle Nachrichten, die vom Client an den Zielserver gesendet wurden, gegenüber dem der bösartige Server als Client auftreten will. Alle Authentifizierungsnachrichten des Zielservers werden an den tatsächlichen Client zurückgeschickt. Nach abgeschlossener Authentifizierung geht der Zielserver davon aus, dass er eine genehmigte Sitzung mit dem Client abhält, kommuniziert aber in Wirklichkeit mit dem bösartigen Server. Der Client merkt währenddessen überhaupt nicht, dass er sich gegenüber dem Zielserver authentifiziert hat.

Abbildung 3: Weiterleiten der NTLM-Authentifizierung
Abbildung 3 Weiterleiten der NTLM-Authentifizierung

Der Weiterleitungsangriff funktioniert bei Kerberos nicht, da die Authentifizierungsnachrichten dort nur von dem Server verarbeitet werden können, für den sie bestimmt sind. Und selbst wenn NTLM verwendet wird, bedeutet eine erfolgreiche Authentifizierung, dass Client und Zielserver über einen geheimen Sitzungsschlüssel verfügen, den sich der bösartige Server nicht beschaffen kann. Wenn also der Zielserver darauf besteht, dass an ihn gesendete Nachrichten mithilfe des gemeinsamen Sitzungsschlüssels signiert und verschlüsselt werden, wird es dem bösartigen Server nicht gelingen, eine vom Zielserver akzeptierte Nachricht zu senden. Damit ist es ihm auch nicht möglich, Nachrichten, die der Client an den Zielserver sendet, zu verstehen oder zu verändern, ebenso wenig wie die Antworten des Servers. Vergessen Sie nicht, dass auch bei der Verwendung von Kerberos der Datenverkehr signiert und verschlüsselt werden muss, es sei denn, Sie verwenden einen sicheren Übertragungsweg (z. B. SSL). Denn nur dann sind Sie wirklich vor Man-in-the-Middle-Angriffen zwischen Ihnen und dem Server geschützt.

Unangebrachtes Vertrauen

Es fällt leicht anzunehmen, dass durch die Verwendung eines sicheren Übertragungswegs Man-in-the-Middle-Angriffe absolut unmöglich sind. Das stimmt aber nicht unbedingt. Betrachten Sie einmal die Sicherheitsgarantien, die sichere Übertragungswege geben.

Als Beispiel dienen SSL und die damit verbundenen Sicherheitsgarantien. SSL garantiert also, dass die Verbindung verschlüsselt ist und dass der Client mit dem gewünschten Server kommuniziert. Wodurch wird sichergestellt, dass der Client den richtigen Server anfordert? Es gibt häufig Situationen, in denen diese Anforderung auf Grundlage einer vorherigen Klartext-Kommunikation beruht. In diesem Fall kann sich der Angreifer ein vertrauenswürdiges SSL-Zertifikat beschaffen und dann einfach das Klartext-Protokoll so manipulieren, dass die SSL-Verbindung umgeleitet wird. Mit einer vertrauenswürdigen SSL-Verbindung zum Client kann der Angreifer das Vertrauen, das der Client in eine SSL-Verbindung setzt, weidlich ausnutzen.

Ein anderes Problem tritt auf, wenn SSL-Verbindungen unsichere Authentifizierungsprotokolle schützen. Zu oft ist ein unsicheres Authentifizierungsprotokoll nicht auf den gleichen Computer wie die SSL-Verbindung beschränkt. Nehmen Sie einmal an, der Server am Ende einer vertrauenswürdigen SSL-Verbindung handelt bösartig. In diesem Fall kann der bösartige Server das unsichere Authentifizierungsprotokoll über eine andere SSL-Verbindung auf einen anderen Server umleiten (siehe Abbildung 4). Wenn der Client keine Möglichkeit hat, die Authentifizierung auf den Server zu beschränken, mit dem die SSL-Verbindung besteht, authentifiziert er sich möglicherweise für einen beliebigen Server. Abhängig vom unsicheren Authentifizierungsprotokoll könnte der bösartige Server dann als der Client auftreten.

Abbildung 4: Authentifizierung umleiten
Abbildung 4 Authentifizierung umleiten

IPsec ist auch nicht gegen dieses Problem immun. Ein Beispiel ist eine Sicherheitsrichtlinie, die jedes Mal, wenn ein bestimmtes Protokoll verwendet wird, einen IPsec-Tunnel anfordert. Wird dies korrekt umgesetzt, kann damit sichergestellt werden, dass alle Teilnehmer gültige IPsec-Anmeldeinformationen haben. Allerdings sind normalerweise keine Verbindungen zwischen den IPsec-Anmeldeinformationen der Teilnehmer und dem durch den Tunnel genutzten Protokoll vorgesehen. Daher kann jeder, der über gültige Anmeldeinformationen verfügt, das Protokoll angreifen. Auch wenn viele potenzielle Angreifer sicherlich nicht über gültige Anmeldeinformationen verfügen: Bietet diese Sicherheitsrichtlinie wirklich den gewünschten Schutz? Möglicherweise haben Lieferanten, Berater und verärgerte Mitarbeiter gültige Anmeldeinformationen. Kann man ihnen trauen? Wie ist es um die Sicherheit ihrer Computer bestellt?

Unabhängig vom sicheren Übertragungsweg muss man sich der Schwäche des zugrunde liegenden Protokolls bewusst sein und verstehen, wie der Übertragungsweg Schutz vor Angreifern bietet, die diese Schwächen ausnutzen. Ein Beispiel hierfür ist ein sehr leistungsschwaches Klartext-Authentifizierungsprotokoll. Die Verwendung eines sicheren Übertragungswegs wird sicherlich Schutz vor der Preisgabe von Kennwörtern bieten, aber möglicherweise wird dieser Schutz nicht immer ausreichen. Angenommen, die Anmeldeinformationen eines Clients sind auf mehreren Servern gültig. Wenn sich der Client mit dem Klartext-Protokoll bei einem Server anmeldet, ist dieser Server in der Lage, die Anmeldeinformationen des Clients auf allen anderen Servern erneut zu verwenden. Das könnte sehr problematisch sein, wenn einer der Server bösartig ist oder manipuliert wurde. In solchen Situationen bietet der sichere Übertragungsweg nicht den gewünschten absoluten Schutz. Wenn so ein Fall eintritt, muss zur Gewährleistung eines ausreichenden Schutzes möglicherweise eine neue Version des schwachen Protokolls erstellt werden, oder es muss durch ein anderes Protokoll ersetzt werden. So könnte z. B. die Klartext-Authentifizierung durch eine SSPI-Authentifizierung ersetzt werden.

Der größte Teil der wirtschaftlichen Verluste aufgrund von Sicherheitslücken geht nicht auf Ereignisse zurück, die das gesamte Internet betreffen (wie z. B. der Blaster-Wurm), sondern auf Insider-Angriffe. Der Löwenanteil dieser Angriffe ist nur möglich, weil authentifizierten Parteien fälschlicherweise zu großes Vertrauen entgegen gebracht wird.

Natürlich wird einem authentifizierten Kommunikationspartner mehr vertraut als einem unbekannten. Dieses zusätzliche Vertrauen muss allerdings streng auf die Aktionen und Daten beschränkt sein, die ihm von der Zugriffsteuerungsrichtlinie des Systems zugewiesen sind. Oft wird einem authentifizierten Kommunikationspartner eher anständiges Verhalten zugetraut als einer fremden Person: Eingabeprüfungen sind lockerer, die Zugriffskontrolle nicht so streng und so weiter.

Mit „authentifizierten Kommunikationspartnern“ sind aber nicht nur Clients, sondern auch Server gemeint. Ein technisch ausgereiftes System schützt nicht nur einen Server vor einem bösartigen Client, sondern auch den Client vor einem bösartigen Server. Das wird häufig übersehen. Als Beispiel dient der Datenaustausch zwischen Client und Server in Abbildung 5. Der Client fordert Daten an und ordnet den Speicherplatz zu, der ihm vom Server genannt wird. Der Server sendet aber ein zusätzliches Datenpaket von 1 KB. Der Client kopiert die gesamten 101 KB, ohne die tatsächliche Größe der gesendeten Datenmenge zu überprüfen, sodass der Puffer überläuft und der Server willkürlichen Code auf dem Clientsystem ausführen kann.

Abbildung 5: Bösartiger Client-Server-Austausch
Abbildung 4 Authentifizierung umleiten

Es klingt vielleicht merkwürdig, dass ein Server versuchen soll, einen Client anzugreifen, aber es geschieht. Möglicherweise wurde der Computer, der den Server hostet, von einem Angreifer manipuliert. In anderen Fällen hat vielleicht der Server-Administrator bösartige Absichten. Eventuell handelt es sich auch um einen Man-in-the-Middle-Angriff. Was auch immer der Grund sein mag, der Client ist für seine eigene Sicherheit zuständig. Er muss die vom Server eingehenden Daten überprüfen und darf nicht davon ausgehen, dass unmittelbare Antworten auch Konsistenz bedeuten.

Sicherheitsüberlegungen dieser Art gehen weit über Probleme mit Implementierungsfehlern hinaus. Stellen Sie sich vor, ein vertrauenswürdiger Server wird von einem Hacker übernommen oder der Administrator ist aus irgendeinem Grund über die Firma verärgert. Welche Risiken würden daraus für die Clients des Servers entstehen? Die ideale Antwort darauf wäre „Keine“, aber das entspricht meist nicht der Praxis. Nehmen Sie einmal an, das Protokoll übermittelt personenbezogene Informationen (PII). Wenn die Aufgabe des Servers darin besteht, diese PII zu verarbeiten, stellt ein manipulierter oder bösartiger Server fast immer ein Risiko für den Client dar. Der Zugriff auf den Client sollte in der Praxis auf die Mindestfunktionalität begrenzt sein, die vom Server verlangt wird. Dieses Minimum ist nicht immer klar definiert.

Wenn nun ein Protokoll eine automatische Update-Funktion hat: Als Teil des Aktualisierungsvorgangs muss der Server möglicherweise eine ausführbare Datei für das Update an den Client senden. Auf den ersten Blick sieht es so aus, als ob die Mindestfunktionalität dieser Funktion es dem manipulierten Server erlauben würde, alle Clients dieses Servers zu manipulieren, indem er ihnen einfach bösartige ausführbare Aktualisierungsdateien schickt. Das muss aber nicht so sein. Für diese Funktion ist als Mindestfunktionalität nur die Verteilung vertrauenswürdiger ausführbarer Dateien erforderlich, nicht die Verteilung beliebiger ausführbarer Dateien. Nehmen Sie einmal an, die Clients sind so entworfen, dass sie nur ausführbare Dateien ausführen, die mit einem bestimmten privaten Schlüssel signiert sind, und dass dieser private Schlüssel niemals auf dem Server gespeichert wird. Plötzlich stellt ein manipulierter Server nicht mehr automatisch eine Gefahr für die Clients dar. Jetzt müsste erst noch der private Schlüssel, mit dem die ausführbaren Dateien signiert werden, von einem Angreifer oder einem Administrator mit bösartigen Absichten manipuliert werden.

Allzu oft sind Clients leider deutlich weiter zugänglich als für die notwendigen Mindestfunktionalität. Ein letzter Hinweis zu Servern: Denken Sie daran, dass ein Server mit Verbindungen zu vielen Clients ein großartiges Ziel für die Weitergabe von Würmern darstellt.

Versionskontrolle vorbereiten

Die Entwicklung im Bereich Sicherheit bleibt nicht stehen. Ein heute leistungsstarkes Verschlüsselungs- oder Authentifizierungsprotokoll kann schon morgen einem Hackerangriff zum Opfer fallen. Vielleicht wird bei Ihrer eigenen Entwicklung ein Entwurfs- oder Implementierungsfehler festgestellt, bei dessen Behebung die Kompatibilität zwischen alter und neuer Version verloren gehen würde. Für alle diese Fälle müssen Sie Ihr Protokoll auf die Versionskontrolle vorbereiten. Bauen Sie Ihr Protokoll so auf, dass die vom Kommunikationspartner verwendete Version beim Nachrichtenaustausch frühzeitig festgestellt werden kann. Bereiten Sie Ihre Neuentwicklungen darauf vor, mehrere Authentifizierungsschemas, zusätzliche Schlüssel und ältere Clients oder Server zu unterstützen. Ein Tipp für jede dieser Arten der Versionskontrolle:

Authentifizierungsschemas hinzufügen:  SSPI reduziert den Bedarf an Endprotokollen und regelt so um die Einzelheiten der Authentifizierungsmechanismen. Es erstellt auch einen zentralen Ort für die Authentifizierungsprotokolle. Falls bei einem dieser Protokolle ein Entwurfsfehler festgestellt wird, vereinfacht dieser zentralen Ort die Aktualisierung der betroffenen Protokolle ungemein. Microsoft empfiehlt generell die Verwendung des Aushandlungspakets für die Authentifizierung. Dieses Paket versucht zu verhandeln, dass das leistungsstärkere Kerberos-Protokoll verwendet wird, und fällt auf NTLM zurück, wenn sich dies als unmöglich herausstellt. Sie sollten nicht versuchen, diese Aufgabe besser auszuführen als das Aushandlungspaket. Außerdem wird das Aushandlungspaket zukünftig aktualisiert, damit ein leistungsstärkeres Authentifizierungsprotokoll verwendet werden kann, sobald eins verfügbar ist.

Kryptografische Flexibilität einplanen:  Wenn Ihr Protokoll von der Stärke einer bestimmten Verschlüsselung abhängt, z. B. 3DES, sollten Sie auf den Fall vorbereitet sein, dass sich diese Verschlüsselung später einmal als zu schwach erweist. Weiter oben in diesem Artikel haben Sie das Beispiel eines Protokolls gesehen, das eine Verschlüsselungssuite verhandelt. Wenn Sie ähnliche Vorkehrungen in Ihren Entwurf einfließen lassen, erhalten Sie sich die Möglichkeit, Ihr installiertes Protokoll auf eine leistungsstärkere Verschlüsselung zu aktualisieren, ohne dabei die Kompatibilität zu zerstören. Die CNG-API (Cryptography Next Generation, Nächste Verschlüsselungsgeneration), die für Windows Vista geplant ist, wird es Ihnen ermöglichen, Ihre eigenen Verschlüsselungsprotokolle nahtlos mit Windows zu kombinieren.

Veraltete Protokolle schrittweise auslaufen lassen:  Die Versionskontrolle von Protokollen ist meist ein schrittweiser Prozess. Wenn eine neue Protokollversion auf den Markt kommt, werden über einen bestimmten Zeitraum meist beide Versionen unterstützt. Dann sind die Teilnehmer am anfälligsten für Downgrade-Angriffe: Ein Client oder Server kann vorgeben, eine ältere Version zu unterstützen, und versucht so, auf der anderen Seite oder im Protokoll selbst Sicherheitslücken im Entwurf oder in der Implementierung auszunutzen. Eine Versionskontrollenstrategie muss eine Möglichkeit zum Abschalten der Unterstützung für Clients oder Server mit älteren Versionen vorsehen, sobald solche Versuche überhand nehmen.

Schlussbemerkung

Das Entwerfen eines sicheren Protokolls ist eine knifflige Angelegenheit. In diesem Artikel wurden einige der häufigsten Fehlerquellen umrissen, aber es gibt noch viele weitere. Eine gute Möglichkeit, Ihren Entwurf gegen Fehler abzusichern, besteht darin, ihn von anderen Softwareentwicklern überprüfen zu lassen. Geben Sie ihnen eine Aufstellung Ihrer Sicherheitsgarantien, und erläutern Sie Ihre Vorgehensweise. So können Sie sicherstellen, dass sie während des iterativen Softwareentwicklungsprozesses keine Sicherheitslücken übersehen.

Diese Aufgabe ist nicht zu meistern, wenn Sie nicht im Detail die Sicherheitscharakteristiken der von Ihnen verwendeten Bausteine verstehen, einschließlich der Erkenntnis, dass sie nicht unfehlbar sind. Sie können mit einiger Sicherheit davon ausgehen, dass früher oder später auch in Ihrem Entwurf Sicherheitslücken entdeckt werden. Wappnen Sie sich dafür, indem Sie Ihren Entwurf auf die Versionskontrolle vorbereiten und austauschbare Elemente einplanen, wie z. B. Authentifizierungs- und Verschlüsselungsgrundlagen.

Die Autoren

Mark Pustilnik und Andrew Roths sind Mitglieder eines Teams bei Microsoft, das neue Microsoftprodukte auf potenzielle Sicherheitsrisiken untersucht. Dieser Artikel beruht auf echten Erfahrungen beim Analysieren von Netzwerkprotokollen.

Aus der Ausgabe vom September 2006 des MSDN-Magazins.


Microsoft führt eine Onlineumfrage durch, um Ihre Meinung zur MSDN-Website zu erfahren. Wenn Sie sich zur Teilnahme entscheiden, wird Ihnen die Onlineumfrage angezeigt, sobald Sie die MSDN-Website verlassen.

Möchten Sie an der Umfrage teilnehmen?
Anzeigen:
© 2015 Microsoft