Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
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
Herramientas/GitHubGitHub/aleister1102/kibana-prototype-pollusion
Análisis de VulnerabilidadesAnálisis de CódigoExplotaciónExplotación de Aplicaciones WebPapers e InvestigaciónAprendizaje y Educación
GitHubaleister1102/kibana-prototype-pollusion

kibana-prototype-pollusion

PoC y análisis para Kibana Prototype Pollution RCE (CVE-2019-7609).

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
Ver Repositorio
hace 2 añosAún no revisado

CVE-2019-7609

Las versiones de Kibana anteriores a 5.6.15 y 6.6.1 contienen una falla de ejecución de código arbitrario en el visualizador Timelion. Un atacante con acceso a la aplicación Timelion podría enviar una solicitud que intente ejecutar código JavaScript. Esto podría permitir que un atacante ejecute comandos arbitrarios con los permisos del proceso de Kibana en el sistema host.

CVSS:

cvss

Blog: https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/

Payload: https://github.com/mpgn/CVE-2019-7609

Objetivo

Configuración:

  • Docker: https://www.elastic.co/guide/en/kibana/8.14/docker.html
  • Docker Compose

Uso:

  • Kibana: https://www.elastic.co/guide/en/kibana/current/development-getting-started.html
  • Timelion: https://www.elastic.co/guide/en/kibana/5.4/timelion.html

Análisis

Timelion

Después de analizar la hoja:

alt text

Después del preprocesamiento de la hoja, tenemos un objeto queries:

alt text

Luego, recorremos el array queries (que se convierte en un array mediante el método values) y pasamos a invoke el query.function y query.arguments para invocar la función.

En la función invoke, primero obtenemos la definición de la función según su nombre (query.function):

alt text

Esta definición de función incluye tres tipos de función: fn, originalFn y timelionFn. Luego, recorre los args (que son query.arguments) y resuelve los argumentos:

alt text

En este caso, el argumento en args es un objeto con tipo 'literal', por lo que simplemente devuelve el valor literal:

alt text

En realidad, el valor está envuelto en una promesa.

alt text

El argumento indexado es un argumento con un objeto byName que tiene un array q en su interior:

alt text

Después, la función invoke llamará a functionDef.fn, que es una función de la clase Timelion, con todos los argumentos indexados:

alt text

La función fn llamará a originalFn, que proviene de config.fn, donde config es tlConfig. Y esa función es fn de la clase Datasource extends Timelion:

alt text

Como podemos ver, llama a otro originalFn llamado esFn, que devuelve un objeto seriesList:

alt text

Esa función se usa para "extraer datos de una instancia de Elasticsearch" llamando a la función callWithRequest.

El seriesList se ve así en Datasource.fn:

alt text

Y se ve así en Timelion.fn:

alt text

Después del preprocesamiento de la hoja, la lista de cadenas es:

alt text

Y el código llamará a resolveChainList para resolver la lista de cadenas:

alt text

Cada cadena se asignará a una Promise que devuelve una función que invoke con 'first' como fnName y la propia cadena como args.

La definición de la función se obtiene nuevamente por el nombre:

alt text

Esta vez, resolveArguments recibe args como un array y llama a resolveArguments recursivamente para resolver cada argumento. Pero solo tenemos un argumento con índice 0. Y ese argumento es un objeto con type == chain.

Entonces, en el caso del switch, llamará a la función invokeChain y le pasará el objeto de la cadena:

alt text

Dentro de la cadena de invocación, se aplicará shift al array chain. La función shift devolverá el elemento eliminado, por lo que link será el objeto es:

alt text

Debido a que el tipo de es no es 'chain' (es 'function') y !result es verdadero, el código llama a la función invoke con 'first' como fnName y el objeto es como args:

Esta vez, el procedimiento es el mismo que el anterior, así que pasamos a la llamada de invokeChain con link como objeto props:

alt text

De nuevo, el código llama a la función invoke con 'first' como fnName y el objeto props como args:

alt text

El originalFn de props ahora es firstFn en lugar de fn como es, y solo acepta un argumento:

alt text

