Модель безопасности Windows для разработчиков драйверов
Модель безопасности Windows основана на защищаемых объектах. Каждый компонент операционной системы должен обеспечить безопасность объектов, для которых она отвечает. Поэтому драйверы должны обеспечить безопасность своих устройств и объектов устройств.
В этом разделе описывается, как модель безопасности Windows применяется к драйверам режима ядра.
Модель безопасности Windows
Модель безопасности Windows основана главным образом на правах каждого объекта с небольшим количеством привилегий на уровне системы. К объектам, которые могут быть защищены, относятся, но не ограничиваются процессами, потоками, событиями и другими объектами синхронизации, а также файлами, каталогами и устройствами.
Для каждого типа объекта универсальный набор прав чтения, записи и выполнения прав сопоставляется с подробными правами конкретного объекта. Например, для файлов и каталогов возможные права включают право на чтение или запись файла или каталога, право на чтение или запись расширенных атрибутов файла, право на обход каталога и право на запись дескриптора безопасности объекта.
Модель безопасности включает в себя следующие понятия:
- Идентификаторы безопасности (SID)
- Маркеры доступа
- Дескрипторы безопасности
- Списки управления доступом (ACL)
- Привилегии
Идентификаторы безопасности (SID)
Идентификатор безопасности (SID, также называемый субъектом) определяет пользователя, группу или сеанс входа. У каждого пользователя есть уникальный идентификатор безопасности, который извлекается операционной системой при входе.
Идентификаторы безопасности выдаются центром, например операционной системой или сервером домена. Некоторые идентификаторы SID хорошо известны и имеют имена, а также идентификаторы. Например, идентификатор БЕЗОПАСНОСТИ S-1-1-0 определяет всех (или мир).
Маркеры доступа
Каждый процесс имеет маркер доступа. Маркер доступа описывает полный контекст безопасности процесса. Он содержит идентификатор безопасности пользователя, идентификатор безопасности групп, к которым принадлежит пользователь, и идентификатор безопасности сеанса входа, а также список привилегий на уровне системы, предоставленных пользователю.
По умолчанию система использует основной маркер доступа для процесса всякий раз, когда поток процесса взаимодействует с защищаемым объектом. Однако поток может олицетворить учетную запись клиента. При олицетворении потока он имеет маркер олицетворения в дополнение к собственному основному маркеру. Маркер олицетворения описывает контекст безопасности учетной записи пользователя, олицетворяющей поток. Олицетворение особенно распространено в обработке удаленного вызова процедур (RPC).
Маркер доступа, описывающий контекст ограниченной безопасности для потока или процесса, называется маркером ограниченного доступа. Идентификаторы безопасности в ограниченном маркере могут быть заданы только для запрета доступа, не разрешающего доступ к защищаемым объектам. Кроме того, маркер может описать ограниченный набор привилегий на уровне системы. Идентификатор и идентификатор пользователя остаются неизменными, но права доступа пользователя ограничены, пока процесс использует ограниченный маркер. Функция CreateRestrictedToken создает ограниченный маркер.
Дескрипторы безопасности
Каждый именованный объект Windows имеет дескриптор безопасности; некоторые неназванные объекты тоже. Дескриптор безопасности описывает идентификаторы владельца и группы для объекта вместе со своими списками управления доступом.
Дескриптор безопасности объекта обычно создается функцией, создающей объект. Когда драйвер вызывает подпрограмму IoCreateDevice или IoCreateDeviceSecure для создания объекта устройства, система применяет дескриптор безопасности к созданному объекту устройства и задает списки управления доступом для объекта. Для большинства устройств списки управления доступом указываются в файле сведений об устройстве (INF).
Дополнительные сведения о дескрипторах безопасности см. в документации по драйверу ядра.
Списки управления доступом
контроль доступа Списки (ACL) позволяют точно контролировать доступ к объектам. ACL является частью дескриптора безопасности для каждого объекта.
Каждый список ACL содержит ноль или более контроль доступа записей (ACE). Каждый ACE, в свою очередь, содержит один идентификатор БЕЗОПАСНОСТИ, определяющий пользователя, группу или компьютер, а также список прав, которые запрещены или разрешены для этого идентификатора безопасности.
Списки управления доступом для объектов устройств
ACL для объекта устройства можно задать тремя способами:
- Установите дескриптор безопасности по умолчанию для своего типа устройства.
- Создается программным способом функцией RtlCreateSecurityDescriptor и устанавливается функцией RtlSetDaclSecurityDescriptor.
- Указан в языке определения дескриптора безопасности (SDDL) в INF-файле устройства или вызове подпрограммы IoCreateDeviceSecure .
Все драйверы должны использовать SDDL в INF-файле, чтобы указать списки управления доступом для своих объектов устройства.
SDDL — это расширяемый язык описания, позволяющий компонентам создавать списки управления доступом в строковом формате. SDDL используется как в пользовательском режиме, так и в коде режима ядра. На следующем рисунке показан формат строк SDDL для объектов устройства.
Значение Access указывает тип разрешенного доступа. Значение SID указывает идентификатор безопасности, определяющий, к кому применяется значение Access (например, пользователь или группа).
Например, следующая строка SDDL позволяет системе (SY) получить доступ ко всему и разрешает доступ только для чтения для всех остальных пользователей (WD):
“D:P(A;;GA;;;SY)(A;;GR;;;WD)”
Файл заголовка wdmsec.h также включает набор предопределенных строк SDDL, которые подходят для объектов устройства. Например, файл заголовка определяет SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_RWX следующим образом:
"D:P(A;;GA;;;SY)(A;;GRGWGX;;;BA)(A;;GRGWGX;;;WD)(A;;GRGWGX;;;RC)"
Первый сегмент этой строки позволяет полностью контролировать устройство ядром и операционной системой (SY). Второй сегмент позволяет любому в встроенной группе Администратор istrators (BA) получить доступ ко всему устройству, но не изменять ACL. Третий сегмент позволяет всем (WD) читать или записывать на устройство, а четвертый сегмент предоставляет те же права ненадежному коду (RC). Драйверы могут использовать стандартные строки как модели для строк, относящихся к объекту устройства.
Все объекты устройств в стеке должны иметь одинаковые списки управления доступом. Изменение списков управления доступом на одном объекте устройства в стеке изменяет списки управления доступом во всем стеке устройств.
Однако добавление нового объекта устройства в стек не изменяет списки управления доступом, либо новые объекты устройства (если они имеют списки управления доступом) или любые существующие объекты устройства в стеке. Когда драйвер создает объект устройства и присоединяет его к верхней части стека, драйвер должен скопировать списки управления доступом для стека в новый объект устройства, скопировав поле DeviceObject.Characteristics из следующего нижнего драйвера.
Подпрограмма IoCreateDeviceSecure поддерживает подмножество строк SDDL, использующих предопределенные идентификаторы SID, такие как WD и SY. API в режиме пользователя и INF-файлы поддерживают полный синтаксис SDDL.
Проверка безопасности с помощью списков управления доступом
Когда процесс запрашивает доступ к объекту, безопасность проверка сравнивает списки управления доступом для объекта с идентификаторами SID в маркере доступа вызывающего объекта.
Система сравнивает acEs в строгом порядке сверху вниз и останавливается на первом соответствующем совпадении. Таким образом, при создании ACL необходимо всегда помещать элементы ACES типа "отказ" над соответствующими acES предоставления. В следующих примерах показано, как выполняется сравнение.
Пример 1. Сравнение ACL с маркером доступа
В примере 1 показано, как система сравнивает ACL с маркером доступа для процесса вызывающего объекта. Предположим, что вызывающий объект хочет открыть файл с ACL, показанным в следующей таблице.
Пример ACL файла
Разрешение | SID | Открыть |
---|---|---|
Разрешить | Учет | Запись, удаление |
Разрешить | Продажи | Добавление |
Запрет | Юридические услуги | Добавление, запись, удаление |
Разрешить | Все | Читать |
Этот ACL имеет четыре acCL, которые применяются специально к группам "Учет", "Продажи", "Юридический" и "Все".
Затем предположим, что маркер доступа для процесса запроса содержит идентификаторы SID для одного пользователя и трех групп в следующем порядке:
Пользователь Джим (S-1-5-21...)
Учет групп (S-1-5-22...)
Group Legal (S-1-5-23...)
Группа всех (S-1-1-0)
При сравнении ACL файла с маркером доступа система сначала ищет ACE для пользователя Джима в ACL файла. Нет, поэтому далее он ищет ACE для группы учета. Как показано в предыдущей таблице, ACE для группы учета отображается как первая запись в списке ACL файла, поэтому процесс Джима предоставляется право на запись или удаление файла и остановки сравнения. Если ACE для юридической группы вместо этого предшествует ACE для группы учета в ACL, процесс будет отказано в записи, добавлении и удалении доступа к файлу.
Пример 2. Сравнение ACL с ограниченным маркером
Система сравнивает ACL с ограниченным маркером таким же образом, как оно сравнивает их в маркере, который не ограничен. Однако идентификатор безопасности отказа в ограниченном маркере может соответствовать только запрету ACE в ACL.
В примере 2 показано, как система сравнивает ACL файла с ограниченным маркером. Предположим, что файл имеет тот же ACL, что и в предыдущей таблице. Однако в этом примере процесс имеет ограниченный маркер, содержащий следующие идентификаторы SID:
Пользователь Джим (S-1-5-21...) Отрицать
Учет групп (S-1-5-22...) Отрицать
Group Legal (S-1-5-23...) Отрицать
Группа всех (S-1-1-0)
ACL файла не перечисляет идентификатор безопасности Джима, поэтому система переходит к идентификатору безопасности группы учета. Хотя список ACL файла имеет ACE для группы учета, этот ACE разрешает доступ; Таким образом, он не соответствует идентификатору безопасности в ограниченном маркере процесса, который запрещает доступ. В результате система переходит к идентификатору безопасности юридической группы. ACL для файла содержит ACE для юридической группы, которая запрещает доступ, поэтому процесс не может записывать, добавлять или удалять файл.
Привилегии
Привилегия — это право для пользователя выполнять системную операцию на локальном компьютере, например загрузку драйвера, изменение времени или завершение работы системы.
Привилегии отличаются от прав доступа, так как они применяются к задачам и ресурсам, связанным с системой, а не к объектам, и поскольку они назначаются пользователю или группе системным администратором, а не операционной системой.
Маркер доступа для каждого процесса содержит список привилегий, предоставленных процессу. Перед использованием необходимо включить специальные привилегии. Дополнительные сведения о привилегиях см. в документации по драйверам ядра.
Сценарий модели безопасности Windows: создание файла
Система использует конструкции безопасности, описанные в модели безопасности Windows, всякий раз, когда процесс создает дескриптор для файла или объекта.
На следующей схеме показаны действия, связанные с безопасностью, которые активируются при попытке создания файла в пользовательском режиме.
На предыдущей схеме показано, как система реагирует, когда приложение в пользовательском режиме вызывает функцию CreateFile . Следующие заметки ссылаются на круговые числа на рисунке:
- Приложение в пользовательском режиме вызывает функцию CreateFile , передав допустимое имя файла Microsoft Win32.
- Kernel32.dll пользовательского режима передает запрос в Ntdll.dll, который преобразует имя Win32 в имя файла Microsoft Windows NT.
- Ntdll.dll вызывает функцию NtCreateFile с именем файла Windows. В Ntoskrnl.exe диспетчер ввода-вывода обрабатывает NtCreateFile.
- Диспетчер операций ввода-вывода перепаковывает запрос в вызов диспетчера объектов.
- Диспетчер объектов разрешает символьные ссылки и гарантирует, что пользователь имеет права на обход пути, в котором будет создан файл. Дополнительные сведения см. в разделе "Безопасность проверка" в диспетчере объектов.
- Диспетчер объектов вызывает системный компонент, принадлежащий базовому типу объекта, связанному с запросом. Для запроса на создание файла этот компонент является диспетчером ввода-вывода, который владеет объектами устройства.
- Диспетчер ввода-вывода проверка дескриптор безопасности для объекта устройства с маркером доступа для процесса пользователя, чтобы убедиться, что у пользователя есть необходимый доступ к устройству. Дополнительные сведения см. в разделе "Безопасность проверка" в диспетчере операций ввода-вывода.
- Если у пользовательского процесса есть необходимый доступ, диспетчер ввода-вывода создает дескриптор и отправляет запрос IRP_MJ_CREATE драйверу для устройства или файловой системы.
- При необходимости драйвер выполняет дополнительные проверка безопасности. Например, если запрос указывает объект в пространстве имен устройства, драйвер должен убедиться, что вызывающий объект имеет необходимые права доступа. Дополнительные сведения см. в разделе "Безопасность проверка" в драйвере.
Проверка безопасности в диспетчере объектов
Ответственность за проверка права доступа принадлежит к самому высокому компоненту, который может выполнять такие проверка. Если диспетчер объектов может проверить права доступа вызывающего объекта, он делает это. В противном случае диспетчер объектов передает запрос компоненту, ответственному за базовый тип объекта. Этот компонент, в свою очередь, проверяет доступ, если он может; Если он не удается, он передает запрос в по-прежнему более низкий компонент, например драйвер.
Диспетчер объектов проверка списки управления доступом для простых типов объектов, таких как события и блокировки мьютексов. Для объектов с пространством имен владелец типа выполняет проверка безопасности. Например, диспетчер ввода-вывода считается владельцем типа для объектов устройств и файлов. Если диспетчер объектов находит имя объекта устройства или объекта файла при анализе имени, он передает имя диспетчеру ввода-вывода, как в сценарии создания файла, представленном выше. Затем диспетчер ввода-вывода проверка права доступа, если это возможно. Если имя указывает объект в пространстве имен устройства, диспетчер ввода-вывода отключает имя драйверу устройства (или файловой системы), и этот драйвер отвечает за проверку запрошенного доступа.
Проверка безопасности в диспетчере операций ввода-вывода
Когда диспетчер ввода-вывода создает дескриптор, он проверка права объекта на маркер доступа к процессу, а затем сохраняет права, предоставленные пользователю вместе с дескриптором. Когда последующие запросы ввода-вывода поступают, диспетчер ввода-вывода проверка права, связанные с дескриптором, чтобы убедиться, что процесс имеет право выполнять запрошенную операцию ввода-вывода. Например, если процесс позже запрашивает операцию записи, диспетчер ввода-вывода проверка права, связанные с дескриптором, чтобы убедиться, что вызывающий объект имеет доступ на запись.
Если дескриптор дублируется, права можно удалить из копии, но не добавить в него.
Когда диспетчер ввода-вывода создает объект, он преобразует универсальные режимы доступа Win32 в права конкретного объекта. Например, следующие права применяются к файлам и каталогам:
Режим доступа Win32 | Права конкретного объекта |
---|---|
GENERIC_READ | ReadData |
GENERIC_WRITE | WriteData |
GENERIC_EXECUTE | ReadAttributes |
GENERIC_ALL | Все |
Чтобы создать файл, процесс должен иметь права на обход родительских каталогов в целевом пути. Например, чтобы создать \Device\CDROM0\Directory\File.txt, процесс должен иметь право пройти по \Device\CDROM0 и \Device\CDROM0\Directory. Диспетчер ввода-вывода проверка только права обхода для этих каталогов.
Диспетчер ввода-вывода проверка выполняет обход прав при анализе имени файла. Если имя файла является символьной ссылкой, диспетчер ввода-вывода разрешает его в полный путь, а затем проверка обхода прав, начиная с корневого каталога. Например, предположим, что символьная ссылка \DosDevices\D сопоставляется с именем устройства Windows NT \Device\CDROM0. Процесс должен иметь права обхода в каталог \Device.
Дополнительные сведения см. в разделе "Дескрипторы объектов" и "Безопасность объектов".
Проверка безопасности в драйвере
Ядро операционной системы обрабатывает каждый драйвер, фактически, как файловую систему с собственным пространством имен. Следовательно, когда вызывающий объект пытается создать объект в пространстве имен устройства, диспетчер ввода-вывода проверка, что процесс имеет права на обход каталогов в пути.
При использовании драйверов WDM диспетчер операций ввода-вывода не выполняет проверка безопасности в пространстве имен, если объект устройства не был создан, указав FILE_DEVICE_SECURE_OPEN. Если FILE_DEVICE_SECURE_OPEN не задано, драйвер отвечает за безопасность своего пространства имен. Дополнительные сведения см. в разделе "Управление доступом к пространству имен устройств и защита объектов устройств".
Для драйверов WDF всегда устанавливается флаг FILE_DEVICE_SECURE_OPEN таким образом, чтобы было проверка дескриптора безопасности устройства, прежде чем разрешить приложению доступ к любым именам в пространстве имен устройства. Дополнительные сведения см. в разделе "Управление доступом к устройству" в драйверах KMDF.
Границы безопасности Windows
Водители, взаимодействующие друг с другом и вызывающими в пользовательском режиме различными уровнями привилегий, можно считать пересечением границы доверия. Граница доверия — это любой путь выполнения кода, пересекающийся из более низкого привилегированного процесса в более высокий привилегированный процесс.
Чем выше неравенство на уровнях привилегий, тем интереснее границы для злоумышленников, которые хотят выполнять атаки, такие как атака на повышение привилегий в отношении целевого водителя или процесса.
Часть процесса создания модели угроз заключается в изучении границ безопасности и поиск непреднамеренных путей. Дополнительные сведения см. в разделе "Моделирование угроз" для драйверов.
Все данные, пересекающие границу доверия, являются ненадежными и должны быть проверены.
На этой схеме показаны три драйвера ядра и два приложения, один в контейнере приложений и одно приложение, которое выполняется с правами администратора. Красные линии указывают примеры границ доверия.
Так как контейнер приложения может предоставить дополнительные ограничения и не работает на уровне администратора, путь (1) является более высоким путь риска для атаки эскалации, так как граница доверия находится между контейнером приложения (очень низким процессом привилегий) и драйвером ядра.
Путь (2) — это более низкий путь риска, так как приложение работает с правами администратора и вызывается непосредственно в драйвер ядра. Администратор уже является довольно высокой привилегией в системе, поэтому область атаки от администратора к ядру менее интересна для злоумышленников, но по-прежнему заметной границой доверия.
Путь (3) — это пример пути выполнения кода, пересекающего несколько границ доверия, которые могут быть пропущены, если модель угроз не создана. В этом примере существует граница доверия между драйвером 1 и драйвером 3, так как драйвер 1 принимает входные данные из приложения пользовательского режима и передает его непосредственно драйверу 3.
Все входные данные, поступающие в драйвер из пользовательского режима, ненадежны и должны быть проверены. Входные данные, поступающие из других драйверов, также могут быть ненадежными в зависимости от того, был ли предыдущий драйвер просто сквозной передачи (например, данные были получены драйвером 1 из приложения 1, драйвер 1 не выполнял никаких проверок данных и только что передал его драйверу 3). Обязательно определите все области атак и границы доверия и проверьте все данные, пересекая их, создав полную модель угроз.
Рекомендации модели Безопасность Windows
- Задайте строгие списки управления доступом по умолчанию в вызовах подпрограммы IoCreateDeviceSecure .
- Укажите списки управления доступом в INF-файле для каждого устройства. При необходимости эти списки управления доступом могут ослаблять жесткие списки управления доступом по умолчанию.
- Задайте FILE_DEVICE_SECURE_OPEN характеристику, чтобы применить параметры безопасности объекта устройства к пространству имен устройства.
- Не определяйте ioCTLs, разрешающие FILE_ANY_ACCESS, если такой доступ не может быть злонамерен.
- Используйте подпрограмму IoValidateDeviceIoControlAccess для ужесточения безопасности существующих IOCTLS, которые позволяют FILE_ANY_ACCESS.
- Создайте модель угроз, чтобы изучить границы безопасности и искать непреднамеренные пути. Дополнительные сведения см. в разделе "Моделирование угроз" для драйверов.
- Дополнительные рекомендации по безопасности драйверов см. в списке проверка безопасности драйверов.