Example #1
0
    def __init__(self,
                 stringbinding='',
                 authLevel=6,
                 bruteUUIDs=False,
                 uuids=(),
                 bruteOpnums=False,
                 opnumMax=64,
                 bruteVersions=False,
                 versionMax=64):
        try:
            self.__stringbinding = DCERPCStringBinding(stringbinding)
        except:
            raise Exception("Provided stringbinding is not correct")

        # Empty network address is used to specify that the network address
        # must be obtained from NTLMSSP of RPC proxy.
        if self.__stringbinding.get_network_address() == '' and \
           not self.__stringbinding.is_option_set("RpcProxy"):
            raise Exception("Provided stringbinding is not correct")

        self.__authLevel = authLevel
        self.__brute_uuids = bruteUUIDs
        self.__uuids = uuids
        self.__brute_opnums = bruteOpnums
        self.__opnum_max = opnumMax
        self.__brute_versions = bruteVersions
        self.__version_max = versionMax

        self.__msrpc_lockout_protection = False
        self.__rpctransport = transport.DCERPCTransportFactory(stringbinding)
        self.__dce = self.__rpctransport.get_dce_rpc()
    def __init__(self, stringbinding='', authLevel=6, bruteUUIDs=False, uuids=(), bruteOpnums=False, opnumMax=64):
        try:
            self.__stringbinding = DCERPCStringBinding(stringbinding)
        except:
            raise Exception("Provided stringbinding is not correct")

        if self.__stringbinding.get_network_address() == '' and \
           not self.__stringbinding.is_option_set("RpcProxy"):
            raise Exception("Provided stringbinding is not correct")

        self.__authLevel     = authLevel
        self.__brute_uuids   = bruteUUIDs
        self.__brute_opnums  = bruteOpnums
        self.__opnum_max     = opnumMax
        self.__uuids = uuids
        self.__rpctransport  = transport.DCERPCTransportFactory(stringbinding)
        self.__dce = None
