Esempio n. 1
0
    def validate_params(self):

        if not self.get_global_setting("canary_domain"):
            self.log_error(
                'canary_domain is a mandatory setup parameter, but its value is None.'
            )
            return False

        splunk_session_key = self.session_key
        splunkService = client.connect(token=splunk_session_key)
        api_key = get_api_key(splunkService)
        if not api_key:
            self.log_error(
                'api_key is a mandatory setup parameter, but its value is None.'
            )
            return False
        return True
Esempio n. 2
0
def collect_events(helper, ew):
    domain = helper.get_global_setting('canary_domain')
    api_key = get_api_key(helper.service)
    incident_limit = 20

    #Admin can use XXXXXXX.canary.tools or simply XXXXXXX
    if not domain.endswith('.canary.tools'):
        domain += '.canary.tools'
    #Check to see if proxy setting is configured
    proxy = helper.get_proxy()

    if proxy:
        use_proxy = True
    else:
        use_proxy = False

    #Set a custom useragent header for Splunk API so Canary.tools can measure the use of the product
    #Include the TA-canary version number
    try:
        ta_version = [
            i for i in helper.service.apps.list() if i.name == helper.app
        ][0].content['version']
    except:
        ta_version = 'N/A'
    try:
        splunk_version = helper.service.info['version']
    except KeyError:
        splunk_version = 'Unknown_version'  # the call above worked correctly on 7.3 -> 8.0.5 so another version is likely
    headers = {
        'User-Agent':
        'Splunk API Call TA-Canary ({ta_version}) Splunk ({splunk_version}) '.
        format(ta_version=ta_version, splunk_version=splunk_version),
        'X-Canary-Auth-Token':
        api_key
    }

    #Pass the domain and the api key to the url.
    url = "https://{}/api/v1/ping".format(domain)

    #Set the method of Get to the console
    method = "GET"
    #Try the first connection to see if it works.
    response = helper.send_http_request(url,
                                        method,
                                        headers=headers,
                                        verify=True,
                                        timeout=60,
                                        use_proxy=use_proxy)

    try:
        response
    except Exception as e:
        helper.log_error(
            "Error occured with canary.tools API call. Error Message: {}".
            format(e))
        sys.exit()

    if response.status_code == 200:
        #Successfull Connection
        helper.log_info("Successfully connected to Canary.tools API")

        #Get current time for testing purposes.
        current_time = time.time()

        #Collect All incidents from Canary Tools
        url_allIncidents = "https://{}/api/v1/incidents/all?tz=UTC&limit={}".format(
            domain, incident_limit)
        if helper.get_check_point('last_updated_id'):
            url_allIncidents += '&incidents_since={}'.format(
                helper.get_check_point('last_updated_id'))
            # helper.log_info("last_updated_id URL is {}".format(url_allIncidents))

        #Collect All Registered Devices from Canary Tools
        url_regDevices = "https://{}/api/v1/devices/all?tz=UTC".format(domain)

        #Collect All Canary Tokens from Canary Tools
        url_canarytokens_fetch = "https://{}/api/v1/canarytokens/fetch".format(
            domain)

        #Issue a new response to the Registered DevicesAPI
        response_regDevices = helper.send_http_request(url_regDevices,
                                                       method,
                                                       headers=headers,
                                                       verify=True,
                                                       timeout=60,
                                                       use_proxy=use_proxy)

        #Issue a new response to the Canary Tokens API
        response_canarytokens_fetch = helper.send_http_request(
            url_canarytokens_fetch,
            method,
            headers=headers,
            verify=True,
            timeout=60,
            use_proxy=use_proxy)

        #Try to connect to the url for registered devices
        try:
            response_regDevices
        #Throw an exception if it fails
        except Exception as e:
            helper.log_error(
                "Error occured with canary.tools API call to retrieve all registered devices. Error Message: {}"
                .format(e))
            sys.exit()
        #Try to connect to the url for canary tokens
        try:
            response_canarytokens_fetch
        #Throw an exception if it fails
        except Exception as e:
            helper.log_error(
                "Error occured with canary.tools API call to retrieve all canary tokens. Error Message: {}"
                .format(e))
            sys.exit()
        #Issue a new response to the All Incidents API
        response_allIncidents = helper.send_http_request(url_allIncidents,
                                                         method,
                                                         headers=headers,
                                                         verify=True,
                                                         timeout=60,
                                                         use_proxy=use_proxy)

        #Try to connect to the url for All Incidents
        try:
            response_allIncidents
        #Throw an exception if it fails
        except Exception as e:
            helper.log_error(
                "Error occured with canary.tools API call to retrieve all Incidents. Error Message: {}"
                .format(e))
            sys.exit()

        #Set the most recent updated_id to the last seen incident updated_id, or the epoch
        last_updated_id = helper.get_check_point('last_updated_id')
        if not last_updated_id:
            last_updated_id = 0

        while response_allIncidents.status_code == 200:
            #If we receive a 200 response from the all incidents API
            #Output the results to json
            data = response_allIncidents.json()

            try:
                if last_updated_id < data['max_updated_id']:
                    last_updated_id = data['max_updated_id']
            except:
                #max_updated_id is only present on queries with incidents
                pass

            if len(data['incidents']) > 0:
                for a in data['incidents']:
                    #Add current time of server to timestamp
                    a['_time'] = current_time
                    #Convert data to a string
                    data_dump = json.dumps(a)
                    #Write the event to the destination index
                    event = helper.new_event(
                        data_dump,
                        source=helper.get_input_type(),
                        index=helper.get_output_index(),
                        sourcetype="canarytools:incidents")
                    ew.write_event(event)
            else:
                #If no incidents have been logged
                #Add current time of server to timestamp
                helper.log_info(
                    "No incidents have been logged. Successful connection to canaryapi"
                )

            if not data['cursor']['next_link'] or not data['cursor'][
                    'next_link'].startswith('https://'):
                break

            response_allIncidents = helper.send_http_request(
                data['cursor']['next_link'],
                method,
                headers=headers,
                verify=True,
                timeout=60,
                use_proxy=use_proxy)
        #If the resposne code from querying the Incidents is not 200
        else:
            helper.log_error(
                "Error occured with canary.tools API call. Error Message: {}".
                format(response_allIncidents.json()))

        if last_updated_id:
            helper.save_check_point('last_updated_id', last_updated_id)
            helper.log_debug("Setting last_updated_id checkpoint to {}".format(
                last_updated_id))

        #If we receive a 200 response from the registered devices API
        if response_regDevices.status_code == 200:
            #Output the results to json
            data = response_regDevices.json()
            if len(data['devices']) > 0:
                for a in data['devices']:
                    #Only create a device event for new or changed devices
                    check_point_key = 'device:' + a['id']
                    saved_data = helper.get_check_point(check_point_key)
                    if not saved_data:
                        saved_data = {}

                    monitor_fields = [
                        'name', 'description', 'ip_address', 'live', 'version'
                    ]
                    fields_changed = False
                    for field in monitor_fields:
                        if a.get(field, None) != saved_data.get(field, None):
                            fields_changed = True
                            break
                    if not fields_changed:
                        continue
                    helper.save_check_point(check_point_key, a)

                    #Add current time of server to timestamp
                    a['_time'] = current_time
                    #Convert data to a string
                    data_dump = json.dumps(a)
                    #Write the event to the destination index
                    event = helper.new_event(data_dump,
                                             source=helper.get_input_type(),
                                             index=helper.get_output_index(),
                                             sourcetype="canarytools:devices")
                    ew.write_event(event)
            else:
                #If no devices have been registered
                #Add current time of server to timestamp
                helper.log_info(
                    "No devices have been registered. Successful connection to canaryapi"
                )

        #If the resposne code from querying the Registered devices is not 200
        else:
            helper.log_error(
                "Error occured with canary.tools API call. Error Message: {}".
                format(response_regDevices.json()))

        #If we receive a 200 response from the canary tokens API
        if response_canarytokens_fetch.status_code == 200:
            #Output the results to json
            data = response_canarytokens_fetch.json()

            if len(data['tokens']) > 0:
                for a in data['tokens']:
                    #Only create a token event for new or changed tokens
                    check_point_key = 'token:' + a['node_id']
                    saved_data = helper.get_check_point(check_point_key)
                    if not saved_data:
                        saved_data = {}

                    monitor_fields = ['memo', 'enabled']
                    fields_changed = False
                    for field in monitor_fields:
                        if a.get(field, None) != saved_data.get(field, None):
                            fields_changed = True
                            break
                    if not fields_changed:
                        continue
                    helper.save_check_point(check_point_key, a)

                    #Add current time of server to timestamp
                    a['_time'] = current_time
                    #Convert data to a string
                    data_dump = json.dumps(a)
                    #Write the event to the destination index
                    event = helper.new_event(data_dump,
                                             source=helper.get_input_type(),
                                             index=helper.get_output_index(),
                                             sourcetype="canarytools:tokens")
                    ew.write_event(event)
            else:
                #If no tokens have been registered
                #Add current time of server to timestamp
                helper.log_info(
                    "No tokens have been regiestered. Successful connection to canaryapi"
                )

        else:
            helper.log_error(
                "Error occured with canary.tools API call. Error Message: {}".
                format(response_canarytokens_fetch.json()))

    else:
        helper.log_error(
            "Error occured with canary.tools API call. Error Message: {}".
            format(response.json()))
