Das Wissensportal für IT-Professionals. Entdecke die Tiefe und Breite unseres IT-Contents in exklusiven Themenchannels und Magazinmarken.

SIGS DATACOM GmbH

Lindlaustraße 2c, 53842 Troisdorf

Tel: +49 (0)2241/2341-100

kundenservice@sigs-datacom.de

An Fuzz-Testing führt kein Weg vorbei

Was ist von der Technologie zu halten? Wie wirksam ist Fuzzing im Vergleich zu anderen Security-Testing-Methoden? Und warum setzen Tech-Leader wie Google auf diese Technologie?

  • 27.05.2022
  • Lesezeit: 13 Minuten
  • 17 Views

Erst kürzlich hat die log4j-Schwachstelle eindringlich gezeigt, wie verheerend die Konsequenzen von unentdeckten Sicherheitslücken sein können. Sicherheitsexperten des Cybercrime Magazin prognostizieren sogar einen weltweiten Anstieg der Kosten von Cyberangriffen auf $10,5 Billionen jährlich bis 2025 [CM20].

Um Ereignissen wie log4j vorzubeugen, setzen Tech-Giganten, wie Google und Microsoft (siehe Infobox), daher auf besonders effektive Security-Testing-Technologien, wie Fuzz-Testing. Mit dieser Technologie ist es möglich, Anwendungen kontinuierlich auf Sicherheitslücken zu überprüfen und nach jedem Pull Request einen automatisierten Security-Test durchzuführen. Doch auch in Deutschland findet Fuzzing unter Security-Experten und Pentestern eine immer breitere Anwendung.

Im Folgenden möchte ich näher auf die funktionalen Eigenschaften von Fuzz-Testing eingehen. Außerdem erläutere ich, warum es für langfristigen Erfolg von Security-Testing-Maßnahmen essenziell ist, Entwickler in den Mittelpunkt zu stellen. Anschließend zeige ich anhand echter Bug-Findings, wie Fuzzing es ermöglicht, auch schwerwiegende Schwachstellen mühelos zu identifizieren.

Infobox

Die Anforderungen an Sicherheitstests steigen

Angreifer werden immer besser darin, Sicherheitslücken zu identifizieren und auszunutzen. Security-Testing-Lösungen müssen daher präziser und effektiver werden, um mit dieser Entwicklung mitzuhalten. Auch wenn viele Testing-Lösungen grundsätzlich dazu in der Lage sind, Bugs aufzuspüren, so erfordern diese oftmals einen hohen Grad an manuellem Aufwand, den die meisten Entwickler nicht aufbringen können. Sie skalieren nicht. Selbst wenn sich Entwicklerteams Mühe geben, sichere Software zu entwickeln, wird das Testing oftmals zugunsten von zeitkritischen Anliegen hinten angestellt. Wenn im Nachhinein dann Fehler gefunden werden, brennt natürlich die Hütte. Fehler, die teils Monate alt sind, müssen dann ausgemerzt werden, was Zeit, Geld und Nerven kostet.

Doch weil Angreifer immer effektiver darin werden, Sicherheitslücken auszunutzen, muss auch das Bewusstsein und die Sensibilität für IT-Sicherheit zunehmen. Damit IT-Sicherheit ein fester Bestandteil eines jeden Softwareentwicklungsprozesses wird, ist auch ein kultureller Wandel nötig.

Fuzz-Testing kann dabei eine zentrale Rolle spielen, da es Entwickler dazu ermächtigt, Sicherheitstests eigenständig durchzuführen, ohne dass Security-Experten ihnen dabei ständig über die Schulter schauen müssen. Dies ist auch ein Grund dafür, weshalb Fuzzing in einigen Branchen (wie in der Automobilindustrie) in neueren Industriestandards empfohlen wird [Dec20].

Kasten 1

Wie funktioniert Fuzzing?

Fuzzing (oder auch „Fuzz-Testing“) ist eine dynamische Testmethode, die zum Auffinden von Funktionsfehlern und Sicherheitsproblemen in Software eingesetzt wird. Bei einem Fuzz-Test wird ein Programm mit ungültigen, unerwarteten oder zufälligen Eingaben ausgeführt, mit dem Ziel, die Anwendung zum Absturz zu bringen.

