public Authorization Authenticate (string challenge, WebRequest webRequest, ICredentials credentials) { HttpWebRequest request = webRequest as HttpWebRequest; if (request == null) return null; NetworkCredential cred = credentials.GetCredential (request.RequestUri, "NTLM"); if (cred == null) return null; string userName = cred.UserName; string domain = cred.Domain; string password = cred.Password; if (userName == null || userName == "") return null; domain = domain != null && domain.Length > 0 ? domain : request.Headers ["Host"]; bool completed = false; if (message == null) { Type1Message type1 = new Type1Message (); type1.Domain = domain; message = type1; } else if (message.Type == 1) { // Should I check the credentials? if (challenge == null) { message = null; return null; } Type2Message type2 = new Type2Message (Convert.FromBase64String (challenge)); if (password == null) password = ""; Type3Message type3 = new Type3Message (); type3.Domain = domain; type3.Username = userName; type3.Challenge = type2.Nonce; type3.Password = password; message = type3; completed = true; } else { // Should I check the credentials? // type must be 3 here if (challenge == null || challenge == String.Empty) { Type1Message type1 = new Type1Message (); type1.Domain = domain; message = type1; } else { completed = true; } } string token = "NTLM " + Convert.ToBase64String (message.GetBytes ()); return new Authorization (token, completed); }
// Example for a password smaller than 8 characters - which implies a weak DES key public void SmallPassword () { Type3Message msg = new Type3Message (); msg.Challenge = new byte [8] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; msg.Domain = "DOMAIN"; msg.Host = "HOST"; msg.Password = "******"; msg.Username = "******"; Assert.AreEqual (3, msg.Type, "Type"); Assert.AreEqual ("4E-54-4C-4D-53-53-50-00-03-00-00-00-18-00-18-00-64-00-00-00-18-00-18-00-7C-00-00-00-0C-00-0C-00-40-00-00-00-10-00-10-00-4C-00-00-00-08-00-08-00-5C-00-00-00-00-00-00-00-94-00-00-00-01-B2-00-00-44-00-4F-00-4D-00-41-00-49-00-4E-00-75-00-73-00-65-00-72-00-6E-00-61-00-6D-00-65-00-48-00-4F-00-53-00-54-00-CA-12-00-72-3C-41-D5-77-AB-18-C7-64-C6-DE-F3-4F-A6-1B-FA-06-71-EA-5F-C8-7A-CE-90-85-AB-CC-37-59-38-0B-1C-68-62-E3-98-C3-C0-EF-9C-FC-22-E8-A2-C2", BitConverter.ToString (msg.GetBytes ()), "GetBytes"); }
// Example from http://www.innovation.ch/java/ntlm.html public void Encode1 () { Type3Message msg = new Type3Message (); msg.Challenge = nonce; msg.Domain = "Ursa-Minor"; msg.Host = "LightCity"; msg.Password = "******"; msg.Username = "******"; AssertEquals ("Type", 3, msg.Type); AssertEquals ("GetBytes", "4E-54-4C-4D-53-53-50-00-03-00-00-00-18-00-18-00-72-00-00-00-18-00-18-00-8A-00-00-00-14-00-14-00-40-00-00-00-0C-00-0C-00-54-00-00-00-12-00-12-00-60-00-00-00-00-00-00-00-A2-00-00-00-01-B2-00-00-55-00-52-00-53-00-41-00-2D-00-4D-00-49-00-4E-00-4F-00-52-00-5A-00-61-00-70-00-68-00-6F-00-64-00-4C-00-49-00-47-00-48-00-54-00-43-00-49-00-54-00-59-00-AD-87-CA-6D-EF-E3-46-85-B9-C4-3C-47-7A-8C-42-D6-00-66-7D-68-92-E7-E8-97-E0-E0-0D-E3-10-4A-1B-F2-05-3F-07-C7-DD-A8-2D-3C-48-9A-E9-89-E1-B0-00-D3", BitConverter.ToString (msg.GetBytes ())); }
// Example from http://davenport.sourceforge.net/ntlm.html#type3MessageExample public void Decode2 () { Type3Message msg = new Type3Message (data2); Assert.AreEqual ("DOMAIN", msg.Domain, "Domain"); Assert.AreEqual ("WORKSTATION", msg.Host, "Host"); Assert.AreEqual ("user", msg.Username, "Username"); Assert.AreEqual ((NtlmFlags)0x201, msg.Flags, "Flags"); Assert.AreEqual (3, msg.Type, "Type"); Assert.IsNull (msg.Password, "Password"); Assert.AreEqual ("C3-37-CD-5C-BD-44-FC-97-82-A6-67-AF-6D-42-7C-6D-E6-7C-20-C2-D3-E7-7C-56", BitConverter.ToString (msg.LM), "LM"); Assert.AreEqual ("25-A9-8C-1C-31-E8-18-47-46-6B-29-B2-DF-46-80-F3-99-58-FB-8C-21-3A-9C-C6", BitConverter.ToString (msg.NT), "NT"); }
// Example from http://www.innovation.ch/java/ntlm.html public void Decode1 () { Type3Message msg = new Type3Message (data1); Assert.AreEqual ("URSA-MINOR", msg.Domain, "Domain"); Assert.AreEqual ("LIGHTCITY", msg.Host, "Host"); Assert.AreEqual ("Zaphod", msg.Username, "Username"); Assert.AreEqual ((NtlmFlags)0x8201, msg.Flags, "Flags"); Assert.AreEqual (3, msg.Type, "Type"); Assert.IsNull (msg.Password, "Password"); Assert.AreEqual ("AD-87-CA-6D-EF-E3-46-85-B9-C4-3C-47-7A-8C-42-D6-00-66-7D-68-92-E7-E8-97", BitConverter.ToString (msg.LM), "LM"); Assert.AreEqual ("E0-E0-0D-E3-10-4A-1B-F2-05-3F-07-C7-DD-A8-2D-3C-48-9A-E9-89-E1-B0-00-D3", BitConverter.ToString (msg.NT), "NT"); }
// Example from http://www.innovation.ch/java/ntlm.html public void Encode1 () { Type3Message msg = new Type3Message (); msg.Challenge = nonce; // Type3Message now encodes domain and host case-sensitive. msg.Domain = "URSA-MINOR"; msg.Host = "LIGHTCITY"; msg.Password = "******"; msg.Username = "******"; Assert.AreEqual (3, msg.Type, "Type"); Assert.AreEqual ("4E-54-4C-4D-53-53-50-00-03-00-00-00-18-00-18-00-72-00-00-00-18-00-18-00-8A-00-00-00-14-00-14-00-40-00-00-00-0C-00-0C-00-54-00-00-00-12-00-12-00-60-00-00-00-00-00-00-00-A2-00-00-00-01-B2-00-00-55-00-52-00-53-00-41-00-2D-00-4D-00-49-00-4E-00-4F-00-52-00-5A-00-61-00-70-00-68-00-6F-00-64-00-4C-00-49-00-47-00-48-00-54-00-43-00-49-00-54-00-59-00-AD-87-CA-6D-EF-E3-46-85-B9-C4-3C-47-7A-8C-42-D6-00-66-7D-68-92-E7-E8-97-E0-E0-0D-E3-10-4A-1B-F2-05-3F-07-C7-DD-A8-2D-3C-48-9A-E9-89-E1-B0-00-D3", BitConverter.ToString (msg.GetBytes ()), "GetBytes"); }
// Example from http://www.innovation.ch/java/ntlm.html public void Decode1 () { Type3Message msg = new Type3Message (data1); AssertEquals ("Domain", "URSA-MINOR", msg.Domain); AssertEquals ("Host", "LIGHTCITY", msg.Host); AssertEquals ("Username", "Zaphod", msg.Username); AssertEquals ("Flags", (NtlmFlags)0x8201, msg.Flags); AssertEquals ("Type", 3, msg.Type); AssertNull ("Password", msg.Password); AssertEquals ("LM", "AD-87-CA-6D-EF-E3-46-85-B9-C4-3C-47-7A-8C-42-D6-00-66-7D-68-92-E7-E8-97", BitConverter.ToString (msg.LM)); AssertEquals ("NT", "E0-E0-0D-E3-10-4A-1B-F2-05-3F-07-C7-DD-A8-2D-3C-48-9A-E9-89-E1-B0-00-D3", BitConverter.ToString (msg.NT)); }
// Example from http://davenport.sourceforge.net/ntlm.html#type3MessageExample public void Decode2 () { Type3Message msg = new Type3Message (data2); AssertEquals ("Domain", "DOMAIN", msg.Domain); AssertEquals ("Host", "WORKSTATION", msg.Host); AssertEquals ("Username", "user", msg.Username); AssertEquals ("Flags", (NtlmFlags)0x201, msg.Flags); AssertEquals ("Type", 3, msg.Type); AssertNull ("Password", msg.Password); AssertEquals ("LM", "C3-37-CD-5C-BD-44-FC-97-82-A6-67-AF-6D-42-7C-6D-E6-7C-20-C2-D3-E7-7C-56", BitConverter.ToString (msg.LM)); AssertEquals ("NT", "25-A9-8C-1C-31-E8-18-47-46-6B-29-B2-DF-46-80-F3-99-58-FB-8C-21-3A-9C-C6", BitConverter.ToString (msg.NT)); }
public void Run(string username, string password) { Console.WriteLine ("========="); helper.StandardInput.WriteLine ("SF NTLMSSP_FEATURE_SESSION_KEY"); var sf_response = helper.StandardOutput.ReadLine (); Console.WriteLine (sf_response); if (sf_response != "OK") throw new InvalidDataException (sf_response); var pw_bytes = Encoding.ASCII.GetBytes (password); helper.StandardInput.WriteLine ("PW " + Convert.ToBase64String (pw_bytes)); var pw_result = helper.StandardOutput.ReadLine (); if (pw_result != "OK") throw new InvalidDataException (pw_result); var type1 = new Type1Message (); type1.Flags |= NtlmFlags.NegotiateNtlm2Key; helper.StandardInput.WriteLine ("KK " + Convert.ToBase64String (type1.GetBytes ())); var type1_res = helper.StandardOutput.ReadLine (); if (!type1_res.StartsWith ("TT ")) throw new InvalidDataException (); var type2 = new Type2Message (Convert.FromBase64String (type1_res.Substring (3))); Console.WriteLine ("TYPE2: {0:x} {1}", type2.Flags, type2.Flags); var type3 = new Type3Message (type2); type3.Domain = "SOL"; type3.Host = "PROVCON-FAUST"; type3.Username = username; type3.Password = password; var bytes = type3.GetBytes (); helper.StandardInput.WriteLine ("KK {0}", Convert.ToBase64String (bytes)); var response2 = helper.StandardOutput.ReadLine (); Console.WriteLine (response2); if (!response2.StartsWith ("AF ")) throw new InvalidDataException (response2); }
static void Dump(Type2Message type2, Type3Message type3, out long timestamp, out byte[] nonce, out byte[] namesBlob) { Console.WriteLine (); Console.WriteLine ("DUMP:"); Console.WriteLine ("====="); var ntlm_hash = ChallengeResponse2.Compute_NTLM_Password ("yeknom"); Utils.HexDump ("NTLM HASH", ntlm_hash); var ubytes = Encoding.Unicode.GetBytes ("TEST"); var tbytes = Encoding.Unicode.GetBytes ("PROVCON-FAUST"); var bytes = new byte [ubytes.Length + tbytes.Length]; ubytes.CopyTo (bytes, 0); Array.Copy (tbytes, 0, bytes, ubytes.Length, tbytes.Length); var md5 = new HMACMD5 (ntlm_hash); var ntlmv2_hash = md5.ComputeHash (bytes); Utils.HexDump ("NTLM V2 HASH", ntlmv2_hash); var ntlmv2_md5 = new HMACMD5 (ntlmv2_hash); Utils.HexDump (type3.NT); var br = new BinaryReader (new MemoryStream (type3.NT)); var hash = br.ReadBytes (16); Utils.HexDump (hash); if (br.ReadInt32 () != 0x0101) throw new InvalidDataException (); if (br.ReadInt32 () != 0) throw new InvalidDataException (); timestamp = br.ReadInt64 (); var ticks = timestamp + 504911232000000000; Console.WriteLine ("TIMESTAMP: {0} {1}", timestamp, new DateTime (ticks)); nonce = br.ReadBytes (8); Utils.HexDump ("NONCE", nonce); br.ReadInt32 (); var pos = br.BaseStream.Position; while (true) { var type = br.ReadInt16 (); var length = br.ReadInt16 (); Console.WriteLine ("NAMES BLOB: {0:x} {1:x}", type, length); if (type == 0) break; var contents = br.ReadBytes (length); Utils.HexDump (contents); } namesBlob = new byte [br.BaseStream.Position - pos]; Array.Copy (type3.NT, pos, namesBlob, 0, namesBlob.Length); var blob = new byte [type3.NT.Length - 16]; Array.Copy (type3.NT, 16, blob, 0, blob.Length); Utils.HexDump ("TYPE 2 CHALLENGE", type2.Nonce); var buffer = new byte [type2.Nonce.Length + blob.Length]; type2.Nonce.CopyTo (buffer, 0); blob.CopyTo (buffer, type2.Nonce.Length); Utils.HexDump (blob); var test = ntlmv2_md5.ComputeHash (buffer); Utils.HexDump ("THE HASH", test); var ok = Utils.Compare (hash, test); Console.WriteLine (ok); Console.WriteLine (); Console.WriteLine ("=========="); Console.WriteLine (); }
static void Decode_Type3(string text) { var bytes = Convert.FromBase64String (text); HexDump (bytes); var message = new Type3Message (bytes); Console.WriteLine ("TYPE 3: {0:x} {1:x}", message.Type, message.Flags); HexDump ("LM", message.LM); HexDump ("LT", message.NT); }
public void ProcessMessageType3 (byte [] raw) { /* MemoryStream ms = new MemoryStream (raw); if (!Verify (NtlmSSP, raw, 0, 8)) throw new SecurityNegotiationException ("Expected NTLM SSPI header not found"); BinaryReader reader = new BinaryReader (ms); reader.ReadInt64 (); // skip 8 bytes if (reader.ReadInt32 () != 3) throw new SecurityNegotiationException ("SSPI type 3 message is expected"); SspiSecurityBufferStruct lmResInfo = ReadSecurityBuffer (reader); SspiSecurityBufferStruct ntlmResInfo = ReadSecurityBuffer (reader); SspiSecurityBufferStruct targetNameInfo = ReadSecurityBuffer (reader); SspiSecurityBufferStruct userNameInfo = ReadSecurityBuffer (reader); SspiSecurityBufferStruct wsNameInfo = ReadSecurityBuffer (reader); SspiSecurityBufferStruct sessionKeyInfo = ReadSecurityBuffer (reader); int flags = reader.ReadInt32 (); ServerOSVersion = reader.ReadInt64 (); */ type3 = new Type3Message (raw, NtlmVersion.Version3); }
public void Decode_Null () { Type3Message msg = new Type3Message ((byte[])null); }
public void BadType3Message () { byte[] bad = (byte[]) data1.Clone (); bad [56] = 0x00; bad [57] = 0x00; Type3Message msg = new Type3Message (bad); }
protected internal int ProcessAuthentication () { int pdu_size = Comm.GetTdsShort (); byte[] msg2 = Comm.GetBytes (pdu_size, true); Type2Message t2 = new Type2Message (msg2); // 0x0001 Negotiate Unicode // 0x0200 Negotiate NTLM // 0x8000 Negotiate Always Sign Type3Message t3 = new Type3Message (t2); t3.Domain = this.connectionParms.DefaultDomain; t3.Host = this.connectionParms.Hostname; t3.Username = this.connectionParms.User; t3.Password = GetPlainPassword(this.connectionParms.Password); Comm.StartPacket (TdsPacketType.SspAuth); // 0x11 Comm.Append (t3.GetBytes ()); try { Comm.SendPacket (); } catch (IOException ex) { connected = false; throw new TdsInternalException ("Server closed the connection.", ex); } return 1; // TDS_SUCCEED }
protected internal int ProcessAuthentication () { int pdu_size = Comm.GetTdsShort (); byte[] msg2 = Comm.GetBytes (pdu_size, true); Type2Message t2 = new Type2Message (msg2); // 0x0001 Negotiate Unicode // 0x0200 Negotiate NTLM // 0x8000 Negotiate Always Sign Type3Message t3 = new Type3Message (); t3.Challenge = t2.Nonce; t3.Domain = this.connectionParms.DefaultDomain; t3.Host = this.connectionParms.Hostname; t3.Username = this.connectionParms.User; t3.Password = this.connectionParms.Password; Comm.StartPacket (TdsPacketType.SspAuth); // 0x11 Comm.Append (t3.GetBytes ()); Comm.SendPacket (); return 1; // TDS_SUCCEED }
public void Challenge () { Type3Message msg = new Type3Message (); Assert.IsNull (msg.Challenge, "Challenge"); byte[] c = new byte [8]; msg.Challenge = c; Assert.AreEqual (8, msg.Challenge.Length, "Challenge.Length"); c [0] = 1; Assert.AreEqual (0, msg.Challenge [0], "Challenge not directly accessible"); }
public void Decode_BadHeader () { byte[] header = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x01, 0x00, 0x00, 0x00, 0x00 }; Type3Message msg = new Type3Message (header); }
public byte [] ProcessMessageType3 (string user, string password) { TargetName = Environment.MachineName; ServerName = Environment.MachineName; // FIXME DomainName = ServerName;// IPGlobalProperties.GetIPGlobalProperties ().DomainName; DnsHostName = Dns.GetHostName (); DnsDomainName = DnsHostName; // FIXME type3 = new Type3Message (NtlmVersion.Version3); type3.Flags = (NtlmFlags) (unchecked ((int) 0xE2188235)); type3.Domain = DomainName; type3.Host = DnsHostName; type3.Challenge = type2.Nonce; type3.Username = user; type3.Password = password; return type3.GetBytes (); }
public void Decode_MinimalValidLength () { Type3Message msg = new Type3Message (new byte [8]); }
public void Challenge () { Type3Message msg = new Type3Message (); AssertNull ("Challenge", msg.Challenge); byte[] c = new byte [8]; msg.Challenge = c; AssertEquals ("Challenge.Length", 8, msg.Challenge.Length); c [0] = 1; AssertEquals ("Challenge not directly accessible", 0, msg.Challenge [0]); }
static void Compute_Type3(Type2Message type2) { Type3Message type3 = new Type3Message (); type3.Domain = ""; type3.Host = "PROVCON-FAUST"; type3.Username = "******"; type3.Challenge = type2.Nonce; type3.Password = "******"; HexDump ("CHALLENGE", type2.Nonce); var bytes = type3.GetBytes (); var message = new Type3Message (bytes); HexDump ("LM", message.LM); HexDump ("NT", message.NT); }
public void Challenge_Null () { Type3Message msg = new Type3Message (); msg.Challenge = null; }
public Authorization Authenticate(string challenge, WebRequest request, ICredentials credentials) { if (!challenge.StartsWith ("NTLM")) return null; Console.WriteLine ("AUTHENTICATE: {0} {1}", challenge, request); pipe.StandardInput.WriteLine ("TT{0}", challenge.Substring (4)); var result = pipe.StandardOutput.ReadLine (); Console.WriteLine (result); if (result.StartsWith ("YR ")) return ntlm.Authenticate (challenge, request, credentials); if (!result.StartsWith ("AF ")) return null; var t2_bytes = Convert.FromBase64String (challenge.Substring (5)); var type2 = new Type2Message (t2_bytes); Utils.HexDump (t2_bytes); Console.WriteLine ("TYPE2: {0}", type2.TargetName); var bytes = Convert.FromBase64String (result.Substring (3)); var type3 = new Type3Message (bytes); long timestamp; byte[] nonce, namesBlob; Dump (type2, type3, out timestamp, out nonce, out namesBlob); byte[] nt = ChallengeResponse2.Compute_NTLMv2 ( type2, "test", "yeknom", timestamp, nonce); var ok = Utils.Compare (type3.NT, nt); Console.WriteLine ("COMPARE: {0} - {1:x}", ok, type3.Flags); type3.NT = nt; // Dump (type2, type3); type3.Flags = (NtlmFlags)0x00088201; var bytes2 = type3.GetBytes2 (); var auth = ntlm.Authenticate (challenge, request, credentials); Console.WriteLine (auth.Message); var bytes3 = Convert.FromBase64String (auth.Message.Substring (5)); var test = new Type3Message (bytes3); Console.WriteLine ("TEST: {0:x} - {1} {2}", test.Flags, bytes2.Length, bytes3.Length); Console.WriteLine ("TEST #1: {0} {1} {2} - {3} {4} {5}", type3.Host, type3.Domain, type3.Username, test.Host, test.Domain, test.Username); Console.WriteLine ("TEST #2: {0} {1} {2}", test.LM != null, test.NT.Length, type3.NT.Length); // test.NT = type3.NT; // test.Host = type3.Host; test.Domain = type3.Domain; // test.Flags = type3.Flags; var bytes4 = test.GetBytes2 (); // Utils.HexDump (bytes); // Utils.HexDump (bytes2); // Utils.Compare (bytes2, bytes3); // auth = new Authorization ("NTLM " + Convert.ToBase64String (bytes4)); Console.WriteLine (auth.Message); return auth; }
public void Challenge_InvalidLength () { Type3Message msg = new Type3Message (); msg.Challenge = new byte [9]; }
public Authorization Authenticate (string challenge, WebRequest webRequest, ICredentials credentials) { HttpWebRequest request = webRequest as HttpWebRequest; if (request == null) return null; NetworkCredential cred = credentials.GetCredential (request.RequestUri, "NTLM"); if (cred == null) return null; string userName = cred.UserName; string domain = cred.Domain; string password = cred.Password; if (userName == null || userName == "") return null; if (String.IsNullOrEmpty (domain)) { int idx = userName.IndexOf ('\\'); if (idx == -1) { idx = userName.IndexOf ('/'); } if (idx >= 0) { domain = userName.Substring (0, idx); userName = userName.Substring (idx + 1); } } bool completed = false; if (message == null) { Type1Message type1 = new Type1Message (); type1.Domain = domain; type1.Host = ""; // MS does not send it type1.Flags |= NtlmFlags.NegotiateNtlm2Key; message = type1; } else if (message.Type == 1) { // Should I check the credentials? if (challenge == null) { message = null; return null; } Type2Message type2 = new Type2Message (Convert.FromBase64String (challenge)); if (password == null) password = ""; Type3Message type3 = new Type3Message (type2); type3.Username = userName; type3.Password = password; type3.Domain = domain; message = type3; completed = true; } else { // Should I check the credentials? // type must be 3 here if (challenge == null || challenge == String.Empty) { Type1Message type1 = new Type1Message (); type1.Domain = domain; type1.Host = ""; // MS does not send it message = type1; } else { completed = true; } } string token = "NTLM " + Convert.ToBase64String (message.GetBytes ()); return new Authorization (token, completed); }
protected override SaslExchangeStatus Exchange(ByteString serverChallenge, out ByteString clientResponse) { if (Credential == null) throw new SaslException("Credential property must be set"); clientResponse = null; switch (step) { case 0: { // send NTLM negotiate message (Type 1) const NtlmFlags type1Flags = NtlmFlags.RequestTarget | NtlmFlags.NegotiateNtlm | NtlmFlags.NegotiateUnicode | NtlmFlags.NegotiateOem | NtlmFlags.NegotiateDomainSupplied | NtlmFlags.NegotiateWorkstationSupplied; var type1 = new Type1Message(); type1.Flags = type1Flags; type1.Host = TargetHost ?? string.Empty; // ? type1.Domain = Credential.Domain ?? string.Empty; clientResponse = new ByteString(type1.GetBytes()); step++; return SaslExchangeStatus.Continuing; } case 1: { // receive NTLM challenge message (Type 2) and send NTLM authenticate message (Type 3) if (string.IsNullOrEmpty(Credential.UserName) || string.IsNullOrEmpty(Credential.Password)) return SaslExchangeStatus.Failed; var type2 = new Type2Message(serverChallenge.ByteArray); var type3 = new Type3Message(); type3.Flags = NtlmFlags.NegotiateNtlm | NtlmFlags.NegotiateUnicode; // XXX type3.Host = TargetHost ?? string.Empty; // ? type3.Domain = Credential.Domain ?? string.Empty; type3.Challenge = type2.Nonce; type3.Password = Credential.Password; type3.Username = Credential.UserName; clientResponse = new ByteString(type3.GetBytes()); step++; return SaslExchangeStatus.Succeeded; } default: clientResponse = null; return SaslExchangeStatus.Failed; // unexpected server challenge } }