Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
kibana-prototype-pollusion — PoC e analisi per Kibana Prototype Pollution RCE (CVE-2019-7609). | Kitploit
Strumenti/GitHubGitHub/aleister1102/kibana-prototype-pollusion
Analisi delle VulnerabilitàAnalisi del CodiceExploitSfruttamento di Applicazioni WebPaper e RicercaApprendimento e Formazione
GitHubaleister1102/kibana-prototype-pollusion

kibana-prototype-pollusion

PoC e analisi per Kibana Prototype Pollution RCE (CVE-2019-7609).

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi
Vedi Repository
2 anni faNon ancora revisionato

CVE-2019-7609

Le versioni di Kibana precedenti alla 5.6.15 e alla 6.6.1 contengono una vulnerabilità di esecuzione di codice arbitrario nel visualizzatore Timelion. Un attaccante con accesso all'applicazione Timelion potrebbe inviare una richiesta che tenta di eseguire codice JavaScript. Ciò potrebbe potenzialmente consentire a un attaccante di eseguire comandi arbitrari con i permessi del processo Kibana sul 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

Configurazione:

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

Utilizzo:

  • 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

Analisi

Timelion

Dopo il parsing del foglio:

alt text

Dopo la pre-elaborazione del foglio, abbiamo un oggetto queries:

alt text

Quindi, iteriamo sull'array queries (che viene convertito in un array usando il metodo values) e passiamo a invoke il query.function e query.arguments per invocare la funzione.

Nella funzione invoke, prima otteniamo la definizione della funzione in base al suo nome (query.function):

alt text

Questa definizione di funzione include tre tipi di funzione: fn, originalFn e timelionFn. Poi, itera sugli args (che sono query.arguments) e risolve gli argomenti:

alt text

In questo caso, l'argomento in args è un oggetto con tipo 'literal', quindi restituisce semplicemente il valore letterale:

alt text

In realtà, il valore è avvolto in una promise.

alt text

L'argomento indicizzato è un argomento con un oggetto byName che contiene un array q al suo interno:

alt text

Dopodiché, la funzione invoke chiamerà functionDef.fn, che è una funzione della classe Timelion, con tutti gli argomenti indicizzati:

alt text

La funzione fn chiamerà originalFn, che proviene da config.fn dove config è tlConfig. E quella funzione è fn della classe Datasource extends Timelion:

alt text

Come possiamo vedere, chiama un altro originalFn chiamato esFn che restituisce un oggetto seriesList:

alt text

Quella funzione è usata per "Estrarre dati da un'istanza Elasticsearch" chiamando la funzione callWithRequest.

Il seriesList appare così in Datasource.fn:

alt text

E appare così in Timelion.fn:

alt text

Dopo la pre-elaborazione del foglio, la lista delle catene è:

alt text

E il codice chiamerà resolveChainList per risolvere la lista delle catene:

alt text

Ogni catena viene mappata a una Promise restituita da una funzione invocata con 'first' come fnName e la catena stessa come args.

La definizione della funzione viene ottenuta di nuovo tramite il nome:

alt text

Questa volta, resolveArguments riceve args come array e chiamerà resolveArguments ricorsivamente per risolvere ogni argomento. Ma abbiamo un solo argomento con indice 0. E quell'argomento è un oggetto con type == chain.

Quindi, nel ramo switch, chiamerà la funzione invokeChain e passerà l'oggetto catena al suo interno:

alt text

All'interno della catena di invocazione, eseguirà shift sull'array chain. La funzione shift restituirà l'elemento rimosso, quindi link sarà l'oggetto es:

alt text

Poiché il tipo di es non è 'chain' (è 'function') e !result è truthy, il codice chiama la funzione invoke con 'first' come fnName e l'oggetto es come args:

Questa volta, la procedura è la stessa di sopra, quindi saltiamo alla chiamata di invokeChain in cui link è l'oggetto props:

alt text

Ancora una volta, il codice chiama la funzione invoke con 'first' come fnName e l'oggetto props come args:

alt text

L'originalFn di props ora è firstFn invece di fn come per es e accetta solo un argomento:

alt text

Quella funzione originale finirà per chiamare la vulnerabile funzione unflatten. In realtà, chiamerà prima la fn di Timelion. Poi fn chiamerà l'originalFn di props:

alt text

La firstFn di props ometterà le proprietà inputSeries e global nell'oggetto byName di args:

alt text

Quindi il valore data passato a unflatten sarà:

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

Prova:

alt text

Unflatten

Usa props(label.__proto__.env.AAA="a"). Il data apparirà così:

alt text

Alla prima iterazione, prop = '' non esiste; assegnerà cur[''] = {}. Ciò significa che anche result avrà una proprietà chiamata '' con un oggetto vuoto come valore. Dopodiché, cur viene assegnato a {}, che è il valore di ritorno dell'assegnazione precedente (cur e cur[prop] puntano entrambi allo stesso oggetto):

alt text

Ora, prop diventerà 'label':

alt text

Come prima, result avrà la proprietà 'label' e prop diventerà __proto__:

alt text

Con la terza iterazione, cur diventerà il suo prototipo poiché __proto__ esiste sempre in ogni oggetto:

alt text

Dopodiché, prop diventa env.

Quindi, poiché cur punta a Object.prototype, aggiungerà env a Object.prototype come oggetto vuoto e cur fa riferimento anche a env all'interno di Object.prototype.env.

alt text

Dopodiché, il ciclo terminerà e cur[prop] = data[p] sarà equivalente a env[AAA] = 'a'.

alt text

Il Object.prototype viene contaminato con env:

alt text

Canvas

La funzione fork restituisce un ChildProcess che può essere usato per invocare spawn

Cambia la porta a 9669 (un'altra porta) quando invochi la funzione fork e poi possiamo eseguire il debug del processo principale normalmente:

alt text

Simula il Object.prototype contaminato e salta a prima del ciclo:

alt text

Come possiamo vedere, env è equivalente a { AAA: 'a' } a causa della prototype pollution. Più precisamente, env viene assegnato a options.env. E options non definisce quella proprietà, quindi utilizzerà il valore del suo prototipo.

Dopo il ciclo:

alt text

In qualche modo, con le variabili d'ambiente non valide (AAA=a, env=[Object object]), canvas non riesce a creare un nuovo socket:

alt text

Ma il processo figlio può comunque essere creato:

alt text

Con il flusso normale, creerà una nuova connessione WebSocket:

alt text

Ora prova con il payload ed entra in normalizeSpawnArguments:

alt text

Come possiamo vedere, lo stack trace è lo stesso.

Ma env è contaminato:

alt text

Voila!

Gli envPairs dopo il ciclo:

alt text

E abbiamo ottenuto la reverse shell:

alt text

Spawn

Dopo aver chiamato normalizeSpawnArguments nella funzione spawn:

alt text

Come possiamo vedere, envPairs contiene il nostro payload. Inoltre, dopo di ciò, spawn chiamerà la funzione spawn all'interno di internal/child_process.js:

alt text

La variabile options verrà passata a this._handle.spawn:

alt text

Dove this._handle è un handle a un processo:

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];
Scarica lo strumento