Esempio n. 3
0
def process_event(helper, *args, **kwargs):
    """
    # IMPORTANT
    # Do not remove the anchor macro:start and macro:end lines.
    # These lines are used to generate sample code. If they are
    # removed, the sample code will not be updated when configurations
    # are updated.

    [sample_code_macro:start]

    # The following example gets and sets the log level
    helper.set_log_level(helper.log_level)

    # The following example gets the setup parameters and prints them to the log
    canary_domain = helper.get_global_setting("canary_domain")
    #Admin can use XXXXXXX.canary.tools or simply XXXXXXX
    if not canary_domain.endswith('.canary.tools'):
        canary_domain += '.canary.tools'
    helper.log_info("canary_domain={}".format(canary_domain))
    splunk_session_key = helper.session_key
    splunkService = client.connect(token=splunk_session_key)
    api_key = get_api_key(splunkService)

    # The following example sends rest requests to some endpoint
    # response is a response object in python requests library
    response = helper.send_http_request("http://www.splunk.com", "GET", parameters=None,
                                        payload=None, headers=None, cookies=None, verify=True, cert=None, timeout=None, use_proxy=True)
    # get the response headers
    r_headers = response.headers
    # get the response body as text
    r_text = response.text
    # get response body as json. If the body text is not a json string, raise a ValueError
    r_json = response.json()
    # get response cookies
    r_cookies = response.cookies
    # get redirect history
    historical_responses = response.history
    # get response status code
    r_status = response.status_code
    # check the response status, if the status is not sucessful, raise requests.HTTPError
    response.raise_for_status()


    # The following example gets the alert action parameters and prints them to the log
    incident_id = helper.get_param("incident_id")
    helper.log_info("incident_id={}".format(incident_id))

    index_name = helper.get_param("index_name")
    helper.log_info("index_name={}".format(index_name))


    # The following example adds two sample events ("hello", "world")
    # and writes them to Splunk
    # NOTE: Call helper.writeevents() only once after all events
    # have been added
    helper.addevent("hello", sourcetype="sample_sourcetype")
    helper.addevent("world", sourcetype="sample_sourcetype")
    helper.writeevents(index="summary", host="localhost", source="localhost")

    # The following example gets the events that trigger the alert
    events = helper.get_events()
    for event in events:
        helper.log_info("event={}".format(event))

    # helper.settings is a dict that includes environment configuration
    # Example usage: helper.settings["server_uri"]
    helper.log_info("server_uri={}".format(helper.settings["server_uri"]))
    [sample_code_macro:end]
    """
    import json
    import time
    import splunklib.client as client
    sys.path.insert(0, '../')
    from api_key_retrieval import get_api_key
    helper.log_info("Alert action canary_delete_an_incident started.")

    domain = helper.get_global_setting('canary_domain')
    #Admin can use XXXXXXX.canary.tools or simply XXXXXXX
    if not domain.endswith('.canary.tools'):
        domain += '.canary.tools'
    helper.log_info("canary_domain={}".format(domain))
    splunk_session_key = helper.session_key
    splunkService = client.connect(token=splunk_session_key)
    api_key = get_api_key(splunkService)

    #Check to see if proxy setting is configured
    proxy = helper.get_proxy()

    if proxy:
        use_proxy = True
    else:
        use_proxy = False

    #Set a custom useragent header for Splunk API so Canary.tools can see the use of the product
    #Include the TA-canary version number
    try:
        version = [
            i for i in helper.service.apps.list() if i.name == helper.app
        ][0].content['version']
    except:
        version = 'N/A'
    headers = {
        'User-Agent': 'Splunk API Call ({})'.format(version),
        'X-Canary-Auth-Token': api_key
    }

    #Get ID of Incident
    incident_id = helper.get_param("incident_id")

    #Get Index Name
    index_name = helper.get_param("index_name")

    #Get current time for testing purposes.
    current_time = time.time()

    #Pass the domain and the api key to the url.
    url = "https://{}/api/v1/incident/delete?incident={}".format(
        domain, incident_id)

    #Set the method of Get to the console
    method = "DELETE"

    #Try the first connection to see if it works.
    response = helper.send_http_request(url,
                                        method,
                                        parameters=None,
                                        payload=canary_data,
                                        headers=headers,
                                        cookies=None,
                                        verify=True,
                                        cert=None,
                                        timeout=None,
                                        use_proxy=use_proxy)

    try:
        response
    except Exception as e:
        helper.log_error(
            "Error occured with canary.tools Acknowledging an incident. Error Message: {}"
            .format(e))
        sys.exit()

    if response.status_code == 200:
        #Successfull Connection
        helper.log_info("Successfully deleted incident")

        data = response.json()
        data['api_call'] = 'Incident Acknowledged'
        data['_time'] = current_time
        json_data = json.dumps(data)

        helper.addevent(json_data, sourcetype="canarytools:ar")

        helper.writeevents(source="canary_toolsapi",
                           index=index_name,
                           host="adaptive_response")

    else:
        data = response.json()
        data['api_call'] = 'Incident Deleted'
        data['_time'] = current_time
        json_data = json.dumps(data)
        helper.addevent(json_data, sourcetype="canarytools:ar")
        helper.writeevents(source="canary_toolsapi",
                           index=index_name,
                           host="adaptive_response")
        helper.log_error("Error with deleting incident.")

    # TODO: Implement your alert action logic here
    return 0
Esempio n. 4
0
def collect_events(helper, ew):
    domain = helper.get_global_setting('canary_domain')

    #Admin can use XXXXXXX.canary.tools or simply XXXXXXX
    if not domain.endswith('.canary.tools'):
        domain += '.canary.tools'
    api_key = get_api_key(helper.service)
    # api_key = helper.get_global_setting("api_key")
    incident_limit = 20

    #Check to see if proxy setting is configured
    proxy = helper.get_proxy()

    if proxy:
        use_proxy = True
    else:
        use_proxy = False

    #Set a custom useragent header for Splunk API so Canary.tools can measure the use of the product
    #Include the TA-canary version number
    try:
        version = [
            i for i in helper.service.apps.list() if i.name == helper.app
        ][0].content['version']
    except:
        version = 'N/A'
    headers = {
        'User-Agent': 'Splunk API Call ({})'.format(version),
        'X-Canary-Auth-Token': api_key
    }

    #Pass the domain and the api key to the url.
    url = "https://{}/api/v1/ping".format(domain)

    #Set the method of Get to the console
    method = "GET"
    #Try the first connection to see if it works.
    response = helper.send_http_request(url,
                                        method,
                                        headers=headers,
                                        verify=True,
                                        timeout=60,
                                        use_proxy=use_proxy)

    try:
        response
    except Exception as e:
        helper.log_error(
            "Error occured with canary.tools Device poll API call. Error Message: {}"
            .format(e))
        sys.exit()

    if response.status_code == 200:
        #Successfull Connection
        helper.log_info("Successfully connected to Canary.tools API")

        #Get current time for testing purposes.
        current_time = time.time()

        #Collect All unacknowledged incidents from Canary Tools
        url_unacknowledgedIncidents = "https://{}/api/v1/incidents/unacknowledged?tz=UTC&limit={}".format(
            domain, incident_limit)

        url_cursorIncidents = "https://{}/api/v1/incidents/unacknowledged?tz=UTC&cursor=".format(
            domain)

        #Collect All Registered Devices from Canary Tools
        url_regDevices = "https://{}/api/v1/devices/all?tz=UTC".format(domain)

        #Collect All Canary Tokens from Canary Tools
        url_canarytokens_fetch = "https://{}/api/v1/canarytokens/fetch".format(
            domain)

        #Issue a new response to the Registered DevicesAPI
        response_regDevices = helper.send_http_request(url_regDevices,
                                                       method,
                                                       headers=headers,
                                                       verify=True,
                                                       timeout=60,
                                                       use_proxy=use_proxy)

        #Issue a new response to the Canary Tokens API
        response_canarytokens_fetch = helper.send_http_request(
            url_canarytokens_fetch,
            method,
            headers=headers,
            verify=True,
            timeout=60,
            use_proxy=use_proxy)

        #Issue a new response to the All Incidents API
        response_unacknowledgedIncidents = helper.send_http_request(
            url_unacknowledgedIncidents,
            method,
            headers=headers,
            verify=True,
            timeout=60,
            use_proxy=use_proxy)

        #Try to connect to the url for All Incidents
        try:
            response_unacknowledgedIncidents
        #Throw an exception if it fails
        except Exception as e:
            helper.log_error(
                "Error occured with canary.tools API call to retrieve all unacknowledged Incidents. Error Message: {}"
                .format(e))
            sys.exit()
        #Set the most recent timestamp to the current time.
        most_recent_timestamp = current_time

        #Try to connect to the url for registered devices
        try:
            response_regDevices
        #Throw an exception if it fails
        except Exception as e:
            helper.log_error(
                "Error occured with canary.tools API call to retrieve all registered devices. Error Message: {}"
                .format(e))
            sys.exit()
        #Try to connect to the url for canary tokens
        try:
            response_canarytokens_fetch
        #Throw an exception if it fails
        except Exception as e:
            helper.log_error(
                "Error occured with canary.tools API call to retrieve all canary tokens. Error Message: {}"
                .format(e))
            sys.exit()

        #If we receive a 200 response from the registered devices API
        if response_regDevices.status_code == 200:
            #Output the results to json
            data = response_regDevices.json()
            if len(data['devices']) > 0:
                for a in data['devices']:
                    #Add current time of server to timestamp
                    a['_time'] = current_time
                    #Convert data to a string
                    data_dump = json.dumps(a)
                    #Write the event to the destination index
                    event = helper.new_event(data_dump,
                                             source=helper.get_input_type(),
                                             index=helper.get_output_index(),
                                             sourcetype="canarytools:devices")
                    ew.write_event(event)
            else:
                #If no devices have been registered
                helper.log_info(
                    "No devices have been registered. Successful connection to canaryapi"
                )

        #If the resposne code from querying the Registered devices is not 200
        else:
            helper.log_error(
                "Error occured with canary.tools API call. Error Message: {}".
                format(response_regDevices.json()))

        #If we receive a 200 response from the canary tokens API
        if response_canarytokens_fetch.status_code == 200:
            #Output the results to json
            data = response_canarytokens_fetch.json()

            if len(data['tokens']) > 0:
                for a in data['tokens']:
                    #Add current time of server to timestamp
                    a['_time'] = current_time
                    #Convert data to a string
                    data_dump = json.dumps(a)
                    #Write the event to the destination index
                    event = helper.new_event(data_dump,
                                             source=helper.get_input_type(),
                                             index=helper.get_output_index(),
                                             sourcetype="canarytools:tokens")
                    ew.write_event(event)
            else:
                #If no tokens have been registered
                helper.log_info(
                    "No tokens have been regiestered. Successful connection to canaryapi"
                )

        else:
            helper.log_error(
                "Error occured with canary.tools API call. Error Message: {}".
                format(response_canarytokens_fetch.json()))

        while response_unacknowledgedIncidents.status_code == 200:
            #If we receive a 200 response from the all incidents API
            #Output the results to json
            data = response_unacknowledgedIncidents.json()

            if len(data['incidents']) > 0:
                for a in data['incidents']:
                    #Add current time of server to timestamp
                    a['_time'] = current_time
                    #Convert data to a string
                    data_dump = json.dumps(a)
                    #Write the event to the destination index
                    event = helper.new_event(
                        data_dump,
                        source=helper.get_input_type(),
                        index=helper.get_output_index(),
                        sourcetype="canarytools:incidents")
                    ew.write_event(event)
                    try:
                        created_timestamp = int(a['description']['created'])
                        if created_timestamp > most_recent_timestamp:
                            most_recent_timestamp = created_timestamp
                    except (KeyError, ValueError) as e:
                        helper.log_error(
                            "Error updating timestamp {}".format(e))

            else:
                #If no incidents have been logged
                helper.log_info(
                    "No incidents have been logged. Successful connection to canaryapi"
                )

            if not data['cursor']['next_link'] or not data['cursor'][
                    'next_link'].startswith('https://'):
                break

            response_unacknowledgedIncidents = helper.send_http_request(
                data['cursor']['next_link'],
                method,
                headers=headers,
                verify=True,
                timeout=60,
                use_proxy=use_proxy)
        #If the resposne code from querying the Incidents is not 200
        else:
            helper.log_error(
                "Error occured with canary.tools API call. Error Message: {}".
                format(response_unacknowledgedIncidents.json()))

    else:
        helper.log_error(
            "Error occured with canary.tools device API call. Error Message: {}"
            .format(response.json()))