示例#1
0
    def _from_bytes_and_header(cls, data: memoryview,
                               header: Header) -> SessionSetupRequest:
        super()._from_bytes_and_header(data=data, header=header)

        body_data: memoryview = data[len(header):]

        if bytes(body_data[8:12]) != cls._RESERVED_CHANNEL:
            # TODO: Use proper exception.
            raise ValueError

        security_buffer_offset: int = unpack_from('<H',
                                                  buffer=body_data,
                                                  offset=12)[0]
        security_buffer_length: int = unpack_from('<H',
                                                  buffer=body_data,
                                                  offset=14)[0]

        return cls(header=header,
                   flags=SessionSetupRequestFlag(
                       unpack_from('<B', buffer=body_data, offset=2)[0]),
                   security_mode=SecurityMode(
                       unpack_from('<B', buffer=body_data, offset=3)[0]),
                   capabilities=CapabilitiesFlag.from_int(
                       unpack_from('<I', buffer=body_data, offset=4)[0]),
                   previous_session_id=bytes(body_data[16:24]),
                   security_buffer=bytes(
                       data[security_buffer_offset:security_buffer_offset +
                            security_buffer_length]))
示例#2
0
    def _from_bytes_and_header(cls, data: memoryview,
                               header: Header) -> NegotiateResponse:
        super()._from_bytes_and_header(data=data, header=header)

        body_data: memoryview = data[len(header):]

        dialect_revision = Dialect(
            unpack_from('<H', buffer=body_data, offset=4)[0])
        security_buffer_offset: int = unpack_from('<H',
                                                  buffer=body_data,
                                                  offset=56)[0]
        security_buffer_length: int = unpack_from('<H',
                                                  buffer=body_data,
                                                  offset=58)[0]

        base_kwargs = dict(
            header=header,
            dialect_revision=dialect_revision,
            security_mode=SecurityMode.from_int(
                value=unpack_from('<H', buffer=body_data, offset=2)[0]),
            # TODO: Cannot do it from a `memoryview`?
            server_guid=UUID(bytes=bytes(body_data[8:24])),
            capabilities=CapabilitiesFlag.from_int(
                unpack_from('<I', buffer=body_data, offset=24)[0]),
            max_transact_size=unpack_from('<I', buffer=body_data,
                                          offset=28)[0],
            max_read_size=unpack_from('<I', buffer=body_data, offset=32)[0],
            max_write_size=unpack_from('<I', buffer=body_data, offset=36)[0],
            _system_time=unpack_from('<Q', buffer=data, offset=40)[0],
            _server_start_time=unpack_from('<Q', buffer=data, offset=48)[0],
            security_buffer=data[
                security_buffer_offset:security_buffer_offset +
                security_buffer_length])

        # TODO: Use a map?

        if dialect_revision == Dialect.SMB_3_1_1:
            negotiate_context_offset: int = unpack_from('<I',
                                                        buffer=body_data,
                                                        offset=60)[0]
            return SMB311NegotiateResponse(
                **base_kwargs,
                negotiate_context_list=NegotiateContextList.from_bytes(
                    data=body_data[negotiate_context_offset - len(header):],
                    num_contexts=unpack_from('<I', buffer=body_data,
                                             offset=6)[0]))
        elif dialect_revision is Dialect.SMB_2_0_2:
            return SMB202NegotiateResponse(**base_kwargs)
        elif dialect_revision is Dialect.SMB_2_1:
            return SMB210NegotiateResponse(**base_kwargs)
        elif dialect_revision is Dialect.SMB_3_0:
            return SMB300NegotiateResponse(**base_kwargs)
        elif dialect_revision is Dialect.SMB_3_0_2:
            return SMB302NegotiateResponse(**base_kwargs)
        elif dialect_revision is Dialect.SMB_2_WILDCARD:
            return SMB2WildcardNegotiateResponse(**base_kwargs)
        else:
            # TODO: Use proper exception.
            raise ValueError
