SSL Verkehr überwachen
Im letzten Artikel (zur Poodle Lücke) habe ich die klare Empfehlung ausgesprochen SSL 3.0 (und 2.0 sowieso) abzuschalten, wenn es nicht mehr benötigt wird. Hier stellt sich natürlich sofort die Frage: "gibt es noch kritische Verwender von SSL3 in meinem Netz".
Für die Unternehmens-IT kann das eine relativ komplizierte Angelegenheit werden die Owner aller Anwendungen zu befragen. Die Anwendungen zu ermitteln (einfach die Liste der freigeschaltenen Ports in der Firewall durchgehen) ist noch relativ einfach, ob aber die Befragten die Antwort kennen (oder die Frage verstehen) ist eine ganz andere Sache.
SSL Log im Apache aktivieren
Dazu kommt noch das Problem dass in jeder Anwendung die Art und Weise wie man die verwendeten SSL Protokolle sehen kann unterschiedlich ist. Teilweise ist die Funktion nicht aktiviert oder lässt sich nur mit vielen zusätzlichen Debug Meldungen einschalten.
Bei einem Apache httpd ist es eigentlich zwingend das erweiterte SSL Log Format "combinedssl" immer zu verwenden:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{SSL_PROTOCOL}x %{SSL_CIPHER}x" combinedssl CustomLog /var/log/httpd/access.log combinedssl
Es ist praktisch, wenn die SSL/TLS Terminierung an möglichst wenigen Stellen erfolgt. Zum Beispiel einen Cluster aus Reverse Proxies oder Load Balancern. Und natürlich sollte für diese Dienste ein entsprechendes Log bereitstehen.
tls-hello-dump
Aber nicht immer gibt es diese Möglichkeit (für alle Anwendungen). Insbesondere nicht bei Client Verbindungen. Es kann von daher notwendig sein auf Netzwerkebene den Datenstrom zu überwachen und eine Statistik zu erstellen (oder die IP Addressen der notorischen SSL3 Verwender manuell nach zu püfen. Es könnte ja auch der unternehmenskritische Bestellfluss des größten Auftraggebers sein). Ich vermute mal ein gutes Network Intrusion Detection System (NIDS) kann diese Statistiken liefern. Ist eine solche Klassifizierung des Traffics aber nicht gegeben, so beginnt die Suche nach einfachen Tools.
Mit tcpdump oder vergleichbaren Sniffern muss man recht viel selbst bauen. Auch ssldump ist hier recht sperrig (und auch nicht sehr aktuell). Das einfachste Tool was ich bisher gefunden habe ist tls-hello-dump von Georg Lukas. Es schreibt pro Handshake 2 Zeilen, eine für die vorgeschlagenen Ciphers des Clients (ClientHello) und eine für die vom Server angenommenen Parameter (ServerHello). Es setzt auf libpcap auf, kann somit auf Linux/FreeBSD einfach eingesetzt werden. Es kann sowohl Verbindungen an das lokale System überwachen als auch Netzwerktraffic (solange der Host auf dem tls-hello-dump läuft am Netzwerkport der in PROMISC geschaltet ist alle Daten sieht).
Hier als Beispiel ein Chrome38/Apache2.2 Handshake sowie ein (unbeantworteter) openssl s_client -ssl3 -connect versuch:
109.192.117.164 195.49.138.57 TLSv1 ClientHello TLSv1.2 :CC14:CC13: C02B:C02F:009E:C00A:C009:C013:C014:C007:C011:0033:0032:0039:009C: 002F:0035:000A:0005:0004: 195.49.138.57 109.192.117.164 TLSv1.2 ServerHello TLSv1.2 cipher C02F 109.192.117.164 195.49.138.57 SSLv3 ClientHello SSLv3 :C014:C00A:C022: C021:0039:0038:0088:0087:C00F:C005:0035:0084:C012:C008:C01C:C01B: 0016:0013:C00D:C003:000A:C013:C009:C01F:C01E:0033:0032:009A:0099: 0045:0044:C00E:C004:002F:0096:0041:0007:C011:C007:C00C:C002:0005: 0004:0015:0012:0009:0014:0011:0008:0006:0003:00FF:
Und das ganze noch einmal aufbereitet mit dem ebenfalls beigelegten sed script, welches aus den Hex-codes der Ciphers lesbare Namen macht.
109.192.117.164 195.49.138.57 TLSv1 ClientHello TLSv1.2 :TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:TLS_ECDHE_RSA_WITH_RC4_128_SHA:TLS_DHE_RSA_WITH_AES_128_CBC_SHA: TLS_DHE_DSS_WITH_AES_128_CBC_SHA:TLS_DHE_RSA_WITH_AES_256_CBC_SHA:TLS_RSA_WITH_AES_128_GCM_SHA256: TLS_RSA_WITH_AES_128_CBC_SHA:TLS_RSA_WITH_AES_256_CBC_SHA:TLS_RSA_WITH_3DES_EDE_CBC_SHA: TLS_RSA_WITH_RC4_128_SHA:TLS_RSA_WITH_RC4_128_MD5: 195.49.138.57 109.192.117.164 TLSv1.2 ServerHello TLSv1.2 cipher TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 109.192.117.164 195.49.138.57 SSLv3 ClientHello SSLv3 :TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA:TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA: TLS_DHE_RSA_WITH_AES_256_CBC_SHA:TLS_DHE_DSS_WITH_AES_256_CBC_SHA:TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA:TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: TLS_RSA_WITH_AES_256_CBC_SHA:TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA: TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA:TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:TLS_RSA_WITH_3DES_EDE_CBC_SHA: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA: TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA:TLS_DHE_RSA_WITH_AES_128_CBC_SHA:TLS_DHE_DSS_WITH_AES_128_CBC_SHA: TLS_DHE_RSA_WITH_SEED_CBC_SHA:TLS_DHE_DSS_WITH_SEED_CBC_SHA:TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA:TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: TLS_RSA_WITH_AES_128_CBC_SHA:TLS_RSA_WITH_SEED_CBC_SHA:TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:TLS_RSA_WITH_IDEA_CBC_SHA: TLS_ECDHE_RSA_WITH_RC4_128_SHA:TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:TLS_ECDH_RSA_WITH_RC4_128_SHA: TLS_ECDH_ECDSA_WITH_RC4_128_SHA:TLS_RSA_WITH_RC4_128_SHA:TLS_RSA_WITH_RC4_128_MD5:TLS_DHE_RSA_WITH_DES_CBC_SHA: TLS_DHE_DSS_WITH_DES_CBC_SHA:TLS_RSA_WITH_DES_CBC_SHA:TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:TLS_RSA_EXPORT_WITH_DES40_CBC_SHA:TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5: TLS_RSA_EXPORT_WITH_RC4_40_MD5:TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
Ich hab ein paar Patches beigesteuert die es etwas robuster machen, man muss sich aber vor Augen halten dass das Tool nur sehr einfache Handshakes versteht (diese müssen im Anfang der gefilterten IPv4 Pakete stehen). Schon ein TLS Alert (Warnung: unrecognized_name) verhindert, dass das ServerHello erkannt wird. Außerdem ist aktuell der Parser sehr ungenau was die Überprüfung der Paketformate angeht, es bietet sich also an das Tool nicht als Root auf einem kritischen System laufen zu lassen sondern vielmehr den Traffic mittels tcpdump -w file zu speichern und dann Offline auszuwerten (mit einem User ohne weitere Rechte).
Es sollte auch darauf hingewiesen werden dass es sich hier nur um die Handshakes handelt, Clients die viele erfolglose Verbindungen aufbauen sind in den Zahlen entsprechend überräpresentiert. Wenn eine persistente HTTPS connection tausende Anfragen verarbeitet steht diese nur einmal in der Liste. Ebenso sieht man nicht, ob ein Client, wenn er SSL3 offeriert bekam dieses auch akzeptiert (oder ablehnt).
tls-hello-dump kann nicht mit STARTLS (wie es z.B. in SMTP und IMAP Verwendung findet) umgehen. Das liegt hauptsächlich daran dass es sich nicht damit befasst die gefilterten Pakete zu TCP Strömen zusammenzusetzen. Das macht das Tool leichtgewichtig aber eben auch beschränkt. ssldump wäre für diesen Fall die bessere Wahl.
Compilieren und starten
tls-hello-dump steht auf GitHub als source code zur Verfügung (habe noch kein Binärpaket gesehen) und sollte auf jedem Linux Rechner mit entsprechenden Entwicklungspaketen übersetzbar sein:
git clone https://github.com/ge0rg/tls-hello-dump.git cd tls-hello-dump/ make clean all FILTER="tcp port 443 and tcp[tcp[12]/16*4]=22 and (tcp[tcp[12]/16*4+5]=1 or tcp[tcp[12]/16*4+5]=2)" sudo tcpdump -p -s 1518 -i eth0 -w handshakes.pcap "$FILTER" ./tls-hello-dump handshakes.pcap | sed -f readable.sed
Oder für die Mutigen: "sudo ./tls-hello-dump eth0 https | sed -f readable.sed"