Ejemplo n.º 1
0
    def _handle_check_results(self, param):

        self.save_progress("In action handler for: {0}".format(self.get_action_identifier()))

        action_result = self.add_action_result(ActionResult(dict(param)))
        location = param['location']
        ret_val, response = self._make_rest_call(location, action_result, params=None, headers=None)

        if (phantom.is_fail(ret_val)):
            return action_result.get_status()

        action_result.add_data(response)

        return action_result.set_status(phantom.APP_SUCCESS)
Ejemplo n.º 2
0
    def _handle_list_intel_framework(self, param):

        self.save_progress("In action handler for: {0}".format(self.get_action_identifier()))

        action_result = self.add_action_result(ActionResult(dict(param)))

        response = self._fetch_list_intel_framework(action_result)

        if response is None:
            return action_result.get_status()

        action_result.add_data(response)

        return action_result.set_status(phantom.APP_SUCCESS)
Ejemplo n.º 3
0
    def _handle_list_input_framework(self, param):

        self.save_progress("In action handler for: {0}".format(self.get_action_identifier()))

        action_result = self.add_action_result(ActionResult(dict(param)))

        ret_val, response = self._make_rest_call('/api/bro/input', action_result, params=None, headers=None)

        if (phantom.is_fail(ret_val)):
            return action_result.get_status()

        action_result.add_data(response)

        return action_result.set_status(phantom.APP_SUCCESS)
Ejemplo n.º 4
0
    def _handle_send_email(self, param, action_result=None):

        if (action_result is None):
            action_result = self.add_action_result(ActionResult(dict(param)))

        try:
            status_code = self._send_email(param, action_result)
        except Exception as e:
            return action_result.set_status(
                phantom.APP_ERROR,
                "{} {}".format(SMTP_ERR_SMTP_SEND_EMAIL,
                               self._get_error_message_from_exception(e)))

        return status_code
    def _handle_domain_category(self, param):

        # Adding action handler message
        self.save_progress("In action handler for: {0}".format(self.get_action_identifier()))

        # Add an action result object to self (BaseConnector) to represent the action for this param
        action_result = self.add_action_result(ActionResult(dict(param)))

        # Pass domain to the search
        domain = param['domain']

        # Issue request to the tags endpoint
        endpoint = '/domain/{}/tags'.format(domain)

        # Make connection to the SecurityTrails endpoint
        ret_val, response = self._make_rest_call(endpoint, action_result)

        # Connect to Phantom Endpoint
        self.save_progress("Connecting to endpoint")

        if (phantom.is_fail(ret_val)):
            # the call to the 3rd party device or service failed, action result should contain all the error details
            # so just return from here
            message = "Failed Response to domain category."
            return action_result.set_status(phantom.APP_ERROR, status_message=message)

        # If domain has no tags
        try:
            response['tags'][0]

        except:
            response['tags'] = "No Results"

        # Create new python dictionary to store output
        data_output = {}

        # Create new python dictionary to store output
        data_output = response

        # Add the response into the data section
        action_result.add_data(data_output)

        # Add a dictionary that is made up of the most important values from data into the summary
        summary = action_result.update_summary({})
        summary['domain'] = domain
        summary['tags'] = data_output['tags']

        # Return success, no need to set the message, only the status
        # BaseConnector will create a textual message based off of the summary dictionary
        return action_result.set_status(phantom.APP_SUCCESS)
Ejemplo n.º 6
0
    def _handle_lookup_ip(self, param):

        # Implement the handler here
        # use self.save_progress(...) to send progress messages back to the platform
        self.save_progress("In action handler for: {0}".format(
            self.get_action_identifier()))

        # Add an action result object to self (BaseConnector) to represent the action for this param
        action_result = self.add_action_result(ActionResult(dict(param)))
        """
        # Access action parameters passed in the 'param' dictionary

        # Required values can be accessed directly
        required_parameter = param['required_parameter']

        # Optional values should use the .get() function
        optional_parameter = param.get('optional_parameter', 'default_value')
        """

        # make rest call
        ret_val, response = self._make_rest_call('/hostname',
                                                 action_result,
                                                 params=None,
                                                 headers=None)

        if (phantom.is_fail(ret_val)):
            # the call to the 3rd party device or service failed, action result should contain all the error details
            # so just return from here
            return action_result.get_status()

        # Now post process the data,  uncomment code as you deem fit

        # Add the response into the data section
        # action_result.add_data(response)
        response_dict = {'host_name': response}
        action_result.add_data(response_dict)

        action_result.add_data({})

        # Add a dictionary that is made up of the most important values from data into the summary
        summary = action_result.update_summary({})
        summary['host_name'] = response

        # Return success, no need to set the message, only the status
        # BaseConnector will create a textual message based off of the summary dictionary
        return action_result.set_status(phantom.APP_SUCCESS)

        # For now return Error with a message, in case of success we don't set the message, but use the summary
        return action_result.set_status(phantom.APP_ERROR,
                                        "Action not yet implemented")
    def _get_file_from_url(self, param):
        action_result = self.add_action_result(ActionResult(dict(param)))
        disassembled = urlparse(param['url'])
        filename, file_ext = splitext(basename(disassembled.path))

        guid = uuid.uuid4()
        local_dir = '/vault/tmp/{}'.format(guid)
        self.save_progress("Using temp directory: {0}".format(guid))

        try:
            os.makedirs(local_dir)
        except Exception as e:
            return action_result.set_status(
                phantom.APP_ERROR,
                "Unable to create temporary folder '/vault/tmp'.", e)

        f_out_name = local_dir + '/online_file_{}_{}{}'.format(
            str(time.time()).replace('.', ''), filename, file_ext)

        self.save_progress('Fetching data from given url')
        file_resp = urllib.urlopen(param['url'])
        f_out = open(f_out_name, 'wb')
        f_out.write(file_resp.read())
        f_out.close()

        vault_ret_dict = Vault.add_attachment(
            f_out_name,
            self.get_container_id(),
            file_name=os.path.basename(f_out_name))

        data = {}
        if vault_ret_dict['succeeded']:
            data = {
                'vault_id': vault_ret_dict[phantom.APP_JSON_HASH],
                'file_name': os.path.basename(f_out_name),
                'file_type': file_ext[1:],
            }

            action_result.set_status(phantom.APP_SUCCESS)
        else:
            action_result.set_status(phantom.APP_ERROR,
                                     phantom.APP_ERR_FILE_ADD_TO_VAULT)
            action_result.append_to_message(vault_ret_dict['message'])

        shutil.rmtree(local_dir)

        action_result.add_data(data)
        action_result.set_summary(data)

        return action_result.get_status()
