All About Security
  • Aktuelle Sicherheitsartikeln als RSS Feed
  • All About Security auf Twitter
  • All About Security auf Xing
  • All About Security auf Google+
  • Unter4Ohren IT-Security Podcast auf YouTube

Risiko- & Kontinuitätsmanagement, Fachartikel

Unscharfe Prozesskommunikation – Fuzz-Testing IEC 60870-5-104

Unscharfe Prozesskommunikation – Fuzz-Testing IEC 60870-5-104

Eine nicht protokollkonforme Prozesskommunikation führte im Jahr 2013 in Österreich zu gravierenden Störungen im Fernwirknetz der Stromversorgung. Derartige Fehlfunktionen in der Prozesskommunikation treten immer wieder auf, auch wenn die Auswirkungen unter normalen Umständen nicht dermaßen drastisch sind. Sie sind in der Regel auf einen zu großen Spielraum in der Auslegung von Kommunikationsstandards für die Leit- und Automatisierungstechnik sowie auf Programmierfehler in den Protokollimplementierungen zurückzuführen. Man stelle sich allerdings vor, jemand sucht diese Fehlfunktionen gezielt, um sie dann als äußerst wirkungsvollen Angriff auf kritische Infrastrukturen zu missbrauchen. Dieser Artikel möchte zunächst kurz in die wesentlichen Angriffsformen auf Netzwerkprotokolle einführen und ein von der GAI NetConsult initiiertes Fuzzing-Projekt vorstellen, das derartige Schwachstellen in der Kommunikation des Fernwirkprotokolls IEC 60870-5-104 aufspürt.

Im Mai 2013 ereignete sich im geschlossenen Fernwirknetz der österreichischen Stromversorgung eine gravierende Störung. Gemäß den öffentlich verfügbaren Informationen trug sich der Vorfall derartig zu, dass im Rahmen von Funktionstests bei einem Gasnetzbetreiber im süddeutschen Raum eine spezielle Zählerabfrage des Fernwirk-Protokolls IEC 60870-5-104 unbeabsichtigt den Weg in das österreichische Fernwirknetz fand. Dort wurde die Zählerabfrage, die auf Anwendungsebene an alle Teilnehmer gesendet wurde („Broadcast“-Nachricht) von einem Gerät entgegen der Protokollspezifikation abermals als Broadcast-Nachricht an alle Teilnehmer beantwortet. Diese Antwort wurde wiederrum von weiteren Geräten beim Empfang ebenfalls inkorrekt verarbeitet und an alle bekannten Teilnehmer versendet. Die Antwort verbreitete sich damit binnen kürzester Zeit aufgrund dieser massenhaften Vervielfältigung explosionsartig. Dieser „Netzwerksturm“ wurde durch die fehlerhafte Verarbeitung einer einfachen Zählerabfrage hervorgerufen und führte im Ergebnis dazu, dass der explodierende Datenverkehr eine Übertragung von regulären Steuer- und Prozessinformationen nicht mehr zuließ.

Dieser Vorfall kann als ein eindrucksvolles Beispiel für eine Angriffsform betrachtet werden, die abseits der prozessnahen Informationstechnologie bereits zu einer eher alltäglichen Bedrohung gehört. Es handelt sich hierbei um Angriffe auf die komponenteninterne Verarbeitung von Netzwerkdaten eines Netzwerkprotokolls. Ein Angreifer mit Zugang zum unterliegenden Netzwerk und dem Wissen über die fehlerhafte Verarbeitung der Zählerabfrage aus dem geschilderten Vorfall hätte die beschriebene Abfrage gezielt einschleusen und den Netzwerkausfall somit bewusst provozieren können. Abhängig von der konkreten Ausprägung des Verarbeitungsfehlers wäre es ggf. auch möglich gewesen, einzelne Fernwirkkomponenten zum Absturz zu bringen oder Programmcodes auf dem Zielsystem auszuführen und dieses so zu kompromittieren.

Angriff auf die Verarbeitung von Netzwerkdaten: „Denial-of-Service“

Ein typischer Angriff auf die Verarbeitung von Netzwerkdaten stellt den Versuch dar, einen Ausfall des Netzwerkdienstes bzw. der verarbeitenden Komponente zu provozieren („Denial of Service“). Abbildung-1 zeigt einige Beispiele von Dienst- und Programmabstürzen unter dem Betriebssystem Windows, die auf eine fehlerhafte Verarbeitung von Netzwerkdaten zurückzuführen sind. Ein Angreifer mit dem Wissen, unter welchen Umständen ein System bei der Verarbeitung von Netzwerkdaten ausfällt, kann parallel mehrere Systeme des gleichen Typs angreifen und so den entstandenen Schaden deutlich erhöhen. Er kann die Informationen über die Schwachstelle beispielsweise über den (ggf. illegalen) Schwachstellenhandel käuflich erwerben oder nach Erwerb einer ausgesuchten Komponente gezielt nach solchen Implementierungsfehlern suchen, z.B. mit Hilfe eines im Folgenden näher beschriebenen „Fuzzers“.

