Wie wir Wasserwerke im Internet entdeckten

Internetwache.org hat in den vergangenen Monaten die Sicherheit von Industrial Control Systems (ICS) im Internet untersucht. Dabei stießen wir auf über hundert ungesicherte Steuerungen von Wasser-, Heizkraftwerken, Parkplätzen und Gebäuden.

Alles begann im Oktober 2015 als Tim ein Datenleck im Prime Tower entdeckte. Angestoßen von dieser Entdeckung suchte er nach weiteren ICS und wurde alsbald auch fündig. Er entdeckte ein Wasserwerk, welches nach seinem Hinweis an das BSI einige Tage später nicht mehr öffentlich zugänglich war. Im Rahmen des Projektes Internetwache.org haben Tim und Sebastian daraufhin einen großflächigeren Scan durchgeführt und weitere Wasserwerke sowie ICS gefunden. Die zentralen Ergebnisse und eine Einführung in verschiedene Problematiken findet man in dem Artikel auf Golem.de.

In diesem Blogpost soll die dahinterstehende Methodik und genauere Hintergrundinformationen dargestellt werden.

Aller Anfang ist schwer…

Am Anfang hatte Tim mit Hilfe eines kleinen Python-Scripts angefangen, das Internet nach ICS abzusuchen. Dadurch ließen sich bereits erste erstaunliche Sachen finden (was uns wiederholt zeigt, dass es vermutlich noch mehr zu entdecken gibt) - allerdings war das Vorgehen insgesamt langsam. Zu diesem Zeitpunkt hatte Tim bereits einen Anhaltspunkt entdecken können, mit welchem mit hoher Wahrscheinlichkeit ICS im Internet ausfindig gemacht werden konnten. Es fehlte nur noch ein effizienterer Prozess, um diese “Nadeln im Heuhaufen” zu entdecken.

Sebastian hatte daraufhin die Idee, einen neuen Ansatz zu wählen und mit Hilfe des Programmes Zmap, ein Tool der University of Michigan, was auch den treffenden Namen “The Internet Scanner” trägt, und dem dazugehörigen Tool Zgrab das Internet nach diesen Systemen zu durchsuchen. Laut Webseite sind damit (je nach verfügbarer Bandbreite) Scans des gesamten Internet in unter 5 Minuten möglich. Damit kann man also den kompletten öffentlichen IPv4-Bereich nach Systemen abscannen, welche auf bestimmten Ports (u.a. Port 80) erreichbar sind, um diese dann später weiter auf bestimmte Kriterien untersuchen zu können.

Der Aufruf sah folgendermaßen aus:

1
sudo zmap -B 10M -p 80 --output-fields='*' | ztee results.csv | zgrab --port 80 --http="/" | gzip >  banners.gz 

Allerdings stellte sich dieser Ansatz, nach einigen Probescans, für uns nicht als optimal heraus, da wir keinen passenden Internetanschluss bzw. Hoster hatten, von dem man einen entsprechenden Scan ohne Abusemails oder ähnliche Nachfolgen hätten durchführen können. Außerdem hätte dies bei einer weniger schnellen Anbindung (<1 Gbit/s) mehrere Stunden in Anspruch genommen - es wären allenfalls Forschungseinrichtungen oder Firmen mit einer solchen Anbindung in Frage gekommen.

Wir wählten also einen anderen Weg, denn Sebastian erinnerte sich, dass ähnliche, fertige Datensätze auf dem Projekt scans.io veröffentlicht werden. Die Daten umfassen internetweite Scans und sind für jeden kostenlos auf der Webseite von scans.io abrufbar. Sie werden weltweit immer wieder zu Forschungszwecke herangezogen und schienen auch uns sehr geeignet für unser Vorhaben. In der Sammlung fanden wir in einer eigenen Kategorie einen wöchentlichen Scan der HTTP-Antworten aller erreichbaren Systeme auf Port 80 hochgeladen. Dieser Datensatz ist komprimiert rund 80 Gigabyte groß und enthät mehr als 62276536 Einträge. Bei dem Scan wird versucht alle im Internet erreichbaren IPv4-Adressen abzuscannen, antworten diese - so gelangt ihr Datensatz in den Scan - ist das nicht der Fall, so werden diese nicht mit aufgenommen.