Ejemplo n.º 8
0
    def get_campaign_details(self, param):
        action_result = self.add_action_result(ActionResult(param))
        campaign_id = self._handle_py_ver_compat_for_input_str(param.get('campaign_id'))

        campaign_url = PP_API_PATH_CAMPAIGN.format(campaign_id)

        params = {'format': 'json'}

        ret_val, data = self._make_rest_call(action_result, campaign_url, params=params)
        if phantom.is_fail(ret_val):
            return action_result.get_status()

        action_result.add_data(data)
        return action_result.set_status(phantom.APP_SUCCESS)
Ejemplo n.º 9
0
    def _handle_lookup_hash(self, param):
        self.save_progress("In action handler for: {0}".format(
            self.get_action_identifier()))

        action_result = self.add_action_result(ActionResult(dict(param)))

        file_hash = param['file_hash']
        data = {}
        if len(file_hash) == 64:
            data['sha256_hash'] = file_hash
        elif len(file_hash) == 32:
            data['md5_hash'] = file_hash
        else:
            return action_result.set_status(
                phantom.APP_ERROR,
                "File Hash length not supported. Please verify hash is sha256 (64 char) or md5 (32)"
            )

        ret_val, response = self._make_rest_call('/payload',
                                                 action_result,
                                                 params=None,
                                                 headers=None,
                                                 method="post",
                                                 data=data)

        if phantom.is_fail(ret_val):
            self.save_progress("Failed to contact URLhaus")
            return action_result.get_status()

        action_result.add_data(response)

        try:
            summary = action_result.update_summary({})
            if response['query_status'] == "no_results":
                summary['message'] = "No results found for: {0}".format(
                    file_hash)
            elif response['query_status'] == "ok":
                summary['firstseen'] = response['firstseen']
                url_count = len(response['urls'])
                summary['url_count'] = url_count
                signature = response['signature']
                summary[
                    'message'] = "File Hash {0} observed being served by {1} URLs. Possible signature {2}".format(
                        file_hash, url_count, signature)
            summary['query_status'] = response['query_status']
        except Exception as e:
            error_msg = self._get_error_message_from_exception(e)
            return action_result.set_status(phantom.APP_ERROR, error_msg)

        return action_result.set_status(phantom.APP_SUCCESS)
Ejemplo n.º 10
0
    def _whois_ip(self, param):

        action_result = self.add_action_result(ActionResult(dict(param)))

        ip = param[PASSIVETOTAL_JSON_IP]

        # Validation for checking valid IP or not (IPV4 as well as IPV6)
        if not self._is_ip(ip):
            return action_result.set_status(
                phantom.APP_ERROR,
                'Please provide a valid IPV4 or IPV6 address')

        # Progress
        self.save_progress(PASSIVETOTAL_USING_BASE_URL,
                           base_url=self._base_url)

        # Connectivity
        self.save_progress(phantom.APP_PROG_CONNECTING_TO_ELLIPSES, self._host)

        # Whois info
        ret_val, response, status_code = self._make_rest_call(
            '/whois', {'query': ip}, action_result)

        if (phantom.is_fail(ret_val)):
            # We don't seem to have any data _and_ the last call failed
            return action_result.get_status()

        if (not response):
            # return with a message
            return action_result.set_status(phantom.APP_SUCCESS,
                                            "No registrant info found")

        action_result.add_data(response)
        registrant = response.get('registrant')

        if (not registrant):
            # return with a message
            return action_result.set_status(phantom.APP_SUCCESS,
                                            "No registrant info found")

        action_result.update_summary({
            'city':
            registrant.get('city'),
            'country':
            registrant.get('country'),
            'organization':
            registrant.get('organization')
        })

        return action_result.set_status(phantom.APP_SUCCESS)
Ejemplo n.º 11
0
    def _handle_test_connectivity(self, param):
        action_result = self.add_action_result(ActionResult(dict(param)))
        self.save_progress("Connecting to endpoint")
        ret_val, response = self._make_rest_call('/',
                                                 action_result,
                                                 params=None,
                                                 headers=None)

        if (phantom.is_fail(ret_val)):
            self.save_progress("Test Connectivity Failed.")
            return action_result.get_status()

        self.save_progress("Test Connectivity Passed")
        return action_result.set_status(phantom.APP_SUCCESS)
