Выбрать главу

Ничуть не безопасней локальная регистрация - под UNIX существует множество закладок, имитирующих процедуру входа в систему, а на самом деле похищающих пароли. Поэтому, разработчики подсистемы защиты Windows NT Джим Келли (Jim Kelly) и Клифф Ван Дайк (Cliff Van Dyke) «подцепили» процедуру регистрации на комбинацию клавиш “Alt-Ctrl-Del”. Никакое приложение, исполняющееся с пользовательскими привилегиями, не способно в этот момент захватить управление. Конечно, системные драйверы вольны перехватывать что угодно, в том числе и нажатие “Atl-Ctrl-Del”, но право установки новых драйверов в систему дано только администратору, а непривилегированные пользователи установить подобную закладку в Windows NT уже не смогут [151].

Однако такая защита не очень-то помогает, если используется автоматический вход в систему (а используется он удручающе часто [152]). В ветке реестра “HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrenetVersion\Winlogon”, по умолчанию доступной группе Everyone (всем пользователям), содержатся имя пользователя, вошедшего в систему, (“DefaultUsername”) и его пароль (“DefaultPassword”). Если удаленные подключения разрешены, любой член группы Everyone (т.е. всякий, зарегистрированный в системе), сможет просмотреть указанную ветвь реестра, со всеми отсюда вытекающими (для администратора) последствиями.

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

Внешне процедура аутентификации выглядит безупречно. Клиент, установив сессию по протоколу NetBIOS, уведомляет сервер о своем желании вступить с ним в связь, посылая сообщение SMB_CON_NEGOTIATE, в котором перечисляются все известные клиенту диалекты SMB.

Сервер, выбрав самый современный из доступных ему и клиенту протоколов [153], возвращает либо случайную 8-байтовую последовательность, именуемую challenge [154], либо просьбу передать пароль в открытом виде [155].

Клиент, в отклик, посылает сообщение SMB_SESSION_SETUP_ANDX, содержащее пользовательское имя (открытым текстом); открытый пароль или challenge, зашифрованный хеш - значением пароля.

Сервер извлекает из базы данных (в просторечии «файла паролей») оригинальный хеш пароля данного пользователя, шифрует им challenge и сравнивает полученный результат с откликом клиента. Если они совпадают - хорошо, а нет - invalid user.

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

Говоря математическим языком, если f - функция шифрования, key - ключ, а value - шифруемые данные, то: f(value) ? key® crypt, а F(crypt) ? key® value, где F - функция дешифрования. Если key - challenge, а value - хеш пароля, то злоумышленник, перехватив challenge и crypt, сможет восстановить хеш - значение пароля! Но как все изменится, если key - хеш, а value - challenge! Тогда, чтобы из crypt извлечь challenge (а на кой его извлекать, когда оно и без того известно?!), необходимо знать ключ шифрования - хеш значение пароля, а его как раз и требуется найти. Причем, функция шифрования специально подобрана так, чтобы, зная исходный и зашифрованный текст (то есть challenge и crypt), вычислить ключ (key, он же хеш - значение пароля) было невозможно, иначе, чем прямым перебором.

Строго говоря, сервер также не в состоянии расшифровать ответ клиента, ибо не имеет никакого представления, каким ключом он был зашифрован. Но это и не нужно! Функция необратимого шифрования позволяет установить идентичность аргументов, но не позволяет узнать сами аргументы по значению функции. Математически это можно выразить так. Пусть f(x) ® y, f(x1) ® y1; тогда, очевидно если y -y1, то и x - x1. [156]

Описанная выше схема (именуемая «запрос-отклик») нечувствительная к перехвату канала связи (то есть перехват y не дает никакого представления о значении x), но критична к криптостойкости используемых алгоритмов хеширования и шифрования (а так же, разумеется, защищенности «хранилища» хеш-значений паролей).

Операционная система Windows NT 4.0 (Windows 2000) поддерживает один алгоритм шифрования и, по крайней мере, два алгоритма хеширования: хеш LAN Manager (далее просто LM-хеш), разработанный Microsoft для операционной системы IBM OS/2, а позже интегрированный в Windows 3.1, Windows 3.11 for Workgroups, Windows 95, Windows 98 и, собственно, свой «родной» NT-хеш.

В базе данных диспетчера учетных записей SAM (Security Account Manager) обычно хранятся оба хеш значения - как LM-хеш, так и NT-хеш, поэтому, клиент для аутентификации может посылать либо LM-хеш, либо NT-хеш, либо и тот и другой сразу. Но если поменять свой пароль из операционной системы, не поддерживающей NT-хеш, его значение в базе SAM аннулируется [157]! Теперь, для аутентификации клиент вынужден передавать LM-хеш, до тех пор, пока вновь не поменяет свой пароль из операционной системы поддерживающий оба типа хеш -значений одновременно. Поэтому большинство клиентов посылают и LM, и NT хеш, даже если требуется лишь один из них [158].

Алгоритм получения LM-хеша при ближайшем рассмотрении выглядит так: пароль, введенный пользователем, превращается в строку фиксированной длины, равной четырнадцати символам. Короткие пароли расширяются добавлением нулевых элементов, а длинные усекаются. Все символы из множества ‘a’-‘z’ переводятся в верхний регистр, и, полученная в результате этой операции, строка расчленяется на две независимые половинки, состоящие из семи символов. Каждая из них играет роль ключа для шифровки последовательности нулей алгоритмом DES. Затем, полученные строки дописываются друг к другу, образуя шестнадцати байтовый LM-хеш.

Алгоритм получения LM-хеша

Независимое хеширование половинок пароля, в 1 000 000 000 000 000 раз уменьшает количество попыток, требующихся для его перебора (а вовсе не в два раза, как это может показаться на первый взгляд). Это же какой талант надо иметь, чтобы допустить такой ляп! Уж сколько раз твердили миру (то бишь разработчикам) - не разводите самодеятельность, используйте проверенные временем алгоритмы, да только все не впрок.

Но эмоции эмоциями, а как все это звучит на языке математики? Путь f - некая хеш функция, а x1…7y8…14 - введенный пользователем пароль. Тогда LM-хеш будет равен f(x)+264*f(y), поскольку область допустимых значений функции f лежит в интервале целых неотрицательных чисел, не превышающих 264, то поиск подходящего пароля заключается в решении двух уравнений (где P - искомый пароль, а H значение LM-хеша):

1. DES(0) - P 1…7® H1…8; [159]

2. DES(0) - P 8…14® H9…16;

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