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

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

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

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

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

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
CVE-2022-42864 — CVE-2022-42864 IOHIDFamily रेस कंडीशन के लिए प्रूफ-ऑफ-कॉन्सेप्ट | Kitploit
उपकरण/GitHubGitHub/muirey03/cve-2022-42864
भेद्यता विश्लेषणशोषणबाइनरी शोषण
GitHubmuirey03/cve-2022-42864

CVE-2022-42864

CVE-2022-42864 IOHIDFamily रेस कंडीशन के लिए प्रूफ-ऑफ-कॉन्सेप्ट

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

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

सभी देखें →

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

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

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

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

CVE-2022-42864: शैतानी कुकीज़

यह रिपॉजिटरी क्या है?

यह CVE-2022-42864 के लिए मेरा (अधूरा) proof-of-concept एक्सप्लॉइट है, जो IOHIDFamily में एक time-of-check-time-of-use (TOCTOU) भेद्यता है, जिसे iOS 16.2 / macOS Ventura 13.1 में ठीक किया गया था।

proof-of-concept की स्थिति क्या है?

यह एक्सप्लॉइट वर्तमान में वही "arbitrary kfree" प्रिमिटिव प्राप्त करता है जो multicast_bytecopy एक्सप्लॉइट में उपयोग किया गया था। हालाँकि, multicast_bytecopy के आगे के एक्सप्लॉइट प्रवाह के विरुद्ध भारी शमन (mitigation) किया जा चुका है, इसलिए यह एक पूर्ण एक्सप्लॉइट नहीं है, यह केवल समस्या की गंभीरता को प्रदर्शित करता है।

क्या मुझे इसे चलाना चाहिए?

अगर आपको पूछना पड़ रहा है, तो नहीं। यह कुछ उपयोगी नहीं करता, यह केवल kernel panic उत्पन्न करता है। इस कोड के कारण होने वाली किसी भी डेटा हानि या अस्थिरता की जिम्मेदारी मैं नहीं लेता।

बग

जब यह समस्या ठीक की गई थी, तब स्रोत कोड में Apple की टिप्पणी इसे अच्छी तरह से संक्षेपित करती है:

// Find the number of cookies in the data. The data from elementData is shared with user space and may change at any time.

आइए पैच से पहले के फ़ंक्शन पर एक नज़र डालें (मैंने प्रासंगिक पंक्तियों को लेबल करने का प्रयास किया है):

IOReturn IOHIDDevice::postElementTransaction(const void* elementData, UInt32 dataSize, UInt32 completionTimeout, IOHIDCompletion * completion)
{
    IOReturn ret = kIOReturnError;
    uint32_t   cookies_[kMaxLocalCookieArrayLength];
    uint32_t   *cookies = cookies_;
    uint32_t   cookieCount = 0;
    uint32_t   cookieSize = 0;
    uint32_t   dataOffset = 0;
    uint8_t    *data = (uint8_t*)elementData;
    IOMemoryDescriptor *elementDesc = getMemoryWithCurrentElementValues();
    require(_elementArray && elementDesc, fail);

    WORKLOOP_LOCK;

    // Find the number of cookies in the data. Check that all cookies are valid elements.                   [1]
    while (dataOffset < dataSize) {
        const IOHIDElementValueHeader *headerPtr = (const IOHIDElementValueHeader *)(data + dataOffset);
        IOHIDElementPrivate *element = GetElement(headerPtr->cookie);
        if (!element) {
            HIDDeviceLogError("Could not find element for cookie: %d", headerPtr->cookie);
            ret = kIOReturnAborted;
            goto fail;
        }
        cookieCount++;

        require_noerr_action(os_add3_overflow(dataOffset, headerPtr->length, sizeof(IOHIDElementValueHeader), &dataOffset), fail, HIDDeviceLogError("Overflow iterating cookie data buffer %u %u", dataOffset, headerPtr->length));
    }
    // Data isn't as large as expected, don't overrun, just abort
    if (dataOffset != dataSize) {   //                                                                      [2]
        HIDDeviceLogError("Cookie data buffer is smaller than expected. %u vs. %u",
                        (unsigned int)dataSize, (unsigned int)dataOffset);
        ret = kIOReturnAborted;
        goto fail;
    }
    dataOffset = 0;

    require_noerr_action(os_mul_overflow(cookieCount, sizeof(uint32_t), &cookieSize),
                        fail,
                        HIDDeviceLogError("Overflow calculating cookieSize"));

    cookies = (cookieCount <= kMaxLocalCookieArrayLength) ? cookies : (uint32_t*)IOMallocData(cookieSize); // [3]

    if (cookies == NULL) {
        ret = kIOReturnNoMemory;
        goto fail;
    }

    // Update the elements, this replaced the shared kernel-user shared memory.
    for (size_t index = 0; dataOffset < dataSize; ++index) {    //                                          [4]
        const IOHIDElementValueHeader *headerPtr;
        IOHIDElementPrivate *element;
        OSData *elementVal;

        headerPtr = (const IOHIDElementValueHeader *)(data + dataOffset);
        element = GetElement(headerPtr->cookie);
        dataOffset += headerPtr->length + sizeof(IOHIDElementValueHeader);

        elementVal = OSData::withBytesNoCopy((void*)headerPtr->value,
                                            headerPtr->length); //                                          [5]
        require_action(elementVal, fail, ret = kIOReturnNoMemory);
        element->setDataBits(elementVal);
        elementVal->release();

        cookies[index] = headerPtr->cookie; //                                                              [6]
    }

    // Actually post elements
    ret = postElementValues((IOHIDElementCookie *)cookies, (UInt32)cookieCount, 0, completionTimeout, completion);

fail:
    WORKLOOP_UNLOCK;
    if (cookies != &cookies_[0]) {
        IOFreeData(cookies, cookieSize);
    }

    return ret;
}
  • [1] पर लूप बफर में IOHIDElementValue की संख्या गिनता है, और इस गिनती को cookieCount में संग्रहीत करता है।
  • [2] पर जाँच (while लूप की शर्त के साथ संयुक्त) यह सुनिश्चित करेगी कि प्रत्येक हेडर का length फ़ील्ड elementData बफर की सीमा से बाहर न फैले (न ही यह बफर के अंत से पहले समाप्त हो सकता है, हालाँकि यह कम प्रासंगिक है)।
  • एक बार सभी तत्वों की गिनती और sanity-check इस लूप द्वारा हो जाने के बाद, [3] पर cookieCount * 4 आकार के साथ हीप (heap) में एक cookies बफर आवंटित किया जाता है (या यदि cookieCount पर्याप्त छोटा है तो एक स्टैक बफर उपयोग किया जाता है)।
  • फिर [4] पर एक दूसरा लूप बफर के माध्यम से दूसरी बार गुजरता है, IOHIDElementValue को फिर से पार्स करता है।
  • [5] पर प्रत्येक तत्व का मान रखने के लिए OSData ऑब्जेक्ट बनाए जाते हैं, जो पहले लूप में मान्य किए गए length फ़ील्ड का उपयोग करते हैं।
  • [6] पर, प्रत्येक तत्व का cookie [3] पर आवंटित cookies सरणी में लिखा जाता है।