Ejemplo n.º 12
0
    def _make_rest_call_abstract(self,
                                 endpoint,
                                 action_result,
                                 data=None,
                                 params=None,
                                 auth_mode="Bearer",
                                 method="post"):

        # Use this object for make_rest_call
        # Final status of action_result would be determined
        # after retry if token expired
        intermediate_action_result = ActionResult()
        response = None

        headers = {
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        }

        # Generate new token if not available
        if not self._token:
            ret_code = self._generate_api_token(action_result)
            if phantom.is_fail(ret_code):
                return action_result.get_status(), response

        # Make rest call
        rest_ret_code, response = self._make_rest_call(
            endpoint, intermediate_action_result, headers, data, params,
            auth_mode, method)

        # If token is invalid in case of api calls other than generate token, generate new token and retry
        if auth_mode != "Basic" and 'Detail: invalid_token' in str(
                intermediate_action_result.get_message()):
            ret_code = self._generate_api_token(action_result)
            if phantom.is_fail(ret_code):
                return action_result.get_status(), response

            # Retry the rest call with new token generated
            rest_ret_code, response = self._make_rest_call(
                endpoint, intermediate_action_result, headers, data, params,
                auth_mode, method)

        # Assigning intermediate action_result to action_result,
        # since no further invocation required
        if phantom.is_fail(rest_ret_code):
            action_result.set_status(rest_ret_code,
                                     intermediate_action_result.get_message())
            return action_result.get_status(), response

        return phantom.APP_SUCCESS, response
Ejemplo n.º 13
0
    def _handle_update_finding(self, param):
        """
        Updates the finding by adding or changing the feedback and comment of the finding

        :param detector_id: The ID of the detector
        :param finding_id: The ID of the finding
        :param feedback: Feedback value of the finding
        :param comment: Additional feedback about the finding
        return: Details of updated finding
        """
        action_result = self.add_action_result(ActionResult(dict(param)))

        if phantom.is_fail(self._create_client(action_result)):
            return action_result.get_status()

        detector_id = param['detector_id']
        finding_ids = param['finding_id']
        feedback = param['feedback']
        comments = param.get('comment')

        if comments:
            ret_val, response = self._make_boto_call(
                action_result,
                'update_findings_feedback',
                DetectorId=detector_id,
                FindingIds=[finding_ids],
                Feedback=feedback,
                Comments=comments)
        else:
            ret_val, response = self._make_boto_call(
                action_result,
                'update_findings_feedback',
                DetectorId=detector_id,
                FindingIds=[finding_ids],
                Feedback=feedback)

        if phantom.is_fail(ret_val):
            return action_result.get_status()

        try:
            del response['ResponseMetadata']
        except:
            pass

        action_result.add_data(response)

        summary = action_result.update_summary({})
        summary['total_updated_findings'] = action_result.get_data_size()

        return action_result.set_status(phantom.APP_SUCCESS)
Ejemplo n.º 14
0
    def _handle_update_incident(self, param):

        # Implement the handler here
        # use self.save_progress(...) to send progress messages back to the platform
        self.save_progress("In action handler for: {0}".format(
            self.get_action_identifier()))

        # Add an action result object to self (BaseConnector) to represent the action for this param
        action_result = self.add_action_result(ActionResult(dict(param)))

        incident = param['incident']
        params = {'incident': incident}

        incidentState = param['incident_state']
        if incidentState == "acknowledge":
            endpoint = "/incident/acknowledge"
        if incidentState == "unacknowledge":
            endpoint = "/incident/unacknowledge"

        # Optional values should use the .get() function
        # optional_parameter = param.get('optional_parameter', 'default_value')

        # make rest call
        ret_val, response = self._make_rest_call(endpoint,
                                                 action_result,
                                                 params=params,
                                                 headers=None,
                                                 method="post")

        if (phantom.is_fail(ret_val)):
            return action_result.get_status()

        # Now post process the data,  uncomment code as you deem fit

        # Add the response into the data section

        if response:
            action_result.add_data(response)
            summary = action_result.update_summary({})
            summary['result'] = response.get('result')

            if response.get('result') == "success":
                return action_result.set_status(phantom.APP_SUCCESS)
            else:
                return action_result.set_status(
                    phantom.APP_ERROR,
                    "Error while communicating with Canary API")
        else:
            return action_result.set_status(
                phantom.APP_ERROR, "Error while communicating with Canary API")
