Skip to content
KitploitKITPLOIT
उपकरणएक्सप्लॉइटब्लॉग
Log in
जमा करें
उपकरणएक्सप्लॉइटब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
dsa — CVE-2016-3959 का विश्लेषण और एक Go SSH सर्वर के विरुद्ध प्रूफ ऑफ कॉन्सेप्ट हमला | Kitploit
उपकरण/GitHubGitHub/alexmullins/dsa
भेद्यता विश्लेषणशोषणक्रिप्टोग्राफीपेनिट्रेशन टेस्टिंगलर्निंग और शिक्षा
GitHubalexmullins/dsa

dsa

CVE-2016-3959 का विश्लेषण और एक Go SSH सर्वर के विरुद्ध प्रूफ ऑफ कॉन्सेप्ट हमला

रिपॉजिटरी देखें
11710 साल पहलेअभी तक समीक्षित नहीं

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

Go के crypto/dsa कमजोरी (CVE-2016-3959) का सारांश

Alex Mullins

9 अप्रैल, 2016


परिचय

हाल ही में, Go प्रोग्रामिंग भाषा के लिए Digital Signature Algorithm (DSA) क्रिप्टो लाइब्रेरी में एक बग खोजा गया था। इस लेख में हम बग के विवरण और यह देखेंगे कि कैसे एक हमलावर इसका उपयोग करके एक मानक Go SSH सर्वर के खिलाफ सेवा अस्वीकार हमला शुरू कर सकता है जो क्लाइंट को प्रमाणित करने के लिए अंतर्निहित DSA लाइब्रेरी का उपयोग करता है।

इस कमजोरी का पहला उल्लेख Open Source Security (oss-sec) मेलिंग लिस्ट पर एक पोस्ट में दिखाई दिया: http://seclists.org/oss-sec/2016/q2/11।

Go में कई बड़े पूर्णांक रूटीन में एक अनंत लूप है जो Go प्रोग्राम को रिमोट सेवा अस्वीकार हमलों के प्रति संवेदनशील बनाता है। HTTPS क्लाइंट प्रमाणीकरण या Go ssh सर्वर लाइब्रेरी का उपयोग करने वाले प्रोग्राम इस कमजोरी के संपर्क में हैं। इसका समाधान निम्नलिखित CL में किया जा रहा है: https://golang.org/cl/21533

-- Jason Buberel

संक्षेप में, यदि इस कमजोरी का शोषण किया जाता है, तो यह अंतर्निहित BigNum लाइब्रेरी कोड में एक अनंत लूप का कारण बन सकता है। यह CPU और मेमोरी के संदर्भ में सिस्टम संसाधनों को खा जाएगा और अंततः प्रोग्राम या सिस्टम को स्वयं अनुत्तरदायी बना सकता है।

उपरोक्त कथन कहता है कि SSH के साथ-साथ HTTPS क्लाइंट प्रमाणीकरण प्रभावित हैं, लेकिन Go के crypto/tls और net/http पैकेजों को देखने के बाद ऐसा लगता है कि यह गलत है। HTTPS क्लाइंट प्रमाणीकरण केवल RSA या ECDSA हस्ताक्षर योजनाओं का उपयोग कर सकता है, DSA का नहीं। नीचे देखें। यदि मैं इस बारे में गलत हूं तो कृपया मुझे बताएं।

https://golang.org/pkg/crypto/tls/#Certificate

type Certificate struct {
        Certificate [][]byte
        // PrivateKey contains the private key corresponding to the public key
        // in Leaf. For a server, this must implement crypto.Signer and/or
        // crypto.Decrypter, with an RSA or ECDSA PublicKey. For a client
        // (performing client authentication), this must be a crypto.Signer
        // with an RSA or ECDSA PublicKey.
        PrivateKey crypto.PrivateKey

        ... other fields
}

