コード例 #1
0
        private Smb2Packet DecodeCompressedSmb2Packet(
            byte[] messageBytes,
            Smb2Role role,
            ulong realSessionId,
            uint realTreeId,
            out int consumedLength,
            out int expectedLength,
            Transform_Header?transformHeader
            )
        {
            var compressedPacket = new Smb2CompressedPacket();

            compressedPacket.FromBytes(messageBytes, out consumedLength, out expectedLength);
            var orignialPacketBytes = Smb2Compression.Decompress(compressedPacket, compressionInfo, role);
            var decodedPacket       = DecodeSmb2Packet(
                orignialPacketBytes,
                role,
                realSessionId,
                realTreeId,
                out consumedLength,
                out expectedLength,
                transformHeader
                );


            decodedPacket.Compressed       = true;
            decodedPacket.CompressedPacket = compressedPacket;

            return(decodedPacket);
        }
コード例 #2
0
        /// <summary>
        /// Decode the message as smb2 packet
        /// </summary>
        /// <param name="messageBytes">The received packet</param>
        /// <param name="role">The role of this decoder, client or server</param>
        /// <param name="realSessionId">The real sessionId for this packet</param>
        /// <param name="realTreeId">The real treeId for this packet</param>
        /// <param name="consumedLength">[OUT]The consumed length of the message</param>
        /// <param name="expectedLength">[OUT]The expected length</param>
        /// <param name="transformHeader">The optional transform header</param>
        /// <returns>A Smb2Packet</returns>
        private Smb2CompressiblePacket DecodeSmb2Packet(
            byte[] messageBytes,
            Smb2Role role,
            ulong realSessionId,
            uint realTreeId,
            out int consumedLength,
            out int expectedLength,
            Transform_Header?transformHeader
            )
        {
            Packet_Header smb2Header;

            smb2Header = TypeMarshal.ToStruct <Packet_Header>(messageBytes);

            if (smb2Header.NextCommand != 0)
            {
                return(DecodeCompoundPacket(messageBytes, role, out consumedLength, out expectedLength, transformHeader));
            }
            else
            {
                if (transformHeader != null)
                {
                    if (smb2Header.SessionId != transformHeader.Value.SessionId)
                    {
                        // 3.3.4.6 Object Store Indicates an Oplock Break
                        // The server MUST construct an Oplock Break Notification following the syntax specified in section 2.2.23.1 to send back to the client.
                        // The server MUST set the Command in the SMB2 header to SMB2 OPLOCK_BREAK, and the MessageId to 0xFFFFFFFFFFFFFFFF.
                        // The server SHOULD <209> set the SessionId in the SMB2 header to Open.Session.SessionId.The server MUST set the TreeId in the SMB2 header to zero.
                        //
                        // <209> Section 3.3.4.6: Windows Vista SP1, Windows Server 2008, Windows 7, Windows Server 2008 R2, Windows 8, Windows Server 2012 operating system, Windows 8.1, and Windows Server 2012 R2 set the SessionId in the SMB2 header to zero.
                        //
                        // 3.2.5.19 Receiving an SMB2 OPLOCK_BREAK Notification
                        // If the MessageId field of the SMB2 header of the response is 0xFFFFFFFFFFFFFFFF, this MUST be processed as an oplock break indication.Otherwise, the client MUST process it as a response to an oplock break acknowledgment.
                        bool isIgnoreFor12R2 = smb2Header.Command == Smb2Command.OPLOCK_BREAK && smb2Header.MessageId == ulong.MaxValue && smb2Header.SessionId == 0;
                        if (!isIgnoreFor12R2)
                        {
                            // For client: If the NextCommand field in the first SMB2 header of the message is equal to 0
                            // and SessionId of the first SMB2 header is not equal to the SessionId field in SMB2 TRANSFORM_HEADER of response, the client MUST discard the message.
                            //
                            // For server: For a singleton request if the SessionId field in the SMB2 header of the request is not equal to Request.TransformSessionId,
                            // the server MUST disconnect the connection.
                            throw new InvalidOperationException("SessionId is inconsistent for encrypted response.");
                        }
                    }
                }
                return(DecodeSinglePacket(
                           messageBytes,
                           role,
                           realSessionId,
                           realTreeId,
                           out consumedLength,
                           out expectedLength
                           ));
            }
        }
コード例 #3
0
        /// <summary>
        /// Decode the message as smb2 compound packet
        /// </summary>
        /// <param name="messageBytes">The received packet</param>
        /// <param name="role">The role of this decoder, client or server</param>
        /// <param name="consumedLength">[OUT]The consumed length of the message</param>
        /// <param name="expectedLength">[OUT]The expected length</param>
        /// <param name="transformHeader">The optional transform header</param>
        /// <returns>A Smb2Packet</returns>
        public Smb2Packet DecodeCompoundPacket(
            byte[] messageBytes,
            Smb2Role role,
            out int consumedLength,
            out int expectedLength,
            Transform_Header?transformHeader
            )
        {
            Smb2CompoundPacket compoundPacket = new Smb2CompoundPacket();

            compoundPacket.decoder = this;

            compoundPacket.FromBytes(messageBytes, out consumedLength, out expectedLength);

            VerifyCompoundPacket(compoundPacket, role, transformHeader);

            return(compoundPacket);
        }