Moderne Fuzzing-Lösungen analysieren die Struktur des Codes, den sie testen, und können so Tausende von automatisierten Testfällen pro Sekunde erzeugen. Dabei werden alle Pfade und Programmzustände (States) markiert, die von den Eingaben durchquert werden. Auf diese Weise erhält ein Fuzzer detailliertes Feedback über die Codeabdeckung (siehe Abbildung 2), welche die Eingaben bei der Ausführung des Quellcodes erreichen. Sobald ein Fuzzer eine Eingabe gefunden hat, die zu einem Crash führt, oder einen neuen State erreicht, verwendet er Mutationsalgorithmen, um weitere Eingaben zu generieren, die den Fund mit hoher Wahrscheinlichkeit reproduzieren können. Da moderne Fuzzer zufällige und ungültige Eingaben testen und gezielt versuchen, die Testabdeckung zu maximieren, können sie auch unwahrscheinliche oder unerwartete Randfälle abdecken, die andere Testansätze übersehen.

Abb. 2: Feedback-based fuzzing

Fuzzing ermöglicht es, eine hohe Codeabdeckung zu erreichen, was auch die Sicherheit von Anwendungen deutlich erhöht. Die Business Unit HMI des Automobilzulieferers Continental hat mithilfe von Fuzzing zum Beispiel erreicht, dass der Großteil ihrer Module heute eine Codeabdeckung von über 95 Prozent aufweist [Per21-b]. Da Fuzzing-Tools die zu testende Software zudem mit realen Eingaben ausführen, liefern die Fuzz-Tests den Entwicklern auch den notwendigen Anwendungskontext, um die Fehler später schnell und einfach zu reproduzieren

Was macht Fuzzing so effektiv?

Die folgenden Eigenschaften machen Fuzzing so effektiv, weitere finden sich in [Dec22].

Keine False Positives und wenig manueller Aufwand

Automatisierte Testverfahren, wie die statische Codeanalyse, lassen sich leicht anwenden und ermöglichen ebenfalls eine besonders hohe Testabdeckung. Doch da bei diesen Testverfahren der Code während des Testens nicht ausgeführt werden kann, generieren sie auch viele falsch-positive Fehlermeldungen. Diese müssen anschließend manuell aussortiert werden, was gelegentlich als lästige Tätigkeit empfunden wird. Statische Codeanalyse und Fuzzing ergänzen sich jedoch sehr gut. Indem man statische Tools mit dynamischen Testverfahren, wie Fuzzing, kombiniert, kann man diese Fehlalarme deutlich reduzieren und spart sich auch viel manuellen Aufwand beim Testen.

Effizientes Debugging durch nachweisbare Eingaben

Systemabstürze, die mit Unittests oder statischer Codeanalyse aufgedeckt werden, erfordern ein gewisses Maß an Fachexpertise, um diese auf den zugrunde liegenden Fehler zurückzuführen. Selbst für Fachexperten lässt sich dies nicht immer problemlos bewerkstelligen. Entwickler, die keinen speziellen Security-Hintergrund haben, sind dafür jedoch häufig nicht gewappnet. Auch hier können Fuzzing-Lösungen aushelfen, da sie zu jeder Fehlermeldung den passenden Input und einen Bug-Report mitliefern, was es Entwicklern ermöglicht, Fehler umgehend nachzuvollziehen und zu beheben.

Messbare Codeabdeckung

Fuzz-Tests, die auf dem Quellcode durchgeführt werden, können Angaben zur Codeabdeckung enthalten (siehe Abbildung 3). Die Codeabdeckung ist eine wichtige Metrik für Sicherheitstests, da sie dabei hilft einzuschätzen, wie hoch das verbleibende Restrisiko ist, kritische Sicherheitslücken zu übersehen. Sie ermöglicht es Entwicklern auch, Aussagen darüber zu treffen, welche Teile des Codes von den Testeingaben bereits durchlaufen wurden. Diese Informationen ermöglichen letztendlich eine präzise Interpretation der Testergebnisse und aussagekräftige Testberichte.

Abb. 3: Code Coverage Reporting in der Fuzzing-Plattform CI Fuzz [Fuzz]

Automatisierte Testfallgenerierung

Moderne Fuzzer erhalten durch eine intelligente Instrumentierung kontinuierlich Feedback zur Struktur und zum Verhalten der Anwendung. Der Fuzzer kann dieses Wissen über die Anwendung nutzen, um seine Testeingaben gezielt zu variieren und eine möglichst hohe Testabdeckung zu erreichen. Dabei können Open-Source-Fuzzing-Lösungen wie AFL oder Jazzer bereits mit der Hilfe von ein paar Tutorials ohne großes Vorwissen bedient werden.

