コード例 #1
0
ファイル: challenge.py プロジェクト: vphpersson/ntlm
    def _from_bytes(cls,
                    buffer: memoryview,
                    strict: bool = True) -> ChallengeMessage:
        # TODO: Check reserved.

        target_name_offset: int = struct_unpack_from('<I',
                                                     buffer=buffer,
                                                     offset=16)[0]
        target_info_offset: int = struct_unpack_from('<I',
                                                     buffer=buffer,
                                                     offset=44)[0]

        payload_offset_start: int = min(target_name_offset, target_info_offset)

        target_info_bytes: bytes = get_message_bytes_data(
            buffer, *struct_unpack_from('<HH', buffer=buffer, offset=40),
            target_info_offset)

        return cls(
            target_name=get_message_bytes_data_str(
                buffer, *struct_unpack_from('<HH', buffer=buffer, offset=12),
                target_name_offset),
            negotiate_flags=NegotiateFlags.from_int(
                value=struct_unpack_from('<I', buffer=buffer, offset=20)[0]),
            challenge=bytes(buffer[24:32]),
            target_info=AVPairSequence.from_bytes(buffer=target_info_bytes,
                                                  break_on_eol=True)
            if target_info_bytes else None,
            os_version=Version.from_bytes(buffer=buffer, base_offset=48)
            if payload_offset_start != 48 else None)
コード例 #2
0
    def from_bytes(cls,
                   buffer: ByteString,
                   base_offset: int = 0,
                   strict: bool = True):
        if cls == NTLMSSPMessageSignature:
            raise NotImplementedError

        if strict and (version := struct_unpack_from(
                '<I', buffer=buffer, offset=base_offset)) != cls.VERSION:
            # TODO: Use proper exception (the parse one?)
            raise ValueError
コード例 #3
0
    def from_bytes(cls,
                   buffer: ByteString,
                   base_offset: int = 0,
                   strict: bool = True) -> Message:

        import ntlm.messages.negotiate
        import ntlm.messages.challenge
        import ntlm.messages.authenticate

        buffer = memoryview(buffer)[base_offset:]

        if strict and (signature := struct_unpack_from(
                '<8s', buffer=buffer, offset=0)[0]) != cls.SIGNATURE:
            raise MalformedSignatureError(observed_signature=signature)
コード例 #4
0
    def from_bytes(cls,
                   buffer: ByteString,
                   base_offset: int = 0,
                   strict: bool = True,
                   break_on_eol: bool = False) -> AVPairSequence:

        buffer = memoryview(buffer)[base_offset:]

        offset = 0
        eol_observed = False
        av_pairs_list: List[AVPair] = []

        while offset + 4 <= len(buffer):
            av_pair = AVPair.from_bytes(buffer=buffer[offset:])
            av_pairs_list.append(av_pair)

            if isinstance(av_pair, EOLAVPair):
                if strict and eol_observed:
                    raise MultipleEOLError

                eol_observed = True
                if break_on_eol:
                    break

            av_len: int = struct_unpack_from('<H',
                                             buffer=buffer,
                                             offset=offset + 2)[0]
            offset += 4 + av_len

        if strict and not eol_observed:
            raise EOLNotObservedError

        return cls(av_pairs_list)
コード例 #5
0
    def from_bytes(cls, buffer: ByteString, base_offset: int = 0) -> AVPair:

        from ntlm.structures.av_pairs.single_host_data import SingleHostDataAVPair
        from ntlm.structures.av_pairs.dns_tree_name import DnsTreeNameAVPair
        from ntlm.structures.av_pairs.channel_bindings import ChannelBindingsAVPair
        from ntlm.structures.av_pairs.target_name import TargetNameAVPair
        from ntlm.structures.av_pairs.dns_computer_name import DnsComputerNameAVPair
        from ntlm.structures.av_pairs.flags import FlagsAVPair
        from ntlm.structures.av_pairs.domain_name import DomainNameAVPair
        from ntlm.structures.av_pairs.timestamp import TimestampAVPair
        from ntlm.structures.av_pairs.computer_name import ComputerNameAVPair
        from ntlm.structures.av_pairs.eol import EOLAVPair
        from ntlm.structures.av_pairs.dns_domain_name import DnsDomainNameAVPair

        buffer = memoryview(buffer)[base_offset:]

        av_id, av_len = struct_unpack_from('<HH', buffer=buffer, offset=0)
        value_bytes: bytes = get_message_bytes_data(buffer=buffer,
                                                    length=av_len,
                                                    alloc=0,
                                                    offset=4)

        if cls != AVPair:
            if av_id != cls.AV_ID:
                # TODO: Use proper exception.
                raise ValueError
            return cls.from_value_bytes(value_bytes=value_bytes)
        else:
            return cls.AV_ID_TO_AV_PAIR_CLASS[av_id].from_value_bytes(
                value_bytes=value_bytes)