Esa función original eventualmente llamará a la vulnerable función unflatten. En realidad, primero llamará al fn de Timelion. Luego, fn llamará al originalFn de props:

alt text

El firstFn de props omitirá las propiedades inputSeries y global en el objeto byName de args:

alt text

Por lo tanto, el data pasado a unflatten será:

root@kitploit:~
{
    label.__proto__.env.AAA: "a"
}

Prueba:

alt text

Unflatten

Usa props(label.__proto__.env.AAA="a"). El data se verá así:

alt text

En la primera iteración, prop = '' no existe, por lo que asignará cur[''] = {}. Esto significa que result también tendrá una propiedad llamada '' con un objeto vacío como valor. Después de eso, cur se asigna con {}, que es el valor de retorno de la asignación anterior (cur y cur[prop] apuntan al mismo objeto):

alt text

Ahora, prop se convertirá en 'label':

alt text

Igual que antes, result tendrá la propiedad 'label' y prop se convertirá en __proto__:

alt text

Con la tercera iteración, cur se convertirá en su prototipo, ya que __proto__ siempre existe en todos los objetos:

alt text

Después de eso, prop se convierte en env.

Entonces, dado que cur apunta a Object.prototype, agregará env a Object.prototype como un objeto vacío y cur también hará referencia a env dentro de Object.prototype.env.

alt text

Después de eso, el bucle saldrá y cur[prop] = data[p] será equivalente a env[AAA] = 'a'.

alt text

El Object.prototype está contaminado con env:

alt text

Canvas

La función fork devuelve un ChildProcess que se puede usar para invocar spawn

Al invocar la función fork, cambiamos el puerto a 9669 (otro puerto) y entonces podemos depurar el proceso principal con normalidad:

alt text

Simulamos el Object.prototype contaminado y saltamos a justo antes del bucle:

alt text

Como podemos ver, env es equivalente a { AAA: 'a' } debido a la contaminación de prototipos. Más específicamente, env se asigna a options.env. Y options no define esa propiedad, por lo que usará el valor de su prototipo.

Después del bucle:

alt text

De algún modo, con las variables de entorno no válidas (AAA=a, env=[Object object]), canvas no puede crear un nuevo socket:

alt text

Pero el proceso hijo aún puede crearse:

alt text

Con el flujo normal, se creará una nueva conexión WebSocket:

alt text

Ahora probemos con el payload y saltemos a normalizeSpawnArguments:

alt text

Como podemos ver, la traza de pila es la misma.

Pero el env está contaminado:

alt text

¡Voilà!

Los envPairs después del bucle:

alt text

Y obtuvimos la reverse shell:

alt text

Spawn

Después de llamar a normalizeSpawnArguments en la función spawn:

alt text

Como podemos ver, envPairs contiene nuestro payload. Además, después de eso, spawn llamará a la función spawn dentro de internal/child_process.js:

alt text

La variable options se pasará a this._handle.spawn:

alt text

Donde this._handle es un manejador de un proceso:

alt text

Parche

root@kitploit:~
From 3377f813a5d96ff466bdf7343ce161de24830ed4 Mon Sep 17 00:00:00 2001
From: ppisljar <[email protected]>
Date: Wed, 16 Jan 2019 06:01:20 -0800
Subject: [PATCH] fixes

---
 .../core_plugins/timelion/server/series_functions/props.js      | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/legacy/core_plugins/timelion/server/series_functions/props.js b/src/legacy/core_plugins/timelion/server/series_functions/props.js
index 81b74901d4db..80e9cafd6712 100644
--- a/src/legacy/core_plugins/timelion/server/series_functions/props.js
+++ b/src/legacy/core_plugins/timelion/server/series_functions/props.js
@@ -32,7 +32,7 @@ function unflatten(data) {
     let prop = '';
     let m;
     while (m = regex.exec(p)) {
-      cur = cur[prop] || (cur[prop] = (m[2] ? [] : {}));
+      cur = (cur.hasOwnProperty(prop) && cur[prop]) || (cur[prop] = (m[2] ? [] : {}));
       prop = m[2] || m[1];
     }
     cur[prop] = data[p];
Descargar herramienta