CI/CD-Integration für kontinuierliches Fuzzing

Viele Fuzz-Testing-Tools lassen sich problemlos in Jenkins, Github, Kubernetes und Co. integrieren, um dort kontinuierliche Tests durchzuführen. Durch die CI/CD-Integration können Entwickler mit jedem Pull Request einen automatisierten Sicherheitstest durchführen, bevor Veränderungen mit der Codebase zusammengeführt werden. Anstelle von großen und aufwendigen Abnahmetests ermöglicht dies einen kontinuierlichen Testzyklus, der bereits in den frühen Phasen der Softwareentwicklung beginnt. So können Fehler direkt nach ihrer Entstehung gefunden und behoben werden.

Was für Schwachstellen findet Fuzzing?

Fuzzing ist besonders versiert darin, Speicherkorruption zu finden. In C/C++-Projekten, wie zum Beispiel in der Automobil- und Luftfahrtbranche, wo viel sicherheitskritische embedded Software verbaut wird, ist Fuzzing daher besonders weit verbreitet. Aber auch in Web-Anwendungen kann Fuzzing eine Reihe von schwerwiegenden Sicherheitslücken entlarven, wie beispielsweise Cross-Site-Scripting, Denial-of-Service-Möglichkeiten, Code-Injections und viele weitere Arten von Schwachstellen.

Fuzzing in der Praxis: Corona-Warn-App

