-
Technisches Gebiet
-
Die Erfindung betrifft Verfahren zum Testen eines Programmcodes durch sogenanntes Fuzzing-Testen. Die vorliegende Erfindung betrifft insbesondere Maßnahmen zur Auswahl einer Fuzzing-Methode zum Fuzzing-Testen eines bestimmten Programmcodes.
-
Technischer Hintergrund
-
Ein herkömmliches Verfahren zur Detektion von Fehlern in einer auf einem Computersystem ausgeführten Programmcode, der in Software oder Hardware implementiert sein kann, besteht darin, dieses mithilfe eines Fuzzing-Testverfahrens auf Programmausführungsfehler oder Systemabstürze zu untersuchen. Dabei werden die sogenannten Fuzzing-Eingaben für das Computersystem generiert, ein zu testender Programmcode mit den Eingaben ausgeführt und die Funktion des Algorithmus des Programmcodes überwacht. Die Überwachung der Ausführung des Programmcodes umfasst das Feststellen, ob der Ablauf des Algorithmus zu einem Programmausführungsfehler, d. h. z. B. einem Systemabsturz oder unerwarteten Ausführungsstopp, führt.
-
Während des Ausführens des Programms wird das interne Verhalten des Programmablaufs überwacht, insbesondere hinsichtlich der durch den Programmcode ausgeführten Programmablaufpfade. Dieser Vorgang wird mit unterschiedlichen Eingaben wiederholt, um eine Information über das Verhalten des Programmcodes für eine große Bandbreite an Eingaben zu erhalten. Das Ziel der Programmcode-Überwachung besteht darin, die Eingaben so zu generieren, dass eine möglichst große Überdeckung der Programmablaufpfade erreicht wird, d. h. es wird eine möglichst große Zahl an Programmablaufpfaden während der wiederholten Variation der Eingaben durchlaufen.
-
Tritt während einer Ausführung eines Programmcodes ein Fehler bzw. ein unerwartetes Verhalten auf, wird dies durch das Fuzzing-Werkzeug erkannt und entsprechende Informationen, die angeben, welche Fuzzing-Eingabe zu dem Fehler geführt hat, signalisiert.
-
Offenbarung der Erfindung
-
Erfindungsgemäß sind ein computerimplementiertes Verfahren zum Auswählen einer Fuzzing-Methode zum Durchführen eines Fuzzing-Tests gemäß Anspruch 1 sowie ein Verfahren zum Trainieren eines datenbasierten Fuzzing-Auswahlmodells für die Auswahl einer Fuzzing-Methode sowie eine entsprechende Vorrichtung gemäß den nebengeordneten Ansprüchen vorgesehen.
-
Weitere Ausgestaltungen sind in den abhängigen Ansprüchen angegeben.
-
Gemäß einem ersten Aspekt ist ein computerimplementiertes Verfahren zur Auswahl einer Fuzzing-Methode für das Durchführen eines Fuzzing-Testens eines vorgegebenen Programmcodes vorgesehen, mit folgenden Schritten:
- - Bereitstellen von Programmcodemetriken, die den zu testenden Programmcode charakterisieren;
- - Anwenden der Programmcodemetriken auf ein datenbasiertes Fuzzing-Auswahlmodell zum Ermitteln von den Fuzzing-Methoden zugeordneten Leistungsmetriken für eine Anzahl von Fuzzing-Methoden, wobei das datenbasierte Fuzzing-Auswahlmodell trainiert ist, für jede der Fuzzing-Methoden eine Leistungsmetrik auszugeben;
- - Auswählen eines oder mehrerer Fuzzing-Methoden entsprechend der zugeordneten Leistungsmetriken;
- - Durchführen eines Fuzzing-Testens entsprechend der einen oder der mehreren ausgewählten Fuzzing-Methoden.
-
Gemäß einem weiten Aspekt ist ein Verfahren zum Trainieren eines datenbasierten Fuzzing-Auswahlmodells vorgesehen, mit folgenden Schritten:
- - Bereitstellen von Programmcodes aus einer vorgegebenen Programmcodesammlung;
- - Durchführen von Fuzzing-Testverfahren der Programmcodes entsprechend den vorgegebenen Fuzzing-Methoden;
- - Ermitteln einer Leistungsmetrik für jedes durchgeführte Fuzzing-Testverfahren für jeden Programmcode;
- - Ermitteln eines Satzes von einer oder mehreren Programmcodemetriken für jeden der Programmcodes, so dass Trainingsdatensätze gebildet werden, die jeweils für eine Fuzzing-Methode und einen damit getesteten Programmcode einen Satz der einen oder der mehreren Programmcodemetriken der entsprechenden Leistungsmetrik zuordnen;
- - Erstellen des datenbasierten Fuzzing-Auswahlmodells basierend auf den Trainingsdatensätzen, so dass einem Satz einer oder mehrerer Programmcodemetriken eine Leistungsmetrik zugeordnet wird.
-
Es ist eine Vielzahl von Fuzzing-Methoden bekannt, die sich im Wesentlichen in die Klassen des Quellcode-Fuzzings und des Protokoll-Fuzzings unterteilen lassen. Das Quellcode-Fuzzing dient zum Auffinden von Fehlern in einem Programmcode, wobei versucht wird, möglichst viele Programmablaufpfade in dem Programmcode hinsichtlich eines unerwünschten Programmablaufs zu testen. Beim Protokoll-Fuzzing wird die Kommunikation eines Programmcodes überwacht, indem Kommunikationsnachrichten verzögert, abgefangen, manipuliert und dergleichen werden, um ein unerwünschtes Systemverhalten zu provozieren. Die Fuzzing-Software dient dabei als Man-in-the-Middle-Einheit zwischen zwei Teileinheiten des zu testenden Systems.
-
Für das Quellcode-Fuzzing sind derzeit einige Fuzzing-Methoden bekannt, die in verschiedenen Fuzzing-Softwaretools implementiert sind. Beispiele für derartige Fuzzing-Softwaretools sind American Fuzzing Lop, libFuzz oder honggfuzz.
-
Ferner können die Fuzzing-Verfahren mit verschiedenen Seed-Daten als Eingaben starten, die den Verlauf des Fuzzing-Tests erheblich beeinflussen. Das Fuzzing-Testen beruht zum großen Teil auf Zufälligkeit, so dass die gewählte Seed-Datei sowie die Zufallsauswahlen während des Testens einen Vergleich zwischen Fuzzing-Methoden erschweren.
-
Daher sollten für den Vergleich der Fuzzing-Sofwaretools die gleichen Seed-Daten verwendet werden.
-
Eine Seed-Datei stellt eine Minimalmenge von gültigen Eingaben dar. Programme, die auf den gleichen Eingaben beruhen, sollten die gleichen Seed-Daten zur Verfügung haben. Dies gilt insbesondere für Medienformate, wie PNG, JPG, PDAF, AVI, MP3, GIF, aber auch für andere Datenstrukturen, wie PDF, ELF, XML, SQL und dergleichen.
-
Auch sollten die Fuzzing-Softwaretools dieselben Wörterbücher (Dictionary) für den gleichen Eingangstyp der verwendeten Seed-Daten verwenden. Ein Dictionary umfasst eine Vorgabemenge für bestimmte Eingaben, wie z. B. Fehlerinjektionsmuster (fault injection patterns) und dergleichen, und enthält insbesondere Einträge in der Form von Zeichen, Symbolen, Wörtern, binäre Zeichenketten, oder ähnlichen, welche typischerweise Bestandteil des Eingabewertes zur testenden Software sind. Es gibt sowohl allgemeine Wörterbücher z.B. für PDF, ELF, XML oder SQL Parser, aber auch individuelle Wörterbücher für nur eine Software. Wörterbücher dienen dem Fuzzer als Hilfsmittel, um Eingaben zu generieren, welche einen längeren Ausführungspfad in der zu testenden Software verursachen.
-
Eine Fuzzing-Methode ist demnach durch das verwendete Fuzzing-Softwaretool, die Seed-Daten und den Dictionary charakterisiert. Weitere Aspekte, nach denen die Fuzzing-Methoden unterscheidbar sind, umfassen Fuzzing-Test-Parameter wie eine Beschränkung des verfügbaren Speichers, eine Einstellung eines Timeouts pro Testfall, ein Modus bzw., eine Auswahl von Heuristiken des Fuzzing-Tools, eine Verwendung einer Grammatik, und dergleichen. Zusätzliche Kriterien können die Testzeit des Fuzzing-Tests, die Datenverarbeitungsplattform, auf der das Fuzzing-Softwaretool betrieben wird, sowie deren Konfiguration betreffen.
-
Eine Idee des obigen Verfahrens besteht nun darin, ein Fuzzing-Auswahlmodell zur Verfügung zu stellen, das es ermöglicht, basierend auf Programmcodemetriken, die den Programmcode basierend auf statistischen Merkmalen charakterisieren, eine geeignete Fuzzing-Methode für das Fuzzing-Testen auszuwählen und zu konfigurieren.
-
Die Programmcodemetriken können hierzu beispielsweise eine oder mehrere der folgenden Metriken umfassen: Anzahl der Codezeilen, zyklomatische Komplexität, durchschnittliche Menge der Programmablaufpfade, einfache Ausführungszeit, Lastzeit, Programmcodegröße, Anzahl potentiell gefährlicher Funktionsaufrufe (z.B. memcpy), einer Anzahl von Speicherzugriffen und dergleichen.
-
Mithilfe des datenbasierten Fuzzing-Auswahlmodells ergibt sich eine Leistungsmetrik für verschiedene Fuzzing-Methoden, die durch das Fuzzing-Auswahlmodell klassifiziert werden. Entsprechend der Leistungsmetrik können ein oder mehrere der Fuzzing-Methoden für das Fuzzing-Testen des bereitgestellten Programmcodes ermittelt werden. Eine derartige Leistungsmetrik kann die Abdeckung der Programmablaufpfade (Coverage), insbesondere eine funktionale Abdeckung, Programmzeilenabdeckung oder eine Pfadabdeckung, die Anzahl der ausgeführten Programmablaufpfade, die Zahl der gefundenen unterschiedlichen Fehler und die durchschnittliche Fuzzing-Ausführungszeit umfassen bzw. davon abhängen.
-
So kann insbesondere die Fuzzing-Methode zum Fuzzing-Testen ausgewählt werden, die den höchsten Wert der Leistungsmetrik erhalten hat.
-
Das datenbasierte Fuzzing-Auswahlmodell kann ein Klassifikationsmodell sein und beispielsweise mithilfe eines neuronalen Netzes ausgebildet sein. Alternativ kann das Fuzzing-Auswahlmodell auch als lineare Regression oder eine Lookup-Tabelle (Zuordnungsfunktion) bereitgestellt werden, die angibt, welche Fuzzing-Methode in der Vergangenheit am besten war.
-
Das Trainieren des Fuzzing-Auswahlmodells kann datenbasiert erfolgen. Dazu werden zum Beispiel Programmcodes, die Codeschnipsel, Codebeispiele oder reale Software umfassen können, in einer Programmcodesammlung bereitgestellt. Diese sollten jeweils mit mindestens einem künstlichen oder bekannten realen Fehler (CVE: Common Vulnerabilities and Exposures) versehen sein, der zu einem Programmabbruch führt, wenn der entsprechende Programmablaufpfad ausgeführt wird.
-
Die Auswahl der Programmcodesammlung für das Training des Fuzzing-Auswahlmodells kann fest vorgegeben sein oder diese kann entsprechend der zu bewertenden Leistungsmetrik basierend auf Verfahren des Reinforcement Learning ausgewählt werden. Zum Training werden Trainingsdatensätze erstellt, wobei zunächst die Programmcodemetriken für die Programmcodes der Programmcodesammlung ermittelt werden.
-
Reinforcement Learning kann angewendet werden, wenn während eines Trainings des Fuzzing-Auswahlmodells eine beobachtete Leistungsmetrik (z.B. Coverage) nicht mehr (oder zu wenig) ändert und dann für einen nächsten Fuzzing Lauf die Programm (z.B. Timeout) leicht angepasst werden, um die Leistungsmetriken (hoffentlich) zu maximieren.
-
Weiterhin wird mithilfe jeder der bereitgestellten Fuzzing-Methoden jeder der Programmcodes der bereitgestellten Programmcodesammlung getestet. Das Testen erfolgt unter gleichen Bedingungen, d. h. es werden Datenverarbeitungseinrichtungen gleicher Leistungsfähigkeit und die gleiche Testdauer angenommen. Anschließend wird das Testergebnis hinsichtlich einer oder mehrerer der Leistungsmetriken bewertet.
-
Das datenbasierte Fuzzing-Auswahlmodell kann nun trainiert werden, insbesondere als Klassifikationsmodell, wobei die Programmcodemetriken auf einen Ausgabevektor abgebildet werden, der für jede der Fuzzing-Methoden die entsprechende Leistungsmetrik vorgibt.
-
Figurenliste
-
Ausführungsformen werden nachfolgend anhand der beigefügten Zeichnungen näher erläutert. Es zeigen:
- 1 ein Blockdiagramm zur Veranschaulichung eines Systems zur Auswahl einer Fuzzing-Methode zum Testen eines Programmcodes;
- 2 ein Flussdiagramm zur Veranschaulichung des Verfahrens zur Auswahl einer Fuzzing-Methode für einen Fuzzing-Test eines vorgegebenen Programmcodes;
- 3 ein Blockdiagramm zur Veranschaulichung der Funktion eines Systems zum Training eines Fuzzing-Auswahlmodells; und
- 4 ein Flussdiagramm zur Veranschaulichung eines Verfahrens zum Trainieren eines Fuzzing-Auswahlmodells für die Nutzung in einem System der 3.
-
Beschreibung von Ausführungsformen
-
1 zeigt ein Blockdiagramm zur Veranschaulichung der Funktion zur Auswahl einer oder mehrerer Fuzzing-Methoden für einen Fuzzing-Test eines vorgegebenen Programmcodes. Die Funktion wird nachfolgend anhand des Flussdiagramms der 2 ausführlicher beschrieben. Das Verfahren und Funktionalität des Systems wird in einer Datenverarbeitungseinrichtung bereitgestellt.
-
In Schritt S1 wird ein Programmcode PC bereitgestellt. Der Programmcode PC kann einem Codeschnipsel, einem Codebeispiel oder einer realen Software entsprechen, die mithilfe eines Fuzzing-Tests getestet werden soll. Der Programmcode PC kann von einem Programmcodespeicher 11 abrufbar bereitgestellt werden. Zur Durchführung des Fuzzing-Tests ist es notwendig, dass der Programmcode kompilierbar, interpretierbar und ausführbar ist.
-
In Schritt S2 werden in einem Analyseblock 12 Programmcodemetriken PM aus dem vorgegebenen Programmcode ermittelt. Die Programmcodemetriken PM können einen oder mehrere der folgenden Metriken umfassen: eine zyklomatische Komplexität, eine Befehlspfadlänge (Anzahl von Maschinencodebefehlen der gesamten Programmpfadlänge), die Anzahl von Codezeilen, die Programmausführungszeit, die Programmladezeit und die Programmgröße (in Byte). Die Programmcodemetriken PM sind so gewählt, dass diese den vorgegebenen Programmcode charakterisieren, und sollten insbesondere durch wenige, insbesondere eine Programmausführung des bereitgestellten Programmcodes ermittelbar sein.
-
Die zyklomatische Komplexität, auch McCabe-Metrik genannt, dient zur Bestimmung einer Komplexität eines Software-Moduls (Funktion, Prozedur oder allgemein ein Stück Sourcecode). Diese ist definiert als Anzahl linear unabhängiger Pfade auf dem Kontrollflussgraphen eines Programmcodes und damit als eine obere Grenze für die minimale Anzahl der Testfälle, die nötig sind, um eine vollständige Zweigüberdeckung des Kontrollflussgraphen zu erreichen.
-
Die Programmcodemetriken PM werden in Schritt S3 einem trainierten datenbasierten Fuzzing-Auswahlmodell in einem Fuzzing-Auswahlmodellblock 13 zugeführt, um ein Klassifikationsergebnis für die in dem Fuzzing-Auswahlmodell berücksichtigten Fuzzing-Methoden zu erhalten.
-
Das Fuzzing-Auswahlmodell entspricht einem datenbasierten Klassifikationsmodell, das trainiert ist, um für eine Anzahl berücksichtigter Fuzzing-Methoden jeweils eine Leistungsmetrik abhängig von den Programmcodemetriken z. B. in Form eines Ausgabevektors A auszugeben. Die Leistungsmetrik gibt jeweils an, wie gut die entsprechende Fuzzing-Methode für das Testen des vorgegebenen Programmcodes geeignet ist. Diese Leistungsmetrik kann z.B. einen Wertebereich zwischen 0 und 1 aufweisen.
-
Abhängig von dem Ausgabevektor können in Schritt S4 in einem Auswahlblock 14 die eine oder die mehreren der Fuzzing-Methoden mit der höchsten Leistungsmetrik ausgewählt werden, um den vorgegebenen Programmcode entsprechend mit Fuzzing-Testverfahren entsprechend der Fuzzing-Methode zu testen.
-
In Schritt S5 werden die ausgewählten Fuzzing-Methoden zur Durchführung von Fuzzing-Tests verwendet. Somit werden entsprechend dem Ergebnis des Fuzzing-Auswahlmodells die eine oder die mehreren ausgewählten Fuzzing-Methoden auf dem Programmcode in einem Ausführungsblock angewendet.
-
Fuzzing-Methoden unterscheiden sich in erster Linie durch das verwendete Fuzzing-Softwaretool und durch die anfänglich bereitgestellten Seed-Daten, die Anfangseingaben für das Fuzzing-Testen bereitstellen. Weitere Parameter für die ausgewählten Fuzzing-Methoden stellen der verwendete Dictionary, die Verarbeitungskapazität, die Testzeit, eine Mindestzahl von Programmausführungen und mögliche Konfigurationen des Fuzzing-Softwaretools dar.
-
In 3 ist ein Blockdiagramm zur Veranschaulichung einer Funktion zum Trainieren eines datenbasierten Fuzzing-Auswahlmodells dargestellt. Die Funktion wird mit Bezug auf das Flussdiagramm der 4 näher erläutert. Das darin beschriebene Verfahren kann auf einer herkömmlichen Datenverarbeitungseinrichtung ausgeführt werden.
-
Zum Trainieren des Fuzzing-Auswahlmodells werden Trainingsdatensätze verwendet, die jeweils eine oder mehrere Programmcodemetriken auf einen Ausgabevektor abbilden. Der Ausgabevektor klassifiziert die Programmcodemetrik entsprechend einer Fuzzing-Methode. Dazu kann jedes Element des Ausgabevektors einer unterschiedlichen Fuzzing-Methode zugeordnet sein und einen entsprechenden Wert aufweisen, der einer Leistungsmetrik entspricht. Der Wert kennzeichnet die Geeignetheit der entsprechenden Fuzzing-Methode für die durch die Programmcodemetriken charakterisierte Programmcodeart.
-
Zu Beginn des Verfahrens wird in Schritt S11 in einem Programmcodespeicher 21 eine Programmcodesammlung (Benchmark Suite) mit einer Anzahl von verschiedenen Programmcodebeispielen BSP bereitgestellt. Die Programmcodesammlung kann als Fixed Suite, wie z. B. „The DARPA CGC binaries“, „LAVA test suite“, „Google Fuzzer Suite“, „NIST Software Assurance Metrics And Tool Evaluation (SAMATE)“, „FEData“, als Evolvable Suite, wie z. B. in Klees G. et al., „Evaluating fuzz testing“, in Proceedings of the 2018 ACM SIGSAC Conference on Computer and Communications Security, CCS '18, Seiten 2123-2138, New York, NY, USA, 2018. ACM offenbart, und/oder als Labeled Suite, die eine Programmcodesammlung zur Unterscheidung der Fehlerarten bereitstellt und die z. B. mit der Google Fuzzer Suite und dem NIST SAMATE project bereitstellt werden, vorgesehen sein.
-
Die Programmcodebeispiele BSP werden entsprechend in einem Analyseblock 22 in Schritt S12 analysiert, um jeweils Programmcodemetriken PM zu ermitteln.
-
Ferner werden in Schritt S13 mithilfe einer Reihe von ausgewählten Fuzzing-Methoden, die in einem Fuzzing-Testblock 23 ausgeführt werden, die Programmcodebeispiele BSP mithilfe von Fuzzing-Testverfahren entsprechend den bereitgestellten Fuzzing-Methoden getestet.
-
In einem Bewertungsblock 24 werden in Schritt S14 als Ergebnis des Testens eine Leistungsmetrik ermittelt. Die Leistungsmetrik kann eine oder mehrere der folgenden Metriken umfassen oder von diesen abhängen: die Testüberdeckung (Coverage), die Anzahl der ausgeführten Programmablaufpfade, eine Fehlererkennungsrate (z. B. die Anzahl der erkannten Fehler) und eine durchschnittliche Fuzzing-Ausführungszeit. Die Leistungsmetrik kann einen oder mehrere dieser Metriken berücksichtigen und einer entsprechenden Maßzahl zuordnen. Anschließend wird aus den Leistungsmetriken ein Vektor erstellt, dessen Elemente für jede der entsprechenden Fuzzing-Methoden die zugehörige Leistungsmetrik angeben.
-
Mithilfe geeigneter maschineller Lernverfahren kann nun in Schritt S15 in einem Modelltrainingsblock 25 ein datenbasiertes Fuzzing-Auswahlmodell erstellt/trainiert werden, mit Trainingsdatensätzen, die die einem Programmcodebeispiele der Programmcodesammlung zugeordnete Programmcodemetriken dem entsprechenden Vektor zuordnen. Beispielsweise können die maschinellen Lernverfahren Gauß-Prozess-Modelle oder neuronale Netzwerke als Fuzzing-Auswahlmodell umfassen.
-
Weitere Möglichkeiten der Ausbildung des Fuzzing-Auswahlmodells bestehen in statistischen Lernverfahren sowie Reinforcement Learning.