def list_resource_groups_command(): """ List all Resource Groups belonging to your Azure subscription returns: Resource-Group Objects """ response = list_resource_groups() # Retrieve relevant properties to return to context value = response.get('value') resource_groups = [] for resource_group in value: resource_group_context = { 'Name': resource_group.get('name'), 'ID': resource_group.get('id'), 'Location': resource_group.get('location'), 'ProvisioningState': resource_group.get('properties', {}).get('provisioningState') } resource_groups.append(resource_group_context) title = 'List of Resource Groups' human_readable = tableToMarkdown(title, resource_groups, removeNull=True) entry_context = {'Azure.ResourceGroup(val.Name && val.Name === obj.Name)': resource_groups} demisto.results({ 'Type': entryTypes['note'], 'Contents': response, 'ContentsFormat': formats['text'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': human_readable, 'EntryContext': entry_context })
def get_report_command(): """Return ANYRUN analysis report to Demisto""" args = demisto.args() task_id = args.get('task') response = get_report(task_id) images = images_from_report(response) contents = contents_from_report(response) formatting_funcs = [underscore_to_camel_case, make_capital, make_singular, make_upper] formatted_contents = travel_object(contents, key_functions=formatting_funcs) dbot_score = generate_dbotscore(response) entity = ec_entity(response) entry_context = { 'ANYRUN.Task(val.ID && val.ID === obj.ID)': { 'ID': task_id, **formatted_contents }, **dbot_score, **entity } title = 'Report for Task {}'.format(task_id) human_readable_content = humanreadable_from_report_contents(formatted_contents) human_readable = tableToMarkdown(title, human_readable_content, removeNull=True) return_outputs(readable_output=human_readable, outputs=entry_context, raw_response=response) if images: demisto.results(images)
def get_all_query_viewers_command(): query_path = 'www/manager-service/rest/QueryViewerService/findAllIds' params = { 'authToken': AUTH_TOKEN, 'alt': 'json' } headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json' } res = send_request(query_path, headers=headers, params=params) if not res.ok: demisto.debug(res.text) return_error("Failed to get query viewers:\nStatus Code: {}\nResponse: {}".format(res.status_code, res.text)) res_json = res.json() if 'qvs.findAllIdsResponse' in res_json and 'qvs.return' in res_json.get('qvs.findAllIdsResponse'): query_viewers = res_json.get('qvs.findAllIdsResponse').get('qvs.return') contents = decode_arcsight_output(query_viewers) outputs = {'ArcSightESM.AllQueryViewers': contents} human_readable = tableToMarkdown(name='', t=query_viewers, headers='Query Viewers', removeNull=True) return_outputs(readable_output=human_readable, outputs=outputs, raw_response=contents) else: demisto.results('No Query Viewers were found')
def delete_tags(): """ The command deletes tags for the specified endpoint. demisto parameter: (string) endpoint_id The unique ID of the endpoint demisto parameter: (array) body The tags to delete from the endpoint """ endpoint_id = demisto.args().get('endpoint_id') body = argToList(demisto.args().get('tags')) response = delete_tags_request(endpoint_id, body) response = endpoint_tags_request(endpoint_id) response = { 'tags': response, 'Id': endpoint_id } context = { 'CounterTack.Endpoint(val.Id && val.Id === obj.Id)': createContext(response, keyTransform=underscoreToCamelCase) } entry = { 'Type': entryTypes['note'], 'Contents': response, 'ContentsFormat': formats['json'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown( 'Endpoint tags were deleted successfully', response), 'EntryContext': context } demisto.results(entry)
def get_endpoint_tags(): """ Get the tags for the specified endpoint demisto parameter: (string) endpoint_id The unique ID of the endpoint """ endpoint_id = demisto.args().get('endpoint_id') response = endpoint_tags_request(endpoint_id) response = { 'tags': response } tags_context = { 'Id': endpoint_id, 'tags': response } context = { 'CounterTack.Endpoint(val.Id && val.Id === obj.Id)': createContext(tags_context, keyTransform=underscoreToCamelCase) } entry = { 'Type': entryTypes['note'], 'Contents': response, 'ContentsFormat': formats['json'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown('CounterTack tags for the specified endpoint:', response, removeNull=True), 'EntryContext': context } demisto.results(entry)
def test_integration(): # the login is executed in the switch panel code if IS_FETCH: # just check the correctness of the parameter parse_date_range(FETCH_TIME) list_pcap_components() demisto.results('ok')
def get_behaviors(): """ retrieve information on a collection of behaviors. """ data = [] behaviors = get_behaviors_request() for behavior in behaviors: data.append({ 'Id': behavior.get('id'), 'Name': behavior.get('name'), 'Type': behavior.get('type'), 'ImpactLevel': behavior.get('impact_level'), 'lastReported': behavior.get('last_reported'), 'EndpointId': behavior.get('endpoint_id') }) context = { 'CounterTack.Behavior(val.Id && val.Id === obj.Id)': createContext(behaviors, keyTransform=underscoreToCamelCase) } headers = ['Name', 'Id', 'Type', 'ImpactLevel', 'EndpointId', 'lastReported'] entry = { 'Type': entryTypes['note'], 'Contents': behaviors, 'ContentsFormat': formats['json'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown('CounterTack Endpoints Behaviors', data, headers, removeNull=True), 'EntryContext': context } demisto.results(entry)
def get_security_events_command(): ids = demisto.args().get('ids') last_date_range = demisto.args().get('lastDateRange') ids = argToList(str(ids) if isinstance(ids, int) else ids) raw_events = get_security_events(ids, last_date_range) if raw_events: events = [] contents = decode_arcsight_output(raw_events) for raw_event in contents: event = { 'Event ID': raw_event.get('eventId'), 'Time': timestamp_to_datestring(raw_event.get('endTime'), '%Y-%m-%d, %H:%M:%S'), 'Source Address': decode_ip(demisto.get(raw_event, 'source.address')), 'Destination Address': decode_ip(demisto.get(raw_event, 'destination.address')), 'Name': raw_event.get('name'), 'Source Port': demisto.get(raw_event, 'source.port'), 'Base Event IDs': raw_event.get('baseEventIds') } events.append(event) human_readable = tableToMarkdown('Security Event: {}'.format(','.join(map(str, ids))), events, removeNull=True) outputs = {'ArcSightESM.SecurityEvents(val.eventId===obj.eventId)': contents} return_outputs(readable_output=human_readable, outputs=outputs, raw_response=contents) else: demisto.results('No events were found')
def test_module(): try: get_on_call_now_users_command() except Exception as e: raise Exception(e.message) demisto.results('ok')
def main(): """ COMMANDS MANAGER / SWITCH PANEL """ command = demisto.command() LOG(f'Command being called is {command}') try: if command == 'test-module': # This is the call made when pressing the integration test button. test_module() demisto.results('ok') elif command in ('msgraph-mail-list-emails', 'msgraph-mail-search-email'): list_mails_command() elif command == 'msgraph-mail-get-email': get_message_command() elif command == 'msgraph-mail-delete-email': delete_mail_command() elif command == 'msgraph-mail-list-attachments': list_attachments_command() elif command == 'msgraph-mail-get-attachment': get_attachment_command() # Log exceptions except Exception as e: LOG(e) LOG.print_log() raise
def poll(target, step, args=(), kwargs=None, timeout=None, max_tries=None, check_success=is_truthy, step_function=step_constant, ignore_exceptions=(), poll_forever=False, collect_values=None, *a, **k): kwargs = kwargs or dict() values = collect_values or Queue() max_time = time.time() + timeout if timeout else None tries = 0 last_item = None while True: try: val = target(*args, **kwargs) last_item = val except ignore_exceptions as e: last_item = e else: if check_success(val): return val values.put(last_item) tries += 1 if max_time is not None and time.time() >= max_time: demisto.results('The operation timed out. Please try again with a longer timeout period.') time.sleep(step) step = step_function(step)
def wildfire_get_verdicts_command(): if ('EntryID' in demisto.args() and 'hash_list' in demisto.args()) or ( 'EntryID' not in demisto.args() and 'hash_list' not in demisto.args()): return_error('Specify exactly 1 of the following arguments: EntryID, hash_list.') if 'EntryID' in demisto.args(): inputs = argToList(demisto.args().get('EntryID')) paths = [demisto.getFilePath(element)['path'] for element in inputs] else: paths = hash_list_to_file(argToList(demisto.args().get('hash_list'))) for file_path in paths: result, verdicts_data = wildfire_get_verdicts(file_path) pretty_verdicts = prettify_verdicts(verdicts_data) md = tableToMarkdown('WildFire Verdicts', pretty_verdicts, removeNull=True) dbot_score = create_dbot_score_from_verdicts(pretty_verdicts) ec = { "WildFire.Verdicts(val.SHA256 == obj.SHA256 || val.MD5 == obj.MD5)": pretty_verdicts, "DBotScore(val.Indicator == obj.Indicator)": dbot_score } demisto.results({ 'Type': entryTypes['note'], 'Contents': result, 'ContentsFormat': formats['json'], 'HumanReadable': md, 'ReadableContentsFormat': formats['markdown'], 'EntryContext': ec })
def get_token_command(): """ Fetch a Canary Token from the Canary Tools server :return: Canary Token information or file """ token = demisto.args().get('token') params = { 'canarytoken': token } res = http_request('GET', SERVER + 'canarytoken/fetch', params=params) context = demisto.get(res, 'token.canarytoken') contents = res human_readable = 'File Fetched Successfully' outputs = {'CanaryTools.Token(val.CanaryToken && val.CanaryToken === obj.CanaryToken)': context} if demisto.get(res, 'token.doc'): name = demisto.get(res, 'token.doc_name') content = demisto.get(res, 'token.doc') token_file = fileResult(name, content) demisto.results(token_file) if demisto.get(res, 'token.web_image'): name = demisto.get(res, 'token.web_image_name') content = demisto.get(res, 'token.web_image') token_file = fileResult(name, content) demisto.results(token_file) else: human_readable = tableToMarkdown('Canary Tools Tokens', res.get('token')) return_outputs(readable_output=human_readable, outputs=outputs, raw_response=contents)
def snowflake_query_command(): args = demisto.args() query = args.get('query') db = args.get('database') if args.get('database') else DATABASE schema = args.get('schema') if args.get('schema') else SCHEMA col_descriptions, results = snowflake_query(args) if not results: demisto.results('No data found matching the query') else: results = format_to_json_serializable(col_descriptions, results) entry_context = { 'Database': db, 'Schema': schema, 'Query': query, 'Result': results } columns = argToList(args.get('columns')) human_readable = tableToMarkdown(query, results, columns, removeNull=True) demisto_transform = 'Snowflake(val.Query && val.Query === obj.Query' demisto_transform += ' && val.Database && val.Database === obj.Database' demisto_transform += ' && val.Schema && val.Schema === obj.Schema)' outputs = {demisto_transform: entry_context} return_outputs( outputs=outputs, readable_output=human_readable, raw_response=results )
def get_alert_command(): args = demisto.args() alert_id = args['alert_id'] alert = get_alert(alert_id) output = { 'ID': alert['alertId'], 'ThreatScore': alert['fidelisScore'], 'Time': alert['time'], 'RuleID': alert['ruleId'], 'RuleName': alert['rule'], 'Summary': alert['summary'], 'PolicyName': alert['policy'], 'Severity': alert['severity'], 'Protocol': alert['protocol'], 'Type': alert['alertType'], 'AssignedUser': alert['ticket']['assignedUserId'] if alert['ticket'] is not None else None, } demisto.results({ 'Type': entryTypes['note'], 'ContentsFormat': formats['json'], 'Contents': alert, 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown('Alert {}'.format(alert_id), output, headerTransform=pascalToSpace), 'EntryContext': { 'Fidelis.Alert(val.ID && val.ID == obj.ID)': output, }, })
def get_malware_data_command(): args = demisto.args() alert_id = args['alert_id'] result = get_malware_data(alert_id) output = { 'ID': alert_id, 'Malware': { 'Name': result['malwareName'], 'Behavior': result['malwareBehavior'], 'Description': result['malwareDescription'], 'DetailName': result['malwareDetailName'], 'Platform': result['malwarePlatform'], 'Type': result['malwareType'], 'Variant': result['malwareVariant'], } } demisto.results({ 'Type': entryTypes['note'], 'ContentsFormat': formats['json'], 'Contents': result, 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown('Alert {} Malware:'.format(alert_id), result, headerTransform=pascalToSpace), 'EntryContext': { 'Fidelis.Alert(val.ID && val.ID == obj.ID)': output, }, })
def add_entries_command(): resource_id = demisto.args().get('resourceId') entries = demisto.args().get('entries') query_path = 'www/manager-service/services/ActiveListService/' if not isinstance(entries, dict): try: entries = json.loads(entries) except ValueError as ex: demisto.debug(str(ex)) return_error('Entries must be in JSON format. Must be array of objects.') if not all([entry.keys() == entries[0].keys() for entry in entries[1:]]): return_error('All entries must have the same fields') columns = ''.join(COLUMN(column) for column in entries[0]) # the fields in the entryList matrix are the columns entry_list = BODY(columns + ''.join(ENTRY_LIST(''.join(ENTRY(v) for v in en.values())) for en in entries)) body = REQ_SOAP_BODY(function='addEntries', auth_token=AUTH_TOKEN, resource_id=resource_id, entryList=entry_list) res = send_request(query_path, body=body) if not res.ok: demisto.debug(res.text) return_error("Failed to add entries. Please make sure to enter Active List resource ID" "\nResource ID: {}\nStatus Code: {}\nRequest Body: {}\nResponse: {}".format(resource_id, res.status_code, body, res.text)) demisto.results("Success")
def rasterize_image(): global return_code, error_message res = demisto.getFilePath(demisto.args()['EntryID']) with open(res['path'], 'r') as f: data = f.read() b64 = base64.b64encode(data) html = '<img src="data:image/png;base64, ' + b64 + '">' return_code = 0 friendly_name = 'image.png' f = open('htmlImage.html', 'w') f.write('<html style="background:white;"><body>' + html + '</body></html>') f.close() command = ['phantomjs', '/usr/local/bin/rasterize.js', 'htmlImage.html', friendly_name] if demisto.get(demisto.args(), 'width') and demisto.get(demisto.args(), 'height'): command.append(demisto.get(demisto.args(), 'width') + '*' + demisto.get(demisto.args(), 'height')) try: error_message = subprocess.check_output(command) except Exception as e: return_code = -1 error_message = e.message if return_code == 0: file = file_result_existing_file(friendly_name) file['Type'] = entryTypes['image'] demisto.results(file) else: demisto.results({'ContentsFormat': 'text', 'Type': entryTypes['error'], 'Contents': 'PhantomJS returned - ' + error_message})
def get_case_event_ids_command(): case_id = demisto.args().get('caseId') with_correlated_events = demisto.args().get('withCorrelatedEvents') == 'true' query_path = 'www/manager-service/rest/CaseService/getCaseEventIDs' params = { 'authToken': AUTH_TOKEN, 'caseId': case_id } res = send_request(query_path, params=params, method='get') if not res.ok: demisto.debug(res.text) return_error("Failed to get Event IDs with:\nStatus Code: {}\nResponse: {}".format(res.status_code, res.text)) res_json = res.json() if 'cas.getCaseEventIDsResponse' in res_json and 'cas.return' in res_json.get('cas.getCaseEventIDsResponse'): event_ids = res_json.get('cas.getCaseEventIDsResponse').get('cas.return') if not isinstance(event_ids, list): event_ids = [event_ids] if with_correlated_events: event_ids = get_correlated_events_ids(event_ids) contents = decode_arcsight_output(res_json) human_readable = tableToMarkdown(name='', headers='Case {} Event IDs'.format(case_id), t=event_ids, removeNull=True) outputs = {'ArcSightESM.CaseEvents': event_ids} return_outputs(readable_output=human_readable, outputs=outputs, raw_response=contents) else: demisto.results('No result returned')
def rasterize(): global return_code, error_message return_code = 0 error_message = '' url = demisto.args()['url'] if not (url.startswith("http")): url = "http://" + url friendly_name = 'url.png' if demisto.get(demisto.args(), 'type') == 'pdf': friendly_name = 'url.pdf' proxy_flag = "" if proxy: if url.startswith("https"): proxy_flag = "--proxy=" + https_proxy else: proxy_flag = "--proxy=" + http_proxy demisto.debug('rasterize proxy settings: ' + proxy_flag) command = ['phantomjs', proxy_flag, '/usr/local/bin/rasterize.js', url, friendly_name] if demisto.get(demisto.args(), 'width') and demisto.get(demisto.args(), 'height'): command.append(demisto.get(demisto.args(), 'width') + '*' + demisto.get(demisto.args(), 'height')) try: error_message = subprocess.check_output(command) except subprocess.CalledProcessError: return_code = -1 error_message = "Can't access the URL. It might be malicious, or unreachable for one of several reasons." if return_code == 0: file = file_result_existing_file(friendly_name) file['Type'] = entryTypes['image'] demisto.results(file) else: demisto.results({'ContentsFormat': 'text', 'Type': entryTypes['error'], 'Contents': 'PhantomJS returned - ' + error_message})
def free_search(default_base_dn, page_size): args = demisto.args() search_filter = args.get('filter') size_limit = int(args.get('size-limit', '0')) time_limit = int(args.get('time-limit', '0')) search_base = args.get('base-dn') or default_base_dn attributes = args.get('attributes') context_output = args.get('context-output') # if ALL was specified - get all the object's attributes, else expect a string of comma separated values if attributes: attributes = ALL_ATTRIBUTES if attributes == 'ALL' else attributes.split(',') entries = search_with_paging( search_filter, search_base, attributes=attributes, size_limit=size_limit, time_limit=time_limit, page_size=page_size ) ec = {} if context_output == 'no' else {'ActiveDirectory.Search(obj.dn == val.dn)': entries['flat']} demisto_entry = { 'ContentsFormat': formats['json'], 'Type': entryTypes['note'], 'Contents': entries['raw'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown("Active Directory Search", entries['flat']), 'EntryContext': ec } demisto.results(demisto_entry)
def add_behavior_tags(): """ Add specific tags to specified behavior demisto parameter: (string) behavior_id The unique ID of the behavior demisto parameter: (Array) Body. The tags to add to the behavior. seperate the tags with comma """ behaviour_id = demisto.args().get('behaviour_id') body = argToList(demisto.args().get('tags')) response = behaviour_add_tags_request(behaviour_id, body) behavior_tags = get_behavior_request(behaviour_id) response = { 'tags': behavior_tags.get('tags'), 'Id': behaviour_id } context = { 'CounterTack.Behavior(val.Id && val.Id === obj.Id)': createContext(response, keyTransform=underscoreToCamelCase) } entry = { 'Type': entryTypes['note'], 'Contents': response, 'ContentsFormat': formats['json'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown('Behavior tags were added successfully', response), 'EntryContext': context } demisto.results(entry)
def format_device_results(data): hr_table = [] ec = { "ExtraHop": { "Device": [] } } for device in data: hr = {} if 'id' in device: hr['ID'] = device.get('id') if 'display_name' in device: hr['Display Name'] = device.get('display_name') if 'ipaddr4' in device: hr['IP Address'] = device.get('ipaddr4') if 'macaddr' in device: hr['MAC Address'] = device.get('macaddr') if 'vendor' in device: hr['Vendor'] = device.get('vendor') hr_table.append(hr) ec['ExtraHop']['Device'].append(createContext(device, keyTransform=string_to_context_key, removeNull=True)) demisto.results({ 'Type': entryTypes['note'], 'ContentsFormat': formats['markdown'], 'Contents': data, 'HumanReadable': tableToMarkdown('Devices Found', hr_table), 'EntryContext': ec })
def list_alerts_command(): args = demisto.args() time_frame = args.get('time_frame') start_time = args.get('start_time') end_time = args.get('end_time') severity = args.get('severity') _type = args.get('type') threat_score = args.get('threat_score') ioc = args.get('ioc') results = list_alerts(time_frame=time_frame, start_time=start_time, end_time=end_time, severity=severity, _type=_type, threat_score=threat_score, ioc=ioc) output = [{ 'ID': alert['ALERT_ID'], 'Time': alert['ALERT_TIME'], 'Summary': alert['SUMMARY'], 'Severity': alert['SEVERITY'], 'Type': alert['ALERT_TYPE'], } for alert in results] demisto.results({ 'Type': entryTypes['note'], 'ContentsFormat': formats['json'], 'Contents': results, 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown('Found {} Alerts:'.format(len(output)), output), 'EntryContext': { 'Fidelis.Alert(val.ID && val.ID == obj.ID)': output, }, })
def test_module(): """ Performs basic get request to get item samples """ test_result = report_malicious_site("https://www.test.com", "test", True) if test_result[0] != MALICIOUS_REPORT_SUCCESS: raise Exception("Test request failed.") demisto.results("ok")
def snowflake_update_command(): args = demisto.args() db_operation = args.get('db_operation') params = get_connection_params(args) with snowflake.connector.connect(**params) as connection: with connection.cursor() as cursor: cursor.execute(db_operation) demisto.results('Operation executed successfully.')
def test_module(): """ Performs basic get request to get item samples """ req_res = jira_req('GET', 'rest/api/latest/myself') run_query(demisto.getParam('query'), max_results=1) if req_res.ok: demisto.results('ok')
def get_attachment_command(): message_id = demisto.args().get('message_id') user_id = demisto.args().get('user_id') folder_id = demisto.args().get('folder_id') attachment_id = demisto.args().get('attachment_id') raw_response = get_attachment(message_id, user_id, folder_id=folder_id, attachment_id=attachment_id) entry_context = file_result_creator(raw_response) demisto.results(entry_context)
def delete_issue_command(issue_id_or_key): url = f'rest/api/latest/issue/{issue_id_or_key}' issue = get_issue_fields(**demisto.args()) result = jira_req('DELETE', url, json.dumps(issue)) if result.status_code == 204: demisto.results('Issue deleted successfully.') else: demisto.results('Failed to delete issue.')
def get_endpoint(): """ Get the information for the requested endpoint demisto parameter: (string) endpoint_id The unique ID of the endpoint returns: The information about the specified endpoint """ endpoint_id = demisto.args().get('endpoint_id') response = get_endpoint_request(endpoint_id) content = { 'OS': response.get('product_name'), 'Domain': response.get('domain'), 'IP': response.get('ip'), 'Threat': response.get('threat'), 'MaxImpact': response.get('max_impact'), 'TenantID': response.get('tenant'), 'IsQuarantined': response.get('is_quarantined'), 'Profile': response.get('current_profile'), 'Cluster_hosts': response.get('cluster_hosts'), 'Status': response.get('status'), 'Tags': response.get('tags') } endpoint_standards = { 'Id': response.get('id'), 'IPAddress': response.get('ips'), 'Domain': response.get('domain'), 'MACAddress': response.get('mac'), 'OS': response.get('product_name'), 'OSVersion': response.get('driver_version'), 'Model': response.get('current_profile'), 'Memory': response.get('memory'), 'Processors': response.get('num_cpus') } context = { 'CounterTack.Endpoint(val.Id && val.Id === obj.Id)': createContext(response, keyTransform=underscoreToCamelCase), 'Endpoint': endpoint_standards } headers = ['OS', 'Domain', 'IP', 'Threat', 'MaxImpact', 'TenantID', 'IsQuarantined', 'Profile', 'Tags', 'Cluster_Hosts', 'Status'] entry = { 'Type': entryTypes['note'], 'Contents': response, 'ContentsFormat': formats['json'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown( 'CounterTack Endpoint information:', content, headers, removeNull=True), 'EntryContext': context } demisto.results(entry)
def format_results(client, uuid): # Scan Lists sometimes returns empty num_of_attempts = 0 relationships = [] response = urlscan_submit_request(client, uuid) scan_lists = response.get('lists') while scan_lists is None: try: num_of_attempts += 1 demisto.debug('Attempting to get scan lists {} times'.format(num_of_attempts)) response = urlscan_submit_request(client, uuid) scan_lists = response.get('lists') except Exception: if num_of_attempts == 5: break demisto.debug('Could not get scan lists, sleeping for 5 minutes before trying again') time.sleep(5) scan_data = response.get('data', {}) scan_lists = response.get('lists', {}) scan_tasks = response.get('task', {}) scan_page = response.get('page', {}) scan_stats = response.get('stats', {}) scan_meta = response.get('meta', {}) url_query = scan_tasks.get('url', {}) scan_verdicts = response.get('verdicts', {}) ec = makehash() dbot_score = makehash() human_readable = makehash() cont = makehash() file_context = makehash() url_cont = makehash() feed_related_indicators = [] LIMIT = int(demisto.args().get('limit', 20)) if 'certificates' in scan_lists: cert_md = [] cert_ec = [] certs = scan_lists['certificates'] for x in certs[:LIMIT]: info, ec_info = cert_format(x) cert_md.append(info) cert_ec.append(ec_info) CERT_HEADERS = ['Subject Name', 'Issuer', 'Validity'] cont['Certificates'] = cert_ec url_cont['Data'] = url_query if 'urls' in scan_lists: url_cont['Data'] = demisto.args().get('url') cont['URL'] = demisto.args().get('url') if isinstance(scan_lists.get('urls'), list): for url in scan_lists['urls']: feed_related_indicators.append({'value': url, 'type': 'URL'}) # effective url of the submitted url human_readable['Effective URL'] = scan_page.get('url') cont['EffectiveURL'] = scan_page.get('url') if 'uuid' in scan_tasks: ec['URLScan']['UUID'] = scan_tasks['uuid'] if 'ips' in scan_lists: ip_asn_MD = [] ip_ec_info = makehash() ip_list = scan_lists['ips'] asn_list = scan_lists['asns'] ip_asn_dict = dict(zip(ip_list, asn_list)) i = 1 for k in ip_asn_dict: if i - 1 == LIMIT: break v = ip_asn_dict[k] ip_info = { 'Count': i, 'IP': k, 'ASN': v } ip_ec_info[i]['IP'] = k ip_ec_info[i]['ASN'] = v ip_asn_MD.append(ip_info) i = i + 1 cont['RelatedIPs'] = ip_ec_info if isinstance(scan_lists.get('ips'), list): for ip in scan_lists.get('ips'): feed_related_indicators.append({'value': ip, 'type': 'IP'}) IP_HEADERS = ['Count', 'IP', 'ASN'] # add redirected URLs if 'requests' in scan_data: redirected_urls = [] for o in scan_data['requests']: if 'redirectResponse' in o['request']: if 'url' in o['request']['redirectResponse']: url = o['request']['redirectResponse']['url'] redirected_urls.append(url) cont['RedirectedURLs'] = redirected_urls if 'countries' in scan_lists: countries = scan_lists['countries'] human_readable['Associated Countries'] = countries cont['Country'] = countries if None not in scan_lists.get('hashes', []): hashes = scan_lists.get('hashes', []) cont['RelatedHash'] = hashes human_readable['Related Hashes'] = hashes for hashe in hashes: feed_related_indicators.append({'value': hashe, 'type': 'File'}) if 'domains' in scan_lists: subdomains = scan_lists.get('domains', []) cont['Subdomains'] = subdomains human_readable['Subdomains'] = subdomains for domain in subdomains: feed_related_indicators.append({'value': domain, 'type': 'Domain'}) if 'linkDomains' in scan_lists: link_domains = scan_lists.get('domains', []) for domain in link_domains: feed_related_indicators.append({'value': domain, 'type': 'Domain'}) if 'asn' in scan_page: cont['ASN'] = scan_page['asn'] url_cont['ASN'] = scan_page.get('asn') if 'asnname' in scan_page: url_cont['ASOwner'] = scan_page['asnname'] if 'country' in scan_page: url_cont['Geo']['Country'] = scan_page['country'] if 'domain' in scan_page: feed_related_indicators.append({'value': scan_page['domain'], 'type': 'Domain'}) if 'ip' in scan_page: feed_related_indicators.append({'value': scan_page['ip'], 'type': 'IP'}) if 'url' in scan_page: feed_related_indicators.append({'value': scan_page['url'], 'type': 'URL'}) if 'overall' in scan_verdicts: human_readable['Malicious URLs Found'] = scan_stats['malicious'] if scan_verdicts['overall'].get('malicious'): human_readable['Malicious'] = 'Malicious' url_cont['Data'] = demisto.args().get('url') cont['Data'] = demisto.args().get('url') dbot_score['Indicator'] = demisto.args().get('url') url_cont['Malicious']['Vendor'] = 'urlscan.io' cont['Malicious']['Vendor'] = 'urlscan.io' dbot_score['Vendor'] = 'urlscan.io' url_cont['Malicious']['Description'] = 'Match found in Urlscan.io database' cont['Malicious']['Description'] = 'Match found in Urlscan.io database' dbot_score['Score'] = 3 dbot_score['Type'] = 'url' else: dbot_score['Vendor'] = 'urlscan.io' dbot_score['Indicator'] = demisto.args().get('url') dbot_score['Score'] = 0 dbot_score['Type'] = 'url' human_readable['Malicious'] = 'Benign' dbot_score['Reliability'] = client.reliability if 'urlscan' in scan_verdicts and 'tags' in scan_verdicts['urlscan']: url_cont['Tags'] = scan_verdicts['urlscan']['tags'] processors_data = scan_meta['processors'] if 'download' in processors_data and len(scan_meta['processors']['download']['data']) > 0: meta_data = processors_data['download']['data'][0] sha256 = meta_data['sha256'] filename = meta_data['filename'] filesize = meta_data['filesize'] filetype = meta_data['mimeType'] human_readable['File']['Hash'] = sha256 cont['File']['Hash'] = sha256 file_context['SHA256'] = sha256 human_readable['File']['Name'] = filename cont['File']['FileName'] = filename file_context['Name'] = filename human_readable['File']['Size'] = filesize cont['File']['FileSize'] = filesize file_context['Size'] = filesize human_readable['File']['Type'] = filetype cont['File']['FileType'] = filetype file_context['Type'] = filetype file_context['Hostname'] = demisto.args().get('url') if feed_related_indicators: related_indicators = [] for related_indicator in feed_related_indicators: related_indicators.append(Common.FeedRelatedIndicators(value=related_indicator['value'], indicator_type=related_indicator['type'])) url_cont['FeedRelatedIndicators'] = related_indicators if demisto.params().get('create_relationships') is True: relationships = create_list_relationships({'page': scan_page}, url_query, client.reliability) outputs = { 'URLScan(val.URL && val.URL == obj.URL)': cont, outputPaths['file']: file_context } if 'screenshotURL' in scan_tasks: human_readable['Screenshot'] = scan_tasks['screenshotURL'] screen_path = scan_tasks['screenshotURL'] response_img = requests.request("GET", screen_path, verify=client.use_ssl) stored_img = fileResult('screenshot.png', response_img.content) dbot_score = Common.DBotScore(indicator=dbot_score.get('Indicator'), indicator_type=dbot_score.get('Type'), integration_name=BRAND, score=dbot_score.get('Score'), reliability=dbot_score.get('Reliability')) url = Common.URL(url=url_cont.get('Data'), dbot_score=dbot_score, relationships=relationships, feed_related_indicators=url_cont.get('FeedRelatedIndicators')) command_result = CommandResults( readable_output=tableToMarkdown('{} - Scan Results'.format(url_query), human_readable), outputs=outputs, indicator=url, raw_response=response, relationships=relationships ) demisto.results(command_result.to_context()) if len(cert_md) > 0: demisto.results({ 'Type': entryTypes['note'], 'ContentsFormat': formats['markdown'], 'Contents': tableToMarkdown('Certificates', cert_md, CERT_HEADERS), 'HumanReadable': tableToMarkdown('Certificates', cert_md, CERT_HEADERS) }) if 'ips' in scan_lists: if isinstance(scan_lists.get('ips'), list): feed_related_indicators += scan_lists.get('ips') demisto.results({ 'Type': entryTypes['note'], 'ContentsFormat': formats['markdown'], 'Contents': tableToMarkdown('Related IPs and ASNs', ip_asn_MD, IP_HEADERS), 'HumanReadable': tableToMarkdown('Related IPs and ASNs', ip_asn_MD, IP_HEADERS) }) if 'screenshotURL' in scan_tasks: demisto.results({ 'Type': entryTypes['image'], 'ContentsFormat': formats['text'], 'File': stored_img['File'], 'FileID': stored_img['FileID'], 'Contents': '' })
def get_jit_command(client: MsClient, args: dict): """Getting given Just-in-time machine Args: client: args (dict): usually demisto.args() """ policy_name = args.get("policy_name") asc_location = args.get("asc_location") resource_group_name = args.get("resource_group_name") policy = client.get_jit(policy_name, asc_location, resource_group_name) # Property table property_table_output = [ { "Name": policy.get("name"), "Kind": policy.get("kind"), "ProvisioningState": policy.get("properties").get("provisioningState") if policy.get("properties") and policy.get("properties", {}).get("provisioningState") else None, "Location": policy.get("location"), "Rules": policy.get("properties").get("virtualMachines") if policy.get("properties") and policy.get("properties", {}).get("virtualMachines") else None, "Requests": policy.get("properties").get("requests") if policy.get("properties") and policy.get("properties", {}).get("requests") else None, "ID": policy.get("id"), } ] md = tableToMarkdown( "Azure Security Center - Get JIT Access Policy - Properties", property_table_output, ["Name", "Kind", "ProvisioningState", "Location", "ID"], removeNull=True, ) ec = { "AzureSecurityCenter.JITPolicy(val.ID && val.ID === obj.ID)": property_table_output } property_table_entry = { "Type": entryTypes["note"], "Contents": policy, "ContentsFormat": formats["json"], "ReadableContentsFormat": formats["markdown"], "HumanReadable": md, "EntryContext": ec, } # Rules table rules_table_output = list() properties = policy.get("properties") virtual_machines = properties.get("virtualMachines") if isinstance(properties, dict) and virtual_machines: for rule in virtual_machines: rules_table_output.append( { "VmID": rule.get("id"), "Ports": format_jit_port_rule(rule.get("ports")), } ) md = tableToMarkdown( "Azure Security Center - Get JIT Access Policy - Rules", rules_table_output, ["VmID", "Ports"], removeNull=True, ) rules_table_entry = { "Type": entryTypes["note"], "Contents": properties.get("virtualMachines"), "ContentsFormat": formats["json"], "ReadableContentsFormat": formats["markdown"], "HumanReadable": md, } # Requests table requests_table_output = list() for requestData in properties.get("requests", []): vms = list() for vm in requestData.get("virtualMachines"): vm_name = vm["id"].split("/")[-1] vm_ports = format_jit_port_request(vm.get("ports")) vms.append("[{}: {}]".format(vm_name, vm_ports)) requests_table_output.append( { "VirtualMachines": ", ".join(vms), "Requestor": requestData.get("requestor") if requestData.get("requestor") else "service-account", "StartTimeUtc": requestData.get("startTimeUtc"), } ) md = tableToMarkdown( "Azure Security Center - Get JIT Access Policy - Requests", requests_table_output, ["VirtualMachines", "Requestor", "StartTimeUtc"], removeNull=True, ) requests_table_entry = { "Type": entryTypes["note"], "Contents": properties.get("requests"), "ContentsFormat": formats["json"], "ReadableContentsFormat": formats["markdown"], "HumanReadable": md, } demisto.results([property_table_entry, rules_table_entry, requests_table_entry])
def urlscan_search_command(client): LIMIT = int(demisto.args().get('limit')) HUMAN_READBALE_HEADERS = ['URL', 'Domain', 'IP', 'ASN', 'Scan ID', 'Scan Date'] raw_query = demisto.args().get('searchParameter', '') if is_ip_valid(raw_query, accept_v6_ips=True): search_type = 'ip' else: # Parsing query to see if it's a url parsed = urlparse(raw_query) # Checks to see if Netloc is present. If it's not a url, Netloc will not exist if parsed[1] == '' and len(raw_query) == 64: search_type = 'hash' else: search_type = 'page.url' # Making the query string safe for Elastic Search query = quote(raw_query, safe='') r = urlscan_search(client, search_type, query) if r['total'] == 0: demisto.results('No results found for {}'.format(raw_query)) return if r['total'] > 0: demisto.results('{} results found for {}'.format(r['total'], raw_query)) # Opening empty string for url comparison last_url = '' hr_md = [] cont_array = [] ip_array = [] dom_array = [] url_array = [] for res in r['results'][:LIMIT]: ec = makehash() cont = makehash() url_cont = makehash() ip_cont = makehash() dom_cont = makehash() file_context = makehash() res_dict = res res_tasks = res_dict['task'] res_page = res_dict['page'] if last_url == res_tasks['url']: continue human_readable = makehash() if 'url' in res_tasks: url = res_tasks['url'] human_readable['URL'] = url cont['URL'] = url url_cont['Data'] = url if 'domain' in res_page: domain = res_page['domain'] human_readable['Domain'] = domain cont['Domain'] = domain dom_cont['Name'] = domain if 'asn' in res_page: asn = res_page['asn'] cont['ASN'] = asn ip_cont['ASN'] = asn human_readable['ASN'] = asn if 'ip' in res_page: ip = res_page['ip'] cont['IP'] = ip ip_cont['Address'] = ip human_readable['IP'] = ip if '_id' in res_dict: scanID = res_dict['_id'] cont['ScanID'] = scanID human_readable['Scan ID'] = scanID if 'time' in res_tasks: scanDate = res_tasks['time'] cont['ScanDate'] = scanDate human_readable['Scan Date'] = scanDate if 'files' in res_dict: HUMAN_READBALE_HEADERS = ['URL', 'Domain', 'IP', 'ASN', 'Scan ID', 'Scan Date', 'File'] files = res_dict['files'][0] sha256 = files['sha256'] filename = files['filename'] filesize = files['filesize'] filetype = files['mimeType'] url = res_tasks['url'] human_readable['File']['Hash'] = sha256 cont['Hash'] = sha256 file_context['SHA256'] = sha256 human_readable['File']['Name'] = filename cont['FileName'] = filename file_context['File']['Name'] = filename human_readable['File']['Size'] = filesize cont['FileSize'] = filesize file_context['Size'] = filesize human_readable['File']['Type'] = filetype cont['FileType'] = filetype file_context['File']['Type'] = filetype file_context['File']['Hostname'] = url ec[outputPaths['file']] = file_context hr_md.append(human_readable) cont_array.append(cont) ip_array.append(ip_cont) url_array.append(url_cont) dom_array.append(dom_cont) # Storing last url in memory for comparison on next loop last_url = url ec = ({ 'URLScan(val.URL && val.URL == obj.URL)': cont_array, 'URL': url_array, 'IP': ip_array, 'Domain': dom_array }) demisto.results({ 'Type': entryTypes['note'], 'ContentsFormat': formats['markdown'], 'Contents': r, 'HumanReadable': tableToMarkdown('URLScan.io query results for {}'.format(raw_query), hr_md, HUMAN_READBALE_HEADERS, removeNull=True), 'EntryContext': ec })
def main(): args = demisto.args() # type: dict file_entry_id = '' if args.get('fileName') or args.get('lastZipFileInWarroom'): entries = demisto.executeCommand('getEntries', {}) for entry in entries: fn = demisto.get(entry, 'File') is_text = type(fn) in [unicode, str] is_correct_file = args.get('fileName', '').lower() == fn.lower() is_zip = fn.lower().endswith('.zip') if is_text and is_zip: if args.get('fileName') and is_correct_file: file_entry_id = entry['ID'] break if args.get('lastZipFileInWarroom'): file_entry_id = entry['ID'] if not file_entry_id: if args.get('fileName'): demisto.results({ 'Type': entryTypes['error'], 'ContentsFormat': formats['text'], 'Contents': args.get('fileName', '') + ' not such file in war room' }) if args.get('lastZipFileInWarroom'): demisto.results({ 'Type': entryTypes['error'], 'ContentsFormat': formats['text'], 'Contents': 'Not found zip file in war room' }) sys.exit(0) if 'entryID' in args: file_entry_id = args.get('entryID') # type: ignore if not file_entry_id: return_error( 'You must set entryID or fileName or lastZipFileInWarroom=true when executing Unzip script' ) res = demisto.executeCommand('getFilePath', {'id': file_entry_id}) if res[0]['Type'] == entryTypes['error']: demisto.results({ 'Type': entryTypes['error'], 'ContentsFormat': formats['text'], 'Contents': 'Failed to get the file path for entry: ' + file_entry_id }) sys.exit(0) file_path = res[0]['Contents']['path'] password = args.get('password', None) filenames = [] # remembering which files and dirs we currently have so we add them later as newly extracted files. excluded_files = [f for f in os.listdir('.') if isfile(f)] excluded_dirs = [d for d in os.listdir('.') if isdir(d)] # extracting the zip file process = Popen(["7z", "x", "-p{}".format(password), file_path], stdout=PIPE, stderr=PIPE) stdout, stderr = process.communicate() if stderr: return_error(str(stderr)) if 'Wrong password?' in stdout: demisto.debug(str(stdout)) return_error("Data Error in encrypted file. Wrong password?") # recursive call over the file system top down for root, directories, files in os.walk('.'): # removing the previously existing dirs from the search directories[:] = [d for d in directories if d not in excluded_dirs] for f in files: # skipping previously existing files and verifying that the current file is a file and # then adding it to the extracted files list if f not in excluded_files and isfile(os.path.join(root, f)): filenames.append(os.path.join(root, f)) if len(filenames) == 0: demisto.results({ 'Type': entryTypes['error'], 'ContentsFormat': formats['text'], 'Contents': 'Could not find files in archive' }) else: results = [] # extracted files can be in sub directories so we save the base names of # the files and also the full path of the file files_base_names = [ os.path.basename(file_path) for file_path in filenames ] # noqa[F812] files_dic = { file_path: os.path.basename(file_path) for file_path in filenames } for file_path, file_name in files_dic.items(): demisto.results(file_result_existing_file(file_path, file_name)) results.append({ 'Type': entryTypes['note'], 'ContentsFormat': formats['json'], 'Contents': { 'extractedFiles': files_base_names }, 'EntryContext': { 'ExtractedFiles': files_base_names, 'File(val.EntryID=="' + file_entry_id + '").Unzipped': True }, 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown('Extracted Files', [{ 'name': file_name, 'path': file_path } for file_path, file_name in files_dic.items()]) }) demisto.results(results)
def initiate_jit_command(client: MsClient, args: dict): resource_group_name = args.get("resource_group_name") asc_location = args.get("asc_location") policy_name = args.get("policy_name") vm_id = args.get("vmID") port = args.get("port") source_address = args.get("source_address") duration = args.get("duration") response = client.initiate_jit( resource_group_name, asc_location, policy_name, vm_id, port, source_address, duration, ) policy_id = f"/subscriptions/{client.subscription_id}/resourceGroups/{resource_group_name}/providers/" \ f"Microsoft.Security/locations/{asc_location}/jitNetworkAccessPolicies/{policy_name}" virtual_machines = response.get("virtualMachines") if virtual_machines and len(virtual_machines) > 0: machine = virtual_machines[0] port = machine.get("ports")[0] outputs = { "VmID": machine.get("id"), "PortNum": port.get("number"), "AllowedSourceAddress": port.get("allowedSourceAddressPrefix"), "EndTimeUtc": port.get("endTimeUtc"), "Status": port.get("status"), "Requestor": response.get("requestor"), "PolicyID": policy_id, } md = tableToMarkdown( "Azure Security Center - Initiate JIT Access Request", outputs, [ "VmID", "PortNum", "AllowedSourceAddress", "EndTimeUtc", "Status", "Requestor", ], removeNull=True, ) ec = { "AzureSecurityCenter.JITPolicy(val.ID && val.ID =" "== obj.{}).Initiate(val.endTimeUtc === obj.EndTimeUtc)".format( policy_id ): outputs } demisto.results( { "Type": entryTypes["note"], "Contents": response, "ContentsFormat": formats["json"], "ReadableContentsFormat": formats["markdown"], "HumanReadable": md, "EntryContext": ec, } )
def main(): ''' INSTANCE CONFIGURATION ''' SERVER_IP = demisto.params().get('server_ip') USERNAME = demisto.params().get('credentials')['identifier'] PASSWORD = demisto.params().get('credentials')['password'] DEFAULT_BASE_DN = demisto.params().get('base_dn') SECURE_CONNECTION = demisto.params().get('secure_connection') DEFAULT_PAGE_SIZE = int(demisto.params().get('page_size')) NTLM_AUTH = demisto.params().get('ntlm') UNSECURE = demisto.params().get('unsecure', False) PORT = demisto.params().get('port') if PORT: # port was configured, cast to int PORT = int(PORT) try: server = initialize_server(SERVER_IP, PORT, SECURE_CONNECTION, UNSECURE) except Exception as e: return_error(str(e)) return global conn if NTLM_AUTH: # intialize connection to LDAP server with NTLM authentication # user example: domain\user domain_user = SERVER_IP + '\\' + USERNAME if '\\' not in USERNAME else USERNAME conn = Connection(server, user=domain_user, password=PASSWORD, authentication=NTLM) else: # here username should be the user dn conn = Connection(server, user=USERNAME, password=PASSWORD) # bind operation is the “authenticate” operation. try: # open socket and bind to server if not conn.bind(): message = "Failed to bind to server. Please validate the credentials configured correctly.\n{}".format( json.dumps(conn.result)) demisto.info(message) return_error(message) return except Exception as e: exc_msg = str(e) demisto.info("Failed bind to: {}:{}. {}: {}".format( SERVER_IP, PORT, type(e), exc_msg + "\nTrace:\n{}".format(traceback.format_exc()))) message = "Failed to access LDAP server. Please validate the server host and port are configured correctly" if 'ssl wrapping error' in exc_msg: message = "Failed to access LDAP server. SSL error." if not UNSECURE: message += ' Try using: "Trust any certificate" option.' demisto.info(message) return_error(message) return demisto.info('Established connection with AD LDAP server') if not base_dn_verified(DEFAULT_BASE_DN): message = "Failed to verify the base DN configured for the instance.\n" \ "Last connection result: {}\n" \ "Last error from LDAP server: {}".format(json.dumps(conn.result), json.dumps(conn.last_error)) demisto.info(message) return_error(message) return demisto.info('Verfied base DN "{}"'.format(DEFAULT_BASE_DN)) ''' COMMAND EXECUTION ''' try: if demisto.command() == 'test-module': if conn.user == '': # Empty response means you have no authentication status on the server, so you are an anonymous user. raise Exception("Failed to authenticate user") demisto.results('ok') if demisto.command() == 'ad-search': free_search(DEFAULT_BASE_DN, DEFAULT_PAGE_SIZE) if demisto.command() == 'ad-expire-password': expire_user_password(DEFAULT_BASE_DN) if demisto.command() == 'ad-set-new-password': set_user_password(DEFAULT_BASE_DN) if demisto.command() == 'ad-unlock-account': unlock_account(DEFAULT_BASE_DN) if demisto.command() == 'ad-disable-account': disable_user(DEFAULT_BASE_DN) if demisto.command() == 'ad-enable-account': enable_user(DEFAULT_BASE_DN) if demisto.command() == 'ad-remove-from-group': remove_member_from_group(DEFAULT_BASE_DN) if demisto.command() == 'ad-add-to-group': add_member_to_group(DEFAULT_BASE_DN) if demisto.command() == 'ad-create-user': create_user() if demisto.command() == 'ad-delete-user': delete_user() if demisto.command() == 'ad-update-user': update_user(DEFAULT_BASE_DN) if demisto.command() == 'ad-modify-computer-ou': modify_computer_ou(DEFAULT_BASE_DN) if demisto.command() == 'ad-create-contact': create_contact() if demisto.command() == 'ad-update-contact': update_contact() if demisto.command() == 'ad-get-user': search_users(DEFAULT_BASE_DN, DEFAULT_PAGE_SIZE) if demisto.command() == 'ad-get-computer': search_computers(DEFAULT_BASE_DN, DEFAULT_PAGE_SIZE) if demisto.command() == 'ad-get-group-members': search_group_members(DEFAULT_BASE_DN, DEFAULT_PAGE_SIZE) except Exception as e: message = "{}\nLast connection result: {}\nLast error from LDAP server: {}".format( str(e), json.dumps(conn.result), conn.last_error) demisto.info(message) return_error(message) return finally: # disconnect and close the connection conn.unbind()
def main(): LOG('command is %s' % (demisto.command(),)) try: handle_proxy(proxy_param_name='useProxy') if demisto.command() == 'test-module': # This is the call made when pressing the integration test button. # disable-secrets-detection-start if check_file_behaviour( '10676cf66244cfa91567fbc1a937f4cb19438338b35b69d4bcc2cf0d3a44af5e'): # guardrails-disable-line # disable-secrets-detection-end demisto.results('ok') else: demisto.results('test failed') elif demisto.command() == 'vt-private-check-file-behaviour': demisto.results(check_file_behaviour_command()) elif demisto.command() == 'vt-private-get-domain-report': demisto.results(get_domain_report_command()) elif demisto.command() == 'vt-private-get-file-report': demisto.results(get_file_report_command()) elif demisto.command() == 'vt-private-get-url-report': demisto.results(get_url_report_command()) elif demisto.command() == 'vt-private-get-ip-report': demisto.results(get_ip_report_command()) elif demisto.command() == 'vt-private-search-file': demisto.results(search_file_command()) elif demisto.command() == 'vt-private-hash-communication': demisto.results(hash_communication_command()) elif demisto.command() == 'vt-private-download-file': demisto.results(download_file_command()) except Exception as e: return_error(str(e))
def get_insight_details(): """ Get insight details """ alert_id = demisto.getArg('insight-id') resp_json = req('GET', 'alert/' + alert_id, QUERY) ec = insight_to_readable(resp_json) details_md = tableToMarkdown('Insight Details:', [ec], [ 'Id', 'Name', 'Action', 'AssignedTo', 'Description', 'IpAddress', 'LastUpdated', 'LastUpdatedBy', 'Severity', 'InsightTime', 'WorkflowStatus' ]) entity_display = entity_to_readable(resp_json.get('asset_details')) entity_display.update({ 'IpAddress': demisto.get(resp_json['asset_details']['ip'], 'address') }) ec['EntityDetails'] = entity_display entity_display['Id'] = resp_json.get('id') entity_markdown = tableToMarkdown( 'Insight\'s Main Entity Details:', [entity_display], [ 'Id', 'EntityType', 'Hostname', 'Groups', 'FirstSeen', 'LastSeen', 'IpAddress', 'IsWhitelisted', 'RiskScore', 'Source' ]) related_assets_json = resp_json.get('related_assets') or [] results_assets_list = [] for rel_asset in related_assets_json: results_asset = to_readable( rel_asset, ['id', 'is_whitelisted', 'risk_score', 'source', 'asset_type'], {'asset_type': 'EntityType'}) if rel_asset.get('asset_type') == 'hostname': results_asset['Name'] = rel_asset.get('hostname') elif rel_asset.get('asset_type') == 'username': results_asset['Name'] = rel_asset.get('username') if demisto.get(rel_asset, 'ip.address'): results_asset['IpAddress'] = demisto.get(rel_asset, 'ip.address') results_assets_list.append(results_asset) ec['RelatedEntityList'] = results_assets_list rel_assets_md = tableToMarkdown('Related Entities:', results_assets_list, [ 'Id', 'EntityType', 'IpAddress', 'Name', 'IsWhitelisted', 'RiskScore', 'Source' ]) signal_list_json = resp_json.get('signals') or [] signal_list = [] threat_intel = 0 anomalies = 0 patterns = 0 for signal_item in signal_list_json: result_signal = signal_to_readable(signal_item) if result_signal['SourceType'] == 'threatintel': threat_intel += 1 elif result_signal['SourceType'] == 'rule': patterns += 1 elif result_signal['SourceType'] == 'anomaly': anomalies += 1 signal_list.append(result_signal) ec['SignalList'] = signal_list signals_md = tableToMarkdown( 'Related Signals:', signal_list, ['Id', 'Name', 'Description', 'Category', 'SourceType']) ec['SignalListMetadata'] = { 'Patterns': { 'Count': patterns }, 'Anomalies': { 'Count': anomalies }, 'ThreatIntel': { 'Count': threat_intel } } final_ec = {'Jask.Insight(val.Id === obj.Id)': ec} signal_metadata_md = tableToMarkdown( 'Signal Metadata:', [{ 'Pattern Count': patterns, 'Anomaly Count': anomalies, 'Threat Intel Count': threat_intel }], ['Pattern Count', 'Anomaly Count', 'Threat Intel Count']) combined_md = details_md + '\n\n' + entity_markdown + '\n\n' + rel_assets_md +\ '\n\n' + signals_md + '\n\n' + signal_metadata_md link = URL.replace('/api/', '/insight/') + alert_id md_link = "[" + link + "](" + link + ")" combined_md += '\n\n' + md_link demisto.results({ 'Type': entryTypes['note'], 'EntryContext': final_ec, 'HumanReadable': combined_md, 'Contents': resp_json, 'ContentsFormat': formats['json'] })
def search_group_members(default_base_dn, page_size): # this command is equivalent to ADGetGroupMembers script args = demisto.args() member_type = args.get('member-type') group_dn = args.get('group-dn') custome_attributes: List[str] = [] default_attributes = DEFAULT_PERSON_ATTRIBUTES if member_type == 'person' else DEFAULT_COMPUTER_ATTRIBUTES if args.get('attributes'): custome_attributes = args['attributes'].split(",") attributes = list(set(custome_attributes + default_attributes)) # neasted search query = "(&(objectCategory={})(objectClass=user)(memberOf:1.2.840.113556.1.4.1941:={}))".format( member_type, group_dn) entries = search_with_paging(query, default_base_dn, attributes=attributes, page_size=page_size) members = [{ 'dn': entry['dn'], 'category': member_type } for entry in entries['flat']] demisto_entry = { 'ContentsFormat': formats['json'], 'Type': entryTypes['note'], 'Contents': entries['raw'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown("Active Directory - Get Group Members", entries['flat']), 'EntryContext': { 'ActiveDirectory.Groups(obj.dn ==' + group_dn + ')': { 'dn': group_dn, 'members': members } } } if member_type == 'person': demisto_entry['EntryContext'][ 'ActiveDirectory.Users(obj.dn == val.dn)'] = entries['flat'] demisto_entry['EntryContext']['Account'] = [ account_entry(entry, custome_attributes) for entry in entries['flat'] ] else: demisto_entry['EntryContext'][ 'ActiveDirectory.Computers(obj.dn == val.dn)'] = entries['flat'] demisto_entry['EntryContext']['Endpoint'] = [ endpoint_entry(entry, custome_attributes) for entry in entries['flat'] ] demisto.results(demisto_entry)
def exabeam_timeline(): """ Returns session, triggered rules and events of a user """ res = http_request( 'GET', URL_UBA + 'user/%s/timeline/entities/all' % demisto.args()['username'], None) risk_score = 0 session = '' for entity in res.get('entities', []): if entity.get('tp') == 'session' and entity.get('rs', 0) > risk_score: risk_score = entity.get('rs', 0) session = entity.get('id') if session: session_info = http_request('GET', URL_UBA + 'session/%s/info' % session, None) si = session_info.get('sessionInfo') if not si: return_error('Unable to find session info') session_data = { 'Username': si.get('username'), 'RiskScore': si.get('riskScore'), 'InitialRiskScore': si.get('initialRiskScore'), 'NumOfReasons': si.get('numOfReasons'), 'LoginHost': si.get('loginHost'), 'Zones': ','.join(si.get('zones', [])), 'Assets': si.get('numOfAssets'), 'Events': si.get('numOfEvents'), 'SecurityEvents': si.get('numOfSecurityEvents') } md = tableToMarkdown( 'Session %s from %s to %s' % (session, convert_unix_to_date(si.get('startTime')), convert_unix_to_date(si.get('endTime'))), [session_data], [ 'Username', 'RiskScore', 'InitialRiskScore', 'NumOfReasons', 'LoginHost', 'Zones', 'Assets', 'Events', 'SecurityEvents' ]) triggered_rules_data = [{ 'ID': tr.get('ruleId'), 'Type': tr.get('ruleType'), 'Name': demisto.get(session_info, 'rules.%s.ruleName' % (tr.get('ruleId'))), 'EventID': tr.get('eventId'), 'SessionID': tr.get('sessionId'), 'Source': demisto.get( session_info, 'triggeredRuleEvents.%s.fields.source' % (tr.get('eventId'))), 'Domain': demisto.get( session_info, 'triggeredRuleEvents.%s.fields.domain' % (tr.get('eventId'))), 'Host': demisto.get( session_info, 'triggeredRuleEvents.%s.fields.host' % (tr.get('eventId'))), 'DestIP': demisto.get( session_info, 'triggeredRuleEvents.%s.fields.dest_ip' % (tr.get('eventId'))), 'EventType': demisto.get( session_info, 'triggeredRuleEvents.%s.fields.event_type' % (tr.get('eventId'))) } for tr in session_info.get('triggeredRules')] md += '\n' + tableToMarkdown('Triggered Rules', triggered_rules_data, [ 'ID', 'Type', 'Name', 'EventID', 'SessionID', 'EventType', 'Source', 'Domain', 'Host', 'DestIP' ]) session_data['TriggeredRules'] = triggered_rules_data events = http_request( 'GET', URL_UBA + 'timeline/events/start', { 'username': demisto.args()['username'], 'sequenceTypes': 'session', 'startSequenceType': 'session', 'startSequenceId': session, 'preferredNumberOfEvents': 200 }) events_data = [{ 'Type': ev.get('tp'), 'Count': ev.get('c'), 'Start': convert_unix_to_date(ev.get('ts')), 'End': convert_unix_to_date(ev.get('te')), 'Sources': [es.get('fields', {}).get('source') for es in ev.get('es')] } for ev in events.get('aggregatedEvents', [])] md += '\n' + tableToMarkdown('Timeline', events_data, ['Type', 'Count', 'Start', 'End']) session_data['Events'] = events_data demisto.results({ 'Type': entryTypes['note'], 'ContentsFormat': formats['json'], 'Contents': events, 'HumanReadable': md, 'EntryContext': { 'Exabeam.Timeline': session_data } }) else: demisto.results('No risk score exists for the given user')
demisto.results({ 'Type': entryTypes['note'], 'ContentsFormat': formats['json'], 'Contents': res, 'HumanReadable': md }) ''' EXECUTION ''' login() LOG('command is %s' % (demisto.command(), )) try: if demisto.command() == 'test-module': demisto.results('ok') elif demisto.command() == 'xb-users': exabeam_users() elif demisto.command() == 'xb-assets': exabeam_assets() elif demisto.command() == 'xb-sessions': exabeam_sessions() elif demisto.command() == 'xb-events': exabeam_events() elif demisto.command() == 'xb-anomalies': exabeam_anomalies()
def exabeam_user_info(): """ Returns user info """ username = demisto.args()['username'] res = http_request('GET', URL_UBA + 'user/%s/info' % username, None) if res.get('username'): u = { 'Username': res['username'], 'AccountNames': ','.join(res.get('accountNames', [])), 'Executive': res['isExecutive'], 'WatchList': res['isOnWatchlist'], 'Name': demisto.get(res, 'userInfo.info.fullName'), 'ID': demisto.get(res, 'userInfo.info.accountId'), 'Department': demisto.get(res, 'userInfo.info.department'), 'DN': demisto.get(res, 'userInfo.info.dn'), 'Email': demisto.get(res, 'userInfo.info.email'), 'Type': demisto.get(res, 'userInfo.info.employeeType'), 'Groups': demisto.get(res, 'userInfo.info.group'), 'SID': demisto.get(res, 'userInfo.info.sid'), 'Title': demisto.get(res, 'userInfo.info.title'), 'RiskScore': demisto.get(res, 'userInfo.riskScore'), 'AverageRiskScore': demisto.get(res, 'userInfo.averageRiskScore'), 'Labels': demisto.get(res, 'userInfo.labels'), 'FirstSeen': convert_unix_to_date(demisto.get(res, 'userInfo.firstSeen')), 'LastSeen': convert_unix_to_date(demisto.get(res, 'userInfo.lastSeen')), 'LastSessionID': demisto.get(res, 'userInfo.lastSessionId'), 'PastScores': ','.join(map(str, demisto.get(res, 'userInfo.pastScores'))) } md = tableToMarkdown('User info', [u], [ 'Name', 'Username', 'Email', 'Department', 'DN', 'Groups', 'Title', 'RiskScore', 'AverageRiskScore', 'Executive', 'WatchList', 'AccountNames', 'ID', 'Type', 'SID', 'Labels', 'FirstSeen', 'LastSeen', 'LastSessionID', 'PastScores' ]) if demisto.get(res, 'userInfo.info.photo'): md += '\n![Photo](data:image/png;base64,' + demisto.get( res, 'userInfo.info.photo') + ')\n' # Let's get the sessions as well notable_res = http_request('GET', URL_UBA + 'users/notable', { 'numberOfResults': 100, 'unit': 'd', 'num': 7 }) if notable_res.get('users'): for un in notable_res['users']: if demisto.get(un, 'user.username') == username: u['NotableList'] = True md += '\n## User is on the notable list\n' notable_session_ids = un.get('notableSessionIds', []) if notable_session_ids: u['NoteableSessionIDs'] = notable_session_ids session_res = http_request( 'GET', URL_UBA + 'user/%s/riskTimeline/data' % username, { 'unit': 'd', 'num': 7, 'endTimeSequenceType': 'session', 'endTimeSequenceId': notable_session_ids[0] }) if session_res.get('sessions'): md += '\n' + tableToMarkdown( 'Sessions', session_res['sessions']) demisto.results({ 'Type': entryTypes['note'], 'ContentsFormat': formats['json'], 'Contents': res, 'HumanReadable': md, 'EntryContext': { 'Account(val.Email && val.Email === obj.Email || val.ID && val.ID === obj.ID ||' ' val.Username && val.Username === obj.Username)': u } }) else: demisto.results('No username with [' + username + '] found')
indicators_data_list = [] fetched_iocs = demisto.searchIndicators(query=indicator_query, page=page, size=limit).get('iocs') for indicator in fetched_iocs: indicators_values_list.append(indicator['value']) indicators_data_list.append({ 'Value': indicator['value'], 'Type': indicator['indicator_type'] }) return indicators_values_list, indicators_data_list # Command selector try: LOG('Command being called is {command}'.format(command=demisto.command())) if demisto.command() == 'test-module': demisto.results(test_module()) elif demisto.command() == 'fetch-incidents': demisto.incidents(fetch_incidents()) elif demisto.command() in ['qradar-offenses', 'qr-offenses']: demisto.results(get_offenses_command()) elif demisto.command() == 'qradar-offense-by-id': demisto.results(get_offense_by_id_command()) elif demisto.command() in ['qradar-update-offense', 'qr-update-offense']: demisto.results(update_offense_command()) elif demisto.command() in ['qradar-searches', 'qr-searches']: demisto.results(search_command()) elif demisto.command() in ['qradar-get-search', 'qr-get-search']: demisto.results(get_search_command()) elif demisto.command() in ['qradar-get-search-results', 'qr-get-search-results']: demisto.results(get_search_results_command()) elif demisto.command() in ['qradar-get-assets', 'qr-get-assets']:
START = demisto.args()["start"] LIMIT_DATA = int(demisto.args()["limitData"]) if "allowedContentTypes" not in demisto.args(): ALLOWED_CONTENT_TYPES = ("text", "application/json", "multipart/form-data", "application/xml", "application/xhtml+xml", "application/ld+json", "application/javascript", "multipart/alternative", "application/x-www-form-urlencoded") else: ALLOWED_CONTENT_TYPES = tuple(demisto.args()["allowedContentTypes"].split(",")) # type: ignore # Work on the pcap file and return a result http_flows = get_http_flows(pcap_file_path_in_container) # Cut results according to the user args (times 2, because we are working on pairs of requests and responses). if START: http_flows = http_flows[int(START):] if LIMIT: http_flows = http_flows[:int(LIMIT)] # Format and get output representation of the flows formatted_http_flows = format_http_flows(http_flows, PYSHARK_RES_TO_DEMISTO, LIMIT_DATA, ALLOWED_CONTENT_TYPES) markdown_output = get_markdown_output(formatted_http_flows) context_output = formatted_http_flows # Profit, send the output demisto.results({"Type": entryTypes["note"], "ContentsFormat": formats["markdown"], "Contents": markdown_output, "EntryContext": {"PcapHTTPFlows": context_output}})
def poll_uri(client): uri = demisto.args().get('uri') demisto.results(requests.get(uri, verify=client.use_ssl).status_code)
else: return fileResult( '%s_report.%s' % ( info.get('filename', webid), rsc_type, ), res, entryTypes['entryInfoFile']) ''' EXECUTION CODE ''' LOG('command is %s' % (demisto.command(), )) try: handle_proxy() if demisto.command() in ['test-module', 'joe-is-online']: # This is the call made when pressing the integration test button. if is_online(): demisto.results('ok') else: demisto.results('not online') elif demisto.command() == 'joe-list-analysis': demisto.results(list_analysis()) elif demisto.command() == 'joe-analysis-info': demisto.results(analysis_info()) elif demisto.command() == 'joe-analysis-submit-url': demisto.results(analyse_url()) elif demisto.command() == 'joe-detonate-url': demisto.args()['should_wait'] = 'True' demisto.results(analyse_url()) elif demisto.command() == 'joe-analysis-submit-sample': demisto.results(analyse_sample()) elif demisto.command() == 'joe-detonate-file': demisto.args()['should_wait'] = 'True'
def test_module(client): """ If we got here, the instance is working without any error """ if client.topics is not None: demisto.results('ok')
# maintaining queue of 100 last seen alert ids if len(known_ids) >= 100: known_ids.pop(0) known_ids.append(current_alert_id) demisto.setLastRun({'ids': known_ids}) demisto.incidents(final_alerts) ''' EXECUTION CODE ''' try: if demisto.command() == 'test-module': # This is the call made when pressing the integration test button. if list_alerts_command(): demisto.results('ok') else: demisto.results('test failed') elif demisto.command() == 'sw-show-alert': demisto.results(show_alert_command()) elif demisto.command() == 'sw-update-alert': demisto.results(update_alert_command()) elif demisto.command() == 'sw-list-alerts': demisto.results(list_alerts_command()) elif demisto.command() == 'sw-block-domain-or-ip': demisto.results(block_domain_command()) elif demisto.command() == 'sw-unblock-domain': demisto.results(unblock_domain_command()) elif demisto.command() == 'sw-list-blocked-domains': demisto.results(list_blocked_domains_command()) elif demisto.command() == 'sw-list-observations':
def test_func(): headers = {'Content-Type': "application/json"} try: if USERNAME: res = requests.get(SERVER, auth=(USERNAME, PASSWORD), verify=INSECURE, headers=headers) else: res = requests.get(SERVER, verify=INSECURE, headers=headers) if res.status_code >= 400: try: res.raise_for_status() except requests.exceptions.HTTPError as e: if HTTP_ERRORS.get(res.status_code) is not None: # if it is a known http error - get the message form the preset messages return_error("Failed to connect. " "The following error occurred: {}".format( HTTP_ERRORS.get(res.status_code))) else: # if it is unknown error - get the message from the error itself return_error( "Failed to connect. The following error occurred: {}". format(str(e))) except requests.exceptions.RequestException as e: return_error( "Failed to connect. Check Server URL field and port number.\nError message: " + str(e)) if demisto.params().get('isFetch'): # check the existence of all necessary fields for fetch fetch_params_check() try: # build general Elasticsearch class es = elasticsearch_builder() # test if FETCH_INDEX exists test_general_query(es) # test if TIME_FIELD in index exists response = test_time_field_query(es) # try to get response from FETCH_QUERY - if exists check the time field from that query temp = test_fetch_query(es) if temp: response = temp # get the value in the time field hit_date = str( response.get('hits', {}).get('hits')[0].get('_source').get( str(TIME_FIELD))) # if not a timestamp test the conversion to datetime object if 'Timestamp' not in TIME_METHOD: datetime.strptime(hit_date, TIME_FORMAT) # test timestamp format and conversion to date else: test_timestamp_format(hit_date) timestamp_to_date(hit_date) except ValueError as e: return_error("Inserted time format is incorrect.\n" + str(e) + '\n' + TIME_FIELD + ' fetched: ' + hit_date) demisto.results('ok')
def main(): params = demisto.params() aws_default_region = params.get('defaultRegion') aws_role_arn = params.get('roleArn') aws_role_session_name = params.get('roleSessionName') aws_role_session_duration = params.get('sessionDuration') aws_role_policy = None aws_access_key_id = params.get('access_key') aws_secret_access_key = params.get('secret_key') aws_gd_severity = params.get('gs_severity', '') verify_certificate = not params.get('insecure', True) timeout = params.get('timeout') or 1 retries = params.get('retries') or 5 try: validate_params(aws_default_region, aws_role_arn, aws_role_session_name, aws_access_key_id, aws_secret_access_key) aws_client = AWSClient(aws_default_region, aws_role_arn, aws_role_session_name, aws_role_session_duration, aws_role_policy, aws_access_key_id, aws_secret_access_key, verify_certificate, timeout, retries) client = aws_client.aws_session(service=SERVICE) # The command demisto.command() holds the command sent from the user. if demisto.command() == 'test-module': # This is the call made when pressing the integration test button. result = test_function(client) if demisto.command() == 'aws-gd-create-detector': result = create_detector(client, demisto.args()) if demisto.command() == 'aws-gd-delete-detector': result = delete_detector(client, demisto.args()) if demisto.command() == 'aws-gd-get-detector': result = get_detector(client, demisto.args()) if demisto.command() == 'aws-gd-update-detector': result = update_detector(client, demisto.args()) if demisto.command() == 'aws-gd-create-ip-set': result = create_ip_set(client, demisto.args()) if demisto.command() == 'aws-gd-delete-ip-set': result = delete_ip_set(client, demisto.args()) if demisto.command() == 'aws-gd-list-detectors': result = list_detectors(client, demisto.args()) if demisto.command() == 'aws-gd-update-ip-set': result = update_ip_set(client, demisto.args()) if demisto.command() == 'aws-gd-get-ip-set': result = get_ip_set(client, demisto.args()) if demisto.command() == 'aws-gd-list-ip-sets': result = list_ip_sets(client, demisto.args()) if demisto.command() == 'aws-gd-create-threatintel-set': result = create_threat_intel_set(client, demisto.args()) if demisto.command() == 'aws-gd-delete-threatintel-set': result = delete_threat_intel_set(client, demisto.args()) if demisto.command() == 'aws-gd-get-threatintel-set': result = get_threat_intel_set(client, demisto.args()) if demisto.command() == 'aws-gd-list-threatintel-sets': result = list_threat_intel_sets(client, demisto.args()) if demisto.command() == 'aws-gd-update-threatintel-set': result = update_threat_intel_set(client, demisto.args()) if demisto.command() == 'aws-gd-list-findings': result = list_findings(client, demisto.args()) if demisto.command() == 'aws-gd-get-findings': result = get_findings(client, demisto.args()) if demisto.command() == 'aws-gd-create-sample-findings': result = create_sample_findings(client, demisto.args()) if demisto.command() == 'aws-gd-archive-findings': result = archive_findings(client, demisto.args()) if demisto.command() == 'aws-gd-unarchive-findings': result = unarchive_findings(client, demisto.args()) if demisto.command() == 'aws-gd-update-findings-feedback': result = update_findings_feedback(client, demisto.args()) if demisto.command() == 'aws-gd-list-members': result = list_members(client, demisto.args()) if demisto.command() == 'aws-gd-get-members': result = get_members(client, demisto.args()) if demisto.command() == 'fetch-incidents': fetch_incidents(client, aws_gd_severity) sys.exit(0) demisto.results(result) sys.exit(0) except Exception as e: return_error( 'Error has occurred in the AWS GuardDuty Integration: {error}\n {message}' .format(error=type(e), message=e.message))
def create_user(): assert conn is not None args = demisto.args() object_classes = ["top", "person", "organizationalPerson", "user"] user_dn = args.get('user-dn') username = args.get("username") password = args.get("password") custome_attributes = args.get('custom-attributes') attributes = {"samAccountName": username} # set common user attributes if args.get('display-name'): attributes['displayName'] = args['display-name'] if args.get('description'): attributes['description'] = args['description'] if args.get('email'): attributes['mail'] = args['email'] if args.get('telephone-number'): attributes['telephoneNumber'] = args['telephone-number'] if args.get('title'): attributes['title'] = args['title'] # set user custome attributes if custome_attributes: try: custome_attributes = json.loads(custome_attributes) except Exception as e: demisto.info(str(e)) raise Exception( "Failed to parse custom attributes argument. Please see an example of this argument in the description." ) for attribute_name, attribute_value in custome_attributes.items(): # can run default attribute stting attributes[attribute_name] = attribute_value # add user success = conn.add(user_dn, object_classes, attributes) if not success: raise Exception("Failed to create user") # set user password success = conn.extend.microsoft.modify_password(user_dn, password) if not success: raise Exception("Failed to reset user password") # enable user and expire password modification = { # enable user 'userAccountControl': [('MODIFY_REPLACE', NORMAL_ACCOUNT)], # set to 0, to force password change on next login "pwdLastSet": [('MODIFY_REPLACE', "0")] } modify_object(user_dn, modification) demisto_entry = { 'ContentsFormat': formats['text'], 'Type': entryTypes['note'], 'Contents': "Created user with DN: {}".format(user_dn) } demisto.results(demisto_entry)
def get_ipp_command(client: MsClient, args: dict): """Getting Internet Presence Provider information Args: client: args (dict): usually demisto.args() """ policy_name = args.get("policy_name") management_group = args.get("management_group") policy = client.get_ipp(policy_name, management_group) properties = policy.get("properties") labels = properties.get("labels") if properties and isinstance(labels, dict): # Basic Property table labels = ", ".join( [ (str(label.get("displayName")) + str(label.get("enabled"))) for label in labels.values() ] ) basic_table_output = [ {"Name": policy.get("name"), "Labels": labels, "ID": policy.get("id")} ] md = tableToMarkdown( "Azure Security Center - Get Information Protection Policy - Basic Property", basic_table_output, ["Name", "Labels", "ID"], removeNull=True, ) ec = { "AzureSecurityCenter.InformationProtectionPolicy(val.ID && val.ID === obj.ID)": basic_table_output } basic_table_entry = { "Type": entryTypes["note"], "Contents": policy, "ContentsFormat": formats["json"], "ReadableContentsFormat": formats["markdown"], "HumanReadable": md, "EntryContext": ec, } # Information Type table info_type_table_output = list() for information_type_data in properties.get("informationTypes").values(): keywords = ", ".join( [(str(keyword.get("displayName")) + str(keyword.get("custom")) + str(keyword.get("canBeNumeric"))) for keyword in information_type_data.get("keywords", [])]) info_type_table_output.append( { "DisplayName": information_type_data.get("displayname"), "Enabled": information_type_data("enabled"), "Custom": information_type_data("custom"), "Keywords": keywords, "RecommendedLabelID": information_type_data("recommendedLabelId"), } ) md = tableToMarkdown( "Azure Security Center - Get Information Protection Policy - Information Types", info_type_table_output, ["DisplayName", "Enabled", "Custom", "Keywords", "RecommendedLabelID"], removeNull=True, ) info_type_table_entry = { "Type": entryTypes["note"], "Contents": properties.get("informationTypes"), "ContentsFormat": formats["json"], "ReadableContentsFormat": formats["markdown"], "HumanReadable": md, } demisto.results([basic_table_entry, info_type_table_entry]) else: demisto.results("No properties found in {}".format(management_group))
def search_computers(default_base_dn, page_size): # this command is equivalent to ADGetComputer script args = demisto.args() attributes: List[str] = [] custome_attributes: List[str] = [] # default query - list all users (computer category) query = "(&(objectClass=user)(objectCategory=computer))" # query by user DN if args.get('dn'): query = "(&(objectClass=user)(objectCategory=computer)(dn={}))".format( args['dn']) # query by name if args.get('name'): query = "(&(objectClass=user)(objectCategory=computer)(name={}))".format( args['name']) # query by custom object attribute if args.get('custom-field-type'): if not args.get('custom-field-data'): raise Exception( 'Please specify "custom-field-data" as well when quering by "custom-field-type"' ) query = "(&(objectClass=user)(objectCategory=computer)({}={}))".format( args['custom-field-type'], args['ustom-field-data']) if args.get('attributes'): custome_attributes = args['attributes'].split(",") attributes = list(set(custome_attributes + DEFAULT_COMPUTER_ATTRIBUTES)) entries = search_with_paging(query, default_base_dn, attributes=attributes, page_size=page_size) endpoints = [ endpoint_entry(entry, custome_attributes) for entry in entries['flat'] ] demisto_entry = { 'ContentsFormat': formats['json'], 'Type': entryTypes['note'], 'Contents': entries['raw'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown("Active Directory - Get Computers", entries['flat']), 'EntryContext': { 'ActiveDirectory.Computers(obj.dn == val.dn)': entries['flat'], # 'backward compatability' with ADGetComputer script 'Endpoint(obj.ID == val.ID)': endpoints } } demisto.results(demisto_entry)
def get_alert_command(client: MsClient, args: dict): """Getting specified alert from API Args args (dict): dictionary containing commands args """ resource_group_name = args.get("resource_group_name") asc_location = args.get("asc_location") alert_id = args.get("alert_id") alert = client.get_alert(resource_group_name, asc_location, alert_id) final_output = list() # Basic Property Table properties = alert.get("properties") if properties: basic_table_output = [ { "DisplayName": properties.get("alertDisplayName"), "CompromisedEntity": properties.get("compromisedEntity"), "Description": properties.get("description"), "DetectedTime": properties.get("detectedTimeUtc"), "ReportedTime": properties.get("reportedTimeUtc"), "ReportedSeverity": properties.get("reportedSeverity"), "ConfidenceScore": properties.get("confidenceScore", "None"), "State": properties.get("state"), "ActionTaken": properties.get("actionTaken"), "CanBeInvestigated": properties.get("canBeInvestigated"), "RemediationSteps": properties.get("remediationSteps"), "VendorName": properties.get("vendorName"), "AssociatedResource": properties.get("associatedResource"), "AlertName": properties.get("alertName"), "InstanceID": properties.get("instanceId", "None"), "ID": alert.get("name"), "ExtendedProperties": properties.get("extendedProperties"), "Entities": properties.get("entities"), "SubscriptionID": properties.get("subscriptionId"), } ] md = tableToMarkdown( "Azure Security Center - Get Alert - Basic Property", basic_table_output, [ "DisplayName", "CompromisedEntity", "Description", "DetectedTime", "ReportedTime", "ReportedSeverity", "ConfidenceScore", "State", "ActionTaken", "CanBeInvestigated", "RemediationSteps", "VendorName", "AssociatedResource", "AlertName", "InstanceID", "ID"], removeNull=True) ec = {"AzureSecurityCenter.Alert(val.ID && val.ID === obj.ID)": basic_table_output} basic_table_entry = { "Type": entryTypes["note"], "Contents": alert, "ContentsFormat": formats["json"], "ReadableContentsFormat": formats["markdown"], "HumanReadable": md, "EntryContext": ec, } final_output.append(basic_table_entry) # Extended Properties Table if ( alert.get("properties") and alert.get("properties") and alert.get("properties").get("extendedProperties") ): extended_properties = dict() properties = alert.get("properties") if isinstance(properties.get("extendedProperties"), dict): for key, value in alert["properties"]["extendedProperties"].items(): extended_properties[normalize_context_key(key)] = value extended_table_entry = { "Type": entryTypes["note"], "Contents": alert["properties"]["extendedProperties"], "ContentsFormat": formats["json"], "ReadableContentsFormat": formats["markdown"], "HumanReadable": tableToMarkdown( "Azure Security Center - Get Alert - Extended Property", extended_properties, removeNull=True, ), } final_output.append(extended_table_entry) # Entities Table entities = properties.get("entities") if entities: if isinstance(entities, dict): entities_table_output = list() for entity in entities: entities_table_output.append( { "Content": ast.literal_eval(str(entity)), "Type": entity["type"], } ) md = tableToMarkdown( "Azure Security Center - Get Alert - Entity", entities_table_output, removeNull=True, ) entities_table_entry = { "Type": entryTypes["note"], "Contents": alert.get("properties").get("entities"), "ContentsFormat": formats["json"], "ReadableContentsFormat": formats["markdown"], "HumanReadable": md, } final_output.append(entities_table_entry) demisto.results(final_output)
def search_users(default_base_dn, page_size): # this command is equivalant to script ADGetUser # will preform a custom search to find users by a specific (one) attribute specified by the user args = demisto.args() attributes: List[str] = [] custom_attributes: List[str] = [] # zero is actually no limitation limit = int(args.get('limit', '0')) # default query - list all users query = "(&(objectClass=User)(objectCategory=person))" # query by user DN if args.get('dn'): query = "(&(objectClass=User)(objectCategory=person)(distinguishedName={}))".format( args['dn']) # query by name if args.get('name'): query = "(&(objectClass=User)(objectCategory=person)(cn={}))".format( args['name']) # query by email if args.get('email'): query = "(&(objectClass=User)(objectCategory=person)(mail={}))".format( args['email']) # query by sAMAccountName if args.get('username'): query = "(&(objectClass=User)(objectCategory=person)(sAMAccountName={}))".format( args['username']) # query by custom object attribute if args.get('custom-field-type'): if not args.get('custom-field-data'): raise Exception( 'Please specify "custom-field-data" as well when quering by "custom-field-type"' ) query = "(&(objectClass=User)(objectCategory=person)({}={}))".format( args['custom-field-type'], args['custom-field-data']) if args.get('attributes'): custom_attributes = args['attributes'].split(",") attributes = list(set(custom_attributes + DEFAULT_PERSON_ATTRIBUTES)) entries = search_with_paging(query, default_base_dn, attributes=attributes, size_limit=limit, page_size=page_size) accounts = [ account_entry(entry, custom_attributes) for entry in entries['flat'] ] if args.get('user-account-control-out', '') == 'true': # display a literal translation of the numeric account control flag for i, user in enumerate(entries['flat']): flag_no = user.get('userAccountControl')[0] entries['flat'][i][ 'userAccountControl'] = COOMON_ACCOUNT_CONTROL_FLAGS.get( flag_no) or flag_no demisto_entry = { 'ContentsFormat': formats['json'], 'Type': entryTypes['note'], 'Contents': entries['raw'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown("Active Directory - Get Users", entries['flat']), 'EntryContext': { 'ActiveDirectory.Users(obj.dn == val.dn)': entries['flat'], # 'backward compatability' with ADGetUser script 'Account(obj.ID == val.ID)': accounts } } demisto.results(demisto_entry)
def main(): params: dict = demisto.params() server = params.get('server_url', '').rstrip('/') + '/' tenant = params.get('tenant_id') auth_and_token_url = params.get('auth_id', '') enc_key = params.get('enc_key') use_ssl = not params.get('unsecure', False) self_deployed: bool = params.get('self_deployed', False) proxy = params.get('proxy', False) subscription_id = demisto.args().get("subscription_id") or params.get("default_sub_id") ok_codes = (200, 201, 202, 204) try: if not subscription_id: raise Exception("A subscription ID must be provided.") client = MsClient(tenant_id=tenant, auth_id=auth_and_token_url, enc_key=enc_key, app_name=APP_NAME, proxy=proxy, server=server, verify=use_ssl, self_deployed=self_deployed, subscription_id=subscription_id, ok_codes=ok_codes) if demisto.command() == "test-module": # If the command will fail, error will be thrown from the request itself client.list_locations() demisto.results("ok") elif demisto.command() == "azure-sc-get-alert": get_alert_command(client, demisto.args()) elif demisto.command() == "azure-sc-list-alert": return_outputs(*list_alerts_command(client, demisto.args())) elif demisto.command() == "azure-sc-update-alert": return_outputs(*update_alert_command(client, demisto.args())) elif demisto.command() == "azure-sc-list-location": return_outputs(*list_locations_command(client)) elif demisto.command() == "azure-sc-update-atp": return_outputs(*update_atp_command(client, demisto.args())) elif demisto.command() == "azure-sc-get-atp": return_outputs(*get_atp_command(client, demisto.args())) elif demisto.command() == "azure-sc-update-aps": return_outputs(*update_aps_command(client, demisto.args())) elif demisto.command() == "azure-sc-list-aps": return_outputs(*list_aps_command(client)) elif demisto.command() == "azure-sc-get-aps": return_outputs(*get_aps_command(client, demisto.args())) elif demisto.command() == "azure-sc-list-ipp": list_ipp_command(client, demisto.args()) elif demisto.command() == "azure-sc-get-ipp": get_ipp_command(client, demisto.args()) elif demisto.command() == "azure-sc-list-jit": return_outputs(*list_jit_command(client, demisto.args())) elif demisto.command() == "azure-sc-get-jit": get_jit_command(client, demisto.args()) elif demisto.command() == "azure-sc-initiate-jit": initiate_jit_command(client, demisto.args()) elif demisto.command() == "azure-sc-delete-jit": delete_jit_command(client, demisto.args()) elif demisto.command() == "azure-sc-list-storage": return_outputs(*list_sc_storage_command(client)) elif demisto.command() == "azure-list-subscriptions": return_outputs(*list_sc_subscriptions_command(client)) except Exception as err: LOG(str(err)) LOG.print_log() return_error(str(err))
def export_pcap_command(client, args): tds_analysis_id = drop_prefix(args.get('tds_analysis_id')) pcap = client.export_pcap(tds_analysis_id) demisto.results(fileResult(filename='dump.pcap', data=pcap))
def http_request(method, params): r = requests.Response if method is 'GET': r = requests.get(BASE_URL + "/" + URL_SUFFIX, params=params, verify=SECURE) elif method is 'POST': if not API_KEY: headers = { 'Content-Type': 'application/json', 'Accept': 'application/json' } else: headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'X-FunTranslations-Api-Secret': API_KEY } r = requests.post(BASE_URL + "/" + URL_SUFFIX, params=params, headers=headers, verify=SECURE) if r.status_code is not 200: return_error('Error in API call [%d] - %s' % (r.status_code, r.reason)) json_result = json.loads(xml2json(str(r.text))) # handle non success if json_result['response']['@status'] != 'success': if 'msg' in json_result['response'] and 'line' in json_result[ 'response']['msg']: # catch non existing object error and display a meaningful message if json_result['response']['msg']['line'] == 'No such node': raise Exception( 'Object was not found, verify that the name is correct and that the instance was committed.' ) # catch urlfiltering error and display a meaningful message elif str(json_result['response']['msg']['line']).find( 'test -> url') != -1: raise Exception( 'The URL filtering license is either expired or not active.' ' Please contact your PAN-OS representative.') # catch non valid jobID errors and display a meaningful message elif isinstance(json_result['response']['msg']['line'], str) and \ json_result['response']['msg']['line'].find('job') != -1 and \ (json_result['response']['msg']['line'].find('not found') != -1 or json_result['response']['msg']['line'].find('No such query job')) != -1: raise Exception('Invalid Job ID error: ' + json_result['response']['msg']['line']) # catch already at the top/bottom error for rules and return this as an entry.note elif str(json_result['response']['msg']['line']).find( 'already at the') != -1: demisto.results('Rule ' + str(json_result['response']['msg']['line'])) sys.exit(0) # catch already registered ip tags and return this as an entry.note elif str(json_result['response']['msg']['line']).find( 'already exists, ignore') != -1: if isinstance( json_result['response']['msg']['line']['uid-response'] ['payload']['register']['entry'], list): ips = [ o['@ip'] for o in json_result['response']['msg']['line'] ['uid-response']['payload']['register']['entry'] ] else: ips = json_result['response']['msg']['line'][ 'uid-response']['payload']['register']['entry']['@ip'] demisto.results( 'IP ' + str(ips) + ' already exist in the tag. All submitted IPs were not registered to the tag.' ) sys.exit(0) # catch timed out log queries and return this as an entry.note elif str(json_result['response']['msg']['line']).find( 'Query timed out') != -1: demisto.results( str(json_result['response']['msg']['line']) + '. Rerun the query.') sys.exit(0) if '@code' in json_result['response']: raise Exception('Request Failed.\nStatus code: ' + str(json_result['response']['@code']) + '\nWith message: ' + str(json_result['response']['msg']['line'])) else: raise Exception('Request Failed.\n' + str(json_result['response'])) # handle @code if 'response' in json_result and '@code' in json_result['response']: if json_result['response']['@code'] not in ['19', '20']: # error code non exist in dict and not of success if 'msg' in json_result['response']: raise Exception('Request Failed.\nStatus code: ' + str(json_result['response']['@code']) + '\nWith message: ' + str(json_result['response']['msg'])) else: raise Exception('Request Failed.\n' + str(json_result['response'])) return json_result['response']['result']
tableToMarkdown("AbuseIPDB report categories", categories, removeNull=True), 'EntryContext': { 'AbuseIPDB.Categories(val && val == obj)': createContext(categories, removeNull=True), } } return entry try: if demisto.command() == 'test-module': # Tests connectivity and credentails on login test_module() elif demisto.command() == 'ip': demisto.results(check_ip_command(**demisto.args())) elif demisto.command() == 'abuseipdb-check-cidr-block': demisto.results(check_block_command(**demisto.args())) elif demisto.command() == 'abuseipdb-report-ip': demisto.results(report_ip_command(**demisto.args())) elif demisto.command() == 'abuseipdb-get-blacklist': demisto.results(get_blacklist_command(**demisto.args())) elif demisto.command() == 'abuseipdb-get-categories': demisto.results( get_categories_command(**demisto.args())) # type:ignore except Exception as e: LOG.print_log() return_error(e.message)
# }, # { # 'Type': entryTypes['note'], # 'Contents': { # 'events': events, # 'sources': sources, # 'location': location, # 'domains': domains, # 'urls': urls, # 'asn': asn # }, # 'HumanReadable': markdown, # 'EntryContext': context, # 'ContentsFormat': formats['json'] # }] ''' EXECUTION CODE ''' try: command = demisto.command() if command == 'test-module': demisto.results( 'Cymon has been Deprecated and is no longer in service. Please delete the instance.' ) elif command == 'ip': cymon_says() elif command == 'domain': cymon_says() except Exception, e: raise