Esempio n. 1
0
DWORD
NtlmCreateValidatedContext(
    IN PNTLM_RESPONSE_MESSAGE_V1 pNtlmRespMsg,
    IN DWORD dwMsgSize,
    IN PNTLM_CONTEXT pNtlmCtxtChlng,
    IN PBYTE pSessionKey,
    IN DWORD dwSessionKeyLen,
    IN NTLM_CRED_HANDLE hCred,
    OUT PNTLM_CONTEXT *ppNtlmContext
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    PNTLM_CONTEXT pNtlmContext = NULL;
    SEC_CHAR* pUserName = NULL;
    SEC_CHAR* pDomainName = NULL;
    PNTLM_RESPONSE_MESSAGE_V2 pV2Message = NULL;
    RC4_KEY Rc4Key;

    *ppNtlmContext = NULL;

    dwError = NtlmCreateContext(hCred, &pNtlmContext);
    BAIL_ON_LSA_ERROR(dwError);

    pNtlmContext->NtlmState = NtlmStateResponse;

    pNtlmContext->NegotiatedFlags = pNtlmCtxtChlng->NegotiatedFlags;

    dwError = LwAllocateStringPrintf(
                    &pNtlmContext->pszClientUsername,
                    "%s\\%s",
                    pNtlmCtxtChlng->pUserInfo->pszDomain,
                    pNtlmCtxtChlng->pUserInfo->pszAccount);
    BAIL_ON_LSA_ERROR(dwError);

    memcpy(pNtlmContext->SessionKey, pSessionKey, NTLM_SESSION_KEY_SIZE);
    pNtlmContext->cbSessionKeyLen = dwSessionKeyLen;
    pNtlmContext->bInitiatedSide = FALSE;

    if (pNtlmContext->NegotiatedFlags & NTLM_FLAG_KEY_EXCH)
    {
        pV2Message = (PNTLM_RESPONSE_MESSAGE_V2)pNtlmRespMsg;
        if (dwMsgSize < sizeof(*pV2Message))
        {
            dwError = ERROR_INVALID_PARAMETER;
            BAIL_ON_LSA_ERROR(dwError);
        }

        if (LW_LTOH32(pV2Message->SessionKey.dwOffset) +
                LW_LTOH16(pV2Message->SessionKey.usLength) > dwMsgSize)
        {
            dwError = ERROR_INVALID_PARAMETER;
            BAIL_ON_LSA_ERROR(dwError);
        }

        if (LW_LTOH16(pV2Message->SessionKey.usLength) != NTLM_SESSION_KEY_SIZE)
        {
            dwError = ERROR_INVALID_PARAMETER;
            BAIL_ON_LSA_ERROR(dwError);
        }

        RC4_set_key(
                &Rc4Key,
                pNtlmContext->cbSessionKeyLen,
                pNtlmContext->SessionKey);
        RC4(&Rc4Key,
                NTLM_SESSION_KEY_SIZE,
                LW_LTOH32(pV2Message->SessionKey.dwOffset) + (PBYTE)pV2Message,
                pNtlmContext->SessionKey);
    }

    dwError = NtlmInitializeKeys(pNtlmContext);
    BAIL_ON_LSA_ERROR(dwError);

cleanup:
    LW_SAFE_FREE_MEMORY(pUserName);
    LW_SAFE_FREE_MEMORY(pDomainName);
    *ppNtlmContext = pNtlmContext;
    return dwError;

error:
    if (pNtlmContext)
    {
        NtlmFreeContext(&pNtlmContext);
    }
    goto cleanup;
}
Esempio n. 2
0
DWORD
NtlmCreateResponseContext(
    IN PNTLM_CHALLENGE_MESSAGE pChlngMsg,
    IN NTLM_CRED_HANDLE hCred,
    IN BOOLEAN bDoAnonymous,
    OUT PNTLM_CONTEXT* ppNtlmContext,
    OUT PSecBuffer pOutput
)
{
    DWORD dwError = LW_ERROR_SUCCESS;
    PNTLM_RESPONSE_MESSAGE_V1 pMessage = NULL;
    PCSTR pUserNameTemp = NULL;
    PCSTR pPassword = NULL;
    PNTLM_CONTEXT pNtlmContext = NULL;
    PBYTE pMasterKey = NULL;
    BYTE LmUserSessionKey[NTLM_SESSION_KEY_SIZE] = {0};
    BYTE NtlmUserSessionKey[NTLM_SESSION_KEY_SIZE] = {0};
    BYTE LanManagerSessionKey[NTLM_SESSION_KEY_SIZE] = {0};
    BYTE SecondaryKey[NTLM_SESSION_KEY_SIZE] = {0};
    PLSA_LOGIN_NAME_INFO pUserNameInfo = NULL;
    DWORD dwMessageSize = 0;
    NTLM_CONFIG config;
    DWORD dwNtRespType = 0;
    DWORD dwLmRespType = 0;

    *ppNtlmContext = NULL;

    dwError = NtlmReadRegistry(&config);
    BAIL_ON_LSA_ERROR(dwError);

    if (bDoAnonymous)
    {
        pUserNameTemp = "";
        pPassword = "";
    }
    else
    {
        NtlmGetCredentialInfo(
            hCred,
            &pUserNameTemp,
            &pPassword,
            NULL);

        if (!pUserNameTemp[0] && !pPassword[0])
        {
            bDoAnonymous = TRUE;
        }
    }

    if (bDoAnonymous)
    {
        dwError = LwAllocateMemory(
                      sizeof(*pUserNameInfo),
                      OUT_PPVOID(&pUserNameInfo));
        BAIL_ON_LSA_ERROR(dwError);

        dwError = LwAllocateString(
                      "",
                      &pUserNameInfo->pszName);
        BAIL_ON_LSA_ERROR(dwError);
        dwError = LwAllocateString(
                      "",
                      &pUserNameInfo->pszDomain);
        BAIL_ON_LSA_ERROR(dwError);
    }
    else
    {
        dwError = LsaSrvCrackDomainQualifiedName(
                      pUserNameTemp,
                      &pUserNameInfo);
        BAIL_ON_LSA_ERROR(dwError);
    }

    dwError = NtlmCreateContext(hCred, &pNtlmContext);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LwAllocateString(
                  pUserNameTemp,
                  &pNtlmContext->pszClientUsername);
    BAIL_ON_LSA_ERROR(dwError);

    if (bDoAnonymous)
    {
        dwNtRespType = NTLM_RESPONSE_TYPE_ANON_NTLM;
        dwLmRespType = NTLM_RESPONSE_TYPE_ANON_LM;
    }
    else if (config.bSendNTLMv2)
    {
        dwNtRespType = NTLM_RESPONSE_TYPE_NTLMv2;
        // TODO: the correct thing is to use LMv2
        dwLmRespType = NTLM_RESPONSE_TYPE_LM;
    }
    else if(LW_LTOH32(pChlngMsg->NtlmFlags) & NTLM_FLAG_NTLM2)
    {
        dwLmRespType = NTLM_RESPONSE_TYPE_NTLM2;
        dwNtRespType = NTLM_RESPONSE_TYPE_NTLM2;
    }
    else
    {
        dwNtRespType = NTLM_RESPONSE_TYPE_NTLM;
        dwLmRespType = NTLM_RESPONSE_TYPE_LM;
    }

    dwError = NtlmCreateResponseMessage(
                  pChlngMsg,
                  pUserNameInfo->pszName,
                  pUserNameInfo->pszDomain,
                  pPassword,
                  (PBYTE)&gXpSpoof,
                  dwNtRespType,
                  dwLmRespType,
                  &dwMessageSize,
                  &pMessage,
                  LmUserSessionKey,
                  NtlmUserSessionKey
              );
    BAIL_ON_LSA_ERROR(dwError);

    // As a side effect of creating the response, we must also set/produce the
    // master session key...

    pMasterKey = NtlmUserSessionKey;

    if (LW_LTOH32(pChlngMsg->NtlmFlags) & NTLM_FLAG_LM_KEY)
    {
        NtlmGenerateLanManagerSessionKey(
            pMessage,
            LmUserSessionKey,
            LanManagerSessionKey);

        pMasterKey = LanManagerSessionKey;
    }

    if (LW_LTOH32(pChlngMsg->NtlmFlags) & NTLM_FLAG_KEY_EXCH)
    {
        // This is the key we will use for session security...
        dwError = NtlmGetRandomBuffer(
                      SecondaryKey,
                      NTLM_SESSION_KEY_SIZE);
        BAIL_ON_LSA_ERROR(dwError);

        // Encrypt it with the "master key" set above and send it along with the
        // response
        NtlmStoreSecondaryKey(
            pMasterKey,
            SecondaryKey,
            pMessage);

        pMasterKey = SecondaryKey;
    }

    NtlmWeakenSessionKey(
        pChlngMsg,
        pMasterKey,
        &pNtlmContext->cbSessionKeyLen);

    memcpy(pNtlmContext->SessionKey, pMasterKey, NTLM_SESSION_KEY_SIZE);

    pNtlmContext->NegotiatedFlags = LW_LTOH32(pChlngMsg->NtlmFlags);
    pOutput->cbBuffer = dwMessageSize;
    pOutput->BufferType = SECBUFFER_TOKEN;
    pOutput->pvBuffer = pMessage;
    pNtlmContext->NtlmState = NtlmStateResponse;
    pNtlmContext->bInitiatedSide = TRUE;
    pNtlmContext->bDoAnonymous = bDoAnonymous;

    dwError = NtlmInitializeKeys(pNtlmContext);
    BAIL_ON_LSA_ERROR(dwError);

cleanup:
    if (pUserNameInfo)
    {
        LsaSrvFreeNameInfo(pUserNameInfo);
    }

    *ppNtlmContext = pNtlmContext;

    return dwError;
error:
    LW_SAFE_FREE_MEMORY(pMessage);
    if (pNtlmContext)
    {
        NtlmFreeContext(&pNtlmContext);
    }
    pOutput->cbBuffer = 0;
    pOutput->BufferType = 0;
    pOutput->pvBuffer = NULL;

    goto cleanup;
}
Esempio n. 3
0
DWORD
NtlmCreateGuestContext(
    OUT PNTLM_CONTEXT *ppNtlmContext
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    PNTLM_CONTEXT pNtlmContext = NULL;
    HANDLE hConnection = (HANDLE)NULL;
    LSA_QUERY_LIST queryList = {0};
    PLSA_SECURITY_OBJECT* ppObjects = NULL;
    PSTR pszGuestSid = NULL;

    *ppNtlmContext = NULL;

    dwError = NtlmCreateContext(NULL, &pNtlmContext);
    BAIL_ON_LSA_ERROR(dwError);

    pNtlmContext->NtlmState = NtlmStateResponse;

    // Set the NegotiatedFlags to 0 since there's the resulting
    // context has no direct relation to the original user authentication
    // request and no session key.  This may change with future
    // investigation.

    pNtlmContext->NegotiatedFlags = 0;

    // Verify that the local Guest account has been enabled

    dwError = LsaSrvOpenServer(0, 0, getpid(), &hConnection);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = NtlmGetLocalGuestAccountSid(&pszGuestSid);
    BAIL_ON_LSA_ERROR(dwError);

    queryList.ppszStrings = (PCSTR*)&pszGuestSid;

    dwError = LsaSrvFindObjects(
                  hConnection,
                  LSA_PROVIDER_TAG_LOCAL,
                  0,
                  LSA_OBJECT_TYPE_USER,
                  LSA_QUERY_TYPE_BY_SID,
                  1,
                  queryList,
                  &ppObjects);
    BAIL_ON_LSA_ERROR(dwError);

    if (!ppObjects[0])
    {
        dwError = LW_ERROR_NO_SUCH_USER;
        BAIL_ON_LSA_ERROR(dwError);
    }

    if (ppObjects[0]->userInfo.bAccountDisabled)
    {
        dwError = LW_ERROR_ACCOUNT_DISABLED;
        BAIL_ON_LSA_ERROR(dwError);
    }

    dwError = LwAllocateStringPrintf(
                  &pNtlmContext->pszClientUsername,
                  "%s\\%s",
                  ppObjects[0]->pszNetbiosDomainName,
                  ppObjects[0]->pszSamAccountName);
 
    // NULL session key
    memset(pNtlmContext->SessionKey, 0x0, NTLM_SESSION_KEY_SIZE);
    pNtlmContext->cbSessionKeyLen = NTLM_SESSION_KEY_SIZE;
    pNtlmContext->bInitiatedSide = FALSE;
    pNtlmContext->MappedToGuest = TRUE;

cleanup:

    LsaUtilFreeSecurityObjectList(1, ppObjects);

    if (hConnection)
    {
        LsaSrvCloseServer(hConnection);
    }

    LW_SAFE_FREE_STRING(pszGuestSid);

    *ppNtlmContext = pNtlmContext;

    return dwError;

error:

    if (pNtlmContext)
    {
        NtlmFreeContext(&pNtlmContext);
    }
    goto cleanup;
}
Esempio n. 4
0
DWORD
NtlmCreateNegotiateContext(
    IN NTLM_CRED_HANDLE hCred,
    IN DWORD fContextReq,
    IN PCSTR pDomain,
    IN PCSTR pWorkstation,
    IN PBYTE pOsVersion,
    OUT PNTLM_CONTEXT* ppNtlmContext,
    OUT PSecBuffer pOutput
)
{
    DWORD dwError = LW_ERROR_SUCCESS;
    PNTLM_CONTEXT pNtlmContext = NULL;
    DWORD dwMessageSize = 0;
    PNTLM_NEGOTIATE_MESSAGE_V1 pMessage = NULL;
    NTLM_CONFIG config;
    DWORD dwDefaultOptions =
        // Always do signing and sealing since they cannot be turned off on
        // Windows
        NTLM_FLAG_SIGN                  |
        NTLM_FLAG_SEAL                  |
        NTLM_FLAG_OEM                   |
        NTLM_FLAG_REQUEST_TARGET        |
        NTLM_FLAG_NTLM                  |
        NTLM_FLAG_DOMAIN                |
        0;
    DWORD dwDceStyleOptions =
        NTLM_FLAG_OEM                   |
        NTLM_FLAG_REQUEST_TARGET        |
        NTLM_FLAG_NTLM                  |
        NTLM_FLAG_DOMAIN                |
        0;
    DWORD dwOptions = 0;

    *ppNtlmContext = NULL;

    dwError = NtlmCreateContext(hCred, &pNtlmContext);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = NtlmReadRegistry(&config);
    BAIL_ON_LSA_ERROR(dwError);

    if (fContextReq & ISC_REQ_USE_DCE_STYLE)
    {
        dwOptions = dwDceStyleOptions;
    }
    else
    {
        dwOptions = dwDefaultOptions;
    }

    if (config.bSupportUnicode)
    {
        dwOptions |= NTLM_FLAG_UNICODE;
    }
    if (config.bSupportNTLM2SessionSecurity)
    {
        dwOptions |= NTLM_FLAG_NTLM2;
    }
    if (config.bSupportKeyExchange)
    {
        dwOptions |= NTLM_FLAG_KEY_EXCH;
    }
    if (config.bSupport56bit)
    {
        dwOptions |= NTLM_FLAG_56;
    }
    if (config.bSupport128bit)
    {
        dwOptions |= NTLM_FLAG_128;
    }

    if (fContextReq & ISC_REQ_INTEGRITY)
    {
        dwOptions |= NTLM_FLAG_SIGN;
    }

    if (fContextReq & ISC_REQ_CONFIDENTIALITY)
    {
        dwOptions |= NTLM_FLAG_SEAL;
    }

    if (fContextReq & ISC_REQ_NULL_SESSION)
    {
        pNtlmContext->bDoAnonymous = TRUE;
    }

    dwError = NtlmCreateNegotiateMessage(
                  dwOptions,
                  pDomain,
                  pWorkstation,
                  pOsVersion,
                  &dwMessageSize,
                  &pMessage);
    BAIL_ON_LSA_ERROR(dwError);

    pOutput->cbBuffer = dwMessageSize;
    pOutput->BufferType = SECBUFFER_TOKEN;
    pOutput->pvBuffer = pMessage;
    pNtlmContext->NtlmState = NtlmStateNegotiate;

cleanup:

    *ppNtlmContext = pNtlmContext;

    return dwError;

error:
    LW_SAFE_FREE_MEMORY(pMessage);
    pOutput->cbBuffer = 0;
    pOutput->BufferType = 0;
    pOutput->pvBuffer = NULL;
    if (pNtlmContext)
    {
        NtlmFreeContext(&pNtlmContext);
    }
    goto cleanup;
}