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;
}
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)
{
SimpleProtectedNegotiationTokenResponse token = new SimpleProtectedNegotiationTokenResponse();

View file

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

View file

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