Esempio n. 1
0
 def __init__(self, transport):
     dcerpc.DCERPC.__init__(self, transport)
     self.__activity_uuid = uuid.generate()
     self.__seq_num = 0
     self._bind = 0 # Don't attempt binding unless it explicitly requested.
     self.set_idempotent(0)
Esempio n. 2
0
    def bind(self, uuid, alter=0, bogus_binds=0):
        bind = MSRPCBind()
        # Standard NDR Representation
        NDRSyntax = ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0')
        # NDR 64
        NDR64Syntax = ('71710533-BEBA-4937-8319-B5DBEF9CCC36', '1.0')
        #item['TransferSyntax']['Version'] = 1
        ctx = self._ctx
        for i in range(bogus_binds):
            item = CtxItem()
            item['ContextID'] = ctx
            item['TransItems'] = 1
            item['ContextID'] = ctx
            # We generate random UUIDs for bogus binds
            item['AbstractSyntax'] = generate() + stringver_to_bin('2.0')
            item['TransferSyntax'] = uuidtup_to_bin(NDRSyntax)
            bind.addCtxItem(item)
            self._ctx += 1
            ctx += 1

        # The true one :)
        item = CtxItem()
        item['AbstractSyntax'] = uuid
        item['TransferSyntax'] = uuidtup_to_bin(NDRSyntax)
        item['ContextID'] = ctx
        item['TransItems'] = 1
        bind.addCtxItem(item)

        packet = MSRPCHeader()
        packet['type'] = MSRPC_BIND
        packet['pduData'] = str(bind)
        packet['call_id'] = self.__callid

        if alter:
            packet['type'] = MSRPC_ALTERCTX

        if (self.__auth_level != RPC_C_AUTHN_LEVEL_NONE):
            if (self.__username is None) or (self.__password is None):
                self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, self.__TGT, self.__TGS = self._transport.get_credentials(
                )
            if self.__auth_type == RPC_C_AUTHN_WINNT:
                auth = ntlm.getNTLMSSPType1(
                    '',
                    self.__domain,
                    signingRequired=True,
                    use_ntlmv2=self._transport.doesSupportNTLMv2())
            elif self.__auth_type == RPC_C_AUTHN_NETLOGON:
                from mitmflib.impacket.dcerpc import netlogon
                auth = netlogon.getSSPType1(self.__username[:-1],
                                            self.__domain,
                                            signingRequired=True)

            sec_trailer = SEC_TRAILER()
            sec_trailer['auth_type'] = self.__auth_type
            sec_trailer['auth_level'] = self.__auth_level
            sec_trailer['auth_ctx_id'] = self._ctx + 79231

            pad = (4 - (len(packet.get_packet()) % 4)) % 4
            if pad != 0:
                packet['pduData'] = packet['pduData'] + '\xFF' * pad
                sec_trailer['auth_pad_len'] = pad

            packet['sec_trailer'] = sec_trailer
            packet['auth_data'] = str(auth)

        self._transport.send(packet.get_packet())

        s = self._transport.recv()

        if s != 0:
            resp = MSRPCHeader(s)
        else:
            return 0  #mmm why not None?

        if resp['type'] == MSRPC_BINDACK or resp['type'] == MSRPC_ALTERCTX_R:
            bindResp = MSRPCBindAck(str(resp))
        elif resp['type'] == MSRPC_BINDNAK:
            resp = MSRPCBindNak(resp['pduData'])
            status_code = resp['RejectedReason']
            if rpc_status_codes.has_key(status_code):
                raise Exception(rpc_status_codes[status_code], resp)
            elif rpc_provider_reason.has_key(status_code):
                raise Exception("Bind context rejected: %s" %
                                rpc_provider_reason[status_code])
            else:
                raise Exception(
                    'Unknown DCE RPC fault status code: %.8x' % status_code,
                    resp)
        else:
            raise Exception('Unknown DCE RPC packet type received: %d' %
                            resp['type'])

        # check ack results for each context, except for the bogus ones
        for ctx in range(bogus_binds + 1, bindResp['ctx_num'] + 1):
            result = bindResp.getCtxItem(ctx)['Result']
            if result != 0:
                msg = "Bind context %d rejected: " % ctx
                msg += rpc_cont_def_result.get(
                    result,
                    'Unknown DCE RPC context result code: %.4x' % result)
                msg += "; "
                reason = bindResp.getCtxItem(ctx)['Reason']
                msg += rpc_provider_reason.get(
                    reason, 'Unknown reason code: %.4x' % reason)
                if (result, reason) == (
                        2, 1
                ):  # provider_rejection, abstract syntax not supported
                    msg += " (this usually means the interface isn't listening on the given endpoint)"
                raise Exception(msg, resp)

        self.__max_xmit_size = bindResp['max_tfrag']

        if self.__auth_level != RPC_C_AUTHN_LEVEL_NONE:
            if self.__auth_type == RPC_C_AUTHN_WINNT:
                response, randomSessionKey = ntlm.getNTLMSSPType3(
                    auth,
                    bindResp['auth_data'],
                    self.__username,
                    self.__password,
                    self.__domain,
                    self.__lmhash,
                    self.__nthash,
                    use_ntlmv2=self._transport.doesSupportNTLMv2())
                self.__flags = response['flags']
            elif self.__auth_type == RPC_C_AUTHN_NETLOGON:
                response = None

            self.__sequence = 0

            if self.__auth_level in (RPC_C_AUTHN_LEVEL_CONNECT,
                                     RPC_C_AUTHN_LEVEL_PKT_INTEGRITY,
                                     RPC_C_AUTHN_LEVEL_PKT_PRIVACY):
                if self.__auth_type == RPC_C_AUTHN_WINNT:
                    if self.__flags & ntlm.NTLMSSP_NTLM2_KEY:
                        self.__clientSigningKey = ntlm.SIGNKEY(
                            self.__flags, randomSessionKey)
                        self.__serverSigningKey = ntlm.SIGNKEY(
                            self.__flags, randomSessionKey, "Server")
                        self.__clientSealingKey = ntlm.SEALKEY(
                            self.__flags, randomSessionKey)
                        self.__serverSealingKey = ntlm.SEALKEY(
                            self.__flags, randomSessionKey, "Server")
                        # Preparing the keys handle states
                        cipher3 = ARC4.new(self.__clientSealingKey)
                        self.__clientSealingHandle = cipher3.encrypt
                        cipher4 = ARC4.new(self.__serverSealingKey)
                        self.__serverSealingHandle = cipher4.encrypt
                    else:
                        # Same key for everything
                        self.__clientSigningKey = randomSessionKey
                        self.__serverSigningKey = randomSessionKey
                        self.__clientSealingKey = randomSessionKey
                        self.__serverSealingKey = randomSessionKey
                        cipher = ARC4.new(self.__clientSigningKey)
                        self.__clientSealingHandle = cipher.encrypt
                        self.__serverSealingHandle = cipher.encrypt
                elif self.__auth_type == RPC_C_AUTHN_NETLOGON:
                    pass

            sec_trailer = SEC_TRAILER()
            sec_trailer['auth_type'] = self.__auth_type
            sec_trailer['auth_level'] = self.__auth_level
            sec_trailer['auth_ctx_id'] = self._ctx + 79231

            if response is not None:
                auth3 = MSRPCHeader()
                auth3['type'] = MSRPC_AUTH3
                # pad (4 bytes): Can be set to any arbitrary value when set and MUST be
                # ignored on receipt. The pad field MUST be immediately followed by a
                # sec_trailer structure whose layout, location, and alignment are as
                # specified in section 2.2.2.11
                auth3['pduData'] = '    '
                auth3['sec_trailer'] = sec_trailer
                auth3['auth_data'] = str(response)

                # Use the same call_id
                self.__callid = resp['call_id']
                auth3['call_id'] = self.__callid
                self._transport.send(auth3.get_packet(), forceWriteAndx=1)

            self.__callid += 1

        return resp  # means packet is signed, if verifier is wrong it fails
