Ein Angebot von

Mit statischen Analysen zu besseren Design-Entscheidungen

| Autor / Redakteur: Christian Guss * / Sebastian Gerstl

Bild 1: Vergleich der ICS-Software Sicherheitslücken.
Bild 1: Vergleich der ICS-Software Sicherheitslücken. (Bild: CISA)

Im Zeitalter der zunehmenden Vernetzung sind einige Anstrengungen nötig um sicherzustellen, dass das Risiko von Cyber-Security Attacken nicht zu gefährlichen Situationen führt. Mit Hilfe von Modelbasiertem Design und statischer Analyse lassen sich Applikationen absichern, standard-konform entwickeln und dennoch perfomant implementieren.

Das Thema Security und Cybersecurity gerät zunehmend in den Vordergrund der Software-Entwicklungsprozesse. Jüngste Schätzungen gehen von mehreren Millliarden vernetzten Geräten im Jahre 2019 [1][2] aus. Das U.S. Department of Homeland Security (DHS) hat durch das „Industrial Control Systems (ICS) Cyber Emergency Response Team“ (ICS-CERT) ermittelt, dass der höchste Prozentsatz von bekannten Schwachstellen bzw. Sicherheitslücken in ICS-Software durch fehlende oder mangelhafte Überprüfung von Eingaben verursacht wird (siehe Bild 1).

Oftmals scheitert die Absicherung durch robuste Sicherheitsmaßnahmen an den begrenzten physikalischen Ressourcen der eingebetteten Systeme. Insbesondere bei der Verwendung von kleinen, kostengünstigen Komponenten. Ist so ein System erst einmal infiziert, ist es schwer dies zu erkennen, um die Software zu aktualisieren. Hinzu kommt, dass in der Praxis häufig erst an die Sicherheit gedacht wird, wenn die Geräte schon fertig entworfen und möglicherweise bereits im Einsatz sind.

Aufgrund der hohen Gefahr durch Angriffe entstehen zunehmend Regularien und Standards zum Thema Cybersecurity. Standards wie CERT C, ISO-TS 17961, der CWE und MISRA C:2012 Amendment 1 befassen sich mit dem Thema Security von Software. Beim System- und Komponenten Design und der Implementierung müssen dadurch oft Kompromisse gemacht werden, da die Anforderungen in Bezug auf Funktionalität, Performanz, sowie Safety und Security teilweise konkurrierend zueinander sind, speziell wenn es um die Erfüllung von Standards geht.

Modell-basierte Threat-/Risk Analyse

Model-based Design hat sich als eine effektive Methodik bewährt, Fehler und Schwachstellen während der frühen Entwicklungsphasen kosteneffizienter zu entdecken und zu bereinigen, als in den späteren Phasen der Entwicklung [3]. Der Aufbau eines Modells entspricht im Allgemeinen der Applikation eines Embedded Software Systems, welches in vielen Fällen über Schnittstellen mit externen Komponenten verbunden ist (Bild 2). Diese Schnittstellen können Unbefugten Zugriff auf sensible Bereiche Ihrer Applikation verschaffen.

Ein strukturiertes Vorgehen, um die Ursache und Fortpflanzung von Angriffen zu erkennen, ist dabei ein wichtiger Erfolgsfaktor. In Bild 3 sehen wir Analyseverfahren, die auf verschiedenen Ebenen durchgeführt werden, z.B. Assets and Attack Potentials, sowie Threat and Risk Assessment. Auf das Modell, bestehend aus den Blöcken Sensors, Control und Actuators, werden dabei gezielt Angriffsszenarien auf die Eingänge induziert, um herauszufinden welche Kanäle anfällig sind.

Im Modell angewendete Angriffs-Methoden sind:

  • Attacker Centric: Dieser Ansatz startet beim Angreifer selbst, um dessen Angriffsziele zu simulieren.
  • Design Centric: Dieser Ansatz beleuchtet das Design des Systems selbst und identifiziert mögliche Schwachstellen
  • Asset Centric: Dieser Ansatz bezieht sich auf Daten, Informationen oder Geräte die es zu schützen gilt. Diese meist streng vertraulichen Informationen unterstehen einer höheren Priorität als die des Gesamtsystems und müssen somit gesondert betrachtet und geschützt werden.

