AuthenticateMessage.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Text;
  10. using Utilities;
  11. namespace SMBLibrary.Authentication.NTLM
  12. {
  13. /// <summary>
  14. /// [MS-NLMP] AUTHENTICATE_MESSAGE (Type 3 Message)
  15. /// </summary>
  16. public class AuthenticateMessage
  17. {
  18. public const string ValidSignature = "NTLMSSP\0";
  19. public string Signature; // 8 bytes
  20. public MessageTypeName MessageType;
  21. public byte[] LmChallengeResponse; // 1 byte for anonymous authentication, 24 bytes for NTLM v1, NTLM v1 Extended Session Security and NTLM v2.
  22. public byte[] NtChallengeResponse; // 0 bytes for anonymous authentication, 24 bytes for NTLM v1 and NTLM v1 Extended Session Security, >= 48 bytes for NTLM v2.
  23. public string DomainName;
  24. public string UserName;
  25. public string WorkStation;
  26. public byte[] EncryptedRandomSessionKey;
  27. public NegotiateFlags NegotiateFlags;
  28. public NTLMVersion Version;
  29. // 16-byte MIC field is omitted for Windows NT / 2000 / XP / Server 2003
  30. public AuthenticateMessage()
  31. {
  32. Signature = ValidSignature;
  33. MessageType = MessageTypeName.Authenticate;
  34. DomainName = String.Empty;
  35. UserName = String.Empty;
  36. WorkStation = String.Empty;
  37. EncryptedRandomSessionKey = new byte[0];
  38. }
  39. public AuthenticateMessage(byte[] buffer)
  40. {
  41. Signature = ByteReader.ReadAnsiString(buffer, 0, 8);
  42. MessageType = (MessageTypeName)LittleEndianConverter.ToUInt32(buffer, 8);
  43. LmChallengeResponse = AuthenticationMessageUtils.ReadBufferPointer(buffer, 12);
  44. NtChallengeResponse = AuthenticationMessageUtils.ReadBufferPointer(buffer, 20);
  45. DomainName = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 28);
  46. UserName = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 36);
  47. WorkStation = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 44);
  48. EncryptedRandomSessionKey = AuthenticationMessageUtils.ReadBufferPointer(buffer, 52);
  49. NegotiateFlags = (NegotiateFlags)LittleEndianConverter.ToUInt32(buffer, 60);
  50. if ((NegotiateFlags & NegotiateFlags.Version) > 0)
  51. {
  52. Version = new NTLMVersion(buffer, 64);
  53. }
  54. }
  55. public byte[] GetBytes()
  56. {
  57. if ((NegotiateFlags & NegotiateFlags.KeyExchange) == 0)
  58. {
  59. EncryptedRandomSessionKey = new byte[0];
  60. }
  61. int fixedLength = 64;
  62. if ((NegotiateFlags & NegotiateFlags.Version) > 0)
  63. {
  64. fixedLength += NTLMVersion.Length;
  65. }
  66. int payloadLength = LmChallengeResponse.Length + NtChallengeResponse.Length + DomainName.Length * 2 + UserName.Length * 2 + WorkStation.Length * 2 + EncryptedRandomSessionKey.Length;
  67. byte[] buffer = new byte[fixedLength + payloadLength];
  68. ByteWriter.WriteAnsiString(buffer, 0, ValidSignature, 8);
  69. LittleEndianWriter.WriteUInt32(buffer, 8, (uint)MessageType);
  70. LittleEndianWriter.WriteUInt32(buffer, 60, (uint)NegotiateFlags);
  71. if ((NegotiateFlags & NegotiateFlags.Version) > 0)
  72. {
  73. Version.WriteBytes(buffer, 64);
  74. }
  75. int offset = fixedLength;
  76. AuthenticationMessageUtils.WriteBufferPointer(buffer, 12, (ushort)LmChallengeResponse.Length, (uint)offset);
  77. ByteWriter.WriteBytes(buffer, ref offset, LmChallengeResponse);
  78. AuthenticationMessageUtils.WriteBufferPointer(buffer, 20, (ushort)NtChallengeResponse.Length, (uint)offset);
  79. ByteWriter.WriteBytes(buffer, ref offset, NtChallengeResponse);
  80. AuthenticationMessageUtils.WriteBufferPointer(buffer, 28, (ushort)(DomainName.Length * 2), (uint)offset);
  81. ByteWriter.WriteUTF16String(buffer, ref offset, DomainName);
  82. AuthenticationMessageUtils.WriteBufferPointer(buffer, 36, (ushort)(UserName.Length * 2), (uint)offset);
  83. ByteWriter.WriteUTF16String(buffer, ref offset, UserName);
  84. AuthenticationMessageUtils.WriteBufferPointer(buffer, 44, (ushort)(WorkStation.Length * 2), (uint)offset);
  85. ByteWriter.WriteUTF16String(buffer, ref offset, WorkStation);
  86. AuthenticationMessageUtils.WriteBufferPointer(buffer, 52, (ushort)EncryptedRandomSessionKey.Length, (uint)offset);
  87. ByteWriter.WriteBytes(buffer, ref offset, EncryptedRandomSessionKey);
  88. return buffer;
  89. }
  90. }
  91. }