コード例 #6
0
ファイル: bolt.py プロジェクト: deeru10/Crawler_testing
 def chunk_reader(self):
     chunk_size = -1
     while chunk_size != 0:
         chunk_header = self._recv(2)
         chunk_size, = struct_unpack_from(">H", chunk_header)
         if chunk_size > 0:
             data = self._recv(chunk_size)
             yield data
コード例 #7
0
 def chunk_reader(self):
     chunk_size = -1
     while chunk_size != 0:
         chunk_header = self._recv(2)
         chunk_size, = struct_unpack_from(">H", chunk_header)
         if chunk_size > 0:
             data = self._recv(chunk_size)
             yield data
コード例 #8
0
 def _from_bytes(cls,
                 buffer: memoryview,
                 strict: bool = True) -> AuthenticateMessage:
     return cls(
         lm_challenge_response=get_message_bytes_data(
             buffer,
             *struct_unpack_from('<HHI', buffer=buffer, offset=12),
         ),
         nt_challenge_response=NTLMv2Response.from_bytes(
             buffer=get_message_bytes_data(
                 buffer,
                 *struct_unpack_from('<HHI', buffer=buffer, offset=20),
             )),
         domain_name=get_message_bytes_data_str(
             buffer, *struct_unpack_from('<HHI', buffer=buffer, offset=28)),
         user_name=get_message_bytes_data_str(
             buffer, *struct_unpack_from('<HHI', buffer=buffer, offset=36)),
         workstation_name=get_message_bytes_data_str(
             buffer, *struct_unpack_from('<HHI', buffer=buffer, offset=44)),
         encrypted_random_session_key=get_message_bytes_data(
             buffer, *struct_unpack_from('<HHI', buffer=buffer, offset=52)),
         negotiate_flags=NegotiateFlags.from_int(
             value=struct_unpack_from('<I', buffer=buffer, offset=60)[0]),
         os_version=Version.from_bytes(buffer=buffer, base_offset=64),
         mic=bytes(buffer[72:88]))
コード例 #9
0
 def from_bytes(cls,
                data: bytes,
                size_per_element: int = 1) -> UnidimensionalConformantArray:
     try:
         maximum_count: int = struct_unpack('<I', data[:4])[0]
         return cls(representation=tuple(
             bytes(
                 struct_unpack_from(size_per_element * 'B',
                                    buffer=data[4:],
                                    offset=i * size_per_element))
             for i in range(maximum_count)))
     except struct_error as e:
         raise ValueError from e
コード例 #10
0
    def _from_bytes(cls,
                    buffer: memoryview,
                    strict: bool = True) -> NegotiateMessage:
        domain_name_offset: int = struct_unpack_from('<I',
                                                     buffer=buffer,
                                                     offset=20)[0]
        workstation_name_offset: int = struct_unpack_from('<I',
                                                          buffer=buffer,
                                                          offset=28)[0]

        payload_offset_start: int = min(domain_name_offset,
                                        workstation_name_offset)

        return cls(
            negotiate_flags=NegotiateFlags.from_int(
                value=struct_unpack_from('<I', buffer=buffer, offset=12)[0]),
            domain_name=get_message_bytes_data_str(
                buffer, *struct_unpack_from('<HH', buffer[16:20]),
                domain_name_offset),
            workstation_name=get_message_bytes_data_str(
                buffer, *struct_unpack_from('<HH', buffer[24:28]),
                workstation_name_offset),
            os_version=Version.from_bytes(
                buffer=buffer[32:40]) if payload_offset_start != 32 else None)
コード例 #11
0
    def from_bytes(cls,
                   buffer: ByteString,
                   base_offset: int = 0,
                   strict: bool = True):

        buffer = memoryview(buffer)[base_offset:]

        super().from_bytes(buffer=buffer,
                           base_offset=base_offset,
                           strict=strict)

        return cls(checksum=buffer[base_offset + 4:base_offset + 12],
                   seq_num=struct_unpack_from('<I',
                                              buffer=buffer,
                                              offset=base_offset + 12)[0])
