mirror of
https://github.com/TalAloni/SMBLibrary.git
synced 2025-08-05 23:34:56 +02:00
NegotiateRequest: Parse NegotiateContextList (SMB 3.1.1)
This commit is contained in:
parent
1aef438a8e
commit
e40a5b2daf
2 changed files with 98 additions and 6 deletions
46
SMBLibrary.Tests/SMB2/NegotiateRequestParsingTests.cs
Normal file
46
SMBLibrary.Tests/SMB2/NegotiateRequestParsingTests.cs
Normal file
|
@ -0,0 +1,46 @@
|
|||
/* Copyright (C) 2024 Tal Aloni <tal.aloni.il@gmail.com>. 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 Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using SMBLibrary.SMB2;
|
||||
|
||||
namespace SMBLibrary.Tests.SMB2
|
||||
{
|
||||
[TestClass]
|
||||
public class NegotiateRequestParsingTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void ParseNegotiateRequestWithNegotiateContextList()
|
||||
{
|
||||
byte[] negotiateRequestCommandBytes = new byte[]
|
||||
{
|
||||
0xfe,0x53,0x4d,0x42,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x24,0x00,0x05,0x00,0x01,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0xd2,0xb6,0x2a,0x44,
|
||||
0x99,0x4d,0xef,0x11,0xb8,0x9d,0x00,0x22,0x48,0x39,0x02,0x34,0x70,0x00,0x00,0x00,
|
||||
0x04,0x00,0x00,0x00,0x02,0x02,0x10,0x02,0x00,0x03,0x02,0x03,0x11,0x03,0x00,0x00,
|
||||
0x01,0x00,0x26,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x20,0x00,0x01,0x00,0x6c,0xec,
|
||||
0x6e,0x4d,0x8e,0x58,0x93,0xd9,0xb3,0x47,0x24,0x09,0x12,0x7a,0xc8,0x4f,0x9b,0xf6,
|
||||
0x1d,0xaa,0xbc,0xab,0x22,0xf5,0xec,0xf6,0x3d,0xb5,0x3e,0xc3,0x76,0x85,0x00,0x00,
|
||||
0x02,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x01,0x00,0x00,0x00,
|
||||
0x03,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
|
||||
0x04,0x00,0x02,0x00,0x03,0x00,0x01,0x00,0x05,0x00,0x34,0x00,0x00,0x00,0x00,0x00,
|
||||
0x6d,0x00,0x69,0x00,0x72,0x00,0x61,0x00,0x67,0x00,0x65,0x00,0x2d,0x00,0x73,0x00,
|
||||
0x65,0x00,0x72,0x00,0x76,0x00,0x65,0x00,0x72,0x00,0x34,0x00,0x2e,0x00,0x75,0x00,
|
||||
0x73,0x00,0x65,0x00,0x72,0x00,0x73,0x00,0x2e,0x00,0x6c,0x00,0x6f,0x00,0x63,0x00,
|
||||
0x61,0x00,0x6c,0x00
|
||||
};
|
||||
|
||||
NegotiateRequest negotiateRequest = new NegotiateRequest(negotiateRequestCommandBytes, 0);
|
||||
Assert.AreEqual(5, negotiateRequest.Dialects.Count);
|
||||
Assert.AreEqual(4, negotiateRequest.NegotiateContextList.Count);
|
||||
Assert.AreEqual(NegotiateContextType.SMB2_PREAUTH_INTEGRITY_CAPABILITIES, negotiateRequest.NegotiateContextList[0].ContextType);
|
||||
Assert.AreEqual(NegotiateContextType.SMB2_ENCRYPTION_CAPABILITIES, negotiateRequest.NegotiateContextList[1].ContextType);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
/* Copyright (C) 2017-2024 Tal Aloni <tal.aloni.il@gmail.com>. 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,
|
||||
|
@ -23,8 +23,9 @@ namespace SMBLibrary.SMB2
|
|||
public ushort Reserved;
|
||||
public Capabilities Capabilities; // If the client does not implements the SMB 3.x dialect family, this field MUST be set to 0.
|
||||
public Guid ClientGuid;
|
||||
public DateTime ClientStartTime;
|
||||
public DateTime ClientStartTime; // If Dialects does not contain SMB311
|
||||
public List<SMB2Dialect> Dialects = new List<SMB2Dialect>();
|
||||
public List<NegotiateContext> NegotiateContextList = new List<NegotiateContext>(); // If Dialects contains SMB311
|
||||
|
||||
public NegotiateRequest() : base(SMB2CommandName.Negotiate)
|
||||
{
|
||||
|
@ -39,12 +40,28 @@ namespace SMBLibrary.SMB2
|
|||
Reserved = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 6);
|
||||
Capabilities = (Capabilities)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 8);
|
||||
ClientGuid = LittleEndianConverter.ToGuid(buffer, offset + SMB2Header.Length + 12);
|
||||
ClientStartTime = DateTime.FromFileTimeUtc(LittleEndianConverter.ToInt64(buffer, offset + SMB2Header.Length + 28));
|
||||
|
||||
bool containsNegotiateContextList = false;
|
||||
for (int index = 0; index < dialectCount; index++)
|
||||
{
|
||||
SMB2Dialect dialect = (SMB2Dialect)LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 36 + index * 2);
|
||||
Dialects.Add(dialect);
|
||||
|
||||
if (dialect == SMB2Dialect.SMB311)
|
||||
{
|
||||
containsNegotiateContextList = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (containsNegotiateContextList)
|
||||
{
|
||||
uint negotiateContextOffset = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 28);
|
||||
ushort NegotiateContextCount = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 32);
|
||||
NegotiateContextList = NegotiateContext.ReadNegotiateContextList(buffer, offset + (int)negotiateContextOffset, NegotiateContextCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClientStartTime = DateTime.FromFileTimeUtc(LittleEndianConverter.ToInt64(buffer, offset + SMB2Header.Length + 28));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,12 +73,31 @@ namespace SMBLibrary.SMB2
|
|||
LittleEndianWriter.WriteUInt16(buffer, offset + 6, Reserved);
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 8, (uint)Capabilities);
|
||||
LittleEndianWriter.WriteGuid(buffer, offset + 12, ClientGuid);
|
||||
LittleEndianWriter.WriteInt64(buffer, offset + 28, ClientStartTime.ToFileTimeUtc());
|
||||
|
||||
|
||||
bool containsNegotiateContextList = false;
|
||||
for (int index = 0; index < Dialects.Count; index++)
|
||||
{
|
||||
SMB2Dialect dialect = Dialects[index];
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 36 + index * 2, (ushort)dialect);
|
||||
|
||||
if (dialect == SMB2Dialect.SMB311)
|
||||
{
|
||||
containsNegotiateContextList = true;
|
||||
}
|
||||
}
|
||||
|
||||
int paddingLength = (8 - ((36 + Dialects.Count * 2) % 8)) % 8;
|
||||
if (containsNegotiateContextList)
|
||||
{
|
||||
uint negotiateContextOffset = (uint)(SMB2Header.Length + 36 + Dialects.Count * 2 + paddingLength);
|
||||
ushort negotiateContextCount = (ushort)NegotiateContextList.Count;
|
||||
LittleEndianWriter.WriteUInt32(buffer, offset + 28, negotiateContextOffset);
|
||||
LittleEndianWriter.WriteUInt16(buffer, offset + 32, negotiateContextCount);
|
||||
NegotiateContext.WriteNegotiateContextList(buffer, offset - SMB2Header.Length + (int)negotiateContextOffset, NegotiateContextList);
|
||||
}
|
||||
else
|
||||
{
|
||||
LittleEndianWriter.WriteInt64(buffer, offset + 28, ClientStartTime.ToFileTimeUtc());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,7 +105,17 @@ namespace SMBLibrary.SMB2
|
|||
{
|
||||
get
|
||||
{
|
||||
return 36 + Dialects.Count * 2;
|
||||
bool containsNegotiateContextList = Dialects.Contains(SMB2Dialect.SMB311);
|
||||
if (containsNegotiateContextList)
|
||||
{
|
||||
int paddingLength = (8 - ((36 + Dialects.Count * 2) % 8)) % 8;
|
||||
int negotiateContextListLength = NegotiateContext.GetNegotiateContextListLength(NegotiateContextList);
|
||||
return 36 + Dialects.Count * 2 + paddingLength + negotiateContextListLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 36 + Dialects.Count * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue