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

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

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

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

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

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
CVE-2022-20474 — एंड्रॉइड CVE-2022-20474 के लिए विस्तृत तकनीकी विश्लेषण और प्रूफ-ऑफ-कॉन्सेप्ट, एक Bundle mismatch भेद्यता जो नकारात्मक लंबाई के साथ LazyValue का शोषण करके self-changing Bundle व्यवहार प्राप्त करती है। | Kitploit
उपकरण/GitHubGitHub/cxxsheng/cve-2022-20474
एंड्रॉइड सुरक्षाभेद्यता विश्लेषणशोषणपेपर और शोधलर्निंग और शिक्षाबाइनरी शोषण
GitHubcxxsheng/cve-2022-20474

CVE-2022-20474

एंड्रॉइड CVE-2022-20474 के लिए विस्तृत तकनीकी विश्लेषण और प्रूफ-ऑफ-कॉन्सेप्ट, एक Bundle mismatch भेद्यता जो नकारात्मक लंबाई के साथ LazyValue का शोषण करके self-changing Bundle व्यवहार प्राप्त करती है।

रिपॉजिटरी देखें
20141 साल पहलेKitploit द्वारा समीक्षित

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

सभी देखें →

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

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

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

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

CVE-2022-20474 विश्लेषण – LazyValue के तहत Self-changed Bundle

प्रस्तावना

कृपया ध्यान दें, इस लेख को पढ़ने से पहले, आपको Bundle Mismatch संबंधित कमजोरियों की बुनियादी समझ होनी चाहिए। यदि आपने नीचे दिए गए संदर्भ सामग्री को अभी तक नहीं पढ़ा है, तो पहले उन्हें पढ़ने की सलाह दी जाती है:

  1. Bundle फेंगशुई – Android सीरियलाइज़ेशन और डीसीरियलाइज़ेशन बेमेल भेद्यता विस्तृत विवरण: क्लासिक प्रवेश स्तर ट्यूटोरियल।
  2. Android डीसीरियलाइज़ेशन भेद्यता आक्रमण और रक्षा इतिहास: एक अच्छा सारांश लेख।
  3. TheLastBundleMismatch: LazyValue मोड में पहला Bundle Mismatch लेख।

पृष्ठभूमि

हाल ही में मैं michalbednarski के LeakValue लेख का गहन अध्ययन कर रहा था। Canyie के साथ चर्चा करते समय, उन्होंने कहा कि इस लेख में LazyValue परिदृश्य में Self-changing Bundle की एक स्थिति का भी उल्लेख किया गया है, और फिर मैंने मूल लेख ढूंढा, वास्तव में ऐसा एक पैराग्राफ था, जिसे मैंने Michal का लेख पढ़ते समय सीधे छोड़ दिया था। मूल लेख में ऐसा कहा गया है:

