Какое TargetName использовать при вызове InitializeSecurityContext (согласование)?

Вопрос

При вызовеInitializeSecurityContextкакое значение я передаю параметру TargetName?

Пересмотренный фон

Я вызываю функциюInitializeSecurityContext:

InitializeSecurityContextA(
      @pAS.hcred,           //[in] credentials
      phContext,            //[in] optional] Context handle structure
      pszTargetName,        //[in, optional] Target name
      0,                    //[in] context requirements
      0,                    //[in] reserved1, must be zero
      SECURITY_NATIVE_DREP, //[in] target data representation
      pInput,               //[in] optional] SecBufferDescription
      0,                    //[in] reserved2, must be zero
      @pAS.hctxt,           //[in, out] pointer to context handle structure
      @OutBuffDesc,         //[in, out] pointer to SecBufferDesc
      ContextAttributes,    //[out] context attributes
      @lifetime);           //[out] expiration timestamp

Что передать pszTargetName?

Я пробовал

  • null: (скрытый) phContext, null, ...);
  • "": (скрыто) phContext, "", ...);
  • "spn/HOSTNAME": (скрытый) phContext, "spn/HOSTNAME", ...);
  • spn/HOSTNAME.DOMAIN.COM: (скрытый) phContext, "spn/HOSTNAME.DOMAIN.COM", ...);
  • "каргокульт/ПРОГРАММИРОВАНИЕ": (скрытый) phContext, "каргокульт/ПРОГРАММИРОВАНИЕ", ...);
  • "http/TFS.DOMAIN.COM": (скрытый) phContext, "http/TFS.DOMAIN.COM", ...);
  • "http/HOSTNAME": (скрытый) phContext, "http/HOSTNAME", ...);
  • "qwertyasdf": (скрыто) phContext, "qwertyasdf", ...);

  • "AuthSamp": (скрыто) phContext, "AuthSamp", ...);

Все они либо терпят неудачу, либо переходят на NTLM.

Примечание: Моя машина присоединена к домену, но домен нес именем domain.comили даже hostname.domain.com, или даже qwertyasdf. Так что я не удивлен, что эти попытки терпят неудачу. Но люди сказали попробовать что-то вроде http/HOSTNAME, поэтому я вставил http/HOSTNAME.

Фон

ФункцияInitializeSecurityContext(согласование)имеет необязательный параметрTargetName:

pszTargetName[in, необязательный]

Указатель на строку с завершающим нулем, которая указывает имя участника-службы (SPN) или контекст безопасности целевого сервера.
Приложения должны предоставлять действительное имя участника-службы, чтобы смягчить атаки повторного воспроизведения.

Что это должно быть?

Дополнительная информация

Я пытаюсь проверить набор учетных данных пользователя, например:

Boolean ValidateCredentials(String username, String password, String domain)
{
   ...
}

Проверка набора учетных данных пользователя требует использования SSPI API. Первая вызываемая функция — InitializeSecurityContext. Одним из параметров InitializeSecurityContextявляется строка «TargetName».

Я пытался оставить его null, но Application Verifierзапускает точку останова, записывая ошибку:

VERIFIER STOP 00005003: pid 0xF08:
InitializeSecurityContext использует цель NULL или неправильно сформированную цель для службы Kerberos.
Пожалуйста, смотрите pszTargetName для значения цели.
00000000 : Не используется.
00000000 : Нет

На этом этапе было бы полезно помнить, что провайдер Negotiateпопытается использовать Kerberos, но вернется к NTLM. В случае Negotiate, Kerberosили NTLMпараметр TargetNameзадокументирован как :

Имя субъекта-службы(SPN) иликонтекст безопасностицелевого сервера.

Но тогда что я должен пройти?

Я попытался сделать то, что делает статья базы знаний SSPI, но ничего (т.е. пройти NULL):

Как проверить учетные данные пользователя в операционных системах Microsoft

