
पासपोर्ट-सैमल के कमजोर संस्करणों का उपयोग करके SAML SSO इंटीग्रेशन में प्रमाणीकरण को बायपास करने के लिए एक सरल CVE-2022-39299 PoC एक्सप्लॉइट जनरेटर
परामर्श : https://github.com/node-saml/passport-saml/security/advisories/GHSA-m974-647v-whv7
पैच : https://github.com/node-saml/passport-saml/commit/8b7e3f5a91c8e5ac7e890a0c90bc7491ce33155e
node-saml परीक्षण मामलों से निकाला गया मूल पेलोड उदाहरण: https://github.com/node-saml/node-saml/blob/c1f275c289c01921e58f5c70ce0fdbc5287e5fbe/test/static/signatures/invalid/response.root-signed.multiple-root-elements.xml.
बग लेखक: felixwilhelm
शोषण जनरेटर लेखक (आसान हिस्सा): Francesco Lacerenza
एक दूरस्थ हमलावर passport-saml लाइब्रेरी को प्रभावित करने वाले CVE-2022-39299 का शोषण करके किसी प्लेटफ़ॉर्म पर SAML SSO प्रमाणीकरण को बाईपास कर सकता है।
एक सार्वजनिक शोषण उपलब्ध नहीं था (लेखन के समय), और परामर्श 10/12/2022 को बहुत कम/कोई जानकारी के साथ प्रकाशित किया गया था। Doyensec ने मल्टी-टेनेंट प्लेटफ़ॉर्म के खिलाफ समस्या की पुष्टि करने के लिए एक काम करने वाला प्रूफ ऑफ कॉन्सेप्ट (PoC) जनरेटर विकसित किया है जिसमें टेनेंट एडमिन कस्टम IdP के साथ SAML SSO कॉन्फ़िगर कर सकता है।
जैसा कि परामर्श में कहा गया है:
एक सफल हमले के लिए आवश्यक है कि हमलावर के पास एक मनमाना IDP हस्ताक्षरित XML तत्व हो। उपयोग किए गए IDP के आधार पर, पूरी तरह से अप्रमाणित हमले (अर्थात, एक वैध उपयोगकर्ता तक पहुंच के बिना) भी संभव हो सकते हैं यदि हस्ताक्षरित संदेश उत्पन्न करना शुरू किया जा सके।
कमजोर जांच passport-saml-2.0.0/src/passport-saml/saml.ts:775 पर validatePostResponse फ़ंक्शन के अंदर स्थित है
// Check if this document has a valid top-level signature
let validSignature = false;
if (this.options.cert && this.validateSignature(xml, doc.documentElement, certs!)) {
validSignature = true;
}
विशेष रूप से, validateSignature जांचता है कि पूर्ण XML दस्तावेज़ में doc.documentElement में एक वैध हस्ताक्षर है। चूंकि documentElement प्रॉपर्टी दस्तावेज़ का पहला रूट नोड लौटाती है, यह केवल पहले रूट तत्व पर हस्ताक्षर सत्यापित करेगी।
फ़ंक्शन यह सत्यापित करके जारी रहता है कि XML में केवल एक ही असर्शन है:
const assertions = xmlCrypto.xpath(doc, "/*[local-name()='Response']/*[local-name()='Assertion']") as HTMLElement[];
const encryptedAssertions = xmlCrypto.xpath(doc,
"/*[local-name()='Response']/*[local-name()='EncryptedAssertion']");
if (assertions.length + encryptedAssertions.length > 1) {
// There's no reason I know of that we want to handle multiple assertions, and it seems like a
// potential risk vector for signature scope issues, so treat this as an invalid signature
throw new Error('Invalid signature: multiple assertions');
}
परिणामस्वरूप, XML पार्सर एकाधिक रूट वाले XML दस्तावेज़ को पार्स करेगा। जबकि एक हस्ताक्षर केवल एक रूट नोड पर लागू हो सकता है, XPath प्रमाणीकरण और प्राधिकरण तत्वों को खोजने के लिए कई रूट नोड्स को पार कर सकता है।
निष्कर्ष में, एक रूट नोड पर हस्ताक्षर किया जा सकता है (जैसे, सामान्य SAML त्रुटि संदेश) और फिर दूसरे, अहस्ताक्षरित नोड में संशोधित प्रमाणीकरण और प्राधिकरण जानकारी हो सकती है। इस तरह हमलावर प्रमाणीकरण जानकारी के साथ छेड़छाड़ करने और टेनेंट के भीतर किसी भी खाते तक पहुंच प्राप्त करने में सक्षम होता है।
नोट: शोषण की सफलता पूरी तरह से passport lib के उपयोग से संबंधित आंतरिक प्रमाणीकरण तर्क पर निर्भर करती है। यदि प्रमाणीकरण तर्क passport.authenticate(...PASSPORT-SAML_OPTIONS...) से परिणामी प्रमाणित-सत्र ऑब्जेक्ट पर पूरी तरह भरोसा करता है, तो यह संभवतः कमजोर है।
openssl के साथ एक नया प्रमाणपत्र और कुंजी उत्पन्न करें:openssl req -x509 -new -newkey rsa:2048 -nodes -subj '/C=US/ST=California/L=San Francisco/O=JankyCo/CN=Test Identity Provider' -keyout key.pem -out cert.pem -days 7300
वैकल्पिक रूप से, इस रिपॉजिटरी के अंदर वाले का उपयोग करें।
लक्ष्य प्लेटफ़ॉर्म पर, व्यवस्थापक के रूप में SAML SSO एकीकरण पैनल पर जाएं। फिर, IdP से हस्ताक्षर सत्यापित करने के लिए उपयोग किए जाने वाले प्रमाणपत्र को इस फ़ोल्डर के अंदर वाले के रूप में सेट करें।
SAML SSO उपयोगकर्ताओं को प्रमाणित करने के लिए प्लेटफ़ॉर्म द्वारा आवश्यक authn और authz तत्वों के साथ payload_appendix.xml कॉन्फ़िगर करें। आप ऐसी जानकारी दस्तावेज़ों में या मान्य प्रमाणीकरण तत्वों को सीखने के लिए एक काम करने वाला SSO एकीकरण बनाकर पा सकते हैं।
अपने छेड़छाड़ किए गए डेटा वाला एक हस्ताक्षरित मल्टी-रूट तत्व SAML प्रतिक्रिया उत्पन्न करने के लिए निम्न कमांड चलाएं।
python3 payloadGenerator.py
मल्टी-रूट तत्व SAML प्रतिक्रिया की निम्नलिखित संरचना है:
<!— BEGINNING OF THE SIGNED ERROR MESSAGE —>
<samlp:Response xmlns="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="IDVALUE" Version="2.0" IssueInstant="2022-28-08T14:38:05Z">
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Responder">
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:NoPassive">
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:PartialLogout">
</samlp:StatusCode>
</samlp:StatusCode>
</samlp:StatusCode>
<samlp:StatusMessage>Random Error</samlp:StatusMessage>
</samlp:Status>
</samlp:Response>
<!— END OF THE SIGNED ERROR MESSAGE. BEGINNING OF THE UNSIGNED AUTHENTICATION INFO—>
<Response>
<saml:Assertion ID="whatever" IssueInstant="2022-10-30T18:00:00+00:00" Version="2.0">
<!— TAMPERED AUTHN & AUTHZ INFO —>
</saml:Assertion>
</Response>
नोट: यदि आप इस समस्या का शोषण तब करना चाहते हैं जब आपके पास IdP कॉन्फ़िगरेशन तक पहुंच नहीं है, तो बस अंतिम पेलोड बनाने के लिए उपयोग किए जाने वाले वेरिएबल signed_base_payload_unicode को प्रतिस्थापित करके payloadGenerator.py को संशोधित करें। काम करने के लिए, आपको इसे एक हस्ताक्षरित SAML प्रतिक्रिया से प्रतिस्थापित करना होगा जिसमें असर्शन न हों। लक्ष्य के IdP से इसे प्राप्त करने का तरीका खोजने के लिए शुभकामनाएँ (मामला-दर-मामला तर्क लागू होता है और उनके बारे में कोई साहित्य मौजूद नहीं है)।
SAML SSO एकीकरण सक्षम वाले संगठनों में, हमलावर प्रमाणीकरण को बाईपास कर सकते हैं और टेनेंट में किसी भी उपयोगकर्ता के साथ लॉगिन कर सकते हैं।
हालांकि परामर्श में कहा गया है कि हमलावर "एक मनमाना IDP हस्ताक्षरित XML तत्व" का उपयोग कर सकता है, passport-saml लाइब्रेरी किसी भी XML संदेश को रोकती है जिसमें कई असर्शन हों (विवरण अनुभाग में कोड स्निपेट देखें)। यह सीमा हमलावर को एक ऐसा हस्ताक्षरित SAML संदेश प्राप्त करने के लिए मजबूर करती है जिसमें कोई असर्शन न हो, जैसे कोई त्रुटि संदेश। ऐसे संदेशों की उपस्थिति IdP कार्यान्वयन पर निर्भर करती है।
एक उदाहरण के रूप में, बिना असर्शन के SAML प्रतिक्रियाएं Auth0 की लाइब्रेरी node-samlp द्वारा सीधे समर्थित हैं। See at https://github.com/auth0/node-samlp/blob/master/lib/samlp.js
function buildSamlResponse(options) {
var SAMLResponse = templates.samlresponse({
id: '_' + utils.generateUniqueID(),
instant: utils.generateInstant(),
destination: options.destination || options.audience,
inResponseTo: options.inResponseTo,
issuer: options.issuer,
samlStatusCode: options.samlStatusCode,
samlStatusMessage: options.samlStatusMessage,
assertion: options.samlAssertion || ''
});
उपरोक्त उदाहरण Auth0 तकनीक का उपयोग करते समय भी बिना असर्शन के हस्ताक्षरित संदेशों की ओर ले जाने वाले कोड पथ पेश करने की संभावना दिखाता है। उस अर्थ में, ग्राहकों के IdP में ऐसे पैटर्न हो सकते हैं।
यदि कोई हमलावर ऐसे संदेशों को ट्रिगर करने का कोई तरीका ढूंढता है, तो पूरी तरह से अप्रमाणित हमले (अर्थात, एक वैध उपयोगकर्ता तक पहुंच के बिना) भी संभव हो सकते हैं।