उस पोस्ट के oss-sec मेलिंग लिस्ट पर दिखाई देने के तुरंत बाद, एक CVE नंबर जारी किया गया: CVE-2016-3959। Go अनुरक्षकों के पास इसके लिए एक फिक्स तैयार है और यह संस्करण 1.5.4 और 1.6.1 में दिखाई देगा जो बुधवार, 13 अप्रैल, 2016 को जारी किए जाएंगे; https://groups.google.com/forum/#!topic/golang-nuts/MmSbFHLPo8g।

इस लेख में कोड नमूनों के साथ अनुसरण करने के लिए आपको Go संस्करण 1.6 स्थापित करना होगा। https://golang.org/doc/install पर दिए गए निर्देशों का पालन करें। यदि आप इस दस्तावेज़ और कोड नमूनों को डाउनलोड करना चाहते हैं तो आपको Git भी स्थापित करना होगा। https://git-scm.com/book/en/v2/Getting-Started-Installing-Git पर दिए गए निर्देशों का पालन करें। रिपॉजिटरी को क्लोन करने के लिए टर्मिनल में निम्नलिखित कमांड जारी करें:

$ go get github.com/alexmullins/dsa

यह रिपॉजिटरी को आपके Go वर्कस्पेस में क्लोन करेगा।

अगला भाग कमजोरी के विवरण को कवर करेगा।

दोष

तो वास्तव में क्या गलत है? इसका उत्तर देने के लिए, किसी को oss-sec मेलिंग लिस्ट पर मूल घोषणा पर वापस जाना होगा। समस्या के सामान्य स्पष्टीकरण और https://golang.org/cl/21533 पर कोड फिक्स के लिंक के अलावा वहां ज्यादा जानकारी नहीं है। उस परिवर्तन के लिए कमिट संदेश में निम्नलिखित है:

crypto/dsa: invalid PublicKey को जल्दी हटाएं

PublicKey.P == 0 के लिए, Verify विफल होगा। कोशिश भी न करें।

--- Robert Griesemer

और फिक्स्ड कोड:

https://github.com/golang/go/blob/master/src/crypto/dsa/dsa.go#L247

// Verify verifies the signature in r, s of hash using the public key, pub. It
// reports whether the signature is valid.
//
// Note that FIPS 186-3 section 4.6 specifies that the hash should be truncated
// to the byte-length of the subgroup. This function does not perform that
// truncation itself.
func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
    // FIPS 186-3, section 4.7

    // Code fix added to check if the key parameters are sensible.
    if pub.P.Sign() == 0 {
        return false
    }

    if r.Sign() < 1 || r.Cmp(pub.Q) >= 0 {
        return false
    }
    if s.Sign() < 1 || s.Cmp(pub.Q) >= 0 {
        return false
    }

    w := new(big.Int).ModInverse(s, pub.Q)

    n := pub.Q.BitLen()
    if n&7 != 0 {
        return false
    }
    z := new(big.Int).SetBytes(hash)

    u1 := new(big.Int).Mul(z, w)
    u1.Mod(u1, pub.Q)
    u2 := w.Mul(r, w)
    u2.Mod(u2, pub.Q)
    v := u1.Exp(pub.G, u1, pub.P)
    u2.Exp(pub.Y, u2, pub.P)
    v.Mul(v, u2)
    v.Mod(v, pub.P)
    v.Mod(v, pub.Q)

    return v.Cmp(r) == 0
}

उपरोक्त कमिट संदेश और कोड फिक्स को संक्षेप में: Go 1.6 और पिछले संस्करणों में crypto/dsa पैकेज के Verify फ़ंक्शन में एक बग है। यदि कोई पब्लिक की पैरामीटर P को 0 पर सेट करके Verify को कॉल करता है, तो यह Verify फ़ंक्शन में आगे के एक स्टेटमेंट में अनंत लूप का कारण बनेगा।