Ejemplo n.º 15
0
    def _handle_add_ip(self, param):

        self.save_progress(
            AWSWAF_INFO_ACTION.format(self.get_action_identifier()))

        # Add an action result object to self (BaseConnector) to represent the action for this param
        action_result = self.add_action_result(ActionResult(dict(param)))

        ip_set_id = param.get('ip_set_id')
        ip_set_name = param.get('ip_set_name')
        ip_address = param.get('ip_address')
        ip_address_list = [
            x.strip() for x in ip_address.split(',') if x.strip()
        ]
        ip_type = self.validate_params(action_result, ip_set_id, ip_set_name,
                                       ip_address_list)

        ip_set = self.paginator(AWSWAF_DEFAULT_LIMIT, action_result, param)
        ip_set_id, ip_set_name = self._verify_ip_set(action_result, ip_set,
                                                     ip_set_id, ip_set_name)

        if not ip_set_id:
            ip_set_name = param.get('ip_set_name')
            # create a new IP set with given IP addresses
            ret_val, resp_json = self._make_boto_call(
                action_result,
                'create_ip_set',
                Name=ip_set_name,
                IPAddressVersion=ip_type,
                Addresses=ip_address_list)

            if phantom.is_fail(ret_val):
                return action_result.set_status(phantom.APP_ERROR,
                                                AWSWAF_ERR_CREATE_IPSET)

            action_result.set_status(phantom.APP_SUCCESS)
            ip_set_id = resp_json.get('Summary', {}).get('Id')
            action_result.add_data({'Id': ip_set_id})
        else:
            ret_val = self._ip_update(action_result, ip_address_list,
                                      ip_set_id, ip_set_name)

        summary = action_result.update_summary({})

        if phantom.is_fail(ret_val):
            summary['ip_status'] = AWSWAF_ADD_IP_FAILED

        summary['ip_status'] = AWSWAF_ADD_IP_SUCCESS

        return action_result.get_status()
Ejemplo n.º 16
0
    def _handle_unarchive_finding(self, param):
        """
        Unarchive Amazon GuardDuty findings specified by the detector ID and list of finding IDs

        :param detector_id: The ID of the detector
        :param finding_id: The ID of the finding
        return: Details of unarchived findings
        """
        action_result = self.add_action_result(ActionResult(dict(param)))

        if phantom.is_fail(self._create_client(action_result)):
            return action_result.get_status()

        detector_id = param['detector_id']
        finding_ids = param['finding_id']

        # Comma separated list handling for 'finding_id'
        finding_ids = [x.strip() for x in finding_ids.split(',')]
        finding_ids = list(filter(None, finding_ids))
        if not finding_ids:
            return action_result.set_status(
                phantom.APP_ERROR, AWSGUARDDUTY_INVALID_FINDING_ID_ERR_MSG)

        ret_val, valid_findings_ids = self._validate_findings_id(
            finding_ids, 'UNARCHIVED', action_result, detector_id)
        if not ret_val:
            return action_result.get_status()
        self.debug_print(
            "Valid finding IDs are: \n{}".format(valid_findings_ids))

        while valid_findings_ids:
            ret_val, response = self._make_boto_call(
                action_result,
                'unarchive_findings',
                DetectorId=detector_id,
                FindingIds=valid_findings_ids[:min(50, len(valid_findings_ids)
                                                   )])
            if phantom.is_fail(ret_val):
                return action_result.get_status()

            try:
                del response['ResponseMetadata']
            except:
                pass

            action_result.add_data(response)
            del valid_findings_ids[:min(50, len(valid_findings_ids))]

        return action_result.set_status(
            phantom.APP_SUCCESS, AWSGUARDDUTY_UNARCHIVE_FINDING_SUCC_MSG)
Ejemplo n.º 17
0
    def _handle_copy_contact(self, param):
        self.save_progress("In action handler for: {0}".format(self.get_action_identifier()))

        action_result = self.add_action_result(ActionResult(dict(param)))

        scopes = [GOOGLE_CONTACTS_SCOPE, GOOGLE_OTHER_CONTACTS_SCOPE_READ_ONLY]

        ret_val, client = self._create_client(action_result, scopes)

        if phantom.is_fail(ret_val):
            self.debug_print(GOOGLE_CREATE_CLIENT_FAILED_MSG)
            return action_result.get_status()

        resource_name = param['resource_name']
        if OTHER_CONTACTS_RESOURCE_NAME_PREFIX not in resource_name:
            return action_result.set_status(phantom.APP_ERROR, "Resource name of contact to be copied must be 'otherContact'")

        data = {}

        copy_mask = param.get('copy_mask', 'names,emailAddresses,phoneNumbers')

        # Validation for comma-separated value
        masks = [x.strip() for x in copy_mask.split(",")]
        masks = list(filter(None, masks))

        if not masks:
            return action_result.set_status(phantom.APP_ERROR, INVALID_COMMA_SEPARATED_ERR_MSG.format('copy mask'))

        copy_mask = ",".join(masks)

        data.update({'copyMask': copy_mask})

        try:
            response = client.otherContacts().copyOtherContactToMyContactsGroup(resourceName=resource_name, body=data).execute()
        except HttpError as e:
            if "_get_reason" in dir(e):
                return action_result.set_status(phantom.APP_ERROR, "{}. {}".format(GOOGLE_COPY_CONTACT_FAILED_MSG, e._get_reason()))
            err_msg = self._get_error_message_from_exception(e)
            self.debug_print("Exception message: {}".format(err_msg))
            return action_result.set_status(phantom.APP_ERROR, GOOGLE_COPY_CONTACT_FAILED_MSG)
        except Exception as e:
            err_msg = self._get_error_message_from_exception(e)
            self.debug_print("Exception message: {}".format(err_msg))
            return action_result.set_status(phantom.APP_ERROR, GOOGLE_COPY_CONTACT_FAILED_MSG)

        action_result.add_data(response)

        action_result.update_summary({'total_contacts_copied': 1})

        return action_result.set_status(phantom.APP_SUCCESS, 'Successfully copied 1 contact')
