/// <summary>
        /// Build a Smb2Packet from a byte array
        /// </summary>
        /// <param name="data">The byte array</param>
        /// <param name="consumedLen">The consumed data length</param>
        /// <param name="expectedLen">The expected data length</param>
        internal override void FromBytes(byte[] data, out int consumedLen, out int expectedLen)
        {
            consumedLen = 0;
            this.NegotiateContext_ENCRYPTION = null;
            this.NegotiateContext_PREAUTH    = null;
            this.Header = TypeMarshal.ToStruct <Packet_Header>(data, ref consumedLen);

            byte[] tempData = data.Skip(consumedLen).ToArray();
            this.PayLoad = Smb2Utility.UnmarshalStructure <NEGOTIATE_Response>(tempData);
            consumedLen += Marshal.SizeOf(this.PayLoad);

            if (this.PayLoad.SecurityBufferLength > 0)
            {
                this.Buffer  = data.Skip(this.PayLoad.SecurityBufferOffset).Take(this.PayLoad.SecurityBufferLength).ToArray();
                consumedLen += this.Buffer.Length;
            }

            while (data.Length > consumedLen)
            {
                // Skip padding
                int paddingLen = 8 - (consumedLen) % 8;
                if (paddingLen != 8)
                {
                    if (data.Length - consumedLen <= paddingLen)
                    {
                        break;
                    }
                    consumedLen += paddingLen;
                }

                if (data.Length - consumedLen < 8)
                {
                    break;
                }
                SMB2_NEGOTIATE_CONTEXT_Type_Values contextType = (SMB2_NEGOTIATE_CONTEXT_Type_Values)BitConverter.ToUInt16(data, consumedLen);
                if (contextType == SMB2_NEGOTIATE_CONTEXT_Type_Values.SMB2_PREAUTH_INTEGRITY_CAPABILITIES)
                {
                    if (this.NegotiateContext_PREAUTH != null)
                    {
                        throw new Exception("More than one SMB2_PREAUTH_INTEGRITY_CAPABILITIES are present.");
                    }
                    this.NegotiateContext_PREAUTH = TypeMarshal.ToStruct <SMB2_PREAUTH_INTEGRITY_CAPABILITIES>(data, ref consumedLen);
                }
                else if (contextType == SMB2_NEGOTIATE_CONTEXT_Type_Values.SMB2_ENCRYPTION_CAPABILITIES)
                {
                    if (this.NegotiateContext_ENCRYPTION != null)
                    {
                        throw new Exception("More than one SMB2_ENCRYPTION_CAPABILITIES are present.");
                    }
                    this.NegotiateContext_ENCRYPTION = TypeMarshal.ToStruct <SMB2_ENCRYPTION_CAPABILITIES>(data, ref consumedLen);
                }
                else
                {
                    throw new Exception(string.Format("Unknow Negotiate Context: {0}.", (ushort)contextType));
                }
            }
            expectedLen = 0;
        }
        /// <summary>
        /// Build a Smb2Packet from a byte array
        /// </summary>
        /// <param name="data">The byte array</param>
        /// <param name="consumedLen">The consumed data length</param>
        /// <param name="expectedLen">The expected data length</param>
        internal override void FromBytes(byte[] data, out int consumedLen, out int expectedLen)
        {
            consumedLen = 0;
            this.Header = TypeMarshal.ToStruct <Packet_Header>(data, ref consumedLen);

            byte[] tempData = data.Skip(consumedLen).ToArray();
            this.PayLoad = Smb2Utility.UnmarshalStructure <NEGOTIATE_Request>(tempData);
            consumedLen += Marshal.SizeOf(this.PayLoad);

            this.Buffer = data.Skip(consumedLen).ToArray(); //Dialects + Padding + NegotiateContextList

            if (PayLoad.DialectCount > 0)
            {
                this.Dialects = Smb2Utility.UnmarshalStructArray <DialectRevision>(Buffer, PayLoad.DialectCount);
                consumedLen  += PayLoad.DialectCount * sizeof(DialectRevision);
            }

            while (data.Length > consumedLen)
            {
                // Skip padding
                int paddingLen = 8 - (consumedLen) % 8;
                if (paddingLen != 8)
                {
                    if (data.Length - consumedLen <= paddingLen)
                    {
                        break;
                    }
                    consumedLen += paddingLen;
                }

                if (data.Length - consumedLen < 8)
                {
                    break;
                }
                SMB2_NEGOTIATE_CONTEXT_Type_Values contextType = (SMB2_NEGOTIATE_CONTEXT_Type_Values)BitConverter.ToUInt16(data, consumedLen);
                if (contextType == SMB2_NEGOTIATE_CONTEXT_Type_Values.SMB2_PREAUTH_INTEGRITY_CAPABILITIES)
                {
                    this.NegotiateContext_PREAUTH = TypeMarshal.ToStruct <SMB2_PREAUTH_INTEGRITY_CAPABILITIES>(data, ref consumedLen);
                }
                else if (contextType == SMB2_NEGOTIATE_CONTEXT_Type_Values.SMB2_ENCRYPTION_CAPABILITIES)
                {
                    this.NegotiateContext_ENCRYPTION = TypeMarshal.ToStruct <SMB2_ENCRYPTION_CAPABILITIES>(data, ref consumedLen);
                }
                else if (contextType == SMB2_NEGOTIATE_CONTEXT_Type_Values.SMB2_COMPRESSION_CAPABILITIES)
                {
                    this.NegotiateContext_COMPRESSION = TypeMarshal.ToStruct <SMB2_COMPRESSION_CAPABILITIES>(data, ref consumedLen);
                }
                else if (contextType == SMB2_NEGOTIATE_CONTEXT_Type_Values.SMB2_NETNAME_NEGOTIATE_CONTEXT_ID)
                {
                    this.NegotiateContext_NETNAME = SMB2_NETNAME_NEGOTIATE_CONTEXT_ID.Unmarshal(data, ref consumedLen);
                }
            }

            expectedLen = 0;
        }
        /// <summary>
        /// Build a Smb2TreeConnectRequestPacket from a byte array
        /// </summary>
        /// <param name="data">The byte array</param>
        /// <param name="consumedLen">The consumed data length</param>
        /// <param name="expectedLen">The expected data length</param>
        internal override void FromBytes(byte[] data, out int consumedLen, out int expectedLen)
        {
            consumedLen  = 0;
            this.Header  = TypeMarshal.ToStruct <Packet_Header>(data, ref consumedLen);
            this.PayLoad = Smb2Utility.UnmarshalStructure <TREE_CONNECT_Request>(data.Skip(consumedLen).ToArray()); //based on .net unmarshal
            consumedLen += Marshal.SizeOf(typeof(TREE_CONNECT_Request));

            var packetBuffer = this as IPacketBuffer;
            int bufferLength = (int)packetBuffer.BufferLength;

            this.Buffer  = data.Skip(consumedLen).Take(bufferLength).ToArray();
            consumedLen += bufferLength;

            expectedLen = 0;
        }
        public static byte[] Decrypt(byte[] bytes, Dictionary <ulong, Smb2CryptoInfo> cryptoInfoTable, Smb2Role role)
        {
            // Client: If the size of the message received from the server is not greater than the size of SMB2 TRANSFORM_HEADER as specified, the client MUST discard the message.
            // Server: If the size of the message received from the client is not greater than the size of the SMB2 TRANSFORM_HEADER, the server MUST disconnect the connection.
            int minimumLength = Marshal.SizeOf(typeof(Transform_Header));

            if (bytes.Length < minimumLength)
            {
                throw new InvalidOperationException(
                          String.Format(
                              "Too less data for encrypted message. Expected length more than {0}, actual {1}.",
                              minimumLength,
                              bytes.Length
                              )
                          );
            }

            Transform_Header transformHeader = Smb2Utility.UnmarshalStructure <Transform_Header>(bytes);

            // Client: If the Flags/EncryptionAlgorithm in the SMB2 TRANSFORM_HEADER is not 0x0001, the client MUST discard the message.
            // Server: If the Flags/EncryptionAlgorithm in the SMB2 TRANSFORM_HEADER is not 0x0001, the server MUST disconnect the connection.
            if (transformHeader.Flags != TransformHeaderFlags.Encrypted)
            {
                throw new InvalidOperationException(
                          String.Format(
                              "Flags/EncryptionAlgorithm field is invalid for encrypted message. Expected value 0x0001, actual {0}.",
                              (ushort)transformHeader.Flags
                              )
                          );
            }

            if (transformHeader.SessionId == 0 || !cryptoInfoTable.ContainsKey(transformHeader.SessionId))
            {
                throw new InvalidOperationException("Invalid SessionId in TRANSFORM_HEADER.");
            }

            Smb2CryptoInfo cryptoInfo = cryptoInfoTable[transformHeader.SessionId];

            using (var bcrypt = new BCryptAlgorithm("AES"))
            {
                int nonceLength       = 0;
                BCryptCipherMode mode = BCryptCipherMode.NotAvailable;
                GetCryptoParams(cryptoInfo, CryptoOperationType.Decrypt, out mode, out nonceLength);
                bcrypt.Mode = mode;
                bcrypt.Key  = role == Smb2Role.Server ? cryptoInfo.ServerInKey : cryptoInfo.ServerOutKey;
                return(bcrypt.Decrypt(bytes.Skip(52).ToArray(), transformHeader.Nonce.ToByteArray().Take(nonceLength).ToArray(), bytes.Skip(20).Take(32).ToArray(), transformHeader.Signature));
            }
        }
