/// <summary>Calculates the effective user session key.</summary> /// <remarks>Calculates the effective user session key.</remarks> /// <param name="challenge">The server challenge.</param> /// <param name="dest"> /// The destination array in which the user session key will be /// placed. /// </param> /// <param name="offset"> /// The offset in the destination array at which the /// session key will start. /// </param> /// <exception cref="SharpCifs.Smb.SmbException"></exception> internal void GetUserSessionKey(byte[] challenge, byte[] dest, int offset) { if (HashesExternal) { return; } try { Md4 md4 = new Md4(); md4.Update(Runtime.GetBytesForString(Password, SmbConstants.UniEncoding) ); switch (LmCompatibility) { case 0: case 1: case 2: { md4.Update(md4.Digest()); md4.Digest(dest, offset, 16); break; } case 3: case 4: case 5: { if (ClientChallenge == null) { ClientChallenge = new byte[8]; Random.NextBytes(ClientChallenge); } Hmact64 hmac = new Hmact64(md4.Digest()); hmac.Update(Runtime.GetBytesForString(Username.ToUpper(), SmbConstants.UniEncoding )); hmac.Update(Runtime.GetBytesForString(Domain.ToUpper(), SmbConstants.UniEncoding )); byte[] ntlmv2Hash = hmac.Digest(); hmac = new Hmact64(ntlmv2Hash); hmac.Update(challenge); hmac.Update(ClientChallenge); Hmact64 userKey = new Hmact64(ntlmv2Hash); userKey.Update(hmac.Digest()); userKey.Digest(dest, offset, 16); break; } default: { md4.Update(md4.Digest()); md4.Digest(dest, offset, 16); break; } } } catch (Exception e) { throw new SmbException(string.Empty, e); } }
public static byte[] NtowFv2(string domain, string username, string password) { try { Md4 md4 = new Md4(); md4.Update(Runtime.GetBytesForString(password, SmbConstants.UniEncoding) ); Hmact64 hmac = new Hmact64(md4.Digest()); hmac.Update(Runtime.GetBytesForString(username.ToUpper(), SmbConstants.UniEncoding )); hmac.Update(Runtime.GetBytesForString(domain, SmbConstants.UniEncoding)); return hmac.Digest(); } catch (UnsupportedEncodingException uee) { throw new RuntimeException(uee.Message); } }
public static byte[] NtowFv1(string password) { if (password == null) { throw new RuntimeException("Password parameter is required"); } try { Md4 md4 = new Md4(); md4.Update(Runtime.GetBytesForString(password, SmbConstants.UniEncoding) ); return md4.Digest(); } catch (UnsupportedEncodingException uee) { throw new RuntimeException(uee.Message); } }
/// <summary>Creates the LMv2 response for the supplied information.</summary> /// <remarks>Creates the LMv2 response for the supplied information.</remarks> /// <param name="domain">The domain in which the username exists.</param> /// <param name="user">The username.</param> /// <param name="password">The user's password.</param> /// <param name="challenge">The server challenge.</param> /// <param name="clientChallenge">The client challenge (nonce).</param> public static byte[] GetLMv2Response(string domain, string user, string password, byte[] challenge, byte[] clientChallenge) { try { byte[] hash = new byte[16]; byte[] response = new byte[24]; // The next 2-1/2 lines of this should be placed with nTOWFv1 in place of password Md4 md4 = new Md4(); md4.Update(Runtime.GetBytesForString(password, SmbConstants.UniEncoding) ); Hmact64 hmac = new Hmact64(md4.Digest()); hmac.Update(Runtime.GetBytesForString(user.ToUpper(), SmbConstants.UniEncoding )); hmac.Update(Runtime.GetBytesForString(domain.ToUpper(), SmbConstants.UniEncoding )); hmac = new Hmact64(hmac.Digest()); hmac.Update(challenge); hmac.Update(clientChallenge); hmac.Digest(response, 0, 16); Array.Copy(clientChallenge, 0, response, 16, 8); return response; } catch (Exception ex) { if (_log.Level > 0) { Runtime.PrintStackTrace(ex, _log); } return null; } }
/// <summary>Generate the Unicode MD4 hash for the password associated with these credentials. /// </summary> /// <remarks>Generate the Unicode MD4 hash for the password associated with these credentials. /// </remarks> public static byte[] GetNtlmResponse(string password, byte[] challenge) { byte[] uni = null; byte[] p21 = new byte[21]; byte[] p24 = new byte[24]; try { uni = Runtime.GetBytesForString(password, SmbConstants.UniEncoding); } catch (UnsupportedEncodingException uee) { if (_log.Level > 0) { Runtime.PrintStackTrace(uee, _log); } } Md4 md4 = new Md4(); md4.Update(uni); try { md4.Digest(p21, 0, 16); } catch (Exception ex) { if (_log.Level > 0) { Runtime.PrintStackTrace(ex, _log); } } E(p21, challenge, p24); return p24; }
/// <summary>Creates a Type-3 message in response to the given Type-2 message.</summary> /// <remarks>Creates a Type-3 message in response to the given Type-2 message.</remarks> /// <param name="type2">The Type-2 message which this represents a response to.</param> /// <param name="password">The password to use when constructing the response.</param> /// <param name="domain">The domain in which the user has an account.</param> /// <param name="user">The username for the authenticating user.</param> /// <param name="workstation"> /// The workstation from which authentication is /// taking place. /// </param> public Type3Message(Type2Message type2, string password, string domain, string user , string workstation, int flags) { SetFlags(flags | GetDefaultFlags(type2)); if (workstation == null) { workstation = GetDefaultWorkstation(); } SetWorkstation(workstation); SetDomain(domain); SetUser(user); switch (LmCompatibility) { case 0: case 1: { if ((GetFlags() & NtlmsspNegotiateNtlm2) == 0) { SetLmResponse(GetLMResponse(type2, password)); SetNtResponse(GetNTResponse(type2, password)); } else { // NTLM2 Session Response byte[] clientChallenge = new byte[24]; //RANDOM.NextBytes(clientChallenge); Arrays.Fill(clientChallenge, 8, 24, unchecked((byte)unchecked(0x00))); // NTLMv1 w/ NTLM2 session sec and key exch all been verified with a debug build of smbclient byte[] responseKeyNt = NtlmPasswordAuthentication.NtowFv1(password); byte[] ntlm2Response = NtlmPasswordAuthentication.GetNtlm2Response(responseKeyNt, type2.GetChallenge(), clientChallenge); SetLmResponse(clientChallenge); SetNtResponse(ntlm2Response); if ((GetFlags() & NtlmsspNegotiateSign) == NtlmsspNegotiateSign) { byte[] sessionNonce = new byte[16]; Array.Copy(type2.GetChallenge(), 0, sessionNonce, 0, 8); Array.Copy(clientChallenge, 0, sessionNonce, 8, 8); Md4 md4 = new Md4(); md4.Update(responseKeyNt); byte[] userSessionKey = md4.Digest(); Hmact64 hmac = new Hmact64(userSessionKey); hmac.Update(sessionNonce); byte[] ntlm2SessionKey = hmac.Digest(); if ((GetFlags() & NtlmsspNegotiateKeyExch) != 0) { _masterKey = new byte[16]; //RANDOM.NextBytes(masterKey); byte[] exchangedKey = new byte[16]; Rc4 rc4 = new Rc4(ntlm2SessionKey); rc4.Update(_masterKey, 0, 16, exchangedKey, 0); SetSessionKey(exchangedKey); } else { _masterKey = ntlm2SessionKey; SetSessionKey(_masterKey); } } } break; } case 2: { byte[] nt = GetNTResponse(type2, password); SetLmResponse(nt); SetNtResponse(nt); break; } case 3: case 4: case 5: { byte[] responseKeyNt1 = NtlmPasswordAuthentication.NtowFv2(domain, user, password ); byte[] clientChallenge1 = new byte[8]; //RANDOM.NextBytes(clientChallenge_1); SetLmResponse(GetLMv2Response(type2, domain, user, password, clientChallenge1)); byte[] clientChallenge2 = new byte[8]; //RANDOM.NextBytes(clientChallenge2); SetNtResponse(GetNtlMv2Response(type2, responseKeyNt1, clientChallenge2)); if ((GetFlags() & NtlmsspNegotiateSign) == NtlmsspNegotiateSign) { Hmact64 hmac = new Hmact64(responseKeyNt1); hmac.Update(_ntResponse, 0, 16); // only first 16 bytes of ntResponse byte[] userSessionKey = hmac.Digest(); if ((GetFlags() & NtlmsspNegotiateKeyExch) != 0) { _masterKey = new byte[16]; //RANDOM.NextBytes(masterKey); byte[] exchangedKey = new byte[16]; Rc4 rc4 = new Rc4(userSessionKey); rc4.Update(_masterKey, 0, 16, exchangedKey, 0); SetSessionKey(exchangedKey); } else { _masterKey = userSessionKey; SetSessionKey(_masterKey); } } break; } default: { SetLmResponse(GetLMResponse(type2, password)); SetNtResponse(GetNTResponse(type2, password)); break; } } }