示例#3
0
class SessionSetupRequest(RequestMessage):
    STRUCTURE_SIZE: ClassVar[int] = 25
    COMMAND: ClassVar[SMBv2Command] = SMBv2Command.SMB2_SESSION_SETUP
    MALFORMED_ERROR_CLASS: ClassVar[
        Type[MalformedSMBv2MessageError]] = MalformedSessionSetupRequestError
    RESPONSE_MESSAGE_CLASS: ClassVar[ResponseMessage] = SessionSetupResponse
    _RESERVED_CHANNEL: ClassVar[bytes] = bytes(4)

    security_mode: SecurityMode
    security_buffer: bytes
    flags: SessionSetupRequestFlag = SessionSetupRequestFlag.SMB2_SESSION_FLAG_NONE
    capabilities: CapabilitiesFlag = CapabilitiesFlag()
    previous_session_id: bytes = bytes(8)

    @classmethod
    def _from_bytes_and_header(cls, data: memoryview,
                               header: Header) -> SessionSetupRequest:
        super()._from_bytes_and_header(data=data, header=header)

        body_data: memoryview = data[len(header):]

        if bytes(body_data[8:12]) != cls._RESERVED_CHANNEL:
            # TODO: Use proper exception.
            raise ValueError

        security_buffer_offset: int = unpack_from('<H',
                                                  buffer=body_data,
                                                  offset=12)[0]
        security_buffer_length: int = unpack_from('<H',
                                                  buffer=body_data,
                                                  offset=14)[0]

        return cls(header=header,
                   flags=SessionSetupRequestFlag(
                       unpack_from('<B', buffer=body_data, offset=2)[0]),
                   security_mode=SecurityMode(
                       unpack_from('<B', buffer=body_data, offset=3)[0]),
                   capabilities=CapabilitiesFlag.from_int(
                       unpack_from('<I', buffer=body_data, offset=4)[0]),
                   previous_session_id=bytes(body_data[16:24]),
                   security_buffer=bytes(
                       data[security_buffer_offset:security_buffer_offset +
                            security_buffer_length]))

    def __len__(self) -> int:
        return len(self.header) + 24 + len(self.security_buffer)

    def __bytes__(self) -> bytes:
        return bytes(self.header) + b''.join([
            pack('<H', 25),
            pack('<B', self.flags.value),
            pack('<B', int(self.security_mode)),
            pack('<I', int(self.capabilities)), self._RESERVED_CHANNEL,
            pack('<H',
                 len(self.header) + 24),
            pack('<H', len(self.security_buffer)), self.previous_session_id,
            self.security_buffer
        ])
示例#4
0
    def _from_bytes_and_header(cls, data: bytes,
                               header: Header) -> NegotiateResponse:

        body_data: bytes = data[len(header):]

        try:
            cls.check_structure_size(
                structure_size_to_test=struct_unpack('<H', body_data[:2])[0])
        except IncorrectStructureSizeError as e:
            raise MalformedNegotiateResponseError(str(e)) from e

        dialect_revision = Dialect(struct_unpack('<H', body_data[4:6])[0])
        security_buffer_offset: int = struct_unpack('<H', body_data[56:58])[0]
        security_buffer_length: int = struct_unpack('<H', body_data[58:60])[0]

        base_kwargs = dict(
            header=header,
            dialect_revision=dialect_revision,
            security_mode=SecurityMode(struct_unpack('<H', body_data[2:4])[0]),
            server_guid=UUID(bytes=body_data[8:24]),
            capabilities=CapabilitiesFlag.from_int(
                struct_unpack('<I', body_data[24:28])[0]),
            max_transact_size=struct_unpack('<I', body_data[28:32])[0],
            max_read_size=struct_unpack('<I', body_data[32:36])[0],
            max_write_size=struct_unpack('<I', body_data[36:40])[0],
            _system_time=struct_unpack('<Q', data[40:48])[0],
            _server_start_time=struct_unpack('<Q', data[48:56])[0],
            security_buffer=data[
                security_buffer_offset:security_buffer_offset +
                security_buffer_length])

        # TODO: Use a map?

        if dialect_revision == Dialect.SMB_3_1_1:
            negotiate_context_offset: int = struct_unpack(
                '<I', body_data[60:64])[0]
            return SMB311NegotiateResponse(
                **base_kwargs,
                negotiate_context_list=NegotiateContextList.from_bytes(
                    data=body_data[negotiate_context_offset - len(header):],
                    num_contexts=struct_unpack('<I', body_data[6:8])[0]))
        elif dialect_revision is Dialect.SMB_2_0_2:
            return SMB202NegotiateResponse(**base_kwargs)
        elif dialect_revision is Dialect.SMB_2_1:
            return SMB210NegotiateResponse(**base_kwargs)
        elif dialect_revision is Dialect.SMB_3_0:
            return SMB300NegotiateResponse(**base_kwargs)
        elif dialect_revision is Dialect.SMB_3_0_2:
            return SMB302NegotiateResponse(**base_kwargs)
        elif dialect_revision is Dialect.SMB_2_WILDCARD:
            return SMB2WildcardNegotiateResponse(**base_kwargs)
        else:
            # TODO: Use proper exception.
            raise ValueError