ss = _InitializeSecurityContext(
 &pAS->hcred,
pAS->fИнициализировано? &pAS->hctxt : NULL,
NULL, //fИнициализировано? &sbdIn : NULL,
0,
 &pAS->hctxt,
 &sbdOut,
 &fContextAtr,
 &tsИстечение);

Но ничего (т.е. NULL) не работает.

Примечание:Статья в базе знаний была сильно переписана в 2007 году. В ее первоначальном воплощении 1999 года они передали "AuthSamp"в качестве цели, но это также не работает.

Bonus Chatter:

имя участника-службы
(SPN)Имя, по которому клиент однозначно идентифицирует экземпляр службы. Если вы устанавливаете несколько экземпляров службы на компьютерах в лесу, каждый экземпляр должен иметь собственное имя участника-службы. У данного экземпляра службы может быть несколько имен участников-служб, если существует несколько имен, которые клиенты могут использовать для аутентификации.

контекст безопасности
Атрибуты или правила безопасности, действующие в данный момент. Например, текущий пользователь вошел в систему на компьютере или личный идентификационный номер, введенный пользователем смарт-карты. Для SSPI контекст безопасности — это непрозрачная структура данных, которая содержит данные безопасности, относящиеся к соединению, такие как ключ сеанса или указание продолжительности сеанса.

Дополнительная болтовня 2

Из документации верификатора приложений:

Подключаемый модуль верификатора обнаруживает следующие ошибки:

  • Пакет NTLM прямо указывается в вызове AcquireCredentialsHandle (или API-оболочки более высокого уровня).

  • Целевое имя в вызове InitializeSecurityContext имеет значение NULL.

  • Целевое имя в вызове InitializeSecurityContext не является правильно сформированным именем SPN, UPN или доменным именем в стиле NetBIOS.

  • Последние два случая заставят Negotiate вернуться к NTLM либо напрямую (первый случай), либо косвенно (контроллер домена вернет ошибку «основной не найден» во втором случае, что приведет к возврату Negotiate).

  • Подключаемый модуль также регистрирует предупреждения при обнаружении перехода на NTLM; например, если имя участника-службы не найдено контроллером домена.Они регистрируются только как предупреждения, поскольку часто являются законными случаями — например, при аутентификации в системе, которая не присоединена к домену.

В моем случае домен, который я проверяю, равен null(поскольку я не знаю доменного имени машины или даже если является доменом). Но результаты будут такими же, если жестко закодировать доменное имя моей машины разработки.

Обновление 3

Значения pszTargetName, которые вызывают ошибку AppVerifier, но вход в систему проходит успешно:

  • ноль
  • ""
  • "AuthSamp"
  • "qwertyasdf"
  • *имя домена, для которого выполняется проверка (например, "avatopia.com")
  • *имя домена, к которому подключена машина (например, "avatopia.com")
  • *имя домена, в котором находится учетная запись пользователя (например, "avatopia.com")

Значения pszTargetNameкоторые не вызывают ошибку AppVerifier, но вход в систему завершается ошибкой :

  • "http/HOSTNAME"
  • "http/TFS.DOMAIN.COM"
  • "frob/GROBBER"
  • " cargocult/PROGRAMMING"
  • "spn/HOSTNAME"
  • "spn/HOSTNAME.DOMAIN.COM"

Значения pszTargetname, которые не вызывают ошибку AppVerifier, и вход выполнен успешно:

  • нет

Обновление 4

Что я пытаюсь сделать: выяснить, допустимы ли имя пользователя/пароль.

  • у меня есть имя пользователя: например. "ian"
  • у меня есть пароль: напр."pass1"

Теперь есть еще одна проблема: учетная запись ianможет быть локальнойучетной записью или доменнойучетной записью. И вам нужно решить, является ли ianлокальной или доменной учетной записью, прежде чем вы сможете задать вопрос. Это связано с тем, что ianможет иметь две учетные записи:

  • ianв домене stackoverflow.com
  • ianна локальном компьютере

