Введение в перехваты в режиме ядра. IDA Pro «с нуля» ч.54

Обсудить статью на форуме


Массу свежих 2020 года крэкерских инструментов, видеоуроков и статей вы сможете найти на видеокурсе от нашего сайта. Подробнее здесь.
Мы собираемся немного изменить предыдущее упражнение, а также сделаем программу для пользовательского режима, прямо в PYTHON.

Для этого, на целевой машине, где запущен драйвер, мы должны установить PYTHON. Я установил версию 2.7, а также загрузил инсталлятор PYWIN32, который соответствует моей версии PYTHON.

https://sourceforge.net/projects/pywin32/files/pywin32/Build 214/

Поскольку моя версия PYTHON равна 2.7, то скачайте этот файл.

IDA Pro взлом и реверсинг программ

Это инсталлятор. Запускаем его и он устанавливается. С этой программой мы сможем запустить скрипт PYTHON, который заменит предыдущую пользовательскую программу.

Мы видим, что у драйвера теперь есть еще два кода IOCTL.

IDA Pro взлом и реверсинг программ

В дополнение к коду IOCTL_SAYHELLO, который у нас уже был, теперь есть два новых: код IOCTL_HOOK и код IOCTL_UNHOOK.

IDA Pro взлом и реверсинг программ

Мы видим, что внутри CASE, когда MAJORFUNCTION равен IRP_MJ_DEVICE_CONTROL, есть еще один переключатель, который имеет три CASE IOCTL.

Мы видим, что код IOCTL, который мы имели раньше, все еще печатает только фразу “HELLO WORLD

case IOCTL_SAYHELLO:
DbgPrint("Hello World!\n");
status = STATUS_SUCCESS;
break;

Давайте посмотрим другие два.

case IOCTL_HOOK:
PsSetCreateProcessNotifyRoutine(
DriverProcessNotifyRoutine, FALSE);
break;
case IOCTL_UNHOOK:
PsSetCreateProcessNotifyRoutine(
DriverProcessNotifyRoutine, TRUE);
break;

Мы видим, что драйвер использует функцию PSSETCREATEPROCESSNOTIFYROUTINE

IDA Pro взлом и реверсинг программ

Эта функция позволяет нам добавить CALLBACK, т.е. свою собственную функцию, которая будет срабатывать каждый раз, когда система запускает или останавливает программу, передавая ей для активации второй аргумент FALSE, а в первый аргумент адрес функции, в которую будет переходить драйвер.

Наша функция, в которую будет переходить драйвер, называется DRIVERPROCESSNOTIFYROUTINE, и если условие CREATE истинно, драйвер печатает, что создан новый процесс, PID родительского процесса, который его создал, и сам ID процесса.

VOID DriverProcessNotifyRoutine(
IN HANDLE ParentId,
IN HANDLE ProcessId,
IN BOOLEAN Create)
{
if (Create)
{
DbgPrint("Process %d created process %d\n",
ParentId, ProcessId);
}
else
{
DbgPrint("Process %d has ended\n",
ProcessId);
}
}

И когда процесс завершается, так как условие CREATE будет ложным, драйвер напечатает, что процесс завершился и его PID.

Конечно, вы должны убедиться, что перед остановкой драйвера, что функция будет отключена, иначе драйвер будет переходить к функции, которая не существует, и будет вызывать BSOD.

case IOCTL_UNHOOK:
PsSetCreateProcessNotifyRoutine(
DriverProcessNotifyRoutine, TRUE);
break;

Второй аргумент установленный в TRUE отключает функцию - и система продолжает работать нормально.

Хорошо. Исходный код драйвера будет доступен во вложении. Помните, что если вы скомпилируете его в VISUAL STUDIO, вы должны изменить НАСТРОЙКИ в WINDOWS 7 и свойства DESKTOP, а также снизить уровень строгости ошибок с 4 уровня до 1 или 2.

Хорошо. Теперь идет скрипт PYTHON, который отправит IOCTL драйверу, когда тот будет запущен.

IDA Pro взлом и реверсинг программ

Мы видим, что это небольшой скрипт. Вам нужно импортировать модули WIN32API и WIN32FILE, в дополнение к WINIOCTLCON. Всё это входит в пакет PYWIN32, который мы установили. Если вы его не установили, это даст вам ошибку.

IOCTL_HOOK =winioctlcon.CTL_CODE( FILE_DEVICE_HELLOWORLD, 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS )

IOCTL_UNHOOK =winioctlcon.CTL_CODE( FILE_DEVICE_HELLOWORLD, 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS )


IOCTL_SAYHELLO=winioctlcon.CTL_CODE( FILE_DEVICE_HELLOWORLD, 0x00, METHOD_BUFFERED, FILE_ANY_ACCESS )

Мы видим, что функция CTL_CODE, которую мы используем, когда мы создали исполняемый файл на C++, чтобы найти IOCTL. В PYTHON импортирует их из модуля WINIOCTLCON. Мы сможем найти три IOCTL.

Затем у нас идёт вызов функции CREATEFILE.

hDevice = win32file.CreateFile(r"\\.\HelloWorld",win32file.GENERIC_READ | win32file.GENERIC_WRITE, 0, None,win32file.OPEN_EXISTING, win32file.FILE_ATTRIBUTE_NORMAL, 0)

