Введение
Этот пост, как следует из названия, будет посвящен написанию драйверов ядра Windows для расширенного Персистенса. Поскольку тема довольно сложная, я решил разделить проект на три или четыре части. Это первая статья в серии, в ней будет представлена основная информация, которую вам необходимо знать, чтобы начать разработку ядра. Она включает настройку среды разработки, настройку удаленной отладки ядра и написание вашего первого драйвера «Hello World».
Если все пойдет по плану, последующие посты серии будут посвящены следующим темам:
Часть 2: Создание сетевого триггера для удаленного управления драйвером ядра
Часть 3: Создание процессов из ядра
В итоге у вас должен быть драйвер, который можно запускать удаленно с помощью пользовательского сетевого пакета для создания высокопривилегированных процессов в целевой системе. С учетом сказанного, давайте начнем!
Отказ от ответственности
Я пишу эти сообщения в блоге, когда сам изучаю и продвигаюсь по этой теме. Поэтому мне может потребоваться некоторое время, чтобы опубликовать последующие сообщения. Спасибо за ваше терпение и не стесняйтесь обращаться ко мне, если вы обнаружите какие-либо ошибки.
Требования
Чтобы приступить к разработке драйверов ядра, вам сначала нужно настроить лабораторную среду. Вот минимальные требования, которые вам понадобятся для начала работы:
64-битный процессор (4+ ядра)
8 ГБ ОЗУ
96 ГБ доступной памяти
Учетная запись Microsoft (для Visual Studio )
Программное обеспечение для виртуализации
Я буду использовать VMWare Workstation 16, однако можно использовать любое программное обеспечение, поддерживающее виртуализацию.
Windows 10 или 11 ISO
В качестве альтернативы вы также можете использовать тестовый образ MSEdge.
Лабораторная установка
Для лабораторной установки потребуются 2 виртуальные машины (ВМ). Один для разработки, а другой для тестирования драйвера ядра. Если вы планируете работать над этим проектом на компьютере с Windows, можно обойтись только тестовой виртуальной машиной. Однако для этого вам потребуется установить все инструменты разработки на хост-компьютере, чего я бы не рекомендовал.
Если вам интересно, зачем вам отдельная виртуальная машина для тестирования, есть несколько причин.
- Для эффективной отладки ядра необходима отдельная тестовая виртуальная машина, так как локальная отладка ядра имеет множество ограничений, таких как невозможность установки правильных точек останова.
-Из-за критической природы ядра незначительные ошибки в коде драйвера могут привести к появлению в системе синих экранов смерти ( BSOD ), поскольку ядро, в отличие от пользовательских процессов, использует единое пространство памяти для всех своих драйверов и других ресурсов.
С этим покончено, давайте запачкаем же руки.
Лабораторная сеть
Прежде чем мы начнем настраивать виртуальные машины, давайте настроим тестовую сеть.
Сначала откройте редактор виртуальной сети VMWare от имени администратора:
Затем нажмите на Add Network... и выберите любую неназначенную сеть ( в моем случае VMNet19 ):
После нажатия OK вы должны вернуться в главное меню и должны увидеть только что созданную сеть в своем списке сетей. Выберите её и настройте с помощью адаптера только для хоста вместе с соответствующей информацией о подсети.
В этой статье я буду работать с подсетью 10.10.20.0/24, где виртуальной машине разработки будет присвоен IP-адрес 10.10.20.2 , а виртуальной машине тестирования — IP-адрес 10.10.20.3
Примечание
Поскольку сеть только для хоста не обеспечивает доступ к Интернету для виртуальных машин, важно назначить обеим виртуальным машинам два разных сетевых адаптера, например адаптер NAT и адаптер, который мы только что создали. Сеть NAT обеспечит доступ в Интернет для обеих виртуальных машин, а сеть только для хоста будет использоваться для связи между ними.
Одним из преимуществ этой настройки является то, что после настройки обеих машин мы можем удалить адаптер NAT с обеих виртуальных машин, чтобы получить изолированную сеть без исходящего доступа в Интернет. Это устраняет риск случайной отправки образца антивирусу и позволяет нам также изменять настройки брандмауэра виртуальных машин, не опасаясь атак из локальной сети.
Отказ от ответственности
Сообщение в блоге охватывает только установку необходимых компонентов для разработки ядра. Читатель должен завершить настройку, установив виртуальные машины Windows и настроив статические IP-адреса.
ВМ для разработки
Виртуальная машина разработки — это машина, на которой будет выполняться большая часть работы, поэтому я рекомендую выделить ей как минимум 4 ядра, 6 ГБ ОЗУ и 64 ГБ хранилища. Лично я буду использовать Windows 11 22H2, но Windows 10 будет работать отлично. Имея это в виду, давайте перейдем к фактической настройке.
Visual Studio 2022
По понятным причинам вам потребуется установить Visual Studio. При установке Visual Studio обязательно выберите разработку для настольных ПК с рабочей нагрузкой C++ и библиотеками устранения рисков Spectre. Если вы не можете найти библиотеки защиты, найдите их на вкладке «Отдельные компоненты».
Windows SDK
Нам также необходимо установить Windows Software Development Kit (SDK). Этот SDK содержит всю документацию, заголовочные файлы, библиотеки, примеры и инструменты, необходимые для разработки приложений для Microsoft Windows.
Больше ничего не нужно говорить. Как только вы начнете установку SDK, просто щелкайте по подсказкам установки, пока все не будет завершено.
Windows WDK
Помимо SDK нам также понадобится комплект драйверов Windows (WDK). WDK используется для разработки, тестирования и развертывания драйверов для Windows. При установке WDK обязательно установите расширение комплекта драйверов Visual Studio для Windows.
Примечание. Для правильной установки расширения необходимо закрыть Visual Studio .
WinDbg
Нам также понадобится отладчик. В этом случае мы будем использовать отладчик Windows ( WinDbg Preview ), который является важным инструментом для разработки ядра. В основном он будет использоваться для устранения неполадок нашего драйвера ядра в случае сбоев или неожиданного поведения.
Общий сетевой ресурс (необязательно)
В Visual Studio у нас есть возможность создавать так называемые события после сборки , которые могут запускать для нас множество полезных команд после того, как мы скомпилируем наш драйвер. Одним из таких событий после сборки, которое можно создать для упрощения процесса разработки, является копирование скомпилированного драйвера в папку (настроенную как сетевой ресурс). Этот сетевой ресурс будет использоваться для хранения всех встроенных драйверов, к которым может получить доступ тестовая виртуальная машина.
Если вы настроили свою лабораторию в соответствии с моими рекомендациями, вы можете избавить себя от необходимости настраивать общий ресурс с надлежащими элементами управления доступом и разрешениями. Просто дайте всем разрешения RWX, и все готово.
В конечном итоге ваша установка должна выглядеть примерно так:
Тестирование ВМ
Спецификации тестируемой виртуальной машины не имеют большого значения. Просто не забудьте дать ему достаточно мощности. Например, моя тестовая виртуальная машина была сконфигурирована с 2 ядрами, 4 ГБ ОЗУ и 32 ГБ хранилища. Опять же, он работает под управлением Windows 11 22H2, но у вас не должно быть никаких проблем, если вы используете Windows 10.
Данные конфигурации загрузки (BCD)
Далее нам нужно настроить BCD с помощью bcdedit команды. Откройте административную подсказку и введите следующие команды:
Первая команда включает отладку ядра, а вторая включает тестовую подпись. Отладка ядра позволяет нам отлаживать ядро машины, в то время как тестовая подпись отключает проверку подписи драйверов, позволяя нам загружать и тестировать наши пользовательские драйверы без необходимости соблюдать строгие правила безопасности драйверов Microsoft.
Обратите внимание, что включение тестовой подписи приведет к отображению предупреждающего водяного знака в правом нижнем углу машины:
Наконец, нам нужно включить удаленную отладку. Для этого мы можем использовать команду, аналогичную приведенной ниже:
Просто обратите внимание на то, чтобы задать hostip для свойства IP-адрес виртуальной машины разработки и установить для порта значение от 50000 до 50039. Кроме того, будьте осторожны, чтобы не перепутать IP-адреса машин разработки и тестирования. В этом случае мы хотим ввести IP-адрес компьютера для разработки, чтобы он мог подключиться к порту отладки.
Если все прошло так, как ожидалось, вы должны увидеть сгенерированный ключ, отображаемый в консоли:
Значение удаленной отладки будет объяснено позже. На данный момент убедитесь, что вы отложили сгенерированный ключ.
Брандмауэр
Чтобы предотвратить прерывания во время удаленной отладки, мы отключим брандмауэр. Для этого вы можете либо использовать графический интерфейс, либо выполнить следующую команду в административной строке:
Кроме того, вы также можете внести порт отладки в белый список через настройки, если вы предпочитаете не отключать брандмауэр полностью.
Отладка фильтра печати
Чтобы обеспечить вывод всех сообщений отладки ядра в отладчик, необходимо настроить фильтр печати отладки . Можно использовать следующую команду:
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter" /v Default /t REG_DWORD /d 0xf
Обратите внимание, что для того, чтобы это изменение вступило в силу, компьютер необходимо перезагрузить. Неважно, перезагрузите ли вы виртуальную машину сейчас или после ее настройки. Просто не забудьте перезагрузить его в какой-то момент.
Загрузчик драйверов OSR
OSR Driver Loader — это инструмент, который мы будем использовать для загрузки или «выполнения» нашего драйвера. Одно из основных преимуществ использования загрузчика OSR вместо ручной настройки служб Windows заключается в том, что он содержит удобный графический интерфейс пользователя, что упрощает его использование.
Улучшения QoL (необязательно)
Вот несколько дополнительных советов, которые могут помочь сэкономить время:
Если вы настроили сетевую папку, содержащую встроенные драйверы, вы можете смонтировать ее и добавить в удобное место, например на рабочий стол.
Поскольку вы, скорее всего, будете бесчисленное количество раз сталкиваться с синим экраном во время тестирования драйвера, может быть полезно включить автоматический вход в систему без пароля и сделать снимок работающей виртуальной машины, чтобы вы могли легко вернуться к ней в случае серьезного сбоя.
Разработка драйверов
Наконец-то мы можем начать процесс разработки!
Присоединение WinDbg
При включенной удаленной отладке ядра вы сможете удаленно подключаться к ядру тестируемой виртуальной машины из виртуальной машины разработки.
Для этого откройте свой компьютер для разработки и запустите WinDbg. Зайдите в главное меню и выберите Attach to kernel:
В Net подменю введите сведения о тестируемой ВМ:
В моем случае IP-адрес тестируемой ВМ — 10.10.20.3, порт — 50039 и ключ — это значение, которое я сказал вам сохранить ранее (ваш ключ будет другим).
После нажатия OK вы должны быть подключены к ядру тестовой машины:
С этого момента вы можете устанавливать точки останова, проверять адреса памяти и многое другое. Просто имейте в виду, что если вы установите точку останова, тестируемая виртуальная машина может перейти в приостановленное (замороженное) состояние. Вам нужно будет удалить все точки останова, чтобы виртуальная машина возобновила работу. Кроме того, WinDbg также будет использоваться для проверки вызовов отладочной печати из нашего драйвера. Поскольку у драйверов нет консоли, использование отладчика для просмотра сообщений — единственный доступный нам вариант.
Создание проекта
Теперь давайте продолжим и создадим первый проект кода ядра! Начните с открытия Visual Studio и выбора Create a new project. Затем найдите Kernel Mode Driver, Empty (KMDF)шаблон.
Подтвердите свой выбор и назовите проект HelloWorld. После того, как Visual Studio загрузит решение, щелкните правой кнопкой мыши Source Files, затем щелкните Add и, наконец New Item..., .
Откроется окно, в котором вам будет предложено выбрать элемент для добавления в проект. Выберите C++ File (.cpp)и назовите его Driver.c. На самом деле вы можете назвать его как хотите, просто убедитесь, что у файла есть .c расширение.
Привет, мир!
Мы подходим к хорошему! В этом разделе мы, наконец, приступим к написанию драйвера.
Предупреждение
Чтобы писать драйверы ядра, необходимо хорошо понимать язык программирования Си. Если вы не знакомы с C, рекомендуется освежить свои навыки, прежде чем продолжить.
Все драйверы требуют подпрограммы DriverEntry, отвечающей за инициализацию драйвера. Думайте об этом как о main функции в стандартных программах на C.
Мы можем создать простую DriverEntry процедуру для файла Driver.c, которая будет выглядеть так:
В дополнение к подпрограмме входа нам также нужно что-то, называемое подпрограммой «выход», которая вызывается каждый раз, когда драйвер выгружается. Основное различие между процедурой выхода и процедуры входа состоит в том, что процедура выхода не имеет предопределенного имени. Таким образом, нам нужно вручную указать процедуру выгрузки при инициализации драйвера.
В моем случае я создал новую процедуру выхода под названием DriverUnload. Обновленный файл Driver.c после добавления подпрограммы должен выглядеть так:
Это почти все, что касается программирования! Есть только одна проблема, которую нам нужно решить. Если вы попытаетесь создать решение сейчас, оно завершится ошибкой с несколько раздражающим сообщением об ошибке:
Поскольку ядро является критически важным компонентом операционной системы, и любые проблемы с драйвером могут иметь серьезные последствия, Microsoft выбрала осторожный подход к разработке. Поэтому решения, настроенные с помощью шаблона каркаса драйвера режима ядра ( KMDF ), всегда обрабатывают любые предупреждения как ошибки. Хотя это поведение можно отключить, делать это не рекомендуется, поскольку чем сложнее становится драйвер, тем сложнее будет устранять неполадки.
Вместо этого мы изменим наш код, чтобы устранить ошибку. Предупреждения указывают на наличие двух нессылочных параметров функции: driverObjectи registryPath. Вы можете либо использовать эти параметры где-то в своем коде, либо использовать макрос, UNREFERENCED_PARAMETER()чтобы пометить их как заведомо «неиспользуемые».
С этой настройкой драйвер должен быть наконец завершен:
Отсюда обязательно установите целевую архитектуру на x64 и создайте драйвер в режиме отладки. Если вы правильно выполнили все шаги, теперь у вас должен быть самый первый драйвер ядра HelloWorld.sys!
Примечание
Если вы получаете сообщение об ошибке, похожее на DriverVer set to incorrect dateто, когда вы пытаетесь построить свой проект, не беспокойтесь. Просто зайдите в свойства проекта и найдите конфигурацию Inf2Cat. Найдите строку с вопросом, хотите ли вы использовать местное время, и выберите Yes (/uselocaltime).
Загрузка драйвера
Теперь, когда драйвер скомпилирован, нам нужно перенести его на тестовую виртуальную машину, используя ранее созданный сетевой ресурс. Если вы не создавали сетевую папку, найдите альтернативный способ переноса драйвера.
Для демонстрации я поместил драйвер в папку «Документы». Для его загрузки я буду использовать приложение OSRLoader.
Вам не нужно ничего настраивать, кроме указания местоположения вашего драйвера. Однако обратите внимание, что когда вы загружаете драйвер в первый раз, вам нужно будет зарегистрировать его как службу. Для этого нажмите на кнопку Register Service. Вы получите предупреждение, которое сообщит вам, было ли действие успешным или нет. Если это было успешно, теперь вы можете нажать кнопку Start Service , чтобы загрузить драйвер, и Stop Service, чтобы выгрузить его!
Запустив службу и загрузив драйвер, давайте проверим WinDbg, чтобы убедиться, что драйвер работает должным образом. Вспомним, что мы запрограммировали драйвер на печать «Hello World» при загрузке и «Goodbye World» при выгрузке.
Идеально! Это именно то, что мы хотели!
Заключение
Спасибо, что дочитали до конца поста! Я ценю, что вы нашли время, чтобы прочитать его, и я надеюсь, что вы нашли его полезным и информативным. Имейте в виду, что это была только первая часть серии, так что следите за следующей! Если с моей стороны все пойдет хорошо, следующая часть должна охватывать процесс создания драйвера, который можно активировать удаленно с помощью пользовательских сетевых пакетов.
Переведено специально для xss.pro
Автор перевода: yashechka
Источник: https://v3ded.github.io/redteam/red...ernel-drivers-for-advanced-persistence-part-1
Этот пост, как следует из названия, будет посвящен написанию драйверов ядра Windows для расширенного Персистенса. Поскольку тема довольно сложная, я решил разделить проект на три или четыре части. Это первая статья в серии, в ней будет представлена основная информация, которую вам необходимо знать, чтобы начать разработку ядра. Она включает настройку среды разработки, настройку удаленной отладки ядра и написание вашего первого драйвера «Hello World».
Если все пойдет по плану, последующие посты серии будут посвящены следующим темам:
Часть 2: Создание сетевого триггера для удаленного управления драйвером ядра
Часть 3: Создание процессов из ядра
В итоге у вас должен быть драйвер, который можно запускать удаленно с помощью пользовательского сетевого пакета для создания высокопривилегированных процессов в целевой системе. С учетом сказанного, давайте начнем!
Отказ от ответственности
Я пишу эти сообщения в блоге, когда сам изучаю и продвигаюсь по этой теме. Поэтому мне может потребоваться некоторое время, чтобы опубликовать последующие сообщения. Спасибо за ваше терпение и не стесняйтесь обращаться ко мне, если вы обнаружите какие-либо ошибки.
Требования
Чтобы приступить к разработке драйверов ядра, вам сначала нужно настроить лабораторную среду. Вот минимальные требования, которые вам понадобятся для начала работы:
64-битный процессор (4+ ядра)
8 ГБ ОЗУ
96 ГБ доступной памяти
Учетная запись Microsoft (для Visual Studio )
Программное обеспечение для виртуализации
Я буду использовать VMWare Workstation 16, однако можно использовать любое программное обеспечение, поддерживающее виртуализацию.
Windows 10 или 11 ISO
В качестве альтернативы вы также можете использовать тестовый образ MSEdge.
Лабораторная установка
Для лабораторной установки потребуются 2 виртуальные машины (ВМ). Один для разработки, а другой для тестирования драйвера ядра. Если вы планируете работать над этим проектом на компьютере с Windows, можно обойтись только тестовой виртуальной машиной. Однако для этого вам потребуется установить все инструменты разработки на хост-компьютере, чего я бы не рекомендовал.
Если вам интересно, зачем вам отдельная виртуальная машина для тестирования, есть несколько причин.
- Для эффективной отладки ядра необходима отдельная тестовая виртуальная машина, так как локальная отладка ядра имеет множество ограничений, таких как невозможность установки правильных точек останова.
-Из-за критической природы ядра незначительные ошибки в коде драйвера могут привести к появлению в системе синих экранов смерти ( BSOD ), поскольку ядро, в отличие от пользовательских процессов, использует единое пространство памяти для всех своих драйверов и других ресурсов.
С этим покончено, давайте запачкаем же руки.
Лабораторная сеть
Прежде чем мы начнем настраивать виртуальные машины, давайте настроим тестовую сеть.
Сначала откройте редактор виртуальной сети VMWare от имени администратора:
Затем нажмите на Add Network... и выберите любую неназначенную сеть ( в моем случае VMNet19 ):
После нажатия OK вы должны вернуться в главное меню и должны увидеть только что созданную сеть в своем списке сетей. Выберите её и настройте с помощью адаптера только для хоста вместе с соответствующей информацией о подсети.
В этой статье я буду работать с подсетью 10.10.20.0/24, где виртуальной машине разработки будет присвоен IP-адрес 10.10.20.2 , а виртуальной машине тестирования — IP-адрес 10.10.20.3
Примечание
Поскольку сеть только для хоста не обеспечивает доступ к Интернету для виртуальных машин, важно назначить обеим виртуальным машинам два разных сетевых адаптера, например адаптер NAT и адаптер, который мы только что создали. Сеть NAT обеспечит доступ в Интернет для обеих виртуальных машин, а сеть только для хоста будет использоваться для связи между ними.
Одним из преимуществ этой настройки является то, что после настройки обеих машин мы можем удалить адаптер NAT с обеих виртуальных машин, чтобы получить изолированную сеть без исходящего доступа в Интернет. Это устраняет риск случайной отправки образца антивирусу и позволяет нам также изменять настройки брандмауэра виртуальных машин, не опасаясь атак из локальной сети.
Отказ от ответственности
Сообщение в блоге охватывает только установку необходимых компонентов для разработки ядра. Читатель должен завершить настройку, установив виртуальные машины Windows и настроив статические IP-адреса.
ВМ для разработки
Виртуальная машина разработки — это машина, на которой будет выполняться большая часть работы, поэтому я рекомендую выделить ей как минимум 4 ядра, 6 ГБ ОЗУ и 64 ГБ хранилища. Лично я буду использовать Windows 11 22H2, но Windows 10 будет работать отлично. Имея это в виду, давайте перейдем к фактической настройке.
Visual Studio 2022
По понятным причинам вам потребуется установить Visual Studio. При установке Visual Studio обязательно выберите разработку для настольных ПК с рабочей нагрузкой C++ и библиотеками устранения рисков Spectre. Если вы не можете найти библиотеки защиты, найдите их на вкладке «Отдельные компоненты».
Windows SDK
Нам также необходимо установить Windows Software Development Kit (SDK). Этот SDK содержит всю документацию, заголовочные файлы, библиотеки, примеры и инструменты, необходимые для разработки приложений для Microsoft Windows.
Больше ничего не нужно говорить. Как только вы начнете установку SDK, просто щелкайте по подсказкам установки, пока все не будет завершено.
Windows WDK
Помимо SDK нам также понадобится комплект драйверов Windows (WDK). WDK используется для разработки, тестирования и развертывания драйверов для Windows. При установке WDK обязательно установите расширение комплекта драйверов Visual Studio для Windows.
Примечание. Для правильной установки расширения необходимо закрыть Visual Studio .
WinDbg
Нам также понадобится отладчик. В этом случае мы будем использовать отладчик Windows ( WinDbg Preview ), который является важным инструментом для разработки ядра. В основном он будет использоваться для устранения неполадок нашего драйвера ядра в случае сбоев или неожиданного поведения.
Общий сетевой ресурс (необязательно)
В Visual Studio у нас есть возможность создавать так называемые события после сборки , которые могут запускать для нас множество полезных команд после того, как мы скомпилируем наш драйвер. Одним из таких событий после сборки, которое можно создать для упрощения процесса разработки, является копирование скомпилированного драйвера в папку (настроенную как сетевой ресурс). Этот сетевой ресурс будет использоваться для хранения всех встроенных драйверов, к которым может получить доступ тестовая виртуальная машина.
Если вы настроили свою лабораторию в соответствии с моими рекомендациями, вы можете избавить себя от необходимости настраивать общий ресурс с надлежащими элементами управления доступом и разрешениями. Просто дайте всем разрешения RWX, и все готово.
В конечном итоге ваша установка должна выглядеть примерно так:
Тестирование ВМ
Спецификации тестируемой виртуальной машины не имеют большого значения. Просто не забудьте дать ему достаточно мощности. Например, моя тестовая виртуальная машина была сконфигурирована с 2 ядрами, 4 ГБ ОЗУ и 32 ГБ хранилища. Опять же, он работает под управлением Windows 11 22H2, но у вас не должно быть никаких проблем, если вы используете Windows 10.
Данные конфигурации загрузки (BCD)
Далее нам нужно настроить BCD с помощью bcdedit команды. Откройте административную подсказку и введите следующие команды:
Первая команда включает отладку ядра, а вторая включает тестовую подпись. Отладка ядра позволяет нам отлаживать ядро машины, в то время как тестовая подпись отключает проверку подписи драйверов, позволяя нам загружать и тестировать наши пользовательские драйверы без необходимости соблюдать строгие правила безопасности драйверов Microsoft.
Обратите внимание, что включение тестовой подписи приведет к отображению предупреждающего водяного знака в правом нижнем углу машины:
Наконец, нам нужно включить удаленную отладку. Для этого мы можем использовать команду, аналогичную приведенной ниже:
Просто обратите внимание на то, чтобы задать hostip для свойства IP-адрес виртуальной машины разработки и установить для порта значение от 50000 до 50039. Кроме того, будьте осторожны, чтобы не перепутать IP-адреса машин разработки и тестирования. В этом случае мы хотим ввести IP-адрес компьютера для разработки, чтобы он мог подключиться к порту отладки.
Если все прошло так, как ожидалось, вы должны увидеть сгенерированный ключ, отображаемый в консоли:
Значение удаленной отладки будет объяснено позже. На данный момент убедитесь, что вы отложили сгенерированный ключ.
Брандмауэр
Чтобы предотвратить прерывания во время удаленной отладки, мы отключим брандмауэр. Для этого вы можете либо использовать графический интерфейс, либо выполнить следующую команду в административной строке:
Кроме того, вы также можете внести порт отладки в белый список через настройки, если вы предпочитаете не отключать брандмауэр полностью.
Отладка фильтра печати
Чтобы обеспечить вывод всех сообщений отладки ядра в отладчик, необходимо настроить фильтр печати отладки . Можно использовать следующую команду:
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter" /v Default /t REG_DWORD /d 0xf
Обратите внимание, что для того, чтобы это изменение вступило в силу, компьютер необходимо перезагрузить. Неважно, перезагрузите ли вы виртуальную машину сейчас или после ее настройки. Просто не забудьте перезагрузить его в какой-то момент.
Загрузчик драйверов OSR
OSR Driver Loader — это инструмент, который мы будем использовать для загрузки или «выполнения» нашего драйвера. Одно из основных преимуществ использования загрузчика OSR вместо ручной настройки служб Windows заключается в том, что он содержит удобный графический интерфейс пользователя, что упрощает его использование.
Улучшения QoL (необязательно)
Вот несколько дополнительных советов, которые могут помочь сэкономить время:
Если вы настроили сетевую папку, содержащую встроенные драйверы, вы можете смонтировать ее и добавить в удобное место, например на рабочий стол.
Поскольку вы, скорее всего, будете бесчисленное количество раз сталкиваться с синим экраном во время тестирования драйвера, может быть полезно включить автоматический вход в систему без пароля и сделать снимок работающей виртуальной машины, чтобы вы могли легко вернуться к ней в случае серьезного сбоя.
Разработка драйверов
Наконец-то мы можем начать процесс разработки!
Присоединение WinDbg
При включенной удаленной отладке ядра вы сможете удаленно подключаться к ядру тестируемой виртуальной машины из виртуальной машины разработки.
Для этого откройте свой компьютер для разработки и запустите WinDbg. Зайдите в главное меню и выберите Attach to kernel:
В Net подменю введите сведения о тестируемой ВМ:
В моем случае IP-адрес тестируемой ВМ — 10.10.20.3, порт — 50039 и ключ — это значение, которое я сказал вам сохранить ранее (ваш ключ будет другим).
После нажатия OK вы должны быть подключены к ядру тестовой машины:
С этого момента вы можете устанавливать точки останова, проверять адреса памяти и многое другое. Просто имейте в виду, что если вы установите точку останова, тестируемая виртуальная машина может перейти в приостановленное (замороженное) состояние. Вам нужно будет удалить все точки останова, чтобы виртуальная машина возобновила работу. Кроме того, WinDbg также будет использоваться для проверки вызовов отладочной печати из нашего драйвера. Поскольку у драйверов нет консоли, использование отладчика для просмотра сообщений — единственный доступный нам вариант.
Создание проекта
Теперь давайте продолжим и создадим первый проект кода ядра! Начните с открытия Visual Studio и выбора Create a new project. Затем найдите Kernel Mode Driver, Empty (KMDF)шаблон.
Подтвердите свой выбор и назовите проект HelloWorld. После того, как Visual Studio загрузит решение, щелкните правой кнопкой мыши Source Files, затем щелкните Add и, наконец New Item..., .
Откроется окно, в котором вам будет предложено выбрать элемент для добавления в проект. Выберите C++ File (.cpp)и назовите его Driver.c. На самом деле вы можете назвать его как хотите, просто убедитесь, что у файла есть .c расширение.
Привет, мир!
Мы подходим к хорошему! В этом разделе мы, наконец, приступим к написанию драйвера.
Предупреждение
Чтобы писать драйверы ядра, необходимо хорошо понимать язык программирования Си. Если вы не знакомы с C, рекомендуется освежить свои навыки, прежде чем продолжить.
Все драйверы требуют подпрограммы DriverEntry, отвечающей за инициализацию драйвера. Думайте об этом как о main функции в стандартных программах на C.
Мы можем создать простую DriverEntry процедуру для файла Driver.c, которая будет выглядеть так:
C:
1
#include <ntddk.h> // Kernel header
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT driverObject, _In_ PUNICODE_STRING registryPath) {
KdPrint(("Hello World!\n")); // Printf "equivalent"
// - Only prints data when build settings are set to 'Debug',
// otherwise doesn't do anything
return STATUS_SUCCESS;
}
В дополнение к подпрограмме входа нам также нужно что-то, называемое подпрограммой «выход», которая вызывается каждый раз, когда драйвер выгружается. Основное различие между процедурой выхода и процедуры входа состоит в том, что процедура выхода не имеет предопределенного имени. Таким образом, нам нужно вручную указать процедуру выгрузки при инициализации драйвера.
В моем случае я создал новую процедуру выхода под названием DriverUnload. Обновленный файл Driver.c после добавления подпрограммы должен выглядеть так:
C:
#include <ntddk.h>
NTSTATUS DriverUnload(_In_ PDRIVER_OBJECT driverObject) {
KdPrint(("Goodbye World!\n"));
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT driverObject, _In_ PUNICODE_STRING registryPath) {
KdPrint(("Hello World!\n"));
driverObject->DriverUnload = DriverUnload; // Set the unload function to DriverUnload
return STATUS_SUCCESS;
}
Это почти все, что касается программирования! Есть только одна проблема, которую нам нужно решить. Если вы попытаетесь создать решение сейчас, оно завершится ошибкой с несколько раздражающим сообщением об ошибке:
Поскольку ядро является критически важным компонентом операционной системы, и любые проблемы с драйвером могут иметь серьезные последствия, Microsoft выбрала осторожный подход к разработке. Поэтому решения, настроенные с помощью шаблона каркаса драйвера режима ядра ( KMDF ), всегда обрабатывают любые предупреждения как ошибки. Хотя это поведение можно отключить, делать это не рекомендуется, поскольку чем сложнее становится драйвер, тем сложнее будет устранять неполадки.
Вместо этого мы изменим наш код, чтобы устранить ошибку. Предупреждения указывают на наличие двух нессылочных параметров функции: driverObjectи registryPath. Вы можете либо использовать эти параметры где-то в своем коде, либо использовать макрос, UNREFERENCED_PARAMETER()чтобы пометить их как заведомо «неиспользуемые».
С этой настройкой драйвер должен быть наконец завершен:
C:
#include <ntddk.h>
NTSTATUS DriverUnload(_In_ PDRIVER_OBJECT driverObject) {
UNREFERENCED_PARAMETER(driverObject);
KdPrint(("Goodbye World!\n"));
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT driverObject, _In_ PUNICODE_STRING registryPath) {
UNREFERENCED_PARAMETER(registryPath);
KdPrint(("Hello World!\n"));
driverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
Отсюда обязательно установите целевую архитектуру на x64 и создайте драйвер в режиме отладки. Если вы правильно выполнили все шаги, теперь у вас должен быть самый первый драйвер ядра HelloWorld.sys!
Примечание
Если вы получаете сообщение об ошибке, похожее на DriverVer set to incorrect dateто, когда вы пытаетесь построить свой проект, не беспокойтесь. Просто зайдите в свойства проекта и найдите конфигурацию Inf2Cat. Найдите строку с вопросом, хотите ли вы использовать местное время, и выберите Yes (/uselocaltime).
Загрузка драйвера
Теперь, когда драйвер скомпилирован, нам нужно перенести его на тестовую виртуальную машину, используя ранее созданный сетевой ресурс. Если вы не создавали сетевую папку, найдите альтернативный способ переноса драйвера.
Для демонстрации я поместил драйвер в папку «Документы». Для его загрузки я буду использовать приложение OSRLoader.
Вам не нужно ничего настраивать, кроме указания местоположения вашего драйвера. Однако обратите внимание, что когда вы загружаете драйвер в первый раз, вам нужно будет зарегистрировать его как службу. Для этого нажмите на кнопку Register Service. Вы получите предупреждение, которое сообщит вам, было ли действие успешным или нет. Если это было успешно, теперь вы можете нажать кнопку Start Service , чтобы загрузить драйвер, и Stop Service, чтобы выгрузить его!
Запустив службу и загрузив драйвер, давайте проверим WinDbg, чтобы убедиться, что драйвер работает должным образом. Вспомним, что мы запрограммировали драйвер на печать «Hello World» при загрузке и «Goodbye World» при выгрузке.
Идеально! Это именно то, что мы хотели!
Заключение
Спасибо, что дочитали до конца поста! Я ценю, что вы нашли время, чтобы прочитать его, и я надеюсь, что вы нашли его полезным и информативным. Имейте в виду, что это была только первая часть серии, так что следите за следующей! Если с моей стороны все пойдет хорошо, следующая часть должна охватывать процесс создания драйвера, который можно активировать удаленно с помощью пользовательских сетевых пакетов.
Переведено специально для xss.pro
Автор перевода: yashechka
Источник: https://v3ded.github.io/redteam/red...ernel-drivers-for-advanced-persistence-part-1