. мне нужно указать, хочу ли я:

  • запрашивать конкретный домен (например, stackoverflow.com) или
  • запрашивать локальный компьютер (который я представлюкак ".")

Теперь мы можем придумать перекрестную ссылку:

Username  Password  Domain             Machine on domain?  Validate as
========  ========  =================  ==================  ==============
iboyd     pass1     .                  No                  Local account
iboyd     pass1     (empty)            No                  Local account
iboyd     pass1     stackoverflow.com  No                  Domain account

iboyd     pass1     .                  Yes                 Local account
iboyd     pass1     (empty)            Yes                 Domain account
iboyd     pass1     stackoverflow.com  Yes                 Domain account

Обновление 5

Это может помочь объяснить, что я пытаюсь сделать, а затем как Делать это станет легче. Допустим, я захожу в случайное офисное здание в центре города, захожу в случайную кабинку и ввожу случайное имя пользователя и пароль:

enter image description here

я попытаюсь войти в домен TURBOENCABULATOR. я указал, что хочу попытаться аутентифицироваться в домене TURBOENCABULATOR, добавив к моему имени пользователя префикс:

TURBOENCABULATOR\ian

Примечание: я очень сомневаюсь, что в сети есть домен с именем turboencabulator, поскольку само название происходит только от автоматизации Rockwell. Попытка войти почти точноне удастся.Но как Windows проверяет их?

КакWindowsпытается проверить эти учетные данные? КакWindowsпроверяет учетные данные:

  • Имя пользователя : ian
  • Пароль : pass1
  • Домен : TURBOENCABULATOR

Делает лиWindowsиспользовать интерфейс пакета поддержки безопасности? Предполагая, чтоWindows использует для аутентификации Negotiateили Kerberos, чтоWindowsпередает в качестве параметра pszTarget? Почти наверняка введенные мной учетные данные будут недействительны.КакWindowsопределит, действительны ли они? Какой API будет вызыватьWindowsдля проверки учетных данных?

Windowsможет проверять учетные данные.Ятакже хочу проверить учетные данные.

Возможно, вместо того, чтобы пытаться подключиться к домену TURBOENCABULATOR, я пытаюсь подключиться к домену turboencabulator.com, добавляя домен к моему имени пользователя как turboencabulator.com. \ian:

enter image description here

Тот же вопрос. КакWindowsпроверяет учетные данные? Я хочу делать то, что делает Windows. Предполагая, что Windows использует kerberos для авторизации, что Windows передает как параметр pszTargetNameв SSPI?

Возможно, вместо того, чтобы пытаться подключиться к домену turboencabulator.com, я пытаюсь подключиться к домену turboencabulator.net:

enter image description here

Обратите внимание, что в этом примере я добавилдоменное имя к моему имени пользователя, а не добавил перед ним.

Возможно, вместо того, чтобы пытаться подключиться к домену turboencabulator.net, я пытаюсь проверить пользователя как локальную (машинную) учетную запись, добавив префикс .\к моему имени пользователя:

enter image description here

Как Windows проверяет имя пользователя и пароль в базе данных локальных учетных записей? Использует ли он SSPI с пакетом Negotiate? Если да, то какое значение передается как pszTargetName?

Люди говорят о веб-серверах, http, сервере Team Foundation. Я действительно не знаю, откуда они это берут.Или они говорят о редактировании пользователя в активном каталоге, чтобы убедиться, что что-то присутствует - я не понимаю, почему мне нужно что-то редактировать:Windowsничего не редактирует.

Что TargetNameя использовал при вызове InitializeSecurityContextдля проверки набора учетных данных?

Bonus Chatter

Вот глава из документации Application Verifier о том, почему у них есть тест, если кто-то по ошибке использует NTLM:

