
# Учебный пример и руководство по разработке эксплойта для CVE-2022-0185 Учебный пример и пошаговое руководство по разработке эксплойта для CVE-2022-0185 — переполнения буфера в куче ядра Linux, позволяющего повысить привилегии локально. Включает POC, отладку в QEMU и эксплойт для Ubuntu с подробным техническим анализом.
Это тематическое исследование является результатом задания по курсу ECE 9069: Introduction to Hacking : https://whisperlab.org/introduction-to-hacking/
CVE-2022-0185 — это ошибка переполнения буфера в куче (heap-based buffer overflow), обнаруженная в том, как функция legacy_parse_param в функциональности Filesystem Context ядра Linux проверяет длину переданных параметров. Непривилегированный локальный пользователь (в случае, если включены непривилегированные пользовательские пространства имён; в противном случае требуется привилегия CAP_SYS_ADMIN в пределах пространства имён), способный открыть файловую систему, которая не поддерживает API Filesystem Context (и, таким образом, переключается на устаревшую обработку), мог использовать эту ошибку для повышения своих привилегий в системе. [1]
После сообщения об этой уязвимости был выпущен патч для исправления ошибки:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=722d94847de2
https://ubuntu.com/security/CVE-2022-0185#impact-score
Существует подробный разбор от исследователя: https://www.hackthebox.com/blog/CVE-2022-0185:_A_case_study
В этом репозитории я объясню основные шаги и сопутствующую справочную информацию для воспроизведения этой уязвимости. Кроме того, если что-то останется для вас неясным, вы можете написать мне на почту: [email protected]. Я с удовольствием отвечу на ваши вопросы.
Уязвимость CVE-2022-0185 была опубликована 11.02.2022, с базовой оценкой CVSS 3.x 8.4 (High).[1] Эта уязвимость представляет собой переполнение буфера в куче, вызванное целочисленным переполнением беззнакового целого (unsigned integer underflow).
Уязвимость была внесена в ядро Linux v5.1, затрагивая все дистрибутивы Linux с версиями ядра выше 5.1. Например, Ubuntu 20.04 LTS (focal) была уязвима к этой ошибке. Однако патч был выпущен и доступен начиная с версии 5.4.0-96.109.[3]
Эксплуатация этой уязвимости позволяет непривилегированному локальному пользователю повысить свои привилегии в системе, потенциально ставя под угрозу всю систему.[1] [2] Вот подробный анализ оценки CVSS: Базовая оценка: 8.4, что указывает на значительный риск безопасности, требующий немедленного внимания. Оценка воздействия: 5.9, что предполагает существенный потенциальный ущерб в случае эксплуатации. Высокие значения конфиденциальности, целостности и доступности способствуют этой оценке. Оценка эксплуатируемости: 2.5, что предполагает относительно высокую эксплуатируемость. Локальный вектор атаки, высокие значения целостности и доступности способствуют этой оценке.
Таблица 1.1 и Таблица 1.2 содержат дополнительную информацию об этих оценках и их компонентах.
| Серьёзность CVSS v3.1 | Значение |
|---|---|
| Базовая оценка | 8.4 HIGH |
| Оценка воздействия | 5.9 |
| Оценка эксплуатируемости | 2.5 |
Таблица 1.1 Оценки серьёзности CVSS[1]
| Метрики CVSS v3.1 | Значение |
|---|---|
| Вектор атаки (AV) | Локальный |
| Требуемые привилегии (PR) | Отсутствуют |
| Взаимодействие с пользователем (UI) | Отсутствует |
| Конфиденциальность (C) | Высокая |
| Целостность (I) | Высокая |
| Доступность (A) | Высокая |
Таблица 1.2 Вектор CVSS[1]
В современных компьютерах существуют два типа целых чисел: знаковые и беззнаковые. Представление знаковых чисел обычно включает операцию, называемую дополнительным кодом.[4] «В дополнительном коде старший двоичный разряд используется как знак, указывающий, является ли двоичное число положительным или отрицательным»[4]
Введение дополнительного кода преобразует операцию вычитания в сложение, тем самым упрощая проектирование и реализацию ЦП. Преобразование целого числа в дополнительный код включает три шага:[4]
Рис. 2.1.1.1 показывает процесс преобразования на схеме с реальным примером преобразования «-6» в формат дополнительного кода.

Рис. 2.1.1.2 Сложение с использованием дополнительного кода
Рисунок 2.1.1.2 показывает процесс сложения дополнительного кода «-6» с «+6». Это демонстрирует, как использование дополнительного кода позволяет использовать сложение в качестве замены вычитания.

Рис. 2.1.1.2 Сложение с использованием дополнительного кода
Из раздела 2.1.1 мы уже знаем, что такое дополнительный код. Теперь рассмотрим сценарий переполнения беззнакового целого в компьютерах. В современных компьютерах при использовании беззнаковых чисел самый старший бит не рассматривается как знаковый; вместо этого он является частью самого беззнакового числа. Это означает, что при выполнении вычитания с беззнаковым числом нужно быть осторожным, так как это может привести к состоянию, известному как переполнение беззнакового целого.[5]
Рис. 2.1.2.1 иллюстрирует ситуацию вычитания 6 из 5 для 8-битного беззнакового числа. Конечным результатом является 255 из-за зацикливания беззнакового числа. Когда такое переполнение происходит в условном операторе, оно может нарушить функциональность этого оператора.

Рис. 2.1.2.1 Переполнение беззнакового целого
В ядре Linux Allocator Slab (Slab Allocator) — это механизм управления памятью, используемый для эффективного выделения и освобождения небольших блоков памяти. Он обеспечивает производительность, поддерживая несколько кэшей слэбов, каждый из которых содержит блоки памяти фиксированного размера. Как правило, kmalloc-32 выделяет 32 байта памяти, это слэб kmalloc-32, тогда как kmalloc-4k выделяет 4096 байт памяти, это слэб kmalloc-4k.[6]
Кроме того, выделение слэбов в ядре Linux обычно включает выделение памяти из непрерывного адресного пространства в области кучи ядра. Это непрерывное адресное пространство управляется ядром и используется для выделения памяти для различных объектов ядра и структур данных. Рис. 2.2.1.1 показывает расположение слэбов в памяти ядра Linux.

Рис. 2.2.1.1 Аллокатор Slab в Linux [7] (Автор этого рисунка — https://leviathan.vip/)
Если вы хотите воспроизвести процесс с самостоятельно скомпилированным ядром Linux, пожалуйста, прочитайте следующие markdown-файлы, чтобы получить справочную информацию:
Примечание:
Все markdown-файлы, а также код и скрипты находятся в разных папках этого репозитория. В каждой папке есть собственный markdown-файл. Прочитайте его, прежде чем пытаться что-либо сделать!