Jeder Eintrag enthält die folgenden Daten im JSON-Format:

1
2
3
4
5
6
7
{
    "ip": "8.8.8.8"
    "host": "8.8.8.8",
    "vhost": "8.8.8.8", 
    "port": 80, 
    "data": base64(HTTP-Antwort), 
}

Der “data”-Eintrag enthielt die komplette HTTP-Antwort des angesprochenen Servers, inklusive HTTP-Headern und komplettem Inhalt, allerdings noch mittels “base64” kodiert.

Durchführen des Scans

Alle HMIs ließen sich an einem bestimmten Wert in einem der HTTP-Header erkennen (wie bereits oben beschrieben), sodass Sebastian ein kleines Python-Script schrieb, welches den heruntergeladenen Datensatz dekomprimierte, zeilenweise auslies und nach dem Base64-Dekodieren der Daten nach einem bestimmten Header ausschau hielt, der in zwei verschiedenen Variationen vorkommen konnte. Wir reduzierten den Datensatz auf 1796 Einträge.

1
2
3
4
$> python2 filter_scansio.py
$> wc -l output*.ips
     142 output-type1.ips
    1654 output-type2.ips

Die Ausgabe des Scriptes enthielt einige unnötige Leerzeilen und möglicherweise doppelte Einträge, sodass wir uns entschieden, alle IP-Adresse zu extrahieren:

1
2
$> grep -oP "\d+\.\d+\.\d+\.\d+" /tmp/output-*.ips | sort | uniq | tac | wc -l 
838

In einem ersten Durchlauf testeten wir alle IP-Adressen erneut auf Erreichbarkeit und ob sie ein HMI darstellen oder nicht. Dabei stellten wir fest, dass nicht wenige der Systeme Gebrauch von dem in das Produkt integrierte HTTP-Basic-Authentication-Protokolls machten, also einen Passwortschutz konfiguriert hatten. Allerdings stellte sich auch heraus, dass der Wert nach dem gesucht wurde, nicht eindeutig ist und erstaunlicherweise auch mehrere Pornoseiten diesen in ihrem HTML-Quelltext nutzen, sodass hier viele Falsepositives enstanden.

Ein weiterer Filter musste angewendet werden. Diesmal orientierten wir uns an einem Dateinamen einer Javascriptdatei, welche in allen Webseiten des Herstellers genutzt wird.

1
$> python2 js_filter.py | sort | uniq | tac | wc -l                  

Der Datensatz reduzierte sich weiter auf über 60 Systeme, welche alle ohne Passwortschutz im Internet waren.

Nach den ersten Kontaktaufnahmen und Abschirmungen vom Internet stellte sich das manuelle Überprüfen der Systeme als unhandlich heraus. Sebastian entwickelte daher ein Plugin für die Nmap-Script-Engine (NSE), welches die zuvor genannten Filterschritte und Erkennungen durchführte. Der Aufruf sah folgendermaßen aus:

1
$> nmap -n -PN -d --script nmap-find-hmis.nse -p 80 -iL all.ips  -oX nmap-all-ips-plugin-scan.xml -T paranoid

Die Ausgaben des Scriptes wurden im XML-Format durch Nmap gespeichert und mussten nur noch auf die entsprechenden Kategorien gefiltert werden:

  • “Discovered, authenticated”
  • “Discovered, unauthenticated”
  • “Not Discovered”

Dies erledigte ein weiteres Python-Script:

1
2
3
4
5
6
$> python2 filter-nmap-plugin.py ./nmap-all-ips-plugin-scan.xml | sort -u | grep "Discovered, unauthenticated" | wc -l 
42
$> python2 filter-nmap-plugin.py ./nmap-all-ips-plugin-scan.xml | sort -u | grep "Discovered, authenticated" | wc -l 
40 
$> python2 filter-nmap-plugin.py ./nmap-all-ips-plugin-scan.xml | sort -u | grep "Not Discovered" | wc -l
673 

