Esempio n. 1
0
bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx,
			   const char *user, const char *domain, const uint8_t nt_hash[16],
			   const DATA_BLOB *server_chal,
			   const DATA_BLOB *names_blob,
			   DATA_BLOB *lm_response, DATA_BLOB *nt_response,
			   DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key)
{
	uint8_t ntlm_v2_hash[16];

	/* We don't use the NT# directly.  Instead we use it mashed up with
	   the username and domain.
	   This prevents username swapping during the auth exchange
	*/
	if (!ntv2_owf_gen(nt_hash, user, domain, ntlm_v2_hash)) {
		return false;
	}

	if (nt_response) {
		*nt_response = NTLMv2_generate_response(mem_ctx,
							ntlm_v2_hash, server_chal,
							names_blob);
		if (user_session_key) {
			*user_session_key = data_blob_talloc(mem_ctx, NULL, 16);

			/* The NTLMv2 calculations also provide a session key, for signing etc later */
			/* use only the first 16 bytes of nt_response for session key */
			SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, user_session_key->data);
		}
	}

	/* LMv2 */

	if (lm_response) {
		*lm_response = LMv2_generate_response(mem_ctx,
						      ntlm_v2_hash, server_chal);
		if (lm_session_key) {
			*lm_session_key = data_blob_talloc(mem_ctx, NULL, 16);

			/* The NTLMv2 calculations also provide a session key, for signing etc later */
			/* use only the first 16 bytes of lm_response for session key */
			SMBsesskeygen_ntv2(ntlm_v2_hash, lm_response->data, lm_session_key->data);
		}
	}

	return true;
}
Esempio n. 2
0
/****************************************************************************
 makes lm and nt OWF crypts
 ****************************************************************************/
void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
			 const char *user, const char *server,
			 const char *domain, uchar sess_key[16])
{
	uchar kr[16];

	RPC_DBG_PRINTF(rpc_e_dbg_auth, 10, ("pwd_make_lm_nt_owf2: user %s, srv %s, dom %s\n",
		   user, server, domain));


	SMBgenclientchals(pwd->lm_cli_chal,
			  pwd->nt_cli_chal,
			  &pwd->nt_cli_chal_len, server, domain);

	ntv2_owf_gen(pwd->smb_nt_pwd, user, domain, kr);

	/* lm # */
	SMBOWFencrypt_ntv2(kr,
			   srv_key, 8, pwd->lm_cli_chal, 8, pwd->smb_lm_owf);
	memcpy(&pwd->smb_lm_owf[16], pwd->lm_cli_chal, 8);

	/* nt # */
	SMBOWFencrypt_ntv2(kr,
			   srv_key, 8,
			   pwd->nt_cli_chal, pwd->nt_cli_chal_len,
			   pwd->smb_nt_owf);
	memcpy(&pwd->smb_nt_owf[16], pwd->nt_cli_chal, pwd->nt_cli_chal_len);
	pwd->nt_owf_len = pwd->nt_cli_chal_len + 16;

	SMBsesskeygen_ntv2(kr, pwd->smb_nt_owf, sess_key);

#ifdef DEBUG_PASSWORD
	RPC_DBG_PRINTF(rpc_e_dbg_auth, 20, ("server cryptkey: "));
	dump_data(20, srv_key, 8);

	RPC_DBG_PRINTF(rpc_e_dbg_auth, 20, ("client lmv2 cryptkey: "));
	dump_data(20, pwd->lm_cli_chal, 8);

	RPC_DBG_PRINTF(rpc_e_dbg_auth, 20, ("client ntv2 cryptkey: "));
	dump_data(20, pwd->nt_cli_chal, pwd->nt_cli_chal_len);

	RPC_DBG_PRINTF(rpc_e_dbg_auth, 20, ("ntv2_owf_passwd: "));
	dump_data(20, pwd->smb_nt_owf, pwd->nt_owf_len);
	RPC_DBG_PRINTF(rpc_e_dbg_auth, 20, ("nt_sess_pwd: "));
	dump_data(20, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));

	RPC_DBG_PRINTF(rpc_e_dbg_auth, 20, ("lmv2_owf_passwd: "));
	dump_data(20, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
	RPC_DBG_PRINTF(rpc_e_dbg_auth, 20, ("lm_sess_pwd: "));
	dump_data(20, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));

	RPC_DBG_PRINTF(rpc_e_dbg_auth, 20, ("session key:\n"));
	dump_data(20, sess_key, 16);
