/Reverse-engineering-a-signed-kernel-driver-ft.-VMProtect-RUS-

Original:https://zerocondition.com/posts/reversing-a-signed-driver/

BSD 3-Clause "New" or "Revised" LicenseBSD-3-Clause

Sample Page Posts :: Reverse engineering a signed kernel driver ft. VMProtect

zer0condition

Реверсим signed kernel driver ft. VMProtect. Перевел Nitr0-G.

14 April, 2023 — 20 min read

Начало начал:

Недавно ко мне обратился пользователь discord, который попросил меня взломать платный чит-сервис, название которого я не буду называть, поскольку он был забанен ими после того, как испытал некоторые трудности при попытке воспользоваться их услугами. Хотя поначалу я колебался, но скука взяла надо мной верх, и я решил взглянуть. Я не был удивлен, обнаружив, что загрузчик был упакован и виртуализирован с использованием одного из новейших VMProtect3версии, которые немного усложняли ситуацию. Однако с помощью динамического анализа я обнаружил, что двоичный файл был на диске в моем C:\Windows\System32. Я ожидал, что это будет исполняемый файл, но он имел расширение .sys и вызывался 'winhelper.sys '. При ближайшем рассмотрении я обнаружил, что размер драйвера составляет около 2 МБ, что необычно для дриверов, а его цифровой сертификат был подписан revoked/expired сертификатом EV от китайской компании под названием 'Binzhoushi Yongyu Feed Co.,LTd.'

deviceo

Расследование:

Дальнейшее расследование показало, что driver's timestamp относится к 2015 году, что было необычно. Я решил загрузить драйвер в IDA и обнаружил, что он был упакован и виртуализирован с помощью VMProtect 3 еще раз.

deviceo

К сожалению, EP была виртуализирована, поэтому мне пришлось прибегнуть к помощи друга, чтобы девиртнуть файл с помощью тулзов. Получив девиртуализированный файл, я углубился во внутренние устройства драйвера и обнаружил, что он использует I/O для communication, что не является чем-то необычным.

В конце концов, я нашел driver object's reference, выполнил подфункцию и нашел обработчик IRP/Dispatch драйвера.

deviceo device1

Хотя функциональность была не слишком сложной, управляющий код, передаваемый через расположение стека, был "зашифрован" с помощью некоторых операций XOR и bitwise операций. Пример программы driver controller объясняет, как это работает.

deviceo

IOCTLs and Functionalities:

Я решил ознакомиться с функциональными возможностями драйверов и их control codes.

GetProcessBaseAddresss:

0x13370400: Это был первый код ioctl, с которым я столкнулся, который использует структуру с двумя переменными, отправляемыми через системный буфер IRP. Буфер возвращается в user mode после выполнения реквеста. Он принимает интовый параметр process id, который используется для PsLookupProcessByProcessId() для получения EPROCESS целевого процесса и передается в PsGetProcessSectionBaseAddress(), который возвращает SectionBaseAddress EPROCESS. Затем доступ к базовому адресу осуществляется из user mode со второй переменной внутри структуры.

deviceo

ReadProcessMemory:

0x13370800: Это был второй найденный код ioctl, он также использует структуру, переданную из SystemBuffer, но другого размера, содержащую int, uintptr_t, uintptr_t и size_t соответственно. Позже выяснилось, что первым параметром является идентификатор процесса, переданный из запроса usermode, вторым - адрес источника, третьим - буфер и, наконец, размер.

deviceo

Дальнейший анализ выявил назначение двух приведенных здесь вызовов функций. Первый вызов функции настраивает функции, необходимые для процесса чтения/записи в память:

deviceo device1Второй вызов функции считывает память процесса через физическую память. Он принимает source address, buffer, size, and a variable, которая возвращает значение, но больше не используется:

deviceo

Заглянув внутрь функции, можно увидеть, что в ней нет ничего такого сложного; она принимает переданный виртуальный адрес и преобразует его в физический адрес (линейное преобразование) и используется в MmCopyMemory для чтения памяти процесса.

deviceo

WriteProcessMemory

0x13370C00: Это был последний найденный код, предназначенный для записи в память процесса. Он принимает структуру того же размера, что и readprocessmemory, с теми же переменными. Та же функция, вызванная ранее в обработчике запроса на чтение, настраивает функцию записи, которая будет использоваться, и сама функция записи вызывается после этого, принимая адрес источника, буфер, размер и переменную, которая возвращает значение, но больше не используется.

deviceo

Функция write принимает переданный виртуальный адрес и преобразует его в физический адрес (линейное преобразование) и используется в MmMapIoSpaceEx для записи/отображения значений в память процесса.

deviceo deviceo

Вывод:

В целом, реверс signed kernel driver был интересной и сложной задачей. Это включало динамический анализ, девиртуализацию и исследование driver's internals, чтобы раскрыть его функциональные возможности и control codes.

Если копнуть глубже, причина, по которой этот отозванный сертификат мог быть загружен, приводит к китайскому инструменту под названием "HookSigntool".

Ссылка на репозиторий содержит подписанный двоичный файл вместе с примером программы о том, как отправлять запросы к этому драйверу и технически использовать его.

Read other posts


Demystifying PatchGuard: An In-Depth Analysis Through Practical Engineering →

© 2023 zerocondition
contact@zerocondition.com

Posts :: Reverse engineering a signed kernel driver ft. VMProtect