示例#5
0
class SessionSetupRequest(RequestMessage):
    STRUCTURE_SIZE: ClassVar[int] = 25
    COMMAND: ClassVar[SMBv2Command] = SMBv2Command.SMB2_SESSION_SETUP
    RESPONSE_MESSAGE_CLASS: ClassVar[ResponseMessage] = SessionSetupResponse
    _RESERVED_CHANNEL: ClassVar[bytes] = bytes(4)

    security_mode: SecurityMode
    security_buffer: bytes
    flags: SessionSetupRequestFlag = SessionSetupRequestFlag.SMB2_SESSION_FLAG_NONE
    capabilities: CapabilitiesFlag = CapabilitiesFlag()
    previous_session_id: bytes = bytes(8)

    @classmethod
    def _from_bytes_and_header(cls, data: bytes, header: Header):

        body_data: bytes = data[len(header):]

        try:
            cls.check_structure_size(structure_size_to_test=struct_unpack('<H', body_data[:2])[0])
        except IncorrectStructureSizeError as e:
            raise MalformedSessionSetupRequestError(str(e)) from e

        if body_data[8:12] != cls._RESERVED_CHANNEL:
            # TODO: Use proper exception.
            raise ValueError

        security_buffer_offset: int = struct_unpack('<H', body_data[12:14])[0]
        security_buffer_length: int = struct_unpack('<H', body_data[14:16])[0]

        return cls(
            header=header,
            flags=SessionSetupRequestFlag(struct_unpack('<B', body_data[2:3])[0]),
            security_mode=SecurityMode(struct_unpack('<B', body_data[3:4])[0]),
            capabilities=CapabilitiesFlag.from_int(struct_unpack('<I', body_data[4:8])[0]),
            previous_session_id=body_data[16:24],
            security_buffer=data[security_buffer_offset:security_buffer_offset+security_buffer_length]
        )

    def __len__(self) -> int:
        return len(self.header) + 24 + len(self.security_buffer)

    def __bytes__(self) -> bytes:
        return bytes(self.header) + b''.join([
            struct_pack('<H', 25),
            struct_pack('<B', self.flags.value),
            struct_pack('<B', self.security_mode.value),
            struct_pack('<I', int(self.capabilities)),
            self._RESERVED_CHANNEL,
            struct_pack('<H', len(self.header) + 24),
            struct_pack('<H', len(self.security_buffer)),
            self.previous_session_id,
            self.security_buffer
        ])