Ejemplo n.º 18
0
    def _test_connectivity(self, param):
        """
        Called when the user depresses the test connectivity button on the Phantom UI.
        """
        action_result = ActionResult(
            dict(param))  # Add an action result to the App Run
        self.add_action_result(action_result)

        self.debug_print("%s TEST_CONNECTIVITY %s" %
                         (CSR_Connector.BANNER, param))
        config = self.get_config()

        try:
            self.username = config["username"]
            self.password = config["password"]
            self.device = config["trigger_host"]
        except KeyError:
            self.debug_print("Error: {0}".format(KeyError))
            return self.set_status_save_progress(
                phantom.APP_ERROR,
                "KeyError attempting to parse organization ID and name")

        self.debug_print("Username: {0}, Password: {1}".format(
            self.username, self.password))

        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(self.device,
                    username=self.username,
                    password=self.password,
                    allow_agent=False,
                    look_for_keys=False)
        csr_conn = ssh.invoke_shell()
        self.debug_print(type(csr_conn))
        csr_conn.send('show version\n')
        time.sleep(1)
        resp = csr_conn.recv(99999)
        csr_conn.close()
        ssh.close()
        self.debug_print(
            "Initial test connectivity to device resp: {0}".format(resp))

        if resp:
            self.debug_print("Connected to device: {0}".format(resp))
            return self.set_status_save_progress(
                phantom.APP_SUCCESS, "SUCCESS!  Connected to device")
        else:
            self.debug_print("Unable to connect to device: {0}".format(resp))
            return self.set_status_save_progress(
                phantom.APP_ERROR, "FAILURE!  Unable to connect to device")
Ejemplo n.º 19
0
    def _handle_get_endpoint_info(self, param):

        self.save_progress("In action handler for: {0}".format(
            self.get_action_identifier()))
        action_result = self.add_action_result(ActionResult(dict(param)))
        ip_hostname = param['ip_hostname']

        try:
            ret_val = self._get_agent_id(ip_hostname, action_result)
        except Exception as e:
            return action_result.set_status(
                phantom.APP_ERROR,
                "Error occurred while getting agent id : {0}".format(e))
        self.save_progress('Agent query: ' + ret_val)

        if ret_val == '0':
            return action_result.set_status(phantom.APP_SUCCESS,
                                            "Endpoint not found")
        elif ret_val == '99':
            return action_result.set_status(phantom.APP_SUCCESS,
                                            "More than one endpoint found")
        else:
            summary = action_result.update_summary({})
            summary['ip_hostname'] = ip_hostname
            summary['agent_id'] = ret_val

            # make rest call
            # GET /web/api/v1.6/agents/{id}
            headers = self.HEADER
            headers["Authorization"] = "APIToken %s" % self.token
            try:
                ret_val, response = self._make_rest_call(
                    '/web/api/v2.0/agents?ids=' + ret_val,
                    action_result,
                    headers=headers)
                if (phantom.is_fail(ret_val)):
                    return action_result.get_status()
                self.save_progress("ret_val: {0}".format(ret_val))
            except Exception as ee:
                return action_result.set_status(
                    phantom.APP_ERROR,
                    "Error occurred while getting endpoint info : {0}".format(
                        ee))

        if not response.get('data'):
            return action_result.set_status(
                phantom.APP_ERROR, 'Found no details for the given endpoint')
        else:
            action_result.add_data(response.get('data')[0])
        return action_result.set_status(phantom.APP_SUCCESS)
Ejemplo n.º 20
0
    def _handle_add_category(self, param):
        """ Add an API-managed category in Forcepoint and build action_results.

        Args:
            param (dict): Action parameters

        Returns:
            ActionResult status: success/failure
        """
        self.save_progress("In action handler for: {0}".format(
            self.get_action_identifier()))

        # Add an action result object to self (BaseConnector) to represent the action for this param
        action_result = self.add_action_result(ActionResult(dict(param)))
        summary = action_result.update_summary({})

        cat = param['category']
        desc = param.get('description')

        # Start transaction
        ret_val, transaction_id = self._start_transaction(action_result)
        if phantom.is_fail(ret_val):
            # Starting transaction failed, no rollback is required
            return action_result.get_status()
        summary['transaction_id'] = transaction_id

        # Create Category
        ret_val, response = self._create_category(action_result,
                                                  transaction_id, cat, desc)
        if phantom.is_fail(ret_val):
            # Adding category failed, attempt rollback and return error
            ret_val, rollback_time = self._rollback_transaction(
                action_result, transaction_id)
            summary['rollback_time'] = rollback_time
            return action_result.get_status()
        action_result.add_data(response)

        # Commit changes
        ret_val, commit_time = self._commit_transaction(
            action_result, transaction_id)
        if phantom.is_fail(ret_val):
            # Commit failed, attempt rollback and return error
            ret_val, rollback_time = self._rollback_transaction(
                action_result, transaction_id)
            summary['rollback_time'] = rollback_time
            return action_result.get_status()
        summary['commit_time'] = commit_time

        message = 'Added category: {}'.format(cat)
        return action_result.set_status(phantom.APP_SUCCESS, message)