В этом случае, в имени драйвера вам нужно просто добавить обратную косую черту. Остальная часть строки похожа на константы для аргументов, которые находятся в модуле WIN32FILE.

И затем происходит вызов функции DEVICEIOCONTROL. Мы предлагаем, что пользователь вводить клавишу и в зависимости от того, что он выбирает, мы отправляем драйверу соответствующий код. Если пользователь выбирает нуль, перед выходом их программы, он отключит эту функцию, чтобы избежать BSOD.

while 1:
print "1=HELLO\n","2=HOOK\n","3=UNHOOK\n","0=UNHOOK AND EXIT\n"

case=raw_input()
if case ==0:
break
if
case==1:
win32file.DeviceIoControl(hDevice,IOCTL_SAYHELLO, None, None, None)
if case == 2:
win32file.DeviceIoControl(hDevice,IOCTL_HOOK, None, None, None)
if case == 3:
win32file.DeviceIoControl(hDevice,IOCTL_UNHOOK, None, None, None)

win32file.DeviceIoControl(hDevice,IOCTL_UNHOOK, None, None, None)
win32file.CloseHandle(hDevice)

С помощью этого скрипта мы могли бы управлять драйвером, отправляя разные коды IOCTL. Давайте протестируем его.

IDA Pro взлом и реверсинг программ

Я запускаю целевую систему и запускаю драйвер с помощью OSRLOADER, и оставляю его запущенным. Теперь я буду использовать скрипт PYTHON, чтобы узнать, работает ли он.

Мы видим, что после того, как нам напечатается дескриптор драйвера, нам покажутся опции для выбора.

IDA Pro взлом и реверсинг программ

Если я нажму 1, то ничего не происходит. Что же произошло?

case=raw_input()
1
case
type(case)

Out[6]: str

Ааа. Результат RAW_INPUT - это строка, и мы сравниваем ее с целым числом. Давайте изменим это.

IDA Pro взлом и реверсинг программ

Посмотрим сейчас.

IDA Pro взлом и реверсинг программ

Теперь всё работает. Когда мы нажимаем 1, нам показывается перехваченная фраза “HELLO WORLD”. Сейчас я нажимаю 2.

IDA Pro взлом и реверсинг программ

Теперь позапускаем некоторые программы в машине.

IDA Pro взлом и реверсинг программ

Мы видим, как драйвер логирует процессы, которые запускаются и закрываются. В моем случае, запускается INTERNET EXPLORER.

IDA Pro взлом и реверсинг программ

PID IE равен 4084, а родителем является – EXPLORER. При запуске двойным щелчком, любой процесс, который запускается на машине или останавливается будет логироваться. Теперь я закрываю IE.

IDA Pro взлом и реверсинг программ

Хорошо. Всё работает. Теперь выключим перехват через пункт 3. Мы видим, что процессы, которые мы открываем и закрываем, больше не регистрируются.

Что касается реверсинга, то это похоже на предыдущий случай.

IDA Pro взлом и реверсинг программ

В обработчике мы видим, что в этом случае регистр EDI, равен IRP + 0x60. Он будет иметь адрес структуры _IO_STACK_LOCATION. Кроме того, поставим там BP. Как только мы синхронизируем необходимые структуры в LOCAL TYPES, нам покажут, что это поле MAJORFUNCTION.

IDA Pro взлом и реверсинг программ

В случае, когда MAJORFUNCTION равно 0xE, другими словами, когда мы используем DEVICEIOCONTROL. Мы нажимаем T и из всех опций, которые есть, мы выбираем, те для которых используется DEVICEIOCONTROL.

IDA Pro взлом и реверсинг программ

Мы видим, что когда код равен IOCTL_SAYHELLO, драйвер переходит к желтому блоку, который напечатает HELLO WORLD. В двух других случаях он идёт в зеленые блоки. В случае IOCTL_HOOK выполняется инструкция PUSH ESI, регистр которой равен нулю, чтобы передать аргумент FALSE в API PSSETCREATEPROCESSNOTIFYROUTINE@8, а в случае IOCTL_UNHOOK исполняет инструкцию PUSH 1, что является TRUE.

Другим аргументом является смещение функции, в которую будет переходить драйвер.

IDA Pro взлом и реверсинг программ

Если мы сделаем щелчок здесь, мы перейдём к этой функции.

IDA Pro взлом и реверсинг программ

Здесь мы видим, если переменная CREATE ложная, т.е. равна нулю, драйвер переходит в PROCESS (PID) HAS ENDED, а если переменная истинна, то переходит в ROCESS (PID) CREATED PROCESS (PID)

Если мы поставим BP здесь, драйвер будет останавливаться каждый раз, когда мы запускам процесс, после того, как я нажму 2 в скрипте PYTHON для ПЕРЕХВАТА.

Я оставляю вам домашнюю работу поставить BP в этой функции, и в обработчике и трассировать код, чтобы проверить, то что мы увидели при реверсинге.

=======================================================
Автор текста: Рикардо Нарваха - Ricardo Narvaja (@ricnar456)
Перевод на русский с испанского: Яша_Добрый_Хакер(Ростовский фанат Нарвахи).
26.10.2018
Версия 1.0


Обсуждение статьи: Введение в перехваты в режиме ядра. IDA Pro «с нуля» ч.54 >>>


При перепечатке ссылка на https://exelab.ru обязательна.



Видеокурс ВЗЛОМ