#endif
	pwd->crypted = True;

}
Esempio n. 3
0
static bool smb_sess_key_ntlmv2(TALLOC_CTX *mem_ctx,
                                const DATA_BLOB *ntv2_response,
                                const uint8_t *part_passwd,
                                const DATA_BLOB *sec_blob,
                                const char *user, const char *domain,
                                bool upper_case_domain, /* should the domain be transformed into upper case? */
                                DATA_BLOB *user_sess_key)
{
    /* Finish the encryption of part_passwd. */
    uint8_t kr[16];
    uint8_t value_from_encryption[16];
    DATA_BLOB client_key_data;

    if (part_passwd == NULL) {
        DEBUG(10,("No password set - DISALLOWING access\n"));
        /* No password set - always false */
        return false;
    }

    if (sec_blob->length != 8) {
        DEBUG(0, ("smb_sess_key_ntlmv2: incorrect challenge size (%lu)\n",
                  (unsigned long)sec_blob->length));
        return false;
    }

    if (ntv2_response->length < 24) {
        /* We MUST have more than 16 bytes, or the stuff below will go
           crazy.  No known implementation sends less than the 24 bytes
           for LMv2, let alone NTLMv2. */
        DEBUG(0, ("smb_sess_key_ntlmv2: incorrect password length (%lu)\n",
                  (unsigned long)ntv2_response->length));
        return false;
    }

    client_key_data = data_blob_talloc(mem_ctx, ntv2_response->data+16, ntv2_response->length-16);

    if (!ntv2_owf_gen(part_passwd, user, domain, upper_case_domain, kr)) {
        return false;
    }

    SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption);
    *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
    SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data);
    return true;
}
Esempio n. 4
0
BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, 
		      const DATA_BLOB *server_chal, 
		      const DATA_BLOB *names_blob,
		      DATA_BLOB *lm_response, DATA_BLOB *nt_response, 
		      DATA_BLOB *user_session_key) 
{
	uchar nt_hash[16];
	uchar ntlm_v2_hash[16];
	E_md4hash(password, nt_hash);

	/* We don't use the NT# directly.  Instead we use it mashed up with
	   the username and domain.
	   This prevents username swapping during the auth exchange
	*/
	if (!ntv2_owf_gen(nt_hash, user, domain, True, ntlm_v2_hash)) {
		return False;
	}
	
	if (nt_response) {
		*nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal,
							names_blob); 
		if (user_session_key) {
			*user_session_key = data_blob(NULL, 16);
			
			/* The NTLMv2 calculations also provide a session key, for signing etc later */
			/* use only the first 16 bytes of nt_response for session key */
			SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, user_session_key->data);
		}
	}
	
	/* LMv2 */
	
	if (lm_response) {
		*lm_response = LMv2_generate_response(ntlm_v2_hash, server_chal);
	}
	
	return True;
}
Esempio n. 5
0
static bool smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx,
				 const DATA_BLOB *ntv2_response,
				 const uint8_t *part_passwd,
				 const DATA_BLOB *sec_blob,
				 const char *user, const char *domain,
				 DATA_BLOB *user_sess_key)
{
	/* Finish the encryption of part_passwd. */
	uint8_t kr[16];
	uint8_t value_from_encryption[16];
	DATA_BLOB client_key_data;

	if (part_passwd == NULL) {
		DEBUG(10,("No password set - DISALLOWING access\n"));
		/* No password set - always false */
		return false;
	}

	if (sec_blob->length != 8) {
		DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect challenge size (%lu)\n", 
			  (unsigned long)sec_blob->length));
		return false;
	}

	if (ntv2_response->length < 24) {
		/* We MUST have more than 16 bytes, or the stuff below will go
		   crazy.  No known implementation sends less than the 24 bytes
		   for LMv2, let alone NTLMv2. */
		DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%lu)\n", 
			  (unsigned long)ntv2_response->length));
		return false;
	}

	client_key_data = data_blob_talloc(mem_ctx, ntv2_response->data+16, ntv2_response->length-16);
	/* 
	   todo:  should we be checking this for anything?  We can't for LMv2, 
	   but for NTLMv2 it is meant to contain the current time etc.
	*/

	if (!ntv2_owf_gen(part_passwd, user, domain, kr)) {
		return false;
	}

	SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption);