示例#6
0
    def _from_bytes_and_header(cls, data: bytes, header: Header):

        body_data: bytes = data[len(header):]

        try:
            cls.check_structure_size(structure_size_to_test=struct_unpack('<H', body_data[:2])[0])
        except IncorrectStructureSizeError as e:
            raise MalformedSessionSetupRequestError(str(e)) from e

        if body_data[8:12] != cls._RESERVED_CHANNEL:
            # TODO: Use proper exception.
            raise ValueError

        security_buffer_offset: int = struct_unpack('<H', body_data[12:14])[0]
        security_buffer_length: int = struct_unpack('<H', body_data[14:16])[0]

        return cls(
            header=header,
            flags=SessionSetupRequestFlag(struct_unpack('<B', body_data[2:3])[0]),
            security_mode=SecurityMode(struct_unpack('<B', body_data[3:4])[0]),
            capabilities=CapabilitiesFlag.from_int(struct_unpack('<I', body_data[4:8])[0]),
            previous_session_id=body_data[16:24],
            security_buffer=data[security_buffer_offset:security_buffer_offset+security_buffer_length]
        )
示例#7
0
    def _from_bytes_and_header(cls, data: bytes,
                               header: Header) -> NegotiateRequest:

        body_data: bytes = data[len(header):]

        try:
            cls.check_structure_size(
                structure_size_to_test=struct_unpack('<H', body_data[:2])[0])
        except IncorrectStructureSizeError as e:
            raise MalformedNegotiateRequestError(str(e)) from e

        dialect_count: int = struct_unpack('<H', body_data[2:4])[0]
        if dialect_count <= 0:
            raise NoNegotiateDialectsError(
                observed_dialect_count=dialect_count)

        dialects: Tuple[Dialect, ...] = tuple(
            Dialect(dialect_value) for dialect_value in struct_unpack(
                f'<{dialect_count * "H"}', body_data[36:36 +
                                                     dialect_count * 2]))
        body_base_kwargs = dict(
            security_mode=SecurityMode(struct_unpack('<H', body_data[4:6])[0]),
            # TODO: The bytes may need to be reorder.
            client_guid=UUID(bytes=body_data[12:28]),
            dialects=dialects)

        if any(dialect in dialects for dialect in
               [Dialect.SMB_3_1_1, Dialect.SMB_3_0_2, Dialect.SMB_3_0]):
            capabilities = CapabilitiesFlag.from_int(
                struct_unpack(f'<{dialect_count * "H"}',
                              body_data[36:36 + dialect_count * 2]))

            if Dialect.SMB_3_1_1 in dialects:
                negotiate_context_offset = struct_unpack(
                    '<H', body_data[28:32])[0]
                negotiate_context_count = struct_unpack(
                    '<H', body_data[32:34])[0]

                return SMB311NegotiateRequest(
                    header=header,
                    **body_base_kwargs,
                    capabilities=capabilities,
                    negotiate_context_list=NegotiateContextList.from_bytes(
                        data=body_data[negotiate_context_offset -
                                       len(header):],
                        num_contexts=negotiate_context_count))
            elif Dialect.SMB_3_0_2 in dialects:
                return SMB302NegotiateRequest(header=header,
                                              **body_base_kwargs,
                                              capabilities=capabilities)
            elif Dialect.SMB_3_0 in dialects:
                return SMB300NegotiateRequest(header=header,
                                              **body_base_kwargs,
                                              capabilities=capabilities)
            else:
                raise NotImplementedNegotiateRequestError(
                    f'Expected `dialects` to include one of SMB_3_1_1, SMB_3_0_2, and SMB_3_0, observed {dialects}.'
                )
        elif any(dialect in dialects
                 for dialect in [Dialect.SMB_2_1, Dialect.SMB_2_0_2]):
            capabilities_value = body_data[8:12]
            if capabilities_value != b'\x00\x00\x00\x00':
                raise NegotiateRequestCapabilitiesNotEmpty(
                    observed_capabilities_value=capabilities_value)

            # TODO: Do something with this?
            client_start_time = body_data[28:36]

            if Dialect.SMB_2_1 in dialects:
                return SMB210NegotiateRequest(header=header,
                                              **body_base_kwargs)
            elif Dialect.SMB_2_0_2 in dialects:
                return SMB202NegotiateRequest(header=header,
                                              **body_base_kwargs)
            else:
                raise NotImplementedNegotiateRequestError(
                    f'Expected `dialects` to include one of SMB_2_1 and SMB_2_0_2, observed {dialects}.'
                )
        else:
            raise NotImplementedNegotiateRequestError(
                f'Expected `dialects` to include one of SMB_2_1 and SMB_2_0_2, observed {dialects}.'
            )