Wobei “unauthenticated” für Onlinesteuerungen ohne HTTP-Basic-Authenthication steht, und “authenticated” entsprechend für die geschützten Systeme. Je nach verwendetem Proxy und Timeout variierten die Ergebnisse ein wenig auf Grund der teilweise langen Antwortzeiten der Systeme.

Auswertung

Am Ende haben wir so eine Liste erhalten - mit der wir sehr gut weiterarbeiten und die eigentliche Auswertung starten konnten. Von den entdeckten Systemen waren ungefähr 50% mittels HTTP-Basic-Authentication abgesichert und genauso viele leider nicht. Dabei korrelierte die HTTP-Authentication meist mit der Verschlüsselung. Nicht besonders geschützten Systeme (ohne HTTP-Authentication) haben wir uns genauer angeschaut, indem wir sie manuell im Browser geöffnet haben. Dabei konnten wir feststellen, dass die HMIs in folgenden Bereichen eingesetzt wurden:

  • Wasserwerke: 4
  • Parkplatzanlagen: ~10
  • Smart Homes + Hotels: >5
  • Biogasanlagen / Blockheizkraftwerke / Fernheizwerke: 7

Laut Geo-IP-Location waren vor allem die Länder aus dem DACH Bereich betroffen, aber auch aus den USA, Frankreich, Italien oder Israel. Das liegt vermutlich vor allem daran, dass der Hersteller der Software überwiegend im DACH-Bereich seine Software vertreibt und in anderen Ländern Reseller den Vertrieb übernehmen.

Nach diesen Erkenntnissen wandten wir uns an über 10 CERTs von betroffenen Ländern und schilderten das Problem. Zudem baten wir um eine rasche Kontaktaufnahme mit den jeweiligen Betreibern. Die meisten CERTs bedankten sich für den Hinweis und teilten uns mit, man habe die Informationen weitergeleitet. Tatsächlich konnten wir in den darauffolgenden Wochen feststellen, dass immer mehr Systeme auf unserer Liste offline waren oder den Passwortschutz aktiviert hatten.

Auch das Betreiben eines mittels HTTP-Basic-Authentication geschützten Systems im öffentlichen Internet ist durchaus bedenklich, wenn man es unter dem Gesichtspunkt der IT-Sicherheit betrachtet. Einem Angreifer ist es möglich von außen zu erkennen, dass eine Software genutzt wird, welche sich für Anlagensteuerungen nutzen lässt - mittels der Informationen aus dem WHOIS oder dem IP-Lookup lassen sich ebenfalls Rückschlüsse auf die Betreiber ziehen. Wir haben beispielsweise IP-Adressen gefunden, bei denen eine Zuordnung durch offen zugängliche Informationen möglich war (etwa Stadtwerken und Unternehmen).

