
Утилита командной строки Windows для чтения, записи и выполнения кода в режиме ядра из контекста администратора с использованием техники перенаправления выполнения при проверке шрифтов, что обеспечивает расширенную отладку ядра и устранение неполадок системы.
r0ak — это утилита командной строки для Windows, которая позволяет легко читать, записывать и выполнять код на уровне ядра (с некоторыми ограничениями) прямо из командной строки, не требуя ничего, кроме прав администратора.
r0ak v1.0.0 -- Ring 0 Army Knife
http://www.github.com/ionescu007/r0ak
Copyright (c) 2018 Alex Ionescu [@aionescu]
http://www.windows-internals.com
USAGE: r0ak.exe
[--execute <Address | module.ext!function> <Argument>]
[--write <Address | module.ext!function> <Value>]
[--read <Address | module.ext!function> <Size>]

Ядро Windows — это богатая среда, в которой на типичной системе выполняются сотни драйверов и присутствуют тысячи переменных, содержащих глобальное состояние. Для расширенной диагностики ИТ-специалисты обычно используют такие инструменты, как отладчик Windows (WinDbg), утилиты SysInternals или пишут собственные. К сожалению, использование этих инструментов становится всё более сложным, и они сами ограничены собственным доступом к API Windows и предоставляемым функциям.
Некоторые из сегодняшних проблем включают:
В такой среде стало очевидно, что простой инструмент, который можно использовать как экстренную «заплатку»/быстрое исправление и для быстрой диагностики проблем на уровне ядра/системы, которые могут быть выявлены при анализе состояния ядра, может быть ценен для сообщества.

