Unsachgemäße Neutralisierung von Argumenttrennzeichen in einem Befehl ('Argument Injection')

Beschreibung

Unsachgemäße Neutralisierung von Argumenttrennzeichen in einem Befehl, allgemein bekannt als Argument Injection, tritt auf, wenn Software einen Befehlsstring unter Verwendung von Eingaben einer vorgelagerten Komponente konstruiert, aber Sonderzeichen, die modifizieren können, wie Argumente geparst werden, nicht ordnungsgemäß neutralisiert. Anders als Command Injection, die völlig neue Befehle einführt, manipuliert Argument Injection die Argumente, die an einen bestehenden Befehl übergeben werden, und ändert potenziell dessen Verhalten auf unbeabsichtigte Weise. Angreifer können zusätzliche Argumente einschleusen, vorhandene Flags überschreiben, bösartige Dateipfade angeben oder das Befehlsverhalten ändern, indem sie ausnutzen, wie Shells und Programme Argumenttrennzeichen wie Leerzeichen, Anführungszeichen, Bindestriche und Gleichheitszeichen parsen.

Risiko

Argument Injection kann je nach Fähigkeiten des Zielbefehls genauso gefährlich sein wie vollständige Command Injection. Viele Systemdienstprogramme akzeptieren mächtige Argumente: curl kann Dateien hochladen, tar kann beliebige Dateien überschreiben, find kann Befehle ausführen, und git kann beliebige Skripte durch Hooks ausführen. Angreifer können diese Fähigkeiten nutzen, indem sie Argumente einschleusen, selbst wenn der Basisbefehl fest ist. Die Schwachstelle wird oft übersehen, weil Entwickler sich auf die Verhinderung von Shell-Metazeichen konzentrieren, während sie ignorieren, dass das Argument-Parsing selbst ausgenutzt werden kann. Dateinamenbasierte Angriffe sind besonders effektiv: eine Datei namens --help oder -rf kann unerwartetes Verhalten verursachen, wenn sie an Befehle übergeben wird.

Lösung

Übergeben Sie Argumente als separate Array-Elemente, anstatt Befehlsstrings zu konstruieren. Verwenden Sie APIs, die Argument-Arrays akzeptieren (z.B. Pythons subprocess mit Listen-Argumenten, PHPs proc_open mit Arguments-Array). Wenn die Konstruktion von Argument-Strings unvermeidbar ist, validieren Sie, dass Eingaben erwarteten Mustern entsprechen, mit strikten Allowlists. Für Dateinamen stellen Sie benutzergesteuerten Pfaden ./ voran, um die Interpretation als Argumente zu verhindern (z.B. ./--filename). Escapen oder lehnen Sie Eingaben ab, die Zeichen enthalten, die als Argumenttrennzeichen oder Flag-Indikatoren interpretiert werden könnten. Berücksichtigen Sie, ob der aufgerufene Befehl gefährliche Optionen hat, und schränken Sie Eingaben entsprechend ein.

Häufige Auswirkungen

AuswirkungDetails
VertraulichkeitBereich: Vertraulichkeit

Eingeschleuste Argumente können Befehle veranlassen, sensible Informationen auszugeben, beliebige Dateien zu lesen oder Daten an angreifergesteuerte Ziele zu übertragen.
IntegritätBereich: Integrität

Argumente können Befehle anweisen, Dateien zu schreiben, zu modifizieren oder zu löschen, Konfigurationen zu ändern oder den Systemzustand auf unbeabsichtigte Weise zu ändern.
VerfügbarkeitBereich: Verfügbarkeit

Bösartige Argumente können Befehle veranlassen, übermäßige Ressourcen zu verbrauchen, unbegrenzt zu laufen oder kritische Daten zu beschädigen.
ZugriffskontrolleBereich: Zugriffskontrolle

Einige Befehle akzeptieren Argumente, die zusätzlichen Code oder Skripte ausführen und Privilegieneskalation oder unbefugten Zugriff ermöglichen.

Beispielcode + Lösungscode

Anfälliger Code

import subprocess
import os