So viel zur Theorie. Doch wie wird Fuzz-Testing in der Praxis eingesetzt? Fuzzing kommt vor allem dann zur Anwendung, wenn kritische Software besonders gründlich auf Schwachstellen untersucht werden muss. Deutsche Sicherheitsforscher konnten zum Beispiel im Frühjahr 2020 mithilfe von Fuzzing zwei Injections im Server-Code (CWA-Server) einer bis dahin noch unveröffentlichten Version der Corona-Warn-App unschädlich machen (Version #163 und #164). Angreifer hätten die Schwachstelle ansonsten für eine Remote Code Execution (RCE) ausnutzen können [Res20-a] [Res20-b] (siehe Abbildung 4).

Abb. 4: Zwei Expression Language Injections im CWA-Server (Version #163 und #164), die mithilfe von Fuzzing verhindert werden konnten

Derartige Sicherheitslücken frühzeitig zu beseitigen, ist nicht nur für die Sicherheit wichtig, sondern auch für das Vertrauen der User in die Applikation. Das Debakel um die Luca-App hat eindringlich gezeigt, wie wichtig es ist, dass gerade dort, wo persönliche Daten abgerufen werden, Sicherheitsrisiken minimiert werden. Microservices wie das Backend des CWA-Servers zu testen, ist jedoch aufgrund der hohen Interkonnektivität besonders komplex. Diese Bandbreite an Modulen und APIs weist viele Interdependenzen auf, die sich mit manuellen Testverfahren kaum abdecken lassen. Mit automatisierten Fuzz-Tests lässt sich diese Komplexität jedoch beherrschen [Res21].

Die Rolle von Fuzzing im Wandel der IT-Security

Heutzutage wird Security-Testing noch häufig in Form von umfangreichen Abnahmetests als dedizierte Phase des Entwicklungsprozesses wahrgenommen. Doch aktuelle Trends wie DevSecOps und Shift Left sind bereits erste Vorboten einer Zukunft, in der das Testen einen kontinuierlichen Prozess darstellt, in dem Entwicklerteams die Sicherheit ihres Codes selbst in die Hand nehmen.

Auch für den kulturellen Wandel von Security-Testing bietet Fuzzing eine gute Grundlage. Dadurch, dass Entwicklerteams vermehrt in den Testing-Prozess involviert werden, entsteht ein neues Bewusstsein für dieses Thema. Kontinuierliches Security-Testing und Fuzzing, als fester Bestandteil der CI/CD, kann so also auch dazu beitragen, dass IT-Sicherheit in Entwicklungsprozessen zukünftig von Anfang bis Ende mitgedacht wird.

Fazit: Kein Weg führt an Fuzzing vorbei

Durch eine einfache Usability und hilfreiche Dev-Tool-Integrationen machen Fuzzing-Lösungen, wie CI Fuzz, oder OSS-Fuzz, die Vision von kontinuierlichem Security-Testing bereits Realität. Fuzzing ermöglicht es, der steigenden Bedrohung von Cyberangriffen durch effizientes und präzises Security-Testing entgegenzuwirken. Fuzz-Testing wird heute schon von Technologieführern wie Google eingesetzt, doch mittelfristig ist damit zu rechnen, dass Fuzzing sich auch branchenübergreifend als neuer Goldstandard für Software-Security-Testing durchsetzen wird.

Referenzen

[CM20]
S. Morgan, Cybercrime To Cost The World $10.5 Trillion Annually By 2025, Cybercrime Magazin, 13.11.2020, siehe:
https://cybersecurityventures.com/cybercrime-damage-costs-10-trillion-by-2025/

[CW10]
G. Keizer, Microsoft runs fuzzing botnet, finds 1,800 Office bugs, Computerworld, 31.3.2010, siehe:
https://www.computerworld.com/article/2516563/microsoft-runs-fuzzing-botnet--finds-1-800-office-bugs.html

[Dec20]
S. Dechand, Six Tips to Comply With ISO 21434, Code Intelligence Security Blog, 8.10.2020, siehe:
https://www.code-intelligence.com/blog/iso-21434-compliance

[Dec22]
S. Dechand, Schafft modernes Fuzzing bewährte Testing-Methoden ab?, in: Informatik Aktuell, 8.2.2022, siehe:
https://www.informatik-aktuell.de/entwicklung/methoden/schafft-modernes-fuzzing-bewaehrte-testing-methoden-ab.html

[Fuzz]
CI Fuzz, Json-Sanitizer, Code Intelligence Web App, siehe:
https://app.code-intelligence.com/dashboard/projects/organizations_89d295318b3fded6_json-sanitizer-7eff5208/campaign_runs/nostalgic_herschel/coverage

[GitH-a]
Clusterfuzz, Google GitHub Repository, siehe:
https://github.com/google/clusterfuzz

[GitH-b]
OSS-Fuzz, Google GitHub Repository, siehe:
https://google.github.io/oss-fuzz/

[GitH-c]
F. Meumertzheim, Jazzer GitHub Repository, siehe:
https://github.com/CodeIntelligenceTesting/jazzer/blob/main/examples/src/main/java/com/example/Log4jFuzzer.java#L40

[Jeo20]
Y. Jeon, WookHyan H., N. Burow, M. Payer, FuZZan. Efficient Sanitizer Metadata Design for Fuzzing, Usenix Annual Technical Conf. 2020, 15.7.2020, siehe:
https://www.usenix.org/system/files/atc20-jeon.pdf

[Met21]
J. Metzmann, Improving OSS-Fuzz and Jazzer to Catch Log4Shell, Google Security Blog, 16.12.2021, siehe:
https://security.googleblog.com/2021/12/improving-oss-fuzz-and-jazzer-to-catch.html

[Per21-a]
H. Perl, What Bugs Can You Find With Fuzzing, Code Intelligence Security Blog, 12.8.2021, siehe:
https://www.code-intelligence.com/blog/what-bugs-can-you-find-with-fuzzing

[Per21-b]
H. Perl, How Continental Tested 18 000 LoC in Only One Week, Code Intelligence Security Blog, 9.6.2021, siehe:
https://www.code-intelligence.com/blog/fuzzing-automotive-software-faster

[Res20-a]
S. Resch, fix: correct registration key validation #163, CWA Verification Server, GitHub Pull Request, 24.6.2020, siehe:
https://github.com/corona-warn-app/cwa-verification-server/pull/163

[Res20-b]
S. Resch, fix: handle unsupported content type and HTTP method #164, CWA Verification Server, GitHub Pull Request, 26.6.2020, siehe:
https://github.com/corona-warn-app/cwa-verification-server/pull/164

[Res21]
S. Resch, How to Secure Complex Microservices in Five Easy Steps, Code Intelligence Security Blog, 22.7.2021, siehe:
https://www.code-intelligence.com/blog/fuzzing-microservices-in-5-steps

. . .

Author Image
Zu Inhalten
Sergej Dechand blickt auf langjährige Forschungserfahrung im Bereich Usable Security am Fraunhofer FKIE und der Universität Bonn zurück. Als Mitgründer und CEO von Code Intelligence verfolgt er gemeinsam mit seinem Team das Ziel, Application Security Testing zu revolutionieren. Seine Philosophie ist dabei, dass gute Security-Testing-Software die Developer immer in den Vordergrund stellen muss.

Artikel teilen