(Also LazyValue with negative length specified can be used (without using other bugs described in this writeup) to create self-changing Bundle, the thing LazyValue was created to eliminate. But that is another story (and separately reported to Google), in this exploit I'm aiming for more)

Michal का तात्पर्य शायद CVE-2022-20474 (बुलेटिन, पैच) से है। मैंने एक नज़र पैच पर डाली, लेकिन पैच लिंक में फ़ंक्शन पूरा नहीं दिखाया गया था। इसे पूरा करने के बाद ध्यान से देखते हैं:

@@ -4388,6 +4388,9 @@
    public Object readLazyValue(@Nullable ClassLoader loader) {
         int start = dataPosition();
         int type = readInt();
         if (isLengthPrefixed(type)) {
             int objectLength = readInt();
+            if (objectLength < 0) {
+                return null;
+            }
             int end = MathUtils.addOrThrow(dataPosition(), objectLength);
             int valueLength = end - start;
             setDataPosition(end);
             return new LazyValue(this, start, valueLength, type, loader);
         } else {
            return readValue(type, loader, /* clazz */ null);
         }
    }             

कोड में objectLength LazyValue का length है, वास्तव में यह केवल LazyValue में शामिल परिवर्तनीय ऑब्जेक्ट की लंबाई है, जबकि पूरे LazyValue की लंबाई mLength फ़ील्ड द्वारा नियंत्रित होती है, अर्थात कोड में valueLength, जो LazyValue के कंस्ट्रक्टर में mLength को पास किया जाता है।

आइए LazyValue के लेआउट प्रारूप की तुलना करें:

       /**
         *                      |   4B   |   4B   |
         * mSource = Parcel{... |  type  | length | object | ...}
         *                      a        b        c        d
         * length = d - c
         * mPosition = a
         * mLength = d - a
         */

उपरोक्त सामग्री के आधार पर, हम निम्नलिखित तथ्य प्राप्त कर सकते हैं:

  1. mLength पूरे LazyValue की लंबाई को दर्शाता है, mLength = objectLength + 8 बाइट्स।
  2. objectLength >= 0 होना चाहिए।
  3. LazyValue ऑब्जेक्ट केवल mLength संग्रहीत करता है, objectLength नहीं, क्योंकि LazyValue मेमोरी कॉपी पूरे ऑब्जेक्ट के आधार पर की जाती है।
  4. पढ़ने के बाद पॉइंटर आगे बढ़ जाता है, संभवतः LazyValue फिर से पढ़ा जा सकता है।

फिर, गहन विचार के बाद, हम सभी सहमत हैं कि इन तथ्यों का! कुछ! भी! उपयोग! नहीं! है! क्योंकि उपरोक्त तथ्यों के आधार पर, केवल read के दौरान एक बार संशोधित किया जा सकता है, जबकि हम जानते हैं कि Self-changed Bundle का मूल विचार read पूरा होने के बाद संशोधित करना है, तभी सुरक्षा जांच को बायपास किया जा सकता है।

जब हम हार मानने वाले थे, तो अचानक हमने पैच के विवरण में कुछ विवरण पाया:

Addresses a security vulnerability where a (-8) length object would cause dataPosition to be reset back to the statt of the value, and be re-read again.

असामान्य objectLength

इसमें उल्लेख है कि जब objectLength -8 होता है, तो कुछ समस्याएं होती हैं, जिससे हमें अतिरिक्त संकेत मिले। क्या इस समय LazyValue सामान्य रूप से apply हो सकता है?

        @Override
        public Object apply(@Nullable Class<?> clazz, @Nullable Class<?>[] itemTypes) {
            Parcel source = mSource;
            if (source != null) {
                synchronized (source) {
                    // Check mSource != null guarantees callers won't ever see different objects.
                    if (mSource != null) {
                        int restore = source.dataPosition();
                        try {
                            source.setDataPosition(mPosition);
                            mObject = source.readValue(mLoader, clazz, itemTypes);
                        } finally {
                            source.setDataPosition(restore);
                        }
                        mSource = null;
                    }
                }
            }
            return mObject;
        }

  	/**
     * @see #readValue(int, ClassLoader, Class, Class[])
     */
    @Nullable
    private <T> T readValue(@Nullable ClassLoader loader, @Nullable Class<T> clazz,
            @Nullable Class<?>... itemTypes) {
        int type = readInt();
        final T object;
        if (isLengthPrefixed(type)) {
            int length = readInt();
            int start = dataPosition();
            object = readValue(type, loader, clazz, itemTypes);
            int actual = dataPosition() - start;
            if (actual != length) {
                Slog.wtfStack(TAG,
                        "Unparcelling of " + object + " of type " + Parcel.valueTypeToString(type)
                                + "  consumed " + actual + " bytes, but " + length + " expected.");
            }
        } else {
            object = readValue(type, loader, clazz, itemTypes);
        }
        return object;
    }

देखा जा सकता है कि वास्तविक readValue mPosition से शुरू होता है, फिर क्रमशः LazyType और objectLength पढ़ता है, और फिर सामान्य Value पढ़ने की प्रक्रिया में प्रवेश करता है, जैसे Parcelable को ClassName पढ़ने की आवश्यकता होती है, फिर createFromParcel निष्पादित होता है, पढ़ने के बाद, सामान्य Key-Value से कोई अंतर नहीं होता, और बाद के सीरियलाइज़ेशन पर कोई प्रभाव नहीं पड़ता। फिर से समीक्षा करें, Self-changed Bundle का मूल विचार read पूरा होने के बाद संशोधित करना है, यहाँ तो बस एक सामान्य आउट-ऑफ-बाउंड रीड है, ऐसा लगता है कि यह दिशा काम नहीं करेगी।

तो क्या LazyValue इस प्रक्रिया में apply नहीं होता? दूसरे शब्दों में, यह LazyValue के रूप में IPC में भाग लेना जारी रखता है, इस समय इसका writeToParcel फ़ंक्शन कॉल किया जाता है:

     public void writeToParcel(Parcel out) {
            Parcel source = mSource;
            if (source != null) {
                synchronized (source) {
                    if (mSource != null) {
                        out.appendFrom(source, mPosition, mLength);
                        return;
                    }
                }
            }
            out.writeValue(mObject);
        }

पूरा LazyValue सीधे कॉपी हो जाता है, जब तक कि mLength = 0 न हो। रुको! ऊपर उल्लेख किया गया है कि mLength = objectLength + 8 बाइट्स, और पैच जानकारी से ज्ञात होता है कि भेद्यता को ट्रिगर करने के लिए objectLength -8 होना चाहिए, तो इस समय mLength = 0 सत्य हो जाता है। दूसरे शब्दों में, इस परिदृश्य में पूरा LazyValue गायब हो जाता है, केवल String Key कॉपी होता है, जिससे एक लापता लेखन होता है, और Self-changed Bundle की शर्त सीधे पूरी हो जाती है।

कारण जानने के बाद, हम प्रतिलिपि बनाना शुरू कर सकते हैं, लेकिन इससे पहले, हमें थोड़ी और विस्तृत जानकारी की आवश्यकता है।

विवरण 1: दो प्रकार के Bundle

टूल डाउनलोड करें