def fetch(): """ Query viewer should be defined in ArcSight ESM. fetch incidents fetches the results of query viewer and converts them to Demisto incidents. We can query Cases or Events. If Cases are fetched then the query viewer query must return fields ID and Create Time. If Events are fetched then Event ID and Start Time. """ events_query_viewer_id = demisto.params().get('viewerId') cases_query_viewer_id = demisto.params().get('casesQueryViewerId') type_of_incident = 'case' if events_query_viewer_id else 'event' last_run = json.loads(demisto.getLastRun().get('value', '{}')) already_fetched = last_run.get('already_fetched', []) fields, query_results = get_query_viewer_results(events_query_viewer_id or cases_query_viewer_id) # sort query_results by creation time query_results.sort(key=lambda k: int(k.get('Start Time') or k.get('Create Time'))) incidents = [] for result in query_results: # convert case or event to demisto incident r_id = result.get('ID') or result.get('Event ID') if r_id not in already_fetched: create_time_epoch = int(result.get('Start Time') or result.get('Create Time')) result['Create Time'] = parse_timestamp_to_datestring(create_time_epoch) incident_name = result.get('Name') or 'New {} from arcsight at {}'.format(type_of_incident, datetime.now()) labels = [{'type': key.encode('utf-8'), 'value': value.encode('utf-8') if value else value} for key, value in result.items()] incident = { 'name': incident_name, 'occurred': result['Create Time'], 'labels': labels, 'rawJSON': json.dumps(result) } incidents.append(incident) if len(incidents) >= FETCH_CHUNK_SIZE: break if len(already_fetched) > MAX_UNIQUE: already_fetched.pop(0) already_fetched.append(r_id) last_run = { 'already_fetched': already_fetched, } demisto.setLastRun({'value': json.dumps(last_run)}) decode_arcsight_output(incidents) if demisto.command() == 'as-fetch-incidents': contents = { 'last_run': last_run, 'last_run_updated': demisto.getLastRun(), 'incidents': incidents, 'already_fetched': already_fetched } return_outputs(readable_output='', outputs={}, raw_response=contents) else: demisto.incidents(incidents)
def fetch_incidents(): param_dict = {} now_time = datetime.utcnow() now = datetime.isoformat(now_time) lastRunObject = demisto.getLastRun() if lastRunObject: param_dict['since'] = lastRunObject['time'] else: param_dict['since'] = datetime.isoformat(now_time - timedelta(minutes=int(FETCH_INTERVAL))) param_dict['until'] = now url = SERVER_URL + GET_INCIDENTS_SUFFIX + configure_status() res = http_request('GET', url, param_dict) _, parsed_incidents, raw_responses = parse_incident_data(res.get('incidents', [])) incidents = [] for incident, raw_response in zip(parsed_incidents, raw_responses): incidents.append({ 'name': incident['ID'] + ' - ' + incident['Title'], 'occurred': incident['created_at'], 'severity': translate_severity(incident['urgency']), 'rawJSON': json.dumps(raw_response) }) demisto.incidents(incidents) demisto.setLastRun({'time': now})
def fetch_incidents(): last_run = demisto.getLastRun() # Get the last fetch time, if exists last_fetch = last_run.get('time') # Handle first time fetch, fetch incidents retroactively if last_fetch is None: last_fetch, _ = parse_date_range(FETCH_TIME, date_format='%Y-%m-%dT%H:%M:%S') latest = datetime.strptime(last_fetch, '%Y-%m-%dT%H:%M:%S') demisto.debug('getting alarms since {}'.format(last_fetch)) incidents = [] items = list_alerts(time_frame='Custom', start_time=last_fetch) demisto.debug('got {} new alarms'.format(len(items))) for item in items: incident_date = datetime.strptime(item['ALERT_TIME'], '%Y-%m-%d %H:%M:%S') incident = { 'Type': 'Fidelis', 'name': '{} {}'.format(item['ALERT_ID'], item['SUMMARY']), 'occurred': incident_date.strftime('%Y-%m-%dT%H:%M:%SZ'), 'rawJSON': json.dumps(item), } latest = max(latest, incident_date) incidents.append(incident) if latest != last_fetch: last_fetch = (latest + timedelta(seconds=1)).strftime('%Y-%m-%dT%H:%M:%S') demisto.setLastRun({'time': last_fetch}) demisto.incidents(incidents)
def fetch_incidents(): last_fetched_event_timestamp = demisto.getLastRun().get('last_fetched_event_timestamp') if last_fetched_event_timestamp is not None: last_fetched_event_timestamp = datetime.strptime(last_fetched_event_timestamp, '%Y-%m-%dT%H:%M:%S.%f') else: last_fetched_event_timestamp, _ = parse_date_range(FIRST_FETCH_TIMESTAMP) # Need sometime in the future, so the timestamp will be taken from the query service_end_date_epoch = int(datetime.now().strftime('%s')) + 1000 global FETCH_QUERY if 'panw.' in FETCH_QUERY: service_start_date_epoch = int(last_fetched_event_timestamp.strftime('%s')) FETCH_QUERY += f' WHERE receive_time>{service_start_date_epoch}' elif 'tms.' in FETCH_QUERY: service_start_date_iso = last_fetched_event_timestamp.strftime('%Y-%m-%dT%H:%M:%S.%fZ') FETCH_QUERY += f" WHERE serverTime>'{service_start_date_iso}'" query_data = { 'query': FETCH_QUERY, 'startTime': 0, 'endTime': service_end_date_epoch, } response = query_loggings(query_data) try: result = response.json()['result'] pages = result['esResult']['hits']['hits'] except ValueError: raise Exception('Failed to parse the response from Cortex') incident_pairs = [] max_fetched_event_timestamp = last_fetched_event_timestamp for page in pages: incident, time_received = convert_log_to_incident(page) if 'panw.' in FETCH_QUERY: time_received_dt = datetime.fromtimestamp(time_received) elif 'tms.' in FETCH_QUERY: time_received_dt = datetime.strptime(time_received, '%Y-%m-%dT%H:%M:%S.%fZ') incident_pairs.append((incident, time_received_dt)) if incident_pairs: incidents, max_fetched_event_timestamp = process_incident_pairs(incident_pairs, 100) # max 100 per run demisto.setLastRun({ 'last_fetched_event_timestamp': max_fetched_event_timestamp.strftime('%Y-%m-%dT%H:%M:%S.%f') }) demisto.incidents(incidents) else: demisto.incidents([])
def fetch_incidents(): """ Generates and fetches phishing email-like incidents Generates phishing email-like incidents, with the number of incidents, the speed of generation and the recurring time period all set by the values entered in the integration instance parameters. This method operates under the assumption that fetch-incidents is called once per minute. returns: Email-like incidents """ try: update_parameters() if not FREQUENCY: # Run once last_run = 0 if not demisto.getLastRun() else demisto.getLastRun().get('numOfIncidentsCreated', 0) num_of_incidents_created, incidents = generate_incidents(last_run) demisto.incidents(incidents) demisto.setLastRun({'numOfIncidentsCreated': last_run + num_of_incidents_created}) return else: minutes_of_generation = MAX_NUM_OF_INCIDENTS / float(INCIDENTS_PER_MINUTE) if minutes_of_generation > FREQUENCY: err_msg = 'The maximum number of incidents divided by the incidents to generate per minute' err_msg += ' exceeds every how often incidents should be generated. Please increase the value' err_msg += ' entered for how often the integration should generate incidents.' raise Exception(err_msg) run_counter = 0 if not demisto.getLastRun() else demisto.getLastRun().get('run_count', 0) last_run = 0 if not demisto.getLastRun() else demisto.getLastRun().get('numOfIncidentsCreated', 0) should_run = run_counter % FREQUENCY if should_run < math.ceil(minutes_of_generation): # then should run if should_run == 0: last_run = 0 num_of_incidents_created, incidents = generate_incidents(last_run) demisto.incidents(incidents) total_incidents_created = last_run + num_of_incidents_created updated_run_count = run_counter + 1 demisto.setLastRun({ 'numOfIncidentsCreated': total_incidents_created, 'run_count': updated_run_count }) return else: updated_run_count = run_counter + 1 demisto.setLastRun({ 'numOfIncidentsCreated': last_run, 'run_count': updated_run_count }) demisto.incidents([]) except Exception: raise
def fetch_incidents(): params = demisto.params() user_key = params.get('queryUserKey') user_key = user_key if user_key else ADMIN_EMAIL query = '' if params['query'] is None else params['query'] last_run = demisto.getLastRun() last_fetch = last_run.get('time') # handle first time fetch if last_fetch is None: last_fetch = datetime.datetime.now() - datetime.timedelta(days=1) else: last_fetch = datetime.datetime.strptime( last_fetch, '%Y-%m-%dT%H:%M:%SZ') current_fetch = last_fetch credentials = get_credentials( ['https://www.googleapis.com/auth/gmail.readonly', ], user_key) service = discovery.build('gmail', 'v1', credentials=credentials) query += last_fetch.strftime(' after:%Y/%m/%d') LOG('GMAIL: fetch parameters:\nuser: %s\nquery=%s\nfetch time: %s' % (user_key, query, last_fetch, )) result = service.users().messages().list( userId=user_key, maxResults=100, q=query).execute() incidents = [] # so far, so good LOG('GMAIL: possible new incidents are %s' % (result, )) for msg in result.get('messages', []): msg_result = service.users().messages().get( id=msg['id'], userId=user_key).execute() incident = mail_to_incident(msg_result, service, user_key) temp_date = datetime.datetime.strptime( incident['occurred'], '%Y-%m-%dT%H:%M:%SZ') # update last run if temp_date > last_fetch: last_fetch = temp_date + datetime.timedelta(seconds=1) # avoid duplication due to weak time query if temp_date > current_fetch: incidents.append(incident) demisto.info('extract {} incidents'.format(len(incidents))) demisto.setLastRun({'time': last_fetch.isoformat().split('.')[0] + 'Z'}) return incidents
def fetch_incidents(query, id_offset=None, fetch_by_created=None, **_): last_run = demisto.getLastRun() demisto.debug(f"last_run: {last_run}" if last_run else 'last_run is empty') id_offset = last_run.get("idOffset") if (last_run and last_run.get("idOffset")) else id_offset incidents, max_results = [], 50 if id_offset: query = f'{query} AND id >= {id_offset}' if fetch_by_created: query = f'{query} AND created>-1m' res = run_query(query, '', max_results) for ticket in res.get('issues'): id_offset = max(id_offset, ticket.get("id")) incidents.append(create_incident_from_ticket(ticket)) demisto.setLastRun({"idOffset": id_offset}) demisto.incidents(incidents)
def load_extended_keys(): global EXTENDED_KEYS if demisto.command() == 'fetch-incidents': last_run = demisto.getLastRun() EXTENDED_KEYS = last_run.get('extended_keys', {}) else: integration_context = demisto.getIntegrationContext() EXTENDED_KEYS = integration_context.get('extended_keys', {}) if not EXTENDED_KEYS: session = login() url = REST_ADDRESS + '/eventAttributeType/all' response = session.get(url, verify=VERIFY_SSL, auth=AUTH) EXTENDED_KEYS = dict((attr['attributeId'], attr['displayName']) for attr in response.json()) if demisto.command() != 'fetch-incidents': demisto.setIntegrationContext({'extended_keys': EXTENDED_KEYS})
def fetch_incidents(objects_names, fetch_time, max_results, query_string, fetch_attachments, real_fetch=False): validate_params_for_fetch(max_results, objects_names, real_fetch) max_results = int(max_results) last_run = demisto.getLastRun() last_objects_fetched = last_run.get('objects_names_to_fetch') if 'last_created_time' in last_run and last_objects_fetched == objects_names: last_created_time = last_run.get('last_created_time') else: try: last_created_time, _ = parse_date_range(fetch_time, date_format=DATE_FORMAT, to_timestamp=False) except ValueError: error_message = f'First fetch time stamp should be of the form: <number> <time unit>, e.g., 12 hours, ' \ f'7 days. Received: "{fetch_time}"' raise_or_return_error(error_message, real_fetch) incidents = get_all_incidents(objects_names, last_created_time, max_results, query_string, real_fetch) if fetch_attachments: incidents = fetch_incidents_attachments(incidents, real_fetch) if real_fetch: save_incidents(incidents) return incidents
def fetch_incidents(): query_id = GetEventQuery() res = GetIncidentsByOrg(query_id) known_ids = demisto.getLastRun().get('ids', None) if known_ids is None or not known_ids: known_ids = [] incidents = [] for inc in res: if inc.get('incidentId') not in known_ids: incidents.append({"name": inc.get('eventName', 'New FortiSIEM Event'), "rawJSON": json.dumps(inc)}) if len(known_ids) >= 1000: known_ids.pop(0) known_ids.append(inc.get('incidentId')) demisto.setLastRun({ 'ids': known_ids, 'extended_keys': EXTENDED_KEYS }) demisto.incidents(incidents) sys.exit(0)
def fetch_incidents(): incidents = [] last_run = demisto.getLastRun() if last_run and last_run['time_stamp']: last_update_time = last_run['time_stamp'] else: # In first run last_update_time, _ = parse_date_range(FETCH_TIME, date_format='%Y-%m-%dT%H:%M:%S.%f'[:-3]) max_timestamp = last_update_time if FETCH_BEHAVIORS: params = 'behaviors.time_stamp>' + last_update_time behaviors = fetch_behaviors_request(params) for behavior in behaviors.get('results'): incident = behavior_to_incident(behavior) # 0 corresponds to never triggered time_stamp = behavior.get('behaviors.time_stamp')[:-5] # comapre time_stamp if time_stamp > max_timestamp: max_timestamp = time_stamp incidents.append(incident) if FETCH_NOTIFICATIONS: params = 'notifications.time_stamp>' + last_update_time notifications = search_notifications_request(params) for notification in notifications.get('results'): incident = notifications_to_incidents(notification) time_stamp = notification.get('notifications.time_stamp')[:-5] if time_stamp > max_timestamp: max_timestamp = time_stamp incidents.append(incident) demisto.setLastRun({ 'time_stamp': max_timestamp }) demisto.incidents(incidents)
def fetch_incidents(): """ Fetch events from this integration and return them as Demisto incidents returns: Demisto incidents """ # demisto.getLastRun() will returns an obj with the previous run in it. last_run = demisto.getLastRun() # Get the last fetch time and data if it exists last_fetch = last_run.get('last_fetched_data_timestamp') last_fetched_data = last_run.get('last_fetched_data') # Handle first time fetch, fetch incidents retroactively if not last_fetch: last_fetch, _ = parse_date_range(FETCH_TIME, to_timestamp=True) args = {'rows': MAX_ROWS, 'query': FETCH_QUERY} column_descriptions, data = snowflake_query(args) data.sort(key=lambda k: k[DATETIME_COLUMN]) # convert the data/events to demisto incidents incidents = [] for row in data: incident = row_to_incident(column_descriptions, row) incident_timestamp = incident.get('timestamp') # Update last run and add incident if the incident is newer than last fetch if incident_timestamp and incident_timestamp >= last_fetch: last_fetch = incident_timestamp if incident.get('rawJSON') != last_fetched_data: last_fetched_data = incident.get('rawJSON') del incident['timestamp'] incidents.append(incident) this_run = { 'last_fetched_data': last_fetched_data, 'last_fetched_data_timestamp': last_fetch } demisto.setLastRun(this_run) demisto.incidents(incidents)
def fetch_incidents_command(): """ Fetch alerts from Canary Tools as incidents in Demisto last_fetch: The latest fetched alert creation time """ last_fetch = demisto.getLastRun().get('time') if last_fetch is None: last_fetch = parse_date_range(FETCH_DELTA, '%Y-%m-%d-%H:%M:%S')[0] # All alerts retrieved from get_alerts are newer than last_fetch and are in a chronological order alerts = get_alerts(last_fetch) incidents = [] current_fetch = last_fetch for alert in alerts: current_fetch = 1000 * (int(demisto.get(alert, 'description.created'))) current_fetch = timestamp_to_datestring(current_fetch, '%Y-%m-%d-%H:%M:%S') incident = create_incident(alert) incidents.append(incident) demisto.incidents(incidents) demisto.setLastRun({'time': current_fetch})
def fetch_incidents(): last_run = demisto.getLastRun() last_fetched_event_timestamp = last_run.get('last_fetched_event_timestamp') last_query_id = last_run.get('last_query_id') if last_query_id: # Need to poll query results fron last run response = poll_query_result(last_query_id) else: if last_fetched_event_timestamp is not None: last_fetched_event_timestamp = datetime.strptime( last_fetched_event_timestamp, '%Y-%m-%dT%H:%M:%S.%f') else: last_fetched_event_timestamp, _ = parse_date_range( FIRST_FETCH_TIMESTAMP) # Need sometime in the future, so the timestamp will be taken from the query service_end_date_epoch = int(datetime.now().strftime('%s')) + 1000 if 'Firewall' in FETCH_QUERY: # type: ignore fetch_timestamp = int(last_fetched_event_timestamp.strftime('%s')) elif 'Traps' in FETCH_QUERY: # type: ignore fetch_timestamp = last_fetched_event_timestamp.strftime( '%Y-%m-%dT%H:%M:%S.%fZ') query = prepare_fetch_query(fetch_timestamp) query_data = { 'query': query, 'startTime': 0, 'endTime': service_end_date_epoch, } response = query_loggings(query_data) try: response_json = response.json() query_status = response_json.get('queryStatus', '') if query_status == 'JOB_FAILED': raise Exception( f'Logging query job failed with status: JOB_FAILED\nResponse: {response.text}' ) elif query_status == 'RUNNING': if isinstance(last_fetched_event_timestamp, datetime): # In case we don't have query ID from previous run last_fetched_event_timestamp = last_fetched_event_timestamp.strftime( '%Y-%m-%dT%H:%M:%S.%f') # If query job is still running after 30 seconds (max timeout), pass it to next run demisto.setLastRun({ 'last_fetched_event_timestamp': last_fetched_event_timestamp, 'last_query_id': response_json.get('queryId', '') }) demisto.incidents([]) return result = response_json.get('result', {}) pages = result['esResult']['hits']['hits'] except ValueError: raise Exception('Failed to parse the response from Cortex') incident_pairs = [] max_fetched_event_timestamp = last_fetched_event_timestamp for page in pages: incident, time_received = convert_log_to_incident(page) if 'Firewall' in FETCH_QUERY: # type: ignore time_received_dt = datetime.fromtimestamp(time_received) elif 'Traps' in FETCH_QUERY: # type: ignore time_received_dt = datetime.strptime(time_received, '%Y-%m-%dT%H:%M:%S.%fZ') incident_pairs.append((incident, time_received_dt)) if incident_pairs: incidents, max_fetched_event_timestamp = process_incident_pairs( incident_pairs, 100) # max 100 per run demisto.setLastRun({ 'last_fetched_event_timestamp': max_fetched_event_timestamp.strftime('%Y-%m-%dT%H:%M:%S.%f') }) demisto.incidents(incidents) else: demisto.incidents([])
def fetch_incidents(aws_client, aws_queue_url, max_fetch, parse_body_as_json): """ Fetching the messages from the queue by following steps: 1. fetch. 2. create-incidents (while skipping previous fetch). 3. save fetch results to context. 4. try to delete all messages (if not successful, will continue next run). """ try: client = aws_client.aws_session(service='sqs') # The 'receipt_handles' of the messages that were received from the last call. last_receipt_handles = demisto.getLastRun().get('lastReceiptHandles') if last_receipt_handles: demisto.debug( 'last_receipt_handles before fetch occurred" -> {} {}'.format( len(last_receipt_handles), last_receipt_handles)) incidents_created = 0 # type: int max_number_of_messages = min(max_fetch, 10) receipt_handles = set() # type: set incidents = [] # type: list while incidents_created < max_fetch: messages = client.receive_message( QueueUrl=aws_queue_url, MaxNumberOfMessages=max_number_of_messages, VisibilityTimeout=30, WaitTimeSeconds=5, ) if "Messages" not in messages.keys(): if incidents_created == 0: if demisto.command() == 'fetch-incidents': demisto.incidents([]) return messages, incidents, receipt_handles else: break # Creating incidents and avoiding creating incidents that were already created previously for message in messages["Messages"]: receipt_handles.add(message['ReceiptHandle']) if last_receipt_handles and message[ 'ReceiptHandle'] in last_receipt_handles: continue incidents.append( parse_incident_from_finding(message, parse_body_as_json)) incidents_created += 1 if incidents_created == max_fetch: break # Save fetch results to context. demisto.incidents(incidents) # The "receipt_handles" of converted messages to the incidents are saved for next fetch demisto.setLastRun({"lastReceiptHandles": receipt_handles}) demisto.debug( 'last_receipt_handles after fetch occurred" -> {} {}'.format( len(receipt_handles), receipt_handles)) # try to delete all messages (if not successful, will continue next run) for receipt_handle in receipt_handles: client.delete_message(QueueUrl=aws_queue_url, ReceiptHandle=receipt_handle) except Exception as e: return raise_error(e)
def build_iterator(self, **kwargs): results = [] urls = self._base_url if not isinstance(urls, list): urls = [urls] for url in urls: _session = requests.Session() prepreq = self._build_request(url) # this is to honour the proxy environment variables kwargs.update( _session.merge_environment_settings( prepreq.url, {}, None, None, None # defaults )) kwargs['stream'] = True kwargs['verify'] = self._verify kwargs['timeout'] = self.polling_timeout if is_demisto_version_ge('6.5.0'): # Set the If-None-Match and If-Modified-Since headers if we have etag or # last_modified values in the context. last_run = demisto.getLastRun() etag = last_run.get(url, {}).get('etag') last_modified = last_run.get(url, {}).get('last_modified') if etag: self.headers['If-None-Match'] = etag if last_modified: self.headers['If-Modified-Since'] = last_modified # set request headers if 'headers' in kwargs: self.headers.update(kwargs['headers']) del kwargs['headers'] if self.headers: prepreq.headers = self.headers try: r = _session.send(prepreq, **kwargs) except requests.exceptions.ConnectTimeout as exception: err_msg = 'Connection Timeout Error - potential reasons might be that the Server URL parameter' \ ' is incorrect or that the Server is not accessible from your host.' raise DemistoException(err_msg, exception) except requests.exceptions.SSLError as exception: # in case the "Trust any certificate" is already checked if not self._verify: raise err_msg = 'SSL Certificate Verification Failed - try selecting \'Trust any certificate\' checkbox in' \ ' the integration configuration.' raise DemistoException(err_msg, exception) except requests.exceptions.ProxyError as exception: err_msg = 'Proxy Error - if the \'Use system proxy\' checkbox in the integration configuration is' \ ' selected, try clearing the checkbox.' raise DemistoException(err_msg, exception) except requests.exceptions.ConnectionError as exception: # Get originating Exception in Exception chain error_class = str(exception.__class__) err_type = '<' + error_class[error_class.find('\'') + 1:error_class.rfind('\'')] + '>' err_msg = 'Verify that the server URL parameter' \ ' is correct and that you have access to the server from your host.' \ '\nError Type: {}\nError Number: [{}]\nMessage: {}\n' \ .format(err_type, exception.errno, exception.strerror) raise DemistoException(err_msg, exception) try: r.raise_for_status() except Exception: return_error('Exception in request: {} {}'.format( r.status_code, r.content)) raise response = self.get_feed_content_divided_to_lines(url, r) if self.feed_url_to_config: fieldnames = self.feed_url_to_config.get(url, {}).get( 'fieldnames', []) skip_first_line = self.feed_url_to_config.get(url, {}).get( 'skip_first_line', False) else: fieldnames = self.fieldnames skip_first_line = False if self.ignore_regex is not None: response = filter( # type: ignore lambda x: self.ignore_regex.match(x) is None, # type: ignore response) csvreader = csv.DictReader(response, fieldnames=fieldnames, **self.dialect) if skip_first_line: next(csvreader) no_update = get_no_update_value( r, url) if is_demisto_version_ge('6.5.0') else True results.append( {url: { 'result': csvreader, 'no_update': no_update }}) return results
def main(): """ Intercept and execute commands. """ # IdentityIQ Base URL (https://identityiq-server.com/identityiq) base_url = demisto.params().get('identityiq_url') # OAuth 2.0 Credentials client_id = demisto.params().get('client_id') client_secret = demisto.params().get('client_secret') grant_type = 'client_credentials' # Convert the argument to an int or set to MAX_INCIDENTS_TO_FETCH max_results = int(demisto.params().get('max_fetch')) if not max_results or max_results > MAX_INCIDENTS_TO_FETCH: max_results = MAX_INCIDENTS_TO_FETCH first_fetch_str = demisto.params().get('first_fetch', '3 days') # Other configs verify_certificate = not demisto.params().get('insecure', False) proxy = handle_proxy() request_timeout = 10 demisto.debug(f'Command being called is {demisto.command()}') try: headers = get_headers(base_url, client_id, client_secret, grant_type, verify_certificate) client = Client(base_url=base_url, verify=verify_certificate, proxy=proxy, headers=headers, max_results=max_results, request_timeout=request_timeout) results = None if demisto.command() == 'test-module': # This is the call made when pressing the integration Test button. results = test_connection(client) elif demisto.command() == 'fetch-incidents': next_run, incidents = fetch_incidents(client, demisto.getLastRun(), first_fetch_str) demisto.setLastRun(next_run) demisto.incidents(incidents) elif demisto.command() == 'identityiq-search-identities': id = demisto.args().get('id', None) email = demisto.args().get('email', None) risk = demisto.args().get('risk', 0) active = demisto.args().get('active', True) response = search_identities(client, id, email, risk, active) results = build_results('IdentityIQ.Identity', 'id', response) elif demisto.command() == 'identityiq-get-policyviolations': id = demisto.args().get('id', None) response = get_policy_violations(client, id) results = build_results('IdentityIQ.PolicyViolation', 'policyName', response) elif demisto.command() == 'identityiq-get-taskresults': id = demisto.args().get('id', None) response = get_task_results(client, id) results = build_results('IdentityIQ.TaskResult', 'id', response) elif demisto.command() == 'identityiq-get-accounts': id = demisto.args().get('id', None) display_name = demisto.args().get('display_name', None) last_refresh = demisto.args().get('last_refresh', None) native_identity = demisto.args().get('native_identity', None) last_target_agg = demisto.args().get('last_target_agg') identity_name = demisto.args().get('identity_name', None) application_name = demisto.args().get('application_name', None) response = get_accounts(client, id, display_name, last_refresh, native_identity, last_target_agg, identity_name, application_name) results = build_results('IdentityIQ.Account', 'id', response) elif demisto.command() == 'identityiq-disable-account': id = demisto.args().get('id', None) response = change_account_status(client, id, False) results = build_results('IdentityIQ.Account', 'id', response) elif demisto.command() == 'identityiq-enable-account': id = demisto.args().get('id', None) response = change_account_status(client, id, True) results = build_results('IdentityIQ.Account', 'id', response) elif demisto.command() == 'identityiq-delete-account': id = demisto.args().get('id', None) results = delete_account(client, id) elif demisto.command() == 'identitytiq-get-launched-workflows': id = demisto.args().get('id', None) response = get_launched_workflows(client, id) results = build_results('IdentityIQ.Workflow', 'id', response) elif demisto.command() == 'identityiq-get-roles': id = demisto.args().get('id', None) response = get_roles(client, id) results = build_results('IdentityIQ.Role', 'name', response) elif demisto.command() == 'identityiq-get-entitlements': id = demisto.args().get('id', None) response = get_entitlements(client, id) results = build_results('IdentityIQ.Entitlement', 'id', response) elif demisto.command() == 'identityiq-get-alerts': id = demisto.args().get('id', None) response = get_alerts(client, id) results = build_results('IdentityIQ.Alert', 'id', response) elif demisto.command() == 'identityiq-create-alert': display_name = demisto.args().get('display_name', None) attribute = demisto.args().get('attribute', None) response = create_alert(client, display_name, attribute) results = build_results('IdentityIQ.Alert', 'id', response) return_results(results) # Log exceptions and return errors except Exception as e: demisto.error(traceback.format_exc()) return_error( f'Failed to execute {demisto.command()} command.\nError:\n{str(e)}' )
def main() -> None: """main function, parses params and runs command functions :return: :rtype: """ try: command = demisto.command() demisto.debug(f'Orca Command being called is {command}') api_key = demisto.params().get('apikey') api_host = demisto.params().get('api_host') fetch_informational = demisto.params().get('fetch_informational') max_fetch = int(demisto.params().get('max_fetch', '200')) pull_existing_alerts = demisto.params().get('pull_existing_alerts') fetch_type = demisto.params().get('fetch_type') if max_fetch > 500: max_fetch = 500 api_url = f"https://{api_host}/api" # How much time before the first fetch to retrieve incidents first_fetch_time = None if arg := demisto.params().get('first_fetch'): first_fetch_time_stamp = dateparser.parse(arg) if first_fetch_time_stamp: first_fetch_time = first_fetch_time_stamp.isoformat() client = BaseClient( base_url=api_url, verify=True, headers={ 'Authorization': f'Bearer {api_key}' }, proxy=True) orca_client = OrcaClient(client=client) if command == "orca-get-alerts": demisto_args = demisto.args() alert_type = demisto_args.get('alert_type') asset_unique_id = demisto_args.get('asset_unique_id') alerts = orca_client.get_alerts_by_filter( alert_type=alert_type, asset_unique_id=asset_unique_id, limit=ORCA_API_LIMIT, ) if isinstance(alerts, str): # this means alert is an error command_result = CommandResults(readable_output=alerts, raw_response=alerts) else: command_result = CommandResults(outputs_prefix="Orca.Manager.Alerts", outputs=alerts, raw_response=alerts) return_results(command_result) elif command == "orca-get-asset": asset = orca_client.get_asset(asset_unique_id=demisto.args()['asset_unique_id']) command_result = CommandResults(outputs_prefix="Orca.Manager.Asset", outputs=[asset], raw_response=asset) return_results(command_result) elif command == "fetch-incidents": next_run, incidents = fetch_incidents( orca_client, last_run=demisto.getLastRun(), max_fetch=max_fetch, fetch_informational=fetch_informational, pull_existing_alerts=pull_existing_alerts, fetch_type=fetch_type, first_fetch_time=first_fetch_time ) demisto.setLastRun(next_run) demisto.incidents(incidents) elif command == "test-module": test_res = orca_client.validate_api_key() return_results(test_res) else: raise NotImplementedError(f'{command} is not an existing orca command')
def fetch_incidents(): """ Function to fetch incidents (events) from Lacework """ date_format = "%Y-%m-%dT%H:%M:%SZ" # Make a placeholder for events new_incidents = [] # Get data from the last run max_event_id = demisto.getLastRun().get('max_event_id', 0) now = datetime.now(timezone.utc) # Generate ISO8601 Timestamps end_time = now.strftime(date_format) start_time = now - timedelta(days=int(LACEWORK_EVENT_HISTORY_DAYS)) start_time = start_time.strftime(date_format) # Get the event severity threshold event_severity_threshold = get_event_severity_threshold() # Get events from Lacework events_response = lacework_client.events.get_for_date_range( start_time, end_time) events_data = events_response.get('data', []) temp_max_event_id = max_event_id # Iterate through all events for event in events_data: # Convert the current Event ID to an integer event_id = int(event['EVENT_ID']) event_severity = int(event['SEVERITY']) # If the event is severe enough, continue if event_severity <= event_severity_threshold: # If the Event ID is newer than we've imported, then add it if event_id > max_event_id: # Store our new max Event ID if event_id > temp_max_event_id: temp_max_event_id = event_id # Get the event details from Lacework event_details = lacework_client.events.get_details( event['EVENT_ID']) event_details['data'][0]['SEVERITY'] = event['SEVERITY'] incident = { 'name': 'Lacework Event: ' + event['EVENT_TYPE'], 'occurred': event['START_TIME'], 'rawJSON': json.dumps(event_details['data'][0]) } new_incidents.append(incident) max_event_id = temp_max_event_id demisto.setLastRun({'max_event_id': max_event_id}) demisto.incidents(new_incidents)
def main(): base_url = demisto.params().get('base_url', 'https://manage.office.com/api/v1.0/') verify_certificate = not demisto.params().get('insecure', False) first_fetch_delta = demisto.params().get('first_fetch_delta', '10 minutes').strip() first_fetch_datetime, _ = parse_date_range(first_fetch_delta) proxy = demisto.params().get('proxy', False) args = demisto.args() params = demisto.params() LOG(f'Command being called is {demisto.command()}') try: if demisto.command() == 'test-module': result = test_module() return_error(result) refresh_token = params.get('refresh_token', '') self_deployed = params.get('self_deployed', False) redirect_uri = params.get('redirect_uri', '') tenant_id = refresh_token if self_deployed else '' auth_id = params['auth_id'] enc_key = params['enc_key'] refresh_token = get_integration_context().get( 'current_refresh_token') or refresh_token client = Client(base_url=base_url, tenant_id=tenant_id, verify=verify_certificate, proxy=proxy, self_deployed=self_deployed, refresh_token=refresh_token, auth_and_token_url=auth_id, timeout=calculate_timeout_value(params=params, args=args), enc_key=enc_key, auth_code=params.get('auth_code', ''), redirect_uri=redirect_uri) access_token, token_data = client.get_access_token_data() client.access_token = access_token client.tenant_id = token_data['tid'] if demisto.command() == 'fetch-incidents': next_run, incidents = fetch_incidents( client=client, last_run=demisto.getLastRun(), first_fetch_datetime=first_fetch_datetime) demisto.setLastRun(next_run) demisto.incidents(incidents) elif demisto.command() == 'ms-management-activity-start-subscription': start_or_stop_subscription_command(client, args, 'start') elif demisto.command() == 'ms-management-activity-stop-subscription': start_or_stop_subscription_command(client, args, 'stop') elif demisto.command() == 'ms-management-activity-list-subscriptions': list_subscriptions_command(client) elif demisto.command() == 'ms-management-activity-list-content': list_content_command(client, args) # Log exceptions except Exception as e: return_error( f'Failed to execute {demisto.command()} command. Error: {str(e)}')
FETCH_SEVERITY = demisto.params()['fetch_severity'] FIRST_FETCH = int(demisto.params()['first_fetch']) severity_start = attivo_api.convert_severity_string(FETCH_SEVERITY) if not severity_start: demisto.info( "Attivo fetch-incidents: Unknown severity specified ('{}') using Medium" .format(FETCH_SEVERITY)) severity_start = 7 # Medium severity_end = "15" # Very High # When run for the first time, get events from the specified number of days one_day = 24 * 60 * 60 first_fetch_seconds = (int(time.time()) - (one_day * FIRST_FETCH)) * 1000 last_run_time = demisto.getLastRun().get('time', None) if last_run_time is None or last_run_time == 0: last_run_time = first_fetch_seconds demisto.info( "Attivo fetch-incidents: Last run time {}, severity {}:{}".format( last_run_time, FETCH_SEVERITY, severity_start)) new_last_run = 0 incidents = [] events = attivo_api.get_events(timestamp_start=last_run_time, timestamp_end='now', severity_start=severity_start, severity_end=severity_end)
def main(): user_profile = None params = demisto.params() base_url = urljoin(params['url'].strip('/'), '/api/v1/') token = params.get('apitoken') mapper_in = params.get('mapper-in') mapper_out = params.get('mapper-out') verify_certificate = not params.get('insecure', False) proxy = params.get('proxy', False) command = demisto.command() args = demisto.args() is_create_enabled = params.get("create-user-enabled") is_enable_enabled = params.get("enable-user-enabled") is_disable_enabled = params.get("disable-user-enabled") is_update_enabled = demisto.params().get("update-user-enabled") create_if_not_exists = demisto.params().get("create-if-not-exists") is_fetch = params.get('isFetch') first_fetch_str = params.get('first_fetch') fetch_limit = int(params.get('max_fetch', 1)) auto_generate_query_filter = params.get('auto_generate_query_filter') fetch_query_filter = params.get('fetch_query_filter') context = demisto.getIntegrationContext() headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': f'SSWS {token}' } client = Client(base_url=base_url, verify=verify_certificate, proxy=proxy, headers=headers, ok_codes=(200, )) demisto.debug(f'Command being called is {command}') if command == 'iam-get-user': user_profile = get_user_command(client, args, mapper_in, mapper_out) elif command == 'iam-create-user': user_profile = create_user_command(client, args, mapper_out, is_create_enabled, is_update_enabled, is_enable_enabled) elif command == 'iam-update-user': user_profile = update_user_command(client, args, mapper_out, is_update_enabled, is_enable_enabled, is_create_enabled, create_if_not_exists) elif command == 'iam-disable-user': user_profile = disable_user_command(client, args, is_disable_enabled, mapper_out) if user_profile: return_results(user_profile) try: if command == 'test-module': test_module(client, is_fetch, fetch_query_filter, auto_generate_query_filter, context, first_fetch_str) elif command == 'get-mapping-fields': return_results(get_mapping_fields_command(client)) elif command == 'okta-get-app-user-assignment': return_results(get_app_user_assignment_command(client, args)) elif command == 'okta-iam-list-applications': return_results(list_apps_command(client, args)) elif command == 'okta-iam-list-user-applications': return_results(list_user_apps_command(client, args)) elif command == 'okta-iam-get-configuration': return_results(get_configuration(context)) elif command == 'okta-iam-set-configuration': context = set_configuration(args) demisto.setIntegrationContext(context) elif command == 'iam-get-group': return_results(get_group_command(client, args)) elif command == 'okta-get-logs': return_results(get_logs_command(client, args)) elif command == 'fetch-incidents': last_run = demisto.getLastRun() context = demisto.getIntegrationContext() incidents, next_run = fetch_incidents(client, last_run, first_fetch_str, fetch_limit, fetch_query_filter, auto_generate_query_filter, context) demisto.incidents(incidents) demisto.setLastRun(next_run) except Exception: # For any other integration command exception, return an error return_error( f'Failed to execute {command} command. Traceback: {traceback.format_exc()}' )
def fetch_incidents(client: Client, test_command: bool = False) -> list: date_format = '%Y-%m-%dT%H:%M:%S' last_run = {} if not test_command: last_run = demisto.getLastRun() if not last_run: # if first time running try: new_last_run = { 'time': date_to_timestamp( parse_date_range(client.fetch_time, date_format=date_format, utc=False)[0]) } except Exception as e: return_error(f'Invalid fetch time range.\n{e.args[0]}') else: new_last_run = last_run demisto_incidents: List = list() time_from = new_last_run.get('time') time_to = date_to_timestamp(datetime.now(), date_format=date_format) list_info = create_fetch_list_info(str(time_from), str(time_to), client.fetch_status, client.fetch_filter, client.fetch_limit + 1) params = {'input_data': f'{list_info}'} # Get incidents from Service Desk Plus demisto.info( f'Fetching ServiceDeskPlus incidents. with the query params: {str(params)}' ) incidents = client.get_requests(params=params).get('requests', []) if incidents: count = 0 last_run_id = last_run.get('id', '0') last_incident_id = last_run.get('id', '0') cur_time = new_last_run.get('time', 0) incident_creation_time = new_last_run.get('time', 0) for incident in incidents: if count >= client.fetch_limit: break # Prevent fetching twice the same incident - the last incident that was fetched in the last run, will be the # first incident in the returned incidents from the API call this time. if incident.get('id') == last_run_id: continue incident_creation_time = int( incident.get('created_time', {}).get('value')) if incident_creation_time >= cur_time: demisto_incidents.append({ 'name': f'{incident.get("subject")} - {incident.get("id")}', 'occurred': timestamp_to_datestring(incident_creation_time), 'rawJSON': json.dumps(incident) }) count += 1 last_incident_id = incident.get('id') if demisto_incidents: new_last_run.update({ 'time': incident_creation_time, 'id': last_incident_id }) if not demisto_incidents: new_last_run.update({'time': time_to}) if not test_command: demisto.setLastRun(new_last_run) return demisto_incidents
def fetch_incidents(orca_client: OrcaClient, max_fetch: int, fetch_informational: bool = False, pull_existing_alerts: bool = False, fetch_type="XSOAR-Pull") -> List[Dict[str, Any]]: demisto.info(f"fetch-incidents called {max_fetch=}") if not pull_existing_alerts: demisto.info( "pull_existing_alerts flag is not set, not pulling alerts") demisto.incidents([]) return [] if demisto.getLastRun().get('lastRun'): demisto.info("not first run, exporting reminder of alerts") incidents_queue = demisto.getLastRun().get('incidents_for_next_run') incidents_to_export = incidents_queue[:max_fetch] incidents_for_next_run = incidents_queue[max_fetch:] if not incidents_to_export: # finished exporting from the queue of alerts incidents = [] if fetch_type == "XSOAR-Pull": updated_alerts = orca_client.get_updated_alerts() incidents = get_incidents_from_alerts(updated_alerts) demisto.incidents(incidents) demisto.setLastRun({ 'lastRun': datetime.now().strftime(DEMISTO_OCCURRED_FORMAT), "incidents_for_next_run": [] }) return incidents else: # still exporting from alerts queue demisto.info("still exporting from alerts queue") demisto.incidents(incidents_to_export) demisto.setLastRun({ 'lastRun': datetime.now().strftime(DEMISTO_OCCURRED_FORMAT), "incidents_for_next_run": incidents_for_next_run }) return [] else: # this is the first run alerts = orca_client.get_all_alerts( fetch_informational=fetch_informational) if not alerts: demisto.incidents([]) return [] incidents = get_incidents_from_alerts(alerts) demisto.incidents(incidents[:max_fetch]) demisto.setLastRun({ 'lastRun': datetime.now().strftime(DEMISTO_OCCURRED_FORMAT), "incidents_for_next_run": incidents[max_fetch:] }) return incidents
def fetch_incidents(): last_run = demisto.getLastRun() if 'last_fetch_time' in last_run: last_fetch_time = datetime.strptime(last_run['last_fetch_time'], DATETIME_FORMAT) demisto.info( f'Found last run, fetching new alerts from {last_fetch_time}') else: days_back = int(demisto.params().get('first_fetch_days', DEFAULT_DAYS_BACK)) if days_back > MAX_DAYS_BACK: demisto.info( f'Days back({days_back}) is larger than the maximum, setting to {MAX_DAYS_BACK}' ) days_back = MAX_DAYS_BACK last_fetch_time = datetime.now() - timedelta(days=days_back) demisto.info(f'First run, fetching alerts from {last_fetch_time}') max_incidents_to_return = int(demisto.params().get('max_fetch', DEFAULT_INCIDENTS)) if max_incidents_to_return > MAX_INCIDENTS: demisto.info( f'Max incidents({max_incidents_to_return}) is larger than the maximum, setting to {MAX_INCIDENTS}' ) max_incidents_to_return = MAX_INCIDENTS sixgill_alerts_client = SixgillActionableAlertClient( client_id=demisto.params()['client_id'], client_secret=demisto.params()['client_secret'], channel_id=CHANNEL_CODE, logger=demisto, session=SESSION, verify=VERIFY) filter_alerts_kwargs = get_incident_init_params() incidents = [] items = sixgill_alerts_client.get_actionable_alerts_bulk( limit=MAX_INCIDENTS, **filter_alerts_kwargs) newest_incident_date = datetime.strptime(items[0].get('date'), DATETIME_FORMAT) offset = 0 items_to_add = [] if newest_incident_date > last_fetch_time: # finding all new alerts since last fetch time while items: for item in items: if datetime.strptime(item.get('date'), DATETIME_FORMAT) > last_fetch_time: items_to_add.append(item) if len(items_to_add) - offset == len(items): offset += len(items) items = sixgill_alerts_client.get_actionable_alerts_bulk( limit=MAX_INCIDENTS, offset=offset, **filter_alerts_kwargs) else: items = [] demisto.info( f'Found {len(items_to_add)} new alerts since {last_fetch_time}') # getting more info about oldest ~max_incidents_to_return(can be more because of sub alerts) if len(items_to_add): items_to_add.reverse() newest_incident_date = items_to_add[-1].get('date') for item in items_to_add: item_info = sixgill_alerts_client.get_actionable_alert( actionable_alert_id=item.get('id')) item_info['date'] = item.get('date') new_incidents = item_to_incident(item_info, sixgill_alerts_client) incidents.extend(new_incidents) if len(incidents) >= max_incidents_to_return: newest_incident_date = item.get('date') break demisto.info(f'Adding {len(incidents)} to demisto') demisto.incidents(incidents) if len(incidents): demisto.info(f'Update last fetch time to: {newest_incident_date}') demisto.setLastRun({'last_fetch_time': newest_incident_date})
def main(): """ COMMANDS MANAGER / SWITCH PANEL """ params = demisto.params() self_deployed = params.get('self_deployed', False) # params related to common instance configuration base_url = 'https://graph.microsoft.com/v1.0/' use_ssl = not params.get('insecure', False) proxy = params.get('proxy', False) ok_codes = (200, 201, 202) refresh_token = params.get('refresh_token', '') auth_and_token_url = params.get('auth_id', '') enc_key = params.get('enc_key', '') app_name = 'ms-graph-mail-listener' # params related to mailbox to fetch incidents mailbox_to_fetch = params.get('mailbox_to_fetch', '') folder_to_fetch = params.get('folder_to_fetch', 'Inbox') first_fetch_interval = params.get('first_fetch', '15 minutes') emails_fetch_limit = int(params.get('fetch_limit', '50')) # params related to self deployed tenant_id = refresh_token if self_deployed else '' # params related to oproxy # In case the script is running for the first time, refresh token is retrieved from integration parameters, # in other case it's retrieved from integration context. refresh_token = ( demisto.getIntegrationContext().get('current_refresh_token') or refresh_token) client = MsGraphClient(self_deployed, tenant_id, auth_and_token_url, enc_key, app_name, base_url, use_ssl, proxy, ok_codes, refresh_token, mailbox_to_fetch, folder_to_fetch, first_fetch_interval, emails_fetch_limit) try: command = demisto.command() args = prepare_args(command, demisto.args()) LOG(f'Command being called is {command}') if command == 'test-module': # cannot use test module due to the lack of ability to set refresh token to integration context raise Exception("Please use !msgraph-mail-test instead") if command == 'msgraph-mail-test': client.test_connection() if command == 'fetch-incidents': next_run, incidents = client.fetch_incidents(demisto.getLastRun()) demisto.setLastRun(next_run) demisto.incidents(incidents) elif command == 'msgraph-mail-create-draft': human_readable, ec, raw_response = client.create_draft(**args) return_outputs(human_readable, ec, raw_response) elif command == 'msgraph-mail-reply-to': human_readable = client.reply_to(**args) # pylint: disable=E1123 return_outputs(human_readable) elif command == 'msgraph-mail-send-draft': human_readable = client.send_draft(**args) # pylint: disable=E1123 return_outputs(human_readable) elif command == 'send-mail': human_readable, ec = client.send_email(**args) return_outputs(human_readable, ec) except Exception as e: return_error(str(e))
def main() -> None: api_key = demisto.params().get('credentials', {}).get("password") base_url = demisto.params().get('url') verify_certificate = not demisto.params().get('insecure', False) proxy = demisto.params().get('proxy', False) demisto.debug(f'Command being called is {demisto.command()}') try: client = Client(base_url=base_url, verify=verify_certificate, proxy=proxy, headers={ "Authorization": f"GenieKey {api_key}", }) commands = { 'opsgenie-create-alert': create_alert, 'opsgenie-get-alerts': get_alerts, 'opsgenie-delete-alert': delete_alert, 'opsgenie-ack-alert': ack_alert, 'opsgenie-close-alert': close_alert, 'opsgenie-assign-alert': assign_alert, 'opsgenie-add-responder-alert': add_responder_alert, 'opsgenie-get-escalations': get_escalations, 'opsgenie-escalate-alert': escalate_alert, 'opsgenie-add-alert-tag': add_alert_tag, 'opsgenie-remove-alert-tag': remove_alert_tag, 'opsgenie-get-alert-attachments': get_alert_attachments, 'opsgenie-get-schedules': get_schedules, 'opsgenie-get-schedule-overrides': get_schedule_overrides, 'opsgenie-get-on-call': get_on_call, 'opsgenie-create-incident': create_incident, 'opsgenie-delete-incident': delete_incident, 'opsgenie-get-incidents': get_incidents, 'opsgenie-close-incident': close_incident, 'opsgenie-resolve-incident': resolve_incident, 'opsgenie-add-responder-incident': add_responder_incident, 'opsgenie-add-tag-incident': add_tag_incident, 'opsgenie-remove-tag-incident': remove_tag_incident, 'opsgenie-get-teams': get_teams, 'opsgenie-get-request': get_request_command } command = demisto.command() if command == 'test-module': # This is the call made when pressing the integration Test button. return_results(test_module(client, demisto.params())) elif command == 'fetch-incidents': incidents, new_run_date = fetch_incidents_command( client=client, params=demisto.params(), last_run=demisto.getLastRun().get('lastRun')) demisto.setLastRun(new_run_date) demisto.incidents(incidents) elif command in commands: return_results(commands[command](client, demisto.args())) else: raise NotImplementedError( f'Command "{command}" was not implemented.') # Log exceptions and return errors except Exception as e: demisto.error(traceback.format_exc()) # print the traceback return_error( f'Failed to execute {demisto.command()} command.\nError:\n{str(e)}' )
def main() -> None: logging.getLogger("argus_cli").setLevel("WARNING") first_fetch_period = parse_first_fetch(demisto.params().get( "first_fetch", "-1 day")) set_argus_settings( demisto.params().get("api_key"), demisto.params().get("api_url"), handle_proxy(), demisto.params().get("insecure", None), ) demisto.debug(f"Command being called is {demisto.command()}") try: if demisto.command() == "test-module": # This is the call made when pressing the integration Test button. return_results(test_module_command()) elif demisto.command() == "fetch-incidents": # Set and define the fetch incidents command to run after activated via integration settings. next_run, incidents = fetch_incidents( last_run=demisto.getLastRun(), first_fetch_period=first_fetch_period, limit=demisto.params().get("max_fetch", 25), min_severity=demisto.params().get("min_severity", "low"), ) demisto.setLastRun(next_run) demisto.incidents(incidents) elif demisto.command() == "argus-add-case-tag": return_results(add_case_tag_command(demisto.args())) elif demisto.command() == "argus-add-comment": return_results(add_comment_command(demisto.args())) elif demisto.command() == "argus-advanced-case-search": return_results(advanced_case_search_command(demisto.args())) elif demisto.command() == "argus-close-case": return_results(close_case_command(demisto.args())) elif demisto.command() == "argus-create-case": return_results(create_case_command(demisto.args())) elif demisto.command() == "argus-delete-case": return_results(delete_case_command(demisto.args())) elif demisto.command() == "argus-delete-comment": return_results(delete_comment_command(demisto.args())) elif demisto.command() == "argus-download-attachment": return_results(download_attachment_command(demisto.args())) elif demisto.command() == "argus-edit-comment": return_results(edit_comment_command(demisto.args())) elif demisto.command() == "argus-get-attachment": return_results(get_attachment_command(demisto.args())) elif demisto.command() == "argus-get-case-metadata-by-id": return_results(get_case_metadata_by_id_command(demisto.args())) elif demisto.command() == "argus-list-case-attachments": return_results(list_case_attachments_command(demisto.args())) elif demisto.command() == "argus-list-case-tags": return_results(list_case_tags_command(demisto.args())) elif demisto.command() == "argus-list-case-comments": return_results(list_case_comments_command(demisto.args())) elif demisto.command() == "argus-remove-case-tag-by-id": return_results(remove_case_tag_by_id_command(demisto.args())) elif demisto.command() == "argus-remove-case-tag-by-key-value": return_results(remove_case_tag_by_key_value_command( demisto.args())) elif demisto.command() == "argus-update-case": return_results(update_case_command(demisto.args())) elif demisto.command() == "argus-get-event": return_results(get_event_command(demisto.args())) elif demisto.command() == "argus-get-events-for-case": return_results(get_events_for_case_command(demisto.args())) elif demisto.command() == "argus-find-aggregated-events": return_results(find_aggregated_events_command(demisto.args())) elif demisto.command() == "argus-list-aggregated-events": return_results(list_aggregated_events_command(demisto.args())) elif demisto.command() == "argus-get-payload": return_results(get_payload_command(demisto.args())) elif demisto.command() == "argus-get-pcap": return_results(get_pcap_command(demisto.args())) elif demisto.command() == "argus-find-nids-events": return_results(find_nids_events_command(demisto.args())) elif demisto.command() == "argus-list-nids-events": return_results(list_nids_events_command(demisto.args())) elif demisto.command() == "argus-pdns-search-records": return_results(search_records_command(demisto.args())) elif demisto.command() == "argus-fetch-observations-for-domain": return_results( fetch_observations_for_domain_command(demisto.args())) elif demisto.command() == "argus-fetch-observations-for-ip": return_results(fetch_observations_for_i_p_command(demisto.args())) # Log exceptions and return errors except Exception as e: demisto.error(traceback.format_exc()) # print the traceback return_error( f"Failed to execute {demisto.command()} command.\nError:\n{str(e)}" )
def fetch_incidents(client: MsGraphClient, fetch_time: str, fetch_limit: int, filter: str, providers: str) \ -> list: filter_query = create_filter_query(filter, providers) severity_map = { 'low': 1, 'medium': 2, 'high': 3, 'unknown': 0, 'informational': 0 } last_run = demisto.getLastRun() timestamp_format = '%Y-%m-%dT%H:%M:%S.%fZ' if not last_run: # if first time running new_last_run = { 'time': parse_date_range(fetch_time, date_format=timestamp_format)[0] } else: new_last_run = last_run demisto_incidents: List = list() time_from = new_last_run.get('time') time_to = datetime.now().strftime(timestamp_format) # Get incidents from MS Graph Security demisto.debug( f'Fetching MS Graph Security incidents. From: {time_from}. To: {time_to}\n' ) incidents = client.search_alerts(last_modified=None, severity=None, category=None, vendor=None, time_from=time_from, time_to=time_to, filter_query=filter_query)['value'] if incidents: count = 0 incidents = sorted(incidents, key=lambda k: k['createdDateTime'] ) # sort the incidents by time-increasing order last_incident_time = last_run.get('time', '0') demisto.debug( f'Incidents times: {[incidents[i]["createdDateTime"] for i in range(len(incidents))]}\n' ) for incident in incidents: incident_time = incident.get('createdDateTime') if incident_time > last_incident_time and count < fetch_limit: demisto_incidents.append({ 'name': incident.get('title') + " - " + incident.get('id'), 'occurred': incident.get('createdDateTime'), 'severity': severity_map.get(incident.get('severity', ''), 0), 'rawJSON': json.dumps(incident) }) count += 1 if demisto_incidents: last_incident_time = demisto_incidents[-1].get('occurred') new_last_run.update({'time': last_incident_time}) if not demisto_incidents: new_last_run.update({'time': time_to}) demisto.setLastRun(new_last_run) return demisto_incidents
def simulate_fetch(): """ Ingesting a sample incident to XSOAR """ # Ensure only one sample is created last_run = demisto.getLastRun() if last_run.get("sample_fetched", False): return [] else: demisto.setLastRun({'sample_fetched': True}) now_time = datetime.now() now_time_timestamp_seconds = int(date_to_timestamp(now_time) / 1000) sample_incident = { "incident_id": "incidentID-" + str(now_time_timestamp_seconds), "case_id": "caseID-123", "tx_id": "txID-" + str(now_time_timestamp_seconds), "threat_type": "phishing", "application": "office365", "connection_id": "connectionID", "connection_name": "ConnectionName", "org_id": 1, "tenant_id": "tenantID", "remediation_data": { "remediation_type": "auto_remediation", "remediation": "not_remediated", "policy_action": [{ "performed_date": 1625484377, "messages": None, "action_type": "ADD_BANNER", "action_status": "success" }, { "performed_date": 1625484378, "messages": None, "action_type": "MOVE_TO_SPAM", "action_status": "success" }, { "performed_date": 1625484378, "messages": None, "action_type": "INCIDENT", "action_status": "success" }], "policy_condition": [{ "condition_type": "ORIGIN", "condition_value": "ALL" }, { "condition_type": "EMAIL_STATE", "condition_value": "ALL" }, { "condition_type": "REPORTED_BY", "condition_value": "ALL" }], "policy_name": "Default Rule", "resolution": "pending" }, "message_details": { "internet_message_id": "internetMessageID-" + str(now_time_timestamp_seconds), "targeted_employee": { "name": "user1", "address": "*****@*****.**" }, "other_recipients": [], "sender": { "name": "user2", "address": "*****@*****.**" }, "from": { "name": "user2", "address": "*****@*****.**" }, "to_recipients": [{ "name": "user1", "address": "*****@*****.**" }], "to_cc_recipients": [], "to_bcc_recipients": [], "reply_to": [], "email_subject": "subject - this is a sample", "email_body": "", "received_datetime": "2021-07-05T11:23:27Z", "sent_datetime": "2021-07-05T11:23:22Z", "created_datetime": "2021-07-05T11:23:26Z", "last_modified_datetime": "2021-07-05T11:23:28Z", "is_read": False, "is_external_from": False, "is_external_reply_to": False, "is_external_sender": False, "is_user_subscribed": True, "urls_classification": [{ "url": "http://phishing.com", "classification_type": "malicious", "is_phishing": True, "classification": "malicious" }], "user_id": "userID", "message_id": "messageID-" + str(now_time_timestamp_seconds), "attachments": [{ "file_size": 158, "file_name": "attachment.html", "file_hash": "hash", "file_category": "PHISHING", "aws_key": "key.zip", "aws_bucket": "bucket" }], "folder": "inbox" }, "threat_indicators": [{ "type": "url", "subType": "malicious_url", "value": "http://phishing.com", "details": { "categories": [""], "family_names": ["Generic"], "industries": [""], "screenshot": "screenshot.png" } }, { "type": "attachment", "subType": "attachment_hash", "value": "hash", "details": { "categories": None, "family_names": None, "industries": None, "screenshot": "" }, "attachment": { "file_size": 158, "file_name": "attachment.html", "file_hash": "hash", "file_category": "PHISHING", "aws_key": "key.zip", "aws_bucket": "screenshot" } }], "feedback": [ { "details": "phishing url", "tx_id": "txID", "feedback_type": "phishing", "created_at": 1625653814, "threat_indicators_type": ["url"] }, ], "reported_by": "*****@*****.**", "confidence": 3, "created_at": now_time_timestamp_seconds, "updated_at": now_time_timestamp_seconds } incidents = [] incident_name = 'Cyren Inbox Security Sample - {} ({})'.format( sample_incident.get('threat_type', 'phishing'), sample_incident.get('reported_by', 'System')) incident_timestamp = now_time_timestamp_seconds incident_str_time = timestamp_to_datestring(incident_timestamp * 1000) incident = { 'name': incident_name, 'occurred': incident_str_time, 'rawJSON': json.dumps(sample_incident), 'severity': convert_to_demisto_severity(1), } incidents.append(incident) return incidents
def fetch_incidents_command(): """ Parent command to wrap events and behavior fetch commands """ # Check if it's been run now = datetime.today() yesterday = datetime.strftime(now - timedelta(days=1), "%Y-%m-%d") last_run = demisto.getLastRun() start_date = yesterday end_date = yesterday if "start_time" not in last_run or "complete_for_today" not in last_run: # first time integration is running start_date = datetime.strftime(now - timedelta(days=FIRST_RUN), "%Y-%m-%d") if last_run.get('complete_for_today') is True and last_run.get( 'start_time') == yesterday: # wait until tomorrow to try again demisto.incidents([]) return # Refresh JWT token = do_auth() # Fetch Events more_events = True page_token = None incidents = [] while more_events: event_incidents, page_token = fetch_events_incidents_command( start_date, end_date, token, page_token) for incident in event_incidents: demisto.debug( "Adding event incident name={name}, type={type}, severity={severity}" .format(**incident)) incidents += event_incidents if page_token is None: more_events = False # Fetch Behavior if BEHAVIOR_ENABLED: more_behavior = True next_offset = None while more_behavior: behavior_incidents, next_offset = fetch_behavior_incidents_command( start_date, token, next_offset) for incident in behavior_incidents: demisto.debug( "Adding behavior incident name={name}, type={type}, severity={severity}" .format(**incident)) incidents += behavior_incidents if next_offset is None: more_behavior = False # Send all Incidents demisto.incidents(incidents) # Save last_run demisto.setLastRun({"complete_for_today": True, "start_time": yesterday})
def main(): command = demisto.command() params = demisto.params() """ PARSE AND VALIDATE INTEGRATION PARAMS """ base_url = params.get('url') verify_certificate = not params.get('insecure', False) proxy = params.get('proxy', False) api_key = params.get('apikey', {}) demisto.info(f'Command being called is {command}') client = Client( base_url=base_url, verify=verify_certificate, proxy=proxy, ok_codes=[200], auth=requests.auth.HTTPBasicAuth(api_key, '') ) try: '''EXECUTION CODE''' if command == 'bitsight-get-company-details': readable_output, context, res_json = get_company_details_command(client, demisto.args()) results = CommandResults( readable_output=readable_output, outputs_prefix='BitSight.Company', outputs=context, outputs_key_field='guid', raw_response=res_json ) return_results(results) elif command == 'bitsight-get-company-findings': readable_output, context, res_json = get_company_findings_command(client, demisto.args()) results = CommandResults( readable_output=readable_output, outputs_prefix='BitSight.Finding', outputs=context, outputs_key_field='guid', raw_response=res_json ) return_results(results) elif command == 'test-module': human_readable, outputs, raw_response = test_module(client) return_outputs(readable_output=human_readable, outputs=outputs, raw_response=raw_response) elif command == 'bitsight-get-companies-guid': readable_output, context, res_json = get_companies_guid_command(client) results = CommandResults( readable_output=readable_output, outputs_prefix='BitSight.GUID', outputs=context, outputs_key_field='temporary_id', raw_response=res_json ) return_results(results) elif command == 'fetch-incidents': last_run = demisto.getLastRun() last_run_curr, events = fetch_incidents(client, last_run, params) if last_run != last_run_curr: demisto.setLastRun({'time': last_run_curr['time']}) demisto.incidents(events) else: demisto.incidents([]) # Log exceptions except Exception: return_error(f'Failed to execute {demisto.command()} command. Traceback: {traceback.format_exc()}')
def build_iterator(self, **kwargs): """ For each URL (service), send an HTTP request to get indicators and return them after filtering by Regex :param kwargs: Arguments to send to the HTTP API endpoint :return: List of indicators """ kwargs['stream'] = True kwargs['verify'] = self._verify kwargs['timeout'] = self.polling_timeout if self.headers is not None: kwargs['headers'] = self.headers if self.username is not None and self.password is not None: kwargs['auth'] = (self.username, self.password) try: urls = self._base_url url_to_response_list: List[dict] = [] if not isinstance(urls, list): urls = [urls] for url in urls: # Set the If-None-Match and If-Modified-Since headers if we have etag or # last_modified values in the context. last_run = demisto.getLastRun() etag = last_run.get(url, {}).get('etag') last_modified = last_run.get(url, {}).get('last_modified') if etag: if not kwargs.get('headers'): kwargs['headers'] = {} kwargs['headers']['If-None-Match'] = etag if last_modified: if not kwargs.get('headers'): kwargs['headers'] = {} kwargs['headers']['If-Modified-Since'] = last_modified r = requests.get(url, **kwargs) try: r.raise_for_status() except Exception: LOG(f'{self.feed_name!r} - exception in request:' f' {r.status_code!r} {r.content!r}') raise no_update = get_no_update_value(r, url) url_to_response_list.append( {url: { 'response': r, 'no_update': no_update }}) except requests.exceptions.ConnectTimeout as exception: err_msg = 'Connection Timeout Error - potential reasons might be that the Server URL parameter' \ ' is incorrect or that the Server is not accessible from your host.' raise DemistoException(err_msg, exception) except requests.exceptions.SSLError as exception: # in case the "Trust any certificate" is already checked if not self._verify: raise err_msg = 'SSL Certificate Verification Failed - try selecting \'Trust any certificate\' checkbox in' \ ' the integration configuration.' raise DemistoException(err_msg, exception) except requests.exceptions.ProxyError as exception: err_msg = 'Proxy Error - if the \'Use system proxy\' checkbox in the integration configuration is' \ ' selected, try clearing the checkbox.' raise DemistoException(err_msg, exception) except requests.exceptions.ConnectionError as exception: # Get originating Exception in Exception chain error_class = str(exception.__class__) err_type = '<' + error_class[error_class.find('\'') + 1:error_class.rfind('\'')] + '>' err_msg = 'Verify that the server URL parameter' \ ' is correct and that you have access to the server from your host.' \ '\nError Type: {}\nError Number: [{}]\nMessage: {}\n' \ .format(err_type, exception.errno, exception.strerror) raise DemistoException(err_msg, exception) results = [] for url_to_response in url_to_response_list: for url, res_data in url_to_response.items(): lines = res_data.get('response') result = lines.iter_lines() if self.encoding is not None: result = map( lambda x: x.decode(self.encoding).encode('utf_8'), result) else: result = map(lambda x: x.decode('utf_8'), result) if self.ignore_regex is not None: result = filter( lambda x: self.ignore_regex.match(x) is None, # type: ignore[union-attr] result) results.append({ url: { 'result': result, 'no_update': res_data.get('no_update') } }) return results
def main(): handle_proxy() params: Dict = demisto.params() server: str = params.get('server', '').rstrip('/') credentials: Dict = params.get('credentials', {}) username: str = credentials.get('identifier', '') password: str = credentials.get('password', '') fetch_time: str = params.get('fetch_time', '3 days').strip() try: fetch_limit: int = int(params.get('fetch_limit', '10')) except ValueError: raise DemistoException('Value for fetch_limit must be an integer.') saved_report_id: str = demisto.params().get('saved_report_id', '') last_run: dict = demisto.getLastRun() args: dict = demisto.args() verify_ssl = not params.get('insecure', False) wsdl: str = f'{server}/ProtectManager/services/v2011/incidents?wsdl' session: Session = Session() session.auth = SymantecAuth(username, password, server) session.verify = verify_ssl cache: SqliteCache = SqliteCache(path=get_cache_path(), timeout=None) transport: Transport = Transport(session=session, cache=cache) settings: Settings = Settings(strict=False, xsd_ignore_sequence_order=True) client: Client = Client(wsdl=wsdl, transport=transport, settings=settings) command = demisto.command() demisto.info(f'Command being called is {command}') commands = { 'test-module': test_module, 'fetch-incidents': fetch_incidents, 'symantec-dlp-get-incident-details': get_incident_details_command, 'symantec-dlp-list-incidents': list_incidents_command, 'symantec-dlp-update-incident': update_incident_command, 'symantec-dlp-incident-binaries': incident_binaries_command, 'symantec-dlp-list-custom-attributes': list_custom_attributes_command, 'symantec-dlp-list-incident-status': list_incident_status_command, 'symantec-dlp-incident-violations': incident_violations_command } try: if command == 'fetch-incidents': fetch_incidents(client, fetch_time, fetch_limit, last_run, saved_report_id) # type: ignore[operator] elif command == 'test-module': test_module(client, saved_report_id) # type: ignore[arg-type] elif command == 'symantec-dlp-list-incidents': human_readable, context, raw_response =\ commands[command](client, args, saved_report_id) # type: ignore[operator] return_outputs(human_readable, context, raw_response) elif command == 'symantec-dlp-list-incident-status' or command == 'symantec-dlp-list-custom-attributes': human_readable, context, raw_response = commands[command]( client) # type: ignore[operator] return_outputs(human_readable, context, raw_response) elif command == 'symantec-dlp-incident-binaries': human_readable, context, file_entries, raw_response =\ commands[command](client, args) # type: ignore[operator] return_outputs(human_readable, context, raw_response) for file_entry in file_entries: demisto.results(file_entry) elif command in commands: human_readable, context, raw_response = commands[command]( client, args) # type: ignore[operator] return_outputs(human_readable, context, raw_response) # Log exceptions except Exception as e: err_msg = f'Error in Symantec DLP integration: {str(e)}' if demisto.command() == 'fetch-incidents': LOG(err_msg) LOG.print_log() raise else: return_error(err_msg, error=e)
def main(): """ PARSE AND VALIDATE INTEGRATION PARAMS """ # get the service API token api_token = demisto.params().get('api_token') has_forensics = demisto.params().get('has_forensics') has_forensics = None if has_forensics == "ALL" else has_forensics # get the service API url base_url = demisto.params()['url'] verify_certificate = not demisto.params().get('insecure', False) # How much time before the first fetch to retrieve incidents first_fetch_time = demisto.params().get('fetch_time', '7 days').strip().lower() proxy = demisto.params().get('proxy', False) LOG(f'Command being called is {demisto.command()}') try: headers = DEFAULT_HEADERS_POST_REQUEST headers["Authorization"] = api_token client = Client(base_url=base_url, verify=verify_certificate, headers=headers, proxy=proxy) if demisto.command() == 'test-module': # This is the call made when pressing the integration Test button. result = test_module(client) demisto.results(result) elif demisto.command() == 'fetch-incidents': # Set and define the fetch incidents command to run after activated via integration settings. next_run, incidents = fetch_incidents( client=client, last_run=demisto.getLastRun(), first_fetch_time=first_fetch_time, has_forensics=has_forensics) demisto.setLastRun(next_run) demisto.incidents(incidents) elif demisto.command() == 'illusive-get-forensics-timeline': return_outputs( *get_forensics_timeline_command(client, demisto.args())) elif demisto.command() == 'illusive-get-asm-host-insight': return_outputs( *get_asm_host_insight_command(client, demisto.args())) elif demisto.command() == 'illusive-get-asm-cj-insight': return_outputs(*get_asm_cj_insight_command(client, demisto.args())) elif demisto.command() == 'illusive-get-deceptive-users': return_outputs( *get_deceptive_users_command(client, demisto.args())) elif demisto.command() == 'illusive-get-deceptive-servers': return_outputs( *get_deceptive_servers_command(client, demisto.args())) elif demisto.command() == 'illusive-is-deceptive-user': return_outputs(*is_deceptive_user_command(client, demisto.args())) elif demisto.command() == 'illusive-is-deceptive-server': return_outputs( *is_deceptive_server_command(client, demisto.args())) elif demisto.command() == 'illusive-get-incidents': return_outputs(*get_incidents_command(client, demisto.args())) elif demisto.command() == 'illusive-get-event-incident-id': return_outputs( *get_event_incident_id_command(client, demisto.args())) elif demisto.command() == 'illusive-add-deceptive-users': return_outputs( *add_deceptive_users_command(client, demisto.args())) elif demisto.command() == 'illusive-add-deceptive-servers': return_outputs( *add_deceptive_servers_command(client, demisto.args())) elif demisto.command() == 'illusive-delete-deceptive-users': return_outputs( *delete_deceptive_users_command(client, demisto.args())) elif demisto.command() == 'illusive-delete-deceptive-servers': return_outputs( *delete_deceptive_servers_command(client, demisto.args())) elif demisto.command() == 'illusive-assign-host-to-policy': return_outputs( *assign_host_to_policy_command(client, demisto.args())) elif demisto.command() == 'illusive-remove-host-from-policy': return_outputs( *remove_host_from_policy_command(client, demisto.args())) elif demisto.command() == 'illusive-run-forensics-on-demand': return_outputs( *run_forensics_on_demand_command(client, demisto.args())) elif demisto.command() == 'illusive-get-forensics-artifacts': try: file_results, file_names = get_forensics_artifacts_command( client, demisto.args()) return_results(file_results) return_results( link_forensics_artifacts_name_command( file_names, client, demisto.args())) except ValueError: return_results( link_forensics_artifacts_name_command([], client, demisto.args())) elif demisto.command( ) == 'illusive-get-forensics-triggering-process-info': return_outputs(*get_forensics_triggering_process_info_command( client, demisto.args())) elif demisto.command() == 'illusive-get-forensics-analyzers': return_outputs( *get_forensics_analyzers_command(client, demisto.args())) elif demisto.command() == 'illusive-get-incident-events': return_outputs( *get_incident_events_command(client, demisto.args())) # Log exceptions except Exception as e: return_error( f'Failed to execute {demisto.command()} command. Error: {str(e)}')
def main() -> None: api_key = demisto.params().get('apikey') base_url = demisto.params().get('url') verify_certificate = not demisto.params().get('insecure', False) # How much time before the first fetch to retrieve incidents first_fetch_time = dateparser.parse(demisto.params().get('first_fetch', '3 days')) \ .strftime(XSOAR_DATE_FORMAT) # type: ignore[union-attr] proxy = demisto.params().get('proxy', False) demisto.debug(f'Command being called is {demisto.command()}') mirror_tags = set(demisto.params().get('mirror_tag', '').split(',')) \ if demisto.params().get('mirror_tag') else set([]) query = demisto.params().get('query', '') or '' disable_from_same_integration = demisto.params().get( 'disable_from_same_integration') if disable_from_same_integration: query += ' -sourceBrand:"XSOAR Mirroring"' max_results = arg_to_number(arg=demisto.params().get('max_fetch'), arg_name='max_fetch') if not max_results or max_results > MAX_INCIDENTS_TO_FETCH: max_results = MAX_INCIDENTS_TO_FETCH try: headers = {'Authorization': api_key} client = Client(base_url=base_url, verify=verify_certificate, headers=headers, proxy=proxy) if demisto.command() == 'test-module': if demisto.params().get('isFetch'): fetch_incidents( client=client, max_results=max_results, last_run=demisto.getLastRun(), first_fetch_time=first_fetch_time, query=query, mirror_direction=demisto.params().get('mirror_direction'), mirror_tag=list(mirror_tags)) return_results(test_module(client, first_fetch_time)) elif demisto.command() == 'fetch-incidents': next_run, incidents = fetch_incidents( client=client, max_results=max_results, last_run=demisto.getLastRun(), first_fetch_time=first_fetch_time, query=query, mirror_direction=demisto.params().get('mirror_direction'), mirror_tag=list(mirror_tags)) demisto.setLastRun(next_run) demisto.incidents(incidents) elif demisto.command() == 'xsoar-search-incidents': return_results(search_incidents_command(client, demisto.args())) elif demisto.command() == 'xsoar-get-incident': return_results(get_incident_command(client, demisto.args())) elif demisto.command() == 'get-mapping-fields': return_results(get_mapping_fields_command(client)) elif demisto.command() == 'get-remote-data': return_results( get_remote_data_command(client, demisto.args(), demisto.params())) elif demisto.command() == 'update-remote-system': return_results( update_remote_system_command(client, demisto.args(), mirror_tags)) else: raise NotImplementedError('Command not implemented') except NotImplementedError: raise except Exception as e: return_error( f'Failed to execute {demisto.command()} command.\nError:\n{str(e)}' )
def main() -> None: """main function, parses params and runs command functions :return: :rtype: """ instance = demisto.params().get('instance') username = demisto.params().get('username') password = demisto.params().get('password') property_name = demisto.params().get('property_name') property_value = demisto.params().get('property_value') base_url = demisto.params().get('url') max_fetch = demisto.params().get('max_fetch', 20) # if your Client class inherits from BaseClient, SSL verification is # handled out of the box by it, just pass ``verify_certificate`` to # the Client constructor verify_certificate = not demisto.params().get('insecure', False) # How much time before the first fetch to retrieve incidents first_fetch_time = arg_to_timestamp( arg=demisto.params().get('first_fetch', '3 days'), arg_name='First fetch time', required=True ) # Using assert as a type guard (since first_fetch_time is always an int when required=True) assert isinstance(first_fetch_time, int) # if your Client class inherits from BaseClient, system proxy is handled # out of the box by it, just pass ``proxy`` to the Client constructor proxy = demisto.params().get('proxy', False) # INTEGRATION DEVELOPER TIP # You can use functions such as ``demisto.debug()``, ``demisto.info()``, # etc. to print information in the XSOAR server log. You can set the log # level on the server configuration # See: https://xsoar.pan.dev/docs/integrations/code-conventions#logging demisto.debug(f'Command being called is {demisto.command()}') try: to_xm_client = Client( base_url=base_url, verify=verify_certificate, auth=(username, password), proxy=proxy) from_xm_client = Client( base_url="https://" + instance, verify=verify_certificate, auth=(username, password), proxy=proxy) if demisto.command() == 'xm-trigger-workflow': return_results(xm_trigger_workflow_command( to_xm_client, demisto.args().get('recipients'), demisto.args().get('subject'), demisto.args().get('body'), demisto.args().get('incident_id'), demisto.args().get('close_task_id') )) elif demisto.command() == 'fetch-incidents': # Set and define the fetch incidents command to run after activated via integration settings. alert_status = demisto.params().get('status', None) priority = demisto.params().get('priority', None) next_run, incidents = fetch_incidents( client=from_xm_client, last_run=demisto.getLastRun(), # getLastRun() gets the last run dict first_fetch_time=first_fetch_time, max_fetch=max_fetch, alert_status=alert_status, priority=priority, property_name=property_name, property_value=property_value ) # saves next_run for the time fetch-incidents is invoked demisto.setLastRun(next_run) # fetch-incidents calls ``demisto.incidents()`` to provide the list # of incidents to crate demisto.incidents(incidents) elif demisto.command() == 'xm-get-events': return_results(xm_get_events_command( client=from_xm_client, request_id=demisto.args().get('request_id'), status=demisto.args().get('status'), priority=demisto.args().get('priority'), from_time=demisto.args().get('from'), to_time=demisto.args().get('to'), workflow=demisto.args().get('workflow'), form=demisto.args().get('form'), property_name=demisto.args().get('property_name'), property_value=demisto.args().get('property_value') )) elif demisto.command() == 'xm-get-event': return_results(xm_get_event_command( client=from_xm_client, event_id=demisto.args().get('event_id') )) elif demisto.command() == 'test-module': return_results(test_module( from_xm=from_xm_client, to_xm=to_xm_client, user=username, max_fetch=max_fetch )) # Log exceptions and return errors except Exception as e: demisto.error(traceback.format_exc()) # print the traceback return_error(f'Failed to execute {demisto.command()} command.\nError:\n{str(e)}')
def main(): """ PARSE AND VALIDATE INTEGRATION PARAMS """ params = demisto.params() LOG(f'Command being called is {demisto.command()}') try: client = Client( self_deployed=params.get('self_deployed', False), auth_and_token_url=params.get('auth_id', ''), refresh_token=params.get('refresh_token', ''), enc_key=params.get('enc_key', ''), redirect_uri=params.get('redirect_uri', ''), auth_code=params.get('auth_code', ''), subscription_id=params.get('subscriptionID', ''), resource_group_name=params.get('resourceGroupName', ''), workspace_name=params.get('workspaceName', ''), verify=not params.get('insecure', False), proxy=params.get('proxy', False) ) commands = { 'azure-sentinel-get-incident-by-id': get_incident_by_id_command, 'azure-sentinel-list-incidents': list_incidents_command, 'azure-sentinel-update-incident': update_incident_command, 'azure-sentinel-delete-incident': delete_incident_command, 'azure-sentinel-list-incident-comments': list_incident_comments_command, 'azure-sentinel-incident-add-comment': incident_add_comment_command, 'azure-sentinel-list-incident-relations': list_incident_relations_command, 'azure-sentinel-get-entity-by-id': get_entity_by_id_command, 'azure-sentinel-list-entity-relations': list_entity_relations_command } if demisto.command() == 'test-module': # cannot use test module due to the lack of ability to set refresh token to integration context raise Exception("Please use !azure-sentinel-test instead") elif demisto.command() == 'azure-sentinel-test': test_connection(client, params) elif demisto.command() == 'fetch-incidents': # How much time before the first fetch to retrieve incidents first_fetch_time = params.get('fetch_time', '3 days').strip() min_severity = severity_to_level(params.get('min_severity', 'Informational')) # Set and define the fetch incidents command to run after activated via integration settings. next_run, incidents = fetch_incidents( client=client, last_run=demisto.getLastRun(), first_fetch_time=first_fetch_time, min_severity=min_severity ) demisto.setLastRun(next_run) demisto.incidents(incidents) elif demisto.command() in commands: return_outputs(*commands[demisto.command()](client, demisto.args())) # type: ignore except Exception as e: return_error(f'Failed to execute {demisto.command()} command. Error: {str(e)}')
def fetch_incidents(client, aws_sh_severity, archive_findings, additional_filters): last_run = demisto.getLastRun().get('lastRun', None) next_token = demisto.getLastRun().get('next_token', None) if last_run is None: first_fetch_timestamp = demisto.params().get('first_fetch_timestamp', '15 days').strip() date_from = parse(f'{first_fetch_timestamp} UTC') last_run = date_from.isoformat() # type: ignore now = datetime.now(timezone.utc) filters = { 'CreatedAt': [{ 'Start': last_run, 'End': now.isoformat() }], 'SeverityNormalized': [{ 'Gte': sh_severity_mapping(aws_sh_severity), }] } if additional_filters is not None: filters.update(parse_filter_field(additional_filters)) if next_token: try: response = client.get_findings(NextToken=next_token) # In case a new request is made with another input the nextToken will be revoked except client.exceptions.InvalidInputException: response = client.get_findings(Filters=filters) else: response = client.get_findings(Filters=filters) findings = response['Findings'] next_token = response.get('NextToken') incidents = [{ 'occurred': finding['CreatedAt'], 'severity': severity_mapping(finding['Severity']['Normalized']), 'rawJSON': json.dumps(finding) } for finding in findings] if findings: # in case we got finding, we should get the latest created one and increase it by 1 ms so the next fetch # wont include it in the query and fetch duplicates last_created_finding = max(findings, key=lambda finding: finding.get('CreatedAt')).get('CreatedAt') last_created_finding_dt = parse(last_created_finding) + timedelta(milliseconds=1) # type: ignore[operator] last_run = last_created_finding_dt.isoformat() # type: ignore[union-attr] demisto.setLastRun({'lastRun': last_run, 'next_token': next_token}) demisto.incidents(incidents) if archive_findings: kwargs = { 'FindingIdentifiers': [ {'Id': finding['Id'], 'ProductArn': finding['ProductArn']} for finding in findings ], 'Workflow': { 'Status': 'NOTIFIED', }, 'Note': { 'Text': 'Archived by Demisto', 'UpdatedBy': 'Demisto' } } client.batch_update_findings(**kwargs)
def __init__(self, insecure: bool = True, polling_timeout: int = 20, initial_interval: str = '1 day', discovery_service: str = '', poll_service: str = None, collection: str = None, credentials: dict = None, cert_text: str = None, key_text: str = None, tags: str = None, tlp_color: Optional[str] = None, **kwargs): """ TAXII Client :param insecure: Set to true to ignore https certificate :param polling_timeout: Time before send request timeout :param initial_interval: Interval between each read from TAXII server :param discovery_service: TAXII server discovery service :param poll_service: TAXII poll service :param collection: TAXII collection :param credentials: Username and password dict for basic auth :param cert_text: Certificate File as Text :param cert_Key: Key File as Text :param kwargs: """ self.discovered_poll_service = None self.last_taxii_run = demisto.getLastRun() if isinstance(self.last_taxii_run, dict): self.last_taxii_run = self.last_taxii_run.get('time') self.last_stix_package_ts = None self.last_taxii_content_ts = None self.verify_cert = not insecure self.polling_timeout = polling_timeout try: self.polling_timeout = int(self.polling_timeout) except (ValueError, TypeError): raise TypeError( 'Please provide a valid integer for "Polling Timeout"') self.initial_interval = initial_interval self.initial_interval = interval_in_sec(self.initial_interval) if self.initial_interval is None: self.initial_interval = 86400 self.discovery_service = discovery_service self.poll_service = poll_service self.collection = collection self.api_key = None self.api_header = None self.username = None self.password = None self.crt = None self.tags = argToList(tags) self.tlp_color = tlp_color # authentication if credentials: if '_header:' in credentials.get('identifier', None): self.api_header = credentials.get('identifier', None).split('_header:')[1] self.api_key = credentials.get('password', None) else: self.username = credentials.get('identifier', None) self.password = credentials.get('password', None) if (cert_text and not key_text) or (not cert_text and key_text): raise Exception( 'You can not configure either certificate text or key, both are required.' ) if cert_text and key_text: cert_text_list = cert_text.split('-----') # replace spaces with newline characters cert_text_fixed = '-----'.join( cert_text_list[:2] + [cert_text_list[2].replace(' ', '\n')] + cert_text_list[3:]) cf = tempfile.NamedTemporaryFile(delete=False) cf.write(cert_text_fixed.encode()) cf.flush() key_text_list = key_text.split('-----') # replace spaces with newline characters key_text_fixed = '-----'.join( key_text_list[:2] + [key_text_list[2].replace(' ', '\n')] + key_text_list[3:]) kf = tempfile.NamedTemporaryFile(delete=False) kf.write(key_text_fixed.encode()) kf.flush() self.crt = (cf.name, kf.name) if collection is None or collection == '': all_collections = self.get_all_collections() return_error( f"No collection set. Here is a list of all accessible collections: " f"{str(all_collections)}")
def fetch_incidents(): query_params = {} incidents = [] if FETCH_TIME: fetch_time = FETCH_TIME else: fetch_time = DEFAULTS['fetch_time'] last_run = demisto.getLastRun() if 'time' not in last_run: snow_time, _ = parse_date_range(fetch_time, '%Y-%m-%d %H:%M:%S') else: snow_time = last_run['time'] query = '' if SYSPARM_QUERY: query += SYSPARM_QUERY + '^' query += 'ORDERBY{0}^{0}>{1}'.format(TIMESTAMP_FIELD, snow_time) if query: query_params['sysparm_query'] = query query_params['sysparm_limit'] = SYSPARM_LIMIT path = 'table/' + TICKET_TYPE res = send_request(path, 'get', params=query_params) count = 0 parsed_snow_time = datetime.strptime(snow_time, '%Y-%m-%d %H:%M:%S') for result in res.get('result', []): labels = [] if TIMESTAMP_FIELD not in result: raise ValueError("The timestamp field [{}]" " does not exist in the ticket".format(TIMESTAMP_FIELD)) if count > SYSPARM_LIMIT: break try: if datetime.strptime(result[TIMESTAMP_FIELD], '%Y-%m-%d %H:%M:%S') < parsed_snow_time: continue except Exception: pass for k, v in result.iteritems(): if isinstance(v, basestring): labels.append({ 'type': k, 'value': v }) else: labels.append({ 'type': k, 'value': json.dumps(v) }) severity = SEVERITY_MAP.get(result.get('severity', ''), 0) file_names = [] if GET_ATTACHMENTS: file_entries = get_ticket_attachment_entries(result['sys_id']) for file_result in file_entries: if file_result['Type'] == entryTypes['error']: raise Exception('Error getting attachment: ' + str(file_result['Contents'])) file_names.append({ 'path': file_result['FileID'], 'name': file_result['File'] }) incidents.append({ 'name': 'ServiceNow Incident ' + result.get('number'), 'labels': labels, 'details': json.dumps(result), 'severity': severity, 'attachment': file_names, 'rawJSON': json.dumps(result) }) count += 1 snow_time = result[TIMESTAMP_FIELD] demisto.incidents(incidents) demisto.setLastRun({'time': snow_time})
def main(): """ PARSE AND VALIDATE INTEGRATION PARAMS """ tenant_id = demisto.params()['tenant_id'] access_key_id = demisto.params()['access_key_id'] secret_access_key = demisto.params()['secret_access_key'] api_timeout = 60 try: api_timeout = int(demisto.params().get('api_timeout', '60')) except ValueError: return_error('API timeout needs to be an integer') first_fetch = '-1' try: ff = arg_to_timestamp( arg=demisto.params().get('first_fetch'), arg_name='First fetch time', required=False ) if ff: first_fetch = datetime.fromtimestamp(ff).astimezone(timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ') except ValueError as e: return_error(f'First fetch time is in a wrong format. Error: {str(e)}') max_fetch = 10 try: max_fetch = int(demisto.params().get('max_fetch', '10')) except ValueError: return_error('Maximum number of incidents per fetch needs to be an integer') # get the service API url base_url = urljoin(demisto.params()['url'], '/pub/v4.0') verify_certificate = not demisto.params().get('insecure', False) proxy = demisto.params().get('proxy', False) demisto.info(f'Command being called is {demisto.command()}') try: client = Client( base_url=base_url, tenant_id=tenant_id, api_timeout=api_timeout, first_fetch=first_fetch, max_fetch=max_fetch, verify=verify_certificate, proxy=proxy, ok_codes=(200,), headers={ 'X-Key-Id': access_key_id, 'X-Access-Key': secret_access_key }) if demisto.command() == 'test-module': # This is the call made when pressing the integration Test button. result = test_module(client) demisto.results(result) elif demisto.command() == 'fetch-incidents': # Set and define the fetch incidents command to run after activated via integration settings. next_run, incidents = fetch_incidents( client=client, last_run=demisto.getLastRun()) if next_run is not None: demisto.setLastRun(next_run) if incidents is not None: demisto.incidents(incidents) elif demisto.command() == 'iot-security-get-device': return_results(iot_get_device(client, demisto.args())) elif demisto.command() == 'iot-security-get-device-by-ip': return_results(iot_get_device_by_ip(client, demisto.args())) elif demisto.command() == 'iot-security-list-devices': return_results(iot_list_devices(client, demisto.args())) elif demisto.command() == 'iot-security-list-alerts': return_results(iot_list_alerts(client, demisto.args())) elif demisto.command() == 'iot-security-list-vulns': return_results(iot_list_vulns(client, demisto.args())) elif demisto.command() == 'iot-security-resolve-alert': return_results(iot_resolve_alert(client, demisto.args())) elif demisto.command() == 'iot-security-resolve-vuln': return_results(iot_resolve_vuln(client, demisto.args())) # Log exceptions except Exception as e: return_error(f'Failed to execute {demisto.command()} command. Error: {str(e)}')
def main() -> None: try: arguments = demisto.args() api_key = demisto.params().get('apikey') base_url = urljoin(demisto.params()['url'], '/api/') verify_certificate = not demisto.params().get('insecure', False) first_fetch_time = arg_to_timestamp( arg=demisto.params().get('first_fetch', '1 days'), arg_name='First fetch time', required=True ) assert isinstance(first_fetch_time, int) proxy = demisto.params().get('proxy', False) page = arguments.get('page', "1") page_count_no = arguments.get('max', "25") demisto.debug(f'Command being called is {demisto.command()}') params = {'page': page, 'max': page_count_no} headers = { 'Authorization': f'Bearer {api_key}' } client = Client( base_url=base_url, verify=verify_certificate, headers=headers, proxy=proxy) if demisto.command() == 'test-module': result = test_module_command(client) return_results(result) elif demisto.command() == 'fetch-incidents': max_results = arg_to_int( arg=demisto.params().get('max_fetch'), arg_name='max_fetch', required=False ) if not max_results or max_results > MAX_INCIDENTS_TO_FETCH: max_results = MAX_INCIDENTS_TO_FETCH next_run, incidents = fetch_incidents( client=client, max_results=max_results, last_run=demisto.getLastRun(), # getLastRun() gets the last run dict first_fetch_time=first_fetch_time ) demisto.setLastRun(next_run) demisto.incidents(incidents) elif demisto.command() == 'gra-fetch-users': fetch_records(client, '/users', 'Gra.Users', 'employeeId', params) elif demisto.command() == 'gra-fetch-accounts': fetch_records(client, '/accounts', 'Gra.Accounts', 'id', params) elif demisto.command() == 'gra-fetch-active-resource-accounts': resource_name = arguments.get('resource_name', 'Windows Security') active_resource_url = '/resources/' + resource_name + '/accounts' fetch_records(client, active_resource_url, 'Gra.Active.Resource.Accounts', 'id', params) elif demisto.command() == 'gra-fetch-user-accounts': employee_id = arguments.get('employee_id') user_account_url = '/users/' + employee_id + '/accounts' fetch_records(client, user_account_url, 'Gra.User.Accounts', 'id', params) elif demisto.command() == 'gra-fetch-resource-highrisk-accounts': res_name = arguments.get('Resource_name', 'Windows Security') high_risk_account_resource_url = '/resources/' + res_name + '/accounts/highrisk' fetch_records(client, high_risk_account_resource_url, 'Gra.Resource.Highrisk.Accounts', 'id', params) elif demisto.command() == 'gra-fetch-hpa': fetch_records(client, '/accounts/highprivileged', 'Gra.Hpa', 'id', params) elif demisto.command() == 'gra-fetch-resource-hpa': resource_name = arguments.get('Resource_name', 'Windows Security') resource_hpa = '/resources/' + resource_name + '/accounts/highprivileged' fetch_records(client, resource_hpa, 'Gra.Resource.Hpa', 'id', params) elif demisto.command() == 'gra-fetch-orphan-accounts': fetch_records(client, '/accounts/orphan', 'Gra.Orphan.Accounts', 'id', params) elif demisto.command() == 'gra-fetch-resource-orphan-accounts': resource_name = arguments.get('resource_name', 'Windows Security') resource_orphan = '/resources/' + resource_name + '/accounts/orphan' fetch_records(client, resource_orphan, 'Gra.Resource.Orphan.Accounts', 'id', params) elif demisto.command() == 'gra-user-activities': employee_id = arguments.get('employee_id') user_activities_url = '/user/' + employee_id + '/activity' fetch_records(client, user_activities_url, 'Gra.User.Activity', 'employee_id', params) elif demisto.command() == 'gra-fetch-users-details': employee_id = arguments.get('employee_id') fetch_records(client, '/users/' + employee_id, 'Gra.User', 'employeeId', params) elif demisto.command() == 'gra-highRisk-users': fetch_records(client, '/users/highrisk', 'Gra.Highrisk.Users', 'employeeId', params) elif demisto.command() == 'gra-cases': status = arguments.get('status') cases_url = '/cases/' + status fetch_records(client, cases_url, 'Gra.Cases', 'caseId', params) elif demisto.command() == 'gra-user-anomalies': employee_id = arguments.get('employee_id') anomaly_url = '/users/' + employee_id + '/anomalies/' fetch_records(client, anomaly_url, 'Gra.User.Anomalies', 'anomaly_name', params) elif demisto.command() == 'gra-case-action': action = arguments.get('action') caseId = arguments.get('caseId') subOption = arguments.get('subOption') caseComment = arguments.get('caseComment') riskAcceptDate = arguments.get('riskAcceptDate') cases_url = '/cases/' + action if action == 'riskManageCase': post_url = {"caseId": int(caseId), "subOption": subOption, "caseComment": caseComment, "riskAcceptDate": riskAcceptDate} else: post_url = {"caseId": int(caseId), "subOption": subOption, "caseComment": caseComment} post_url_json = json.dumps(post_url) fetch_post_records(client, cases_url, 'Gra.Case.Action', 'caseId', params, post_url_json) elif demisto.command() == 'gra-case-action-anomaly': action = arguments.get('action') caseId = arguments.get('caseId') anomalyNames = arguments.get('anomalyNames') subOption = arguments.get('subOption') caseComment = arguments.get('caseComment') riskAcceptDate = arguments.get('riskAcceptDate') cases_url = '/cases/' + action if action == 'riskAcceptCaseAnomaly': post_url = {"caseId": int(caseId), "anomalyNames": anomalyNames, "subOption": subOption, "caseComment": caseComment, "riskAcceptDate": riskAcceptDate} else: post_url = {"caseId": int(caseId), "anomalyNames": anomalyNames, "subOption": subOption, "caseComment": caseComment} post_url_json = json.dumps(post_url) fetch_post_records(client, cases_url, 'Gra.Cases.Action.Anomaly', 'caseId', params, post_url_json) elif demisto.command() == 'gra-investigate-anomaly-summary': fromDate = arguments.get('fromDate') toDate = arguments.get('toDate') modelName = arguments.get('modelName') if fromDate is not None and toDate is not None: investigateAnomaly_url = '/investigateAnomaly/anomalySummary/' + modelName + '?fromDate=' + fromDate \ + ' 00:00:00&toDate=' + toDate + ' 23:59:59' else: investigateAnomaly_url = '/investigateAnomaly/anomalySummary/' + modelName fetch_records(client, investigateAnomaly_url, 'Gra.Investigate.Anomaly.Summary', 'modelId', params) elif demisto.command() == 'gra-analytical-features-entity-value': fromDate = arguments.get('fromDate') toDate = arguments.get('toDate') modelName = arguments.get('modelName') entityValue = arguments.get('entityValue') if fromDate is not None and toDate is not None: analyticalFeatures_url = 'profile/analyticalFeatures/' + entityValue + '?fromDate=' + fromDate \ + ' 00:00:00&toDate=' + toDate + ' 23:59:59&modelName=' + modelName else: analyticalFeatures_url = 'profile/analyticalFeatures/' + entityValue + '?modelName=' + modelName fetch_records(client, analyticalFeatures_url, 'Gra.Analytical.Features.Entity.Value', 'entityID', params) # Log exceptions and return errors except Exception as e: demisto.error(traceback.format_exc()) # print the traceback return_error(f'Failed to execute {demisto.command()} command.\nError:\n{str(e)}')
def main(): esm = NitroESM(ESM_URL, USERNAME, PASSWORD) try: esm.login() final_result = 'No result set' if demisto.command() == 'fetch-incidents': last_run = demisto.getLastRun() demisto.debug('\n\nlast run:\n{}\n'.format(last_run)) # for backward compatibility uses if 'value' in last_run and 'alarms' not in last_run: last_run['alarms'] = last_run['value'] configuration_last_case = int(demisto.params().get( 'startingCaseID', 0)) start_alarms = last_run.get('alarms') if start_alarms is None: start_alarms, _ = parse_date_range( demisto.params()['alarm_fetch_time'], date_format='%Y-%m-%dT%H:%M:%S.%f', timezone=TIMEZONE) last_case = last_run.get('cases', 0) # if last_case < configuration_last_case: last_case = max(last_case, configuration_last_case) incidents = [] # type: list mode = demisto.params().get('fetchTypes', 'alarms').lower( ) # alarms is default for backward compatibility next_run = None if mode in ('alarms', 'both'): end = (datetime.now() + timedelta(hours=TIMEZONE)).isoformat() demisto.debug("alarms: start - {} , end - {}".format( start_alarms, end)) alarms = esm.fetch_alarms('CUSTOM', start_alarms, end, '') demisto.debug('alarms found:\n{}\n'.format(alarms)) incidents = [] for alarm in alarms: triggered_date = alarm['triggeredDate'] if next_run is None or next_run < triggered_date: next_run = triggered_date alarm['events'] = esm.list_alarm_events(alarm['ID']) incidents.append({ 'name': alarm['summary'], 'details': 'Alarm {} , ID : {} , was triggered by condition type: {}' .format(alarm['alarmName'], alarm['ID'], alarm['conditionType']), 'severity': severity_to_level(alarm['severity']), 'rawJSON': json.dumps(alarm) }) if mode in ('cases', 'both'): # get new cases cases = [ case for case in esm.get_cases() if case['id']['value'] > last_case ] cases.sort(key=lambda c: c['id']['value']) cases = cases[:MAX_CASES_PER_FETCH] if cases: last_case = cases[-1]['id']['value'] # update last run info last_run['cases'] = last_case demisto.debug('adding %d more cases, last id is: %d' % ( len(cases), last_run['cases'], )) if cases: incidents.extend(cases_to_incidents(cases)) if next_run is not None: next_run_datetime = datetime.strptime(next_run, parse_time(next_run)) next_run = (next_run_datetime + timedelta(seconds=1)).isoformat() else: next_run = start_alarms last_run['value'] = next_run last_run['alarms'] = next_run demisto.incidents(incidents) demisto.setLastRun(last_run) sys.exit(0) elif demisto.command() == 'test-module': if VERSION not in ['10.0', '10.1', '10.2', '10.3', '11.1']: final_result = 'version must be one of 10.x, got %s' % ( VERSION, ) else: esm.fetch_all_fields() final_result = 'ok' elif demisto.command() == 'esm-fetch-fields': res = esm.fetch_all_fields() final_result = res elif demisto.command() == 'esm-search': args = demisto.args() res = esm.search(demisto.get(args, 'timeRange'), demisto.get(args, 'customStart'), demisto.get(args, 'customEnd'), json.loads(args.get('filters')), args.get('fields'), demisto.get(args, 'queryType') or 'EVENT', demisto.get(args, 'maxWait') or 30) final_result = res elif demisto.command() == 'esm-get-case-list': since_date_range = demisto.args().get('since') res = esm.get_cases(since_date_range) final_result = cases_to_entry(esm, 'All cases:', res) elif demisto.command() == 'esm-get-case-detail': args = demisto.args() case_id = int(demisto.get(args, 'id')) res = esm.get_case_detail(case_id) final_result = cases_to_entry(esm, 'Case %d:' % (case_id, ), [res]) elif demisto.command() == 'esm-add-case': args = demisto.args() res = esm.add_case( demisto.get(args, 'summary'), int(demisto.get(args, 'severity')), demisto.get(args, 'status'), demisto.get(args, 'assignee'), demisto.get(args, 'organization'), ) case = esm.get_case_detail(res) final_result = cases_to_entry(esm, 'New Case:', [case]) elif demisto.command() == 'esm-edit-case': args = demisto.args() case_id = int(demisto.get(args, 'id')) severity = demisto.get(args, 'severity') esm.edit_case( case_id, demisto.get(args, 'summary'), int(severity) if severity else None, demisto.get(args, 'status'), demisto.get(args, 'assignee'), demisto.get(args, 'organization'), ) case = esm.get_case_detail(case_id) final_result = cases_to_entry(esm, 'Edited Case:', [case]) elif demisto.command() == 'esm-get-case-statuses': res = esm.get_case_statuses() final_result = case_statuses_to_entry(res) elif demisto.command() == 'esm-add-case-status': args = demisto.args() res = esm.add_case_status( demisto.get(args, 'name'), bool(strtobool(demisto.get(args, 'show_in_case_pane'))), ) final_result = res elif demisto.command() == 'esm-edit-case-status': args = demisto.args() should_show = demisto.get(args, 'show_in_case_pane') res = esm.edit_case_status( demisto.get(args, 'original_name'), demisto.get(args, 'new_name'), bool(strtobool(should_show)) if should_show else None, ) final_result = res elif demisto.command() == 'esm-delete-case-status': args = demisto.args() res = esm.delete_case_status(demisto.get(args, 'name')) final_result = res elif demisto.command() == 'esm-get-case-event-list': args = demisto.args() event_ids = demisto.get(args, 'ids').split(',') res = esm.get_case_event_list(event_ids) final_result = case_events_to_entry(res) elif demisto.command() == 'esm-get-organization-list': res = esm.get_organizations() final_result = organizations_to_entry(res) elif demisto.command() == 'esm-get-user-list': res = esm.get_users() final_result = users_to_entry(res) elif demisto.command() == 'esm-fetch-alarms': args = demisto.args() res = esm.fetch_alarms(demisto.get(args, 'timeRange'), demisto.get(args, 'customStart'), demisto.get(args, 'customEnd'), demisto.get(args, 'assignedUser')) final_result = alarms_to_entry(res) elif demisto.command() == 'esm-acknowledge-alarms': args = demisto.args() res = esm.acknowledge_alarms( argToList(demisto.get(args, 'alarmIds'))) final_result = res elif demisto.command() == 'esm-unacknowledge-alarms': args = demisto.args() res = esm.unacknowledge_alarms( argToList(demisto.get(args, 'alarmIds'))) final_result = res elif demisto.command() == 'esm-delete-alarms': args = demisto.args() res = esm.delete_alarms(argToList(demisto.get(args, 'alarmIds'))) final_result = res elif demisto.command() == 'esm-get-alarm-event-details': args = demisto.args() res = esm.get_alarm_event_details(demisto.get(args, 'eventId')) final_result = alarm_events_to_entry(esm, [res]) elif demisto.command() == 'esm-list-alarm-events': args = demisto.args() res = esm.list_alarm_events(demisto.get(args, 'alarmId')) final_result = alarm_events_to_entry(esm, res['events']) demisto.results(final_result) except Exception as ex: demisto.error('#### error in McAfee ESM v10: ' + str(ex)) if demisto.command() == 'fetch-incidents': LOG(traceback.format_exc()) LOG.print_log() raise else: return_error(str(ex), error=traceback.format_exc()) finally: esm.logout()