воскресенье, 1 мая 2011 г.

Чудеса аутентификации. Чудо первое: доступ разрешён

Как-то раз я поспорил с одним коллегой о том, каким образом ОС Windows хэширует пароли, а именно: солит она их или нет. Коллега, будучи весьма опытным человеком, с абсолютной уверенностью утверждал, что хэш пароля просто обязан быть солёным. Его уверенность базировалась на теории о том, что без применения соли данные по хэшу легко вскрываются атакой со словарём. Вот только эта теория никак не могла объяснить такую странность: 
  • есть 2 хоста, не включённых в домен, – AliceHost и BobHost;
  • на обоих хостах есть одноимённые пользователи с одинаковыми паролями: AliceHost\user и BobHost\user;
  • на хосте AliceHost есть сетевая папка \\AliceHost\Folder, доступ к которой предоставлен только пользователю AliceHost\user;
  • если на хосте BobHost осуществить вход пользователем BobHost\user, то вы легко получите доступ к папке \\AliceHost\Folder.

Хэши
Очевидно, что подобный трюк возможен лишь в 2-ух случаях:
  • пароль хранится открытым текстом или кэшируется в сессии,
  • хэши паролей на обоих хостах совпадают.
Первый вариант можно даже не рассматривать, как совершенно абсурдный. Реальность гораздо проще: ОС Windows действительно не осуществляет никаких модификаций пароля перед хэшированием. Поэтому на разных хостах для одного и того же пароля мы будем иметь один и тот же хэш. Если быть точнее, то хэша может быть два: LM хэш и NT хэш.

Для вычисления LM хэша применяется алгоритм DES, при этом хэшируются только первые 14 символов пароля, преобразованные к верхнему регистру. Этот хэш был разработан для очень старых версий ОС Windows. Его криптографическая надёжность не выдерживает никакой критики, на современных системах он отключен в конфигурации по умолчанию (Windows Vista и выше), включать и использовать не рекомендуется и здесь более упоминаться не будет.
NT хэш гораздо проще и надёжнее. Он представляет собой MD4 хэш над паролем, преобразованным в Unicode строку. Максимальная длина пароля – 128 символов. NT хэш в отличие от LM хэша чувствителен к регистру символов. Длина обоих хэшей равна 16 байтам.

Протоколы
Основными протоколами сетевой аутентификации в ОС Windows являются: Kerberos, NTLMv1 и NTLMv2. Протокол Kerberos применяется только для аутентификации в домене Active Directory. Он является международным стандартом и достаточно хорошо описан. Здесь я его рассматривать не буду.

Протокол NTLM является закрытым протоколом компании Microsoft, вся имеющаяся о нём информация была получена методом reverse engineering`а. Он применяется практически всегда, когда не возможно использование протокола Kerberos, например, вне домена Active Directory. Впервые данный протокол появился в Windows NT 3.5. Первая версия протокола используется до сих пор и сейчас известна под названием NTLMv1. Аутентификация выполняется следующим образом:
  1. Клиент отправляет серверу запрос на аутентификацию.
  2. В ответ на запрос сервер отвечает случайным 8-байтным числом – server challenge.
  3. Клиент берёт 16-байтный NT хэш пароля, дополняет его нулями до 21-ого байта и полученную последовательность разбивает на 3 части по 7 байтов. Каждая из этих частей используется как ключ для независимого шифрования ответа сервера алгоритмом DES. Три полученных шифрованных последовательности соединяются в одно 24-байтное значение, которое отправляется серверу.
  4. Сервер выполняет аналогичное преобразование своего ответа, используя свою версию NT хэша. Если полученное значение совпадает с ответом клиента, то аутентификация считается успешной.
Одного этого описания уже достаточно, чтобы объяснить парадокс, приведённый в начале этой заметки: вне домена Active Directory хост BobHost имеет всю необходимую информацию, чтобы осуществить аутентификацию пользователем user на хосте AliceHost по протоколу NTLM.

Протокол NTLMv2 доступен опционально, начиная с версии ОС Windows NT 4 SP4. Начиная с Windows Vista, он является основным и включен в конфигурации по умолчанию – это означает, что данные операционные системы по умолчанию более не посылают запросов и откликов по протоколу NTLMv1. Данная версия протокола сложнее и надёжнее. Её можно описать следующим образом:
  1. Клиент отправляет серверу запрос на аутентификацию.
  2. В ответ на запрос сервер отвечает случайным 8-байтным числом – server challenge.
  3. Клиент берёт NT хэш пароля, дополняет его именами пользователя и домена и вычисляет для этих идентификационных данных HMAC-MD5 хэш. Затем он генерирует 8-байтное случайное число (client challenge). Эта информация будет использоваться для формирования 2-ух частей ответа.
  4. Первая часть ответа включает хэш идентификационных данных, полученных на шаге 3, server challenge и client challenge. Эти данные хэшируются алгоритмом HMAC-MD5, после чего клиент приписывает к ним client challenge в открытом виде (это необходимо, что сервер мог выполнить проверку).
  5. Вторая часть ответа включает хэш идентификационных данных, server challenge и client challenge 2. Как и в случае первой части данные хэшируются алгоритмом HMAC-MD5, после чего в конец дописывается client challenge 2 в открытом виде. В свою очередь client challenge 2 содержит следующие данные: фиксированный заголовок, текущее время, client challenge и имя домена.
  6. Обе части отправляются серверу.
  7. Сервер формирует аналогичные хэши, используя свою версию NT хэша пароля пользователя, имена пользователя и домена и переданные в открытом виде client challenge и client challenge 2. Если полученное значение совпадает с ответом клиента, то аутентификация считается успешной.

    1 комментарий:

    bada комментирует...

    По поводу темы:
    www.blackhat.com/presentations/win-usa.../urity-winsec02.ppt

    А это еще интереснее:
    http://live.digitaloctober.ru/embed/1207?language=ru&params%5bpw%5d=630&params%5bph%5d=355&params%5bepisodes_under%5d=1&params%5beh%5d=100#time1338458370

    Отправить комментарий