Ejemplo n.º 21
0
    def _handle_list_groups(self, param):

        self.save_progress("In action handler for: {0}".format(self.get_action_identifier()))

        action_result = self.add_action_result(ActionResult(dict(param)))
        uri = '/api/directory/find-groups'
        headers = self._get_request_headers(uri=uri, action_result=action_result)

        data = {
            'meta': {
                'pagination': {
                    'pageToken': None
                }
            },
            'data': [
            ]
        }

        # Build request body params one by one. These params are optional
        data_object = {}

        if param.get('query') is not None:
            data_object['query'] = param.get('query')

        if param.get('source') is not None:
            data_object['source'] = param.get('source')

        if data_object:
            data['data'].append(data_object)

        limit = param.get('page_size')
        if limit is not None:
            limit = self._validate_integers(action_result, limit, "page_size")
            if limit is None:
                return action_result.get_status()

        ret_val, response = self._paginator(uri, action_result, limit=limit, headers=headers, method="post", data=data)

        if phantom.is_fail(ret_val):
            return ret_val

        response['groups'] = response.pop('data')

        action_result.add_data(response)

        summary = action_result.update_summary({})
        summary['num_groups'] = len(response['groups'][0]['folders'])

        return action_result.set_status(phantom.APP_SUCCESS)
Ejemplo n.º 22
0
    def _handle_whitelist_url(self, param):

        self.save_progress("In action handler for: {0}".format(self.get_action_identifier()))

        action_result = self.add_action_result(ActionResult(dict(param)))
        uri = '/api/ttp/url/create-managed-url'
        headers = self._get_request_headers(uri=uri, action_result=action_result)

        # Flipping logic to make 'enable' checkboxes for better UX
        if param.get("enable_log_click"):
            log_click = False
        else:
            log_click = True

        if param.get("enable_rewrite"):
            rewrite = False
        else:
            rewrite = True

        if param.get("enable_user_awareness"):
            user_awareness = False
        else:
            user_awareness = True

        data = {
            "data": [
                {
                    "comment": param.get("comment"),
                    "disableRewrite": rewrite,
                    "url": param.get("url"),
                    "disableUserAwareness": user_awareness,
                    "disableLogClick": log_click,
                    "action": "permit",
                    "matchType": param.get("match_type", "explicit")
                }
            ]
        }

        ret_val, response = self._make_rest_call_helper(uri, action_result, headers=headers, method="post", data=data)

        if phantom.is_fail(ret_val):
            return ret_val

        action_result.add_data(response['data'][0])

        summary = action_result.update_summary({})
        summary['status'] = "Successfully added URL to whitelist"

        return action_result.set_status(phantom.APP_SUCCESS)
Ejemplo n.º 23
0
    def locate_device(self, param):
        """
        Locating client devices means walking a tree based on the API Key. The key is associated with one or more organizations,
        an organization can have one or more networks, each network can have multiple devices, and each device can have one or
        more client machines. Depending on the timespan specified, you may see differing results. Larger timespans may show the same
        client connected to multiple devices. Small timespans, may not return any results.
        """
        self.debug_print("%s LOCATE_DEVICE parameters:\n%s" %
                         (Meraki_Connector.BANNER, param))

        action_result = ActionResult(
            dict(param))  # Add an action result to the App Run
        self.add_action_result(action_result)

        try:
            param["search_string"]  # User left search_string empty
        except KeyError:
            param["search_string"] = "*"

        org_id_list = self.get_org_ids()
        for organization in org_id_list:
            networks_list = self.get_networks(organization["id"])
            for network in networks_list:
                device_list = self.get_devices(network["id"])
                for device in device_list:
                    client_list = self.get_clients(device["serial"],
                                                   param["timespan"])
                    for client in client_list:
                        response = self.build_output_record(
                            param["search_string"], organization, network,
                            device, client)
                        if response:
                            action_result.add_data(response)

        if action_result.get_data_size() > 0:
            action_result.set_status(phantom.APP_SUCCESS)
            self.set_status_save_progress(
                phantom.APP_SUCCESS,
                "Returned: %s clients" % action_result.get_data_size())
        else:
            action_result.set_status(phantom.APP_ERROR)
            self.set_status_save_progress(
                phantom.APP_ERROR,
                "Returned: %s clients" % action_result.get_data_size())

        self.debug_print(
            "%s Data size: %s" %
            (Meraki_Connector.BANNER, action_result.get_data_size()))
        return action_result.get_status()
Ejemplo n.º 24
0
    def _handle_users_by_sq(self, param, obj_type) -> bool:
        """Get users by the name of a Saved Query in Axonius."""
        action_result: phantom.ActionResult = ActionResult(dict(param))
        self.add_action_result(action_result)

        if not self._start_client(action_result):
            return action_result.get_status()

        try:
            sq_name: str = get_str_arg(key=SQ_NAME_KEY,
                                       param=param,
                                       required=True)
            max_rows: int = get_int_arg(key=MAX_ROWS_KEY,
                                        param=param,
                                        default=MAX_ROWS)
        except Exception as exc:
            err_msg = self._get_error_message_from_exception(exc)
            status = f"Failed to parse parameters: {err_msg}"
            return action_result.set_status(phantom.APP_ERROR, status)

        try:
            apiobj: AssetMixin = getattr(self._client, obj_type)
        except AttributeError:
            error_msg = "Error occurred while creating API object"
            return action_result.set_status(phantom.APP_ERROR, error_msg)

        progress = f"Fetching {obj_type} from Saved Query {sq_name!r}"
        self.save_progress(progress)

        try:
            assets: List[dict] = apiobj.get_by_saved_query(name=sq_name,
                                                           max_rows=max_rows,
                                                           field_null=True,
                                                           field_null_value=[])
        except Exception as exc:
            err_msg = self._get_error_message_from_exception(exc)
            status = f"Failed to fetch Saved Query: {err_msg}"
            return action_result.set_status(phantom.APP_ERROR, status)

        progress = f"Fetched {len(assets)} {obj_type} from Saved Query {sq_name!r}"
        self.save_progress(progress)

        for asset in assets:
            action_result.add_data(parse_asset(asset=asset))

        summary: dict = action_result.update_summary({})
        summary[f"total_{obj_type}"] = action_result.get_data_size()

        return action_result.set_status(phantom.APP_SUCCESS)
