Какое TargetName использовать при вызове InitializeSecurityContext (Negotiate)?
При звонке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
: InitializeSecurityContextA(@pAS.hcred, phContext, null, ...);
""
: InitializeSecurityContextA(@pAS.hcred, phContext, "", ...);
"spn/HOSTNAME"
: InitializeSecurityContextA(@pAS.hcred, phContext, "spn/HOSTNAME", ...);
spn/HOSTNAME.DOMAIN.COM
: InitializeSecurityContextA(@pAS.hcred, phContext, "spn/HOSTNAME.DOMAIN.COM", ...);
"cargocult/PROGRAMMING"
: InitializeSecurityContextA(@pAS.hcred, phContext, "cargocult/PROGRAMMING", ...);
"http/TFS.DOMAIN.COM"
: InitializeSecurityContextA(@pAS.hcred, phContext, "http/TFS.DOMAIN.COM", ...);
"http/HOSTNAME"
: InitializeSecurityContextA(@pAS.hcred, phContext, "http/HOSTNAME", ...);
"qwertyasdf"
: InitializeSecurityContextA(@pAS.hcred, phContext, "qwertyasdf", ...);
"AuthSamp"
: InitializeSecurityContextA(@pAS.hcred, phContext, "AuthSamp", ...);
Все они либо терпят неудачу, либо переходят на NTLM.
Запись: Моя машина подключена к домену, но доменне названныйdomain.com
, или дажеhostname.domain.com
, или дажеqwertyasdf
, Поэтому я не удивлен, что эти попытки провалились. Но люди говорят, что попробуйте такие вещи, какhttp/HOSTNAME
так что я положил вhttp/HOSTNAME
.
InitializeSecurityContext
(Согласование) функция имеетпо желанию TargetName
параметр:
pszTargetName [необязательно]
Указатель на строку с нулевым символом в конце, которая указывает имя участника службы (SPN) или контекст безопасности конечного сервера.
Приложения должны предоставить действительное имя участника-службы, чтобы помочь смягчить атаки повторного воспроизведения.
Что это должно быть?
Больше фоная пытаюсь проверить набор учетных данных пользователя, например:
Boolean ValidateCredentials(String username, String password, String domain)
{
...
}
Проверка набора учетных данных пользователя требует использования SSPI API. Первая функция для вызоваInitializeSecurityContext
, Один из параметров дляInitializeSecurityContext
это«Имя_целевого_объект» строка.
я пытался оставить этозначение NULL, ноПроверка приложения запускает точку останова, выдает ошибку:
ОСТАНОВКА ПРОВЕРКИ 00005003: pid 0xF08:
InitializeSecurityContext использует целевую NULL или неверно сформированную цель для службы Kerberos.
Пожалуйста, смотрите pszTargetName для значения цели.
00000000: не используется.
00000000: нет
На этом этапе было бы полезно помнить, чтоNegotiate
провайдер попытается использоватьKerberos
, но отступитьNTLM
, На случай, еслиNegotiate
, Kerberos
или жеNTLM
,TargetName
параметрзадокументировано:
Имя участника службы (SPN) иликонтекст безопасности сервера назначения.
Но тогда что я должен пройти?
я попытался сделать то, что делает статья базы знаний SSPI, ничего (т.е.NULL
):
ss = _InitializeSecurityContext(
&pAS->hcred,
pAS->fInitialized ? &pAS->hctxt : NULL,
NULL, //<-------pszTargetName
0,
0,
SECURITY_NATIVE_DREP,
pAS->fInitialized ? &sbdIn : NULL,
0,
&pAS->hctxt,
&sbdOut,
&fContextAttr,
&tsExpiry);
Но ничего (т.е.NULL
) не работает.
Примечание: Статья КБ была массово переписана в 2007 году. В своем первоначальном воплощении 1999 года они прошли"AuthSamp"
как цель, но это также не удается.
имя участника службы
(SPN) Имя, по которому клиент однозначно идентифицирует экземпляр службы. Если вы устанавливаете несколько экземпляров службы на компьютерах по всему лесу, у каждого экземпляра должен быть свой собственный SPN. У данного экземпляра службы может быть несколько имен участников-служб, если есть несколько имен, которые клиенты могут использовать для проверки подлинности.
контекст безопасности
Атрибуты безопасности или правила, которые в настоящее время действуют. Например, текущий пользователь вошел в систему на компьютере или персональный идентификационный номер, введенный пользователем смарт-карты. Для SSPI контекст безопасности - это непрозрачная структура данных, которая содержит данные безопасности, относящиеся к соединению, такие как ключ сеанса или указание продолжительности сеанса.
Из документации верификатора приложения:
Подключаемый модуль Verifier обнаруживает следующие ошибки:
Пакет NTLM указывается непосредственно в вызове AcquireCredentialsHandle (или API-оболочки более высокого уровня).
Имя цели в вызове InitializeSecurityContext имеет значение NULL.
Целевое имя в вызове InitializeSecurityContext не является правильно сформированным именем домена в стиле SPN, UPN или NetBIOS.
Последние два случая заставят Negotiate перейти к NTLM либо напрямую (первый случай), либо косвенно (контроллер домена вернет ошибку «принципал не найден» во втором случае, что приведет к откату Negotiate).
Плагин также регистрирует предупреждения при обнаружении перехода на NTLM; например, когда SPN не найден контроллером домена. Они регистрируются только как предупреждения, поскольку они часто являются допустимыми случаями - например, при аутентификации в системе, которая не присоединена к домену.
В моем случае домен, который я проверяю, являетсяnull
(так как я не знаю доменное имя машины, или даже если тамявляется домен). Но результаты будут такими же, если жестко закодировать доменное имя моей машины для разработки.
Обновление 3
ЗначенияpszTargetName что вызывает ошибку AppVerifier, но вход в системупреуспевает:
null
""
"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
Это может помочь объяснить, что я пытаюсь сделать, тогда, возможно,как сделать это станет легче. Допустим, я захожу в случайное офисное здание в центре города, захожу в случайную кабину и набираю случайное имя пользователя и пароль:
я собираюсь попробовать войти в доменTURBOENCABULATOR
, я указал, что я хочу попробовать аутентифицироваться противTURBOENCABULATOR
домен с префиксом моего имени пользователя как:
TURBOENCABULATOR\ian
Примечание: я очень сомневаюсь, что в сети есть домен под названиемturboencabulator, так как само название приходит толькоот автоматизации Rockwell, Попытка войти будет почтиконечно провал. Но как Windows проверяет их?
КакWindows пытаться проверить эти учетные данные? КакWindows проверить учетные данные:
имя пользователяЯнпароль: pass1Домен: TURBOENCABULATORЕсть лиWindows использоватьИнтерфейс пакета поддержки безопасности? Если предположить, Windows используетвести переговоры или жеKerberos для аутентификации, что делаетWindows передать какpszTarget
параметр? Почти наверняка введенные мной учетные данные не будут действительными. Как будетWindows определить, действительны ли они? Какой API будетWindows позвонить, чтобы подтвердить полномочия?
Windows может проверить учетные данные.I хочу также проверить учетные данные.
Возможно, вместо того, чтобы пытаться подключиться кTURBOENCABULATOR
домен, я пытаюсь подключиться кturboencabulator.com
домен, добавив домен к моему имени пользователя какturboencabulator.com\ian
:
Тот же вопрос применим. КакWindows проверить учетные данные? Я хочу сделать то, что делает Windows. Предполагая, что Windows использует Kerberos для авторизации, что Windows передает какpszTargetName
параметр в SSPI?
Возможно, вместо того, чтобы пытаться подключиться кturboencabulator.com
домен, я пытаюсь подключиться кturboencabulator.net
домен:
Обратите внимание, что в этом примере яприлагается доменное имя для моего имени пользователя, а непредваряя Это.
Возможно, вместо того, чтобы пытаться подключиться кturboencabulator.net
домен, я пытаюсь проверить пользователя как локальную (машинную) учетную запись, поставив перед моим именем пользователя.\
как:
Как Windows проверяет имя пользователя и пароль в локальной базе данных учетных записей? Использует ли он SSPI свести переговоры пакет? Если да, то какое значение он передает какpszTargetName
?
Люди говорят о веб-серверах, http, Team Foundation Server. Я действительно не знаю, откуда они это получают. Или они говорят о редактировании пользователя в активной директории, чтобы убедиться, что что-то присутствует - я не понимаю, почему мне нужно что-то редактировать:Windows ничего не редактирует
какаяTargetName
я использовал при звонкеInitializeSecurityContext
для проверки набора учетных данных?
Вот глава из документации Application Verifier о том, почему у них есть тест, если кто-то по ошибке использует NTLM:
Почему нужен плагин NTLMNTLM - это устаревший протокол аутентификации с недостатками, которые могут поставить под угрозу безопасность приложений и операционной системы. Наиболее важным недостатком является отсутствие проверки подлинности сервера, что может позволить злоумышленнику обманом заставить пользователей подключиться к поддельному серверу. Как следствие отсутствия аутентификации на сервере, приложения, использующие 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; например, когда SPN не найден контроллером домена. Они регистрируются только как предупреждения, поскольку они часто являются допустимыми случаями - например, при аутентификации в системе, которая не присоединена к домену.
NTLM останавливается5000 - Приложение явно выбрало пакет NTLM
Серьезность - Ошибка
Приложение или подсистема явно выбирают NTLM вместо Negotiate при вызове AcquireCredentialsHandle. Даже если клиент и сервер могут пройти аутентификацию с использованием Kerberos, это предотвращается явным выбором NTLM.
Как исправить эту ошибку
Исправление этой ошибки - выбрать пакет переговоров вместо NTLM. Как это сделать, будет зависеть от конкретной сетевой подсистемы, используемой клиентом или сервером. Некоторые примеры приведены ниже. Вам следует обратиться к документации по конкретной библиотеке или набору API, который вы используете.
APIs(parameter) Used by Application Incorrect Value Correct Value
===================================== =============== ========================
AcquireCredentialsHandle (pszPackage) “NTLM” NEGOSSP_NAME “Negotiate”
Смотрите такжеПараметр InitializeSecurityContext pszTargetName