In Kombination mit formalen Analyse-Methoden, erlaubt es Threat Modeling mögliche Angriffspfade als Szenarien darzustellen und Schwachstellen durch mögliche Attacken zu identifizieren, priorisieren und entsprechend zu schließen. Zum Beispiel verwendet der Simulink Design Verifier [4] formale Methoden, um Schwachstellen in Simulink Modellen automatisiert, ohne umfangreiche Simulationsläufe, zu identifizieren. Durch Property Proving lässt sich beweisen, ob das Design, wie in den Anforderungen beschrieben, unter Berücksichtigung des Angriffsszenarios funktioniert. Sollte dies nicht der Fall sein, wird ein Gegenbeispiel ermittelt, das als Testfall auf das Modell ausgeführt werden kann, um das fehlerhafte Verhalten sichtbar zu machen bzw. um die Sicherheitsalgorithmen, die die Angriffe abwehren soll, zu validieren (siehe Bild 4).

Für das Threat Modelling können z.B. folgende Angriffs-Modelle angewendet werden

  • Interruption attack model [5]: um den Informationsfluss zu unterbrechen
  • Overflow attack model [6]: provozieren von Überläufen von Datentypen über Eingangs-Kanäle
  • Man-in-the-middle attack [6] : ist ein Ansatz die Kommunikation zwischen zwei Systemen abzufangen.

Fuzzing (siehe Bild 5) ist eine Test-Methodik, mit der ein Applikations-Modell mit gültigen und ungültigen Eingaben bzw. „Fault Injections“ bedient wird. Diese sollen bestimmte Attacken an den Schnittstellen simulieren. Untersucht wird das System damit auf bestimmte Verletzungen, z.B. gegen funktionale oder Performance-Anforderungen.

Verifikation auf Code-Ebene

Durch die Integration einzelner Software-Komponenten zu einem Gesamtsystem auf Code-Ebene, das z.B. Multitasking-fähig und durch Interrupts unterbrechbar ist, können zusätzliche Schwachstellen entstehen, die Attacken zulassen und eine Analyse auf Code-Ebene erfordern.

Ein Ansatz, um die Security Anforderungen auf Codeebene einzuhalten, ist die Anwendung von etablierten Security Guidelines, um Schwachstellen zu erkennen und zu vermeiden. Bild 6 zeigt einen Überblick verbreiteter Coding-Standards mit deren Klassifizierung ob der Standard Security oder Safety adressiert, basierend auf „The CERT C Coding Standard“ [7], wobei MISRA C:2012 durch das Amendement 1 mittlerweile ebenso Security addressiert.

Ein effektiver und kostengünster Ansatz zur Überprüfung ist statische Code-Analyse. Diese hilft:

  • Manuelle Code Reviews und Tests zu automatisieren
  • Software auf Code-Richtlinien zu überprüfen und Verletzungen zu dokumentieren oder zu kommentieren
  • Schwachstellen und Defekte automatisiert zu finden

Ein Beispiel für mögliche Schwachstellen sind Daten, die in einer Funktion verwendet, jedoch von einer äußeren Quelle an diese Funktion übergeben werden (Tainted Data), z.B. die Größe eines übergebenen Arrays. Durch gezielte Manipulation dieses Wertes kann damit ein Zugriff außerhalb der gültigen Arraygrenzen und somit auf beliebigen Speicherbereich stattfinden. Tainted Data sind ein beliebtes Ziel von Angriffen. Ein solcher Array-Zugriff kann sowohl ein Safety-, als auch ein Security Problem darstellen. Ein Beispiel für die Identifikation von Tainted Data Schwachstellen mittels statischer Code-Analyse, zeigt Bild 7.

Ist die Schwachstelle identifiziert, kann diese im Design oder im Code, z.B. durch eine gezielte Überprüfung der Schnittstelle auf Gültigkeit der Übergabeparameter zur Laufzeit, behoben und die Robustheit der Applikation erhöht werden.

Statische Analysetools, die zusätzlich über formale Kontroll- und Datenflussanalyse-Methoden verfügen, wie z.B. Polyspace Code Prover [8], sind darüber hinaus in der Lage die Abwesenheit bestimmter Fehler bzw. Schwachstellen zu beweisen, was den Aufwand für Tests, Reviews und den Nachweis der Compliance zu Standards (Bild 8), erheblich reduziert. Des Weiteren lässt sich dadurch auch die Code-Performance erhöhen, sowie der Speicherbedarf reduzieren, da Laufzeitchecks viel zielgerichteter eingesetzt, bzw. vermieden werden können.

Zusammenfassung: Sicher, performant oder schnell entwickelt: Was darf's sein?

Beim Design und der Implementierung von vernetzten Software-Systemen müssen oft Kompromisse eingegangen werden, speziell wenn es um die Erfüllung von Standards und Coding-Guidelines geht. Daraus ergibt sich, dass es enorm wichtig ist, Schwachstellen und Defekte frühzeitig, und am Besten während des Designs und der Implementierungsphase, zu erkennen und zu bereinigen.