Ejemplo n.º 25
0
    def _handle_create_ticket(self, param):

        self.save_progress("In action handler for: {0}".format(self.get_action_identifier()))

        action_result = self.add_action_result(ActionResult(dict(param)))

        data = dict()
        fields = dict()

        ret_val, fields = self._get_fields(param, action_result)

        if phantom.is_fail(ret_val):
            return action_result.get_status()

        if fields:
            data.update(fields)

        title = param['title']
        description = param['description']
        data.update({'title': title, 'description': description})

        severity = param.get('severity', 'Medium')
        try:
            int_severity = THEHIVE_SEVERITY_DICT[severity]
        except KeyError:
            return action_result.set_status(phantom.APP_ERROR, THEHIVE_ERR_INVALID_SEVERITY)
        data.update({'severity': int_severity})

        tlp = param.get('tlp', 'Amber')
        try:
            int_tlp = THEHIVE_TLP_DICT[tlp]
        except KeyError:
            return action_result.set_status(phantom.APP_ERROR, THEHIVE_ERR_INVALID_TLP)
        data.update({'tlp': int_tlp})

        if 'owner' in param:
            data.update({'owner': param.get('owner')})

        # make rest call
        authToken = "Bearer {}".format(self._api_key)
        headers = {'Content-Type': 'application/json', 'Authorization': authToken}
        ret_val, response = self._make_rest_call('api/case', action_result, params=None, data=data, headers=headers, method="post")

        if phantom.is_fail(ret_val):
            return action_result.get_status()

        action_result.add_data(response)
        action_result.update_summary({'new_case_id': response.get('caseId')})
        return action_result.set_status(phantom.APP_SUCCESS, "Successfully created a new case")
    def _get_report(self, param):

        action_result = self.add_action_result(ActionResult(dict(param)))
        summary_data = action_result.update_summary({})

        # Getting mandatory input params
        mati_id = param[DEEPSIGHT_JSON_MATI_ID]

        return_val, resp = self._make_rest_call(
            DEEPSIGHT_ENDPOINT_MATI_REPORT.format(mati_id=mati_id),
            action_result)

        # Something went wrong with the request
        if phantom.is_fail(return_val):
            return action_result.get_status()

        # Resource not found is treated as app success
        if (resp.get(DEEPSIGHT_JSON_RESOURCE_NOT_FOUND)):
            return action_result.set_status(
                phantom.APP_SUCCESS,
                DEEPSIGHT_REST_RESP_RESOURCE_NOT_FOUND_MSG)

        json_resp = resp.get(DEEPSIGHT_JSON_RESPONSE)

        # Fetching summary data
        summ_return_val, summ_resp = self._make_rest_call(
            DEEPSIGHT_ENDPOINT_MATI_REPORT_SUMMARY.format(mati_id=mati_id),
            action_result)

        # Something went wrong with the request
        if phantom.is_fail(summ_return_val):
            return action_result.get_status()

        if (summ_resp.get(DEEPSIGHT_JSON_RESPONSE)):
            summ_json_resp = summ_resp.get(DEEPSIGHT_JSON_RESPONSE)
            json_resp[DEEPSIGHT_JSON_REPORT_SUMMARY_DATA] = summ_json_resp
            summary_data['summary_title'] = summ_json_resp['title']

        action_result.add_data(json_resp)

        # Download pdf and save to vault if enabled
        if param.get(DEEPSIGHT_JSON_DOWNLOAD_REPORT, False):
            download_ret_value = self._download_report_pdf(
                mati_id, self.get_container_id(), action_result, summary_data)
            # Something went wrong with the request
            if phantom.is_fail(download_ret_value):
                return action_result.get_status()

        return action_result.set_status(phantom.APP_SUCCESS)
Ejemplo n.º 27
0
    def _modify_number(self, param, action_id):
        num_to_modify = param.get("number", param.get("default_number"))
        expression = param["expression"]

        action_result = self.add_action_result(ActionResult(dict(param)))

        if not num_to_modify:
            return action_result.set_status(
                phantom.APP_ERROR,
                'A "number to modify" or "default number" must be provided'
            )

        parser = Parser()

        try:
            result = parser.parse(
                expression.format(num_to_modify)
            ).evaluate({})
        except Exception as err:
            try:
                return action_result.set_status(
                    phantom.APP_ERROR,
                    (
                        'Error evaluating expression '
                        + expression.format(num_to_modify)
                        + '. Error Details - ' + err.message
                    )
                )
            except Exception as err2:
                return action_result.set_status(
                    phantom.APP_ERROR,
                    (
                        'Expression format is invalid. '
                        + 'Error Details - ' + err2.message
                    )
                )

        data = {
            'expression': expression.format(num_to_modify),
            'result': result
        }

        action_result.update_summary({'result': result})
        action_result.add_data(data)

        return action_result.set_status(
            phantom.APP_SUCCESS,
            'Operation successfully completed.'
        )
