Skip to content

Commit

Permalink
SMBServer v1.0.5
Browse files Browse the repository at this point in the history
  • Loading branch information
TalAloni committed Dec 22, 2016
1 parent b758204 commit bd1006c
Show file tree
Hide file tree
Showing 400 changed files with 28,062 additions and 0 deletions.
74 changes: 74 additions & 0 deletions SMBLibrary/Authentication/AuthenticateMessage/AVPairUtils.cs
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);
}
}
}
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;
}
}
}
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 SMBLibrary/Authentication/AuthenticateMessage/ChallengeMessage.cs
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 SMBLibrary/Authentication/AuthenticateMessage/Enums/AVPairKey.cs
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
}
}
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,
}
}
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
}
}
Loading

0 comments on commit bd1006c

Please sign in to comment.