Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
kibana-prototype-pollusion — PoC und Analyse für Kibana Prototype Pollution RCE (CVE-2019-7609). | Kitploit
Tools/GitHubGitHub/aleister1102/kibana-prototype-pollusion
SchwachstellenanalyseCode-AnalyseExploitationWebanwendungs-ExploitationPapers & ForschungLernen & Bildung
GitHubaleister1102/kibana-prototype-pollusion

kibana-prototype-pollusion

PoC und Analyse für Kibana Prototype Pollution RCE (CVE-2019-7609).

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen
Repository anzeigen
vor 2 JahrenNoch nicht geprüft

CVE-2019-7609

Kibana-Versionen vor 5.6.15 und 6.6.1 enthalten eine Schwachstelle zur Ausführung beliebigen Codes im Timelion-Visualizer. Ein Angreifer mit Zugriff auf die Timelion-Anwendung kann eine Anfrage senden, die versucht, JavaScript-Code auszuführen. Dies könnte dazu führen, dass ein Angreifer beliebige Befehle mit den Berechtigungen des Kibana-Prozesses auf dem Hostsystem ausführt.

CVSS:

cvss

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

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

Ziel

Einrichtung:

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

Verwendung:

  • 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

Analyse

Timelion

Nach dem Parsen des Sheets:

alt text

Nach der Vorverarbeitung des Sheets haben wir ein queries-Objekt:

alt text

Dann iterieren wir über das queries-Array (das mit der values-Methode in ein Array umgewandelt wird) und übergeben query.function und query.arguments an invoke, um die Funktion aufzurufen.

In der invoke-Funktion holen wir zunächst die Definition der Funktion basierend auf ihrem Namen (query.function):

alt text

Diese Funktionsdefinition enthält drei Funktionstypen: fn, originalFn und timelionFn. Dann iteriert es über die args (welche query.arguments sind) und löst die Argumente auf:

alt text

In diesem Fall ist das Argument in args ein Objekt vom Typ 'literal', daher wird nur der Literalwert zurückgegeben:

alt text

Tatsächlich ist der Wert in ein Promise verpackt.

alt text

Das indizierte Argument ist ein Argument mit einem byName-Objekt, das ein q-Array enthält:

alt text

Danach ruft die invoke-Funktion functionDef.fn auf, eine Funktion der Timelion-Klasse, mit allen indizierten Argumenten:

alt text

Die fn-Funktion ruft originalFn auf, das von config.fn stammt, wobei config tlConfig ist. Und diese Funktion ist fn der Klasse Datasource extends Timelion:

alt text

Wie wir sehen können, ruft sie eine weitere originalFn namens esFn auf, die ein seriesList-Objekt zurückgibt:

alt text

Diese Funktion wird verwendet, um "Daten aus einer Elasticsearch-Instanz abzurufen", indem die callWithRequest-Funktion aufgerufen wird.

Das seriesList sieht in Datasource.fn so aus:

alt text

Und in Timelion.fn sieht es so aus:

alt text

Nach der Vorverarbeitung des Sheets ist die Chain-Liste:

alt text

Und der Code ruft resolveChainList auf, um die Chain-Liste aufzulösen:

alt text

Jede Chain wird einem Promise zugeordnet, das von einer Funktion zurückgegeben wird, die invoke mit 'first' als fnName und der Chain selbst als args aufruft.

Die Funktionsdefinition wird wieder anhand des Namens ermittelt:

alt text

Dieses Mal erhält resolveArguments args als Array und ruft resolveArguments rekursiv auf, um jedes Argument aufzulösen. Aber wir haben nur ein Argument mit Index 0. Und dieses Argument ist ein Objekt mit type == chain.

Im Switch-Case wird also die invokeChain-Funktion aufgerufen und das Chain-Objekt übergeben:

alt text

Innerhalb der invoke chain wird das chain-Array mit shift bearbeitet. Die shift-Funktion gibt das entfernte Element zurück, sodass link das es-Objekt ist:

alt text

