Exemple #1
0
    def message(self):  # type: () -> str
        error_details = []

        for detail in self.error_details:
            if isinstance(detail, SMB2SymbolicLinkErrorResponse):
                flag = str(detail['flags'])
                print_name = detail.get_print_name()
                sub_name = detail.get_substitute_name()
                error_details.append("Flag: %s, Print Name: %s, Substitute Name: %s" % (flag, print_name, sub_name))

            elif isinstance(detail, SMB2ShareRedirectErrorContext):
                ip_addresses = []
                for ip_addr in detail['ip_addr_move_list'].get_value():
                    ip_addresses.append(ip_addr.get_ipaddress())

                resource_name = to_text(detail['resource_name'].get_value(), encoding='utf-16-le')
                error_details.append("IP Addresses: '%s', Resource Name: %s"
                                     % ("', '".join(ip_addresses), resource_name))

            else:
                # unknown error details in response, output raw bytes
                error_details.append("Raw: %s" % to_text(binascii.hexlify(detail)))

        error_msg = '%s %s: 0x%s' % (self._BASE_MESSAGE, str(self.header['status']), format(self.status, 'x').zfill(8))
        if error_details:
            error_msg += " - %s" % ", ".join(error_details)

        return to_native("Received unexpected status from the server: %s" % error_msg)
    def set_name(self, substitute_name, print_name):
        b_substitute_name = to_bytes(to_text(substitute_name),
                                     encoding='utf-16-le')
        b_print_name = to_bytes(to_text(print_name), encoding='utf-16-le')

        self['substitute_name_offset'] = 0
        self['substitute_name_length'] = len(b_substitute_name)
        self['print_name_offset'] = len(b_substitute_name)
        self['print_name_length'] = len(b_print_name)
        self['buffer'] = b_substitute_name + b_print_name
def test_native_to_unicode():
    if PY3:
        expected = u"a\x00b\x00c\x00"
    else:
        expected = u"abc"
    actual = to_text("a\x00b\x00c\x00", encoding='utf-16-le')
    assert actual == expected
Exemple #4
0
    def set_name(self, print_name, substitute_name):
        """
        Set's the path_buffer and print/substitute name length of the message
        with the values passed in. These values should be a string and not a
        byte string as it is encoded in this function.

        :param print_name: The print name string to set
        :param substitute_name: The substitute name string to set
        """
        # Ensure that the to_bytes input is an actual text string for py2 compat with native strings.
        print_bytes = to_bytes(to_text(print_name), encoding='utf-16-le')
        sub_bytes = to_bytes(to_text(substitute_name), encoding='utf-16-le')
        path_buffer = print_bytes + sub_bytes

        self['print_name_offset'].set_value(0)
        self['print_name_length'].set_value(len(print_bytes))
        self['substitute_name_offset'].set_value(len(print_bytes))
        self['substitute_name_length'].set_value(len(sub_bytes))
        self['path_buffer'].set_value(path_buffer)
Exemple #5
0
    def resolve_path(self, link_path):
        """
        [MS-SMB2] 2.2.2.2.1.1 Handling the Symbolic Link Error Response
        https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/a8da655c-8b0b-415a-b726-16dc33fa5827

        Attempts to resolve the link target path. Will fail if the link is pointing to a local path or a UNC path
        on another host or share.

        :param link_path: The original path to the symbolic link to resolve relative paths from.
        :return: The resolved link target path.
        """
        substitute_name = self.get_substitute_name()
        print_name = self.get_print_name()
        unparsed_path_length = self['unparsed_path_length'].get_value()

        b_link_path = to_bytes(to_text(link_path), encoding='utf-16-le')
        unparsed_idx = len(b_link_path) - unparsed_path_length
        base_link_path = to_text(b_link_path[:unparsed_idx],
                                 encoding='utf-16-le')
        unparsed_path = to_text(b_link_path[unparsed_idx:],
                                encoding='utf-16-le')

        # Use the common code in SymbolicLinkReparseDataBuffer() to resolve the link target.
        symlink_buffer = SymbolicLinkReparseDataBuffer()
        symlink_buffer['flags'] = self['flags'].get_value()
        symlink_buffer.set_name(substitute_name, print_name)
        target_path = symlink_buffer.resolve_link(
            base_link_path) + unparsed_path

        if not target_path.startswith('\\\\'):
            raise SMBLinkRedirectionError(
                "Cannot resolve link targets that point to a local path",
                link_path, print_name)

        link_share = ntpath.splitdrive(link_path)[0]
        target_share = ntpath.splitdrive(target_path)[0]
        if link_share != target_share:
            raise SMBLinkRedirectionError(
                "Cannot resolve link targets that point to a different host/share",
                link_path, print_name)

        return target_path
    def _parse_value(self, value):
        if value is None:
            text_value = u""
        elif isinstance(value, binary_type):
            text_value = to_text(value, encoding=self.encoding)
        elif isinstance(value, text_type):
            text_value = value
        elif isinstance(value, types.LambdaType):
            text_value = value
        else:
            raise TypeError("Cannot parse value for field %s of type %s to a "
                            "text string" % (self.name, type(value).__name__))

        return text_value
