Befehlsinjection: So funktioniert sie, welche Risiken sie birgt und wie Sie sie verhindern
25. November 2020
0 Min. LesezeitBei Befehlsinjection-Angriffen – auch als Betriebssystem-Befehlsinjection bezeichnet – wird eine Programmierlücke ausgenutzt, um Systembefehle ohne ausreichende Eingabevalidierung, Escaping oder Bereinigung auszuführen. Dadurch können Angreifer beliebige Befehle ausführen.
Welche Risiken bergen Befehlsinjections?
Je nach Einrichtung der Anwendung und Konfiguration des Prozesses, der sie ausführt, kann eine Befehlsinjection-Schwachstelle zu einer Rechteausweitung des Prozesses führen oder eine Remote-Reverse-Shell starten, über die eine böswillige Partei uneingeschränkt interagieren kann.
Wie funktionieren Befehlsinjection-Angriffe?
Um Programmierfehler im Zusammenhang mit Betriebssystem-Befehlsinjection-Angriffen zu verstehen, sehen wir uns verschiedene Befehlsinjection-Schwachstellen an, die in Node.js-basierten Anwendungen entdeckt wurden.
systeminformation ist eine Bibliothek für Betriebssysteminformationen, die wöchentlich mehr als 500.000 Downloads verzeichnet, regelmäßig gewartet wird (Commits) und von einer Community unterstützt wird. Das sehen wir auf der Seite zum Abhängigkeitszustand von Snyk Advisor:

Allerdings sind alle Versionen von system information vor Version 4.27.11 anfällig für Betriebssystem-Befehlsinjection, da die Bibliothek mehrere anfällige Methoden bereitstellt.
Sehen wir uns den Code der anfälligen Funktion inetChecksite() an. Erkennen Sie die Sicherheitslücke in diesem Code, die ein Beispiel für Befehlsinjection zeigt?
Aus diesem Codeausschnitt lassen sich mehrere Schlüsse ziehen:
Ein
url-Parameter wird bereinigt. Vielleicht kann ich die Bereinigungsfunktionen mit etwas umgehen, das der Autor nicht bedacht hat?Es wird eine unsichere API zum Starten von Betriebssystemprozessen verwendet:
exec()fügt Befehle und ihre Argumente zu einem einzigen Shell-Befehl zusammen, der dann ausgeführt wird. Deshalb musste der Autor auch eine eigene Bereinigung von Befehlszeilenargumenten implementieren.
Die Variable urlSanitized wird mit den an die CLI übergebenen Argumenten verkettet.
Genau darin liegt die Sicherheitslücke: Die Variable urlSanitized wird verkettet. Der mit der Variable cmd referenzierte Befehl ist das Netzwerkprogramm curl. Was wäre, wenn wir curl einfach ein Befehlsargument als URL übergeben könnten?
Ein Befehlsinjection-Angriff lässt sich mit dem folgenden Proof of Concept versuchen. Dabei wird die URL an die anfällige Funktion übergeben, wie im ersten Argument der Funktion inetChecksite() zu sehen ist. Das folgende Beispiel zeigt eine Befehlsinjection:
Das funktioniert hier allerdings nicht, weil dieses npm-Paket gefährliche Benutzereingaben wie das Semikolon (;) bereinigt.
Befehlszeilenargumente benötigen jedoch meist keine Sonderzeichen. Wir könnten eine URL als Benutzereingabe übergeben, etwa https://snyk.io -o hihi. Sie enthält ein Leerzeichen und verkettet das Positionsargument -o von curl, das das Ergebnis der Website in einer von uns kontrollierten Datei speichert.
Hier ist ein weiteres Beispiel für Befehlsinjection, das zeigt, wie ein solcher Angriff ablaufen kann und mit einer anfälligen Version von systeminformation@4.27.10 tatsächlich funktioniert:
Dieser Commit hat die Bereinigung verbessert, um solche Befehlsinjection-Schwachstellen weiter einzudämmen:

Spickzettel zu Befehlsinjection
Aus weiteren Beispielen für Befehlsinjection können wir viel lernen. Darin haben wir Sicherheitslücken in Open-Source-Paketen und die jeweiligen Gegenmaßnahmen identifiziert, etwa bei den Schwachstellen hier und hier.
Mit den folgenden Maßnahmen können Sie Befehlsinjection-Angriffe verhindern:
Übergeben Sie keine Benutzereingaben an Befehle, die Ihre Anwendung ausführt.
Verwenden Sie zum Ausführen von Befehlen ausschließlich sichere APIs wie execFile(). Anders als andere APIs erwartet sie den Befehl als ersten Parameter und ein Array mit Befehlszeilenargumenten als zweiten Funktionsparameter. So wird sichergestellt, dass der Befehl selbst ein gültiges Programm sein muss und nicht aus gefährlichen Eingaben besteht.
Achten Sie bei der Verwendung von
execFile()darauf, dass der Benutzer den Programmnamen nicht kontrollieren kann. Stellen Sie außerdem sicher, dass Sie Benutzereingaben den Befehlsargumenten zuordnen, statt sie unverändert an die Programmausführung weiterzugeben.Prüfen Sie vorsichtshalber auch, ob Benutzereingaben dem erwarteten Format entsprechen. Erwartet ein Funktionsparameter beispielsweise eine URL, sollten Sie validieren, ob die Eingabe eine gültige URL ist. So hätte sich die oben erwähnte Befehlsinjection-Schwachstelle im npm-Paket systeminformation verhindern lassen.
Befehlsinjection-Angriffe in den OWASP Top 10
Um zu zeigen, wie verbreitet Betriebssystem-Befehlsinjection-Angriffe sind, habe ich alle öffentlich bekannten Sicherheitslücken aufgerufen, die das Snyk Security Team für Oktober 2020 veröffentlicht hat, und sie nach dem JavaScript-Ökosystem auf npm gefiltert. Wie Sie sehen, wurden allein in der letzten Oktoberwoche zahlreiche Sicherheitslücken durch Command injection in npm-Paketen entdeckt.

Zusammenfassend lässt sich sagen: Befehlsinjection-Schwachstellen sind häufiger, als Sie vielleicht denken. Kein Wunder also, dass Injection-Angriffe einen berüchtigten Platz in den OWASP Top 10 der Web-Sicherheitsrisiken haben – sie sind weit verbreitet und treten in vielen Formen auf, etwa als SQL-Injection-Angriffe. Ich empfehle Ihnen dringend, Ihre Git-Repositories mit Snyk zu verbinden, um sie auf Befehlsinjection-Schwachstellen zu testen und diese zu beheben. Vielleicht findet Snyk auch noch weitere. Snyk ist kostenlos und Ihre Projekte sind im Handumdrehen überwacht!
Starten Sie mit Capture the Flag
Erfahren Sie in unserem virtuellen On-Demand-Workshop für Einsteiger, wie Sie Capture-the-Flag-Herausforderungen lösen.