DSA को समझाने के लिए एक संक्षिप्त विषयांतर। DSA एक डिजिटल हस्ताक्षर एल्गोरिदम है जो एक संदेश पर हस्ताक्षर करने के लिए असममित क्रिप्टोग्राफी का उपयोग करता है, जिसका उपयोग बाद में यह गारंटी देने के लिए किया जा सकता है कि संदेश वास्तव में प्रेषक/निजी कुंजी धारक द्वारा भेजा गया था। एक सरल उदाहरण, एलिस बॉब को एक संदेश भेजती है जो उसे बताती है कि उन्हें लंच के लिए कहाँ और कब मिलना चाहिए। हालांकि, बॉब यह सुनिश्चित करना चाहता है कि संदेश वास्तव में एलिस ने भेजा है न कि किसी और ने। इसके लिए एलिस अपनी निजी कुंजी से संदेश पर हस्ताक्षर करेगी और बॉब बॉब द्वारा ज्ञात एलिस की सार्वजनिक कुंजी से एलिस के हस्ताक्षर को सत्यापित कर सकता है। निजी कुंजी धारक के अलावा कोई भी ऐसे संदेश पर हस्ताक्षर नहीं कर सकता जिसे बाद में संबंधित सार्वजनिक कुंजी द्वारा सत्यापित किया जा सके (कम से कम विचार यही है)।

काम करने के लिए, DSA को 5 बड़ी संख्याओं की आवश्यकता होती है। पहली 3 संख्याएं DSA पैरामीटर P, Q, और G के रूप में जानी जाती हैं। ये अंतर्निहित समूह और समूह जनरेटर को परिभाषित करती हैं। इन संख्याओं को dsa.GenerateParameters() पर कॉल करके ठीक से बनाया जा सकता है।

type Parameters struct {
        P, Q, G *big.Int
}

DSA के लिए आवश्यक अंतिम दो संख्याएं निजी कुंजी X और संबंधित सार्वजनिक कुंजी Y हैं। इन संख्याओं को dsa.GenerateKey() पर कॉल करके भी बनाया जा सकता है।

type PrivateKey struct {
        PublicKey
        X *big.Int
}

type PublicKey struct {
        Parameters
        Y *big.Int
}

DSA के बारे में अनुसरण करने के लिए आपको बस इतना ही जानना आवश्यक है। अधिक जानकारी के लिए NIST मानक देखें: http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf या विकिपीडिया पृष्ठ: https://en.wikipedia.org/wiki/Digital_Signature_Algorithm।

विषय पर वापस आते हैं; Verify फ़ंक्शन में अनंत लूप कहाँ है? थोड़ी और खोजबीन करने पर आप पाएंगे कि कोड यहाँ अटक जाता है:

v := u1.Exp(pub.G, u1, pub.P)

यह Exp() विधि के लिए टिप्पणी है:

// Exp sets z = x**y mod |m| (i.e. the sign of m is ignored), and returns z.
// If y <= 0, the result is 1 mod |m|; if m == nil or m == 0, z = x**y.
// See Knuth, volume 2, section 4.6.3.
func (z *Int) Exp(x, y, m *Int) *Int {

उपरोक्त से, आप देख सकते हैं कि टिप्पणी निर्दिष्ट करती है कि जब m == 0 होता है तो यह मॉड्यूलर रिडक्शन के बिना घातांक करेगा। जब आप एक बड़ी संख्या लेते हैं और इसे दूसरी बड़ी संख्या के साथ घातांकित करते हैं तो परिणाम भी एक REALLY BIG संख्या होगी। मैं math/big के काम करने के तरीके से बहुत परिचित नहीं हूं, लेकिन मुझे लगता है कि यहाँ यही हो रहा है। Exp() इस घातांक पर काम कर रहा है जिसे पूरा होने में बहुत, बहुत लंबा समय लगेगा (अनंत के बराबर हो सकता है)।

यहाँ dsa.Verify() call में Exp() को उपयोग किए जा रहे कुछ नमूना संख्याएं हैं जो नीचे दिए गए परीक्षण कोड से एकत्र की गई हैं:

x = 87134495734400160760614045850064869082246125869475484226357302998590334523718907040547736115253396811403341841812955872027275698952059512800196447089300992352859585665865224989740
07948775031938554271780506269767106717359222697821209685947889925442133804051298762702245652821695254167558015585995918548052076 (307 digits)

y = 751336012463178371212581620103057049388105279629 (48 digits)

z = x ^ y
टूल डाउनलोड करें