В данном цикле статей мы рассмотрим написание эксплоитов уровня ядра в ОС Windows.
Автор: Mohamed Shahat
Эта серия статей появилась по двум причинам. Во-первых, мне нравится работать с проектом HackSysExtremeVulnerableDriver. Во-вторых, я получил массу пожеланий, чтобы осветить эту тему.
Весь код, используемый при написании этой серии, находится в моем репозитории.
В данном цикле статей мы рассмотрим написание эксплоитов уровня ядра в ОС Windows. Важно отметить, что мы будем иметь дело с известными уязвимостями, и в реверс-инжиниринге нет необходимости (по крайней мере, для драйвера).
Предполагается, что после ознакомления со всеми статьями вы будете знать все наиболее распространенные классы брешей и методы эксплуатации, а также сможете портировать эксплоиты с архитектуры x86 на архитектуру x64 (если возможно) и ознакомитесь с новыми методами защиты в Windows 10.
Схема отладки ядра
В отличие от отладки на уровне пользователя, когда приостанавливается выполнение отдельного процесса, на уровне ядра задействуется вся система, и мы не сможем воспользоваться этим методом. Соответственно, нужна отдельная отладочная машина, которая сможет осуществлять коммуникацию с системой, где отлаживается ядро, просматривать память и структуры ядра, а также отлавливать крахи системы.
Дополнительный материал для изучения:
Эксплуатация уязвимостей ядра
Этот процесс проходит намного веселее, чем эксплуатация на уровне пользователя J.
Главная цель – добиться привилегированного выполнения в контексте ядра. А дальше уже все зависит от нашего воображения, начиная от застолья с домашним пивом и заканчивая внедрением вредоносов, спонсируемых государством.
В целом, наша задача заключается в том, чтобы получить шелл с системными привилегиями.
Темы статей этого цикла
- Часть 1: Настройка рабочей среды
- Конфигурирование трех виртуальных машин и системы, которая будет выступать в роли отладчика.
- Конфигурирование отладчика WinDBG.
- Часть 2: Полезные нагрузки
- Изучение наиболее распространенных полезных нагрузок. В последующих частях будут рассматриваться конкретные уязвимости и, при необходимости, указываться ссылки на эту статью.
- Остальные части.
- Рассмотрение уязвимостей.
Жизненный цикл разработки эксплоита уровня ядра
- Нахождение уязвимости. Эта тема не будет рассматриваться в данном цикле, поскольку мы уже точно знаем, где находятся бреши.
- Перехват потока выполнения. Некоторые уязвимости предусматривают выполнение кода, для некоторых есть дополнительные требования.
- Расширение привилегий. Главная цель – получить шелл с системными привилегиями.
- Восстановление потока выполнения. Неучтенные исключения на уровне ядра приводят к краху системы. Если вы не собираетесь писать эксплоит для DoS-атаки, следует учитывать этот факт.
Типы целевых систем
Мы будем работать с уязвимостями в следующих системах (конкретная версия не принципиальна):
- Win7 x86 VM
- Win7 x64 VM
- Win10 x64 VM
Начнем с архитектуры x86, и далее будем портировать эксплоит для системы Win7 x64. Некоторые эксплоиты не будут запускать на машинах с Win10 из-за присутствия новых защит. В этом случае мы либо будем изменять логику работы эксплоита, либо будем использовать полностью другой подход.
Используемое программное обеспечение:
- Windows 7 x86 VM
- Windows 7 x64 VM
- Windows 10 x64 VM
Настройка систем для отладки
Отладочные системы, с которыми мы будем взаимодействовать, предназначены для загрузки уязвимого драйвера. На этих машинах часто будут возникать крахи, поскольку большинство исключений в ядре способствуют явлениям подобного рода. Необходимо выделить достаточно оперативной памяти для этих систем.
На каждой машине, которая будет отлаживаться, нужно сделать следующее:
- Внутри директории VirtualKD запустите файл target\vminstall.exe. Добавится новая загрузочная запись и будут доступны функции отладки и автоматическое подключение к серверу VirtualKD, установленному в системе, которая выступает в роли отладчика.
В случае с Windows 10 VM необходимо включить режим test signing, который позволяет загружать неподписанные драйвера в ядро.
После выполнения команды bcdedit /set testsinging on и перезагрузки на рабочем столе появится надпись «Test Mode».
Примечание: Windows 10 позволяет осуществлять отладку ядра через сеть. Этот способ, на мой взгляд, быстрее.
- Запустите OSR Driver Loader. Зарегистрируйте и запустите службу. Возможно, потребуется перезагрузка.
- Установите дополнения на гостевой виртуальной машине (необязательное условие).
- Добавьте учетную запись с низкими привилегиями, которая понадобится во время эксплуатации.
C:\Windows\system32>net user low low /add
The command completed successfully.
Настройка отладчика
В системе, которая будет выступать в роли отладчика, будет использоваться WinDBG. Вы сможете инспектировать память, структуры данных и при необходимости выполнять манипуляции. Наличие удаленной отладочной сессии во время падения целевой системы позволит нам подключаться к виртуальной машине и анализировать крахи.
Хост VirtualKD будет выполнять коммуникацию автоматически через именованный канал, вместо установки соединения вручную. Если вы отлаживаете через сеть в Win10 VM, потребуется протестировать соединение вручную.
- Проверьте, что установлен отладчик WinDBG. По умолчанию используется папка C:\Program Files (x86)\Windows Kits\10\Debuggers.
Добавьте этот путь в качестве системного и установите путь к отладчику в VirtualKD
Перезапустите гостевые виртуальные машины. Система с VirtualKD, используемая в качестве отладчика, должна быть запущена. После перезагрузки вы сможете начать сессию в WinDBG.
Настройка WinDBG
Символы содержат отладочную информацию для множества бинарных файлов в ОС Window. Загрузить символы можно при помощи следующей команды:
.sympath srv*c:\Symbols*http://msdl.microsoft.com/download/symbols;C:\HEVD
.reload /f *.*
Включаем режим подробного информирования процесса отладки.
ed nt!Kd_Default_Mask 0xf
Должен загрузиться модуль HEVD:
kd> lm m HEVD
Browse full module list
start end module name
fffff80b`92b50000 fffff80b`92b59000 HEVD (deferred)
Сохраняем настройки профиля и любые изменения рабочей среды:
File -> Save Workspace to File
Введите команду g или нажмите клавишу F5 для продолжения выполнения (перечень других команд, которые вам могут пригодиться, хорошо описан в этом документе).
Краткое описание модуля HEVD
Процедура DriverEntry является стартовой для каждого драйвера:
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) {
UINT32 i = 0;
PDEVICE_OBJECT DeviceObject = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
UNICODE_STRING DeviceName, DosDeviceName = {0};
UNREFERENCED_PARAMETER(RegistryPath);
PAGED_CODE();
RtlInitUnicodeString(&DeviceName, L"\\Device\\HackSysExtremeVulnerableDriver");
RtlInitUnicodeString(&DosDeviceName, L"\\DosDevices\\HackSysExtremeVulnerableDriver");
// Create the device
Status = IoCreateDevice(DriverObject,
0,
&DeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&DeviceObject);
...
}
- Эта процедура содержит вызов функции IoCreateDevice, содержащей имя драйвера, которое мы будем использовать во время коммуникации.
- Для нас важен указатель функции, связанный с процедурой DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL], отвечающей за обработку IOCTL (I/O Control; управление вводом/выводом);
- В HEVD эта функция называется IrpDeviceIoCtlHandler, которая представляет собой большое условное выражение со множеством ответвлений для каждого IOCTL. Каждая уязвимость имеет уникальный IOCTL.
Пример: HACKSYS_EVD_IOCTL_STACK_OVERFLOW представляет собой IOCTL, используемый для активации бреши, связанной с переполнением стека.
На этом первая часть завершается. В следующей статье мы поговорим о полезных нагрузках. На данный момент доступна только полезная нагрузка, предназначенная для кражи токенов, которая будет использоваться в третьей части.
P.S. Я понимаю, что существует масса тонкостей и проблем, с которыми вы можете столкнуться. Поскольку в этом цикле основное внимание уделяется разработке эксплоитов, вам придется решать все попутные проблемы самостоятельно. Однако все возникающие вопросы вы можете задавать в комментариях.