コード例 #12
0
ファイル: __init__.py プロジェクト: vphpersson/bloom_filter
    def import_bytes(cls, data: bytes, hash_function=None, base_offset: int = 0) -> BloomFilter:
        """
        Import an exported `BloomFilter` byte sequence and make an instance.

        :param data: A byte sequence from which to extract the data representing a `BloomFilter`.
        :param hash_function: A hash function to use in case the exported name cannot be looked up in the `hashlib`.
            module.
        :param base_offset: The offset from the start of the byte sequence from where to start extracting.
        :return: A `BloomFilter` instance as represented by the pointed-to byte sequence.
        """

        offset = base_offset

        capacity = struct_unpack_from('>Q', buffer=data, offset=offset)[0]
        offset += struct_calcsize('>Q')

        false_positive_probability = struct_unpack_from('f', buffer=data, offset=offset)[0]
        offset += struct_calcsize('f')

        hash_function_name_bytes_len: int = struct_unpack_from(cls._IMPORT_EXPORT_LENGTH_FORMAT, buffer=data, offset=offset)[0]
        offset += struct_calcsize(cls._IMPORT_EXPORT_LENGTH_FORMAT)
        hash_function_name: str = data[offset:offset+hash_function_name_bytes_len].decode()
        offset += hash_function_name_bytes_len

        bit_array_bytes_len: int = struct_unpack_from(cls._IMPORT_EXPORT_LENGTH_FORMAT, buffer=data, offset=offset)[0]
        offset += struct_calcsize(cls._IMPORT_EXPORT_LENGTH_FORMAT)

        bit_array = bitarray()
        bit_array.frombytes(data[offset:offset + bit_array_bytes_len])

        return cls(
            capacity=capacity,
            false_positive_probability=false_positive_probability,
            hash_function=hash_function or getattr(hashlib, hash_function_name),
            bit_array=bit_array
        )
コード例 #13
0
def dos_time_to_timedelta(dos_time: Union[IntLike, ByteString],
                          offset: IntLike = 0) -> timedelta:
    """
    Convert a DOS time value to a `timedelta` value.

    :param dos_time: A DOS time value as an integer or byte byte string.
    :param offset: An offset in the input value, in case it is a byte string, from where to extract the DOS time integer
        value.
    :return: The DOS time as a `timedelta` instance.
    """

    dos_time: int = int(dos_time if is_int_like(
        value=dos_time
    ) else struct_unpack_from('<H', buffer=dos_time, offset=int(offset))[0])

    return timedelta(
        # Number of "two-seconds", thus shift left by one (multiply by two).
        seconds=(dos_time & 0b0000_0000_0001_1111) << 1,
        minutes=(dos_time & 0b0000_0111_1110_0000) >> 5,
        hours=(dos_time & 0b1111_1000_0000_0000) >> 11)
コード例 #14
0
def dos_date_to_datetime(dos_date: Union[IntLike, ByteString],
                         offset: IntLike = 0) -> Optional[datetime]:
    """
    Convert a DOS date value to a `datetime` value.

    :param dos_date: A DOS date value as an integer or byte string.
    :param offset: An offset in the input value, in case it is byte string, from where to extract the DOS date integer
        value.
    :return: The DOS time as a `datetime` instance, or `None` of the DOS date value is blank.
    """

    dos_date: int = int(dos_date if is_int_like(
        value=dos_date
    ) else struct_unpack_from('<H', buffer=dos_date, offset=int(offset))[0])

    return datetime(year=FAT_TIME_INCEPTION_YEAR +
                    ((dos_date & 0b1111_1110_0000_0000) >> 9),
                    month=((dos_date & 0b0000_0001_1110_0000) >> 5) or 1,
                    day=(dos_date & 0b0000_0000_0001_1111)
                    or 1) if dos_date else None