Da der Typ von es nicht 'chain' ist (sondern 'function') und !result truthy ist, ruft der Code die invoke-Funktion mit 'first' als fnName und dem es-Objekt als args auf:

alt text

Dieses Mal ist der Ablauf derselbe wie oben, daher springen wir zum Aufruf von invokeChain mit link als props-Objekt:

alt text

Wieder ruft der Code die invoke-Funktion mit 'first' als fnName und dem props-Objekt als args auf:

alt text

Die originalFn von props ist jetzt firstFn anstelle von fn wie bei es und akzeptiert nur ein Argument:

alt text

Diese ursprüngliche Funktion wird schließlich die anfällige unflatten-Funktion aufrufen. Tatsächlich wird sie zuerst die fn von Timelion aufrufen. Dann ruft fn die originalFn von props auf:

alt text

Die firstFn von props wird die Eigenschaften inputSeries und global im byName-Objekt von args auslassen:

alt text

Die an unflatten übergebenen data werden also sein:

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

Beweis:

alt text

Unflatten

Mit props(label.__proto__.env.AAA="a") sehen die data so aus:

alt text

Bei der ersten Iteration existiert prop = '' nicht, daher wird cur[''] = {} zugewiesen. Das bedeutet, dass result ebenfalls eine Eigenschaft namens '' mit einem leeren Objekt als Wert erhält. Danach wird cur mit {} belegt, dem Rückgabewert der vorherigen Zuweisung (cur und cur[prop] zeigen auf dasselbe Objekt):

alt text

Jetzt wird prop zu 'label':

alt text

Wie zuvor erhält result eine 'label'-Eigenschaft und prop wird zu __proto__:

alt text

Bei der dritten Iteration wird cur zu seinem Prototyp, da __proto__ in jedem Objekt existiert:

alt text

Danach wird prop zu env.

Da cur auf Object.prototype zeigt, wird env als leeres Objekt zu Object.prototype hinzugefügt und cur referenziert ebenfalls auf env innerhalb von Object.prototype.env.

alt text

Danach wird die Schleife beendet und cur[prop] = data[p] entspricht env[AAA] = 'a'.

alt text

Der Object.prototype ist mit env verschmutzt:

alt text

Canvas

Die fork-Funktion gibt einen ChildProcess zurück, der verwendet werden kann, um spawn aufzurufen

Ändern Sie den Port beim Aufruf der fork-Funktion auf 9669 (ein anderer Port), und dann können wir den Hauptprozess normal debuggen:

alt text

Simulieren Sie den verschmutzten Object.prototype und springen Sie vor die Schleife:

alt text

Wie wir sehen können, ist env aufgrund der Prototype-Pollution gleichbedeutend mit { AAA: 'a' }. Genauer gesagt, wird env options.env zugewiesen. Und da options diese Eigenschaft nicht definiert, wird der Wert seines Prototyps verwendet.

Nach der Schleife:

alt text

Irgendwie kann Canvas mit den ungültigen Umgebungsvariablen (AAA=a, env=[Object object]) keinen neuen Socket erstellen:

alt text

Aber der Kindprozess kann trotzdem erstellt werden:

alt text

Beim normalen Ablauf wird eine neue WebSocket-Verbindung erstellt:

alt text

Versuchen Sie es nun mit dem Payload und springen Sie in die normalizeSpawnArguments-Funktion:

alt text

Wie wir sehen können, ist der Stack-Trace derselbe.

Aber das env ist verschmutzt:

alt text

Voilà!

Die envPairs nach der Schleife:

alt text

Und wir haben die Reverse Shell erhalten:

alt text

Spawn

Nach dem Aufruf von normalizeSpawnArguments in der spawn-Funktion:

alt text

Wie wir sehen können, enthalten die envPairs unseren Payload. Außerdem ruft spawn danach die spawn-Funktion in internal/child_process.js auf:

alt text

Die Variable options wird an this._handle.spawn übergeben:

alt text

Wobei this._handle ein Handle auf einen Prozess ist:

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];
Tool herunterladen