IT-Sicherheit Intelligente Affen
Bochumer Forscher finden Sicherheitslücken in IT-Systemen besonders schnell. Ihr Trick: Sie konzentrieren sich auf das Wesentliche. Das Vorgehen erklären sie mithilfe des Theorems der endlos tippenden Affen.
Ein Programmcode ist ein bisschen wie ein Dschungel: komplex aufgebaut, schwer von außen einzusehen, mit unzähligen möglichen Wegen, die man hindurch nehmen kann. Schwachstellen in einem solchen Code zu finden ist wie Tiere zwischen den Bäumen im Urwald zu suchen: Man weiß, dass sie da sind, aber man sieht sie nicht direkt. Doktorand Tobias Scharnowski entwickelt daher neue Methoden, um im Dschungel der Einsen und Nullen effizient Programmierfehler aufspüren zu können. Er forscht am Lehrstuhl für Systemsicherheit des Horst-Görtz-Instituts der Ruhr-Universität Bochum, betreut von Prof. Dr. Thorsten Holz.
Die Forscher interessieren sich vor allem für eingebettete Systeme: „Wir versuchen, die Sicherheit von Computern zu erhöhen, von denen die meisten Menschen gar nicht wissen, dass sie überhaupt Computer sind“, beschreibt Scharnowski. Smarte Glühlampen, ans Internet angeschlossene Kühlschränke oder intelligente Thermostate sind ein paar Beispiele für die eingebetteten Systeme, die auf der Agenda der Systemsicherheitsforscher stehen. Diese Gegenstände enthalten elektronische Steuerungstechnik mit vielen Zeilen Programmcode, in die sich Fehler eingeschlichen haben können. Es geht den IT-Experten aber nicht nur um Gegenstände aus dem Haushalt. Vor allem interessieren sie sich für Steuerungssysteme in der Industrie, zum Beispiel aus dem Bereich der kritischen Infrastrukturen wie der Energieversorgung. Sicherheitslücken könnten hier besonders dramatische Auswirkungen haben.
Eingebettete Systeme
Die Software mit Absicht zum Absturz bringen
Scharnowski und Holz nutzen das sogenannte Fuzzing, um Fehler im Programmcode aufzuspüren. Als Fuzzer bezeichnet man Algorithmen, die die zu testende Software mit zufälligen Inputs füttern und prüfen, ob sie die Anwendung damit zum Absturz bringen können. Solche Crashs weisen auf Programmierfehler hin. Immer wieder variiert der Fuzzer den Input, um Schritt für Schritt möglichst viele Programmbestandteile zu erkunden.
Für bestimmte Anwendungsbereiche ist das Fuzzing bereits etabliert, zum Beispiel, um Betriebssysteme wie Windows oder Linux zu testen. Eingebettete Systeme hingegen wurden noch nicht ausgiebig damit untersucht; denn sie bringen einige Herausforderungen mit sich: Bei ihnen ist die Software – die sogenannte Firmware – in eine Hardware eingebettet, mit der sie interagiert. Über die Hardware und ihre Funktionsweise haben die Forscher aber in der Regel wenig Informationen. „Das ist wie eine Blackbox für uns“, beschreibt Thorsten Holz. Hinzu kommt, dass diese Blackbox in der Regel nicht besonders leistungsstark ist – oft haben die Systeme verhältnismäßig wenig Speicher und langsame Prozessoren. Ein Problem, wenn die Forscher das Fuzzing direkt im System durchführen wollen. Es würde viel zu lange dauern, alle möglichen Inputs durchzuprobieren und auf die Antwort des Systems zu warten.
Software, Hardware, Firmware
Hardware virtuell imitieren
Deswegen analysiert das Team die Firmware nicht direkt in der industriellen Steuereinheit oder in der Glühbirne. Stattdessen bauen sie die Hardware virtuell nach – emulieren nennt sich dieser Prozess. Der Emulator gaukelt der Firmware vor, sich in dem realen Gegenstand zu befinden. Dazu muss er genauso mit dem Programm interagieren, wie es die echte Hardware tun würde. „Wir müssen also alle Schnittstellen, die es zwischen Hardware und Firmware gibt, nachahmen“, erklärt Thorsten Holz. Gelingt das, können die Wissenschaftler die Firmware in einem leistungsfähigen System testen.
Trotzdem würde es lange dauern, wenn sie ihren Fuzzer alle theoretisch denkbaren Inputs ausprobieren lassen würden. Deswegen schalten die Forscher dem eigentlichen Fuzzing-Prozess einen weiteren Schritt vor, in dem sie die möglichen Inputs eingrenzen. Sie modellieren zunächst, in welchem Rahmen sich die Eingaben befinden müssen, um für die Firmware logisch zu sein. Ein Beispiel: Gehen wir davon es, dass es sich bei der Hardware um einen Kühlschrank mit einem Temperaturfühler handelt. Die gemessenen Temperaturen kann die Kühlschrank-Hardware an die Software des Kühlschranks, also seine Firmware, melden. Realistischerweise können nicht alle möglichen Temperaturen auftreten, sondern nur ein gewisser Bereich. Daher ist auch die Firmware nur für einen bestimmten Temperaturbereich programmiert. Andere Werte könnte sie gar nicht verarbeiten, also muss man sie auch nicht im Fuzzing testen.
Beschränkte Inputs erlauben effiziente Analyse
„Im Fuzzing-Prozess nutzen wir also nur die Inputs, die die Firmware auch erwartet und mit denen sie umgehen kann“, beschreibt Thorsten Holz und vergleicht den Prozess mit dem Infinite Monkey Theorem: „Dieses Theorem besagt, dass, wenn man Affen lange genug auf eine Tastatur drücken lassen würde, irgendwann auch Shakespeares Werke dabei herauskommen würden.“ So wäre es mit dem Fuzzer auch: Wenn man ihn lange genug probieren lassen würde, würde er durch Zufall irgendwann sinnvolle Inputs nutzen. Aber es würde lange dauern. „Wir wollen unsere Affen aber etwas intelligenter machen“, sagt Tobias Scharnowski. „Wir nehmen ihnen alle Tasten weg, die sie nicht brauchen, und versuchen sie dazu zu bringen, nur sinnvoll auf die Tasten zu drücken. Mit den Inputs, die übrigbleiben, können wir den Code trotzdem bis in die hintersten Ecken testen.“ Auf diese Weise wird das Fuzzing mit dem Bochumer System – Fuzzware genannt – besonders effizient.
Wissenschaftsmagazin Rubin kostenlos abonnieren
Zusammen mit Kolleginnen und Kollegen aus Santa Barbara und Amsterdam testete das Bochumer Team 77 Firmwares mit Fuzzware. Im Vergleich zu herkömmlichen Fuzzing-Methoden sortierten sie bis zu 95,5 Prozent der möglichen Inputs aus. Trotzdem gelang es ihnen, mit dem Fuzzware-System in der gleichen Zeit bis zu dreimal mehr von dem Programmcode zu checken wie mit herkömmlichen Verfahren. Dabei fand die Gruppe auch neue Schwachstellen, die mit anderen Fuzzing-Methoden unentdeckt geblieben waren.
Schwachstellen sind immer da
„Man findet eigentlich immer was“, weiß Thorsten Holz. „Wenn ein System noch nie mit Fuzzing getestet wurde, dann gibt es darin auch unentdeckte Schwachstellen.“ Gerade bei eingebetteten Systemen ist es für Programmiererinnen und Programmierer nahezu unmöglich, einen perfekten Code auf die Beine zu stellen. „Um mit der Hardware von eingebetteten Systemen sprechen zu können, muss man eine Low-Level-Programmiersprache nutzen“, erklärt Tobias Scharnowski. Programmierer können in vielen Bereichen nicht auf Codeschnipsel zurückgreifen, die für andere Anwendungen entwickelt wurden. Sie müssen ihren Code von Grund auf neu aufbauen. Gerade Randfälle – Zustände, in denen sich das System selten befindet – werden dann eventuell nicht bedacht. „Für unsere Fuzzer sind diese Zustände aber leicht zu analysieren“, sagt Scharnowski. „Sie können daher helfen, die Systeme robuster zu machen.“ Gefundene Schwachstellen melden die Forscher an die Hersteller und tragen so zu mehr Sicherheit in Industrie, Glühbirnen, Kühlschränken und Co. bei.
Originalveröffentlichung