def _bytes_to_hex(bytes, pretty=False, hex_per_line=8):
    hex = to_text(hexlify(bytes))

    if pretty:
        if hex_per_line == 0:  # show hex on 1 line
            hex_list = [hex]
        else:
            idx = hex_per_line * 2
            hex_list = list(hex[i:i + idx] for i in range(0, len(hex), idx))

        hexes = []
        for h in hex_list:
            hexes.append(' '.join(h[i:i + 2]
                                  for i in range(0, len(h), 2)).upper())
        hex = "\n".join(hexes)

    return hex
Exemple #8
0
def dfs_request(tree, path):  # type: (TreeConnect, str) -> DFSReferralResponse
    """ Send a DFS Referral request to the IPC tree and return the referrals. """
    dfs_referral = DFSReferralRequest()
    dfs_referral['request_file_name'] = to_text(path)

    ioctl_req = SMB2IOCTLRequest()
    ioctl_req['ctl_code'] = CtlCode.FSCTL_DFS_GET_REFERRALS
    ioctl_req['file_id'] = b"\xFF" * 16
    ioctl_req['max_output_response'] = 56 * 1024
    ioctl_req['flags'] = IOCTLFlags.SMB2_0_IOCTL_IS_FSCTL
    ioctl_req['buffer'] = dfs_referral

    request = tree.session.connection.send(ioctl_req, sid=tree.session.session_id, tid=tree.tree_connect_id)
    response = tree.session.connection.receive(request)

    ioctl_resp = SMB2IOCTLResponse()
    ioctl_resp.unpack(response['data'].get_value())

    dfs_response = DFSReferralResponse()
    dfs_response.unpack(ioctl_resp['buffer'].get_value())

    return dfs_response
Exemple #9
0
 def get_substitute_name(self):
     offset = self['substitute_name_offset'].get_value()
     length = self['substitute_name_length'].get_value()
     name_bytes = self['path_buffer'].get_value()[offset:offset + length]
     return to_text(name_bytes, encoding='utf-16-le')
Exemple #10
0
    DFSReferralRequestFlags,
    DFSReferralResponse,
    DFSTarget,
    DomainEntry,
    ReferralEntry,
)

from .conftest import (
    DC_REFERRAL,
    DOMAIN_REFERRAL,
    TARGET_REFERRAL,
    ROOT_REFERRAL,
)

# 'MUSICAL SYMBOL G CLEF' https://www.fileformat.info/info/unicode/char/1d11e/index.htm
UNICODE_TEXT = u'ÜseӜ' + to_text(b"\xF0\x9D\x84\x9E")


class TestDomainEntry(object):
    def test_domain_entry(self):
        domain_entry = DomainEntry(
            DOMAIN_REFERRAL['referral_entries'].get_value()[0])
        assert domain_entry.domain_list == []
        assert domain_entry.domain_name == u'\\DOMAIN'
        assert not domain_entry.is_expired
        assert not domain_entry.is_valid

        domain_entry._start_time = time.time() - 700
        assert domain_entry.is_expired

    def test_process_dc_referral(self):
def test_byte_to_text_diff_encoding():
    expected = u"abc"
    actual = to_text(b"\x61\x00\x62\x00\x63\x00", encoding='utf-16-le')
    assert actual == expected
def test_byte_to_text():
    expected = u"abc"
    actual = to_text(b"\x61\x62\x63")
    assert actual == expected
def test_text_to_text():
    expected = u"abc"
    actual = to_text(u"abc")
    assert actual == expected
 def _get_name(self, prefix):
     offset = self['%s_name_offset' % prefix].get_value()
     length = self['%s_name_length' % prefix].get_value()
     b_name = self['buffer'].get_value()[offset:offset + length]
     return to_text(b_name, encoding='utf-16-le')