Beispiel #5
0
        /// <summary>
        /// Build a Smb2CompressedPacket from a byte array.
        /// </summary>
        /// <param name="data">The byte array.</param>
        /// <param name="consumedLen">The consumed data length.</param>
        /// <param name="expectedLen">The expected data length.</param>
        internal override void FromBytes(byte[] data, out int consumedLen, out int expectedLen)
        {
            int minimumLength = Marshal.SizeOf(Header);

            if (data.Length < minimumLength)
            {
                throw new InvalidOleVariantTypeException("Not enough data for Transform_Header!");
            }

            Header = Smb2Utility.UnmarshalStructure <Transform_Header>(data.Take(minimumLength).ToArray());

            EncryptdData = data.Skip(minimumLength).ToArray();

            consumedLen = data.Length;
            expectedLen = 0;
        }
Beispiel #6
0
        /// <summary>
        /// Build a Smb2CompressedPacket from a byte array.
        /// </summary>
        /// <param name="data">The byte array.</param>
        /// <param name="consumedLen">The consumed data length.</param>
        /// <param name="expectedLen">The expected data length.</param>
        internal override void FromBytes(byte[] data, out int consumedLen, out int expectedLen)
        {
            int minimumLength = Marshal.SizeOf(Header);

            if (data.Length < minimumLength)
            {
                throw new InvalidOperationException("[MS-SMB2] section 3.3.5.2.1.1 If the size of the message received from the client is not greater than" +
                                                    "the size of the SMB2 TRANSFORM_HEADER, the server MUST disconnect the connection.");
            }

            Header = Smb2Utility.UnmarshalStructure <Transform_Header>(data.Take(minimumLength).ToArray());

            EncryptdData = data.Skip(minimumLength).ToArray();

            consumedLen = data.Length;
            expectedLen = 0;
        }
        public static byte[] Decrypt(byte[] bytes, Dictionary <ulong, Smb2CryptoInfo> cryptoInfoTable, Smb2Role role)
        {
            Transform_Header transformHeader = Smb2Utility.UnmarshalStructure <Transform_Header>(bytes);

            if (transformHeader.SessionId == 0 || !cryptoInfoTable.ContainsKey(transformHeader.SessionId))
            {
                throw new InvalidOperationException("Invalid SessionId in TRANSFORM_HEADER.");
            }

            Smb2CryptoInfo cryptoInfo = cryptoInfoTable[transformHeader.SessionId];

            using (var bcrypt = new BCryptAlgorithm("AES"))
            {
                int nonceLength       = 0;
                BCryptCipherMode mode = BCryptCipherMode.NotAvailable;
                GetCryptoParams(cryptoInfo, CryptoOperationType.Decrypt, out mode, out nonceLength);
                bcrypt.Mode = mode;
                bcrypt.Key  = role == Smb2Role.Server ? cryptoInfo.ServerInKey : cryptoInfo.ServerOutKey;
                return(bcrypt.Decrypt(bytes.Skip(52).ToArray(), transformHeader.Nonce.ToByteArray().Take(nonceLength).ToArray(), bytes.Skip(20).Take(32).ToArray(), transformHeader.Signature));
            }
        }