Sicherheitslücke im Linux-Tool beep als Einfallstor ins System

Autor / Redakteur: Mark Hermeling * / Stephan Augsten

Schadcode muss nicht zwingend über bekannte Programme in ein System vordringen, es genügt ein kleines Schlupfloch wie der aktuelle Bug im Linux-Tool beep.c. Solche Sicherheitslücken laufen oft unter dem Testing-Radar hindurch, lassen sich aber durchaus aufspüren.

Anbieter zum Thema

Die Warnung zur der Race Condition in beep.c erfolgt zunächst auf Ebene des Hauptprogramms.
Die Warnung zur der Race Condition in beep.c erfolgt zunächst auf Ebene des Hauptprogramms.
(Bild: GrammaTech)

„Es sind die Kleinigkeiten, wo sich das Naturell enthüllt.“ Sicher hatte der Genfer Philosoph Jean-Jacques Rousseau nicht die Software-Entwicklung im Hinterkopf, als er im 18. Jahrhundert dieses Bonmot von sich gab. Dennoch sollte es bei der Qualitätssicherung im Rahmen von Entwicklungsprojekten berücksichtigt werden. Denn gerade von kleinen Allerwelts-Tools, die seit Jahren genutzt werden und als vertrauenswürdig gelten, kann eine große Schadwirkung ausgehen.

Ein großer Teil des Codes aktueller Entwicklungsprojekte stammt von kommerziellen Zulieferern oder aus der Open-Source-Community. Das spart erheblich Ressourcen bei den Entwicklungs-Teams und beschleunigt die Time to Market. Damit einher geht jedoch auch ein gewisses Risiko: Entspricht der Code aus fremden Händen den eigenen Sicherheits- und Qualitätsanforderungen?

Bildergalerie

Wie schnell ein fehlerhaftes Tool das gesamte System gefährden kann, zeigt der Fall der jüngst beseitigten Lücke in beep. Beep ist ein kleines Kommandozeilen-Tool für Linux mit nicht einmal 250 Code-Zeilen. Es gibt einfach einen Ton auf dem PC-Lautsprecher aus, Frequenz und Dauer sind über Parameter beim Aufruf einstellbar.

Beep ist eines der zahllosen Tools, die irgendwie schon immer da waren und die einfach als gegeben und stabil angesehen werden. So weit, so unspektakulär. Doch in dem kleinen Code befindet sich bis Version 1.3.4 ein Bug, über den ein Angreifer privilegierte Benutzerrechte auf dem System erlangen kann (CVE-2018-0492).

Race Condition über Signal Handler

Voraussetzung für einen Exploit des Bugs ist, dass beep mit setuid root ausgeführt wird. Bei zahlreichen Linux-Distributionen wie etwa Debian war das der Fall, da das Tool einen Schreibzugriff auf die virtuelle Konsole benötigt. Beep parst einige Argumente der Kommandozeile und übergibt den Befehl zur Erzeugung eines Tons an die Systemfunktion ioctl().

Über einen Signal Handler werden Interrupts durch den Anwender erkannt. In diesem Signal Handler liegt die Ursache für die Race Condition. Die Folge: Ein Angreifer kann während der Ausführung eine beliebige Datei angeben, in die beep dann schreibt. Diese Datei kann ein symbolischer Link zu jeder beliebigen Datei sein – auch zu Systemdateien. Details zur Sicherheitslücke können hier nachgelesen werden: https://news.ycombinator.com/item?id=16762794

Generell sollte der Einsatz von Signal Handlern immer gut durchdacht werden. Für Entwickler ist es wichtig zu wissen, dass der Handler-Code jederzeit aufgerufen werden kann, auch mitten aus einem C-Statement heraus. So betrachtet stellen das eigentliche Programm und der Signal Handler zwei parallele, gleichzeitig ablaufende Threads dar. Der Kontext kann beliebig zwischen Hauptprogramm und Handler wechseln.

Damit kann es zu Race Conditions kommen, selbst wenn das Programm eigentlich nur als Single Thread angelegt ist: Eine Race Condition liegt dann vor, wenn zwei Funktionen auf dieselbe Variable schreibend zugreifen und kein Mechanismus wie Lock diese Zugriffe koordiniert.

Statische Analyse macht den Fehler sichtbar

Eine Analyse von beep.c mit CodeSonar von GrammaTech zeigt den Fehler: Das Data Race betrifft die geteilte Variable console_device. Das Hauptprogramm wird, wie im ersten Bild der Bildergalerie zu sehen, als erster Thread erkannt, der zweite Thread ist wie im darauffolgenden Bild zu sehen der Signal Handler. Beide greifen auf die Variable console_device zu, ohne dass ein Locking oder ein anderer Mechanismus zur Synchronisation vorhanden ist (im letzten Bild zu sehen).

Das Beispiel zeigt, wie wichtig auch die Überprüfung kleinster Code-Bausteine ist. In umfangreichen Entwicklungsprojekten geschieht es schnell, dass diese vermeintlich bekannten und sicheren Programme durch die Filter der Qualitätssicherung fallen. Ob ein Fehler wie bei beep im Rahmen des Testings gefunden werden kann, ist zweifelhaft. Denn der Bug führt zu keiner Fehlfunktion, die sich in den Test-Cases niederschlagen würde.

Mark Hermeling
Mark Hermeling
(Bild: Grammatech)

So konnte die Anfälligkeit einige Jahre unbemerkt bleiben – und das, obwohl der Quellcode als Open Source vorliegt, überschaubar und zudem gut dokumentiert ist. Statische Analyse, die den Code in ein Modell überführt und auf dieser Basis alle möglichen Daten- und Steuerströme durchleuchtet, hilft, auch solche Schwachstellen aufzudecken. Bevor die Software ausgeliefert wird.

* Mark Hermeling ist Senior Director Product Marketing bei GrammaTech, Inc.

(ID:45279942)