#if DEBUG_PASSWORD
	DEBUG(100,("Part password (P16) was |\n"));
	dump_data(100, part_passwd, 16);
	DEBUGADD(100,("Password from client was |\n"));
	dump_data(100, ntv2_response->data, ntv2_response->length);
	DEBUGADD(100,("Variable data from client was |\n"));
	dump_data(100, client_key_data.data, client_key_data.length);
	DEBUGADD(100,("Given challenge was |\n"));
	dump_data(100, sec_blob->data, sec_blob->length);
	DEBUGADD(100,("Value from encryption was |\n"));
	dump_data(100, value_from_encryption, 16);
#endif
	data_blob_clear_free(&client_key_data);
	if (memcmp(value_from_encryption, ntv2_response->data, 16) == 0) { 
		if (user_sess_key != NULL) {
			*user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
			SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data);
		}
		return true;
	}
	return false;
}
Esempio n. 6
0
static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response,
				 const uchar *part_passwd,
				 const DATA_BLOB *sec_blob,
				 const char *user, const char *domain,
				 BOOL upper_case_domain, /* should the domain be transformed into upper case? */
				 DATA_BLOB *user_sess_key)
{
	/* Finish the encryption of part_passwd. */
	uchar kr[16];
	uchar value_from_encryption[16];
	uchar client_response[16];
	DATA_BLOB client_key_data;
	BOOL res;

	if (part_passwd == NULL) {
		DEBUG(10,("No password set - DISALLOWING access\n"));
		/* No password set - always False */
		return False;
	}

	if (sec_blob->length != 8) {
		DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect challenge size (%lu)\n", 
			  (unsigned long)sec_blob->length));
		return False;
	}
	
	if (ntv2_response->length < 24) {
		/* We MUST have more than 16 bytes, or the stuff below will go
		   crazy.  No known implementation sends less than the 24 bytes
		   for LMv2, let alone NTLMv2. */
		DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%lu)\n", 
			  (unsigned long)ntv2_response->length));
		return False;
	}

	client_key_data = data_blob(ntv2_response->data+16, ntv2_response->length-16);
	/* 
	   todo:  should we be checking this for anything?  We can't for LMv2, 
	   but for NTLMv2 it is meant to contain the current time etc.
	*/

	memcpy(client_response, ntv2_response->data, sizeof(client_response));

	if (!ntv2_owf_gen(part_passwd, user, domain, upper_case_domain, kr)) {
		return False;
	}

	SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption);
	if (user_sess_key != NULL) {
		*user_sess_key = data_blob(NULL, 16);
		SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data);
	}

#if DEBUG_PASSWORD
	DEBUG(100,("Part password (P16) was |\n"));
	dump_data(100, part_passwd, 16);
	DEBUGADD(100,("Password from client was |\n"));
	dump_data(100, ntv2_response->data, ntv2_response->length);
	DEBUGADD(100,("Variable data from client was |\n"));
	dump_data(100, client_key_data.data, client_key_data.length);
	DEBUGADD(100,("Given challenge was |\n"));
	dump_data(100, sec_blob->data, sec_blob->length);
	DEBUGADD(100,("Value from encryption was |\n"));
	dump_data(100, value_from_encryption, 16);
#endif
	data_blob_clear_free(&client_key_data);
	res = (memcmp(value_from_encryption, client_response, 16) == 0);
	if ((!res) && (user_sess_key != NULL))
		data_blob_clear_free(user_sess_key);
	return res;
}