class RPCMap():
    def __init__(self, stringbinding='', authLevel=6, bruteUUIDs=False, uuids=(), bruteOpnums=False, opnumMax=64):
        try:
            self.__stringbinding = DCERPCStringBinding(stringbinding)
        except:
            raise Exception("Provided stringbinding is not correct")

        if self.__stringbinding.get_network_address() == '' and \
           not self.__stringbinding.is_option_set("RpcProxy"):
            raise Exception("Provided stringbinding is not correct")

        self.__authLevel     = authLevel
        self.__brute_uuids   = bruteUUIDs
        self.__brute_opnums  = bruteOpnums
        self.__opnum_max     = opnumMax
        self.__uuids = uuids
        self.__rpctransport  = transport.DCERPCTransportFactory(stringbinding)
        self.__dce = None

    def set_proxy_credentials(self, username, password, domain='', hashes=None):
        if hashes is not None:
            lmhash, nthash = hashes.split(':')
        else:
            lmhash = ''
            nthash = ''

        if hasattr(self.__rpctransport, 'set_proxy_credentials'):
            self.__rpctransport.set_proxy_credentials(username, password, domain, lmhash, nthash)

    def set_rpc_credentials(self, username, password, domain='', hashes=None, aesKey=None, doKerberos=False, kdcHost=None):
        if hashes is not None:
            lmhash, nthash = hashes.split(':')
        else:
            lmhash = ''
            nthash = ''

        if hasattr(self.__rpctransport, 'set_credentials'):
            self.__rpctransport.set_credentials(username, password, domain, lmhash, nthash, aesKey)
            self.__rpctransport.set_kerberos(doKerberos, kdcHost)

    def set_smb_info(self, smbhost=None, smbport=None):
        if isinstance(self.__rpctransport, SMBTransport):
            if smbhost:
                self.__rpctransport.setRemoteHost(smbhost)
            if smbport:
                self.__rpctransport.set_dport(smbport)

    def connect(self):
        self.__dce = self.__rpctransport.get_dce_rpc()
        self.__dce.set_credentials(*self.__rpctransport.get_credentials())
        self.__dce.set_auth_level(self.__authLevel)

        try:
            self.__dce.connect()
        except:
            if str(self.__stringbinding) != str(self.__rpctransport.get_stringbinding()):
                logging.debug('StringBinding has been changed to %s' % self.__rpctransport.get_stringbinding())
            raise

        if str(self.__stringbinding) != str(self.__rpctransport.get_stringbinding()):
            logging.debug('StringBinding has been changed to %s' % self.__rpctransport.get_stringbinding())

    def disconnect(self):
        self.__dce.disconnect()

    def get_string_binding(self):
        return self.__stringbinding

    def do(self):
        try:
            # Connecting to MGMT interface
            self.__dce.bind(mgmt.MSRPC_UUID_MGMT)

            # Retrieving interfaces UUIDs from the MGMT interface
            ifids = mgmt.hinq_if_ids(self.__dce)

            # If -brute-uuids is set, bruteforcing UUIDs instead of parsing ifids
            # We must do it after mgmt.hinq_if_ids to prevent a specified account from being locked out
            if self.__brute_uuids:
                self.bruteforce_uuids()
                return

            uuidtups = set(
                uuid.bin_to_uuidtup(ifids['if_id_vector']['if_id'][index]['Data'].getData())
                for index in range(ifids['if_id_vector']['count'])
              )

            # Adding MGMT interface itself
            uuidtups.add(('AFA8BD80-7D8A-11C9-BEF4-08002B102989', '1.0'))

            for tup in sorted(uuidtups):
                self.handle_discovered_tup(tup)
        except DCERPCException as e:
            # nca_s_unk_if for Windows SMB
            # reason_not_specified for Samba 4
            # abstract_syntax_not_supported for Samba 3
            if str(e).find('nca_s_unk_if') >= 0 or \
               str(e).find('reason_not_specified') >= 0 or \
               str(e).find('abstract_syntax_not_supported') >= 0:
                logging.info("MGMT Interface not available, bruteforcing UUIDs. The result may not be complete.\n")
                self.bruteforce_uuids()
            else:
                raise

    def bruteforce_opnums(self, binuuid):
        results = []

        for i in range(self.__opnum_max + 1):
            # Is there a way to test multiple opnums in a single rpc channel?
            self.__dce.connect()
            self.__dce.bind(binuuid)
            self.__dce.call(i, b"")
            
            try:
                self.__dce.recv()
            except Exception as e:
                if str(e).find("nca_s_op_rng_error") >= 0:
                    results.append("nca_s_op_rng_error (opnum not found)")
                else:
                    results.append(str(e))
            else:
                results.append("success")

        if len(results) > 1 and results[-1] == results[-2]:
            suffix = results[-1]
            while results and results[-1] == suffix:
                results.pop()

            for i, result in enumerate(results):
                print("Opnum %d: %s" % (i, result))

            print("Opnums %d-%d: %s" % (len(results), self.__opnum_max, suffix))
        else:
            for i, result in enumerate(results):
                print("Opnum %d: %s" % (i, result))

    def bruteforce_uuids(self):
        for tup in sorted(self.__uuids):
            # Is there a way to test multiple UUIDs in a single rpc channel?
            self.__dce.connect()
            binuuid = uuid.uuidtup_to_bin(tup)

            try:
                self.__dce.bind(binuuid)
            except rpcrt.DCERPCException as e:
                # For Windows SMB
                if str(e).find('abstract_syntax_not_supported') >= 0:
                   continue
                # For Samba
                if str(e).find('nca_s_proto_error') >= 0:
                   continue
                # For Samba
                if str(e).find('reason_not_specified') >= 0:
                   continue

            self.handle_discovered_tup(tup)

        logging.info("Tested %d UUID(s)", len(self.__uuids))

    def handle_discovered_tup(self, tup):
        if tup[0] in epm.KNOWN_PROTOCOLS:
            print("Protocol: %s" % (epm.KNOWN_PROTOCOLS[tup[0]]))
        else:
            print("Procotol: N/A")

        if uuid.uuidtup_to_bin(tup)[: 18] in KNOWN_UUIDS:
            print("Provider: %s" % (KNOWN_UUIDS[uuid.uuidtup_to_bin(tup)[:18]]))
        else:
            print("Provider: N/A")

        print("UUID: %s v%s" % (tup[0], tup[1]))
        
        if self.__brute_opnums:
            try:
                self.bruteforce_opnums(uuid.uuidtup_to_bin(tup))
            except DCERPCException as e:
                if str(e).find('abstract_syntax_not_supported') >= 0:
                    print("Listening: False")
                else:
                    raise
        print()