
CVE-2026-51385 के लिए सलाह। इसे प्रकाशित करना आवश्यक था क्योंकि GRAPHIFY ने सलाह को मान्यता नहीं दी है और न ही प्रकाशित किया है, और MITRE ने CVE-2026-51385 आवंटित किया है, यह इसके लिए सलाह है।
CVE-2026-51385 के लिए सलाहकार। इसे प्रकाशित करना आवश्यक था क्योंकि GRAPHIFY ने सलाहकार को न तो पहचाना और न ही प्रकाशित किया, और MITRE ने CVE-2026-51385 निर्धारित किया, यह इसके लिए सलाहकार है।
ES: यह मेरा पहला CVE था, ईमानदारी से कहूं तो मुझे ANTI SSRF फ़ंक्शन में तर्क को तोड़ने का एक तरीका मिला, और मैं वास्तव में अपना पहला CVE प्रकाशित करना चाहता था, इसलिए मैंने सोचा कि यह सुरक्षा को कैसे प्रभावित कर सकता है ताकि प्रभाव प्रदर्शित किया जा सके, भले ही इसे निष्पादित करना जटिल हो (यह वास्तविक इंस्टेंस में होना मुश्किल है, लेकिन संभव है इसलिए इसकी जटिलता उच्च है)। मैंने इसे MITRE को भेजा और उन्होंने स्वीकार कर लिया। यह सलाहकार है।
EN: यह मेरा पहला CVE था, ईमानदारी से कहूं तो मुझे ANTI SSRF फ़ंक्शन में तर्क को तोड़ने का एक तरीका मिला, और मैं वास्तव में CVE प्रकाशित करना चाहता था, इसलिए मैंने सोचा कि यह सुरक्षा को कैसे प्रभावित कर सकता है, और एक औचित्य पाया, इसे MITRE को भेजा और उन्होंने स्वीकार कर लिया। यह सलाहकार है।
ध्यान रखें कि रिपोर्ट आंशिक रूप से AI द्वारा बनाई गई थी, लेकिन एक मानव द्वारा पर्यवेक्षित की गई थी
graphify में DNS रिबाइंडिंग (TOCTOU) के माध्यम से SSRF।
पैकेज: graphify (PyPI: graphifyy), repo Graphify-Labs/graphify
प्रभावित घटक: URL इंजेशन पथ, graphify add <url>
(कमिट , PRs #591 / #592)
8.3 (उच्च),
(SSRF), (TOCTOU रेस)
Arturo Melgarejo Galindo, स्वतंत्र सुरक्षा शोधकर्ता ()
>=0.3.2, <=0.4.290.5.4CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:Hgraphify add <url> खुद को SSRF से बचाने की कोशिश करता है जैसा कि कई फ़ेचर करते हैं: यह होस्टनाम को हल करता है, परिणामी IP को ब्लॉकलिस्ट (लूपबैक, RFC1918, लिंक-लोकल, आरक्षित) के विरुद्ध जांचता है, और केवल तभी फ़ेच करता है जब वह जांच पास हो जाती है।
समस्या यह है कि जिस IP को इसने मान्य किया, वह वह IP नहीं है जिससे यह कनेक्ट होता है। सत्यापन एक DNS लुकअप करता है, और फिर requests.get(hostname) एक दूसरा, स्वतंत्र लुकअप करता है। यदि आप होस्टनाम के DNS ज़ोन के मालिक हैं और दो A रिकॉर्ड के साथ बहुत कम TTL देते हैं, एक सार्वजनिक और एक आंतरिक, तो रिज़ॉल्वर कानूनी रूप से प्रत्येक क्वेरी पर एक अलग उत्तर दे सकता है। पहला उत्तर ब्लॉकलिस्ट पास करता है। दूसरा उत्तर वह है जहां सॉकेट वास्तव में जाता है। यह पूरा बग है। यह "IP जांचें, फिर नाम से कनेक्ट करें" तर्क के विरुद्ध क्लासिक रिबाइंडिंग बाईपास है, और फिक्स मान्य IP को कनेक्शन से जोड़ना है, जो 0.5.4 करता है।
मैं इसके बारे में ईमानदार रहना चाहता हूं, क्योंकि अपने आप में यह जितना है उससे कमजोर दिखता है।
यदि कोई मानव बैठता है और एक URL टाइप करता है जिस पर वे पहले से भरोसा करते हैं graphify add में, तो यह लगभग बेकार है। वह व्यक्ति पहले से ही graphify को अपने 127.0.0.1 पर इंगित कर सकता है यदि वे चाहें। उन्हें इसके लिए रिबाइंडिंग ट्रिक की आवश्यकता नहीं है, और उस चित्र में कोई हमलावर नहीं है।
यह वास्तविक कमजोरी तब बनती है जब graphify एक URL के विरुद्ध चलता है जिसे ऑपरेटर ने चुना नहीं था। और इस उपकरण के लिए यह कोई कोने का मामला नहीं है, यह वह सामान्य तरीका है जिससे इसका उपयोग किया जाता है। graphify ज्ञान ग्राफ बनाता है जो AI सहायकों द्वारा उपभोग किए जाते हैं, इसलिए यथार्थवादी प्रवाह कुछ प्रक्रिया है जो आपकी ओर से graphify add कॉल करती है: एक एजेंट, एक CI जॉब, एक स्क्रिप्ट जो एक README से URL की सूची चलाती है, या एक URL जो सीधे किसी अन्य मॉडल के आउटपुट से आया है। इन सभी में, हमलावर इनपुट स्ट्रिंग को नियंत्रित करता है और मानव ने कभी इसका निरीक्षण नहीं किया।
यही वह मामला है जो मायने रखता है। एक बार इनपुट अविश्वसनीय हो जाता है और रिबाइंडिंग रेस जीत ली जाती है, फ़ेच एक आंतरिक पते पर उतरता है न कि उस सार्वजनिक पते पर जिसे इसने मान्य किया था। ठोस रूप से यह पहुंच सकता है:
127.0.0.1 और लूपबैक से बंधी कोई भी चीज़,169.254.169.254 (क्लाउड इंस्टेंस मेटाडेटा),100.64.0.0/10, जिसे ब्लॉकलिस्ट बिल्कुल कवर नहीं करती है, इसलिए उस एक को रेस की भी आवश्यकता नहीं है, इसमें इंगित करने वाला एक सादा A रिकॉर्ड पर्याप्त है।और उन पतों तक पहुंचना केवल इसलिए नुकसान में बदल जाता है क्योंकि वहां क्या रहता है। कई आंतरिक और डेव सेवाएं GET एंडपॉइंट्स प्रदर्शित करती हैं जो या तो डेटा वापस देते हैं या एक नंगे GET पर स्थिति बदलते हैं। इसलिए एक graphify फ़ेच जो उनमें से किसी एक पर उतरता है, गलत पथ और क्वेरी स्ट्रिंग के साथ, सिर्फ एक पढ़ना नहीं है। यदि आंतरिक लक्ष्य एक Jenkins scriptText, एक Flask/Django डीबगर --debug में, एक एडमिन पैनल, या एक मेटाडेटा एंडपॉइंट है, तो वह malformed GET परिधि के अंदर से कार्य करने वाला हमलावर है। graphify वह डिप्टी है जो उनके लिए अनुरोध करता है।
मैं यह दावा नहीं कर रहा कि यह RCE पहुंचाता है। यह अपने आप में नहीं करता। लेकिन एक पूर्ण SSRF जिसे लूपबैक, IMDS, RFC1918 और CGN पर एक स्वचालित इंजेशन पथ से इंगित किया जा सकता है, वास्तव में वह आदिम है जिस पर वे हमले बनाए गए हैं, और यही रिपोर्ट करने का बिंदु है।
मैंने Tavis Ormandy के सार्वजनिक rbndr.us हार्नेस का उपयोग किया, जो आपको एक होस्टनाम देता है जो प्रत्येक रिज़ॉल्यूशन पर दो IP के बीच फ़्लिप करता है। 7f000001.08080808.rbndr.us 8.8.8.8 और 127.0.0.1 के बीच वैकल्पिक होता है।
आंतरिक लक्ष्य पर कुछ शुरू करें (यहाँ, डेमो के लिए लूपबैक):
sudo python3 -m http.server 80
फिर इंजेशन को ट्रिगर करें और तब तक पुनः प्रयास करें जब तक रेस न उतर जाए। यह लगभग हर 4 या 5 प्रयासों में 1 बार हिट करता है, और एक तुच्छ लूप इसे 99% से अधिक धकेल देता है:
for i in {1..20}; do
graphify add http://7f000001.08080808.rbndr.us/ && break
sleep 1
done
एक जीतने वाले प्रयास पर, graphify वह सब कुछ इंजेस्ट करता है जो स्थानीय सर्वर 127.0.0.1:80 पर लौटाता है, भले ही होस्टनाम ने पहले IP ब्लॉकलिस्ट पास कर दिया हो।
0.5.4 (dd86271) में फिक्स कमिट किया गया, 8 दिन बाद।Arturo Melgarejo Galindo, स्वतंत्र सुरक्षा शोधकर्ता।