¿Qué TargetName usar al llamar a InitializeSecurityContext (Negotiate)?

La pregunt

Cuando llame aInitializeSecurityContext, ¿qué valor le paso a laTargetName parámetro?

Fondo revisado

Estoy llamando a la funciónInitializeSecurityContext:

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

¿Qué le paso apszTargetName?

He intentad

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", ...);

Todos fallan o descienden a NTLM.

Not: Mi máquina está unida al dominio, pero el dominio esn llamadodomain.com, o inclusohostname.domain.com, o inclusoqwertyasdf. Así que no me sorprende que esos intentos fracasen. Pero la gente decía probar cosas comohttp/HOSTNAME, así que puse enhttp/HOSTNAME.

Antecedente

LosInitializeSecurityContext (Negociar)a función @ tiene unaOpciona TargetName parámetro:

pszTargetName [en, opcional]

Un puntero a una cadena terminada en nulo que indica el nombre principal del servicio (SPN) o el contexto de seguridad del servidor de destino.
as aplicaciones deben proporcionar un SPN válido para ayudar a mitigar los ataques de repetición.

¿Qué se supone que es esto?

Más fondo

Estoy intentando validar un conjunto de credenciales de usuario, por ejemplo

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

La validación de un conjunto de credenciales de usuario requiere el uso de la API SSPI. La primera función para llamar esInitializeSecurityContext. Uno de los parámetros paraInitializeSecurityContext es un "TargetName" cuerda

He intentado dejarlonul, pero el Verificador de aplicaciones desencadena un punto de interrupción y escribe el error:

VERIFIER STOP 00005003: pid 0xF08:
InitializeSecurityContext utiliza un objetivo NULL o un objetivo con formato incorrecto para el servicio Kerberos.
Consulte pszTargetName para conocer el valor del objetivo.
00000000: no utilizado.
00000000: No

n este punto, sería útil recordar que laNegotiate proveedor intentará usarKerberos, pero respaldo aNTLM. En el caso deNegotiate, Kerberos oNTLM, elTargetName parámetro está documentado como:

Nombre principal del servicio (SPN) o la contexto de seguridad del servidor de destino.

Pero entonces, ¿qué debo pasar?

intenté hacer lo que hace el artículo de la Base de conocimiento de SSPI, nada (es decir, pasarNULL):

Cómo validar las credenciales de usuario en los sistemas operativos de Microsoft
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);

Pero nada (es decir,NULL) no funciona.

Nota El artículo de KB fue reescrito masivamente en 2007. En su encarnación original de 1999 pasaron"AuthSamp" como objetivo, pero eso también falla.

Bonus Chatter:

nombre principal del servicio
(SPN) El nombre por el cual un cliente identifica de forma exclusiva una instancia de un servicio. Si instala varias instancias de un servicio en computadoras en un bosque, cada instancia debe tener su propio SPN. Una instancia de servicio dada puede tener múltiples SPN si hay varios nombres que los clientes podrían usar para la autenticación

contexto de seguridad
Los atributos o reglas de seguridad que están actualmente vigentes. Por ejemplo, el usuario actual inició sesión en la computadora o el número de identificación personal ingresado por el usuario de la tarjeta inteligente. Para SSPI, un contexto de seguridad es una estructura de datos opaca que contiene datos de seguridad relevantes para una conexión, como una clave de sesión o una indicación de la duración de la sesión.

Bonus Chatter 2

De la documentación del verificador de la aplicación:

El conector Verifier detecta los siguientes errores:

El paquete NTLM se especifica directamente en la llamada a AcquireCredentialsHandle (o API de contenedor de nivel superior).

El nombre de destino en la llamada a InitializeSecurityContext es NULL.

El nombre de destino en la llamada a InitializeSecurityContext no es un nombre de dominio estilo SPN, UPN o NetBIOS correctamente formado.

Los últimos dos casos obligarán a Negotiate a retroceder a NTLM, ya sea directamente (el primer caso) o indirectamente (el controlador de dominio devolverá un error de "principal no encontrado" en el segundo caso haciendo que Negotiate retroceda).

El complemento también registra advertencias cuando detecta degradaciones a NTLM; por ejemplo, cuando el controlador de dominio no encuentra un SPN. Estos solo se registran como advertencias, ya que a menudo son casos legítimos, por ejemplo, cuando se autentica en un sistema que no está unido al dominio.

