Защита конфиденциальных данных от несанкционированного доступа очень важна в любой среде, где множество пользователей обращается к одним и тем же физическим или сетевым ресурсам. У операционной системы, как и у отдельных пользователей, должна быть возможность защиты файлов, памяти и конфигурационных параметров от нежелательного просмотра и внесения изменений. Безопасность операционной системы обеспечивается такими очевидными механизмами, как учетные записи, пароли и защита файлов. Ho она требует и менее очевидных механизмов — защиты операционной системы от повреждения, запрета непривилегированным пользователям определенных действий (например, перезагрузки компьютера), предотвращения неблагоприятного воздействия программ одних пользователей на программы других пользователей или на операционную систему.
B этой главе мы поясним, как жесткие требования к защите повлияли на внутреннее устройство и реализацию Microsoft Windows.
Четкие стандарты безопасности программного обеспечения, в том числе операционных систем, помогают правительству, корпорациям и индивидуальным пользователям защищать хранящиеся в компьютерных системах данные, составляющие личную и коммерческую тайну. Текущий стандарт на рейтинги безопасности, применяемый в США и многих других странах, — Common Criteria (CC). Однако, чтобы понять средства защиты, существующие в Windows, нужно знать историю системы рейтингов безопасности, повлиявшей на архитектуру системы защиты Windows, — Trusted Computer System Evaluation Criteria (TCSEC).
Национальный центр компьютерной безопасности (National Computer Security Center, NCSC, www.radium.ncsc.mil/tpep) был создан в 1981 году в Агентстве национальной безопасности (NSA) Министерства обороны США. Одна из задач NCSC заключалась в определении рейтингов безопасности (см. таблицу 8–1), отражающих степень защищенности коммерческих операционных систем, сетевых компонентов и приложений. Эти рейтинги, детальное описание которых вы найдете по ссылке www.radium.ncsc.mil/tpepflibrary/rainbow/5200.28-STD.html, были определены в 1983 году и часто называются «Оранжевой книгой» («Orange Book»).
Стандарт TCSEC состоит из рейтингов «уровней доверия» («levels of trust» ratings), где более высокие уровни строятся на более низких за счет последовательного ужесточения требований к безопасности и проверке. Ни одна операционная система не соответствует уровню Al (Verified Design). Хотя некоторым операционным системам присвоен один из уровней В, уровень C2 считается достаточным и является высшим для операционных систем общего назначения.
B июле 1995 года Windows NT 3.5 CWorkstation и Server) с Service Pack 3 первой из всех версий Windows NT получила подтверждение об уровне безопасности C2. B марте 1999 года организация ITSEC (Information Technology Security) правительства Великобритании присвоила Windows NT 4 с Service Pack 3 уровень E3, эквивалентный американскому уровню C2. Windows NT 4 с Service Pack 6a получила уровень C2 для сетевой и автономной конфигураций.
Какие требования предъявляются к уровню безопасности C2? Основные требования (они остались прежними) перечислены ниже.
• Механизм безопасной регистрации, требующий уникальной идентификации пользователей. Доступ к компьютеру предоставляется лишь после аутентификации.
• Управление избирательным доступом, позволяющее владельцу ресурса определять круг лиц, имеющих доступ к ресурсу, а также их права на операции с этим ресурсом. Владелец предоставляет пользователям и их группам различные права доступа.
• Аудит безопасности, обеспечивающий возможность регистрации событий, связанных с защитой, а также любых попыток создания, удаления и обращения к системным ресурсам. При входе регистрируются идентификационные данные всех пользователей, что позволяет легко выявить любого, кто попытался выполнить несанкционированную операцию.
• Защита при повторном использовании объектов, которая предотвращает просмотр одним из пользователей данных, удаленных из памяти другим, а также доступ к памяти, освобожденной предыдущим пользователем. Например, в некоторых операционных системах можно создать новый файл определенной длины, а затем просмотреть те данные, которые остались на диске и попали в область, отведенную под новый файл. Среди этих данных может оказаться конфиденциальная информация, хранившаяся в недавно удаленном файле другого пользователя. Так что защита при повторном использовании объектов устраняет потенциальную дыру в системе безопасности, заново инициализируя перед выделением новому пользователю все объекты, включая файлы и память. Windows также отвечает двум требованиям защиты уровня В.
• Функциональность пути доверительных отношений (trusted path functionality), которая предотвращает перехват имен и паролей пользователей программами — троянскими конями. Эта функциональность реализована в Windows в виде входной сигнальной комбинации клавиш Ctrl+Alt+Del и не может быть перехвачена непривилегированными приложениями. Такая комбинация клавиш, известная как SAS (secure attention sequence), вызывает диалоговое окно входа в систему, обходя вызов его фальшивого эквивалента из троянского коня.
• Управление доверительными отношениями (trusted facility management), которое требует поддержки набора ролей (различных типов учетных записей) для разных уровней работы в системе. Например, функции администрирования доступны только по одной группе учетных записей — Administrators (Администраторы).
Windows соответствует всем перечисленным требованиям.
B январе 1996 года США, Великобритания, Германия, Франция, Канада и Нидерланды опубликовали совместно разработанную спецификацию оценки безопасности Common Criteria for Information Technology Security Evaluation (CCITSE). Эта спецификация, чаще называемая Common Criteria (CC) (csrc.nist.gov/cc), является международным стандартом оценки степени защищенности продуктов.
CC гибче уровней доверия TCSEC и по структуре ближе ITSEC, чем TCSEC CC включает две концепции:
• профиля защиты (Protection Profile, PP) — требования к безопасности разбиваются на группы, которые легко определять и сравнивать;
• объекта защиты (Security Target, ST) — предоставляет набор требований к защите, которые могут быть подготовлены с помощью PR Windows 2000 оценивалась на соответствие требованиям Controlled Access PP, эквивалентным TCSEC C2, и на соответствие дополнительным требованиям Common Criteria в октябре 2002 года. K значимым требованиям, не включенным в Controlled Access PP, но предъявляемым по условиям Windows 2000 Security Target, относятся:
• функции управления избирательным доступом (Discretionary Access Control Functions), основанные на применении криптографии. Они peaлизуются файловой системой Encrypting File System и Data Protection API в Windows 2000;
• политика управления избирательным доступом (Discretionary Access Control Policy) для дополнительных пользовательских объектов данных (User Data Objects), например объекты Desktop и WindowStation (реализуются подсистемой поддержки окон Windows 2000), а также объекты Active Directory (реализуются службой каталогов в Windows 2000);
• внутренняя репликация (Internal Replication) для гарантированной синхронизации элементов данных, связанных с защитой, между физически раздельными частями системы Windows 2000 как распределенной операционной системы. Это требование реализуется службой каталогов Windows 2000 с применением модели репликации каталогов с несколькими хозяевами;
• утилизация ресурсов (Resource Utilization) для физических пространств дисков. Это требование реализуется файловой системой NTFS в Windows 2000;
• блокировка интерактивного сеанса (Interactive Session Locking) и путь доверительных отношений (Trusted Path) для первоначального входа пользователя (initial user logging on). Это требование реализуется компонентом Winlogon в Windows 2000;
• защита внутренней передачи данных (Internal Data Transfer Protection), чтобы обезопасить данные от раскрытия и несанкционированной модификации при передаче между физически раздельными частями системы Windows 2000 как распределенной операционной системы. Это требование реализуется службой IPSEC в Windows 2000;
• систематическое устранение обнаруживаемых недостатков в системе защиты (Systematic Flaw Remediation). Это требование реализуется Microsoft Security Response Center и Windows Sustained Engineering Team.
Ha момент написания этой книги Windows XP Embedded, Windows XP Professional и Windows Server 2003 все еще проходили оценку на соответствие Common Criteria. Набор критериев расширен по сравнению с тем, который применялся к Windows 2000. Комитет Common Criteria в настоящее время рассматривает Windows XP и Windows Server 2003 (Standard, Enterprise и Datacenter Edition) для оценки технологий следующих типов (см. niapnist.gov/cc-scheme/in_evaluation.htmt)\
• распределенной операционной системы;
• защиты конфиденциальных данных;
• управления сетью;
• службы каталогов;
• брандмауэра;
• VPN (Virtual Private Network);
• управления рабочим столом;
• инфраструктуры открытого ключа (Public Key Infrastructure, PKI);
• выдачи и управления сертификатами открытого ключа; • встраиваемой операционной системы.
Ниже перечислены главные компоненты и базы данных, на основе которых реализуется защита в Windows.
• Монитор состояния защиты (Security Reference Monitor, SRM) Компонент исполнительной системы (\Windows\System32\ Ntoskrnl.exe), отвечающий за определение структуры данных маркера доступа для представления контекста защиты, за проверку прав доступа к объектам, манипулирование привилегиями (правами пользователей) и генерацию сообщений аудита безопасности.
• Подсистема локальной аутентификации (local security authentication subsystem, LSASS) Процесс пользовательского режима, выполняющий образ \Windows\System32\Lsass.exe, который отвечает за политику безопасности в локальной системе (например, крут пользователей, имеющих право на вход в систему, правила, связанные с паролями, привилегии, выдаваемые пользователям и их группам, параметры аудита безопасности системы), а также за аутентификацию пользователей и передачу сообщений аудита безопасности в Event Log. Основную часть этой функциональности реализует сервис локальной аутентификации Lsasrv (\Windows\System32\Lsasrv.dll) — DLL-модуль, загружаемый Lsass.
• База данных политики LSASS База данных, содержащая параметры политики безопасности локальной системы. Она хранится в разделе реестра HKLM\SECURITY и включает следующую информацию: каким доменам доверена аутентификация попыток входа в систему, кто имеет права на доступ к системе и каким образом, кому предоставлены те или иные привилегии и какие виды аудита следует выполнять. База данных политики LSASS также хранит «секреты», которые включают в себя регистрационные данные, применяемые для входа в домены и при вызове Windows-сервисов (о Windows-сервисах см. главу 5).
• Диспетчер учетных записей безопасности (Security Accounts Manager, SAM) Набор подпрограмм, отвечающих за поддержку базы данных, которая содержит имена пользователей и группы, определенные на локальной машине. Служба SAM, реализованная как \Windows\System32\ Samsrv.dll, выполняется в процессе Lsass.
• База данных SAM База данных, которая в системах, отличных от контроллеров домена, содержит информацию о локальных пользователях и группах вместе с их паролями и другими атрибутами. Ha контроллерах домена SAM содержит определение и пароль учетной записи администратора, имеющего права на восстановление системы. Эта база данных хранится в разделе реестра HKLM\SAM.
• Active Directory Служба каталогов, содержащая базу данных со сведениями об объектах в домене. Домен — это совокупность компьютеров и сопоставленных с ними групп безопасности, которые управляются как единое целое. Active Directory хранит информацию об объектах домена, в том числе о пользователях, группах и компьютерах. Сведения о паролях и привилегиях пользователей домена и их групп содержатся в Active Directory и реплицируются на компьютеры, выполняющие роль контроллеров домена. Сервер Active Directory, реализованный как \Windows\System32\Ntdsa.dll, выполняется в процессе Lsass. Подробнее об Active Directory см. главу 13.
• Пакеты аутентификации DLL-модули, выполняемые в контексте процесса Lsass и клиентских процессов и реализующие политику аутентификации в Windows. DLL аутентификации отвечает за проверку пароля и имени пользователя, а также за возврат LSASS (в случае успешной проверки) детальной информации о правах пользователя, на основе которой LSASS генерирует маркер (token).
• Процесс входа (Winlogon) Процесс пользовательского режима (\Windows\System32\Winlogon.exe), отвечающий за поддержку SAS и управление сеансами интерактивного входа в систему. Например, при регистрации пользователя Winlogon создает оболочку — пользовательский интерфейс.
• GINA (Graphical Identification and Authentication) DLL пользовательского режима, выполняемая в процессе Winlogon и применяемая для получения пароля и имени пользователя или PIN-кода смарт-карты. Стандартная GINA хранится в \Windows\System32\Msgina.dll.
• Служба сетевого входа (Netlogon) Windows-сервис (\Windows\System32 \Netlogon.dll), устанавливающий защищенный канал с контроллером домена, по которому посылаются запросы, связанные с защитой, например для интерактивного входа (если контроллер домена работает под управлением Windows NT), или запросы на аутентификацию от LAN Manager либо NT LAN Manager (vl и v2).
• Kernel Security Device Driver (KSecDD) Библиотека функций режима ядра, реализующая интерфейсы LPC (local procedure call), которые используются другими компонентами защиты режима ядра — в том числе шифрующей файловой системой (Encrypting File System, EFS) — для взаимодействия с LSASS в пользовательском режиме. KsecDD содержится в \Windows\System32\Drivers\Ksecdd.sys.
Ha рис. 8–1 показаны взаимосвязи между некоторыми из этих компонентов и базами данных, которыми они управляют.
ЭКСПЕРИМЕНТ: просмотр содержимого HKLM\SAM и HKLM\Security
Дескрипторы защиты, сопоставленные с разделами реестра SAM и Security, блокируют доступ по любой учетной записи, кроме Local System. Один из способов получить доступ к этим разделам — сбросить их защиту, но это может ослабить безопасность системы. Другой способ — запустить Regedit.exe под учетной записью Local System; такой способ поддерживается утилитой PsExec (wwwsysinternals.com), которая позволяет запускать процессы под этой учетной записью:
C:›psexec — s — i — d c: \windows\regedit.exe
SRM, выполняемый в режиме ядра, и LSASS, работающий в пользовательском режиме, взаимодействуют по механизму LPC (см. главу 3). При инициализации системы SRM создает порт SeRmCommandPort, к которому подключается LSASS. Процесс Lsass при запуске создает LPC-порт SeLsaCommandPort. K этому порту подключается SRM. B результате формируются закрытые коммуникационные порты. SRM создает раздел общей памяти для передачи сообщений длиннее 256 байтов и передает его описатель при запросе на соединение. После соединения SRM и LSASS на этапе инициализации системы они больше не прослушивают свои порты. Поэтому никакой пользовательский процесс не сможет подключиться к одному из этих портов.
Рис. 8–2 иллюстрирует коммуникационные пути после инициализации системы.
Защита объектов и протоколирование обращений к ним — вот сущность управления избирательным доступом и аудита. Защищаемые объекты Windows включают файлы, устройства, почтовые ящики, каналы (именованные и анонимные), задания, процессы, потоки, события, пары событий, мьютексы, семафоры, порты завершения ввода-вывода, разделы общей памяти, LPC-порты, ожидаемые таймеры, маркеры доступа, тома, объекты WindowStation, рабочие столы, сетевые ресурсы, сервисы, разделы реестра, принтеры и объекты Active Directory.
Поскольку системные ресурсы, экспортируемые в пользовательский режим (и поэтому требующие проверки защиты), реализуются как объекты режима ядра, диспетчер объектов играет ключевую роль в их защите (о диспетчере объектов см. главу 3). Для контроля за операциями над объектом система защиты должна быть уверена в правильности идентификации каждого пользователя. Именно по этой причине Windows требует от пользователя входа с аутентификацией, прежде чем ему будет разрешено обращаться к системным ресурсам. Когда какой-либо процесс запрашивает описатель объекта, диспетчер объектов и система защиты на основе идентификационных данных вызывающего процесса определяют, можно ли предоставить ему описатель, разрешающий доступ к нужному объекту.
Контекст защиты потока может отличаться от контекста защиты его процесса. Этот механизм называется олицетворением (impersonation), или подменой. При олицетворении механизмы проверки защиты используют вместо контекста защиты процесса контекст защиты потока, а без олицетворения — контекст защиты процесса, которому принадлежит поток. Важно не забывать, что все потоки процесса используют одну и ту же таблицу описателей, поэтому, когда поток открывает какой-нибудь объект (даже при олицетворении), все потоки процесса получают доступ к этому объекту.
Модель защиты Windows требует, чтобы поток заранее — еще до открытия объекта — указывал, какие операции он собирается выполнять над этим объектом. Система проверяет тип доступа, запрошенный потоком, и, если такой доступ ему разрешен, он получает описатель, позволяющий ему (и другим потокам того же процесса) выполнять операции над объектом. Как уже говорилось в главе 3, диспетчер объектов регистрирует права доступа, предоставленные для данного описателя, в таблице описателей, принадлежащей процессу.
Одно из событий, заставляющее диспетчер объектов проверять права доступа, — открытие процессом существующего объекта по имени. При открытии объекта по имени диспетчер объектов ищет его в своем пространстве имен. Если этого объекта нет во вторичном пространстве имен (например, в пространстве имен реестра, принадлежащем диспетчеру конфигурации, или в пространстве имен файловой системы, принадлежащем драйверу файловой системы), диспетчер объектов вызывает внутреннюю функцию ObpCreateHandle. Как и подсказывает ее имя, она создает элемент в таблице описателей, который сопоставляется с объектом. Однако ObpCreateHandle вызывает функцию исполнительной системы ExCreateHandle и создает описатель, только если другая функция диспетчера объектов, ObpIncrementHandleCount, сообщает, что поток имеет право на доступ к данному объекту. Правда, реальную проверку прав доступа осуществляет другая функция диспетчера объектов, ObCheckObjectAccess, которая возвращает результаты проверки функции ObpIncrementHandleCount.
ObpIncrementHandleCount передает ObCheckObjectAccess удостоверения защиты потока, открывающего объект, типы запрошенного им доступа (чтение, запись, удаление и т. д.), а также указатель на объект. ObCheckObjectAccess сначала блокирует защиту объекта и контекст защиты потока. Блокировка защиты объекта предотвращает ее изменение другим потоком в процессе проверки прав доступа, а блокировка контекста защиты потока не дает другому потоку того же или другого процесса изменить идентификационные данные защиты первого потока при проверке его прав доступа. Далее ObCheckObjectAccess вызывает метод защиты объекта, чтобы получить параметры защиты объекта (описание методов объектов см. в главе 3). Вызов метода защиты может привести к вызову функции из другого компонента исполнительной системы, но многие объекты исполнительной системы полагаются на стандартную поддержку управления защитой, предлагаемую системой.
Если компонент исполнительной системы, определяя объект, не собирается заменять стандартную политику безопасности, он помечает тип этих объектов как использующий стандартную защиту. Всякий раз, когда SRM вызывает метод защиты объекта, он сначала проверяет, использует ли объект стандартную защиту. Объект со стандартной защитой хранит информацию о защите в своем заголовке и предоставляет метод защиты с именем SeDefaultObjectMethod. Объект, не использующий стандартную защиту, должен сам поддерживать информацию о защите и предоставлять собственный метод защиты. Стандартную защиту используют такие объекты, как мьютексы, события и семафоры. Пример объекта с нестандартной защитой — файл. У диспетчера ввода-вывода, определяющего объекты типа «файл», имеется драйвер файловой системы, который управляет защитой своих файлов (или решает не реализовать ее). Таким образом, когда система запрашивает информацию о защите объекта «файл», представляющего файл на томе NTFS, она получает эту информацию от драйвера файловой системы NTFS, который в свою очередь получает ее от метода защиты объекта «файл», принадлежащего диспетчеру ввода-вывода. Заметьте, что при открытии файла ObCheckObjectAccess не выполняется, так как объекты «файл» находятся во вторичных пространствах имен; система вызывает метод защиты объекта «файл», только если потокявно запрашивает или устанавливает параметры защиты файла (например, через Windows-функции SetFileSecurity или GetFileSecurity).
Получив информацию о защите объекта, ObCheckObjectAccess вызывает SRM-функцию SeAccessCheck, на которую опирается вся модель защиты Windows. Она принимает параметры защиты объекта, идентификационные данные защиты потока (в том виде, в каком они получены ObCheckObjectAccess) и тип доступа, запрашиваемый потоком. SeAccessCheck возвращает True или False в зависимости от того, предоставляет ли она потоку запрошенный тип доступа к объекту.
Другое событие, заставляющее диспетчер объектов выполнять проверку прав доступа, — ссылка процесса на объект по существующему описателю. Подобные ссылки часто делаются косвенно, например при манипуляциях с объектом через Windows API с передачей его описателя. Допустим, поток, открывающий файл, запрашивает доступ для чтения из файла. Если у потока есть соответствующие права, определяемые его контекстом защиты и параметрами защиты файла, диспетчер объектов создает описатель данного файла в таблице описателей, которая принадлежит процессу — владельцу этого потока. Информация о предоставленном процессу типе доступа сопоставляется с описателем и сохраняется диспетчером объектов.
Впоследствии поток может попытаться что-то записать в этот файл через Windows-функцию WriteFile, передав в качестве параметра описатель файла. Системный сервис NtWriteFile, который WriteFile вызовет через Ntdll.dll, обратится к функции диспетчера объектов ObReferenceObjectByHandle, чтобы получить указатель на объект «файл» по его описателю. ObReferenceObjectByHandle принимает запрошенный тип доступа как параметр. Найдя в таблице описателей элемент, соответствующий нужному описателю, ObReferenceObjectByHandle сравнит запрошенный тип доступа с тем, который был предоставлен при открытии файла. B данном случае ObReferenceObjectByHandle укажет, что операция записи должна завершиться неудачно, так как вызывающий поток, открывая файл, не получил право на его запись.
Функции защиты Windows также позволяют Windows-приложениям определять собственные закрытые объекты и вызывать SRM-сервисы для применения к этим объектам средств защиты Windows. Многие функции режима ядра, используемые диспетчером объектов и другими компонентами исполнительной системы для защиты своих объектов, экспортируются в виде Windows-функций пользовательского режима. Например, эквивалентом SeAccessCheck для пользовательского режима является AccessCheck. Таким образом, Windows-приложения могут применять модель защиты Windows и интегрироваться с интерфейсами аутентификации и администрирования этой операционной системы.
Сущность модели защиты SRM отражает математическое выражение с тремя входными параметрами: идентификационными данными защиты потока, запрошенным типом доступа и информацией о защите объекта. Его результат — значения «да» или «нет», которые определяют, предоставит ли модель защиты запрошенный тип доступа. B следующих разделах мы поговорим об этих входных параметрах и алгоритме проверки прав доступа в модели защиты.
Для идентификации объектов, выполняющих в системе различные действия, Windows использует не имена (которые могут быть не уникальными), а идентификаторы защиты (security identifiers, SID). SID имеются у пользователей, локальных и доменных групп, локальных компьютеров, доменов и членов доменов. SID представляет собой числовое значение переменной длины, формируемое из номера версии структуры SID, 48-битного кода агента идентификатора и переменного количества 32-битных кодов субагентов и/ или относительных идентификаторов (relative identifiers, RID). Код агента идентификатора (identifier authority value) определяет агент, выдавший SID. Таким агентом обычно является локальная система или домен под управлением Windows. Коды субагентов идентифицируют попечителей, уполномоченных агентом, который выдал SID, a RID — не более чем средство создания уникальных SID на основе общего базового SID (common-based SID). Поскольку длина SID довольно велика и Windows старается генерировать истинно случайные значения для каждого SID, вероятность появления двух одинаковых SID практически равна нулю.
B текстовой форме каждый SID начинается с префикса S за которым следуют группы чисел, разделяемые дефисами, например:
S-1-5-21-1463437245-1224812800-863842198-1128
B этом SID номер версии равен 1, код агента идентификатора — 5 (центр безопасности Windows), далее идут коды четырех субагентов и один RID в конце (1128). Этот SID относится к домену, так что локальный компьютер этого домена получит SID с тем же номером версии и кодом агента идентификатора; кроме того, в нем будет столько же кодов субагентов.
SID назначается компьютеру при установке Windows (программой Windows Setup). Далее Windows назначает SID локальным учетным записям на этом компьютере. SID каждой локальной учетной записи формируется на основе SID компьютера с добавлением RID. RID пользовательской учетной записи начинается с 1000 и увеличивается на 1 для каждого нового пользователя или группы. Аналогичным образом Dcpromo.exe — утилита, применяемая при создании нового домена Windows, — выдает SID только что созданному домену. Новые учетные записи домена получают SID, формируемые на основе SID домена с добавлением RID (который также начинается с 1000 и увеличивается на 1 для каждого нового пользователя или группы). RID с номером 1028 указывает на то, что его SID является 29-м, выданным доменом.
Многим предопределенным учетным записям и группам Windows выдает SID, состоящие из SID компьютера или домена и предопределенного RID. Так, RID учетной записи администратора равен 500, a RID гостевой учетной записи — 501. Например, в основе SID учетной записи локального администратора лежит SID компьютера, к которому добавлен RID, равный 500:
S-1-5-21-13124455-12541255-61235125-500
Для групп Windows также определяет ряд встроенных локальных и доменных SID. Например, SID, представляющий любую учетную запись, называется Everyone или World и имеет вид S-1 -1 -0. Еще один пример — сетевая группа, т. е. группа, пользователи которой зарегистрировались на данном компьютере из сети. SID сетевой группы имеет вид S-l-5-2. Список некоторых общеизвестных SID приведен в таблице 8–2 (полный список см. в документации Platform SDK).
Наконец, Winlogon создает уникальный SID для каждого интерактивного сеанса входа. SID входа, как правило, используется в элементе списка управления доступом (access-control entry, АСЕ), который разрешает доступ на время сеанса входа клиента. Например, Windows-сервис может вызвать функцию LogonUser для запуска нового сеанса входа. Эта функция возвращает маркер доступа, из которого сервис может извлечь SID входа. Потом этот SID сервис может использовать в АСЕ, разрешающем обращение к интерактивным объектам WindowStation и Desktop из сеанса входа клиента. SID для сеанса входа выглядит как S-l-5-5-0, a RID генерируется случайным образом.
ЭКСПЕРИМЕНТ: просмотр SID учетных записей с помощью PsGetSid
Представление SID для любой учетной записи легко увидеть, запустив утилиту PsGetSid (wwwsysinternals.com). У нее следующий интерфейс:
Параметры PsGetSid позволяют транслировать имена учетных записей пользователей и компьютеров в соответствующие SID и наоборот.
Если PsGetSid запускается без параметров, она выводит SID, назначенный локальному компьютеру. Используя тот факт, что учетной записи Administrator всегда присваивается RID, равный 500, вы можете определить имя этой учетной записи (в тех случаях, когда системный администратор переименовал ее по соображениям безопасности), просто передав SID компьютера, дополненный «-500», как аргумент командной строки PsGetSid.
Чтобы получить SID доменной учетной записи, введите имя пользователя с указанием домена:
с: \›psgetsid redmond\daryl
Вы можете выяснить SID домена, передав в PsGetSid его имя как аргумент:
c: \›psgetsid Redmond
Наконец, изучив RID своей учетной записи, вы по крайней мере узнаете, сколько учетных записей защиты (security accounts), равное значению, полученному вычитанием 999 из вашего RID, было создано в вашем домене или на вашем локальном компьютере (в зависимости от используемой вами учетной записи — доменной или локальной). Чтобы определить, каким учетным записям были присвоены RID, передайте SID с интересующим вас RID. Если PsGetSid сообщит, что сопоставить SID с каким-либо именем учетной записи не удалось, и значение RID окажется меньше, чем у вашей учетной записи, значит, учетная запись, по которой был присвоен RID, уже удалена.
Например, чтобы выяснить имя учетной записи, по которой был назначен двадцать восьмой RID, передайте SID домена с добавлением «-1027»:
c: \›psgetsid S-1-5-21-1787744166-3910675280-2727264193-1027 Account for S-1-5-21-1787744166-3910675280-2727264193-1027: User: redmond\daryl
Для идентификации контекста защиты процесса или потока SRM использует объект, называемый маркером (token), или маркером доступа (access token). B контекст защиты входит информация, описывающая привилегии, учетные записи и группы, сопоставленные с процессом или потоком. B процессе входа в систему (этот процесс рассматривается в конце главы) Winlogon создает начальный маркер, представляющий пользователя, который входит в систему, и сопоставляет его с начальным процессом (или процессами) — по умолчанию запускается Userinit.exe. Так как дочерние процессы по умолчанию наследуют копию маркера своего создателя, все процессы в сеансе данного пользователя выполняются с одним и тем же маркером. Вы можете сгенерировать маркер вызовом Windows-функции LogonUser и применить его для создания процесса, который будет выполняться в контексте защиты пользователя, зарегистрированного с помощью функции LogonUser, с этой целью вы должны передать полученный маркер Windows-функции CreateProcessAsUser. Функция CreateProcessWithLogon тоже создает маркер, создавая новый сеанс входа с начальным процессом. Именно так команда runas запускает процессы с альтернативными маркерами.
Длина маркеров варьируется из-за того, что учетные записи разных пользователей имеют неодинаковые наборы привилегий и сопоставлены с разными учетными записями групп. Ho все маркеры содержат одну и ту же информацию, показанную на рис. 8–3.
Механизмы защиты в Windows используют два элемента маркера, определяя, какие объекты доступны и какие операции можно выполнять. Первый элемент состоит из SID учетной записи пользователя и полей SID групп. Используя SID-идентификаторы, SRM определяет, можно ли предоставить запрошенный тип доступа к защищаемому объекту, например к файлу в NTFS.
SID групп в маркере указывают, в какие группы входит учетная запись пользователя. При обработке клиентских запросов серверные приложения могут блокировать определенные группы для ограничения удостоверений защиты, сопоставленных с маркером. Блокирование группы дает почти тот же эффект, что и ее исключение из маркера. (Блокированные SID все же используются при проверке прав доступа, но об этом мы расскажем потом.)
Вторым элементом маркера, определяющим, что может делать поток или процесс, которому назначен данный маркер, является список привилегий — прав, сопоставленных с маркером. Примером привилегии может служить право процесса или потока, сопоставленного с маркером, на выключение компьютера. (Подробнее привилегии будут рассмотрены позже.) Поля основной группы маркера по умолчанию и списка управления избирательным доступом (discretionary access-control list, DACL) представляют собой атрибуты защиты, применяемые Windows к объектам, которые создаются процессом или потоком с использованием маркера. Включая в маркеры информацию о защите, Windows упрощает процессам и потокам создание объектов со стандартными атрибутами защиты, так как в этом случае им не требуется запрашивать информацию о защите при создании каждого объекта.
Маркер может быть основным (primary token) (идентифицирует контекст защиты процесса) и олицетворяющим (impersonation token) (применяется для временного заимствования потоком другого контекста защиты — обычно другого пользователя). Маркеры олицетворения сообщают уровень олицетворения, определяющий, какой тип олицетворения активен в маркере.
Остальные поля маркера служат для информационных нужд. Поле источника маркера содержит сведения (в текстовой форме) о создателе маркера. Оно позволяет различать такие источники, как диспетчер сеансов Windows, сетевой файл-сервер или RPC-сервер. Идентификатор маркера представляет собой локально уникальный идентификатор (locally unique identifier, LUID), который SRM присваивает маркеру при его создании. Исполнительная система поддерживает свой LUID — счетчик, с помощью которого она назначает каждому маркеру уникальный числовой идентификатор.
Еще одна разновидность LUID — идентификатор аутентификации (authentication ID). Он назначается маркеру создателем при вызове функции LsaLogonUser. Если создатель не указывает LUID, то LSASS формирует LUID из LUID исполнительной системы. LSASS копирует идентификатор аутентификации для всех маркеров — потомков начального маркера. Используя этот идентификатор, программа может определить, принадлежит ли какой-то маркер тому же сеансу, что и остальные маркеры, анализируемые данной программой.
LUID исполнительной системы обновляет идентификатор модификации при каждом изменении характеристик маркера. Проверяя этот идентификатор, программа может обнаруживать изменения в контексте защиты с момента его последнего использования.
Маркеры содержат поле времени окончания действия, которое присутствует в них, начиная с Windows NT 3.1, но до сих пор не используется. Будущая версия Windows, возможно, будет поддерживать маркеры, действительные только в течение определенного срока. Представьте, что администратор выдал пользователю учетную запись, срок действия которой ограничен. Сейчас, если срок действия учетной записи истекает в тот момент, когда пользователь все еще находится в системе, он может по-прежнему обращаться к системным ресурсам, доступ к которым был разрешен по просроченной учетной записи. Единственное, что можно сделать в такой ситуации, — принудительно завершить сеанс работы этого пользователя. Если бы Windows поддерживала маркеры с ограниченным сроком действия, система могла бы запретить пользователю доступ к ресурсу сразу по окончании срока действия маркера.
ЭКСПЕРИМЕНТ: просмотр маркеров доступа
Команда dt_TOKEN отладчика ядра показывает формат внутреннего объекта «маркер». Хотя его структура отличается от структуры маркера пользовательского режима, возвращаемой Windows-функциями защиты, их поля аналогичны. Детальное описание маркеров см. в документации Platform SDK.
Ниже приведен пример вывода команды dt_TOKEN отладчика ядра.
Маркер для процесса можно увидеть с помощью команды !token. Адрес маркера вы найдете в информации, сообщаемой командой !process, как показано в следующем примере.
Содержимое маркера можно косвенно увидеть с помощью Process Explorer (wwwsysintemals.com) на вкладке Security в диалоговом окне свойств процесса. B этом окне показываются группы и привилегии, включенные в маркер исследуемого вами процесса.
Олицетворение (impersonation) — мощное средство, часто используемое в модели защиты Windows. Олицетворение также применяется в модели программирования «клиент-сервер». Например, серверное приложение может экспортировать ресурсы (файлы, принтеры или базы данных). Клиенты, которые хотят обратиться к этим ресурсам, посылают серверу запрос. Получив запрос, сервер должен убедиться, что у клиента есть разрешение на выполнение над ресурсом запрошенных операций. Так, если пользователь на удаленной машине пытается удалить файл с сетевого диска NTFS, сервер, экспортирующий этот сетевой ресурс, должен проверить, имеет ли пользователь право удалить данный файл. Казалось бы, в таком случае сервер должен запросить учетную запись пользователя и SID-идентификаторы группы, а также просканировать атрибуты защиты файла. Ho этот процесс труден для программирования, подвержен ошибкам и не позволяет обеспечить поддержку новых функций защиты. Поэтому Windows в таких ситуациях предоставляет серверу сервисы олицетворения.
Олицетворение позволяет серверу уведомить SRM о временном заимствовании профиля защиты клиента, запрашивающего ресурс. После этого сервер может обращаться к ресурсам от имени клиента, a SRM — проводить проверку его прав доступа. Обычно серверу доступен более широкий круг ресурсов, чем клиенту, и при олицетворении сервер может терять часть исходных прав доступа. Также вероятно и обратное: при олицетворении сервер может получить дополнительные права.
Сервер олицетворяет клиент лишь в пределах потока, выдавшего запрос на олицетворение. Управляющие структуры данных потока содержат необязательный элемент для маркера доступа. Однако основной маркер потока, отражающий его реальные права, всегда доступен через управляющие структуры процесса.
За поддержку олицетворения в Windows отвечает несколько механизмов. Если сервер взаимодействует с клиентом через именованный канал, он может вызвать Windows-функцию ImpersonateNamedPipeClient и тем самым сообщить SRM о том, что ему нужно подменить собой пользователя на другом конце канала. Если сервер взаимодействует с клиентом через DDE (Dynamic Data Exchange) или RPC, то выдает аналогичный запрос на олицетворение через DdeImpersonateClient или RpcImpersonateClient. Поток может создать маркер олицетворения просто как копию маркера своего процесса, вызвав функцию ImpersonateSelf. Для блокировки каких-то SID или привилегий поток может потом изменить полученный маркер олицетворения. Наконец, пакет SSPI (Security Support Provider Interface) может олицетворять своих клиентов через ImpersonateSecurityContext. SSPI реализует модель сетевой защиты вроде LAN Manager версии 2 или Kerberos.
После того как серверный поток завершает выполнение своей задачи, он возвращает себе прежний профиль защиты. Эти формы олицетворения удобны для выполнения определенных операций по запросу клиента и для корректного аудита обращений к объектам. (Например, генерируемые данные аудита сообщают идентификацию подменяемого клиента, а не серверного процесса.) Их недостаток в том, что нельзя выполнять всю программу в контексте клиента. Кроме того, маркер олицетворения не дает доступа к сетевым файлам или принтерам, если только они не поддерживают null-сеансы или не используется олицетворение уровня делегирования (delegation-level impersonation), причем удостоверения защиты достаточны для аутентификации на удаленном компьютере. (Null-сеанс создается при анонимном входе.)
Если все приложение должно выполняться в контексте защиты клиента или получать доступ к сетевым ресурсам, клиент должен быть зарегистрирован в системе. Для этого предназначена Windows-функция LogonUser, которая принимает в качестве параметров имя учетной записи, пароль, имя домена или компьютера, тип входа (интерактивный, пакетный или сервисный) и провайдер входа (logon provider), а возвращает основной маркер. Серверный поток принимает маркер в виде маркера олицетворения, либо сервер запускает программу, основной маркер которой включает удостоверения клиента. C точки зрения защиты, процесс, создаваемый с применением маркера, который возвращается при интерактивном входе через Logon-User, например API-функцией CreateProcessAsUser, выглядит как программа, запущенная пользователем при интерактивном входе в систему. Недостаток этого подхода в том, что серверу приходится получать имя и пароль по учетной записи пользователя. Если сервер передает эту информацию по сети, он должен надежно шифровать ее, чтобы избежать получения имени и пароля злоумышленником, перехватывающим сетевой трафик.
Windows не позволяет серверам подменять клиенты без их ведома. Клиентский процесс может ограничить уровень олицетворения серверным процессом, сообщив при соединении с ним требуемый SQOS (Security Quality of Service). Процесс может указывать флаги SECURITY_ANONYMOUS, SECURITY_IDENTIFICATION, SECURITYIMPERSONATION и SECURITYDELEGATION при вызове Windows-функции CreateFile. Каждый уровень позволяет серверу выполнять различный набор операций относительно контекста защиты клиента:
• SecurityAnonymous — самый ограниченный уровень; сервер не может олицетворять или идентифицировать клиент;
• SecurityIdentification — сервер может получать SID и привилегии клиента, но не получает право на олицетворение клиента;
• SecurityImpersonation — сервер может идентифицировать и олицетворять клиент в локальной системе;
• SecurityDelegation — наименее ограниченный уровень. Позволяет серверу олицетворять клиент в локальных и удаленных системах. Windows NT 4 и более ранние версии лишь частично поддерживают этот уровень олицетворения.
Если клиент не устанавливает уровень олицетворения, Windows по умолчанию выбирает SecurityImpersonation. Функция CreateFile также принимает модификаторы SECURITY_EFFECTIVE_ONLY и SECURITY_CONTEXT_TRACKING.
Первый из них не дает серверу включать/выключать какие-то привилегии или группы клиента на время олицетворения. A второй указывает, что все изменения, вносимые клиентом в свой контекст защиты, отражаются и на сервере, который олицетворяет этот клиент. Данный модификатор действует, только если клиентский и серверный процессы находятся в одной системе.
Ограниченный маркер (restricted token) создается на базе основного или олицетворяющего с помощью функции CreateRestrictedToken и является его копией, в которую можно внести следующие изменения:
• удалить некоторые элементы из таблицы привилегий маркера;
• пометить SID-идентификаторы маркера атрибутом проверки только на запрет (deny-only);
• пометить SID-идентификаторы маркера как ограниченные.
Поведение SID с атрибутом проверки только на запрет (deny-only SID) и ограниченных SID (restricted SID) кратко поясняется в следующих разделах. Ограниченные маркеры удобны, когда приложение подменяет клиент при выполнении небезопасного кода. B ограниченном маркере может, например, отсутствовать привилегия на перезагрузку системы, что не позволит коду, выполняемому в контексте защиты ограниченного маркера, перезагрузить систему.
ЭКСПЕРИМЕНТ: просмотр ограниченных маркеров
B Windows XP или Windows Server 2003 можно заставить Explorer создать процесс с ограниченным маркером по следующей процедуре.
1. Создайте на рабочем столе ярлык для \Windows\Notepad.exe.
2. Отредактируйте свойства ярлыка и установите флажок Run With Different Credentials (Запускать с другими учетными данными). Заметьте: в описании под этим флажком говорится о том, что вы можете запускать программу от своего имени, в то же время защищая компьютер от несанкционированных действий данной программы*.
3. Закройте окно свойств и запустите программу двойным щелчком ее ярлыка.
4. Согласитесь с параметрами по умолчанию для выполнения под текущей учетной записью и защиты компьютера от несанкционированных действий этой программы.
5. Запустите Process Explorer и просмотрите содержимое вкладки Security для свойств запущенного вами процесса Notepad. Заметьте, что маркер содержит ограниченные SID и SID с атрибутом проверки только на запрет, а также что у него лишь одна привилегия. Свойства в левой части окна, показанного на следующей иллюстрации, относятся к Notepad, выполняемому с неограниченным маркером, а свойства в правой части окна — к его экземпляру, запущенному по описанной процедуре.
* B русской версии Windows XP ошибочно говорится о защите от несанкционированных действий других программ. — Прим. перев.
Ограниченный маркер дает несколько побочных эффектов.
• Удаляются все привилегии, кроме SeChangeNotifyPrivilege.
• Любые SID администраторов или пользователей с правами администраторов помечаются как Deny-Only (проверка только на запрет). Такой SID удаляет права доступа к любым ресурсам, доступ к которым для администраторов запрещен соответствующим АСЕ, но в ином случае был бы замещен АСЕ, ранее выданным группе администраторов через дескриптор защиты.
• RESTRICTED SID добавляется в список ограниченных SID, как и все остальные SID маркера, кроме SID пользователя и любых SID администраторов или пользователей с правами администраторов.
• SID учетной записи, под которой вы запустили процесс, не включается в список как ограниченный. To есть процесс не сможет обращаться к объектам, доступ к которым разрешен по вашей учетной записи, но не по учетным записям любых групп, в которые вы входите. Например, у каталога вашего профиля в \Documents and Settings имеется дескриптор защиты по умолчанию, разрешающий доступ по вашей учетной записи, по учетной записи группы администраторов и по учетной записи System. Попытавшись открыть этот каталог из Notepad, запущенного так, как было показано ранее, вы не получите к нему доступа, потому что вторая, внутренняя проверка прав доступа, выполняемая с применением ограниченных SID, закончится неудачей — SID пользователя нет в списке ограниченных SID.
Маркеры, которые идентифицируют удостоверения пользователя, являются лишь частью выражения, описывающего защиту объектов. Другая его часть — информация о защите, сопоставленная с объектом и указывающая, кому и какие действия разрешено выполнять над объектом. Структура данных, хранящая эту информацию, называется дескриптором защиты (security descriptor). Дескриптор защиты включает следующие атрибуты.
• Номер версии Версия модели защиты SRM, использованной для создания дескриптора.
• Флаги Необязательные модификаторы, определяющие поведение или характеристики дескриптора. Пример — флаг SE_DACL_PROTECTED, который запрещает наследование дескриптором параметров защиты от другого объекта.
• SID владельца Идентификатор защиты владельца.
• SID группы Идентификатор защиты основной группы для данного объекта (используется только POSIX).
• Список управления избирательным доступом (discretionary access-control list, DACL) Указывает, кто может получать доступ к объекту и какие виды доступа.
• Системный список управления доступом (system access-control list, SACL) Указывает, какие операции и каких пользователей должны регистрироваться в журнале аудита безопасности.
Список управления доступом (access-control list, ACL) состоит из заголовка и может содержать элементы (access-control entries, АСЕ). Существует два типа ACL: DACL и SACL. B DACL каждый ACE содержит SID и маску доступа (а также набор флагов), причем ACE могут быть четырех типов: «доступ разрешен» (access allowed), «доступ отклонен» (access denied), «разрешенный объект» (allowed-object) и «запрещенный объект» (denied-object). Как вы, наверное, и подумали, первый тип ACE разрешает пользователю доступ к объекту, а второй — отказывает в предоставлении прав, указанных в маске доступа.
Разница между ACE типа «разрешенный объект» и «доступ разрешен», а также между ACE типа «запрещенный объект» и «доступ отклонен» заключается в том, что эти типы используются только в Active Directory. ACE этих типов имеют поле глобально уникального идентификатора (globally unique identifier, GUID), которое сообщает, что данный ACE применим только к определенным объектам или под объектам (с GUID-идентификаторами). Кроме того, необязательный GUID указывает, что тип дочернего объекта наследует ACE при его (объекта) создании в контейнере Active Directory, к которому применен АСЕ. (GUID — это гарантированно уникальный 128-битный идентификатор.)
За счет аккумуляции прав доступа, сопоставленных с индивидуальными АСЕ, формируется набор прав, предоставляемых ACL-списком. Если в дескрипторе защиты нет DACL (DACL = null), любой пользователь получает полный доступ к объекту. Если DACL пуст (т. е. в нем нет АСЕ), доступа к объекту не получает никто.
АСЕ, используемые в DACL, также имеют набор флагов, контролирующих и определяющих характеристики АСЕ, связанные с наследованием. Некоторые пространства имен объектов содержат объекты-контейнеры и объекты-листы (leaf objects). Контейнер может включать другие контейнеры и листы, которые являются его дочерними объектами. Примеры контейнеров — каталоги в пространстве имен файловой системы и разделы в пространстве имен реестра. Отдельные флаги контролируют, как ACE применяется к дочерним объектам контейнера, сопоставленного с этим АСЕ. Часть правил наследования ACE представлена в таблице 8–3 (полный список см. в Platform SDK).
SACL состоит из ACE двух типов: системного аудита (system audit ACE) и объекта системного аудита (system audit-object АСЕ). Эти ACE определяют, какие операции, выполняемые над объектами конкретными пользователями или группами, подлежат аудиту. Информация аудита хранится в системном журнале аудита. Аудиту могут подлежать как успешные, так и неудачные операции. Как и специфические для объектов ACE из DACL, ACE объектов системного аудита содержат GUID, указывающий типы объектов или под-объектов, к которым применим данный АСЕ, и необязательный GUID, контролирующий передачу ACE дочерним объектам конкретных типов. При SACL, равном null, аудит объекта не ведется. (Об аудите безопасности мы расскажем позже.) Флаги наследования, применимые к DACL АСЕ, применимы к ACE системного аудита и объектов системного аудита.
Упрощенная схема объекта «файл» и его DACL представлена на рис. 8–4.
Как показано на рис. 8–4, первый ACE позволяет USERl читать файл. Второй ACE разрешает членам группы TEAM1 читать и записывать файл. Третий ACE предоставляет доступ к файлу для выполнения всем пользователям.
ЭКСПЕРИМЕНТ: просмотр дескриптора защиты
Управляя дескрипторами защиты своих объектов, большинство подсистем исполнительной системы полагаются на функции защиты по умолчанию, предоставляемые диспетчером объектов. Эти функции сохраняют дескрипторы защиты для таких объектов, используя указатель дескриптора защиты (security descriptor pointer). Например, защитой по умолчанию пользуется диспетчер процессов, поэтому диспетчер объектов хранит дескрипторы защиты процессов и потоков в заголовках объектов «процесс» и «поток» соответственно. Указатель дескриптора защиты также применяется для хранения дескрипторов защиты событий, мьютексов и семафоров. Для просмотра дескрипторов защиты этих объектов можно использовать отладчик ядра, но сначала вы должны найти заголовок нужного объекта. Вся эта процедура поясняется ниже.
1. Запустите отладчик ядра.
2. Введите !process 0 0, чтобы увидеть адрес Winlogon. (Если в системе активно более одного сеанса Terminal Server, выполняется несколько экземпляров Winlogon.) Затем вновь введите !process, но укажите адрес одного из процессов Winlogon:
3. Введите !object и адрес, следующий за словом PROCESS в выводе предыдущей команды. Это позволит увидеть структуру данных объекта:
4. Введите dt _OBJECT_HEADER и адрес поля заголовка объекта из вывода предыдущей команды для просмотра структуры данных заголовка объекта, включая значение указателя дескриптора защиты:
5. Указатели дескрипторов защиты в заголовке объекта используют младшие три бита как флаги, поэтому следующая команда позволяет создать дамп дескриптора защиты. Вы указываете адрес, полученный из структуры заголовка объекта, но удаляете его младшие три бита:
Дескриптор защиты содержит два ACE типа «доступ разрешен», причем один из них указывает учетную запись администратора (ее можно распознать по RID, равному 500), а другой — учетную запись System (которая всегда выглядит как S-l-5-18). Без декодирования битов, установленных в масках доступа в ACE и определения того, каким типам доступа к процессам они соответствуют, очень трудно сказать, какими правами доступа к объекту «процесс» для Winlogon обладает каждая из этих учетных записей. Однако, если вы сделаете это, используя заголовочные файлы из SDK, то обнаружите, что обе учетные записи имеют полные права доступа.
Чтобы определить, какой DACL следует назначить новому объекту, система защиты использует первое применимое правило из следующего списка.
1. Если вызывающий поток явно предоставляет дескриптор защиты при создании объекта, то система защиты применяет его к объекту. Если у объекта есть имя и он находится в объекте-контейнере (например, именованное событие в каталоге \BaseNamedObjects пространства имен диспетчера объектов), система объединяет в DACL все наследуемые ACE (АСЕ, которые могут быть переданы от контейнера объекта), но только в том случае, если в дескрипторе защиты не установлен флаг SE_DACL_PROTECTED, запрещающий наследование.
2. Если вызывающий поток не предоставляет дескриптор защиты и объекту присваивается имя, система защиты ищет этот дескриптор в контейнере, в котором хранится имя нового объекта. Некоторые ACE каталога объектов могут быть помечены как наследуемые. Это означает, что они должны применяться к новым объектам, создаваемым в данном каталоге. При наличии наследуемых ACE система защиты формирует из них ACL, назначаемый новому объекту. (B АСЕ, наследуемых только объектами-контейнерами, устанавливаются отдельные флаги.)
3. Если дескриптор защиты не определен и объект не наследует какие-либо АСЕ, система защиты извлекает DACL по умолчанию из маркера доступа вызывающего потока и применяет его к новому объекту. B некоторые подсистемы Windows (например, службы, LSA и SAM-объекты) «зашиты» свои DACL, назначаемые ими объектам при создании.
4. Если дескриптор защиты не определен и нет ни наследуемых АСЕ, ни DACL по умолчанию, система создает объект без DACL, что открывает полный доступ к нему любым пользователям и группам. Это правило идентично третьему, если маркер содержит нулевой DACL по умолчанию. Правила, используемые системой при назначении SACL новому объекту,
аналогичны правилам присвоения DACL за двумя исключениями. Первое заключается в том, что наследуемые ACE системного аудита не передаются объектам с дескрипторами защиты, помеченными флагом SE_SACL_PROTEC-TED (DACL точно так же защищается флагом SE_DACL_PROTECTED). Второе исключение: если ACE системного аудита не определены и наследуемого SACL нет, то SACL вообще не присваивается объекту (в маркерах нет SACL по умолчанию).
Когда к контейнеру применяется новый дескриптор защиты, содержащий наследуемые АСЕ, система автоматически передает их в дескрипторы защиты дочерних объектов. (Заметьте, что DACL дескриптора защиты не принимает наследуемые DACL АСЕ, если установлен флаг SE_DACL_PROTECTED, а его SACL не наследует SACL АСЕ, если установлен флаг SE_SACL_PROTECTED.) B соответствии с порядком слияния наследуемых ACE с дескриптором защиты дочернего объекта любые АСЕ, явно примененные к ACL, размещаются до АСЕ, унаследованных объектом. Система использует следующие правила передачи наследуемых АСЕ.
• Если дочерний объект без DACL наследует АСЕ, он получает DACL, содержащий лишь унаследованные АСЕ.
• Если дочерний объект с пустым DACL наследует АСЕ, он также получает DACL, содержащий лишь унаследованные АСЕ.
• Только для объектов в Active Directory: если наследуемый ACE удаляется из родительского объекта, все копии этого ACE автоматически удаляются из всех дочерних объектов.
• Только для объектов в Active Directory: если из DACL дочернего объекта автоматически удалены все АСЕ, у дочернего объекта остается пустой DACL.
Как вы вскоре убедитесь, порядок ACE в ACL является важным аспектом модели защиты Windows.
ПРИМЕЧАНИЕ Как правило, наследование не поддерживается напрямую такими хранилищами объектов, как файловые системы, реестр или Active Directory. Функции Windows API, поддерживающие наследование, в том числе SetSecurityInfo и SetNamedSecurityInfo, реализуют наследование вызовом соответствующих функций из DLL поддержки наследования атрибутов защиты (\Windows\System32\Ntmarta.Dll), которым известно, как устроены эти хранилища объектов.
Для определения прав доступа к объекту используются два алгоритма:
• сравнивающий запрошенные права с максимально возможными для данного объекта и экспортируемый в пользовательский режим в виде Windows-функции GetEffectiveRightsFromAcl\
• проверяющий наличие конкретных прав доступа и активизируемый через Windows-функцию AccessCheck или AccessCheckByType. Первый алгоритм проверяет элементы DACL следующим образом.
1. B отсутствие DACL (DACL = null) объект является незащищенным, и система защиты предоставляет к нему полный доступ.
2. Если у вызывающего потока имеется привилегия на захват объекта во владение (take-ownership privilege), система защиты предоставляет владельцу право на доступ для записи (write-owner access) до анализа DACL (что такое привилегия захвата объекта во владение и право владельца на доступ для записи, мы поясним чуть позже).
3. Если вызывающий поток является владельцем объекта, ему предоставляются права управления чтением (read-control access) и доступа к DACL для записи (write-DACL access).
4. Из маски предоставленных прав доступа удаляется маска доступа каждого ACE типа «доступ отклонен», SID которого совпадает с SID маркера доступа вызывающего потока.
5. K маске предоставленных прав доступа добавляется маска доступа каждого ACE типа «доступ разрешен», SID которого совпадает с SID маркера доступа вызывающего потока (исключение составляют права доступа, в предоставлении которых уже отказано).
После анализа всех элементов DACL рассчитанная маска предоставленных прав доступа возвращается вызывающему потоку как максимальные права доступа. Эта маска отражает полный набор типов доступа, которые этот поток сможет успешно запрашивать при открытии данного объекта.
Все сказанное применимо лишь к той разновидности алгоритма, которая работает в режиме ядра. Его Windows-версия, реализованная функцией GetEffectiveRigbtsFromAcl, отличается отсутствием шага 2, а также тем, что вместо маркера доступа она рассматривает SID единственного пользователя или группы.
Второй алгоритм проверяет, можно ли удовлетворить конкретный запрос на доступ, исходя из маркера доступа вызывающего потока. У каждой Windows-функции открытия защищенных объектов есть параметр, указывающий желательную маску доступа — последний элемент выражения, описывающего защиту объектов. Чтобы определить, имеет ли вызывающий поток право на доступ к защищенному объекту, выполняются следующие операции.
1. B отсутствие DACL (DACL = null) объект является незащищенным, и система защиты предоставляет к нему запрошенный тип доступа.
2. Если у вызывающего потока имеется привилегия на захват объекта во владение, система защиты предоставляет владельцу право на доступ для записи, а затем анализирует DACL. Однако, если такой поток запросил только доступ владельца для записи, система защиты предоставляет этот тип доступа и не просматривает DACL.
3. Если вызывающий поток является владельцем объекта, ему предоставляются права управления чтением и доступа к DACL для записи. Если вызывающий поток запросил только эти права, система защиты предоставляет их без просмотра DACL.
4. Просматриваются все ACE в DACL — от первого к последнему. Обработка ACE выполняется при одном из следующих условий:
a. SID в ACE типа «доступ отклонен» совпадает с незаблокированным SID (SID могут быть незаблокированными и заблокированными) или SID с атрибутом проверки только на запрет в маркере доступа вызывающего потока;
b. SID в ACE типа «доступ разрешен» совпадает с незаблокированным SID в маркере доступа вызывающего потока, и этот SID не имеет атрибута проверки только на запрет;
c. Идет уже второй проход поиска в дескрипторе ограниченных SID, и SID в ACE совпадает с ограниченным SID в маркере доступа вызывающего потока.
5. B случае ACE типа «доступ разрешен» предоставляются запрошенные права из маски доступа АСЕ; проверка считается успешной, если предоставляются все запрошенные права. Доступ к объекту не предоставляется в случае ACE типа «доступ отклонен» и отказа в предоставлении какого-либо из запрошенных прав.
6. Если достигнут конец DACL и некоторые из запрошенных прав доступа еще не предоставлены, доступ к объекту запрещается.
7. Если все права доступа предоставлены, но в маркере доступа вызывающего потока имеется хотя бы один ограниченный SID, то система повторно сканирует DACL в поисках АСЕ, маски доступа которых соответствуют набору запрошенных прав доступа. При этом также идет поиск АСЕ, SID которых совпадает с любым из ограниченных SID вызывающего потока. Поток получает доступ к объекту, если запрошенные права доступа предоставлялись после каждого прохода по DACL.
Поведение обоих алгоритмов проверки прав доступа зависит от относительного расположения разрешающих и запрещающих АСЕ. Возьмем для примера объект с двумя АСЕ, первый из которых указывает, что определенному пользователю разрешен полный доступ к объекту, а второй отказывает в доступе. Если разрешающий ACE предшествует запрещающему, пользователь получит полный доступ к объекту. При другом порядке этих ACE пользователь вообще не получит доступа к объекту.
Более старые Windows-функции вроде AddAccessAllowedAce добавляли ACE в конец DACL, что нежелательно. Таким образом, до появления Windows 2000 большинство Windows-приложений были вынуждены создавать DACL вручную, помещая запрещающие ACE в начало списка. Несколько функций Windows, например SetSecurityInfo и SetNamedSecurityInfo, используют предпочтительный порядок АСЕ: запрещающие ACE предшествуют разрешающим. Заметьте, что эти функции вызываются при редактировании, например, прав доступа к NTFS-файлам и разделам реестра. SetSecurityInfo и SetNamedSecurityInfo также применяют правила наследования ACE к дескриптору защиты, для операций над которым они вызываются.
Ha рис. 8–5 показан пример проверки прав доступа, демонстрирующий, насколько важен порядок АСЕ. B этом примере пользователю отказано в доступе к файлу, хотя ACE в DACL объекта предоставляет такое право (в силу принадлежности пользователя к группе Writers). Это вызвано тем, что запрещающий ACE предшествует разрешающему.
Маркер доступа
Пользователь: DaveC
Как уже говорилось, обработка DACL системой защиты при каждом использовании описателя процессом была бы неэффективной, поэтому SRM проверяет права доступа только при открытии описателя, а не при каждом его использовании. Так что, если процесс один раз успешно открыл описатель, система защиты не может аннулировать предоставленные при этом права доступа — даже когда DACL объекта изменяется. Учтите и вот еще что: поскольку код режима ядра обращается к объектам по указателям, а не по описателям, при использовании объектов операционной системой права доступа не проверяются. Иначе говоря, исполнительная система полностью доверяет себе в смысле защиты.
Тот факт, что владелец объекта всегда получает право на запись DACL при доступе к объекту, означает, что пользователям нельзя запретить доступ к принадлежащим им объектам. Если в силу каких-то причин DACL объекта пуст (доступ запрещен), владелец все равно может открыть объект с правом записи DACL и применить новый DACL, определяющий нужные права доступа.
Модифицируя с помощью GUI-средств параметры защиты объектов «файл», «реестр», Active Directory или других защищаемых объектов, имейте в виду, что основное диалоговое окно безопасности создает потенциально неверное представление о защите, применяемой для объекта. B верхней части этого окна в алфавитном порядке показываются группы и пользователи, чьи ACE имеются в ACL данного объекта. Если вы выдадите Full Control группе Administrators и запретите его группе Everyone, то, судя по алфавитному списку, можете подумать, будто ACE типа «доступ разрешен» для группы Administrators предшествует ACE типа «доступ отклонен» для группы Everyone. Однако, как мы уже говорили, средства редактирования, применяя ACL к объекту, помещают запрещающие ACE перед разрешающими.
Ha вкладке Permissions (Разрешения) диалогового окна Advanced Security Settings (Дополнительные параметры безопасности) показывается порядок ACE в DACL. Однако даже это диалоговое окно может ввести в заблуждение, так как в сложном DACL за запрещающими ACE для различных видов доступа могут быть расположены разрешающие ACE для других типов доступа.
Единственный способ точно узнать, какие виды доступа к объекту будут разрешены конкретному пользователю или группе (помимо метода проб и ошибок), — открыть вкладку Effective Permissions. Введите здесь имя пользователя или группы, и диалоговое окно покажет, какие разрешения на доступ к объекту будут действовать на самом деле.
Auth2 API, впервые введенный в Windows XP, реализует ту же модель защиты, что и Security Reference Monitor (монитор состояния защиты), но исключительно для пользовательского режима; все функции AuthZ API находятся в библиотеке \Windows\System32\Authz.Dll. Это позволяет приложениям, нуждающимся в защите своих закрытых объектов (вроде таблиц базы данных), задействовать Windows-модель защиты без издержек, связанных с переходами из пользовательского режима в режим ядра, которые были бы неизбежны при использовании Security Reference Monitor.
AuthZ API оперирует стандартными структурами дескриптора защиты, SID и привилегиями. Вместо применения маркеров для представления клиентов, AuthZ использует AUTHZ_CLIENT_CONTEXT. AuthZ включает эквиваленты всех функций проверки прав доступа и защиты Windows; например AutbzAccessCbeck — это AuthZ-версия Windows-функции AccessCbeck, которая вызывает функцию SeAccessCbeck, принадлежащую Security Reference Monitor.
Еще одно преимущество AuthZ заключается в том, что приложения могут указывать AuthZ кэшировать результаты проверок прав доступа для ускорения последующих проверок, где используются те же контекст клиента и дескриптор защиты.
AuthZ полностью документирован в Platform SDK.
Многие операции, выполняемые процессами, нельзя авторизовать через подсистему защиты доступа к объектам, так как при этом не происходит взаимодействия с конкретным объектом. Например, возможность обходить проверки прав доступа при открытии файлов для резервного копирования является атрибутом учетной записи, а не конкретного объекта. Windows использует как привилегии, так и права учетных записей, чтобы системный администратор мог управлять тем, каким учетным записям разрешено выполнять операции, затрагивающие безопасность.
Привилегия (privilege) — это право (right) учетной записи на выполнение определенной операции, затрагивающей безопасность, например на выключение компьютера или изменение системного времени. Право учетной записи разрешает или запрещает конкретный тип входа в систему, скажем, локальный или интерактивный.
Системный администратор назначает привилегии группам и учетным записям с помощью таких инструментов, как ММС-оснастка Active Directory Users and Groups (Active Directory — пользователи и группы) или редактора локальной политики безопасности (Local Security Policy Editor)*. Запустить этот редактор можно из папки Administrative Tools (Администрирование). Ha рис. 8–6 показана конфигурация User Rights Assignment (Назначение прав пользователя) редактора локальной политики безопасности, при которой в правой части окна выводится полный список привилегий и прав (учетных записей), доступных в Windows Server 2003. Заметьте, что этот редактор не различает привилегии и права учетных записей. Ho вы можете сделать это сами, поскольку любое право, в названии которого встречается слово «logon» («вход»), на самом деле является привилегией.
* B русской версии Windows XP окно этого редактора называется «Локальные параметры безопасности». — Прим. перев.
Права учетной записи не вводятся в действие монитором состояния защиты (Security Reference Monitor, SRM) и не хранятся в маркерах. За вход отвечает функция LsaLogonUser. B частности, WinLogon вызывает API-функцию LogonUser, когда пользователь интерактивно входит в систему, aLogonUser обращается KLsaLogonUser. Эта функция принимает параметр, указывающий тип выполняемого входа, который может быть интерактивным, сетевым, пакетным, сервисным, через службу терминала или для разблокировки (unlock).
B ответ на запросы входа служба локальной безопасности (Local Security Authority, LSA) извлекает назначенные пользователю права учетной записи из своей базы данных; эта операция выполняется при попытке пользователя войти в систему LSA сверяет тип входа с правами учетной записи и по результатам этой проверки отклоняет попытку входа, если у учетной записи нет права, разрешающего данный тип входа, или, напротив, есть право, которое запрещает данный тип входа. Права пользователей, определенные в Windows, перечислены в таблице 8–4.
Windows-приложения могут добавлять или удалять права из учетной записи пользователя через функции LsaAddAccountRights и LsaRemoveAccount-Rigbts соответственно, а также определять, какие права назначены учетной записи, вызывая функцию LsaEnumerateAccountRigbts.
Число привилегий, определяемых в операционной системе, со временем выросло. B отличие от прав пользователей, которые вводятся в действие в одном месте службой LSA, разные привилегии определяются разными компонентами и ими же применяются. Скажем, привилегия отладки, позволяющая процессу обходить проверки прав доступа при открытии описателя другого процесса через API-функцию OpenProcess, проверяется диспетчером процессов. Полный список привилегий приведен в таблице 8–5.
Компонент, которому нужно проверить маркер на наличие некоей привилегии, обращается к API-функции PrivilegeCheck или LsaEnumerateAccountRights, если он выполняется в пользовательском режиме, либо к SeSingle-PrivilegeCbeck или SePrivilegeCbeck, если он работает в режиме ядра. API-функции, работающие с привилегиями, ничего не знают о правах учетных записей, но API-функциям, оперирующим с правами, привилегии известны.
B отличие от прав учетной записи привилегии можно включать и отключать. Чтобы проверка привилегии прошла успешно, эта привилегия должна находиться в указанном маркере и должна быть включена. Смысл такой схемы в том, что привилегии должны включаться только при реальном их использовании, и в том, чтобы процесс не мог случайно выполнить привилегированную операцию.
ЭКСПЕРИМЕНТ: наблюдение за включением привилегии
Следующая процедура позволит увидеть, как апплет Date and Time (Дата и время) из Control Panel включает привилегию SeSystemTime-Privilege, исходя из того, что его интерфейс будет использован для изменения даты или времени на компьютере.
1. Войдите в систему под учетной записью, имеющей право «Change the system time» (Изменение системного времени); такая учетная запись обычно входит в группу администраторов или пользователей с правами администраторов.
2. Запустите Process Explorer и выберите для частоты обновления значение Paused.
3. Откройте вкладку Security в окне свойств какого-либо процесса, например Explorer. Вы должны увидеть, что привилегия SeChange-SystemTimePrivilege отключена.
4. Запустите апплет Date and Time из Control Panel и обновите окно Process Explorer. B списке появится новый процесс Rundll, выделенный зеленым цветом.
5. Откройте окно свойств для процесса Rundll (дважды щелкнув имя этого процесса) и убедитесь, что командная строка содержит текст «Timedate.Cpl». Наличие этого аргумента сообщает Rundll (хост-процессу Control Panel DLL) загрузить DLL, реализующую UI, который позволяет изменять дату и время.
6. Перейдите на вкладку Security в окне свойств процесса Rundll и вы увидите, что привилегия SeSystemTimePrivilege включена.
ЭКСПЕРИМЕНТ: привилегия Bypass Traverse Checking
Если вы являетесь системным администратором, то должны знать о привилегии Bypass Traverse Checking (Обход перекрестной проверки)* (ее внутреннее название — SeNotifyPrivilege) и о том, какие последствия влечет за собой ее включение. Этот эксперимент демонстрирует, что непонимание ее поведения может привести к серьезному нарушению безопасности.
1. Создайте папку, а в ней — новый текстовый файл с каким-нибудь текстом.
2. Перейдите в Explorer к новому файлу и откройте вкладку Security (Безопасность) в его окне свойств. Щелкните кнопку Advanced (Дополнительно) и сбросьте флажок, управляющий наследованием. Выберите Сору (Копировать), когда появится запрос с предложением удалить или скопировать унаследованные разрешения.
3. Далее сделайте так, чтобы по вашей учетной записи нельзя было получить доступ к этой новой папке. Для этого выберите свою учетную запись и в списке разрешений выберите все флажки типа Deny (отклонить или запретить).
4. Запустите Notepad и попробуйте через его UI перейти в новую папку. Вы не сможете этого сделать.
5. B поле File Name (Имя файла) диалогового окна Open (Открыть) введите полный путь к новому файлу. Файл должен открыться. Если в вашей учетной записи нет привилегии Bypass Traverse Checking, NTFS будет проверять права доступа к каждому каталогу в пути к файлу, когда вы попытаетесь открыть этот файл. И только в таком случае вам будет отказано в доступе к данному файлу.
* Так эта привилегия называется в русской версии Windows XP, но на самом деле никакой перекрестной проверки нет — проверяются промежуточные каталоги в пути к файлу. Поэтому такую привилегию следовало бы назвать «Обход промежуточных проверок». — Прим. перев.
Несколько привилегий дают настолько широкие права, что пользователя, которому они назначаются, называют «суперпользователем» — он получает полный контроль над компьютером. Эти привилегии позволяют получать неавторизованный доступ к закрытым ресурсам и выполнять любые операции. Ho мы уделим основное внимание применению привилегии на запуск кода, который выдает привилегии, изначально не назначавшиеся пользователю, и при этом не будем забывать, что это может быть использовано для выполнения любой операции на локальном компьютере. B этом разделе перечисляются такие привилегии и рассматриваются способы их применения. Прочие привилегии вроде Lock Pages In Physical Memory (Закрепление страниц в памяти) можно использовать для атак типа «отказ в обслуживании», но мы не станем их обсуждать.
• Debug programs (Отладка программ) Пользователь с этой привилегией может открыть любой процесс в системе независимо от его дескриптора защиты. Например, располагая такой привилегией, можно запустить свою программу, которая открывает процесс LSASS, копирует в ее адресное пространство исполняемый код, а затем внедряет поток с помощью API-функции CreateRemoteThread для выполнения внедренного кода в более привилегированном контексте защиты. Этот код мог бы выдавать пользователю дополнительные привилегии и расширять его членство в группах.
• Take ownership (Смена владельца)* Эта привилегия позволяет ее обладателю сменить владельца любого защищаемого объекта, просто вписав свой SID в поле владельца в дескрипторе защиты объекта. Вспомните, что владелец всегда получает разрешение на чтение и модификацию DACL дескриптора защиты, поэтому процесс с такой привилегией мог бы изменить DACL, чтобы разрешить себе полный доступ к объекту, а затем закрыть объект и вновь открыть его с правами полного доступа. Это позволило бы увидеть любые конфиденциальные данные и даже подменить системные файлы, выполняемые при обычных системных операциях, например LSASS, своими программами, которые расширяют привилегии некоего пользователя.
• Restore files and directories (Восстановление файлов и каталогов)
Пользователь с такой привилегией может заменить любой файл в системе на свой — так же, как было описано в предыдущем абзаце.
• Load and unload device drivers (Загрузка и выгрузка драйверов устройств) Злоумышленник мог бы воспользоваться этой привилегией для загрузки драйвера устройства в систему. Такие драйверы считаются доверяемыми частями операционной системы, которые выполняются под системной учетной записью, поэтому драйвер мог бы запускать привилегированные программы, назначающие пользователю-злоумышленнику другие права.
• B русской версии Windows XP эта привилегия называется «Овладение файлами или иными объектами». — Прим. перев.
• Create a token object (Создание маркерного объекта) Эта привилегия позволяет создавать объекты «маркеры», представляющие произвольные учетные записи с членством в любых группах и любыми разрешениями.
• Act as part of operating system (Работа в режиме операционной системы) Эта привилегия проверяется функцией LsaRegisterLogonProcess, вызываемой процессом для установления доверяемого соединения с LSASS. Злоумышленник с такой привилегией может установить доверяемое соединение с LSASS, а затем вызвать LsaLogonUser — функцию, используемую для создания новых сеансов входа. LsaLogonUser требует указания действительных имени и пароля пользователя и принимает необязательный список SID, добавляемый к начальному маркеру, который создается для нового сеанса входа. B итоге можно было бы использовать свои имя и пароль для создания нового сеанса входа, в маркер которого включены SID более привилегированных групп или пользователей. Заметьте, что расширенные привилегии не распространяются за границы локальной системы в сети, потому что любое взаимодействие с другим компьютером требует аутентификации контроллером домена и применения доменных паролей. A доменные пароли не хранятся на компьютерах (даже в зашифрованном виде) и поэтому недоступны злонамеренному коду.
События аудита может генерировать диспетчер объектов в результате проверки прав доступа. Их могут генерировать и непосредственно Windows-функции, доступные пользовательским приложениям. Это же право, разумеется, есть и у кода режима ядра. C аудитом связаны две привилегии: SeSecu-rityPrivilege и SeAuditPrivilege. Для управления журналом событий безопасности, а также для просмотра и изменения SACL объектов процесс должен обладать привилегией SeSecurityPrivilege. Однако процесс, вызывающий системные сервисы аудита, должен обладать привилегией SeAuditPrivilege, чтобы успешно сгенерировать запись аудита в этом журнале.
Решения об аудите конкретного типа событий безопасности принимаются в соответствии с политикой аудита локальной системы. Политика аудита, также называемая локальной политикой безопасности (local security policy), является частью политики безопасности, поддерживаемой LSASS в локальной системе, и настраивается с помощью редактора локальной политики безопасности (рис. 8–7).
При инициализации системы и изменении политики LSASS посылает SRM сообщения, информирующие его о текущей политике аудита. LSASS отвечает за прием записей аудита, генерируемых на основе событий аудита от SRM, их редактирование и передачу Event Logger (регистратору событий). Эти записи посылает именно LSASS (а не SRM), так как он добавляет в них сопутствующие подробности, например информацию, нужную для более полной идентификации процесса, по отношению к которому проводится аудит.
Рис. 8–7. Конфигурация Audit Policy редактора локальной политики безопасности
SRM посылает записи аудита LSASS через свое LPC-соединение. После этого Event Logger заносит записи в журнал безопасности. B дополнение к записям аудита, передаваемым SRM, LSASS и SAM тоже генерируют записи аудита, которые LSASS пересылает непосредственно Event Logger; кроме того, AuthZ API позволяет приложениям генерировать записи аудита, определенные этими приложениями. Вся эта схема представлена на рис. 8–8.
Записи аудита, подлежащие пересылке LSA, помещаются в очередь по мере получения — они не передаются пакетами. Пересылка этих записей осуществляется одним из двух способов. Если запись аудита невелика (меньше максимального размера LPC-сообщения), она посылается как LPC-cooбщение. Записи аудита копируются из адресного пространства SRM в адресное пространство процесса Lsass. Если запись аудита велика, SRM делает ее доступной Lsass через разделяемую память и передает Lsass указатель на нее, используя для этого LPC-сообщение.
Рис. 8–9 обобщает изложенные в этой главе концепции, иллюстрируя базовые структуры защиты процессов и потоков. Обратите внимание на то, что у объектов «процесс» и «поток» имеются ACL, равно как и у самих объектов «маркер доступа». Кроме того, на этой иллюстрации показано, что у потоков 2 и 3 есть маркер олицетворения, тогда как поток 1 по умолчанию использует маркер доступа своего процесса.
При интерактивном входе в систему (в отличие от входа через сеть) происходит взаимодействие с процессами Winlogon, Lsass, одним или несколькими пакетами аутентификации, а также SAM или Active Directory. Пакеты аутентификации (authentication packages) — это DLL-модули, выполняющие проверки, связанные с аутентификацией. Пакетом аутентификации Windows для интерактивного входа в домен является Kerberos, a MSV1_0 — аналогичным пакетом для интерактивного входа на локальные компьютеры, доменного входа в доверяемые домены под управлением версий Windows, предшествовавших Windows 2000, а также для входа в отсутствие контроллера домена.
Winlogon — доверяемый процесс, отвечающий за управление взаимодействием с пользователем в связи с защитой. Он координирует вход, запускает первый процесс при входе в систему данного пользователя, обрабатывает выход из системы и управляет множеством других операций, имеющих отношение к защите, — вводом паролей при регистрации, сменой паролей, блокированием и разблокированием рабочих станций и т. д. Процесс Winlogon должен обеспечить невидимость операций, связанных с защитой, другим активным процессам. Так, Winlogon гарантирует, что в ходе этих операций недоверяемый процесс не сможет перехватить управление рабочим столом и таким образом получить доступ к паролю.
Winlogon получает имя и пароль пользователя через Graphical Identification and Authentication (GINA) DLL. Стандартная GINA — \Windows\System32\ Msgina.dll. Msgina выводит диалоговое окно для входа в систему. Позволяя заменять Msgina другими GINA-библиотеками, Windows дает возможность менять механизмы идентификации пользователей. Например, сторонний разработчик может создать GINA для поддержки устройства распознавания отпечатков пальцев и для выборки паролей пользователей из зашифрованной базы данных.
Winlogon — единственный процесс, который перехватывает запросы на регистрацию с клавиатуры. Получив имя и пароль пользователя от GINA, Winlogon вызывает LSASS для аутентификации этого пользователя. Если аутентификация прошла успешно, процесс Winlogon активизирует оболочку. Схема взаимодействия между компонентами, участвующими в процессе регистрации, показана на рис. 8-10.
Winlogon не только поддерживает альтернативные GINA, но и может загружать дополнительные DLL провайдеров доступа к сетям, необходимые для вторичной аутентификации. Это позволяет сразу нескольким сетевым провайдерам получать идентификационные и регистрационные данные в процессе обычного входа пользователя в систему. Входя в систему под управлением Windows, пользователь может одновременно аутентифицироваться и на UNIX-сервере. После этого он получит доступ к ресурсам UNIX-сервера с компьютера под управлением Windows без дополнительной аутентификации. Эта функциональность является одной из форм унифицированной регистрации (single sign-on).
При инициализации системы, когда ни одно пользовательское приложение еще не активно, Winlogon выполняет ряд операций, обеспечивающих ему контроль над рабочей станцией с момента готовности системы к взаимодействию с пользователем.
1. Создает и открывает интерактивный объект WindowStation (например, \Windows\WindowStations\WinStaO в пространстве имен диспетчера объектов), представляющий клавиатуру, мышь и монитор. Далее создает дескриптор защиты станции с одним АСЕ, содержащим только системный SID. Этот уникальный дескриптор безопасности гарантирует, что другой процесс получит доступ к рабочей станции, только если Winlogon явно разрешит это.
2. Создает и открывает два объекта «рабочий стол»: для приложений (\Win-dows\WinStaO\Default, также известный как интерактивный рабочий стол) и Winlogon (\Windows\WinStaO\Winlogon, также известный как защищенный рабочий стол). Защита объекта «рабочий стол» Winlogon организуется так, чтобы к нему мог обращаться только Winlogon. Другой объект «рабочий стол» доступен как Winlogon, так и пользователям. Следовательно, пока активен объект «рабочий стол» Winlogon, никакой другой процесс не получает доступа к коду и данным, сопоставленным с этим рабочим столом. Эта функциональность используется Windows для защиты операций, требующих передачи паролей, а также для блокировки и разблокировки рабочего стола.
3. До входа какого-либо пользователя в систему видимым рабочим столом является объект «рабочий стол» Winlogon. После входа нажатие клавиш Ctrl+Alt+Del вызывает переключение объектов «рабочий стол» — с Default на Winlogon. (Это объясняет, почему после нажатия Ctrl+Alt+Del с рабочего стола исчезают все окна и почему они возвращаются, как только закрывается диалоговое окно Windows Security.) Таким образом, SAS всегда активизирует защищенный рабочий стол, контролируемый Winlogon.
4. Устанавливает LPC-соединение с LSASS через LsaAutbenticationPort (вызовом LsaRegisterLogonProcess). Это соединение понадобится для обмена информацией при входе и выходе пользователя из системы и при операциях с паролем.
Далее Winlogon настраивает оконную среду.
5. Инициализирует и регистрирует структуру данных оконного класса, которая сопоставляет процедуру Winlogon с создаваемым ею окном.
6. Регистрирует SAS, сопоставляя ее с только что созданным окном. Это гарантирует, что ввод пользователем SAS будет вызывать именно оконную процедуру Winlogon и что программы типа троянских коней не смогут перехватывать управление при вводе SAS.
7. Регистрирует окно, чтобы при выходе пользователя вызывалась процедура, сопоставленная с этим окном. Подсистема Windows проверяет, что запросивший уведомление процесс является именно Winlogon.
SAS безопасна потому, что никакое приложение не может перехватить комбинацию клавиш Ctrl+Alt+Del или воспрепятствовать его получение Winlogon. Winlogon использует документированную API-функцию RegisterHotKey для резервирования комбинации клавиш Ctrl+Alt+Del, поэтому подсистема ввода Windows, обнаружив эту комбинацию, посылает специальное сообщение окну, создаваемому Winlogon для приема таких уведомлений. Любая зарезервированная комбинация клавиш посылается только тому процессу, который зарезервировал ее, и лишь поток, зарезервировавший данную комбинацию клавиш, может отменить ее регистрацию (через API-функцию UnregisterHotKey), так что троянская программа не в состоянии забрать на себя SAS.
Windows-функция SetWindowsHook позволяет приложению установить процедуру-ловушку, вызываемую при каждом нажатии клавиш еще до обработки какой-либо комбинации, и модифицировать эти клавиши. Однако в коде обработки комбинаций клавиш содержится специальный блок case для Ctrl+Alt+Del, который отключает ловушки, исключая возможность перехвата этой последовательности. Кроме того, если интерактивный рабочий стол блокирован, обрабатываются только комбинации клавиш, принадлежащие Winlogon.
Как только при инициализации системы создается рабочий стол Winlogon, он становится активным рабочим столом. Причем активный рабочий стол Winlogon всегда заблокирован. Winlogon разблокирует свой рабочий стол лишь для переключения на рабочий стол приложений или экранной заставки. (Блокировать или разблокировать рабочий стол может только процесс Winlogon.)
Регистрация начинается, когда пользователь нажимает комбинацию клавиш SAS (по умолчанию — Ctrl+Alt+Del). После этого Winlogon вызывает GINA, чтобы получить имя и пароль пользователя. Winlogon также создает уникальный локальный SID для этого пользователя и назначает его данному экземпляру объекта «рабочий стол» (который представляет клавиатуру, экран и мышь). Winlogon передает этот SID в LSASS при вызове LsaLogonUser. Если вход пользователя прошел успешно, этот SID будет включен в маркер процесса входа (logon process token) — такой шаг предпринимается для защиты доступа к объекту «рабочий стол». Например, второй вход по той же учетной записи, но в другой системе, не предоставит доступа для записи к объекту «рабочий стол» первого компьютера, так как в его маркере не будет SID, полученного при втором входе.
После ввода имени и пароля пользователя Winlogon получает описатель пакета аутентификации вызовом Lsass-функции LsaLookupAuthenticationPackage. Эти пакеты перечисляются в разделе реестра HKLM\SYSTEM\CurrentControlSet\Control\Lsa. Winlogon передает пакету данные входа через LsaLogonUser. После того как пакет аутентифицирует пользователя, Winlogon продолжает процесс входа этого пользователя. Если ни один из пакетов не сообщает об успешной аутентификации, процесс входа прекращается.
Windows использует два стандартных пакета аутентификации при интерактивном входе: Kerberos и MSV1_0. Пакет аутентификации по умолчанию в автономной системе Windows — MSVlO (\Windows\System32\Msvl_0.dll); он реализует протокол LAN Manager 2. LSASS также использует MSVlO на компьютерах, входящих в домен, чтобы аутентифицировать домены и компьютеры под управлением версий Windows до Windows 2000, не способные найти контроллер домена для аутентификации. (Отключенные от сети портативные компьютеры относятся к той же категории.) Пакет аутентификации Kerberos (\Windows\System32\Kerberos.dll) используется на компьютерах, входящих в домены Windows. Этот пакет во взаимодействии со службами Kerberos, выполняемыми на контроллере домена, поддерживает протокол Kerberos версии 5 (ревизии 6). Данный протокол определен в RFC 1510. (Подробнее о стандарте Kerberos см. на сайте Internet Engineering Task Force по ссылке www.ietf.org.)
Пакет аутентификации MSVlO принимает имя пользователя и хэшированную версию пароля и посылает локальному SAM запрос на получение информации из учетной записи, включая пароль, группы, в которые входит пользователь, и список ограничений по данной учетной записи. Сначала MSVlO проверяет ограничения, например разрешенное время или типы доступа. Если ограничения из базы данных SAM запрещают регистрацию пользователя в это время суток, MSVlO возвращает LSA статус отказа.
Далее MSVlO сравнивает хэшированный пароль и имя пользователя с теми, которые хранятся в SAM. B случае кэшированного доменного входа MSVlO обращается к кэшированной информации через функции LSASS, отвечающие за сохранение и получение «секретов» из базы данных LSA (куст реестра SECURITY) Если эти данные совпадают, MSVlO генерирует LUID сеанса входа и создает собственно сеанс входа вызовом LSASS. При этом MSVlO сопоставляет данный уникальный идентификатор с сеансом и передает данные, необходимые для того, чтобы в конечном счете создать маркер доступа для пользователя. (Вспомните, что маркер доступа включает SID пользователя, SID групп и назначенные привилегии.)
ПРИМЕЧАНИЕ MSV1_0 не кэширует весь хэш пароля пользователя в реестре, так как это позволило бы любому лицу, имеющему физический доступ к системе, легко скомпрометировать доменную учетную запись пользователя и получить доступ к зашифрованным файлам и к сетевым ресурсам, к которым данный пользователь имеет право обращаться. Поэтому MSV1_0 кэширует лишь половину хэша. Этой половины достаточно для проверки правильности пароля пользователя, но недостаточно для получения доступа к ключам EFS и для аутентификации в домене вместо этого пользователя, так как эти операции требуют полного хэша.
Если MSV1_0 нужно аутентифицировать пользователя с удаленной системы, например при его регистрации в доверяемом домене под управлением версий Windows до Windows 2000, то MSV1_0 взаимодействует с экземпляром Netlogon в удаленной системе через службу Netlogon (сетевого входа в систему). Netlogon в удаленной системе взаимодействует с пакетом аутентификации MSV1_0 этой системы, передавая результаты аутентификации системе, в которой выполняется вход.
Базовая последовательность действий при аутентификации Kerberos в основном та же, что и в случае MSV1_0. Однако в большинстве случаев доменный вход проходит на рабочих станциях или серверах, включенных в домен (а не на контроллере домена), поэтому пакет в процессе аутентификации должен взаимодействовать с ними через сеть. Взаимодействие этого пакета со службой Kerberos на контроллере домена осуществляется через TCP/IP-порт Kerberos (88). Служба Kerberos KeyDistribution Center (\Windows\ System32\Kdcsvc.dll), реализующая протокол аутентификации Kerberos, выполняется в процессе Lsass на контроллерах домена.
После проверки хэшированной информации об имени и пароле пользователя с помощью объектов учетных записей пользователей (user account objects) Active Directory (через сервер Active Directory, \Windows\System32\ Ntdsa.dll) Kdcsvc возвращает доменные удостоверения LSASS, который при успешном входе передает через сеть результат аутентификации и удостоверения пользователя той системе, где выполняется вход.
ПРИМЕЧАНИЕ Приведенное здесь описание аутентификации пакетом Kerberos сильно упрощено, и тем не менее оно иллюстрирует роль различных компонентов в этом процессе. Хотя протокол аутентификации Kerberos играет ключевую роль в обеспечении распределенной защиты доменов в Windows, его детальное рассмотрение выходит за рамки нашей книги.
Как только учетные данные аутентифицированы, LSASS ищет в базе данных локальной политики разрешенный пользователю тип доступа — интерактивный, сетевой, пакетный или сервисный. Если тип запрошенного входа в систему не соответствует разрешенному, вход прекращается. LSASS удаляет только что созданный сеанс входа, освобождая его структуры данных, и сообщает Winlogon о неудаче. Winlogon в свою очередь сообщает об этом пользователю. Если же запрошенный тип входа в систему разрешается, LSASS добавляет любые дополнительные идентификаторы защиты (например, Everyone, Interactive и т. п.). Затем он проверяет в своей базе данных привилегии, назначенные всем идентификаторам данного пользователя, и включает эти привилегии в маркер доступа пользователя.
Собрав всю необходимую информацию, LSASS вызывает исполнительную систему для создания маркера доступа. Исполнительная система создает основной маркер доступа для интерактивного или сервисного сеанса и маркер олицетворения для сетевого сеанса. После успешного создания маркера доступа LSASS дублирует его, создавая описатель, который может быть передан Winlogon, а свой описатель закрывает. Если нужно, проводится аудит операции входа. Ha этом этапе LSASS сообщает Winlogon об успешном входе и возвращает описатель маркера доступа, LUID сеанса входа и информацию из профиля, полученную от пакета аутентификации (если она есть).
ЭКСПЕРИМЕНТ: перечисление активных сеансов входа
Пока существует хотя бы один маркер с данным LUID сеанса входа, Windows считает этот сеанс активным. C помощью утилиты Logon-Sessions (wwwsysintemals.com), которая использует функцию LsaEnu-merateLogonSessions (документированную в Platform SDK), можно перечислить активные сеансы входа:
B информацию, сообщаемую по каждому сеансу, включаются SID и имя пользователя, сопоставленные с данным сеансом, а также пакет аутентификации и время входа. Заметьте, что пакет аутентификации Negotiate, отмеченный в сеансе входа 2, выполняет аутентификацию через Kerberos или NTLM в зависимости от того, какой из них больше подходит для данного запроса на аутентификацию.
LUID для сеанса показывается в строке «Logon Session» блока информации по каждому сеансу, и с помощью утилиты Handle (также доступной с wwwsysinternals.com) можно найти маркеры, представляющие конкретный сеанс входа. Например, чтобы найти маркеры для сеанса входа 8 в предыдущем примере вывода, вы могли бы ввести такую команду:
C: \›handle — a 79da73 43c: Token MARKLAP\Administrator:79da73
Далее Winlogon просматривает параметр реестра HKLM\SOFTWARE\Microsoft\Windows NT\Current Version\Winlogon\Userinit и создает процесс для запуска программ, указанных в строковом значении этого параметра (там могут присутствовать имена нескольких ЕХЕ-файлов, разделенные запятыми). Значение этого параметра по умолчанию приводит к запуску Useri-
nit.exe, который загружает профиль пользователя, а затем создает процесс для запуска программ, перечисленных в HKCU\SOFTWARE\Microsoft\Windows NT\Current Version\Winlogon\Shell, если такой параметр есть. Если же этого параметра нет, Userinit.exe обращается к параметру HKLM\SOFTWARE\ Microsoft\Windows NT\Current Version\Winlogon\Shell, который по умолчанию задает Explorer.exe. После этого Userinit завершается — вот почему Process Explorer показывает Explorer.exe как процесс, не имеющий предка. Подробнее о том, что происходит в процессе входа, см. в главе 5.
Злонамеренный код вроде вирусов и червей создает все больше проблем. B Windows XP введен механизм Software Restriction Policies (Политики ограниченного использования программ), который позволяет администраторам контролировать образы и сценарии, выполняемые в их системах. Узел Software Restriction Policies в редакторе локальной политики безопасности (рис. 8-11) служит интерфейсом управления для политик выполнения кода на компьютере, хотя возможны и политики, индивидуальные для пользователей; в последнем случае применяются доменные политики групп.
Узел Software Restriction Policies (Политики ограниченного использования программ) содержит несколько глобальных параметров.
• Параметр Enforcement (Принудительный) определяет, как применяются политики ограничения — к библиотекам вроде DLL, только к пользователям или к пользователям и администраторам.
• Параметр Designated File Types (Назначенные типы файлов) регистрирует расширения файлов, которые считаются исполняемыми.
• Параметр Trusted Publishers (Доверенные издатели) контролирует, кто имеет право решать, каким издателям сертификатов можно доверять.
При настройке параметра для конкретного сценария или образа администратор может указать системе распознавать этот сценарий или образ по его пути, хэшу, зоне Интернета (как определено в Internet Explorer) или по криптографическому сертификату, а также сопоставить его с уровнем безопасности Disallowed (He разрешено) либо Unrestricted (Неограниченный).
Политики ограниченного использования программ применяются внутри различных компонентов, где файлы рассматриваются как содержащие исполняемый код. Некоторые из таких компонентов перечислены ниже.
• Windows-функция CreateProcess (\Windows\System32\Kernel32.dll) пользовательского режима применяет эти политики к исполняемым образам.
• Код загрузки DLL в Ntdll (\Windows\System32\Ntdll.dll) применяет эти политики к DLL.
• Командная оболочка Windows (\Windows\System32\Cmd.exe) применяет эти политики к командным файлам.
• Компоненты Windows Scripting Host, запускающие сценарии, — \Windows\System32\Cscript.exe (для сценариев командной строки), \Windows\ System32\Wscript.exe (для UI-сценариев) и \Windows\System32\Scrobj.dll (для объектов-сценариев) — применяют эти политики к сценариям. Каждый из этих компонентов определяет, действуют ли политики ограничения, по значению параметра реестра HKLM\SOFTWARE\Policies\Micro-soft\Windows\Safer\CodeIdentifiers\TransparentEnabled. Если он равен 1, то политики действуют. Далее каждый из компонентов проверяет, подпадает ли код, который он собирается выполнить, под действие одного из правил, указанных в подразделе раздела CodeIdentifiers, и, если да, следует ли разрешить выполнение. Если ни одно из правил к данному коду не относится, его выполнение зависит от политики по умолчанию, определяемой параметром DefaultLevel в разделе CodeIdentifiers.
Software Restriction Policies — мощное средство для предотвращения запуска неавторизованного кода и сценариев, но только при правильном применении. Если политика по умолчанию не запрещает выполнение, то в образ, который не разрешено запускать в данной системе, можно внести минимальные изменения, и это позволит обойти правило и запустить данный образ.
ЭКСПЕРИМЕНТ: наблюдение за применением политики ограниченного использования программ
Вы можете косвенно убедиться в применении политик ограниченного использования программ, наблюдая за обращениями к реестру при попытке выполнения образа, запуск которого запрещен.
1. Запустите secpol.msc, чтобы открыть редактор локальной политики безопасности, и перейдите в узел Software Restriction Policies (Политики ограниченного использования программ).
2. Выберите Create New Policies (Создать новые политики) из контекстного меню, если такие политики не определены.
3. Создайте правило, запрещающее путь \Windows\System32\Note-pad.exe.
4. Запустите Regmon и установите включающий фильтр для «Safer» (описание Regmon см. в главе 4).
5. Откройте окно командной строки и попробуйте запустить Notepad. Ваша попытка запуска Notepad должна закончиться появлением сообщения о том, что вам запрещен запуск указанной программы, и Regmon должна показать, как командная оболочка (cmd.exe) запрашивает политики ограничения на локальном компьютере.
Windows поддерживает большой набор функций защиты, соответствующий ключевым требованиям как правительственных организаций, так и коммерческих структур. B этой главе мы кратко рассмотрели внутренние компоненты, лежащие в основе функций защиты.
B следующей главе мы обсудим последний из основных компонентов исполнительной системы, описываемых в этой книге, — подсистему ввода-вывода.