SSL-Angriffe und ihre Abwehr
in HTML, Web | Tags: Angriff, Client, HTML, HTTPS, Man-in-the-middle, Proxy, Server, Spam, SSL, WebWer auf seiner Webseite per SSL Inhalte vor unberechtigten Augen schützen möchte, ist zur Zeit mächtig gebeutelt: Jeden Tag hört man neue Schreckensmeldungen über Angriffsmethoden gegen den verschlüsselten Daten-Austausch zwischen Client und Server. Jetzt fragt man sich natürlich, ob SSL überhaupt noch sicher ist und wenn ja, mit welchen Methoden man sich und die Nutzer seiner Website schützt. Man muss dazu die vorgestellten Angriffsszenarien analysieren.
Man-in-the-middle zwischen Client und Server
Ersteinmal beziehen sich alle Angriffe auf eine Situation namens Man-in-the-middle. Das heißt, der Angreifer sitzt zwischen Nutzer und Server. Er muss also einen Rechner besitzen, der die Anfragen des Client mitliest, an den Server weiterleitet und später dessen Antwort an den Client vermittelt. Ein Proxy, Gateway oder Router erfüllt diese Voraussetzung. Nennen wir ihn einfach mal Proxy. Ohne diese Gegebenheit ist ein SSL-basierter Datenaustausch grundlegend sicher, das ist schon einmal ein guter Ausgangspunkt. Doch wie nutzt nun der Proxy seine Rolle aus?
Während des Datenaustausches zwischen Client und Server kann der Proxy zum Beispiel einen Login-Ablauf des Client am Server mitlauschen und nachspielen. Er tauscht dazu innerhalb einer HTML-Seite mit Verweis zum Login-Bereich alle Aufrufe von https://meinhost.de/login.php durch http://meinhost.de/login.php aus. Der Benutzer wechselt also beim Eintippen gar nicht in den HTTPS- (also SSL-)Modus – und gibt dem Angreifer die gewünschten Informationen per POST-Formular bekannt. Jetzt kann der Proxy die Daten dem Server übergeben – hier kann er verschlüsselt arbeiten – und dadurch sowohl Client als auch dem Server eine funktionierende, direkte Verbindung vortäuschen. Später kann er die Daten für Spionage nach Zahlungsdaten missbrauchen, verkaufen, vom Server aus weitere Angriffe im Namen des Clients starten oder darüber Spam versenden.
Wie kann man nun diesen Angriffen begegnen? Alle Ideen sind hier gefragt! Denn sollte sich herausstellen, dass die verschlüsselte, intime Kommunikation zweier Internet-Teilnehmer untereinander nicht gesichert ist, so ist das Fortbestehen sämtlicher netzbasierten Dienste in Frage gestellt. Zwar ist solch eine Proxy-Situation heutzutage noch sehr selten gegeben. Doch wenn die Möglichkeiten infolge des Problems erst einmal bekannt sind, wird sich das schnell ändern. Ein Angriff auf die Vertrauenswürdigkeit der Internet-Infrastruktur hat im Informationszeitalter durchaus katastrophale Folgen – eine Schande, warum DNS noch so schwächelt!
Ideen sind gefragt
Der wunde Punkt ist wohl das Wissen der Kommunikations-Partner übereinander. Was weiß der Client über den Server? Was weiß der Server über den Client, was er gegen den Angreifer nutzen kann? Leider ist ein Service, zum Beispiel ein Shop oder eine Plattform, grundsätzlich für jedermann offen und auch bisher unbekannte Gäste sind herzlich eingeladen, den Server zu kontaktieren. Doch gibt es etwas, was sie vom Man-in-the-middle unterscheidet?
Mir ist folgendes dazu eingefallen: Wir könnten dem Client signalisieren, er müsse auf die Verschlüssung achten. Zum Beispiel an verschiedenen Stellen darüber informieren, dass wir grundsätzlich sicher kommunizieren wollen. Der Nutzer soll doch darauf achten, dass immer das Verschlüsselungssymbol aktiviert ist. Der Angreifer müsste dann diverse Ausgabetexte manipulieren, um dessen Anzeige zu verhindern. Aber nicht jeder Benutzer liest Hinweise oder folgt diesen gar, zu lange war Software so unausgereift, sodass eine grundsätzliche Ignoranz gegenüber Fehlermeldungen festzustellen ist.
Damit würde man auch nur den Punkt der Nicht-Verschlüsselung der Proxy-Client-Verbindung beheben. Letztenendes könnte auch der Proxy selbst mit dem Client verschlüsselt kommunizieren, mit seinem eigenen Zertifikat natürlich. Wir können aber kaum erwarten, dass der Nutzer nach dem Aufbau der verschlüsselten Verbindung zum Proxy das übermittelte Zertifikat prüft.
Desweiteren könnte man die Verschlüsselung per JavaScript testen. Dazu ruft man nach dem Aufbau der Seite deren URL im Browser ab. Dessen Filterung wäre allerdings sehr einfach und nicht jeder Browser kommt mit JavaScript daher, wenn auch viele. Ich weiß gar nicht, ob es JavaScript-Funktionen zum Auslesen der Zertifikatinformationen gibt. Falls überhaupt, wäre ein einfacher Austausch der JavaScript-Funktionsnamen alles, was der Proxy tun müsste, um seine Tarnung aufrecht zu erhalten.
Eine Idee wäre weiterhin, immer in SSL zu kommunizieren. Da SSL immer auf eine IP-Adresse bezogen ist, wüsste der Proxy im Falle eines Multihosters von vornherein nicht, um welche Domain es sich handelt. Größere Webauftritte haben eher mehrere IPs für eine Domain, da wäre es wieder einfacher – eine leichte Verwirrung also nur für kleinere Seiten, das ist keine Lösung. Was er definitiv nicht weiß, ist, um welche URI, also abgerufene Seite mit Parametern, es sich handelt. Er müsste also darauf setzen, dass eine Session zumeist in einer der Index-Dateien beginnt und an sich keine Parameter mit sich bringt. Mißtrauen wir also allen Besuchern einer Index-Seite? Das geht ebensowenig.
Da das Zertifikat jedoch definitiv nicht passt (es sei denn, es ist für Kollisionen manipuliert), würde der Browser beim Aufbau der SSL-Verbindung zumindest eine Warnung ausgeben. Na das ist ja schon mal etwas. Jetzt muss man nur noch a) den Nutzer dazu bringen, seine eigene URL immer im SSL-Modus zu bookmarken und b) dafür sorgen, dass SSL-Fehler-Warnungen ganz deutlich wahrgenommen werden. Letztlich ist die SSL-Methode weiterhin sicher, nur der Wechsel von HTTP auf HTTPS nicht, weil die Inhalte im HTTP-Modus manipulierbar sind.
Theorie und Praxis
Leider erlebt man jeden Tag den umgekehrten Weg: Statt wenigstens nach dem Login die Session verschlüsselt weiterzuführen, wechseln große Provider gerne mal nach dem Login-Prozedere zurück in den HTTP-Modus. Ist ja auch schneller. Dass sie dabei ihre Nutzer Gefahren aussetzen, wird dabei schnell mal in Kauf genommen. Zum Beispiel ebay. Was man da alles machen könnte – dazu braucht man nicht einmal als Proxy mit SSL arbeiten. Sogar in das eigene Konto kann man per HTTP wechseln! Sicherlich besteht die Seite aus sehr, sehr vielen Bildern, und die müssten alle per HTTPS einzeln abgerufen werden. Das kostet Kondition für Client und Server. Doch was nützt Geschwindigkeit ohne Integrität? Da kann ich gleich eine Seite aus /dev/random ziehen. 😉
In unserem ebrosia Wein-Shop ist eine Bestellung oder das Betreten des Konto-Bereichs ohne HTTPS-Modus gar nicht möglich. Selbst wenn man als Nutzer aus https:// ein http:// macht – unser Shop verlangt einfach die Verschlüsselung und korrigiert es entsprechend. Natürlich ist das heute keine Garantie gegen eine Man-in-the-middle-Attacke. Dazu müssten wir unsere Nutzer zu reinen SSL-Nutzern erziehen. Doch wenn es nötig sein sollte, wird das getan werden. Wir als Service-Betreiber sind das unseren Nutzern einfach schuldig.
Fazit
Nun, mit durchgehender Verschlüsselung wäre schon ein großer Schritt getan. Wenn wir jetzt noch einen Weg fänden, Server-initiiert das eigene Zertifikat auf Seiten des Nutzers zu prüfen, könnten wir den Proxy aus dem Rennen zu werfen…hat dazu jemand eine Idee? Vielleicht braucht man einen dritten Host, der das Geschehen von außen beobachten kann?
Nachträglich frage ich mich: Wie verhält sich der Proxy in Bezug auf Cookies?