
Gutartige, in sich geschlossene Reproduktion von CVE-2026-77521 (MaxKB-Befehlsausführung durch Prompt-Injection)
Ein eigenständiges, harmloses Labor, das
GHSA-f36j-f34j-h3rx
/ CVE-2026-77521 reproduziert: In MaxKB (einer
Open-Source-Plattform für Unternehmens-KI-Assistenten / RAG) erhält jeder Assistent mit einem Tool,
MCP-Tool, Skill oder einer Sub-Anwendung ein automatisch injiziertes Shell-execute-Tool,
das nicht hinter einer Freigabeschranke durch einen Menschen steht — sodass eine Prompt-Injection (aus dem Chat
oder aus einem eingelesenen Dokument) eine Shell erreicht. Eine Sandbox sollte dies eigentlich eindämmen,
doch ein shell=True-String ließ Metazeichen daraus entkommen.
| Advisory | GHSA-f36j-f34j-h3rx |
| CVE | CVE-2026-77521 |
| Projekt | 1Panel-dev/MaxKB |
| Betroffen | < 2.10.5-lts |
| Gepatcht | 2.10.5-lts (Commit 594f50f) — teilweise, siehe unten |
| CVSS | 10.0 CRITICAL (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H) |
| Schwäche | CWE-78 (OS-Befehlsinjektion) · CWE-250 (unnötige Privilegien) · CWE-749 (offengelegte gefährliche Methode) |
Dies reproduziert eine gepatchte, öffentlich offengelegte Schwachstelle zu Bildungs- und Verteidigungszwecken. Es läuft vollständig lokal und harmlos:
id, Schreiben einer Marker-Datei,
die der PoC wieder löscht). Es ist kein echtes gosu/Sandbox/root beteiligt — der Wrapper zum
Privilegienabbau wird durch einen inerten env-Marker ersetzt, damit die Demo überall läuft.Ein MaxKB-Assistent mit einer beliebigen angehängten Fähigkeit basiert auf deepagents mit
einem SandboxShellBackend. deepagents injiziert automatisch ein Shell-execute-Tool (plus
read_file/write_file/…), und MaxKB verwendet keine excluded_tools, sodass execute immer
vorhanden ist. Die interrupt_on-Konfiguration — die entscheidet, was eine menschliche
Freigabe erfordert — ist {"write_file": False, "read_file": False, "edit_file": False}:
execute ist nicht darin enthalten, also läuft es ohne Freigabe. Jeder Text, der das Modell
steuern kann (eine Chat-Nachricht oder ein vergiftetes Dokument, das die RAG-Pipeline einliest), kann
den Agenten daher dazu bringen, Shell-Befehle auszuführen. Bei Quellcode-Installationen ist SANDBOX
standardmäßig deaktiviert, sodass Befehle als der App-Benutzer laufen; im offiziellen (root-)Container
war der Sandbox-Wrapper ein shell=True-String, sodass ;/>/$() außerhalb von
gosu als root liefen.
interrupt_on läuft ein injizierter execute-Aufruf ohne Freigabe; das Hinzufügen von
"execute": True schrankt ihn ein. → poc/01_missing_hitl_gate.py;+Redirect entkommt dem
Ein-String-gosu-Präfix; das erneute Quoting in _build_sandbox_command() von 2.10.5-lts
neutralisiert dies. → poc/02_sandbox_escape.pyexecute mit dem Befehl des Angreifers auf (und nicht bei einem sauberen
Dokument). → poc/03_real_llm.pyDer ausgelieferte Patch 2.10.5-lts (Commit 594f50f)
härtet nur die Sandbox-Escape — er fügt _build_sandbox_command() hinzu, das
an Shell-Operatoren aufteilt, jedes Token mit shlex.quote erneut quotet und
jeden einfachen Befehl in das gosu-Präfix einbettet. Verifiziert gegen die
v2.10.5-lts-Quelle,
ist der Agency-Kern unverändert: interrupt_on lässt execute weiterhin aus, das
Backend ist weiterhin SandboxShellBackend, und SANDBOX ist weiterhin standardmäßig 0. Also
läuft ein per Prompt-Injection eingeschleustes execute auch nach dem Fix weiterhin ohne menschliche Genehmigung —
die innere Mauer wurde verstärkt, während das Tor offen blieb. PoC 1 demonstriert die
empfohlene Gegenmaßnahme (execute am Tor absichern), die der Hersteller nicht ausgeliefert hat.
Keine Abhängigkeiten für PoC 1/2 (Python 3.9+):
./run.sh # all three (PoC 3 skips without an endpoint)
python3 poc/01_missing_hitl_gate.py # missing approval gate
python3 poc/02_sandbox_escape.py # metacharacter sandbox escape
Präsentieren Sie das?
DEMO.mdist ein Runbook unddemo.shsteuert es Tastendruck für Tastendruck.
Jeder OpenAI-kompatible Endpunkt (selbst gehostet oder gehostetes Open-Model). Beispiel (Groq):
export OPENAI_BASE_URL=https://api.groq.com/openai/v1
export OPENAI_API_KEY=$GROQ_API_KEY # read from env only; never logged
MODEL="openai/gpt-oss-20b" python3 poc/03_real_llm.py
Hinter einem TLS-Inspection-Proxy wird es unverifiziert mit einer Warnung erneut versucht
(INSECURE_SSL=1, um es zu erzwingen). Es wird sauber übersprungen, wenn kein Endpoint gesetzt ist.
| Pfad | Was es ist |
|---|---|
sandbox_shell.py | Gutartiges Modell der execute()-Befehlskonstruktion von MaxKB — verwundbare Zeichenkette vs. gepatchtes _build_sandbox_command() |
agent_sim.py | Minimales Modell des interrupt_on-Gates für menschliche Genehmigung von deepagents |
payloads/poisoned-document.md | Vom Angreifer vergiftetes KB-Dokument (indirekte Injection) |
poc/01_missing_hitl_gate.py | Injiziertes execute läuft ohne Genehmigung; Gating blockiert es |
poc/02_sandbox_escape.py | Metazeichen entkommen dem gosu-Präfix; der Parser 2.10.5 enthält sie |
poc/03_real_llm.py | Ein echtes Modell ruft execute aus dem vergifteten Dokument auf (sauber vs. vergiftet) |
DEMO.md / demo.sh | Präsentations-Runbook und getakteter Demo-Treiber |
assets/attack-flow.{svg,png} | Angriffsflussdiagramm (Blog-Hero) |
assets/poc3-groq-sample.txt | Aufgezeichnete PoC-3-Ausgabe (Demo-Fallback) |