def feed_related_indicator(args) -> CommandResults: indicator = args['indicator'] feed_related_indicators = indicator.get('CustomFields', {}).get('feedrelatedindicators', []) ioc = list(filter(lambda x: x.get('value'), feed_related_indicators)) ioc_value = ioc[0].get('value') if ioc else '' content = [] results = demisto.searchIndicators(value=ioc_value).get('iocs', []) urls = demisto.demistoUrls() server_url = urls.get('server', '') if results: ioc_id = results[0].get('id') for item in feed_related_indicators: content.append({ 'Value': f"[{item.get('value')}]({server_url}/indicator/{ioc_id})" if item.get('value') else '', 'Type': item.get('type'), 'Description': f"[{item.get('description')}]({item.get('description')})\n\n" }) else: # In case that no related indicators were found, return the table without the link. for item in feed_related_indicators: content.append({ 'Value': item.get('value', ''), 'Type': item.get('type'), 'Description': f"[{item.get('description')}]({item.get('description')})\n\n" }) output = tableToMarkdown('', content, ['Type', 'Value', 'Description'], removeNull=True) return CommandResults(readable_output=output)
def parse_investigations_to_table(investigations, is_table_result): data: List = [] widget_table = {"total": len(investigations)} urls = demisto.demistoUrls() server_url = urls.get('server', '') for investigation in investigations.keys(): full_size = investigations[investigation].get('leafSize').split(' ') db_name = investigations[investigation].get('Date') size = float(full_size[0]) if size >= 1.0 and full_size[1] == 'MB': if db_name.isdigit(): inv_id = investigation.split('-')[1] inv_link = f"[{inv_id}]({os.path.join(server_url, '#', 'incident', inv_id)})" date = db_name[:2] + "-" + db_name[2:] else: inv_id = "-".join(investigation.split('-')[1:]) inv_link = f"[playground]({os.path.join(server_url, '#', 'WarRoom', 'playground')})" date = "" inv_link = inv_id if is_table_result else inv_link data.append({ "IncidentID": inv_link, "Size(MB)": int(size) if size == int(size) else size, "AmountOfEntries": investigations[investigation].get('keyN'), "Date": date }) widget_table['data'] = sorted(data, key=itemgetter('Size(MB)'), reverse=True) # type: ignore return widget_table
def search_command(client, args): search = args.get('search') demisto_urls = demisto.demistoUrls() indicator_url = demisto_urls.get('server') + "/#/indicator/" sensitive = True if args.get('casesensitive') == 'True' else False return_list_md: List[Dict] = list() entries = list() all_indicators: List[Dict] = list() page = 0 size = 1000 raw_data = demisto.searchIndicators(query=f'type:"{client.indicatorType}"', page=page, size=size) while len(raw_data.get('iocs', [])) > 0: all_indicators.extend(raw_data.get('iocs', [])) page += 1 raw_data = demisto.searchIndicators( query=f'type:"{client.indicatorType}"', page=page, size=size) for indicator in all_indicators: custom_fields = indicator.get('CustomFields', {}) for v in custom_fields.values(): if type(v) != str: continue if sensitive: if search in v and custom_fields.get('mitrename') not in [ x.get('mitrename') for x in return_list_md ]: return_list_md.append({ 'mitrename': custom_fields.get('mitrename'), 'Name': f"[{custom_fields.get('mitrename', '')}]({urljoin(indicator_url, indicator.get('id'))})", }) entries.append({ "id": f"{indicator.get('id')}", "value": f"{indicator.get('value')}" }) break else: if search.lower() in v.lower() \ and custom_fields.get('mitrename') not in [x.get('mitrename') for x in return_list_md]: return_list_md.append({ 'mitrename': custom_fields.get('mitrename'), 'Name': f"[{custom_fields.get('mitrename', '')}]({urljoin(indicator_url, indicator.get('id'))})", }) entries.append({ "id": f"{indicator.get('id')}", "value": f"{indicator.get('value')}" }) break return_list_md = sorted(return_list_md, key=lambda name: name['mitrename']) return_list_md = [{"Name": x.get('Name')} for x in return_list_md] md = tableToMarkdown('MITRE Indicator search:', return_list_md) ec = {'indicators(val.id && val.id == obj.id)': entries} return_outputs(md, ec, return_list_md)
def main(): # pragma: no cover """ Main """ global SERVER params = demisto.params() command = demisto.command() fields_to_present = create_fields_list(params.get('fields_filter', '')) types_for_indicator_sdo = argToList(params.get('provide_as_indicator')) try: port = int(params.get('longRunningPort')) except ValueError as e: raise ValueError(f'Invalid listen port - {e}') collections = get_collections(params) version = params.get('version') credentials = params.get('credentials', {}) server_links = demisto.demistoUrls() server_link_parts: ParseResult = urlparse(server_links.get('server')) host_name = server_link_parts.hostname service_address = params.get('service_address') certificate = params.get('certificate', '') private_key = params.get('key', '') if (certificate and not private_key) or (private_key and not certificate): raise ValueError( 'When using HTTPS connection, both certificate and private key must be provided.' ) http_server = not (certificate and private_key ) # False if (certificate and private_key) else True scheme = 'https' if not http_server else 'http' demisto.debug(f'Command being called is {command}') try: SERVER = TAXII2Server(scheme, str(host_name), port, collections, certificate, private_key, http_server, credentials, version, service_address, fields_to_present, types_for_indicator_sdo) if command == 'long-running-execution': run_long_running(params) elif command == 'test-module': return_results(test_module(params)) except Exception as e: err_msg = f'Error in {INTEGRATION_NAME} Integration [{e}]' return_error(err_msg)
def syslog_send_notification(manager: SyslogManager, min_severity: int): """ Send a message to syslog :param manager: Syslog manager :param min_severity: Minimum severity of incidents to send messages about """ message = demisto.args().get('message', '') entry = demisto.args().get('entry') ignore_add_url = demisto.args().get('ignoreAddURL', False) log_level = demisto.args().get('log_level', 'INFO') severity = demisto.args().get('severity') # From server message_type = demisto.args().get('messageType', '') # From server if severity: try: severity = int(severity) except Exception: severity = None if message_type == INCIDENT_OPENED and (severity is not None and severity < min_severity): return if not message: message = '' message = message.replace('\n', ' ').replace('\r', ' ').replace('`', '') investigation = demisto.investigation() if investigation: investigation_id = investigation.get('id') if entry: message = f'{entry}, {message}' message = f'{investigation_id}, {message}' if ignore_add_url and isinstance(ignore_add_url, str): ignore_add_url = bool(strtobool(ignore_add_url)) if not ignore_add_url: investigation = demisto.investigation() server_links = demisto.demistoUrls() if investigation: if investigation.get('type') != PLAYGROUND_INVESTIGATION_TYPE: link = server_links.get('warRoom') if link: if entry: link += '/' + entry message += f' {link}' else: link = server_links.get('server', '') if link: message += f' {link}#/home' if not message: raise ValueError('No message received') send_log(manager, message, log_level) demisto.results('Message sent to Syslog successfully.')
def reputation_command(client, args): input_indicator = args.get('indicator') demisto_urls = demisto.demistoUrls() indicator_url = demisto_urls.get('server') + "/#/indicator/" all_indicators: List[Dict] = list() size = 1000 search_indicators = IndicatorsSearcher() raw_data: dict = search_indicators.search_indicators_by_version( query=f'type:"{client.indicatorType}" value:{input_indicator}', size=size) if raw_data.get('total') == 0: md = 'No indicators found.' ec = {} else: while len(raw_data.get('iocs', [])) > 0: all_indicators.extend(raw_data.get('iocs', [])) raw_data = search_indicators.search_indicators_by_version( query=f'type:"{client.indicatorType}" value:{input_indicator}', size=size) for indicator in all_indicators: custom_fields = indicator.get('CustomFields', {}) score = indicator.get('score') value = indicator.get('value') indicator_id = indicator.get('id') url = indicator_url + indicator_id md = f"## {[value]}({url}):\n {custom_fields.get('mitredescription', '')}" ec = { "DBotScore(val.Indicator && val.Indicator == obj.Indicator && val.Vendor && val.Vendor == obj.Vendor)": { "Indicator": value, "Type": client.indicatorType, "Vendor": "MITRE ATT&CK", "Score": score }, "MITRE.ATT&CK(val.value && val.value = obj.value)": { 'value': value, 'indicatorid': indicator_id, 'customFields': custom_fields } } raw_data = {'indicators': all_indicators} return_outputs(md, ec, raw_data)
def get_largest_inputs_and_outputs(inputs_and_outputs, largest_inputs_and_outputs, incident_id) -> None: inputs = [] outputs = [] urls = demisto.demistoUrls() server_url = urls.get('server', '') incident_url = os.path.join(server_url, '#', 'incident', incident_id) if inputs_and_outputs: # In case no inputs and outputs are found a getInvPlaybookMetaData will return a string. # in that case we ignore the results and move on. if isinstance(inputs_and_outputs, str): return for task in inputs_and_outputs: task_id = task.get('id') if 'outputs' in task: for output in task.get('outputs'): task_url = os.path.join(server_url, '#', 'WorkPlan', incident_id, task_id) outputs.append({ 'IncidentID': f"[{incident_id}]({incident_url})", 'TaskID': f"[{task_id}]({task_url})", 'TaskName': task.get('name'), 'Name': output.get('name'), 'Size(MB)': float(output.get('size', 0)) / 1024, "InputOrOutput": 'Output', }) else: for arg in task.get('args'): task_url = os.path.join(server_url, '#', 'WorkPlan', incident_id, task_id) inputs.append({ 'IncidentID': f"[{incident_id}]({incident_url})", 'TaskID': f"[{task_id}]({task_url})", 'TaskName': task.get('name'), 'Name': arg.get('name'), 'Size(MB)': float(arg.get('size', 0)) / 1024, 'InputOrOutput': "Input", }) if inputs: largest_inputs_and_outputs.append(find_largest_input_or_output(inputs)) if outputs: largest_inputs_and_outputs.append( find_largest_input_or_output(outputs))
def main(): urls = demisto.demistoUrls() server_url = urls.get('server', '') server_url_parts: ParseResult = urlparse(server_url) host_name = server_url_parts.hostname port = server_url_parts.port scheme = server_url_parts.scheme server_address = { 'Scheme': scheme, 'Host': host_name, 'Port': port, 'URL': server_url } return_outputs(server_url, {'ServerURL': server_address}, server_url)
def main(): """ Main """ params = demisto.params() command = demisto.command() port = get_port(params) collections = get_collections(params) server_links = demisto.demistoUrls() server_link_parts: ParseResult = urlparse(server_links.get('server')) certificate: str = params.get('certificate', '') private_key: str = params.get('key', '') credentials: dict = params.get('credentials', None) http_server = True if (certificate and not private_key) or (private_key and not certificate): raise ValueError( 'When using HTTPS connection, both certificate and private key must be provided.' ) elif certificate and private_key: http_server = False global SERVER scheme = 'http' host_name = server_link_parts.hostname if not http_server: scheme = 'https' service_address = params.get('service_address') SERVER = TAXIIServer(scheme, str(host_name), port, collections, certificate, private_key, http_server, credentials, service_address) demisto.debug(f'Command being called is {command}') commands = {'test-module': test_module} try: if command == 'long-running-execution': run_server(SERVER) else: readable_output, outputs, raw_response = commands[command](SERVER) return_outputs(readable_output, outputs, raw_response) except Exception as e: err_msg = f'Error in {INTEGRATION_NAME} Integration [{e}]' return_error(err_msg)
def send_message(destinations: list, entry: str, ignore_add_url: bool, integration_context: dict, message: str, thread_id: str): """ Sends a message to Slack. :param destinations: The destinations to send to. :param entry: A WarRoom entry to send. :param ignore_add_url: Do not add a Demisto URL to the message. :param integration_context: Current integration context. :param message: The message to send. :param thread_id: The Slack thread ID to send the message to. :return: The Slack send response. """ if not message: message = '\n' if ignore_add_url and isinstance(ignore_add_url, str): ignore_add_url = bool(strtobool(ignore_add_url)) if not ignore_add_url: investigation = demisto.investigation() server_links = demisto.demistoUrls() if investigation: if investigation.get('type') != PLAYGROUND_INVESTIGATION_TYPE: link = server_links.get('warRoom') if link: if entry: link += '/' + entry message += '\n{} {}'.format('View it on:', link) else: link = server_links.get('server', '') if link: message += '\n{} {}'.format('View it on:', link + '#/home') try: response = send_message_to_destinations(destinations, message, thread_id) except SlackApiError as e: if str(e).find('not_in_channel') == -1 and str(e).find( 'channel_not_found') == -1: raise bot_id = integration_context.get('bot_id') if not bot_id: bot_id = get_bot_id() for dest in destinations: invite_users_to_conversation(dest, [bot_id]) response = send_message_to_destinations(destinations, message, thread_id) return response
def reputation_command(client, args): input_indicator = args.get('indicator') demisto_urls = demisto.demistoUrls() indicator_url = demisto_urls.get('server') + "/#/indicator/" all_indicators: List[Dict] = list() page = 0 size = 1000 raw_data = demisto.searchIndicators( query=f'type:"{client.indicatorType}" value:{input_indicator}', page=page, size=size) while len(raw_data.get('iocs', [])) > 0: all_indicators.extend(raw_data.get('iocs', [])) page += 1 raw_data = demisto.searchIndicators( query=f'type:"{client.indicatorType}" value:{input_indicator}', page=page, size=size) for indicator in all_indicators: custom_fields = indicator.get('CustomFields', {}) score = indicator.get('score') value = indicator.get('value') indicator_id = indicator.get('id') url = indicator_url + indicator_id md = f"## {[value]}({url}):\n {custom_fields.get('mitredescription', '')}" ec = { "DBotScore(val.Indicator && val.Indicator == obj.Indicator && val.Vendor && val.Vendor == obj.Vendor)": { "Indicator": value, "Type": client.indicatorType, "Vendor": "MITRE ATT&CK", "Score": score }, "MITRE.ATT&CK(val.value && val.value = obj.value)": { 'value': value, 'indicatorid': indicator_id, 'customFields': custom_fields } } return_outputs(md, ec, score)
def main(): """ Main """ params = demisto.params() command = demisto.command() port = get_port(params) collections = get_collections(params) server_links = demisto.demistoUrls() server_link_parts: ParseResult = urlparse(server_links.get('server')) certificate: str = params.get('certificate', '') private_key: str = params.get('key', '') http_server: bool = params.get('http_flag', True) credentials: dict = params.get('credentials', None) global SERVER scheme = 'http' host_name = server_link_parts.hostname if not http_server: scheme = 'https' host_name = get_https_hostname(host_name) SERVER = TAXIIServer(f'{scheme}://{host_name}', port, collections, certificate, private_key, http_server, credentials) demisto.debug(f'Command being called is {command}') commands = {'test-module': test_module} try: if command == 'long-running-execution': run_server(SERVER) else: readable_output, outputs, raw_response = commands[command](SERVER) return_outputs(readable_output, outputs, raw_response) except Exception as e: err_msg = f'Error in {INTEGRATION_NAME} Integration [{e}]' return_error(err_msg)
def add_incidents_link(data: List): server_url = demisto.demistoUrls().get('server') for incident in data: incident_link = urljoin(server_url, f'#/Details/{incident.get("id")}') incident['incidentLink'] = incident_link return data
async def translate_create(demisto_user: dict, message: str) -> str: """ Processes an incident creation message :param demisto_user: The Demisto user associated with the message (if exists) :param message: The creation message :return: Creation result """ json_pattern = r'(?<=json=).*' name_pattern = r'(?<=name=).*' type_pattern = r'(?<=type=).*' json_match = re.search(json_pattern, message) created_incident = None data = '' if json_match: if re.search(name_pattern, message) or re.search( type_pattern, message): data = 'No other properties other than json should be specified.' else: incidents_json = json_match.group() incidents = json.loads( incidents_json.replace('“', '"').replace('”', '"')) if not isinstance(incidents, list): incidents = [incidents] created_incident = await create_incidents(demisto_user, incidents) if not created_incident: data = 'Failed creating incidents.' else: name_match = re.search(name_pattern, message) if not name_match: data = 'Please specify arguments in the following manner: name=<name> type=[type] or json=<json>.' else: incident_name = re.sub('type=.*', '', name_match.group()).strip() incident_type = '' type_match = re.search(type_pattern, message) if type_match: incident_type = re.sub('name=.*', '', type_match.group()).strip() incident = {'name': incident_name} incident_type = incident_type or INCIDENT_TYPE if incident_type: incident['type'] = incident_type created_incident = await create_incidents(demisto_user, [incident]) if not created_incident: data = 'Failed creating incidents.' if created_incident: if isinstance(created_incident, list): created_incident = created_incident[0] server_links = demisto.demistoUrls() server_link = server_links.get('server') data = ( 'Successfully created incident {}.\n View it on: {}#/WarRoom/{}'. format(created_incident['name'], server_link, created_incident['id'])) return data
import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 BLACK_COLOR = "color:rgb(64,65,66)" server_url = "" html = "" try: incident = demisto.incidents() incident_id = incident[0].get('id', {}) campaign_incident_id = str(incident[0].get('CustomFields', {}).get('partofcampaign', '')) urls = demisto.demistoUrls() server_url = urls.get('server', '') if campaign_incident_id and campaign_incident_id != "None": html = f"""<div style='text-align:center; padding: 40px; font-size:15px; {BLACK_COLOR};' >This incident is part of a <a href="{server_url}/#/Custom/vvoh19d1ue/{campaign_incident_id}" >Phishing Campaign #{campaign_incident_id}</a></div>""" else: html = f"""<div style='text-align:center; padding: 40px; font-size:15px; {BLACK_COLOR};' >This incident is not part of a phishing campaign.</div>""" except Exception: html = f"""<div style='text-align:center; padding: 40px; font-size:15px; {BLACK_COLOR};' >This incident is part of a phishing campaign (incident #{campaign_incident_id}).</div>""" demisto.results({ 'ContentsFormat': formats['html'], 'Type': entryTypes['note'], 'Contents': html