Esempio n. 3
0
    def bind(self, uuid, alter = 0, bogus_binds = 0):
        bind = MSRPCBind()
        # Standard NDR Representation
        NDRSyntax   = ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0')
        # NDR 64
        NDR64Syntax = ('71710533-BEBA-4937-8319-B5DBEF9CCC36', '1.0') 
        #item['TransferSyntax']['Version'] = 1
        ctx = self._ctx
        for i in range(bogus_binds):
            item = CtxItem()
            item['ContextID'] = ctx
            item['TransItems'] = 1
            item['ContextID'] = ctx
            # We generate random UUIDs for bogus binds
            item['AbstractSyntax'] = generate() + stringver_to_bin('2.0')
            item['TransferSyntax'] = uuidtup_to_bin(NDRSyntax)
            bind.addCtxItem(item)
            self._ctx += 1
            ctx += 1

        # The true one :)
        item = CtxItem()
        item['AbstractSyntax'] = uuid
        item['TransferSyntax'] = uuidtup_to_bin(NDRSyntax)
        item['ContextID'] = ctx
        item['TransItems'] = 1
        bind.addCtxItem(item)

        packet = MSRPCHeader()
        packet['type'] = MSRPC_BIND
        packet['pduData'] = str(bind)
        packet['call_id'] = self.__callid

        if alter:
            packet['type'] = MSRPC_ALTERCTX

        if (self.__auth_level != RPC_C_AUTHN_LEVEL_NONE):
            if (self.__username is None) or (self.__password is None):
                self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, self.__TGT, self.__TGS = self._transport.get_credentials()
            if self.__auth_type == RPC_C_AUTHN_WINNT:
                auth = ntlm.getNTLMSSPType1('', self.__domain, signingRequired = True, use_ntlmv2 = self._transport.doesSupportNTLMv2())
            elif self.__auth_type == RPC_C_AUTHN_NETLOGON:
                from mitmflib.impacket.dcerpc import netlogon
                auth = netlogon.getSSPType1(self.__username[:-1], self.__domain, signingRequired = True)

            sec_trailer = SEC_TRAILER()
            sec_trailer['auth_type']   = self.__auth_type
            sec_trailer['auth_level']  = self.__auth_level
            sec_trailer['auth_ctx_id'] = self._ctx + 79231 

            pad = (4 - (len(packet.get_packet()) % 4)) % 4
            if pad != 0:
               packet['pduData'] = packet['pduData'] + '\xFF'*pad
               sec_trailer['auth_pad_len']=pad

            packet['sec_trailer'] = sec_trailer
            packet['auth_data'] = str(auth)

        self._transport.send(packet.get_packet())

        s = self._transport.recv()

        if s != 0:
            resp = MSRPCHeader(s)
        else:
            return 0 #mmm why not None?

        if resp['type'] == MSRPC_BINDACK or resp['type'] == MSRPC_ALTERCTX_R:
            bindResp = MSRPCBindAck(str(resp))
        elif resp['type'] == MSRPC_BINDNAK:
            resp = MSRPCBindNak(resp['pduData'])
            status_code = resp['RejectedReason']
            if rpc_status_codes.has_key(status_code):
                raise Exception(rpc_status_codes[status_code], resp)
            elif rpc_provider_reason.has_key(status_code):
                raise Exception("Bind context rejected: %s" % rpc_provider_reason[status_code])
            else:
                raise Exception('Unknown DCE RPC fault status code: %.8x' % status_code, resp)
        else:
            raise Exception('Unknown DCE RPC packet type received: %d' % resp['type'])

        # check ack results for each context, except for the bogus ones
        for ctx in range(bogus_binds+1,bindResp['ctx_num']+1):
            result = bindResp.getCtxItem(ctx)['Result']
            if result != 0:
                msg = "Bind context %d rejected: " % ctx
                msg += rpc_cont_def_result.get(result, 'Unknown DCE RPC context result code: %.4x' % result)
                msg += "; "
                reason = bindResp.getCtxItem(ctx)['Reason']
                msg += rpc_provider_reason.get(reason, 'Unknown reason code: %.4x' % reason)
                if (result, reason) == (2, 1): # provider_rejection, abstract syntax not supported
                    msg += " (this usually means the interface isn't listening on the given endpoint)"
                raise Exception(msg, resp)

        self.__max_xmit_size = bindResp['max_tfrag']

        if self.__auth_level != RPC_C_AUTHN_LEVEL_NONE:
            if self.__auth_type == RPC_C_AUTHN_WINNT:
                response, randomSessionKey = ntlm.getNTLMSSPType3(auth, bindResp['auth_data'], self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, use_ntlmv2 = self._transport.doesSupportNTLMv2())
                self.__flags = response['flags']
            elif self.__auth_type == RPC_C_AUTHN_NETLOGON:
                response = None

            self.__sequence = 0

            if self.__auth_level in (RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY):
                if self.__auth_type == RPC_C_AUTHN_WINNT:
                    if self.__flags & ntlm.NTLMSSP_NTLM2_KEY:
                        self.__clientSigningKey = ntlm.SIGNKEY(self.__flags, randomSessionKey)
                        self.__serverSigningKey = ntlm.SIGNKEY(self.__flags, randomSessionKey,"Server")
                        self.__clientSealingKey = ntlm.SEALKEY(self.__flags, randomSessionKey)
                        self.__serverSealingKey = ntlm.SEALKEY(self.__flags, randomSessionKey,"Server")
                        # Preparing the keys handle states
                        cipher3 = ARC4.new(self.__clientSealingKey)
                        self.__clientSealingHandle = cipher3.encrypt
                        cipher4 = ARC4.new(self.__serverSealingKey)
                        self.__serverSealingHandle = cipher4.encrypt
                    else:
                        # Same key for everything
                        self.__clientSigningKey = randomSessionKey
                        self.__serverSigningKey = randomSessionKey
                        self.__clientSealingKey = randomSessionKey
                        self.__serverSealingKey = randomSessionKey
                        cipher = ARC4.new(self.__clientSigningKey)
                        self.__clientSealingHandle = cipher.encrypt
                        self.__serverSealingHandle = cipher.encrypt
                elif self.__auth_type == RPC_C_AUTHN_NETLOGON:
                    pass

            sec_trailer = SEC_TRAILER()
            sec_trailer['auth_type'] = self.__auth_type
            sec_trailer['auth_level'] = self.__auth_level
            sec_trailer['auth_ctx_id'] = self._ctx + 79231 

            if response is not None:
                auth3 = MSRPCHeader()
                auth3['type'] = MSRPC_AUTH3
                # pad (4 bytes): Can be set to any arbitrary value when set and MUST be 
                # ignored on receipt. The pad field MUST be immediately followed by a 
                # sec_trailer structure whose layout, location, and alignment are as 
                # specified in section 2.2.2.11
                auth3['pduData'] = '    '
                auth3['sec_trailer'] = sec_trailer
                auth3['auth_data'] = str(response)

                # Use the same call_id
                self.__callid = resp['call_id']
                auth3['call_id'] = self.__callid
                self._transport.send(auth3.get_packet(), forceWriteAndx = 1)

            self.__callid += 1

        return resp     # means packet is signed, if verifier is wrong it fails