En mi caso, el dominio que estoy validando esnull (ya que no sé el nombre de dominio de la máquina, o incluso si haye un dominio). Pero los resultados son los mismos si codifico el nombre de dominio de mi máquina de desarrollo.

Update 3

Valores de pszTargetName que activa el error de AppVerifier, pero inicia sesión tiene éxito:

null"""AuthSamp""qwertyasdf" * el nombre del dominio que estoy validando (por ejemplo,"avatopia.com") * el nombre del dominio al que se une la máquina (por ejemplo,"avatopia.com") * el nombre del dominio en el que se encuentra la cuenta de usuario (por ejemplo,"avatopia.com")

Valores de pszTargetName que no activan un error de AppVerifier, pero inician sesión falla:

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

Valores de pszTargetname que no desencadenan un error de AppVerifier, logon tiene éxito:

ningun

Update 4

o que estoy tratando de hacer: averiguar si un nombre de usuario / contraseña es válido.

tengo un nombre de usuario: p. @"ian" Tengo una contraseña: p. @"pass1"

Ahora hay más arrugas que la cuentaian podría ser unloca cuenta o unadomini cuenta. Y debes decidir siian es una cuenta local o de dominio antes de que pueda solicitarla. Esto es porqueian puede tenerdo cuentas:

ian en el dominiostackoverflow.comian en la máquina local

Así que necesito especificar si quiero:

preguntar un dominio particular (por ejemplo,stackoverflow.com) opreguntar la máquina local (que voy arepresenta como".")

Ahora podemos llegar a una referencia cruzada:

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

Update 5

Podría ayudar a explicar lo que estoy tratando de hacer, entonces tal vezcóm hacerlo será más fácil. Digamos que entro en un edificio de oficinas al azar en el centro, entro en un cubículo aleatorio y escribo un nombre de usuario y contraseña aleatorios:

voy a intentar iniciar sesión en el dominioTURBOENCABULATOR. especifiqué que quiero intentar autenticarme contra laTURBOENCABULATOR dominio con el prefijo mi nombre de usuario como:

TURBOENCABULATOR\ian

Nota Dudo mucho que la red tenga un dominio llamado turboencabulator, ya que el nombre en sí solo vienedesde la automatización de Rockwell. El intento de iniciar sesión casiciertament fallar. Pero, ¿cómo los revisa Windows?

Cómo Windows intento de validar estas credenciales? Cómo Windows validar las credenciales:

Nombre de usuario: ianContraseñ: pass1Domini: TURBOENCABULATOR

Hace Windows utilizar el Interfaz de paquete de soporte de seguridad? Asumiend windows usaNegocia o Kerberos para la autenticación, ¿qué hace Windows pase como elpszTarget parámetro? Es casi seguro que las credenciales que ingrese no serán válidas. ¿Cómo va a Windows determinar si son válidos? ¿Qué API Windows llamar para validar las credenciales?

Windows puede validar credentails. @I también quiere validar las credenciales.

Quizás en lugar de intentar conectarse a laTURBOENCABULATOR dominio, trato de conectarme aturboencabulator.com dominio anteponiendo el dominio a mi nombre de usuario comoturboencabulator.com\ian:

Se aplica la misma pregunta. Cómo Windows validar credenciales? Quiero hacer lo que hace Windows. Suponiendo que Windows usa kerberos para la autorización, ¿qué pasa Windows como pszTargetName parámetro en SSPI?

Quizás en lugar de intentar conectarse a laturboencabulator.com dominio, trato de conectarme aturboencabulator.net dominio:

Nota que en este ejemplo tengo adjunto el nombre de dominio a mi nombre de usuario, en lugar de prepending eso

Quizás en lugar de intentar conectarse a laturboencabulator.net dominio, trato de validar al usuario como una cuenta local (máquina) con el prefijo mi nombre de usuario con.\ como

¿Cómo valida Windows el nombre de usuario y la contraseña en la base de datos de la cuenta local? ¿Utiliza SSPI conNegocia paquete? Si es así, ¿qué valor pasa como pszTargetName?

Personas están hablando de servidores web, http, servidor de fundación de equipo. Realmente no sé de dónde sacan eso. O hablan de editar un usuario en el directorio activo para asegurarse de que algo esté presente; no veo por qué necesito editar algo: Windows no edita nada.

QuéTargetName ¿solía llamar aInitializeSecurityContext para validar un conjunto de credenciales?

Bonus Chatter

Aquí hay un capítulo de la documentación del verificador de aplicaciones sobre por qué tienen una prueba si alguien está usando NTLM por error:

Por qué se necesita el complemento NTLM

NTLM es un protocolo de autenticación obsoleto con fallas que potencialmente comprometen la seguridad de las aplicaciones y el sistema operativo. La deficiencia más importante es la falta de autenticación del servidor, lo que podría permitir a un atacante engañar a los usuarios para que se conecten a un servidor falso. Como corolario de la falta de autenticación del servidor, las aplicaciones que usan NTLM también pueden ser vulnerables a un tipo de ataque conocido como ataque de "reflexión". Esto último permite a un atacante secuestrar la conversación de autenticación de un usuario en un servidor legítimo y usarla para autenticar al atacante en la computadora del usuario. Las vulnerabilidades de NTLM y las formas de explotarlas son el objetivo de aumentar la actividad de investigación en la comunidad de seguridad.

Aunque Kerberos ha estado disponible durante muchos años, muchas aplicaciones todavía están escritas para usar solo NTLM. Esto reduce innecesariamente la seguridad de las aplicaciones. Sin embargo, Kerberos no puede reemplazar NTLM en todos los escenarios, principalmente aquellos en los que un cliente necesita autenticarse en sistemas que no están unidos a un dominio (una red doméstica quizás sea la más común de estas). El paquete de seguridad Negotiate permite un compromiso compatible con versiones anteriores que utiliza Kerberos siempre que sea posible y solo vuelve a NTLM cuando no hay otra opción. Cambiar el código para usar Negotiate en lugar de NTLM aumentará significativamente la seguridad para nuestros clientes al tiempo que introduce pocas o ninguna compatibilidad de aplicaciones. Negociar por sí mismo no es una bala de plata: hay casos en los que un atacante puede forzar la degradación a NTLM, pero estos son significativamente más difíciles de explotar. Sin embargo, una mejora inmediata es que las aplicaciones escritas para usar Negotiate correctamente son automáticamente inmunes a los ataques de reflexión NTLM.

A manera de una última palabra de precaución contra el uso de NTLM: En futuras versiones de Windows, será posible desactivar el uso de NTLM en el sistema operativo. Si las aplicaciones dependen mucho de NTLM, simplemente no podrán autenticarse cuando NTLM esté deshabilitado.

Cómo funciona el complemento

El conector Verifier detecta los siguientes errores:

El paquete NTLM se especifica directamente en la llamada a AcquireCredentialsHandle (o API de contenedor de nivel superior).

El nombre de destino en la llamada a InitializeSecurityContext es NULL.

El nombre de destino en la llamada a InitializeSecurityContext no es un nombre de dominio estilo SPN, UPN o NetBIOS correctamente formado.

Los últimos dos casos obligarán a Negotiate a retroceder a NTLM, ya sea directamente (el primer caso) o indirectamente (el controlador de dominio devolverá un error de "principal no encontrado" en el segundo caso haciendo que Negotiate retroceda).

El complemento también registra advertencias cuando detecta degradaciones a NTLM; por ejemplo, cuando el controlador de dominio no encuentra un SPN. Estos solo se registran como advertencias, ya que a menudo son casos legítimos, por ejemplo, cuando se autentica en un sistema que no está unido al dominio.

NTLM se detiene

5000 - La aplicación ha seleccionado explícitamente el paquete NTLM

Severity - Error

La aplicación o subsistema selecciona explícitamente NTLM en lugar de Negociar en la llamada a AcquireCredentialsHandle. Aunque es posible que el cliente y el servidor se autentiquen usando Kerberos, esto se evita mediante la selección explícita de NTLM.

Cómo arreglar este erro

La solución para este error es seleccionar el paquete Negociar en lugar de NTLM. La forma en que esto se haga dependerá del subsistema de red particular que esté utilizando el cliente o servidor. Algunos ejemplos se dan a continuación. Debe consultar la documentación sobre la biblioteca particular o el conjunto de API que está utilizando.

APIs(parameter) Used by Application    Incorrect Value  Correct Value  
=====================================  ===============  ========================
AcquireCredentialsHandle (pszPackage)  “NTLM”           NEGOSSP_NAME “Negotiate”
Ver tambiéInitializeSecurityContext parámetro pszTargetName

Respuestas a la pregunta(8)

Su respuesta a la pregunta