Всем привет! Как и говорил будем исследовать не документированные функции Windows - на момент написания статьи все перечисленные функции актуальны и могут быть использованы в целях исследования безопасности.
Информация предоставлена исключительно в ознакомительных целях.
Начнем как всегда с теории и посмотрим что мы имеем и что а самое главное как все это можно использовать.
1. NtLoadDriver / ZwLoadDriver
Эти функции позволяют загружать драйверы в операционную систему. Поскольку драйверы работают в режиме ядра (Ring 0), их загрузка позволяет выполнять код с полными правами системы. Это один из наиболее распространенных способов получить доступ к ядру через легитимный механизм Windows.
Прототип функции:
C:
NTSTATUS NtLoadDriver(
PUNICODE_STRING DriverServiceName
);
Аргументы:
- DriverServiceName: Указатель на строку, содержащую имя сервиса драйвера, который нужно загрузить.
Эти функции могут использоваться для загрузки драйверов ядра, что предоставляет возможность выполнить код в контексте ядра. Однако, для использования этой функции необходимо иметь права администратора.
Примечания:
- Использование драйверов для получения привилегий ядра является стандартной практикой в операционных системах, таких как Windows.
- Недокументированное или некорректное использование может привести к краху системы или отказу в доступе.
2. NtCreateThreadEx
Эта функция позволяет создавать поток в произвольном процессе, даже в процессе, который работает в контексте ядра. Злоумышленники могут использовать её для выполнения кода с высокими привилегиями, если они уже получили доступ к системным процессам.
Прототип функции:
C:
NTSTATUS NtCreateThreadEx(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
HANDLE ProcessHandle,
PVOID StartRoutine,
PVOID Argument,
ULONG CreateFlags,
SIZE_T ZeroBits,
SIZE_T StackSize,
SIZE_T MaximumStackSize,
PPS_ATTRIBUTE_LIST AttributeList
);
Примечания:
- Эта функция не документирована для использования в приложениях уровня пользователя и предназначена для внутреннего использования в системе.
- Может использоваться для выполнения кода в контексте другого процесса, что может привести к захвату контроля над привилегированными процессами.
Функция MmMapIoSpace позволяет отобразить физическую память в виртуальное адресное пространство. Это может быть использовано для получения прямого доступа к аппаратным ресурсам, что может быть полезно для чтения и записи в память или управление устройствами на уровне ядра.
Прототип функции:
C:
PVOID MmMapIoSpace(
PHYSICAL_ADDRESS PhysicalAddress,
SIZE_T NumberOfBytes,
MEMORY_CACHING_TYPE CacheType
);
Аргументы:
- PhysicalAddress: Физический адрес, который необходимо отобразить в виртуальное адресное пространство.
- NumberOfBytes: Количество байтов для отображения.
- CacheType: Тип кэширования для отображаемой памяти.
Функция используется в драйверах для взаимодействия с аппаратными устройствами. Получив доступ к физической памяти, злоумышленники могут использовать её для обхода ограничений безопасности.
Примечания:
- Использование этой функции требует прав доступа к режиму ядра.
- Неправильное отображение физической памяти может привести к сбоям в работе системы или к её зависанию.
4. RtlWriteVirtualMemory / NtWriteVirtualMemory
Эти функции позволяют записывать данные в адресное пространство процесса, что может использоваться для изменения поведения привилегированных процессов или для внедрения кода в системные службы.
Прототип функции:
C:
NTSTATUS NtWriteVirtualMemory(
HANDLE ProcessHandle,
PVOID BaseAddress,
PVOID Buffer,
SIZE_T BufferSize,
PSIZE_T NumberOfBytesWritten
);
Аргументы:
- ProcessHandle: Дескриптор процесса, в адресное пространство которого нужно записать данные.
- BaseAddress: Базовый адрес, по которому нужно начать запись.
- Buffer: Указатель на буфер с данными для записи.
- BufferSize: Размер буфера данных.
- NumberOfBytesWritten: Указатель на переменную, куда будет записано количество успешно записанных байт.
Эта функция может использоваться для модификации памяти привилегированных процессов, таких как системные службы. Злоумышленники могут использовать её для внедрения вредоносного кода или для повышения своих привилегий.
Примечания:
- Для успешного использования функции необходимо обладать правами на запись в целевой процесс.
- Злоупотребление этой функцией может быть обнаружено антивирусными программами и средствами защиты от вмешательства в память.
Это структура, используемая ядром Windows для диспетчеризации аппаратных вызовов. Злоумышленники могут модифицировать таблицу для перенаправления вызовов на свои собственные обработчики, таким образом получая привилегированный доступ к системе.
Пример атаки:
Злоумышленник может перехватить вызовы, изменив указатели на функции в HalDispatchTable, что позволит ему выполнять произвольный код на уровне ядра.
Современные изменения в Windows
Начиная с Windows Vista, Microsoft реализовала несколько важных защитных механизмов, таких как PatchGuard (Kernel Patch Protection) и Driver Signing Enforcement, которые усложняют злоумышленникам и легитимным драйверам модификацию критических структур ядра, включая HalDispatchTable. PatchGuard отслеживает целостность ядра и предотвращает изменения, такие как подмена таблиц диспетчеризации, что значительно усложняет выполнение подобных атак. Но нет преград для патриотов)
Примечания:
Модификация HalDispatchTable является распространённой техникой эксплуатации на уровне ядра для получения прав Ring 0.
Данный метод сложен для реализации и требует глубокого понимания работы ядра Windows.
6. IoCreateDevice и IoCreateSymbolicLink
Эти функции используются для создания новых устройств и символьных ссылок в Windows, что может быть использовано для создания механизмов, через которые пользовательские процессы смогут взаимодействовать с драйверами ядра.
Прототип функции:
Код:
NTSTATUS IoCreateDevice(
PDRIVER_OBJECT DriverObject,
ULONG DeviceExtensionSize,
PUNICODE_STRING DeviceName,
DEVICE_TYPE DeviceType,
ULONG DeviceCharacteristics,
BOOLEAN Exclusive,
PDEVICE_OBJECT *DeviceObject
);
NTSTATUS IoCreateSymbolicLink(
PUNICODE_STRING SymbolicLinkName,
PUNICODE_STRING DeviceName
);
Пример использования:
Эти функции могут использоваться для создания устройства, через которое можно обмениваться данными между пользовательскими приложениями и драйверами, работающими на уровне ядра. Злоумышленники могут создать символьную ссылку, которая предоставит доступ к привилегированным ресурсам.
Примечания:
- Для создания устройств и символьных ссылок требуется наличие прав администратора.
- Некорректное использование может привести к созданию уязвимостей или нарушению целостности системы
ZwSetSystemInformation — это функция в ядре Windows, которая позволяет устанавливать различные типы системной информации. Эта функция не является частью публичного API, и её использование в основном задокументировано для работы на уровне ядра (Ring 0). Функция может быть использована для выполнения низкоуровневых операций с системой, но большинство типов информации, которые она может менять, недокументированы или могут изменяться в разных версиях Windows.
Прототип функции:
Код:
NTSTATUS IoCreateDevice(
PDRIVER_OBJECT DriverObject,
ULONG DeviceExtensionSize,
PUNICODE_STRING DeviceName,
DEVICE_TYPE DeviceType,
ULONG DeviceCharacteristics,
BOOLEAN Exclusive,
PDEVICE_OBJECT *DeviceObject
);
NTSTATUS IoCreateSymbolicLink(
PUNICODE_STRING SymbolicLinkName,
PUNICODE_STRING DeviceName
);
NTSTATUS ZwSetSystemInformation(
SYSTEM_INFORMATION_CLASS SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength
);
Аргументы:
- SystemInformationClass: Указывает тип системной информации, которую нужно изменить. Это значение из перечисления SYSTEM_INFORMATION_CLASS, которое определяет, какую именно информацию можно изменить. Например, можно изменить количество процессоров, приоритеты и другие параметры системы.
- SystemInformation: Указатель на буфер, который содержит данные, передаваемые системе в зависимости от класса информации, выбранного в SystemInformationClass.
- SystemInformationLength: Длина данных в буфере SystemInformation.
ZwSetSystemInformation может использоваться для таких задач, как установка системных ограничений на количество доступных процессоров или управление рабочими наборами процессов. Однако изменение критичных системных параметров через эту функцию может привести к нестабильности системы или нарушению её безопасности.
Примечания:
- Это системная функция уровня ядра, поэтому для её использования требуются права администратора или драйвера.
- Некорректное использование этой функции может вызвать системные сбои (синий экран) или непредвиденное поведение.
- Функция не предназначена для использования в пользовательских приложениях, её вызов обычно делается из драйвера.
KeAttachProcess — это функция ядра Windows, которая позволяет прикрепиться к процессу для выполнения операций от его имени на уровне ядра. Она также предоставляет возможность ядру управлять контекстом исполнения в рамках другого процесса. Обычно используется драйверами, которые нуждаются в выполнении операций от имени других процессов.
Прототип функции:
C:
VOID KeAttachProcess(
PRKPROCESS Process
);
Аргументы:
- Process: Указатель на объект процесса (типа PRKPROCESS), к которому нужно прикрепиться. Этот объект процесса может быть получен через вызов функций, таких как PsLookupProcessByProcessId, которые позволяют идентифицировать процесс по его идентификатору (PID).
- Программы, работающие на уровне ядра, могут использовать эту функцию для временного изменения контекста выполнения на другой процесс.
- Например, драйвер может прикрепиться к пользовательскому процессу для чтения или записи в его адресное пространство напрямую. Это может быть полезно при разработке отладочных утилит или антивирусного ПО.
После вызова KeAttachProcess процессор выполняет код в контексте указанного процесса, как если бы это был текущий процесс.
- Чтобы вернуться в исходный контекст, необходимо вызвать KeDetachProcess.
- Использование этой функции может привести к проблемам синхронизации, если не выполнять корректное отсоединение от процесса.
- Подобные манипуляции могут быть использованы для внедрения кода или управления ресурсами процесса на уровне ядра, что делает их потенциально опасными, особенно если используются в целях эксплуатации уязвимостей.
C:
PRKPROCESS process;
NTSTATUS status = PsLookupProcessByProcessId((HANDLE)pid, &process);
if (NT_SUCCESS(status)) {
KeAttachProcess(process);
// Доступ к памяти процесса или выполнение других операций.
KeDetachProcess();
ObDereferenceObject(process); // Освобождение объекта процесса.
}
Примечания:
KeAttachProcess часто используется вместе с другими системными вызовами, такими как MmProbeAndLockPages и MmMapLockedPages, для работы с памятью процесса.
Некорректное использование этой функции может вызвать крах системы (BSOD), поэтому важно использовать её в сочетании с правильными методами синхронизации и управления памятью.
Важные моменты:
Функции работают на уровне ядра, что означает, что они имеют доступ ко всем ресурсам системы и могут влиять на стабильность системы при неправильном использовании.
Эти функции не предназначены для использования в приложениях уровня пользователя, и их использование предполагает работу с драйверами или системными службами.
Использование данных функций требует глубокого понимания внутренней архитектуры операционной системы и управления памятью.
Безопасность:
В реальных приложениях такие функции обычно используются драйверами для выполнения легитимных задач, таких как управление оборудованием. Однако, злоумышленники также могут использовать их для повышения привилегий или обхода защитных механизмов системы.
Теперь пришло время поговорить о том как использовать все эти теоретические знания.
Злоумышленники могут использовать различные техники для получения доступа к системным процессам в операционной системе. Обычно такие методы включают эксплуатацию уязвимостей системы, использование привилегированных функций или драйверов, а также манипуляции с памятью или файловой системой. Ниже описаны наиболее распространенные технические способы получения доступа к системным процессам и выполнения кода с высокими привилегиями.
1. Эскалация привилегий (Privilege Escalation)
Злоумышленник может получить доступ к системным процессам через так называемую эскалацию привилегий. Это процесс получения более высокого уровня прав, чем те, которые у него изначально есть. Эскалация привилегий может быть локальной (с повышения прав от обычного пользователя до администратора или системного пользователя) или удаленной (с повышения прав через сеть).
Техники эскалации:
- Использование уязвимостей в системе или приложениях: Уязвимости в программном обеспечении (особенно в ядре или драйверах) могут позволить злоумышленнику получить доступ к правам администратора или системного пользователя (System).
- Баги в системных службах: Некоторые сервисы или службы, работающие от имени привилегированных пользователей, могут содержать уязвимости, позволяющие злоумышленнику выполнить произвольный код.
- Эксплуатация неправильных настроек прав доступа: Неправильные настройки файловой системы или реестра могут предоставить пользователю доступ к ресурсам, которые ему не предназначены.
- Использование уязвимостей типа "ошибки переполнения буфера" (buffer overflow) в системных службах для выполнения произвольного кода с правами System.
- Ошибки в процессах межпроцессного взаимодействия (например, в механизмах Windows для коммуникации процессов) могут быть использованы для повышения привилегий.
Злоумышленник может внедрить код в системные процессы, такие как lsass.exe или explorer.exe, которые работают с высокими привилегиями. Это позволяет злоумышленнику выполнять код от имени этих процессов, таким образом получая доступ к ресурсам системы.
Способы инъекции:
- DLL-инъекция: Злоумышленник может загрузить свою библиотеку (DLL) в адресное пространство привилегированного процесса. Это может быть сделано через API-функции, такие как CreateRemoteThread, NtCreateThreadEx, или с использованием методов подмены загрузки DLL.
- Инъекция через код памяти (Code Cave Injection): Злоумышленник может внедрить свой код в область памяти процесса, которая не используется, и заставить процесс выполнить этот код.
- Использование API-функции WriteProcessMemory для записи вредоносного кода в процесс, а затем вызов CreateRemoteThread, чтобы заставить этот процесс выполнить код.
- Злоумышленник может инъецировать DLL в системные процессы через механизм AppInit_DLLs в реестре Windows.
3. Использование системных драйверов (Driver Exploitation)
Драйверы устройств работают в режиме ядра (Ring 0) и имеют полный доступ к ресурсам системы. Злоумышленники могут либо использовать уязвимости в легитимных драйверах, либо загрузить свои собственные драйверы для выполнения произвольного кода с правами ядра.
Методы:
Эксплуатация уязвимостей драйверов: Легитимные драйверы могут содержать уязвимости, такие как ошибки управления памятью, которые могут быть использованы для выполнения кода с правами ядра.
Загрузка вредоносного драйвера: Если злоумышленник получил права администратора, он может загрузить драйвер, который выполняет вредоносные действия. Это может быть сделано через вызовы NtLoadDriver или ZwLoadDriver.
Пример:
- Эксплуатация уязвимости драйвера видеокарты для выполнения произвольного кода в контексте ядра, что может привести к компрометации всей системы.
Злоумышленники могут изменить ключевые файлы операционной системы или записи реестра для получения контроля над системными процессами. Это может включать модификацию исполняемых файлов или установку вредоносных записей в реестре.
Методы:
- Замена системных бинарных файлов: Если злоумышленник имеет доступ к системным файлам, он может заменить их модифицированными версиями, которые будут выполняться с привилегиями системных процессов.
- Изменение реестра для перехвата процессов: Например, изменение ключей автозагрузки в реестре может позволить злоумышленнику загружать свои процессы при старте системы с системными правами.
- Злоумышленник может изменить ключи автозагрузки в реестре, такие как HKLM\Software\Microsoft\Windows\CurrentVersion\Run, чтобы загрузить свой процесс с правами администратора при старте системы.
Злоумышленник может использовать возможности отладки (debugging) для манипуляций с системными процессами. Отладка системных процессов позволяет получить доступ к их внутренним данным и изменять их поведение в реальном времени.
Методы:
- Атаки через отладочные интерфейсы: В Windows API существуют функции для отладки процессов, такие как DebugActiveProcess и DbgUiRemoteBreakin, которые могут быть использованы для подключения к привилегированным процессам и манипуляции их состоянием.
- Отладка служб: В некоторых случаях, злоумышленники могут отладить системные службы для выполнения привилегированного кода.
Использование DebugActiveProcess для присоединения к процессу lsass.exe (который хранит критичные учетные данные) и извлечения паролей.
6. Использование API-функций для взаимодействия с процессами
В операционных системах Windows и Linux существуют API-функции, позволяющие выполнять различные операции с процессами, такие как чтение и запись в память процесса, создание новых потоков и т. д. Эти функции могут быть использованы злоумышленниками для управления системными процессами.
Примеры API-функций:
- Windows: NtOpenProcess, WriteProcessMemory, ReadProcessMemory, CreateRemoteThread, NtCreateThreadEx, ZwSetInformationProcess.
- Linux: Системные вызовы вроде ptrace могут использоваться для выполнения отладочных операций на процессах с высокими привилегиями.
Пример:
- Использование WriteProcessMemory для записи произвольного кода в память системного процесса, а затем создание нового потока через CreateRemoteThread, который выполнит этот код.
Злоумышленники могут манипулировать ключевыми структурами данных операционной системы, такими как системные таблицы функций ядра, чтобы перехватить управление и выполнить свой код на уровне ядра.
Методы:
- Модификация IDT, GDT, или SSDT: Эти таблицы содержат указатели на критические функции ядра, и изменение их может позволить злоумышленнику перехватить вызовы системы и выполнить свой код с правами ядра.
- Модификация HalDispatchTable: Это таблица в Windows, которая используется для диспетчеризации аппаратных вызовов. Злоумышленник может модифицировать её для выполнения своего кода на уровне ядра.
- Перехват вызовов системных функций через изменение SSDT (System Service Dispatch Table), что позволит перехватывать и модифицировать выполнение системных функций.
Заключение
Злоумышленники используют различные методы для получения доступа к системным процессам, в том числе эксплуатацию уязвимостей, инъекцию кода, модификацию драйверов и системных файлов, отладочные интерфейсы и манипуляции с таблицами ядра. Защита от таких атак требует обновления систем безопасности, контроля за правами доступа и применения инструментов для обнаружения попыток несанкционированного доступа к системным ресурсам. Начиная со следующей статьи мы начнем рассматривать все перечисленные методы на практике и по порядку.
Последнее редактирование модератором: