SMB2: implemented server-initiated SPNEGO authentication

This commit is contained in:
Tal Aloni 2017-01-23 22:51:21 +02:00
parent ee55b59a2f
commit 092869efa1
4 changed files with 46 additions and 2 deletions

View file

@ -48,6 +48,16 @@ namespace SMBLibrary.Authentication
return null; return null;
} }
public static byte[] GetGSSTokenInitNTLMSSPBytes()
{
SimpleProtectedNegotiationTokenInit token = new SimpleProtectedNegotiationTokenInit();
TokenInitEntry entry = new TokenInitEntry();
entry.MechanismTypeList = new List<byte[]>();
entry.MechanismTypeList.Add(NTLMSSPIdentifier);
token.Tokens.Add(entry);
return SimpleProtectedNegotiationToken.GetTokenBytes(token);
}
public static byte[] GetGSSTokenResponseBytesFromNTLMSSPMessage(byte[] messageBytes) public static byte[] GetGSSTokenResponseBytesFromNTLMSSPMessage(byte[] messageBytes)
{ {
SimpleProtectedNegotiationTokenResponse token = new SimpleProtectedNegotiationTokenResponse(); SimpleProtectedNegotiationTokenResponse token = new SimpleProtectedNegotiationTokenResponse();

View file

@ -51,5 +51,33 @@ namespace SMBLibrary.Authentication
} }
return null; return null;
} }
/// <summary>
/// Will append the generic GSSAPI header.
/// </summary>
public static byte[] GetTokenBytes(SimpleProtectedNegotiationToken token)
{
if (token is SimpleProtectedNegotiationTokenInit)
{
byte[] tokenBytes = token.GetBytes();
int objectIdentifierFieldSize = DerEncodingHelper.GetLengthFieldSize(SPNEGOIdentifier.Length);
int tokenLength = 1 + objectIdentifierFieldSize + SPNEGOIdentifier.Length + tokenBytes.Length;
int tokenLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(tokenLength);
int headerLength = 1 + tokenLengthFieldSize + 1 + objectIdentifierFieldSize + SPNEGOIdentifier.Length;
byte[] buffer = new byte[headerLength + tokenBytes.Length];
int offset = 0;
ByteWriter.WriteByte(buffer, ref offset, ApplicationTag);
DerEncodingHelper.WriteLength(buffer, ref offset, tokenLength);
ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.ObjectIdentifier);
DerEncodingHelper.WriteLength(buffer, ref offset, SPNEGOIdentifier.Length);
ByteWriter.WriteBytes(buffer, ref offset, SPNEGOIdentifier);
ByteWriter.WriteBytes(buffer, ref offset, tokenBytes);
return buffer;
}
else
{
return token.GetBytes();
}
}
} }
} }

View file

@ -13,9 +13,9 @@ namespace SMBLibrary.Authentication
{ {
public class TokenInitEntry public class TokenInitEntry
{ {
public List<byte[]> MechanismTypeList = new List<byte[]>(); // Optional public List<byte[]> MechanismTypeList; // Optional
// reqFlags - Optional, RECOMMENDED to be left out // reqFlags - Optional, RECOMMENDED to be left out
public byte[] MechanismToken = new byte[0]; // Optional public byte[] MechanismToken; // Optional
public byte[] MechanismListMIC; // Optional public byte[] MechanismListMIC; // Optional
} }
@ -32,6 +32,10 @@ namespace SMBLibrary.Authentication
public List<TokenInitEntry> Tokens = new List<TokenInitEntry>(); public List<TokenInitEntry> Tokens = new List<TokenInitEntry>();
public SimpleProtectedNegotiationTokenInit()
{
}
/// <param name="offset">The offset following the NegTokenInit tag</param> /// <param name="offset">The offset following the NegTokenInit tag</param>
public SimpleProtectedNegotiationTokenInit(byte[] buffer, int offset) public SimpleProtectedNegotiationTokenInit(byte[] buffer, int offset)
{ {

View file

@ -45,6 +45,7 @@ namespace SMBLibrary.Server.SMB2
response.MaxWriteSize = 65536; response.MaxWriteSize = 65536;
response.SystemTime = DateTime.Now; response.SystemTime = DateTime.Now;
response.ServerStartTime = DateTime.Today; response.ServerStartTime = DateTime.Today;
response.SecurityBuffer = GSSAPIHelper.GetGSSTokenInitNTLMSSPBytes();
return response; return response;
} }
@ -71,6 +72,7 @@ namespace SMBLibrary.Server.SMB2
response.MaxWriteSize = 65536; response.MaxWriteSize = 65536;
response.SystemTime = DateTime.Now; response.SystemTime = DateTime.Now;
response.ServerStartTime = DateTime.Today; response.ServerStartTime = DateTime.Today;
response.SecurityBuffer = GSSAPIHelper.GetGSSTokenInitNTLMSSPBytes();
return response; return response;
} }