तो समस्या क्या है? यह फ़ंक्शन पूरी तरह से सही व्यवहार करता है जब elementData गैर-परिवर्तनशील (non-volatile) होता है, समस्या तब आती है जब विधि को साझा मेमोरी के साथ बुलाया जाता है। अब आती है IOHIDInterface::SetElementValues_Impl DriverKit विधि:

kern_return_t
IMPL(IOHIDInterface, SetElementValues)
{
    IOReturn ret = kIOReturnError;
    UInt8 *values = NULL;
    IOBufferMemoryDescriptor *md = NULL;
    
    md = OSDynamicCast(IOBufferMemoryDescriptor, elementValues);
    require_action(md && count, exit, ret = kIOReturnBadArgument);

    values = (UInt8 *)md->getBytesNoCopy();
    
    // Post the data to the device
    ret = _owner->postElementTransaction(values, (UInt32)md->getLength());
    require_noerr_action(ret, exit, HIDServiceLogError("postElementValues failed: 0x%x", ret));

exit:
    return ret;
}

यहाँ, postElementTransaction को md->getBytesNoCopy() के साथ बुलाया जाता है, जो userspace के साथ साझा की गई मेमोरी है, जो इस धारणा का उल्लंघन करती है कि elementData गैर-परिवर्तनशील है। elementData बफर की सामग्री [1] पर लूप के बाद, लेकिन [4] पर लूप से पहले बदल सकती है, तो एक हमलावर के लिए इसका क्या अर्थ है?

एक हमलावर इसका दुरुपयोग दो तरीकों से कर सकता है:

  • पहला तरीका है बफर के अंत में एक छोटे IOHIDElementValueHeader के length को बहुत बड़े मान में बदलना। इसका मतलब है कि जब [5] पर OSData बनाया जाता है, तो यह elementData बफर की सीमा से कहीं बाहर तक फैल जाएगा, जिससे एक हमलावर IOHIDInterface::GetElementValues_Impl का उपयोग करके out-of-bounds डेटा पढ़ सकता है।
  • दूसरा तरीका है बफर की शुरुआत में एक बड़े IOHIDElementValueHeader के length को बहुत छोटे मान में बदलना। यह [4] पर लूप को मूल रूप से [1] पर लूप में गिने गए हेडरों की तुलना में कई अधिक हेडर पार्स करने के लिए बना देगा, इसलिए जब [6] पर cookies सरणी में कुकीज़ लिखी जाती हैं, तो वे सरणी से बाहर overflow हो जाएँगी क्योंकि index को कभी भी cookieCount के विरुद्ध मान्य नहीं किया जाता।

व्यवहार में, यह एक हमलावर को मनमाने आकार का out-of-bounds kernel heap डेटा पढ़ने और मनमाना डेटा (फिर से मनमाने आकार का) out-of-bounds kernel heap में लिखने की अनुमति देता है। ये दो शक्तिशाली प्रिमिटिव हैं।

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