Ejemplo n.º 28
0
    def _handle_tag_instance(self, param):
        self.save_progress(
            "In action handler for: {0}".format(self.get_action_identifier())
        )
        action_result = self.add_action_result(ActionResult(dict(param)))

        if not self._create_discovery_client(action_result):
            self.save_progress("Could not create API client")
            return action_result.get_status()

        zone = param["zone"]
        resourceid = param["id"]
        tags = param["tags"]
        tags = [tags.strip() for tags in tags.split(',')]
        tags = list(filter(None, tags))
        if not tags:
            tags = ""
        else:
            tags = ",".join(tags)

        try:
            request = self._client.instances().get(
                project=self._project, zone=zone, instance=resourceid
            )
        except Exception as e:
            err = self._get_error_message_from_exception(e)
            return action_result.set_status(phantom.APP_ERROR, err)

        ret_val, instance_details = self._send_request(request, action_result)
        if phantom.is_fail(ret_val):
            return ret_val

        tags_body = {
            "fingerprint": instance_details.get("tags", {}).get("fingerprint"),
            "items": tags.split(","),
        }

        try:
            request = self._client.instances().setTags(
                project=self._project, zone=zone, instance=resourceid, body=tags_body
            )
        except Exception as e:
            err = self._get_error_message_from_exception(e)
            return action_result.set_status(phantom.APP_ERROR, err)

        ret_val, instance_details = self._send_request(request, action_result)

        action_result.add_data(instance_details)
        return action_result.set_status(phantom.APP_SUCCESS, "Success")
Ejemplo n.º 29
0
    def _handle_reset_password(self, param):
        """
        This method resets a users password.
        """
        action_result = self.add_action_result(ActionResult(dict(param)))
        summary = action_result.update_summary({})
        self.save_progress("In action handler for: {0}".format(
            self.get_action_identifier()))
        self.debug_print("[DEBUG] handle_reset_password")

        user = param['user']
        pwd = param['password']
        ar_data = {}

        if not self._ldap_bind():
            self.debug_print("[DEBUG] handle_reset_password - no bind")
            return RetVal(
                action_result.set_status(phantom.APP_ERROR,
                                         self._ldap_bind.result))

        if param.get("use_samaccountname", False):
            user_dn = self._sam_to_dn([user])  # _sam_to_dn requires a list.
            if len(user_dn) == 0 or user_dn[user] is False:
                return RetVal(action_result.set_status(phantom.APP_ERROR))

            ar_data["user_dn"] = user_dn[user]
            ar_data["samaccountname"] = user
            user = user_dn[user]
        else:
            ar_data["user_dn"] = user

        try:
            self.debug_print("[DEBUG] about to attempt password reset...")
            ret = self._ldap_connection.extend.microsoft.modify_password(
                user, pwd)
        except Exception as e:
            self.debug_print("[DEBUG] handle_reset_password, e = {}".format(
                str(e)))
            return RetVal(
                action_result.set_status(phantom.APP_ERROR, "[DEBUG]", e))
        self.debug_print("[DEBUG] handle_reset_password, ret = {}".format(ret))
        if ret:
            ar_data["reset"] = summary["reset"] = True
            action_result.add_data(ar_data)
            return RetVal(action_result.set_status(phantom.APP_SUCCESS))
        else:
            ar_data["reset"] = summary["reset"] = False
            action_result.add_data(ar_data)
            return RetVal(action_result.set_status(phantom.APP_ERROR))
Ejemplo n.º 30
0
    def _add_comment(self, param):
        """ This function is used to add comment/work log to an incident.

        :param param: includes ID of incident to add comment
        :return: status phantom.APP_SUCCESS/phantom.APP_ERROR (along with appropriate message)
        """

        action_result = self.add_action_result(ActionResult(dict(param)))
        add_attachment_details_param = dict()
        attachment_data = dict()

        # List of optional parameters
        optional_parameters = {"comment": "Detailed Description", "view_access": "View Access",
                               "secure_work_log": "Secure Work Log"}

        # Get optional parameters
        attachment_list = param.get(consts.BMCREMEDY_JSON_VAULT_ID, '')

        if attachment_list:
            # Getting attachment related information
            vault_details_status, add_attachment_details_param, attachment_data = \
                self._provide_attachment_details(attachment_list, action_result)

            # Something went wrong while executing request
            if phantom.is_fail(vault_details_status):
                return action_result.get_status()

        # Adding mandatory parameters
        add_attachment_details_param.update({
            "Incident Number": param[consts.BMCREMEDY_INCIDENT_NUMBER],
            "Work Log Type": param[consts.BMCREMEDY_COMMENT_ACTIVITY_TYPE]
        })

        # Adding optional parameters in 'fields'
        for key_param, api_key in optional_parameters.iteritems():
            if param.get(key_param) and api_key not in add_attachment_details_param:
                add_attachment_details_param[str(api_key)] = str(param.get(key_param))

        if attachment_list:
            attachment_data["entry"] = {"values": add_attachment_details_param}
        else:
            attachment_data["values"] = add_attachment_details_param

        add_attachment_status, add_attachment_response_data = self._add_attachment(attachment_data, action_result)

        if phantom.is_fail(add_attachment_status):
            return action_result.get_status()

        return action_result.set_status(phantom.APP_SUCCESS, consts.BMCREMEDY_ADD_COMMENT_MESSAGE)