Wir haben beispielhaft Modell- und Code-basierte Methoden gezeigt, mit denen Angriffe frühzeitig simuliert und die Robustheit kostengünstig erhöht werden kann. Gerade formale Methoden lassen sich mittlerweile einfach in den Entwicklungsprozess integrieren, um die Code-Performance zu erhöhen und die Aufwände für Test und Konformität zu reduzieren. Die Modell-basierte Entwicklung ermöglicht zudem eine deutlich schnellere Reaktion auf sich ständig ändernde Standards und anderweitigen Änderungen der Anforderungen, als mit traditionell entwickelten Systemen.

Grundlagen des Modellbasierten System-Engineering (MBSE)

Grundlagen des Modellbasierten System-Engineering (MBSE)

17.04.18 - Software und Systeme werden zunehmend schwieriger versteh- und beherrschbar. Infolgedessen wenden sich immer mehr Entwickler modellbasiertem System-Engineering (MBSE) zu. Was gibt es dabei zu beachten? lesen

Mit statischer Code-Analyse Performance-Flaschenhälse finden

Mit statischer Code-Analyse Performance-Flaschenhälse finden

28.06.18 - Viele Performance-Probleme können bereits in einer sehr frühen Phase des Software Development Lifecycles gefunden werden. Je früher ein Flaschenhals erkannt wird, desto einfacher und billiger kann er auch beseitigt werden. Dazu eignet sich ein Tool, das eigentlich in jedem Entwicklungsteam vorhanden sein sollte: Die statische Code-Analyse. lesen

Fuzzing von Embedded Software – Grundlagen und Erfahrungen

Fuzzing von Embedded Software – Grundlagen und Erfahrungen

10.09.18 - Softwaresicherheit lässt sich häufig nur unzureichend als Anforderung formulieren und testen. Teststrategien wie Fuzzing bietet aber eine Möglichkeit, automatisiert die Robustheit von Software zu prüfen. dieser Arikel beschreibt, was Fuzzing ausmacht, welche Hürden es beim Testen von Embedded Software gibt und mögliche Lösungsansätze sich daraus ergeben. lesen

Literatur- und Quellenverzeichnis

[1] J. Greenough, “ ’The Internet of Things’ will be the world’s most massive device market and save companies billions of dollars” Feb 2015
[2] U.G.C.S: Adviser, “The Internet of Things: making the most of the Second Digital Evolution
[3] A. Wasicek, P. Derler, and E. A. Lee. Aspect-oriented modeling of attacks in automotive cyberphysical systems. In Design Automation Conference (DAC), 2014 51st pages 1-6. IEEE, 2014.
[4] Simulink Design Verifier
[5] G. Tassey. The economic impacts of inadequate infrastructure for software testing. RTI Project Number 7007.011, NIST, 2002.
[6] S. Checkoway, D. McCoy, B. Kantor, D. Anderson, H. Shacham, S. Savage, K. Koscher, A. Czeskis, F. Roesner, T. Kohno, et al. Comprehensive experimental analyses of automotive attack surfaces. In USENIX Security Symposium. San Francisco, 2011.
[7] Robert C. Seacord, The CERT C Coding Standard: 98 Rules for Developing Safe, Reliable, and Secure Systems. SEI series in software engineering Addison-Wesley, 2014, ISBN 0321984048, 9780321984043
[8] Polyspace – Making Critical Code Safe and Secure

(Dieser Beitrag wurde mit freundlicher Genehmigung des Autors dem Tagungsband Embedded Software Engineering Kongress 2017 entnommen.)

* Christian Guss ist Application Engineer bei Mathworks und dort speziell im Bereich der Verifikation und Validierung von sicherheitsrelevanten Applikationen zuständig.

Kommentar zu diesem Artikel abgeben

Schreiben Sie uns hier Ihre Meinung ...
(nicht registrierter User)

Zur Wahrung unserer Interessen speichern wir zusätzlich zu den o.g. Informationen die IP-Adresse. Dies dient ausschließlich dem Zweck, dass Sie als Urheber des Kommentars identifiziert werden können. Rechtliche Grundlage ist die Wahrung berechtigter Interessen gem. Art 6 Abs 1 lit. f) DSGVO.
Kommentar abschicken
copyright

Dieser Beitrag ist urheberrechtlich geschützt. Sie wollen ihn für Ihre Zwecke verwenden? Infos finden Sie unter www.mycontentfactory.de (ID: 45882985 / Safety & Security)