Skip to content
KitploitKITPLOIT
FerramentasBlog
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
kibana-prototype-pollusion — PoC e análise para Kibana Prototype Pollution RCE (CVE-2019-7609). | Kitploit
Ferramentas/GitHubGitHub/aleister1102/kibana-prototype-pollusion
Análise de VulnerabilidadesAnálise de CódigoExploraçãoExploração de Aplicações WebPapers e PesquisaAprendizado e Educação
GitHubaleister1102/kibana-prototype-pollusion

kibana-prototype-pollusion

PoC e análise para Kibana Prototype Pollution RCE (CVE-2019-7609).

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
Ver Repositório
há 2 anosAinda não revisado

CVE-2019-7609

As versões do Kibana anteriores a 5.6.15 e 6.6.1 contêm uma falha de execução arbitrária de código no visualizador Timelion. Um atacante com acesso ao aplicativo Timelion poderia enviar uma solicitação que tentará executar código JavaScript. Isso possivelmente pode levar um atacante a executar comandos arbitrários com as permissões do processo Kibana no sistema host.

CVSS:

cvss

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

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

Target

Setup:

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

Using:

  • 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

Analysis

Timelion

After parsing sheet:

alt text

After pre-process sheet, we have a queries object:

alt text

Then, we loop over the queries array (which is converted to an array by using values method) and pass into invoke the query.function and query.arguments for invoking the function.

In the invoke function, first we get the definition of the function based on its name (query.function):

alt text

This function definition includes three types of function: fn, originalFn and timelionFn. Then, it loop over the args (which is query.arguments) and resolve arguments:

alt text

In this case, the argument in args is an object with 'literal' type so it just return the literal value:

alt text

Actually, the value is wrapped in a promise.

alt text

The indexed argument is an argument with byName object that has q array inside it:

alt text

After that, the invoke function will call functionDef.fn, which is a function of the Timelion class, with all of the indexed arguments:

alt text

The fn function will call the originalFn, which comes from config.fn where config is tlConfig. And that function is fn of Datasource extends Timelion class:

alt text

As we can see, it calls to another originalFn named esFn which returns a seriesList object:

alt text

That function is used for "Pull data from an elasticsearch instance" by calling callWithRequest function.

The seriesList looks like this in Datasource.fn:

alt text

And it looks like this in Timelion.fn:

alt text

After pre-process sheet, the chain list is:

alt text

And the code will call the resolveChainList for resolving the chain list:

alt text

Each chain will be mapped to a Promise that is returned from a function that invoke with 'first' as fnName and the chain itself as args.

The function definition is get by the name again:

alt text

This time, resolveArguments receive args as an array and it will call the resolveArguments recursively for resolving each argument. But, we have only one argument with index 0. And that argument is an object with type == chain.

So, in the switch case, it will call the invokeChain function and pass the chain object into it:

alt text

Inside the invoke chain, it will shift the chain array. The shift function will return the removed element so link will be es object:

alt text

Because the type of es is not 'chain' (it is 'function') and !result is truthy, the code calls the invoke function with 'first' as fnName the es object as args:

This time, the procedure is the same as above so skip to the call of invokeChain with link is props object:

alt text

Again, the code calls the invoke function with 'first' as fnName the props object as args:

alt text

The originalFn of props now is firstFn instead of fn like es and only accept one argument:

alt text

That original function is will eventually call the vulnerable unflatten function. Actually, it will call the fn of Timelion first. Then fn will call the originalFn of props:

alt text

The firstFn of props will omit the inputSeries and global properties in byName object of args:

alt text

So the data passed into unflatten will be:

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

Proof:

alt text

Unflatten

Use props(label.__proto__.env.AAA="a"). The data will look like this:

alt text

At the first iteration, prop = '' is not exist, it will assign cur[''] = {}. This means, the result will also have a property named '' with an empty object as value. After that, cur is assigned with {}, which is the return value of the previous assignment (cur and cur[prop] both point to the same object):

alt text

Now, prop will become 'label':

alt text

Same as before, result will have 'label' property and prop will become __proto__:

alt text

With the third iteration, cur will be come its prototype as __proto__ always exist in every object:

alt text

After that, prop becomes env.

Then, due to cur is point to Object.prototype, it will add env to the Object.prototype as an empty object and cur also reference to env inside Object.prototype.env.

alt text

After that, the loop will exit and the cur[prop] = data[p] will be equivalent to env[AAA] = 'a'.

alt text

The Object.prototype is polluted with env:

alt text

Canvas

The fork function return a ChildProcess that can be used to invoke spawn

Change port when invoke fork function to 9669 (another port) and then we can debug the main process normally:

alt text

Simulate the polluted Object.prototype and jump to before the loop:

alt text

As we can see, env is equivalent to { AAA: 'a' } due to prototype pollution. More specific, env is assigned to options.env. And options does not define that property so it will use the value of its prototype.

After the loop:

alt text

Somehow, with the invalid environment variables (AAA=a, env=[Object object]), canvas can not create a new socket:

alt text

But the child process still can be created:

alt text

With normal flow, it will create a new WebSocket connection:

alt text

Now try with the payload and jump in the normalizeSpawnArguments:

alt text

As we can see, the stack trace is the same.

But, the env is polluted:

alt text

Voila!

The envPairs after the loop:

alt text

And we got the reverse shell:

alt text

Spawn

After calling to normalizeSpawnArguments in spawn function:

alt text

As we can see, the envPairs contains our payload. Also, after that, spawn will call to the spawn function inside internal/child_process.js:

alt text

The options variable will be passed into this._handle.spawn:

alt text

Where this._handle is a handle to a process:

alt text

Patch

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];
Baixar ferramenta