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. Эти пакеты перечисляются в разделе реестра HKLMSYSTEMCurrentControlSetControlLsa. Winlogon передает пакету данные входа через LsaLogonUser. После того как пакет аутентифицирует пользователя, Winlogon продолжает процесс входа этого пользователя. Если ни один из пакетов не сообщает об успешной аутентификации, процесс входа прекращается.
Windows использует два стандартных пакета аутентификации при интерактивном входе: Kerberos и MSV1_0. Пакет аутентификации по умолчанию в автономной системе Windows — MSVlO (WindowsSystem32Msvl_0.dll); он реализует протокол LAN Manager 2. LSASS также использует MSVlO на компьютерах, входящих в домен, чтобы аутентифицировать домены и компьютеры под управлением версий Windows до Windows 2000, не способные найти контроллер домена для аутентификации. (Отключенные от сети портативные компьютеры относятся к той же категории.) Пакет аутентификации Kerberos (WindowsSystem32Kerberos.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 System32Kdcsvc.dll), реализующая протокол аутентификации Kerberos, выполняется в процессе Lsass на контроллерах домена.
После проверки хэшированной информации об имени и пароле пользователя с помощью объектов учетных записей пользователей (user account objects) Active Directory (через сервер Active Directory, WindowsSystem32 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 в предыдущем примере вывода, вы могли бы ввести такую команду: