Пример #1
0
    def _fn_bigfix_assets_function(self, event, *args, **kwargs):
        """Function: Resilient Function : Bigfix assets - Get properties in BigFix for an endpoint."""
        try:
            # Get the function parameters:
            bigfix_asset_name = kwargs.get("bigfix_asset_name")  # text
            bigfix_asset_id = kwargs.get("bigfix_asset_id")  # number
            bigfix_incident_id = kwargs.get("bigfix_incident_id")  # number

            log = logging.getLogger(__name__)
            log.info("bigfix_asset_name: %s", bigfix_asset_name)
            log.info("bigfix_asset_id: %s", bigfix_asset_id)
            log.info("bigfix_incident_id: %s", bigfix_incident_id)

            params = {
                "asset_name": bigfix_asset_name,
                "asset_id": bigfix_asset_id,
                "incident_id": bigfix_incident_id
            }

            validate_params(params, "fn_bigfix_assets")

            yield StatusMessage(
                u"Running BigFix Query for Endpoint id {0}, with name {1} ...".
                format(params["asset_id"], params["asset_name"]))
            bigfix_client = BigFixClient(self.options)

            try:
                # Perform the BigFix Query
                response = bigfix_client.get_bf_computer_properties(
                    params["asset_id"])
            except Exception as e:
                log.exception("Failed to query a BigFix asset.")
                yield StatusMessage(
                    "Failed with exception '{}' while trying to query a BigFix asset"
                    .format(type(e).__name__))
                raise Exception(
                    "Failed with exception '{}' while trying to query a BigFix asset"
                    .format(type(e).__name__))

            if not response:
                yield StatusMessage(
                    "No properties retrieved for the asset id '{}'".format(
                        params["asset_id"]))
                results = {}
            else:
                # Create a Resilient attachment
                file_name = "bigfix-properties-" + params["asset_name"] + "-" + \
                            datetime.datetime.today().strftime('%Y%m%d') + ".xml"
                att_report = create_attachment(self.rest_client(), file_name,
                                               response, params)
                results = {"status": "OK", "att_name": att_report["name"]}

            yield StatusMessage("done...")

            log.debug(results)

            # Produce a FunctionResult with the results
            yield FunctionResult(results)
        except Exception:
            yield FunctionError()
def selftest_function(opts):
    """
    Simple test to verify Bigfix connectivity.
    """
    options = opts.get("fn_bigfix", {})
    try:
        bigfix_client = BigFixClient(options)
        r = bigfix_client.test_connectivity()
        if r.status_code == 200:
            return {"state": "success", "status_code": r.status_code }
        else:
            return {"state": "failure", "status_code": r.status_code }

    except Exception as e:
        return {"state": "failure", "status_code": str(e)}
Пример #3
0
    def _fn_bigfix_artifact_function(self, event, *args, **kwargs):
        """Function: Resilient Function : Bigfix artifact - Get hits in BigFix for artifact."""
        try:
            # Get the function parameters:
            bigfix_artifact_id = kwargs.get("bigfix_artifact_id")  # number
            bigfix_artifact_value = kwargs.get("bigfix_artifact_value")  # text
            bigfix_artifact_type = kwargs.get("bigfix_artifact_type")  # text
            bigfix_artifact_properties_name = kwargs.get(
                "bigfix_artifact_properties_name")  # text
            bigfix_artifact_properties_value = kwargs.get(
                "bigfix_artifact_properties_value")  # text
            bigfix_incident_id = kwargs.get("bigfix_incident_id")  # number
            bigfix_incident_plan_status = kwargs.get(
                "bigfix_incident_plan_status")  # text

            log = logging.getLogger(__name__)
            log.info("bigfix_artifact_id: %s", bigfix_artifact_id)
            log.info("bigfix_artifact_value: %s", bigfix_artifact_value)
            log.info("bigfix_artifact_type: %s", bigfix_artifact_type)
            log.info("bigfix_artifact_properties_name: %s",
                     bigfix_artifact_properties_name)
            log.info("bigfix_artifact_properties_value: %s",
                     bigfix_artifact_properties_value)
            log.info("bigfix_incident_id: %s", bigfix_incident_id)
            log.info("bigfix_incident_plan_status: %s",
                     bigfix_incident_plan_status)

            params = {
                "artifact_id": bigfix_artifact_id,
                "artifact_value": bigfix_artifact_value,
                "artifact_properties_name": bigfix_artifact_properties_name,
                "artifact_properties_value": bigfix_artifact_properties_value,
                "artifact_type": bigfix_artifact_type,
                "incident_id": bigfix_incident_id,
                "incident_plan_status": bigfix_incident_plan_status
            }

            validate_params(params, "fn_bigfix_artifact")

            yield StatusMessage(
                "Running BigFix Query for Artifact id {0}, with value {1} ...".
                format(params["artifact_id"], params["artifact_value"]))
            bigfix_client = BigFixClient(self.options)

            try:
                artifact_data = None
                if params["incident_plan_status"] != 'C':
                    # If incident isn't closed
                    if params["artifact_type"] == "IP Address":
                        artifact_data = bigfix_client.get_bf_computer_by_ip(
                            bigfix_artifact_value)
                    elif params["artifact_type"] == "File Path":
                        artifact_data = bigfix_client.get_bf_computer_by_file_path(
                            bigfix_artifact_value)
                    elif params["artifact_type"] == "Process Name":
                        artifact_data = bigfix_client.get_bf_computer_by_process_name(
                            bigfix_artifact_value)
                    elif params["artifact_type"] == "Service":
                        artifact_data = bigfix_client.get_bf_computer_by_service_name(
                            bigfix_artifact_value)
                    elif params["artifact_type"] == "Registry Key":
                        artifact_data = bigfix_client.get_bf_computer_by_registry_key_name_value(
                            bigfix_artifact_value,
                            params["artifact_properties_name"],
                            params["artifact_properties_value"])
                    else:
                        raise ValueError(
                            "Unsupported artifact type {}.".format(
                                bigfix_artifact_type))
            except Exception as e:
                log.exception("Failed to query BigFix.")
                yield StatusMessage(
                    "Failed with exception '{}' while trying to query BigFix.".
                    format(type(e).__name__))
                raise Exception(
                    "Failed with exception '{}' while trying to query BigFix.".
                    format(type(e).__name__))

            if bigfix_incident_plan_status == 'C':
                yield StatusMessage(
                    "Ignoring action, incident {} is closed".format(
                        params["incident_id"]))
                results = {}
            elif not artifact_data:
                yield StatusMessage(
                    "Could not find data about the artifact {}".format(
                        params["artifact_value"]))
                results = {}
            else:
                hits = get_hits(artifact_data, params)
                if len(hits) == 0:
                    yield StatusMessage(
                        "No hits detected for artifact id '{0}' with value '{1}' and of type '{2}'."
                        .format(params["artifact_id"],
                                params["artifact_value"],
                                params["artifact_type"]))
                    results = {}
                elif len(hits) > int(
                        self.options.get("hunt_results_limit", "200")):
                    yield StatusMessage(
                        "Adding artifact data as an incident attachment")
                    # Define file name and content to add as an attachment
                    file_name = "query_for_artifact_{0}_{1}_{2}.txt" \
                        .format(params["artifact_id"], params["artifact_type"],
                                datetime.datetime.today().strftime('%Y%m%d'))
                    file_content = ""
                    for data in hits:
                        file_content += "Resource ID: {0}. Resource Name: {1}. Artifact value: {2}. Artifact Type: {3} \n" \
                            .format(data["computer_id"], data["computer_name"], params["artifact_value"],
                                    params["artifact_type"])
                    # Create an attachment
                    att_report = create_attachment(self.rest_client(),
                                                   file_name, file_content,
                                                   params)
                    results = {
                        "hits_over_limit": True,
                        "att_name": att_report["name"],
                        "hits_count": len(hits)
                    }
                else:
                    query_execution_date = datetime.datetime.now().strftime(
                        '%m-%d-%Y %H:%M:%S')
                    results = {
                        "endpoint_hits": json.loads(json.dumps(hits)),
                        "hits_count": len(hits),
                        "query_execution_date": query_execution_date
                    }

            yield StatusMessage("done...")

            log.debug(results)

            # Produce a FunctionResult with the results
            yield FunctionResult(results)
        except Exception:
            log.exception(
                "Exception in Resilient Function for BigFix integration.")
            yield FunctionError()