コード例 #4
0
        /// <summary>
        /// Decode the message as smb2 packet
        /// </summary>
        /// <param name="messageBytes">The received packet</param>
        /// <param name="role">The role of this decoder, client or server</param>
        /// <param name="realSessionId">The real sessionId for this packet</param>
        /// <param name="realTreeId">The real treeId for this packet</param>
        /// <param name="consumedLength">[OUT]The consumed length of the message</param>
        /// <param name="expectedLength">[OUT]The expected length</param>
        /// <param name="transformHeader">The optional transform header</param>
        /// <returns>A Smb2Packet</returns>
        private Smb2Packet DecodeSmb2Packet(
            byte[] messageBytes,
            Smb2Role role,
            ulong realSessionId,
            uint realTreeId,
            out int consumedLength,
            out int expectedLength,
            Transform_Header?transformHeader
            )
        {
            Packet_Header smb2Header;

            smb2Header = TypeMarshal.ToStruct <Packet_Header>(messageBytes);

            if (smb2Header.NextCommand != 0)
            {
                return(DecodeCompoundPacket(messageBytes, role, out consumedLength, out expectedLength, transformHeader));
            }
            else
            {
                if (transformHeader != null)
                {
                    // For client: If the NextCommand field in the first SMB2 header of the message is equal to 0
                    // and SessionId of the first SMB2 header is not equal to the SessionId field in SMB2 TRANSFORM_HEADER of response, the client MUST discard the message.
                    //
                    // For server: For a singleton request if the SessionId field in the SMB2 header of the request is not equal to Request.TransformSessionId,
                    // the server MUST disconnect the connection.
                    if (smb2Header.SessionId != transformHeader.Value.SessionId)
                    {
                        throw new InvalidOperationException("SessionId is inconsistent for encrypted response.");
                    }
                }
                return(DecodeSinglePacket(
                           messageBytes,
                           role,
                           realSessionId,
                           realTreeId,
                           out consumedLength,
                           out expectedLength
                           ));
            }
        }
コード例 #5
0
        private void VerifyCompoundPacket(Smb2CompoundPacket compoundPacket, Smb2Role role, Transform_Header?transformHeader)
        {
            for (int i = 0; i < compoundPacket.Packets.Count; i++)
            {
                var packet = compoundPacket.Packets[i];

                if (packet.Header.NextCommand % 8 != 0)
                {
                    throw new InvalidOperationException("NextCommand is not a 8-byte aligned offset!");
                }

                switch (role)
                {
                case Smb2Role.Client:
                {
                    if (transformHeader != null)
                    {
                        // For each response in a compounded response, if the SessionId field of SMB2 header is not equal to the SessionId field in the SMB2 TRANSFORM_HEADER,
                        // the client SHOULD<139> discard the entire compounded response and stop processing.
                        if (packet.Header.SessionId != transformHeader.Value.SessionId)
                        {
                            throw new InvalidOperationException("SessionId is inconsistent for encrypted compounded response.");
                        }
                    }
                }
                break;

                case Smb2Role.Server:
                {
                    // The server MUST verify if any of the following conditions returns TRUE and, if so, the server MUST disconnect the connection:
                    // For the first operation of a compounded request,
                    // - SMB2_FLAGS_RELATED_OPERATIONS is set in the Flags field of the SMB2 header of the request
                    // - The SessionId field in the SMB2 header of the request is not equal to Request.TransformSessionId.
                    // In a compounded request, for each operation in the compounded chain except the first one,
                    // - SMB2_FLAGS_RELATED_OPERATIONS is not set in the Flags field of the SMB2 header of the operation and SessionId in the SMB2 header of the operation is not equal to Request.TransformSessionId.
                    if (i == 0)
                    {
                        if (packet.Header.Flags.HasFlag(Packet_Header_Flags_Values.FLAGS_RELATED_OPERATIONS))
                        {
                            throw new InvalidOperationException("FLAGS_RELATED_OPERATIONS should not be set for the first compounded request.");
                        }
                        if (transformHeader != null)
                        {
                            if (packet.Header.SessionId != transformHeader.Value.SessionId)
                            {
                                throw new InvalidOperationException("SessionId is inconsistent for encrypted compounded request.");
                            }
                        }
                    }
                    else
                    {
                        if (transformHeader != null)
                        {
                            if (!packet.Header.Flags.HasFlag(Packet_Header_Flags_Values.FLAGS_RELATED_OPERATIONS))
                            {
                                if (packet.Header.SessionId != transformHeader.Value.SessionId)
                                {
                                    throw new InvalidOperationException("SessionId is inconsistent for encrypted compounded request.");
                                }
                            }
                        }
                    }
                }
                break;
                }
            }
        }