Зачем нужен подключаемый модуль NTLM

NTLM — устаревший протокол аутентификации с недостатки, которые потенциально поставить под угрозу безопасность приложений и операционную система. Самый главный недостаток это отсутствие сервера аутентификация, которая может позволить злоумышленнику обмануть пользователей подключение к поддельному серверу. Как следствие отсутствия сервера аутентификации, приложения, использующие NTLM, также могут быть уязвимы для тип атаки, известный как атака «отражение». Последнее позволяет злоумышленник, чтобы перехватить сеанс аутентификации пользователя на законный сервер и использовать его для аутентификации злоумышленника на компьютер пользователя. Уязвимости NTLM и способы их использования являются целью повышения исследовательской активности в области безопасности сообщество.

Хотя Kerberos был доступен в течение многих лет, многие приложения по-прежнему написаны для использования только NTLM. Это без необходимости снижает безопасность приложений.Однако Kerberos не может заменить NTLM во всех сценарии — в основном те, где клиенту необходимо пройти аутентификацию для системы, которые не присоединены к домену (возможно, домашняя сеть самый распространенный из них). Пакет безопасности Negotiate позволяет компрометация с обратной совместимостью, использующая Kerberos, когда это возможно и возвращается к NTLM только тогда, когда нет другого выбора. Код переключения использование Negotiate вместо NTLM значительно увеличит безопасность для наших клиентов при внедрении нескольких приложений или их отсутствии совместимости. Переговоры сами по себе не панацея – есть случаи, когда злоумышленник может принудительно перейти на NTLM, но они значительно труднее использовать. Однако один немедленный улучшение заключается в том, что приложения, написанные для правильного использования Negotiate автоматически невосприимчивы к атакам отражения NTLM.

В качестве последнего предостережения против использования NTLM: в будущем версиях Windows можно будет отключить использование NTLM на операционная система. Если приложения имеют жесткую зависимость от NTLM они просто не смогут аутентифицироваться, когда NTLM отключен.

Как работает подключаемый модуль

Подключаемый модуль Verifier обнаруживает следующие ошибки:

  • Пакет NTLM напрямую указывается в вызове AcquireCredentialsHandle (или API-оболочки более высокого уровня).

  • Целевое имя в вызове InitializeSecurityContext имеет значение NULL.

  • Целевое имя в вызове InitializeSecurityContext не является правильно сформированным именем SPN, UPN или доменным именем в стиле NetBIOS.

Последние два случая заставят Negotiate вернуться к NTLM либо напрямую (первый случай), либо косвенно (контроллер домена вернет ошибку «основной не найден» во втором случае, что приведет к возврату Negotiate).

Подключаемый модуль также регистрирует предупреждения при обнаружении перехода на NTLM; например, если имя участника-службы не найдено контроллером домена.Они регистрируются только как предупреждения, поскольку часто являются допустимыми случаями — например, при аутентификации в системе, которая не присоединена к домену.

NTLM Stops

5000 — приложение явно выбрало пакет NTLM

Серьезность — ошибка

Приложение или подсистема явно выбирает NTLM вместо Negotiate при вызове AcquireCredentialsHandle. Даже если клиент и сервер могут пройти аутентификацию с помощью Kerberos, это предотвращается явным выбором NTLM.

Как исправить эту ошибку

Исправление этой ошибки заключается в выборе пакета Negotiate вместо NTLM. То, как это будет сделано, будет зависеть от конкретной сетевой подсистемы, используемой клиентом или сервером. Некоторые примеры приведены ниже. Вам следует ознакомиться с документацией по конкретной библиотеке или набору API, который вы используете.

API (параметр), используемый приложением Неверное значение Правильное значение
================================================== == =========================
AcquireCredentialsHandle (pszPackage) «NTLM» NEGOSSP_NAME «Переговоры»

См. также

18
задан Ian Boyd 3 February 2015 в 19:57
поделиться