SSL Renegotiation DoS und Java JSSE SSLServerSocket
Öffentlich zugängliche SSL/TLS Dienste bilden das Rückgrat der Internet Anwendungen und haben zugleich das Problem, dass der initiale Handshake eine CPU intensive Crypto-Operation auf dem Server erfordert. Das ist deswegen problematisch, weil der Server erst nach dieser Operation feststellen kann ob der Client den Rechenaufwand ebenfalls eingegangen ist, oder einfach nur zufällige Daten beim Schlüsselaustausch geschickt hat. Dieses Ungleichgewicht kann ein Angreifer bei einem DoS (Deny of Service) Angriff ausnutzen und wiederholt (ggf. von verschiedenen bots) eine solche SSL Verbindung anfordern. Dadurch kann es dann zu Überlastungen der Server kommen, ohne dass der Angreifer viele Ressourcen investieren müsste.
Diese Form des SSL DoS lässt sich aber zum Glück einfach erkennen und dank Rate Limits in Firewalls oder SSL Accelerators auch einfach abwehren. Etwas problematischer ist es da schon, dass auch in einer bestehenden TLS Verbindung die Gegenstelle eine neue Aushandlung der Schlüsseldaten anfordern kann. Dazu sind keine von der Firewall bemerkbaren neuen Verbindungen notwendig, und auch die Handshake Records die bei SSL ausgetauscht werden sind als solche nur mit anfälliger Heuristik zu erkennen.
Wenn man das nun mit der Eigenheit von RSA kombiniert, dass das entschlüsseln auf der Serverseite mehr CPU Zeit beansprucht als die Verschlüsselunsoperation, so erhält man eine neue Klasse von Angriffen auf die die deutscheinternationale Security Research Gruppe THC 2011 aufmerksam gemacht hat. Und obwohl ein dDoS Angriff auf den initialen Handshake um ein vielfaches wirkungsvoller ist hat die Veröffentlichung des Tools einige Hersteller dazu bewegt etwas dagegen zu unternehmen (die meisten schalten die Renegotiation komplett ab). Hinweis: THC spricht von Faktor 15 mehr Rechenaufwand auf dem Server als auf dem Client, dem widersprechen allerdings die Zahlen von Vincent (s.u.).
Jedenfalls ist es für einen öffentlich angebotenen SSL Server wichtig die Renegotiation Anfragen der Clients zu erkennen und zu limitieren. Neben den häufig verwendeten nativen Libraries wie puressl oder openssl gibt es auch noch weitere Implementierungen, z.B. den SSLServerSocket bei Java (im Falle der JVM von Oracle mit der ehemals von Sun stammenden JSSE Implementierung). Für diese bleiben aktuell zwei Strategien:
a) HandshakeListener auf jedem SSLServerSocket registrieren: dieser wird bei jedem erfolgreichen Handshake aufgerufen, er kann also mitzählen und ggf. Gegenmaßnahmen einleiten. Das hat aber einen großen Nachteil: der Listener selbst wird Asynchron in einem neuen Thread aufgerufen. Und dies auch dann wenn die Funktion im Listener nicht mehr macht als einen Zähler hochzählen. Das starten des Threads ist im Vergleich dazu viel belastender für den Server. Es sollte also vermieden werden überhaupt einen Listener zu registrieren.
b) Nach dem initialen Handshake die Liste der erlaubten Ciphers auf eine leere Liste setzen. Das führt dazu, dass alle weiteren Handshake Anfragen mit einem SSL Alert abgebrochen werden. Leider gilt das allerdings auch für Handshakes die vom Server angefordert werden (z.B. wenn Client Zertifikate angefordert werden sollen) oder auch bei sehr seltenem Schlüsselaustausch (bei lange bestehenden SSL Verbindungen sinnvoll).
Ich würde mir deswegen wünschen Oracle bessert hier an zwei Stellen nach: zum einen sollte man bei SSLServersockets direkt die Renegotiation die von Clients angefordert wird mittels eines Flags ignorieren/ablehnen können. Zudem macht es Sinn wenn der SSLServerSocket diese automatisch in der Anzahl begrenzen. Zum anderen sollte es möglich sein auf die Erzeugung eines Threads pro Handshake Event zu verzichten, z.b. indem der Anwender einen eigenen Executor mitgeben kann (der einen Pool hat oder aber bei sehr leichtgewichtigen Listener einfach synchron ausführt).
Übrigens bietet die JSSE2 Implementierung von IBM eine Systemproperty (com.ibm.jsse2.renegotiate=NONE) an, mit der man die Renegotiation ausschalten kann. Im Falle von Oracle kann nur die unsichere Renegotiation (ohne RFC5746) verboten werden. Das hilft aber nicht gegen den DOS Angriff.
Zum Weiterlesen
- SSL/TLS and Computational DoS (Eric Rescorla)
- SSL computational DoS mitigation (Vincent Bernant)
- Forward Secrecy for Google HTTPS (Adam Langley)
- JSSESocketServer.java testcode (GitHub Bernd Eckenfels)