Cyberattacken auf eingebettete Systeme nehmen zu. Wie statische Code-Analyse dazu beitragen kann, ihre sicherheitskritischen Funktionen zu schützen, erklären Dr. Jacob Palczynski & Dr.-Ing. Martin Becker von Mathworks.
Ziel von Cyberattacken ist es, Schwachstellen in Software zu finden, durch die unbeabsichtigtes Verhalten ausgelöst werden kann.
Eingebettete Systeme aller Art, auch solche mit sicherheitskritischen Funktionen, werden immer häufiger Ziele von Cyberattacken [1]. Obwohl viele Entwickler bereits statische Code-Analysen und dynamische Tests einsetzen, um die Qualität und die (funktionale) Sicherheit ihrer Software zu erhöhen [2], bleibt das Problem bestehen. Da aber die Zahl von eingebetteten Systemen, denen wir vertrauen können müssen, nicht zuletzt im Kommunikations-, Gesundheits- und Verkehrssektor, weiter zunehmen wird, ist Abhilfe dringend erforderlich. Es gilt auch, die Cyber-Sicherheit dieser Systeme Tool-gestützt zu verbessern.
Sicherheitslücken in Programmcode
Ziel von Cyberattacken ist es, Schwachstellen in Software zu finden, durch die unbeabsichtigtes Verhalten ausgelöst werden kann. Das kann etwa die Möglichkeit sein, auf dem betroffenen System vorhandene Befehle oder eigene Software remote auszuführen, eigentlich verschlüsselte Daten mitzulesen, oder Systeme abstürzen zu lassen. Eine Schwachstelle hat also einen Fehler (Defekt) als Ursache, der sich im System fortpflanzen können muss (Infektion) und dann zu unbeabsichtigtem Verhalten führt (Folge). Nur, wenn diese drei Faktoren zusammenkommen, ist eine Ausnutzung (Exploit) möglich.
Das MITRE hat 1999 das CWE-Projekt (Common Weakness Enumeration) gestartet, das bekannte Schwachstellen aufzählt. Es gehört zum Common Vulnerabilities and Exposures-(CVE) Programm, das eine Liste bekannter Schwachstellen und Anfälligkeiten publiziert. Diese systematisierte Liste warnt nicht nur vor verwundbarer Software, sondern hilft auch allgemein, verbreitete Sicherheitslücken besser zu verstehen. Die laut MITRE 10 gefährlichsten CWEs sind im Bild Tabelle aufgelistet [3]. NV steht für die relative Häufigkeit, CVSS für die Gefährlichkeit der Schwachstelle. Was ist Statische Code-Analyse?
Tabelle: Die laut MITRE 10 gefährlichsten CWEs sind in der Tabelle zu sehen.
(Bild: MathWorks)
Bei der statischen Code-Analyse (Static Application Security Testing, SAST) wird Software auf Fehler getestet, ohne sie auszuführen. Anstatt wie bei dynamischen Tests einzelne Testfälle an der laufenden Software abzuarbeiten, unterzieht man den Code einer analytischen Prüfung, die Entwurfsmängel und fehlerhafte Programmierstile sucht. Dazu werden u. a. Daten- und Kontrollflüsse verfolgt und sämtliche Ausführungspfade einer Software in Betracht gezogen.
Die Funktion von SAST-Tools geht damit über das schlichte Prüfen von Programmier-Richtlinien wie MISRA/CERT deutlich hinaus. Einige Tools sind sogar in der Lage, die Abwesenheit von Fehlern mit formalen Methoden zu beweisen [4], was einem erschöpfenden dynamischen Testen entspricht und damit in der Praxis normalerweise unerreichbar ist. Statische Analyse kann zudem bereits während der Entwicklung von Komponenten eingesetzt werden, ohne dass auf die Gesamtsoftware gewartet werden muss.
Der Möglichkeit, mit formalen Methoden sämtliche Schwachstellen zu finden, steht aber das Entscheidungsproblem entgegen: ein SAST-Tool kann entweder konsistent (sound) sein und keine False-Negatives ausgeben oder aber vollständig (complete) und keine False-Positives erzeugen [5].
Ausgereifte Werkzeuge geben nur wenige Warnungen aus und übersehen auch nur wenige Fehler. In der Praxis ist oft eine Kombination aus beiden Ansätzen sinnvoll. Einige Werkzeuge bieten sogar Modi an, bei denen man wählen kann, ob nur wahrscheinliche Fehler oder alle Fehler gemeldet werden sollen. Ein Beispiel dafür sind die Polyspace Static Code Analysis Tools [6]. Wir nehmen im Folgenden an, dass wir mit einem konsistenten Tool arbeiten, also eher zu viele Warnungen angezeigt, aber keine Fehler übersehen werden.
Was ein gutes SAST-Tool ausmacht
Abb. 1: CVE-2018-16602 ("DHCP-Leak in FreeRTOS", CWE-125) mit partiellem Angriffspfad.
(Bild: MathWorks)
Das richtige SAST-Tool hilft dem Entwickler interaktiv bei der Interpretation von Ergebnissen. Beispielsweise verweisen vom SAST-Tool angezeigte Warnungen verweisen oft auf eine Folge anstatt auf eine Ursache. Damit besteht die Gefahr, die Warnung nicht richtig zu interpretieren und als False-Positive abzutun. Nur, wenn die eigentliche Ursache einer Warnung bekannt ist, lässt sich entscheiden, ob sie ein Problem darstellt, wie es zu diesem Problem kommt und wie bzw. wo im Code man es beseitigen kann [7].
Die für den Entwickler wahrscheinlich wertvollste Eigenschaft ist , wenn sein SAST-Tool ihm aussagekräftige Kontextinformationen zur ausgegebenen Warnung bereitstellt. Dazu gehören unter anderem:
Stand: 08.12.2025
Es ist für uns eine Selbstverständlichkeit, dass wir verantwortungsvoll mit Ihren personenbezogenen Daten umgehen. Sofern wir personenbezogene Daten von Ihnen erheben, verarbeiten wir diese unter Beachtung der geltenden Datenschutzvorschriften. Detaillierte Informationen finden Sie in unserer Datenschutzerklärung.
Einwilligung in die Verwendung von Daten zu Werbezwecken
Ich bin damit einverstanden, dass die Vogel Communications Group GmbH & Co. KG, Max-Planckstr. 7-9, 97082 Würzburg einschließlich aller mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen (im weiteren: Vogel Communications Group) meine E-Mail-Adresse für die Zusendung von redaktionellen Newslettern nutzt. Auflistungen der jeweils zugehörigen Unternehmen können hier abgerufen werden.
Der Newsletterinhalt erstreckt sich dabei auf Produkte und Dienstleistungen aller zuvor genannten Unternehmen, darunter beispielsweise Fachzeitschriften und Fachbücher, Veranstaltungen und Messen sowie veranstaltungsbezogene Produkte und Dienstleistungen, Print- und Digital-Mediaangebote und Services wie weitere (redaktionelle) Newsletter, Gewinnspiele, Lead-Kampagnen, Marktforschung im Online- und Offline-Bereich, fachspezifische Webportale und E-Learning-Angebote. Wenn auch meine persönliche Telefonnummer erhoben wurde, darf diese für die Unterbreitung von Angeboten der vorgenannten Produkte und Dienstleistungen der vorgenannten Unternehmen und Marktforschung genutzt werden.
Meine Einwilligung umfasst zudem die Verarbeitung meiner E-Mail-Adresse und Telefonnummer für den Datenabgleich zu Marketingzwecken mit ausgewählten Werbepartnern wie z.B. LinkedIN, Google und Meta. Hierfür darf die Vogel Communications Group die genannten Daten gehasht an Werbepartner übermitteln, die diese Daten dann nutzen, um feststellen zu können, ob ich ebenfalls Mitglied auf den besagten Werbepartnerportalen bin. Die Vogel Communications Group nutzt diese Funktion zu Zwecken des Retargeting (Upselling, Crossselling und Kundenbindung), der Generierung von sog. Lookalike Audiences zur Neukundengewinnung und als Ausschlussgrundlage für laufende Werbekampagnen. Weitere Informationen kann ich dem Abschnitt „Datenabgleich zu Marketingzwecken“ in der Datenschutzerklärung entnehmen.
Falls ich im Internet auf Portalen der Vogel Communications Group einschließlich deren mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen geschützte Inhalte abrufe, muss ich mich mit weiteren Daten für den Zugang zu diesen Inhalten registrieren. Im Gegenzug für diesen gebührenlosen Zugang zu redaktionellen Inhalten dürfen meine Daten im Sinne dieser Einwilligung für die hier genannten Zwecke verwendet werden. Dies gilt nicht für den Datenabgleich zu Marketingzwecken.
Recht auf Widerruf
Mir ist bewusst, dass ich diese Einwilligung jederzeit für die Zukunft widerrufen kann. Durch meinen Widerruf wird die Rechtmäßigkeit der aufgrund meiner Einwilligung bis zum Widerruf erfolgten Verarbeitung nicht berührt. Um meinen Widerruf zu erklären, kann ich als eine Möglichkeit das unter https://contact.vogel.de abrufbare Kontaktformular nutzen. Sofern ich einzelne von mir abonnierte Newsletter nicht mehr erhalten möchte, kann ich darüber hinaus auch den am Ende eines Newsletters eingebundenen Abmeldelink anklicken. Weitere Informationen zu meinem Widerrufsrecht und dessen Ausübung sowie zu den Folgen meines Widerrufs finde ich in der Datenschutzerklärung, Abschnitt Redaktionelle Newsletter.
Aufrufkontext: Welcher Caller liefert die schädliche Eingabe (Kontextsensitivität)?
Kontrollfluss: Welche Entscheidungen wurden getroffen, um hierher zu gelangen (Pfadsensitivität)?
Variablenwerte: Was sind mögliche Werte von Array-indizierenden Variablen (CWE-787, CWE-125)? Werden Variablen vor deren Verwendung immer initialisiert (CWE-665)?
Pointer-Analyse: Sind sie initialisiert? Wohin zeigen sie, und wie groß sind die zugrunde liegenden Speicherbereiche (CWE-119)?
Taint-Analyse: Verwendet eine Funktion potenziell bösartige Benutzereingaben ohne vorherige Unbedenklichkeitsprüfung (CWE-20)?
Zugriffe auf Globals: Wo werden sie verwendet und wie (lesen/schreiben)? Gibt es mögliche Race Conditions?
Ausgefeiltere SAST-Tools wie Polyspace berechnen Event-Traces, die die o.g. Information in Dialogfeldern als Schrittfolge aufführen. Beim interaktiven Durcharbeiten dieser Schrittfolge lassen sich Variablen und Pointer verfolgen sowie Entscheidungen im Kontrollfluss nachvollziehen. Diese Event-Traces stellen einen Ausschnitt aus der Infektionskette dar. Es lässt sich aus ihnen oft mit wenig Aufwand ein Angriffspfad ableiten (Abb. 1). Ein gutes SAST-Tool sollte diese Fähigkeiten bieten, da sie das Debugging und die Fehlerbehebung erheblich beschleunigen kann.
Contracts und Assertions
Abb. 2: CVE-2018-16522 ("FreeRTOS DoS/RCE") aufgrund unsachgemäßer Initialisierung (CWE-665) am Ort der Folge. Ein Bugfix ist an dieser Stelle nicht möglich. Contracts identifizieren die eigentliche Ursache.
(Bild: MathWorks)
Eine bekannte Möglichkeit, unerwünschtes Verhalten zu identifizieren, sind Assertions und Contracts. Sie können aber auch die Ursachenforschung erleichtern und zudem Zugriff auf Informationen geben, die das SAST-Tool zwar kennt, aber nicht explizit anzeigt. Als Beispiel soll CVE-2018-16522 („FreeRTOS DoS/RCE“, CWE 665) dienen (Abb. 2). Die Sockets_Close-Funktion wird durch Userland-Code aufgerufen, wodurch pxContext beliebigen Inhalt haben kann. Die Dereferenzierung in Zeile 114 ist potenziell unsicher (orange), was aber an dieser Stelle nicht behoben werden kann. Annahmen zum Kontext sind nicht hilfreich, da dieser user-generiert ist. Stattdessen kann man eine Nachbedingung bei SOCKETS_SetSockOpt als Contract setzen:
Abbildung 3.
(Bild: MathWorks)
Dieser nur für das SAST gesetzte Contract checkt bei Zugriff auf das i-te Array-Element, ob dieses korrekt initialisiert wurde. Der Indexoperator ist hier fehlerhaft (orange Hervorhebung durch Polyspace), die Initialisierung kann also unvollständig sein.
Über die statische Analyse hinaus
I. Defensive Programmierung
Defensive Programmierpraktiken berücksichtigen explizit unvorhergesehene Umstände. In der Praxis wird dies durch umfangreiche Fehlerchecks von Zuständen, Call-Parametern und Rückgabewerten erreicht. Das hat zwei Vorteile:
Anders als Contracts, die immer noch verletzt werden können, lässt defensive Programmierung Infektionsketten abbrechen und sorgt damit für echte Robustheit.
Defensiver Programmcode wirkt als Filter für SAST-Tools. Diese prüfen sämtliche im Analysekontext erlaubten Programmzustände und stellen dabei fest, dass nicht erlaubte Werte gar nicht erst in kritische Bereiche propagiert werden.
II. Minimierung kontext-bezogener Annahmen
Martin Becker ist Senior Field Application Engineer für Verifikations- und Validierungsworkflows bei MathWorks.
(Bild: MathWorks)
Nimmt man bei einer Analyse einen genau bekannten Aufrufkontext an, kann das die Zahl der Warnungen reduzieren. Gleichzeitig steigt aber die Gefahr, neue Angriffsflächen zu schaffen, wenn diese Annahmen verletzt werden. Lässt man Annahmen weg oder reduziert sie in bereits vorhandener Software nach und nach, erhöht sich zwar zunächst die Zahl der Warnungen. Das zwingt aber die Entwickler defensiver zu programmieren. Die weitestgehende Vermeidung von Annahmen sorgt also für robustere Software.
Zwei entscheidende Vorteile kommen hinzu. Erstens wird die Analyse beschleunigt, da man nun mit kleineren Codepartitionen arbeiten kann und weniger Kontext benötigt wird. Dies trägt zudem zum frühzeitigen Testen von Code bei.
Dr. Jacob Palczynski arbeitet als Senior Training Engineer bei MathWorks.
(Bild: MathWorks)
Gleichzeitig bedeuten aber kleinere Partitionen auch geringere Komplexität für die Analyse. Es sind weniger Näherungen erforderlich, was präzisere und schnellere Ergebnisse bedeutet. Darüber hinaus wirkt hier übrigens auch der oben beschriebene Filtereffekt.
Polyspace [5] bietet dazu die Option „-unit-by-unit” und macht sich sämtliche hier beschriebenen Vorteile zunutze. Software wird auf diese Weise widerstandsfähiger gegen unvorhergesehene Schwachstellen, die nicht zuletzt auch durch Hardware entstehen können, wie in jüngster Zeit beobachtet werden konnte.
Fazit
Cyberattacken erfolgen über verschiedene Pfade und haben sehr unterschiedliche, teils fatale Folgen. Häufig ist eine Schwachstelle in der eingebetteten Software (mit-)verantwortlich. Wir haben gesehen, wie man selbst noch unbekannte Schwachstellen mittels statischer Code-Analyse systematisch auffinden und somit die Widerstandsfähigkeit gegen Cyberattacken deutlich verbessern kann.
A. Literatur
[1] The MITRE Corporation, "CVE Vulnerabilities by Date", 2020. [Online]. Abrufbar: https://www.cvedetails.com/browse-by-date.php.
[2] M. Beller, R. Bholanath, S. McIntosh and A. Zaidman, "Analyzing the state of static analysis: A large-scale evaluation in open-source software", in International Conference on Software Analysis, Evolution, and Reengineering, 2016.
[3] The MITRE Corporation, "2020 CWE Top 25 Most Dangerous Software Weaknesses", 2020. [Online]. Abrufbar: https://cwe.mitre.org/top25/archive/2020/2020_cwe_top25.html.
[4] The MathWorks Inc., "Polyspace Code Prover," 10 December 2020. [Online]. Abrufbar: https://www.polyspace.com.
[5] A. Turing, "On computable numbers, with an application to the Entscheidungsproblem", in Proceedings of the London mathematical society, 1937.
[7] J. Smith, B. Johnson, E. Murphy-Hill, B. Chu and H. Lipford, "Questions developers ask while diagnosing potential security vulnerabilities with static analysis", in Proceedings of Joint Meeting on Foundations of Software Engineering, 2015.
(mbf)
* Dr. Jacob Palczynski arbeitet als Senior Training Engineer bei MathWorks. Seit über 10 Jahren teilt er seine Expertise beim Einsatz statischer Codeanalyse und der Modellverifikation und -validierung mit Teams, die sicherheitskritische eingebettete Software entwickeln. Dabei arbeitet er auch mit Kunden zusammen, deren Entwicklungsprozesse Standards zur funktionalen Sicherheit wie ISO 26262 und DO178-C folgen. Vor seiner Tätigkeit bei MathWorks hat er als wissenschaftlicher Mitarbeiter am Lehrstuhl Informatik 11 der RWTH Aachen über die Anwendung formaler Methoden im Rahmen der Verifkation und Validierung eingebetteter Software geforscht und gelehrt.
* Martin Becker ist Senior Field Application Engineer für Verifikations- und Validierungsworkflows bei MathWorks. Er ist ein Verfechter von formalen Methoden und statischer Analyse und verfügt über mehr als 15 Jahre Erfahrung mit Embedded Systems. In seiner täglichen Arbeit unterstützt er Kunden aus einer Vielzahl von Branchen bei der effizienten Erstellung von Embedded-Software unter Einhaltung von Sicherheitsstandards. Vor seiner Tätigkeit bei MathWorks arbeitete er als Ingenieur für Luftfahrtkonzepte bei Airbus, als Forschungsingenieur bei Tata Consultancy Services und promovierte zum Dr.-Ing. auf dem Gebiet der Echtzeit-Computersysteme an der Technischen Universität München.