Abbildung-1: Abstürze von DNP3-Diensten unter Microsoft Windows (Quelle: Adam Crain, Automatak LLC)

Häufig können Programmabstürze bzw. Fehlfunktionen auf die folgenden zwei Ursachen zurückgeführt werden: Speicherzugriffsverletzungen und unbehandelte Programmzustände.

Speicherzugriffsverletzungen sind eine sehr häufig anzutreffende Fehlerquelle. Sie resultieren aus dem Umstand, dass aus Performancegründen häufig hardwarenahe Programmiersprachen verwendet werden, die meist eine fehleranfällige direkte Adressierung des Arbeitsspeichers ermöglichen. Die folgenden Fehlerursachen sind dabei vielfach anzutreffen:

  • Eine fehlerhafte Adressarithmetik, die im Ergebnis eine falsche Speicherstelle adressiert (z.B. Pointer-Arithmetik in der Programmiersprache C)
  • Adressierung sogenannter NULL-Pointer, die häufig als leeres Ergebnis von Bibliotheksfunktionen zurückgegeben und von Programmen in Folge meist ungeprüft genutzt werden ("Null Pointer Dereference").
  • Adressierung nicht mehr aktueller Speicherstellen (z.B. im Falle von freigegebenen Objekten im Speicher), die zu sogenannten „Use-After-Free“-Schwachstellen führen.
  • Überlauf des Wertebereichs einer Variablen, die Bestandteil einer Adressierung ist (z.B. „Integer Overflow“)

Beispielcode-1 zeigt eine Speicherzugriffsverletzung in einem C-Programm, das bei Ausführung zu einem Absturz führt. Die Variable „input“ erstreckt sich über einen Speicherbereich von 100 Bytes. Die Speicherreferenzierung „input[10000]“ adressiert allerdings 9900 Bytes darüber hinaus eine Speicherstelle, auf die das Programm nicht zugreifen darf. Es entsteht eine Speicherzugriffsverletzung.

 

Eine weitere oft anzutreffende Ursache für Programmabstürze bzw. einem Fehlverhalten von Programmen sind unbehandelte Programmzustände. Sie beruhen in der Regel auf einer unzureichenden Behandlung von Ausnahmen bzw. Grenzfällen im normalen und beabsichtigten Programmablauf sowie auf einer nicht hinreichenden Validierung der Korrektheit von Eingabedaten. Diese führen dazu, dass der Programmfluss in einen vorab nicht berücksichtigten Zustand gerät. Dies ist insbesondere bei der Verarbeitung von Netzwerkdaten bedeutsam, weil sich Sender und Empfänger immer in einem wohldefinierten Zustand innerhalb der Verbindung gemäß Protokollspezifikation befinden müssen, z.B. Verbindungsaufbau, Datenübertragung, Verbindungsabbau etc.

Der Pseudocode aus dem Beispielcode-2 soll eine Situation verdeutlichen, in der lediglich die Werte 1, 2 und 3 für die Variable „input[0]“ behandelt werden. Ein anderer Wert wurde bei der Entwicklung des Programms nicht berücksichtigt, weil er beispielsweise für das Anwendungsszenario des Netzwerkdienstes als irrelevant erschien. Nimmt „input[0]“ nun doch einen anderen Wert an,  führt dies zu einem nicht definierten Programmzustand mit ungewisser Fortsetzung (im Beispielcode ist dies die Rückkehr der Funktion „input_processing()“). Dies kann dann zu einem Fehlverhalten des Programms bzw. zu einem ungewollten Programmende führen. Im selben Prozess gleichzeitig stattfindende Netzwerkverbindungen sowie der Aufbau von neuen Verbindungen werden unmittelbar in Mitleidenschaft gezogen und gestört. Ein Angreifer mit Wissen um diese Schwachstelle kann durch wiederholtes Senden der fehlerauslösenden Netzwerkpakete die Störung immer wieder auslösen, so dass ein automatisiertes Neustarten des Programms in der Regel keine Abhilfe schafft. 

Im Falle einer korrekten Verarbeitung von Netzwerkdaten und der vollständigen Berücksichtigung von Ausnahmefällen sind negative Auswirkungen, z.B. eine Beendigung der Verbindung, auf die Netzwerkverbindung beschränkt, in der die Ausnahme auftrat.

<< Erste < Vorherige Page 1 Page 2 Page 3 Page 4 Nächste > Letzte >>