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

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

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

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

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

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
CVE-2022-2590-analysis — CVE-2022-2590 का गहन विश्लेषण, जो लिनक्स कर्नेल shmem में Dirty COW का एक वेरिएंट है, जिसमें मूल कारण, रेस कंडीशन और प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट शामिल हैं। | Kitploit
उपकरण/GitHubGitHub/moonnull/cve-2022-2590-analysis
भेद्यता विश्लेषणशोषणबाइनरी शोषण
GitHubmoonnull/cve-2022-2590-analysis

CVE-2022-2590-analysis

CVE-2022-2590 का गहन विश्लेषण, जो लिनक्स कर्नेल shmem में Dirty COW का एक वेरिएंट है, जिसमें मूल कारण, रेस कंडीशन और प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट शामिल हैं।

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

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

सभी देखें →

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

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

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

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

CVE-2022-2590, Dirty COW केवल shmem तक सीमित

लिनक्स कर्नेल संस्करण: Linux/x86 6.0.0-rc1 (commit 37887783b3fef877bf34b8992c9199864da4afcb)

परिचय:

यह भेद्यता हमलावर को UFFDIO_CONTINUE का उपयोग करके can_follow_write_pte फ़ंक्शन को संतुष्ट करके केवल-पठनीय साझा मेमोरी पृष्ठ पर मनमानी सामग्री लिखने की अनुमति देती है, जो FOLL_FORCE, FOLL_COW और pte_dirty की जाँच करता है।

विश्लेषण:

root@kitploit:~
/*
 * FOLL_FORCE can write to even unwritable pte's, but only
 * after we've gone through a COW cycle and they are dirty.
 */
static inline bool can_follow_write_pte(pte_t pte, unsigned int flags)
{
	return pte_write(pte) ||
		((flags & FOLL_FORCE) && (flags & FOLL_COW) && pte_dirty(pte));
}

उपरोक्त फ़ंक्शन यह निर्धारित करता है कि pte लिखने योग्य है या नहीं।

pte को लिखने योग्य माना जाता है, यदि यह निम्नलिखित शर्तों में से एक को पूरा करता है:

  1. pte के फ़्लैग्स में writable फ़्लैग शामिल हो।
  2. flags वेरिएबल में FOLL_FORCE और FOLL_COW फ़्लैग्स हों, और pte के फ़्लैग्स में dirty फ़्लैग शामिल हो।

शर्त 2 को संतुष्ट करने के लिए, निम्नलिखित तीन फ़्लैग्स को सेट करना आवश्यक है:

  1. FOLL_FORCE

    root@kitploit:~