Mehr Informationen dazu finden sich in unserem Golem.de-Artikel](http://www.golem.de/news/smart-city-schweizer-prime-tower-gibt-massenhaft-daten-preis-1601-118552.html)

Sicherheitslücken

Im Rahmen der Untersuchung warfen wir ebenfalls einen kleinen Blick auf die Sicherheit der Webapplikation, nachdem Tim an einer Stelle eine Vermutung hatte. Tatsächlich gelang es Sebastian Tims Vermutung in eine erste Cross-Site-Scripting Lücke zu verwandeln. Außerdem entdeckte er noch eine HTTP-Header-Injection. Beide Sicherheitslücken und die Schließung letzterer werden zur Zeit über das Cert-CC mit dem Hersteller koordiniert.

Updates

Sobald der Hersteller die Lücken behoben hat und/oder das Cert-CC sein Advisory veröffentlicht, sowie mehr betroffene Systeme offline sind, werden wir nach und nach mehr Informationen und unsere Tools veröffentlichen.

Timeline

Damit es möglich ist sich einen Eindruck von dem “Verlauf der Dinge” zu verschaffen, teilen wir hier die grobe Timeline:

  • Oktober 2015

    • Beschäftigung mit Industrieroutern / Fund: Prime Tower Webapplikation
  • Oktober 2015 - Januar 2016

    • Mehrfache Meldung an Betreiberin => 3 Monate, responsible disclosure Zeit abgelaufen
  • 22.01.2016

  • 22.01.2016 (6 Stunden nach Artikelveröffentlichung)

  • März / April 2016

    • Analyse der gespeicherten Dateien (HTTP-Requests, etc.), schreiben Scanscript und Nutzung “zmap”
  • Anfang April 2016

    • erster Scan auf öffentliche IP-Adressen (Fund von einigen Systemen - teils kritisch, teils weniger kritisch)
  • 11.04.2016

    • Email: Nachfrage bei Hersteller, ob bewusst, dass so viele Systeme online
      • Nachfrage nach Security-Hinweis im Handbuch
      • Erste Nachfrage zur Unregelmäßigkeit beim Parametern (später werden daraus die Sicherheitslücken)
  • Mitte April 2016

    • Wochenende: weitere Scans / Analyse der Scans: Fund Wasserwerk (!) Tim und Sebastian finden XSS
  • 17.04.2016

    • Email an Bund-CERT (BSI) - Mitteilung über Wasserwerke
  • 18.04.2016

    • BSI Bestätigung: “Wir werden auf die Betreiber zugehen und uns hier um Abhilfe bemühen.”
  • 19.04.2016

    • Antwort vom Hersteller - überwiegend allgemeine Infos zu Produkten
  • 19.04.2016

    • Antwort an Hersteller
      • Nennung der XSS Lücke
      • Erwähnung: Fund Wasserwerk
      • Nachfrage: Telefonat
  • Ende April 2016

    • Sebastian entdeckt HTTP-Header-Injection (Proof of Concept wird an Hersteller geschickt)
  • 20.05.2016 (1 Monat nach unserer Antwort)

    • Antwort vom Hersteller - Telefonat möglich
  • 20.05.2016

    • Telefonat mit Hersteller via Skype
    • Inhalt:
      • Hersteller sieht sich generell nicht in der Vorantwortung für Kundenprojekte im Internet
      • Hersteller möchte keine generelle Sicherheitsinfo an Kunden geben, kann aber individuelle Ansprache über Reseller vornehmen
      • Security-Hinweise: “in Überarbeitung”, Übersendung soll im Mai erfolgen
      • Frage nach Test-Umgebung: kann im Mai zur Verfügung gestellt werden
  • Ende Mai

    • Sebastian entwickelt neues Script => besseres und schnelleres Scannen möglich
      • Nutzung der Scans von scans.io
      • Entwicklung eines Plugins für nmap
      • Durchführung des Intensiv-Scan (Ergebnisliste mit über 120 Treffern, teils mit Authentifizierung, teils ohne)
      • Erste Sichtung der Ergebnisse (weitere Funde)
  • 26.05.2016

    • Email an Hersteller
      • Nennung der zentralen Scanergebnisse
      • Bitte um schnelle Behebung der Sicherheitslücken
      • Bitte Informationen über Reseller zu vermitteln
  • Ende Mai 2016

    • Versendung von Infos an mehr als 10 CERTs weltweit
  • 06.06.2016

    • Antwort vom Hersteller (letzte erhaltene Email): generelle Informationen
  • 09.06.2016

    • Antwort auf die Email von Hersteller: Konkrete Nachfragen zu den Lücken und Disclosure-Prozess
  • 17.06.2016

    • Letzte Nachfrage bei Hersteller
    • keine Reaktion:
      • keine Informationen zu den Sicherheitslücken
      • kein Security-Paper (Handbuch zum sicheren Betrieb) => Sollte bereits im Mai fertig sein.
      • keine Testumgebung
  • Ende Juni / Anfang Juli 2016

    • Erneutes Anschreiben zahlreicher CERTs / Betreiber
    • Abwarten bis Applikationen offline
  • Anfang Juli 2016

    • Meldung der Sicherheitslücken an das CERT Coordination Center
  • 15.07.2016

    • Veröffentlichung des Artikels auf golem.de
    • Veröffentlichung des Teaser-Artikels auf Spiegel.de
    • Zahlreiche weitere Medien nehmen die Erkenntnisse aus unserer Untersuchung in die Berichterstattung auf
  • 16.07.2016