# ANFÄLLIG: Benutzereingabe im Argument-String
def compress_file(filename):
    # Angreifer-Eingabe: "--help" oder "-rf /etc" oder "; rm -rf /"
    command = f"tar -czf backup.tar.gz {filename}"
    os.system(command)

# ANFÄLLIG: Dateiname kann als Argument interpretiert werden
def list_file(user_filename):
    # Wenn Dateiname "--help" ist, zeigt tar Hilfe anstatt Fehler
    # Wenn Dateiname "-rf" ist, könnte es gefährlich sein
    subprocess.run(f"ls {user_filename}", shell=True)

# ANFÄLLIG: Git mit benutzergesteuertem Branch-Namen
def checkout_branch(branch):
    # Angreifer: "--upload-pack=malicious_script"
    subprocess.run(f"git fetch origin {branch}", shell=True)

Korrigierter Code

import subprocess
import re
import shlex

# SICHER: Argumente als Listen-Elemente, nicht String
def compress_file(filename):
    # Dateinamenformat validieren
    if not re.match(r'^[\w\-./]+$', filename):
        raise ValueError("Ungültiger Dateiname")

    # Mit ./ voranstellen um Interpretation als Argument zu verhindern
    safe_filename = f"./{filename}" if not filename.startswith('/') else filename

    # Argumentliste verwenden - keine Shell-Interpretation
    subprocess.run(
        ['tar', '-czf', 'backup.tar.gz', safe_filename],
        check=True
    )

# SICHER: Argument-Array verhindert Injection
def list_file(user_filename):
    # Validieren und bereinigen
    if not user_filename or '..' in user_filename:
        raise ValueError("Ungültiger Dateiname")

    # -- verwenden um Ende der Optionen zu signalisieren
    subprocess.run(['ls', '--', user_filename], check=True)

# SICHER: Strikte Allowlist-Validierung
def checkout_branch(branch):
    # Nur gültige Branch-Name-Zeichen erlauben
    if not re.match(r'^[a-zA-Z0-9_\-/]+$', branch):
        raise ValueError("Ungültiger Branch-Name")

    if branch.startswith('-'):
        raise ValueError("Branch-Name darf nicht mit Bindestrich beginnen")

    subprocess.run(['git', 'fetch', 'origin', branch], check=True)

# SICHER: -- Argument-Trenner verwenden
def safe_command_with_filename(filename):
    # Das -- signalisiert Ende der Optionen für viele Unix-Befehle
    subprocess.run(['rm', '--', filename], check=True)

Ausgenutzt in der Praxis

Git Argument Injection-Angriffe (Verschiedene, 2017-heute)

Mehrere Git-bezogene Argument-Injection-Schwachstellen wurden entdeckt und ausgenutzt. CVE-2017-1000117 ermöglichte Angreifern, Argumente durch bösartige Repository-URLs einzuschleusen und beliebigen Code über Git-Hooks auszuführen. Ähnliche Schwachstellen in der Git-Submodul-Behandlung ermöglichten Code-Ausführung durch manipulierte Repository-Konfigurationen.

Mercurial HG Argument Injection (Mercurial, 2017)

CVE-2017-9462 ermöglichte Argument Injection in Mercurials hg serve-Befehl und ermöglichte Remote-Code-Ausführung durch speziell gestaltete Repository-Namen, die bösartige Argumente einschleusten.


Tools zum Testen/Ausnutzen

  • Commix — Command-Injection-Tool, das Argument-Injection-Payload-Testfähigkeiten enthält.

  • Custom Wordlists — Argument-Injection-Payloads für verschiedene Befehle und Kontexte.


CVE-Beispiele

  • CVE-2017-1000117 — Git beliebige Code-Ausführung über bösartige SSH-URLs mit Argument Injection.

  • CVE-2022-24765 — Git für Windows Argument Injection ermöglicht beliebige Befehlsausführung.

  • CVE-2023-29007 — Git Symbolic Ref Argument Injection führt zu beliebigem Lesen von Dateien.


Referenzen

  1. MITRE. "CWE-88: Improper Neutralization of Argument Delimiters in a Command." https://cwe.mitre.org/data/definitions/88.html

  2. OWASP. "OS Command Injection Defense Cheat Sheet." https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html