r0ak работает, перенаправляя поток выполнения доверенных проверок шрифтов диспетчера окон при попытке загрузить новый шрифт. Для этого он заменяет процедуру сравнения доверенной таблицы шрифтов на альтернативную функцию, которая планирует элемент рабочей задачи (WORK_QUEUE_ITEM), хранящийся во входном узле. Затем правый дочерний элемент доверенной таблицы шрифтов (который служит корневым узлом) перезаписывается буфером записи именованного канала (NP_DATA_ENTRY), в котором хранится пользовательский элемент работы. Этот элемент, его базовая рабочая функция и параметр будут в конечном итоге выполнены выделенным ExpWorkerThread на уровне PASSIVE_LEVEL после попытки загрузки шрифта и выполнения процедуры сравнения, которая получит родительский узел, основанный на именованном канале, в качестве входных данных. Событие трассировки событий Windows (ETW) в реальном времени используется для получения асинхронного уведомления о завершении выполнения рабочего элемента, что позволяет безопасно разрушить структуры, освободить буферы режима ядра и восстановить нормальную работу.
При использовании опции --execute эта функция и параметр предоставляются пользователем.
При использовании --write используется специальный gadget для изменения произвольных 32-битных значений в любом месте памяти ядра.
При использовании --read write-gadget используется для изменения указателя и размера буфера HSTI системы (Примечание: это деструктивное поведение для любых других приложений, которые будут запрашивать данные HSTI. Поскольку это необязательное поведение Windows, а этот инструмент предназначен для аварийной отладки/экспериментов, потеря данных была сочтена приемлемой). Затем API запроса HSTI используется для копирования данных обратно в адресное пространство пользовательского режима инструмента, и выводится шестнадцатеричный дамп.
Поскольку используются только встроенные, подписанные Microsoft функции Windows, и все вызываемые функции являются частью битовой карты KCFG, не происходит нарушения каких-либо проверок безопасности, не требуются флаги отладки или использование плохо написанных сторонних драйверов.
Нет. Поскольку этот инструмент (и лежащая в его основе техника) требует привилегированного токена уровня SYSTEM, который может получить только пользователь, работающий под учётной записью администратора, не происходит обхода границ безопасности для достижения эффекта. Поведение и полезность инструмента возможны только благодаря повышенному/привилегированному контексту безопасности учётной записи администратора в Windows, и это считается поведением, предусмотренным архитектурой.
Конечно! Важно всегда сообщать о проблемах безопасности в Microsoft, даже если, казалось бы, не произошло нарушения привилегированных границ – их команды исследователей и разработчиков могут найти новые векторы и способы доступа к определённым путям кода, о которых внешний исследователь мог не подумать.
Соответственно, в ноябре 2014 года в Центр безопасности Microsoft (MSRC) был подан запрос по безопасности, на который ответили: «[…] не подпадает под категорию проблем безопасности, которые мы решали бы с помощью традиционного бюллетеня безопасности. Он […] предполагает наличие прав администратора — места, где архитектурно мы в настоящее время не определяем защищаемую границу безопасности. Поэтому мы не будем заниматься исправлением этого.»
Кроме того, в апреле 2015 года на конференции Infiltrate был представлен доклад под названием Insection : AWEsomely Exploiting Shared Memory Objects, в котором подробно описывалась эта проблема, в том числе для присутствовавших разработчиков Microsoft, которые согласились, что в настоящее время это выходит за рамки архитектурных границ безопасности Windows. Это связано с тем, что существуют буквально десятки (если не больше) других способов, с помощью которых администратор может читать/записывать/выполнять память Ring 0. Этот инструмент просто упрощает коммерциализацию одного из таких векторов для целей отладки и устранения неполадок системы.
Упаковка этого кода в виде библиотеки потребовала бы тщательного удаления всего интерактивного разбора командной строки и стандартного вывода, после чего, без серьёзных переписываний, «кит»:
_NT_SYMBOL_PATH на целевой машине и загрузки и кэширования около 15 МБ данных символов в виде PDB-файлов где-то на дискеЗлоумышленники, заинтересованные в использовании этого конкретного подхода (в отличие от многих других, более кроссплатформенных и не требующих прав SYSTEM), вероятно, уже адаптировали свой код на основе Proof-of-Concept от апреля 2015 года — более 3 лет назад.
Из-за использования механизма символов Windows необходимо установить либо Windows Software Development Kit (SDK), либо Windows Driver Kit (WDK) с компонентом «Средства отладки для Windows». Инструмент автоматически найдёт путь установки и задействует DbgHelp.dll и SymSrv.dll, которые находятся в этом каталоге. Поскольку эти файлы не подлежат распространению, они не могут быть включены в релиз инструмента.
В качестве альтернативы, если вы получите эти библиотеки самостоятельно, вы можете изменить исходный код для их использования.
Для использования символов требуется подключение к Интернету, если они не были предварительно кэшированы локально. Кроме того, рекомендуется настроить переменную _NT_SYMBOL_PATH, указывающую на соответствующий сервер символов и кэшированное местоположение.
Предполагается, что ИТ-специалист или другой специалист по устранению неполадок, которому, очевидно, необходимо читать/записывать/выполнять память ядра (и который знает соответствующие переменные ядра для доступа), уже более чем хорошо знаком с вышеуказанными требованиями к настройке. Пожалуйста, не открывайте вопросы с просьбой объяснить, что такое SDK или как установить переменную окружения.
Какой-то драйвер утёк из пула ядра? Почему бы не вызвать ntoskrnl.exe!ExFreePool и не передать адрес ядра, который утекает? А что насчёт ссылки на объект? Вызовите ntoskrnl.exe!ObfDereferenceObject и позвольте ему очистить её.
Хотите сбросить журнал отладки ядра DbgPrint? Почему бы не сбросить внутренний циклический буфер по адресу ntoskrnl.exe!KdPrintCircularBuffer?
Интересуетесь, насколько велики стеки ядра на вашей машине? Попробуйте посмотреть на ntoskrnl.exe!KeKernelStackSize.
Хотите сбросить таблицу системных вызовов, чтобы проверить наличие перехватчиков? Выведите ntoskrnl.exe!KiServiceTable.
Это лишь несколько примеров – принимаются любые адреса Ring 0, либо в синтаксисе module!symbol, либо путём прямой передачи указателя ядра, если он известен. Для их поиска используется механизм символов Windows.
Инструмент требует определённых переменных и функций ядра, которые, как известно, существуют только в современных версиях Windows 10, и был предназначен только для работы в 64-битных системах. Эти ограничения связаны с тем, что в старых системах (или x86-системах) таких строгих требований безопасности нет, и поэтому можно использовать более традиционные подходы. Это личный инструмент, который я предоставляю, и у меня не было потребности в этих старых системах, где я мог бы использовать простой драйвер. Тем не менее, этот репозиторий принимает pull request'ы, если кто-то заинтересован в портировании.
Во-вторых, из-за вариантов использования и моих собственных потребностей действуют следующие ограничения:
Очевидно, эти ограничения можно было бы исправить, программно выбрав другой подход, но они соответствуют потребностям инструмента командной строки и моим задачам. Опять же, pull request'ы принимаются, если кто-то хочет внести свои дополнения.
Обратите внимание, что всё выполнение (включая выполнение команд --read и --write) происходит в контексте рабочего потока системы на уровне PASSIVE_LEVEL. Поэтому адреса пользовательского режима не должны передаваться в качестве параметров/аргументов.
Pull request'ы приветствуются. Для серьёзных изменений сначала откройте вопрос, чтобы обсудить, что вы хотели бы изменить.
Copyright 2018 Alex Ionescu. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided
that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY ALEX IONESCU ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALEX IONESCU
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those of the authors and
should not be interpreted as representing official policies, either expressed or implied, of Alex Ionescu.