コード例 #15
0
def filetime_to_datetime(filetime: Union[IntLike, ByteString],
                         offset: IntLike = 0) -> Optional[datetime]:
    """
    Convert a `FILETIME` value to a datetime object.

    A `FILETIME` value represents a period as a count of 100-nanosecond time slices. When interpreted as a
    timestamp, it should be considered in relation to the inception of the Windows epoch date: 1601-01-01.

    NOTE: There is a loss of precision when converting to a `datetime` object (tenth of a microsecond), because
    `datetime` only has microsecond precision.

    :param filetime: A `FILETIME` value as an integer or bytes.
    :param offset: An offset in the input value, in case it is a byte string, from where the extract the `FILETIME`
        integer value.
    :return: A datetime object corresponding to the provided timestamp; `None` if it is blank.
    """

    filetime: int = int(filetime if is_int_like(
        value=filetime
    ) else struct_unpack_from('<Q', buffer=filetime, offset=int(offset))[0])

    return (MS_EPOCH_INCEPTION +
            timedelta(microseconds=filetime // 10)) if filetime else None
コード例 #16
0
class Message(ABC):
    SIGNATURE: ClassVar[bytes] = b'NTLMSSP\x00'
    MESSAGE_TYPE_ID_TO_MESSAGE_CLASS: ClassVar[Dict[int, Type[Message]]] = {}

    MESSAGE_TYPE_ID: ClassVar[int] = NotImplemented
    MALFORMED_MESSAGE_ERROR_CLASS: ClassVar[
        Type[MalformedMessageError]] = NotImplementedError

    @classmethod
    def from_bytes(cls,
                   buffer: ByteString,
                   base_offset: int = 0,
                   strict: bool = True) -> Message:

        import ntlm.messages.negotiate
        import ntlm.messages.challenge
        import ntlm.messages.authenticate

        buffer = memoryview(buffer)[base_offset:]

        if strict and (signature := struct_unpack_from(
                '<8s', buffer=buffer, offset=0)[0]) != cls.SIGNATURE:
            raise MalformedSignatureError(observed_signature=signature)

        message_type_id: int = struct_unpack_from('<I',
                                                  buffer=buffer,
                                                  offset=8)[0]

        if cls != Message:
            if message_type_id != cls.MESSAGE_TYPE_ID:
                raise UnexpectedMessageTypeError(
                    observed_ntlm_message_type_id=message_type_id,
                    expected_message_type_id=cls.MESSAGE_TYPE_ID)
            return cls._from_bytes(buffer=buffer, strict=strict)
        else:
            return cls.MESSAGE_TYPE_ID_TO_MESSAGE_CLASS[
                message_type_id].from_bytes(buffer=buffer, strict=strict)
コード例 #17
0
ファイル: flags.py プロジェクト: vphpersson/ntlm
 def from_value_bytes(cls, value_bytes: bytes) -> FlagsAVPair:
     return cls(flags=AvFlags.from_int(
         value=struct_unpack_from('<I', buffer=value_bytes)[0]))
コード例 #18
0
ファイル: timestamp.py プロジェクト: vphpersson/ntlm
 def from_value_bytes(cls, value_bytes: bytes) -> TimestampAVPair:
     return cls(
         filetime=value_bytes,
         timestamp=filetime_to_datetime(
             filetime=struct_unpack_from('<Q', buffer=value_bytes)[0]))
コード例 #19
0
ファイル: base.py プロジェクト: adamchainz/mariadb-dyncol
def unpack(buf):
    """
    Convert MariaDB dynamic columns data in a byte string into a dict
    """
    flags, column_count, len_names = struct_unpack_from('<BHH', buf)
    data_offset_code, coldata_size, data_offset_mask = decode_data_size(flags)
    if (flags & 0xFC) != 4:
        raise DynColValueError("Unknown dynamic columns format")

    if column_count == 0:
        return {}

    column_directory_end = (1 + 2 + 2) + coldata_size * column_count
    names_end = column_directory_end + len_names

    column_directory = buf[(1 + 2 + 2):column_directory_end]
    enc_names = buf[column_directory_end:names_end]
    data = buf[names_end:]

    names = {}
    values = {}

    last_name_offset = None
    last_data_offset = None
    last_dtype = None

    for i in six_moves_range(column_count):
        if coldata_size % 2 == 0:
            name_offset, data_offset_dtype = struct_unpack_from(
                '<H' + data_offset_code,
                column_directory,
                offset=i * coldata_size
            )
        else:
            name_offset, = struct_unpack_from(
                '<H',
                column_directory,
                offset=i * coldata_size
            )
            # can't struct_unpack the 3 bytes so hack around
            dodt_bytes = column_directory[(i * coldata_size + 2):
                                          (i * coldata_size + 5)] + b'\x00'
            data_offset_dtype, = struct_unpack('<' + data_offset_code,
                                               dodt_bytes)

        data_offset_dtype &= data_offset_mask
        data_offset = data_offset_dtype >> 4
        dtype = data_offset_dtype & 0xF

        # Store *last* column's name
        if last_name_offset is not None:
            names[i - 1] = (
                enc_names[last_name_offset:name_offset].decode('utf-8')
            )
        last_name_offset = name_offset

        #
        if last_data_offset is not None:
            values[i - 1] = decode(last_dtype,
                                   data[last_data_offset:data_offset])
        last_data_offset = data_offset
        last_dtype = dtype

    names[column_count - 1] = enc_names[last_name_offset:].decode('utf-8')
    values[column_count - 1] = decode(last_dtype, data[last_data_offset:])

    # join data and names
    return {
        names[i]: values[i]
        for i in six_moves_range(column_count)
    }
コード例 #20
0
    @classmethod
    def from_bytes(cls,
                   buffer: ByteString,
                   base_offset: int = 0,
                   strict: bool = True) -> Version:
        buffer = memoryview(buffer)[base_offset:]

        if strict:
            if (reserved := bytes(buffer[4:7])) != cls._RESERVED:
                # TODO: Use proper exception
                raise ValueError

            if (ntlm_revision_current :=
                    buffer[7]) != cls._NTLMRevisionCurrent:
                # TODO: Use proper exception
                raise ValueError

        return cls(major_version_number=buffer[0],
                   minor_version_number=buffer[1],
                   build_number=struct_unpack_from('<H',
                                                   buffer=buffer,
                                                   offset=2)[0])

    def __bytes__(self):
        return b''.join([
            struct_pack('<B', self.major_version_number),
            struct_pack('<B', self.minor_version_number),
            struct_pack('<H', self.build_number), self._RESERVED,
            struct_pack('<B', self._NTLMRevisionCurrent)
        ])
コード例 #21
0
ファイル: base.py プロジェクト: ratanboddu/WorkingPrototype
def unpack(buf):
    """
    Convert MariaDB dynamic columns data in a byte string into a dict
    """
    flags, column_count, len_names = struct_unpack_from('<BHH', buf)
    data_offset_code, coldata_size, data_offset_mask = decode_data_size(flags)
    if (flags & 0xFC) != 4:
        raise DynColValueError("Unknown dynamic columns format")

    if column_count == 0:
        return {}

    column_directory_end = (1 + 2 + 2) + coldata_size * column_count
    names_end = column_directory_end + len_names

    column_directory = buf[(1 + 2 + 2):column_directory_end]
    enc_names = buf[column_directory_end:names_end]
    data = buf[names_end:]

    names = {}
    values = {}

    last_name_offset = None
    last_data_offset = None
    last_dtype = None

    for i in six_moves_range(column_count):
        if coldata_size % 2 == 0:
            name_offset, data_offset_dtype = struct_unpack_from(
                '<H' + data_offset_code,
                column_directory,
                offset=i * coldata_size
            )
        else:
            name_offset, = struct_unpack_from(
                '<H',
                column_directory,
                offset=i * coldata_size
            )
            # can't struct_unpack the 3 bytes so hack around
            dodt_bytes = column_directory[(i * coldata_size + 2):
                                          (i * coldata_size + 5)] + b'\x00'
            data_offset_dtype, = struct_unpack('<' + data_offset_code,
                                               dodt_bytes)

        data_offset_dtype &= data_offset_mask
        data_offset = data_offset_dtype >> 4
        dtype = data_offset_dtype & 0xF

        # Store *last* column's name
        if last_name_offset is not None:
            names[i - 1] = (
                enc_names[last_name_offset:name_offset].decode('utf-8')
            )
        last_name_offset = name_offset

        #
        if last_data_offset is not None:
            values[i - 1] = decode(last_dtype,
                                   data[last_data_offset:data_offset])
        last_data_offset = data_offset
        last_dtype = dtype

    names[column_count - 1] = enc_names[last_name_offset:].decode('utf-8')
    values[column_count - 1] = decode(last_dtype, data[last_data_offset:])

    # join data and names
    return {
        names[i]: values[i]
        for i in six_moves_range(column_count)
    }
コード例 #22
0
 def _from_bytes_and_header(cls, data: memoryview, header: Header) -> Message:
     cls._check_structure_size(
         structure_size_to_test=struct_unpack_from('<H', buffer=data, offset=len(header))[0]
     )