на каком языке пишут эксплойты
Linux exploits
Операционная система Linux доказала миру всю силу Open Source проектов — благодаря ей у нас сегодня есть возможность заглянуть в исходный код рабочей ОС и на его основе собрать свою собственную систему для решения тех или иных задач. По причине своей открытости Linux должна была стать самой безопасной операционной системой в мире, так как открытый исходный код позволяет развивать и улучшать подсистемы защиты от атак на ОС и совершенствовать саму операционную систему. Действительно, на данный момент существует большое количество созданных комьюнити защит: сегодня уже не так просто проэксплуатировать уязвимости типа переполнения буфера для получения повышенных привилегий так же, как 20 лет назад. Тем не менее, сегодня можно в открытом доступе встретить эксплойты, которые даже на последних версиях ядра могут повысить привилегии пользователя. Рассмотрим в этой статье, как это работает и почему так получается. Мы пройдемся по основным составляющим эксплойтов и рассмотрим, как работают некоторые из них.
Вся предоставленная информация была собрана исключительно в ознакомительных целях.
Типы эксплойтов
Выберем общий термин, которым будем обозначать, что есть эксплойт — алгоритм, который нарушает нормальное функционирование операционной системы, а именно — механизмы разграничения доступа. Также введем понятие уязвимости — это несовершенство программного обеспечения, которое может быть использовано алгоритмом эксплойта. Без уязвимости существование эксплойта невозможно.
Введем классификацию эксплойтов. Базовое разделение эксплойтов на подгруппы для любой операционной системы начинается на уровне архитектуры. Сегодня операционные системы включают в себя как минимум 2 уровня привилегий, которые используют для своей работы. Ниже приведен рисунок, который наглядно показывает разделение привилегий. Картинка взята отсюда.
Картинка очень наглядно показывает, что в операционной системе присутствует уровень Ядра (Kernel Space), обычно это самый привилегированный режим, именно здесь находится то, что мы называем операционной системой. И второй уровень — Пользовательский (User Space): здесь запускаются обычные приложения и сервисы, которые мы используем каждый день.
Исторически сложилось, что для каждого из перечисленных выше уровней могут быть найдены уязвимости, для которых может быть создан эксплойт, но эксплойты для каждого из уровней имеют свои ограничения.
На пользовательском уровне любой эксплойт, который затрагивает приложение, будет иметь ровно те привилегии, которые использовал пользователь, который запустил уязвимое приложение. Поэтому такой вид эксплойтов позволяет получить полное управление над ОС только в случае запуска приложения администратором системы. В противоположность пользовательскому уровню, уровень ядра, если содержит уязвимый код, может сразу дать возможность управлять операционной системой с максимальными привилегиями. Ниже сфокусируемся на исследовании этих эксплойтов.
Эксплойты
Представим небольшую статистику по раскрытию уязвимостей для ядра операционной системы Linux дистрибутивов Debian, SUSE, Ubuntu, Arch Linux последних 4-х лет.
Данные взяты отсюда. Картина не претендует на полноту, но показывает, что уязвимостей достаточно много, и даже сегодня есть из чего выбирать для построения эксплойта. Давайте попробуем описать, что из себя представляет эксплойт.
Любой эксплойт для любого уровня операционной системы сегодня состоит из частей, которые должны быть имплементированы в его коде:
1) Выставление необходимого отображения памяти
2) Создание необходимых объектов в ОС
3) Обход механизмов защиты ОС для используемой уязвимости
Вызов уязвимой части ПО.
Выполняет полезную нагрузку:
1) Для открытия доступа к ОС
2) Для изменения конфигурации ОС
3) Для вывода ОС из строя
При выполнении всех пунктов, которые указаны выше, можно написать работоспособный эксплойт. Возьмем для исследования несколько эксплойтов прошлых лет и попробуем выяснить, можно ли найти какие-то закономерности или заимствования, которые используются для нарушения разграничений доступа в операционной системе Linux. В качестве объектов исследования возьмем эксплойты, которые используют следующие уязвимости с CVE идентификаторами:
Разбор эксплойтов
Как автор эксплойта использует данную уязвимость и какая выполняется полезная нагрузка, рассмотрим дальше.
Подготовительный этап
За этот этап отвечает следующая часть кода.
Вызов уязвимого кода
Полезная нагрузка
Обезопасить себя без обновления ОС можно, если внести следующие изменения в конфиг: sudo sysctl kernel.unprivileged_bpf_disabled=1
Эксплойт, который создан для того, чтобы использовать описанную уязвимость, выполняет те же операции, что и эксплойт CVE-2020-8835. Алгоритм эксплойта следующий:
Загрузить код с обработкой 64 битных операций в память
Создать сокет и отправить данные для вызова команд ebpf
Найти в памяти адрес структуры taskstruct за счет выполнения команд в виртуальной машине
Модифицировать значения uid,gid,sgid и запустить интерактивную оболочку.
Автор писал исходный код с новыми фишками и дополнительными функциями. Предлагаем читателю самостоятельно взглянуть на код. Перечисленные этапы работы эксплойта выше не дадут запутаться.
Защита от этой уязвимости без использования обновления такая же: sudo sysctl kernel.unprivileged_bpf_disabled=1
Что в итоге?
На основании двух эксплойтов, который были рассмотрены в статье, можно предположить, что повышение привилегий в современной ОС Linux — это больше не темная магия программирования, а вполне отлаженный шаблонный процесс, который включает в себя переиспользование функций и объектов в оперативной памяти. При этом даже не нужно писать базонезависимый (shellcode) код, который будет выполнять большую часть действий. Достаточно просто изменить идентификаторы, которые используются для назначения привилегий для пользователей.