Иллюстрированный самоучитель по программированию систем защиты

Драйвер контроля доступа

Перехват операций открытия, создания и удаления файлов

Реализация драйвером перехвата файловых операций основана на недокументированном механизме перехвата системных сервисов, описанном в разделе "Реализация защиты на уровне собственного API для ОС Windows NT".

Принцип функционирования драйвера основан на механизме замены адресов функций, предоставляемых "родным" API. Обработчик прерывания int 2E для вызова соответствующего системного сервиса использует таблицу распределения системных сервисов KeServiceDescriptorTable, экспортируемую ntoskrnl.exe.

Во время инициализации драйвера в функции DriverEntry, после успешного создания объекта-устройства, устанавливаются собственные обработчики файловых операций. Для этого сначала надо получить адрес таблицы распределения системных сервисов:

ServiceTable = KeServicepescriptorTable;

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

Это делается следующим образом:

#define SYSCALL(_function)
ServiceTable › ServiceTable[ *(PULONG)((PUCHAR)_function+l)]
RealCreateFile = SYSCALL(ZwCreateFile);
//RealCreateFile – оригинальный обработчик создания файла;
SYSCALL(ZwCreateFile) = (PVOID) HookCreateFile;
//HookCreateFile – собственный обработчик создания файла;
RealO'penFile = SYSCALL (ZwOpenFile);
//RealOpenFile – оригинальный обработчик открытия файла;
SYSCALL(ZwOpenFile) = (PVOID) HookOpenFile;
//HookOpenFile – собственный обработчик открытия файла;

При перехвате функций ZwCreateFile и ZwOpenFile необходимо учитывать, что операции запуска исполняемых файлов, переименования и удаления объектов производятся именно этими функциями при установленных следующим образом флагах:.

  • DesiredAccess & DELETE – операция удаления файла,
  • DesiredAccess & FILE_EXECUTE) || (DesiredAccess & GENERIC_EXECUTE) – запуск исполняемого файла.

Отдельную задачу представляет собой различение операций с объектами типа PIPE или СОМ-порт. В ряде случаев это может быть сделано по имени, например, memcmp(AnsiString.Buffer, "\\dosdevices\\com", 15) после выполнения фрагмента кода:

UnString.Length = (USHORT)
ObjectAttributes › ObjectName › Length;
UnString.MaximumLength = (USHORT)
ObjectAttributes › ObjectName ›.,,.
MaximumLength-;.,
UnString.Buffer = ObjectAttributes › ObjectName › Buffer;.
RtlUnicodeStringToAnsiString
.. (SAnsiString, SUnString, TRUE),.;

Собственный обработчик создания файла и собственный обработчик открытия файла

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

При этом можно вести журнал как удавшихся, так и не удавшихся попыток доступа, регистрируя имя процесса, в контексте которого осуществляется попытка доступа к ресурсу, и имя создаваемого (открываемого) файла. После исполнения собственного обработчика необходимо передать управление по старому адресу, чтобы дать возможность стандартному обработчику выполнить запрошенные действия.

NTSTATUS HookCreateFile (OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK loStatusBlock,
IN PLARGE_INTEGER AllocationSize, IN ULONG FileAttributes,
IN ULONG ShareAccess, IN ULONG CreateDisposition,
IN ULONG CreateOptions,IN PVOID EaBuffer,IN ULONG EaLength)
{
if (Access (ObjectAttributes)) return RealCreateFile (FileHandle, DesiredAccess/ ObjectAttributes,
loStatusBlock, AllocationSize, FileAttributes, ShareAccess,
CreateDisposition, CreateOptions,EaBuf fer, EaLength); return STATUSACCESSDENIED;
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.