static ssize_t mem_rw(struct file *file, char __user *buf, size_t count, loff_t *ppos, int write) { ... flags = FOLL_FORCE | (write ? FOLL_WRITE : 0); while (count > 0) { size_t this_len = min_t(size_t, count, PAGE_SIZE); if (write && copy_from_user(page, buf, this_len)) { copied = -EFAULT; break; } this_len = access_remote_vm(mm, addr, page, this_len, flags); // __get_user_pages with FOLL_FORCE on if (!this_len) { if (!copied) copied = -EIO; break; } ... }

उपरोक्त फ़ंक्शन /proc/<pid>/mem पर पढ़ने/लिखने के ऑपरेशन करता है।

इस फ़ंक्शन का उपयोग करके, आप FOLL_FORCE फ़्लैग चालू रहते हुए __get_user_pages फ़ंक्शन तक पहुँच सकते हैं।

हालाँकि FOLL_FORCE को ptrace में उपयोग किए जाने के लिए बनाया गया है, इसकी आवश्यकता निम्नलिखित commit में सिद्ध की गई है: https://github.com/torvalds/linux/commit/f511c0b17b081562dca8ac5061dfa86db4c66cc2

  • FOLL_COW

    root@kitploit:~
    /*
    * mmap_lock must be held on entry.  If @locked != NULL and *@flags
    * does not include FOLL_NOWAIT, the mmap_lock may be released.  If it
    * is, *@locked will be set to 0 and -EBUSY returned.
    */
    static int faultin_page(struct vm_area_struct *vma,
    	unsigned long address, unsigned int *flags, bool unshare,
    	int *locked)
    {
      ...
    
      /*
      * The VM_FAULT_WRITE bit tells us that do_wp_page has broken COW when
      * necessary, even if maybe_mkwrite decided not to set pte_write. We
      * can thus safely do subsequent page lookups as if they were reads.
      * But only do so when looping for pte_write is futile: in some cases
      * userspace may also be wanting to write to the gotten user page,
      * which a read fault here might prevent (a readonly page might get
      * reCOWed by userspace write).
      */
      if ((ret & VM_FAULT_WRITE) && !(vma->vm_flags & VM_WRITE))
        *flags |= FOLL_COW;
      return 0;
    }
    

    faultin_page फ़ंक्शन में FOLL_COW के साथ OR ऑपरेशन का उपयोग किया जा सकता है, जो Dirty COW के पैच का एक हिस्सा है।

    root@kitploit:~
    static long __get_user_pages(struct mm_struct *mm,
     		unsigned long start, unsigned long nr_pages,
     		unsigned int gup_flags, struct page **pages,
     		struct vm_area_struct **vmas, int *locked)
     {
     	...
     retry:
     		/*
     		 * If we have a pending SIGKILL, don't keep faulting pages and
     		 * potentially allocating memory.
     		 */
     		if (fatal_signal_pending(current)) {
     			ret = -EINTR;
     			goto out;
     		}
     		cond_resched();
    
     		page = follow_page_mask(vma, start, foll_flags, &ctx); // can_follow_write_pte
     		if (!page || PTR_ERR(page) == -EMLINK) {
     			ret = faultin_page(vma, start, &foll_flags,
     					   PTR_ERR(page) == -EMLINK, locked); // flags |= FOLL_COW
     			switch (ret) {
     			case 0:
     				goto retry; // try follow page again
     			case -EBUSY:
     			case -EAGAIN:
     				ret = 0;
     				fallthrough;
     			case -EFAULT:
     			case -ENOMEM:
     			case -EHWPOISON:
     				goto out;
     			}
     			BUG();
     		} else if (PTR_ERR(page) == -EEXIST) {
        ...
     }
    

    FOLL_COW फ़्लैग चालू रहते हुए can_follow_write_pte फ़ंक्शन तक पहुँचने के लिए, आपको __get_user_pages फ़ंक्शन के भीतर faultin_page फ़ंक्शन को कॉल करना होगा, retry लेबल पर रीडायरेक्ट करना होगा, और faultin_page फ़ंक्शन को फिर से कॉल करना होगा।

  • pte_dirty

    यह शर्त निम्नलिखित commit के कारण संतुष्ट की जा सकती है: https://github.com/torvalds/linux/commit/9ae0f87d009ca6c4aab2882641ddfc319727e3db

    root@kitploit:~
    /*
    * Install PTEs, to map dst_addr (within dst_vma) to page.
    *
    * This function handles both MCOPY_ATOMIC_NORMAL and _CONTINUE for both shmem
    * and anon, and for both shared and private VMAs.
    */
    int mfill_atomic_install_pte(struct mm_struct *dst_mm, pmd_t *dst_pmd,
    		     struct vm_area_struct *dst_vma,
    		     unsigned long dst_addr, struct page *page,
    		     bool newly_allocated, bool wp_copy)
    {
     	...
    
     	_dst_pte = mk_pte(page, dst_vma->vm_page_prot);
     	_dst_pte = pte_mkdirty(_dst_pte); // set pte dirty unconditionally
     	if (page_in_cache && !vm_shared)
     		writable = false;
    
     	...
    }
    

    उपरोक्त पैच के कारण, केवल-पठनीय साझा मेमोरी पृष्ठ के लिए pte को बिना किसी शर्त के dirty अवस्था में इंस्टॉल करना संभव है।

  •  

    यदि वे तीनों फ़्लैग्स संतुष्ट हो जाते हैं, तो can_follow_write_pte फ़ंक्शन true लौटाएगा।

    root@kitploit:~
    static struct page *follow_page_pte(struct vm_area_struct *vma,
    		unsigned long address, pmd_t *pmd, unsigned int flags,
    		struct dev_pagemap **pgmap)
    {
    	...
        
    	// true && !true == false
    	if ((flags & FOLL_WRITE) && !can_follow_write_pte(pte, flags)) {
    		pte_unmap_unlock(ptep, ptl);
    		return NULL;
    	}
    
    	page = vm_normal_page(vma, address, pte); // get read-only shared memory page
    
    	...
    
    out:
    	pte_unmap_unlock(ptep, ptl);
    	return page;
    no_page:
    	pte_unmap_unlock(ptep, ptl);
    	if (!pte_none(pte))
    		return NULL;
    	return no_page_table(vma, flags);
    }
    

    follow_page_pte फ़ंक्शन केवल-पठनीय साझा मेमोरी पृष्ठ लौटाता है।

    रेस परिदृश्य:

    निम्नलिखित PoC द्वारा सिद्ध किया गया रेस परिदृश्य है, जिसे बाद में प्रस्तुत किया जाएगा।

    madvise और readUFFDIO_CONTINUE ioctlpwrite
    madvise // पृष्ठ को zap करें
    shmem_fault // read fault
    handle_userfault
    userfaultfd_continue
    mcontinue_atomic_pte
    ret = shmem_getpage(inode, pgoff, &page, SGP_NOALLOC); // पृष्ठ प्राप्त करें
    mfill_atomic_install_pte
    _dst_pte = pte_mkdirty(_dst_pte); // pte को dirty करें
    set_pte_at(dst_mm, dst_addr, dst_pte, _dst_pte); // pte इंस्टॉल करेंmem_rw
    access_remote_vm // FOLL_FORCE के साथ
    __get_user_pages
    can_follow_write_pte // FOLL_COW नहीं, 0 लौटाएँ
    faultin_page
    flags
    retry:
    follow_page_pte
    madvise // पृष्ठ को zap करें
    shmem_fault // read fault
    handle_userfault
    userfaultfd_continue
    mcontinue_atomic_pte
    ret = shmem_getpage(inode, pgoff, &page, SGP_NOALLOC); // पृष्ठ प्राप्त करें
    mfill_atomic_install_pte
    _dst_pte = pte_mkdirty(_dst_pte); // pte को dirty करें
    set_pte_at(dst_mm, dst_addr, dst_pte, _dst_pte); // pte इंस्टॉल करें
    can_follow_write_pte // 1 लौटाएँ
    copy_to_user(buf, page, this_len) // केवल-पठनीय पृष्ठ पर सामग्री लिखें

    madvise और read रूटीन दो बार निष्पादित किए जाते हैं; पहला निष्पादन __get_user_pages के retry को प्रेरित करता है, और दूसरा निष्पादन follow_page_pte को उस पृष्ठ को लौटाने का मार्गदर्शन करता है, जो mfill_atomic_install_pte द्वारा dirty किए गए pte द्वारा इंगित किया गया है।

    PoC और पैच:

    https://www.openwall.com/lists/oss-security/2022/08/15/1

    आप उपरोक्त लिंक पर David Hildenbrand के reproducer की जाँच कर सकते हैं।

    हालाँकि, चूँकि reproducer सटीक रेस परिदृश्य को पहचानना कठिन बनाता है, मैंने अधिक रैखिक निष्पादन को प्राथमिकता देने के लिए reproducer को संशोधित किया, और तदनुसार, Linux कर्नेल स्रोत कोड को भी संशोधित किया।

    .config:

    root@kitploit:~
    ...
    CONFIG_USERFAULTFD=y
    CONFIG_HAVE_ARCH_USERFAULTFD_WP=y
    CONFIG_HAVE_ARCH_USERFAULTFD_MINOR=y
    ...
    

    PoC: (poc.c)

    पैच: (poc_deayzl.patch)

    परीक्षण के लिए, निम्नलिखित प्रारंभिक चरण पूरे किए जाने चाहिए। (david के reproducer में दिए गए निर्देश कहते हैं कि फ़ाइल पथ /tmp/foo है। लेकिन tmpfs वर्तमान संस्करण में साझा मेमोरी नहीं है, इसलिए userfaultfd register विफल हो जाता है)

    root@kitploit:~
    sudo -s
    echo "asdf" > /dev/shm/foo
    chmod 0404 /dev/shm/foo
    exit
    

    PoC चलाने के बाद, आप निम्नलिखित स्क्रीन देखेंगे।

    PoC-result

    संदर्भ:

    commit: https://github.com/torvalds/linux/commit/5535be3099717646781ce1540cf725965d680e7b

    lore.kernel पैच v1: https://lore.kernel.org/linux-mm/[email protected]/#r

    lore.kernel पैच v2: https://lore.kernel.org/all/[email protected]/T/#u

    openwall: https://www.openwall.com/lists/oss-security/2022/08/08/1

    openwall2: https://lists.openwall.net/linux-kernel/2022/08/08/418

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