-
Notifications
You must be signed in to change notification settings - Fork 189
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
400 changed files
with
28,062 additions
and
0 deletions.
There are no files selected for viewing
74 changes: 74 additions & 0 deletions
74
SMBLibrary/Authentication/AuthenticateMessage/AVPairUtils.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/* Copyright (C) 2014 Tal Aloni <[email protected]>. All rights reserved. | ||
* | ||
* You can redistribute this program and/or modify it under the terms of | ||
* the GNU Lesser Public License as published by the Free Software Foundation, | ||
* either version 3 of the License, or (at your option) any later version. | ||
*/ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using Utilities; | ||
|
||
namespace SMBLibrary.Authentication | ||
{ | ||
public class AVPairUtils | ||
{ | ||
public static byte[] GetAVPairSequence(string domainName, string computerName) | ||
{ | ||
KeyValuePairList<AVPairKey, byte[]> pairs = new KeyValuePairList<AVPairKey, byte[]>(); | ||
pairs.Add(AVPairKey.NbDomainName, UnicodeEncoding.Unicode.GetBytes(domainName)); | ||
pairs.Add(AVPairKey.NbComputerName, UnicodeEncoding.Unicode.GetBytes(computerName)); | ||
return AVPairUtils.GetAVPairSequenceBytes(pairs); | ||
} | ||
|
||
public static byte[] GetAVPairSequenceBytes(KeyValuePairList<AVPairKey, byte[]> pairs) | ||
{ | ||
int length = 0; | ||
foreach (KeyValuePair<AVPairKey, byte[]> pair in pairs) | ||
{ | ||
length += 4 + pair.Value.Length; | ||
} | ||
length += 4; | ||
|
||
byte[] result = new byte[length]; | ||
int offset = 0; | ||
foreach (KeyValuePair<AVPairKey, byte[]> pair in pairs) | ||
{ | ||
WriteAVPair(result, ref offset, pair.Key, pair.Value); | ||
} | ||
LittleEndianWriter.WriteUInt16(result, ref offset, (ushort)AVPairKey.EOL); | ||
LittleEndianWriter.WriteUInt16(result, ref offset, 0); | ||
|
||
return result; | ||
} | ||
|
||
public static void WriteAVPair(byte[] buffer, ref int offset, AVPairKey key, byte[] value) | ||
{ | ||
LittleEndianWriter.WriteUInt16(buffer, ref offset, (ushort)key); | ||
LittleEndianWriter.WriteUInt16(buffer, ref offset, (ushort)value.Length); | ||
ByteWriter.WriteBytes(buffer, ref offset, value); | ||
} | ||
|
||
public static KeyValuePairList<AVPairKey, byte[]> ReadAVPairSequence(byte[] buffer, int offset) | ||
{ | ||
KeyValuePairList<AVPairKey, byte[]> result = new KeyValuePairList<AVPairKey,byte[]>(); | ||
AVPairKey key = (AVPairKey)LittleEndianConverter.ToUInt16(buffer, offset); | ||
while (key != AVPairKey.EOL) | ||
{ | ||
KeyValuePair<AVPairKey, byte[]> pair = ReadAVPair(buffer, ref offset); | ||
result.Add(pair); | ||
key = (AVPairKey)LittleEndianConverter.ToUInt16(buffer, offset); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
public static KeyValuePair<AVPairKey, byte[]> ReadAVPair(byte[] buffer, ref int offset) | ||
{ | ||
AVPairKey key = (AVPairKey)LittleEndianReader.ReadUInt16(buffer, ref offset); | ||
ushort length = LittleEndianReader.ReadUInt16(buffer, ref offset); | ||
byte[] value = ByteReader.ReadBytes(buffer, ref offset, length); | ||
return new KeyValuePair<AVPairKey, byte[]>(key, value); | ||
} | ||
} | ||
} |
94 changes: 94 additions & 0 deletions
94
SMBLibrary/Authentication/AuthenticateMessage/AuthenticateMessage.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/* Copyright (C) 2014 Tal Aloni <[email protected]>. All rights reserved. | ||
* | ||
* You can redistribute this program and/or modify it under the terms of | ||
* the GNU Lesser Public License as published by the Free Software Foundation, | ||
* either version 3 of the License, or (at your option) any later version. | ||
*/ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using Utilities; | ||
|
||
namespace SMBLibrary.Authentication | ||
{ | ||
/// <summary> | ||
/// [MS-NLMP] AUTHENTICATE_MESSAGE (Type 3 Message) | ||
/// </summary> | ||
public class AuthenticateMessage | ||
{ | ||
public string Signature; // 8 bytes | ||
public MessageTypeName MessageType; | ||
public byte[] LmChallengeResponse; | ||
public byte[] NtChallengeResponse; | ||
public string DomainName; | ||
public string UserName; | ||
public string WorkStation; | ||
public byte[] EncryptedRandomSessionKey; | ||
public NegotiateFlags NegotiateFlags; | ||
public Version Version; | ||
// 16-byte MIC field is omitted for Windows NT / 2000 / XP / Server 2003 | ||
|
||
public AuthenticateMessage() | ||
{ | ||
Signature = AuthenticationMessageUtils.ValidSignature; | ||
MessageType = MessageTypeName.Authenticate; | ||
DomainName = String.Empty; | ||
UserName = String.Empty; | ||
WorkStation = String.Empty; | ||
EncryptedRandomSessionKey = new byte[0]; | ||
} | ||
|
||
public AuthenticateMessage(byte[] buffer) | ||
{ | ||
Signature = ByteReader.ReadAnsiString(buffer, 0, 8); | ||
MessageType = (MessageTypeName)LittleEndianConverter.ToUInt32(buffer, 8); | ||
LmChallengeResponse = AuthenticationMessageUtils.ReadBufferPointer(buffer, 12); | ||
NtChallengeResponse = AuthenticationMessageUtils.ReadBufferPointer(buffer, 20); | ||
DomainName = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 28); | ||
UserName = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 36); | ||
WorkStation = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 44); | ||
EncryptedRandomSessionKey = AuthenticationMessageUtils.ReadBufferPointer(buffer, 52); | ||
NegotiateFlags = (NegotiateFlags)LittleEndianConverter.ToUInt32(buffer, 60); | ||
if ((NegotiateFlags & NegotiateFlags.NegotiateVersion) > 0) | ||
{ | ||
Version = new Version(buffer, 64); | ||
} | ||
} | ||
|
||
public byte[] GetBytes() | ||
{ | ||
int fixedLength = 64; | ||
|
||
if ((NegotiateFlags & NegotiateFlags.NegotiateVersion) > 0) | ||
{ | ||
fixedLength += 8; | ||
} | ||
|
||
int payloadLength = LmChallengeResponse.Length + NtChallengeResponse.Length + DomainName.Length * 2 + UserName.Length * 2 + WorkStation.Length * 2 + EncryptedRandomSessionKey.Length; | ||
byte[] buffer = new byte[fixedLength + payloadLength]; | ||
ByteWriter.WriteAnsiString(buffer, 0, AuthenticationMessageUtils.ValidSignature, 8); | ||
LittleEndianWriter.WriteUInt32(buffer, 8, (uint)MessageType); | ||
LittleEndianWriter.WriteUInt32(buffer, 60, (uint)NegotiateFlags); | ||
if ((NegotiateFlags & NegotiateFlags.NegotiateVersion) > 0) | ||
{ | ||
Version.WriteBytes(buffer, 64); | ||
} | ||
|
||
int offset = fixedLength; | ||
AuthenticationMessageUtils.WriteBufferPointer(buffer, 12, (ushort)LmChallengeResponse.Length, (uint)offset); | ||
ByteWriter.WriteBytes(buffer, ref offset, LmChallengeResponse); | ||
AuthenticationMessageUtils.WriteBufferPointer(buffer, 20, (ushort)NtChallengeResponse.Length, (uint)offset); | ||
ByteWriter.WriteBytes(buffer, ref offset, NtChallengeResponse); | ||
AuthenticationMessageUtils.WriteBufferPointer(buffer, 28, (ushort)(DomainName.Length * 2), (uint)offset); | ||
ByteWriter.WriteUTF16String(buffer, ref offset, DomainName); | ||
AuthenticationMessageUtils.WriteBufferPointer(buffer, 36, (ushort)(UserName.Length * 2), (uint)offset); | ||
ByteWriter.WriteUTF16String(buffer, ref offset, UserName); | ||
AuthenticationMessageUtils.WriteBufferPointer(buffer, 44, (ushort)(WorkStation.Length * 2), (uint)offset); | ||
ByteWriter.WriteUTF16String(buffer, ref offset, WorkStation); | ||
AuthenticationMessageUtils.WriteBufferPointer(buffer, 52, (ushort)EncryptedRandomSessionKey.Length, (uint)offset); | ||
ByteWriter.WriteBytes(buffer, ref offset, EncryptedRandomSessionKey); | ||
|
||
return buffer; | ||
} | ||
} | ||
} |
64 changes: 64 additions & 0 deletions
64
SMBLibrary/Authentication/AuthenticateMessage/AuthenticationMessageUtils.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/* Copyright (C) 2014 Tal Aloni <[email protected]>. All rights reserved. | ||
* | ||
* You can redistribute this program and/or modify it under the terms of | ||
* the GNU Lesser Public License as published by the Free Software Foundation, | ||
* either version 3 of the License, or (at your option) any later version. | ||
*/ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using Utilities; | ||
|
||
namespace SMBLibrary.Authentication | ||
{ | ||
public class AuthenticationMessageUtils | ||
{ | ||
public const string ValidSignature = "NTLMSSP\0"; | ||
|
||
public static string ReadAnsiStringBufferPointer(byte[] buffer, int offset) | ||
{ | ||
byte[] bytes = ReadBufferPointer(buffer, offset); | ||
return ASCIIEncoding.Default.GetString(bytes); | ||
} | ||
|
||
public static string ReadUnicodeStringBufferPointer(byte[] buffer, int offset) | ||
{ | ||
byte[] bytes = ReadBufferPointer(buffer, offset); | ||
return UnicodeEncoding.Unicode.GetString(bytes); | ||
} | ||
|
||
public static byte[] ReadBufferPointer(byte[] buffer, int offset) | ||
{ | ||
ushort length = LittleEndianConverter.ToUInt16(buffer, offset); | ||
ushort maxLength = LittleEndianConverter.ToUInt16(buffer, offset + 2); | ||
uint bufferOffset = LittleEndianConverter.ToUInt32(buffer, offset + 4); | ||
|
||
if (length == 0) | ||
{ | ||
return new byte[0]; | ||
} | ||
else | ||
{ | ||
return ByteReader.ReadBytes(buffer, (int)bufferOffset, length); | ||
} | ||
} | ||
|
||
public static void WriteBufferPointer(byte[] buffer, int offset, ushort bufferLength, uint bufferOffset) | ||
{ | ||
LittleEndianWriter.WriteUInt16(buffer, offset, bufferLength); | ||
LittleEndianWriter.WriteUInt16(buffer, offset + 2, bufferLength); | ||
LittleEndianWriter.WriteUInt32(buffer, offset + 4, bufferOffset); | ||
} | ||
|
||
public static bool IsSignatureValid(byte[] messageBytes) | ||
{ | ||
string signature = ByteReader.ReadAnsiString(messageBytes, 0, 8); | ||
return (signature == ValidSignature); | ||
} | ||
|
||
public static MessageTypeName GetMessageType(byte[] messageBytes) | ||
{ | ||
return (MessageTypeName)LittleEndianConverter.ToUInt32(messageBytes, 8); | ||
} | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
SMBLibrary/Authentication/AuthenticateMessage/ChallengeMessage.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* Copyright (C) 2014 Tal Aloni <[email protected]>. All rights reserved. | ||
* | ||
* You can redistribute this program and/or modify it under the terms of | ||
* the GNU Lesser Public License as published by the Free Software Foundation, | ||
* either version 3 of the License, or (at your option) any later version. | ||
*/ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using Utilities; | ||
|
||
namespace SMBLibrary.Authentication | ||
{ | ||
/// <summary> | ||
/// [MS-NLMP] CHALLENGE_MESSAGE (Type 2 Message) | ||
/// </summary> | ||
public class ChallengeMessage | ||
{ | ||
public string Signature; // 8 bytes | ||
public MessageTypeName MessageType; | ||
public string TargetName; | ||
public NegotiateFlags NegotiateFlags; | ||
public byte[] ServerChallenge; // 8 bytes | ||
// Reserved - 8 bytes | ||
public byte[] TargetInfo; // sequence of AV_PAIR structures | ||
public Version Version; | ||
|
||
public ChallengeMessage() | ||
{ | ||
Signature = AuthenticationMessageUtils.ValidSignature; | ||
MessageType = MessageTypeName.Challenge; | ||
} | ||
|
||
public ChallengeMessage(byte[] buffer) | ||
{ | ||
Signature = ByteReader.ReadAnsiString(buffer, 0, 8); | ||
MessageType = (MessageTypeName)LittleEndianConverter.ToUInt32(buffer, 8); | ||
TargetName = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 12); | ||
NegotiateFlags = (NegotiateFlags)LittleEndianConverter.ToUInt32(buffer, 20); | ||
ServerChallenge = ByteReader.ReadBytes(buffer, 24, 8); | ||
// Reserved | ||
TargetInfo = AuthenticationMessageUtils.ReadBufferPointer(buffer, 40); | ||
if ((NegotiateFlags & NegotiateFlags.NegotiateVersion) > 0) | ||
{ | ||
Version = new Version(buffer, 48); | ||
} | ||
} | ||
|
||
public byte[] GetBytes() | ||
{ | ||
int fixedLength = 48; | ||
if ((NegotiateFlags & NegotiateFlags.NegotiateVersion) > 0) | ||
{ | ||
fixedLength += 8; | ||
} | ||
|
||
int payloadLength = TargetName.Length * 2 + TargetInfo.Length; | ||
byte[] buffer = new byte[fixedLength + payloadLength]; | ||
ByteWriter.WriteAnsiString(buffer, 0, AuthenticationMessageUtils.ValidSignature, 8); | ||
LittleEndianWriter.WriteUInt32(buffer, 8, (uint)MessageType); | ||
LittleEndianWriter.WriteUInt32(buffer, 20, (uint)NegotiateFlags); | ||
ByteWriter.WriteBytes(buffer, 24, ServerChallenge); | ||
if ((NegotiateFlags & NegotiateFlags.NegotiateVersion) > 0) | ||
{ | ||
Version.WriteBytes(buffer, 48); | ||
} | ||
|
||
int offset = fixedLength; | ||
AuthenticationMessageUtils.WriteBufferPointer(buffer, 12, (ushort)(TargetName.Length * 2), (uint)offset); | ||
ByteWriter.WriteUTF16String(buffer, ref offset, TargetName); | ||
AuthenticationMessageUtils.WriteBufferPointer(buffer, 40, (ushort)TargetInfo.Length, (uint)offset); | ||
ByteWriter.WriteBytes(buffer, ref offset, TargetInfo); | ||
|
||
return buffer; | ||
} | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
SMBLibrary/Authentication/AuthenticateMessage/Enums/AVPairKey.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
|
||
namespace SMBLibrary.Authentication | ||
{ | ||
public enum AVPairKey : ushort | ||
{ | ||
EOL = 0x0000, | ||
NbComputerName = 0x0001, // Unicode | ||
NbDomainName = 0x0002, // Unicode | ||
DnsComputerName = 0x0003, // Unicode | ||
DnsDomainName = 0x0004, // Unicode | ||
DnsTreeName = 0x0005, // Unicode | ||
Flags = 0x0006, // UInt32 | ||
Timestamp = 0x0006, // Filetime | ||
SingleHost = 0x0008, // platform-specific BLOB | ||
TargetName = 0x0009, // Unicode | ||
ChannelBindings = 0x000A, // MD5 Hash | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
SMBLibrary/Authentication/AuthenticateMessage/Enums/MessageTypeName.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
|
||
namespace SMBLibrary.Authentication | ||
{ | ||
public enum MessageTypeName : uint | ||
{ | ||
Negotiate = 0x01, | ||
Challenge = 0x02, | ||
Authenticate = 0x03, | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
SMBLibrary/Authentication/AuthenticateMessage/Enums/NegotiateFlags.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
using System; | ||
|
||
namespace SMBLibrary.Authentication | ||
{ | ||
[Flags] | ||
public enum NegotiateFlags : uint | ||
{ | ||
NegotiateUnicode = 0x01, // NTLMSSP_NEGOTIATE_UNICODE | ||
NegotiateOEM = 0x02, // NTLM_NEGOTIATE_OEM | ||
RequestTarget = 0x04, // NTLMSSP_REQUEST_TARGET | ||
NegotiateSign = 0x10, // NTLMSSP_NEGOTIATE_SIGN | ||
NegotiateSeal = 0x20, // NTLMSSP_NEGOTIATE_SEAL | ||
NegotiateDatagram = 0x40, // NTLMSSP_NEGOTIATE_DATAGRAM | ||
|
||
/// <summary> | ||
/// NegotiateLanManagerKey and NegotiateExtendedSecurity are mutually exclusive | ||
/// If both are set then NegotiateLanManagerKey must be ignored | ||
/// </summary> | ||
NegotiateLanManagerKey = 0x80, // NTLMSSP_NEGOTIATE_LM_KEY | ||
NegotiateNTLMKey = 0x200, // NTLMSSP_NEGOTIATE_NTLM | ||
//NegotiateNTOnly = 0x400, // Unused, must be clear | ||
|
||
/// <summary> | ||
/// If set, the connection SHOULD be anonymous | ||
/// </summary> | ||
NegotiateAnonymous = 0x800, | ||
|
||
NegotiateOEMDomainSupplied = 0x1000, // NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED | ||
NegotiateOEMWorkstationSupplied = 0x2000, // NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED | ||
NegotiateAlwaysSign = 0x8000, // NTLMSSP_NEGOTIATE_ALWAYS_SIGN | ||
NegotiateTargetTypeDomain = 0x10000, // NTLMSSP_TARGET_TYPE_DOMAIN | ||
NegotiateTargetTypeServer = 0x20000, // NTLMSSP_TARGET_TYPE_SERVER | ||
NegotiateTargetTypeShare = 0x40000, // Unused, must be clear | ||
|
||
/// <summary> | ||
/// NegotiateLanManagerKey and NegotiateExtendedSecurity are mutually exclusive | ||
/// If both are set then NegotiateLanManagerKey must be ignored | ||
/// </summary> | ||
NegotiateExtendedSecurity = 0x80000, // NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY | ||
NegotiateIdentify = 0x100000, // NTLMSSP_NEGOTIATE_IDENTIFY | ||
RequestNonNTSession = 0x400000, // NTLMSSP_REQUEST_NON_NT_SESSION_KEY | ||
NegotiateTargetInfo = 0x800000, // NTLMSSP_NEGOTIATE_TARGET_INFO | ||
NegotiateVersion = 0x2000000, // NTLMSSP_NEGOTIATE_VERSION | ||
Negotiate128 = 0x20000000, // NTLMSSP_NEGOTIATE_128 | ||
NegotiateKeyExchange = 0x40000000, // NTLMSSP_NEGOTIATE_KEY_EXCH | ||
Negotiate56 = 0x80000000, // NTLMSSP_NEGOTIATE_56 | ||
} | ||
} |
Oops, something went wrong.