Skip to content
KitploitKITPLOIT
ИнструментыБлог
Log in
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2022-0847-DirtyPipe — Глубокий анализ и proof-of-concept эксплойт для CVE-2022-0847 (DirtyPipe), уязвимости ядра Linux, позволяющей произвольную перезапись файлов и локальное повышение привилегий через неинициализированные флаги буфера канала (pipe). | Kitploit
Инструменты/GitHubGitHub/greetdawn/cve-2022-0847-dirtypipe
Повышение привилегийАнализ уязвимостейЭксплуатацияТестирование на ПроникновениеОбучение и ОбразованиеЭксплуатация Бинарных Файлов
GitHubgreetdawn/cve-2022-0847-dirtypipe

CVE-2022-0847-DirtyPipe

Глубокий анализ и proof-of-concept эксплойт для CVE-2022-0847 (DirtyPipe), уязвимости ядра Linux, позволяющей произвольную перезапись файлов и локальное повышение привилегий через неинициализированные флаги буфера канала (pipe).

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
Репозиторий
114 лет назадЕщё не проверено

title: CVE-2022-0847 (DirtyPipe локальное повышение привилегий) анализ уязвимости date: 2022-03-08 14:41:20 tags: - Повышение привилегий в Linux categories: - Исследование безопасности


Описание уязвимости

CVE-2022-0847 — это уязвимость в ядре Linux, начиная с версии 5.8. Используя её, атакующий может перезаписывать данные в любых файлах, доступных только для чтения. Это позволяет повысить обычные привилегии до root, поскольку непривилегированный процесс может внедрять код в процессы с root-правами.

CVE-2022-0847 похожа на CVE-2016-5195 «Dirty Cow» (повышение привилегий Dirty Cow) и легко эксплуатируется. Автор уязвимости назвал её Dirty Pipe.

Заявление о безопасности

Этот блог предназначен в основном для изучения и фиксации событий безопасности и статей об уязвимостях, для обмена знаниями и тестирования. Любые прямые или косвенные последствия и ущерб, вызванные распространением или использованием информации и инструментов из этого блога, являются ответственностью использующего; автор статей не несёт за это никакой ответственности.

Затронутые версии

Уровень опасности: высокий

POC/EXP: опубликован

Затронутые версии: ядро linux 5.8 и более поздние версии

Примечание: безопасные версии: ядро Linux >= 5.16.11, ядро Linux >= 5.15.25, ядро Linux >= 5.10.102

Анализ уязвимости

Здесь кратко опишем детали уязвимости.

Несколько понятий:

Linux pipe: полудуплексный, поток данных может идти только с одного конца на другой.

pipe_buffer: трубный кэш, используемый для временного хранения данных, записываемых в канал; чтение и запись выполняются в трубном кэше.

page: страница (page frame), 4 КБ, имеет взаимно однозначное соответствие с трубным кэшем.

pipe_buf_operations: хранит набор операций трубного кэша.

can_merge: флаг слияния. Если для общих операций чтения/записи канала задано слияние данных в существующий буфер, то значение равно 1. Если значение равно 0, то для новых данных всегда используется новый сегмент страницы канала.

splice(): перемещает данные между двумя файловыми дескрипторами; как и функция sendfile(), поддерживает zero-copy для каналов. Она связывает кэш страниц файла с трубным кэшем, то есть запись влияет на оба одновременно. При проверке прав проверяется только право на чтение файла-источника; при записи проверка прав не выполняется. Примерная цепочка вызовов:

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

image-20220310151242149

История развития «слияния» в Linux-каналах:

Здесь кратко проанализируем код по описанию автора.

  1. В первоначальной системе Linux всё было так, как описано в концепции: существовал флаг 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

  4. Commit 241699cd72a8 добавил две новые функции, которые могут выделять новый struct pipe_buf_operations, но при этом не инициализируют их флаги flags.

    image-20220310155046455

  5. Commit f6dd975583bd преобразовал это сравнение указателей в сравнение флага PIPE_BUF_FLAG_CAN_MERGE для каждого буфера, а также позволил внедрять PIPE_BUF_FLAG_CAN_MERGE. Одновременно были удалены определения и использование других типов buf_ops.

    image-20220310134233873

    image-20220310134337376

    image-20220310142420972

Поэтому у автора возникла следующая идея эксплуатации:

  1. Создать канал.
  2. Установить флаг PIPE_BUF_FLAG_CAN_MERGE в pipe_buffer.
  3. Очистить канал, затем добавить в него данные из целевого файла начиная с позиции перед целью. При этом splice связывает трубный кэш с кэшем страниц.
  4. Произвольно записать данные в канал. В этот момент write в конечном счёте вызывает copy_page_from_iter() для записи. Из-за флага PIPE_BUF_FLAG_CAN_MERGE запись выполняется напрямую.

Разбор эксплойта

/* 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];
Скачать инструмент