Пример #4
0
    def _fn_bigfix_remediation_function(self, event, *args, **kwargs):
        """Function: Resilient Function : Bigfix remediation - Remediate hit for endpoint in BigFix."""
        try:
            # Get the function parameters:
            bigfix_asset_id = kwargs.get("bigfix_asset_id")  # text
            bigfix_artifact_value = kwargs.get("bigfix_artifact_value")  # text
            bigfix_artifact_type = kwargs.get("bigfix_artifact_type")  # text
            bigfix_incident_id = kwargs.get("bigfix_incident_id")  # number

            log = logging.getLogger(__name__)
            log.info("bigfix_asset_id: %s", bigfix_asset_id)
            log.info("bigfix_artifact_value: %s", bigfix_artifact_value)
            log.info("bigfix_artifact_type: %s", bigfix_artifact_type)
            log.info("bigfix_incident_id: %s", bigfix_incident_id)

            params = {
                "asset_id": bigfix_asset_id,
                "artifact_value": bigfix_artifact_value,
                "artifact_type": bigfix_artifact_type,
                "incident_id": bigfix_incident_id
            }

            validate_params(params, "fn_bigfix_remediation")

            yield StatusMessage(
                u"Running BigFix remediation for Artifact '{0}' on endpoint '{1}' ..."
                .format(params["artifact_value"], params["asset_id"]))
            bigfix_client = BigFixClient(self.options)

            yield StatusMessage("Running BigFix remediation ...")

            # Send a remediation message to BigFix
            try:
                if params["artifact_type"] == "Process Name":
                    response = bigfix_client.send_kill_process_remediation_message(
                        bigfix_artifact_value, bigfix_asset_id)
                elif params["artifact_type"] == "Service":
                    response = bigfix_client.send_stop_service_remediation_message(
                        bigfix_artifact_value, bigfix_asset_id)
                elif params["artifact_type"] == "Registry Key":
                    if len(bigfix_artifact_value.split('\\')) <= 2:
                        log.exception(
                            "Delete not allowed for root level key %s.",
                            bigfix_artifact_value)
                        yield StatusMessage(
                            "Warning: Delete not allowed for root level key {}."
                            .format(bigfix_artifact_value))
                        response = None
                    else:
                        # Test if registry key has 1 or more subkeys
                        response = None
                        result = bigfix_client.check_exists_subkey(
                            bigfix_artifact_value, bigfix_asset_id)
                        # Query should return array with single result.
                        if not result or not result[0]:
                            log.exception(
                                "Delete not allowed for key '%s'. BigFix subkey query did not return a valid result.",
                                bigfix_artifact_value)
                            yield StatusMessage(
                                "Warning: Delete not allowed for key '{}'. BigFix subkey query did not return a valid result."
                                .format(bigfix_artifact_value))
                        elif (result[0]["failure"] == 0 or result[0]["failure"]
                              == "False") and result[0]["result"] == "True":
                            log.exception(
                                "Delete not allowed, key '%s' has 1 or more subkeys.",
                                bigfix_artifact_value)
                            yield StatusMessage(
                                "Warning: Delete not allowed, key '{}' has 1 or more subkeys."
                                .format(bigfix_artifact_value))
                        else:
                            response = bigfix_client.send_delete_registry_key_remediation_message(
                                bigfix_artifact_value, bigfix_asset_id)
                elif params["artifact_type"] == "File Path":
                    # Test if file path is a folder, if so disallow remediate.
                    response = None
                    result = bigfix_client.check_is_folder(
                        bigfix_artifact_value, bigfix_asset_id)
                    # Query should return array with single result.
                    if not result or not result[0]:
                        log.exception(
                            "Delete not allowed' for artifact %s'. BigFix subkey query did not return a valid result.",
                            bigfix_artifact_value)
                        yield StatusMessage(
                            "Warning: Delete not allowed for artifact '{}'. BigFix subkey query did not "
                            "return a valid result".format(
                                bigfix_artifact_value))
                    elif (result[0]["failure"] == 0 or result[0]["failure"]
                          == "False") and result[0]["result"] == "True":
                        log.exception(
                            "Delete not allowed, '%s' is a folder artifact.",
                            bigfix_artifact_value)
                        yield StatusMessage(
                            "Warning: Delete not allowed for folder artifact '{}'."
                            .format(bigfix_artifact_value))
                    else:
                        response = bigfix_client.send_delete_file_remediation_message(
                            bigfix_artifact_value, bigfix_asset_id)
                else:
                    log.error("Unsupported artifact type '%s'.",
                              params["artifact_type"])
                    raise ValueError("Unsupported artifact type '{}'.".format(
                        params["artifact_type"]))
            except Exception as e:
                log.exception("Failed to run a BigFix remediation.")
                yield StatusMessage(
                    "Failed with exception '{}' while trying to run a BigFix remediation."
                    .format(type(e).__name__))
                raise Exception(
                    "Failed with exception '{}' while trying to run a BigFix remediation."
                    .format(type(e).__name__))

            if response is None:
                log.debug("Could not create BigFix Action.")
                raise FunctionError("Could not create BigFix Action")
            else:
                status_message = "BigFix action created successfully."
                action_id = response
                remediation_date = datetime.datetime.today().strftime(
                    '%m-%d-%Y %H:%M:%S')
                results = {
                    "status": "OK",
                    "status_message": status_message,
                    "remediation_date": remediation_date,
                    "action_id": action_id
                }

            yield StatusMessage("done...")

            log.debug(results)

            # Produce a FunctionResult with the results
            yield FunctionResult(results)
        except Exception:
            log.exception(
                "Exception in Resilient Function for BigFix integration.")
            yield FunctionError()
    def _fn_bigfix_action_status_function(self, event, *args, **kwargs):
        """Function: Resilient Function : Bigfix action status - Get status for Bigfix action id."""
        try:
            # Get the function parameters:
            bigfix_action_id = kwargs.get("bigfix_action_id")  # number

            log = logging.getLogger(__name__)
            log.info("bigfix_action_id: %s", bigfix_action_id)

            if is_none(bigfix_action_id):
                raise ValueError(
                    "Required parameter 'bigfix_action_id' not set.")

            yield StatusMessage(
                "Running Query BigFix for BigFix action id '{}' ...".format(
                    bigfix_action_id))
            bigfix_client = BigFixClient(self.options)
            retry_interval = int(self.options.get("bigfix_polling_interval"))
            retry_timeout = int(self.options.get("bigfix_polling_timeout"))

            # Check status every 'retry_interval' secs up to 'retry_timeout' secs
            try:
                status = None
                (status, status_message) = poll_action_status(
                    bigfix_client, bigfix_action_id, retry_interval,
                    retry_timeout)
            except Exception as e:
                log.exception("Failed to poll BigFix action status.")
                yield StatusMessage(
                    "Failed with exception '{}' while trying to poll BigFix action status."
                    .format(type(e).__name__))
                raise Exception(
                    "Failed with exception '{}' while trying to poll BigFix action status."
                    .format(type(e).__name__))

            if not status:
                raise FunctionError(
                    "Function 'poll_action_status' returned bad status {}.".
                    format(status))
            elif status == "OK":
                yield StatusMessage(
                    "Received successful status message '{0}' for BigFix action {1}."
                    .format(re.sub('\.$', '', status_message),
                            bigfix_action_id))
                results = {"status": "OK", "status_message": status_message}
            elif status == "Failed":
                yield StatusMessage(
                    "Received error status {0} for BigFix action {1}.".format(
                        status_message, bigfix_action_id))
                results = {
                    "status": "Failed",
                    "status_message": status_message
                }
            elif status == "Unsupported":
                yield StatusMessage(
                    "Received  unexpected status {0} while retrieving status for BigFix action {1}."
                    .format(status_message, bigfix_action_id))
                results = {}
            elif status == "Timedout":
                yield StatusMessage(
                    "Timed out getting action status for BigFix action {}".
                    format(bigfix_action_id))
                results = {}

            yield StatusMessage("done...")

            log.debug(results)

            # Produce a FunctionResult with the results
            yield FunctionResult(results)
        except Exception:
            log.exception(
                "Exception in Resilient Function for BigFix integration.")
            yield FunctionError()