示例#8
0
    def _from_bytes_and_header(cls, data: memoryview,
                               header: Header) -> NegotiateRequest:
        super()._from_bytes_and_header(data=data, header=header)

        body_data: memoryview = data[len(header):]

        dialect_count: int = unpack_from('<H', buffer=body_data, offset=2)[0]
        if dialect_count <= 0:
            raise NoNegotiateDialectsError(
                observed_dialect_count=dialect_count)

        dialects: Tuple[Dialect, ...] = tuple(
            Dialect(dialect_value) for dialect_value in unpack_from(
                f'<{dialect_count * "H"}', buffer=body_data, offset=36))
        body_base_kwargs = dict(
            security_mode=SecurityMode(
                unpack_from('<H', buffer=body_data, offset=4)[0]),
            # TODO: The bytes may need to be reorder.
            client_guid=UUID(bytes=bytes(body_data[12:28])),
            dialects=dialects)

        if any(dialect in dialects for dialect in
               [Dialect.SMB_3_1_1, Dialect.SMB_3_0_2, Dialect.SMB_3_0]):
            capabilities = CapabilitiesFlag.from_int(
                unpack_from(f'<{dialect_count * "H"}',
                            buffer=body_data,
                            offset=36))

            if Dialect.SMB_3_1_1 in dialects:
                negotiate_context_offset = unpack_from('<H',
                                                       buffer=body_data,
                                                       offset=28)[0]
                negotiate_context_count = unpack_from('<H',
                                                      buffer=body_data,
                                                      offset=32)[0]

                return SMB311NegotiateRequest(
                    header=header,
                    **body_base_kwargs,
                    capabilities=capabilities,
                    negotiate_context_list=NegotiateContextList.from_bytes(
                        data=body_data[negotiate_context_offset -
                                       len(header):],
                        num_contexts=negotiate_context_count))
            elif Dialect.SMB_3_0_2 in dialects:
                return SMB302NegotiateRequest(header=header,
                                              **body_base_kwargs,
                                              capabilities=capabilities)
            elif Dialect.SMB_3_0 in dialects:
                return SMB300NegotiateRequest(header=header,
                                              **body_base_kwargs,
                                              capabilities=capabilities)
            else:
                raise NotImplementedNegotiateRequestError(
                    f'Expected `dialects` to include one of SMB_3_1_1, SMB_3_0_2, and SMB_3_0, observed {dialects}.'
                )
        elif any(dialect in dialects
                 for dialect in [Dialect.SMB_2_1, Dialect.SMB_2_0_2]):
            capabilities_value = body_data[8:12]
            if capabilities_value != bytes(4):
                raise NegotiateRequestCapabilitiesNotEmpty(
                    observed_capabilities_value=capabilities_value)

            # TODO: Do something with this?
            client_start_time = body_data[28:36]

            if Dialect.SMB_2_1 in dialects:
                return SMB210NegotiateRequest(header=header,
                                              **body_base_kwargs)
            elif Dialect.SMB_2_0_2 in dialects:
                return SMB202NegotiateRequest(header=header,
                                              **body_base_kwargs)
            else:
                raise NotImplementedNegotiateRequestError(
                    f'Expected `dialects` to include one of SMB_2_1 and SMB_2_0_2, observed {dialects}.'
                )
        else:
            raise NotImplementedNegotiateRequestError(
                f'Expected `dialects` to include one of SMB_2_1 and SMB_2_0_2, observed {dialects}.'
            )