def send_email_cb(action, success, email, results, handle): if not success: phantom.debug("Error sending email.\n{}".format(json.dumps(results))) return return
def get_registry_key_callback(action, success, incident, results, handle): if not success: phantom.debug('get registry key action failed') return
def list_offenses_cb(action, success, incident, results, handle): if not success: return # dump the results phantom.debug(json.dumps(results, indent=4)) data = None # Get the data from results, ideally we would loop over the results try: data = results[0]['action_results'][0]['data'] except: return if (not data): return # data is a list of offenses, only work on the 1st one for now try: offense_id = data[0]['id'] except: return # Execute all the actions that can be made on an offense id phantom.act('get events', parameters=[{ "count" : "10", "offense_id" : offense_id }], assets=["qradar_entr"], callback=get_events_cb) phantom.act('get flows', parameters=[{ "count" : "10", "ip" : "10.16.1.60", "offense_id" : offense_id }], assets=["qradar_entr"], callback=get_flows_cb) phantom.act('get flows', parameters=[{ "count" : "10", "offense_id" : offense_id }], assets=["qradar_entr"], callback=get_flows1_cb) phantom.act('offense details', parameters=[{ "offense_id" : offense_id }], assets=["qradar_entr"], callback=offense_details_cb) return
def on_start(incident): # lets do VT lookup of file hashes in the artifacts of an incident # artifacts:event.cef.fileHash # artifacts:event.cef.* # artifacts:event.raw.* # artifacts:event.* hashes = phantom.collect(incident, 'artifact:event.cef.fileHash', 'all', 100) phantom.debug('1:'+str(hashes)) #hashes = phantom.collect(incident, 'artifact:event.*.fileHash', 'all', 100) #phantom.debug('2:'+str(hashes)) #hashes = phantom.collect(incident, 'artifact:event.cef.*', 'all', 100) #phantom.debug('3:'+str(hashes)) #hashes = phantom.collect(incident, 'artifact:event.raw.*', 'all', 100) #phantom.debug('4:'+str(hashes)) #hashes = phantom.collect(incident, 'artifact:event.*', 'all', 100) #phantom.debug('5:'+str(hashes)) #hashes = phantom.collect(incident, 'artifact:event.source_data_identifier', 'all', 100) #phantom.debug('6:'+str(hashes)) #hashes = phantom.collect(incident, '*', 'all', 100) #phantom.debug('7:'+str(hashes)) return
def on_finish(email, summary): setupkey = 'setup_data' + str(email['current_rule_run_id']) collectkey = 'collect_data' + str(email['current_rule_run_id']) email_to, email_from, smtp_asset = phantom.get_data(setupkey, clear_data=True) container_url = phantom.get_base_url() + 'container/' + str(email['id']) # calling get_summary to find out if we actually had anything we acted on getsummary = phantom.get_summary() #phantom.debug('Get summary: {}'.format(getsummary)) # if len(getsummary['result']) > 0: # we have processed at least one item in on_start collected_results, collected_vault_items, container_owner = phantom.get_data(collectkey, clear_data=True) # finalize the vault item info and add to email for vaultid in collected_vault_items.keys(): vaultinfo = phantom.get_vault_item_info(vaultid) for app_run_id, datavalues in collected_results.iteritems(): #phantom.debug('iterate collected results: \napprunid: {}\n\ndatavals: {}'.format(app_run_id, datavalues)) if datavalues['detonate_summary']['target'] == vaultid: collected_results[app_run_id]['vault_info'] = vaultinfo if len(collected_results) < (len(getsummary['result'])-2): # subtracting actions that arent counted as detonations collected_results['message'] = "Unexpected: Collected Results: {} is less than actions run: {}".format(len(collected_results), (len(getsummary['result'])-2)) # send summary email email_subject = "Results: Ingest file detonatation" email_body = '\nPhantom Container ID: {} - Owner: {}\nURL: {}\nReturned results by app_run_id:\n{}'.format(email['id'], container_owner, container_url, pprint.pformat(collected_results, indent=4)) phantom.act('send email', parameters=[{ "from" : email_from, "to" : email_to, "subject" : email_subject, "body" : email_body }], assets=[smtp_asset], callback=send_email_cb) phantom.debug("Summary: " + pprint.pformat(summary, indent=4)) else: # no artifacts run on phantom.debug('No artifacts, sending abort email.') email_subject = "Results: No artifacts to run, aborting" email_body = '\nPhantom Container ID: {}\nURL: {} \nSummary:\n{}'.format(email['id'],container_url,summary) phantom.act('send email', parameters=[{ "from" : email_from, "to" : email_to, "subject" : email_subject, "body" : email_body }], assets=[smtp_asset], callback=send_email_cb) return
def get_parameters(success, results): if not success: return [] if (not results): return [] parameters = [] if ('action_results' not in results[0]): return [] result_items = results[0]['action_results'] for result_item in result_items: phantom.debug(result_item) if ('parameter' not in result_item): continue if ('uuid' not in result_item['parameter']): continue param = {"uuid": result_item["parameter"]["uuid"], "reason": "Locking IT"} parameters.append(param) return parameters
def get_parameters(success, results): if not success: return [] if (not results): return [] parameters = [] if ('action_results' not in results[0]): return [] result_items = results[0]['action_results'] for result_item in result_items: phantom.debug(result_item) if ('parameter' not in result_item): continue if ('ip_macaddress' not in result_item['parameter']): continue param = {"ip_macaddress": result_item["parameter"]["ip_macaddress"]} parameters.append(param) return parameters
def run_query_cb(action, success, incident, results, handle): if not success: return phantom.debug(results) return
def on_finish(offense, summary): action_results = phantom.get_action_results(offense) phantom.debug("Action results: "+json.dumps(action_results)) phantom.debug("Summary: " + summary) return
def whois_cb(action, success, incident, results, handle): phantom.debug('Action: {0} {1}'.format(action['action_name'], (' SUCCEEDED' if success else ' FAILED'))) if not success: return success_results = phantom.parse_success(results) for result in success_results: phantom.debug('IP: '+str(result['query'])+' is in Country: '+str(result['asn_country_code'])) return
def on_start(incident): attacker_ips = phantom.attacker_ips(incident, scope='all') if len(attacker_ips) <= 0: phantom.debug('No attacker IP in events') else: params = [] for ip in attacker_ips: params.append({'ip':ip}) phantom.act("whois ip", parameters=params, callback=whois_cb) return
def list_vms_cb(action, success, incident, results, handle): phantom.debug('VSphere list vms'+(' SUCCEEDED' if success else ' FAILED')) if not success: return attacked_ips = phantom.victim_ips(incident) success_results = phantom.parse_success(results) for vm_info in success_results: if 'ip' in vm_info:# if the VM is running, it will have an IP if vm_info['ip'] in attacked_ips: #if the IP address of the VM is the attacked IP phantom.act('snapshot vm', parameters=[{'vmx_path':vm_info['vmx_path'],'download': False}], callback=generic_cb) phantom.act('get process file', parameters=[{'name':'*infostealer*','ip_hostname':attacked_ips[0]}], assets=['domainctrl1'], callback=get_process_file_cb)
def update_ticket_cb(action, success, incident, results, handle): phantom.debug("results: {0}".format(json.dumps(results))) data = results[0]['action_results'][0]['data'] id = data[0]['sys_id'] phantom.act('get ticket', parameters=[{ "id" : id}], assets=["servicenow"]) return
def reboot_system_cb(action, status, incident, results, handle): """Callback for the reboot system action""" phantom.debug('Action: {0} {1}'.format(action['action_name'], (' SUCCEEDED' if status else ' FAILED'))) machine = eval(handle) # reboot done phantom.debug("reboot_system_cb on '{0}' with ip '{1}'".format(machine['name'], machine['ip'])) return
def get_registry_hives_callback(action, success, incident, results, handle): if not success: phantom.debug('get registry hives action failed') return #IMPORTANT: iterate through the results of the 'get registry hives' action to find the hive to search in. In the code below, we are not passing the hive_address parameter to search in, hence this code will search for the key in all hives. phantom.act('get registry key' , parameters=[{ "profile" : results[0]['action_results'][0]['summary']['vol_profile_used'], "vault_id" : results[0]['action_results'][0]['parameter']['vault_id'], 'key':'Software\Microsoft\Windows\CurrentVersion' }], assets=["volatility"], callback=get_registry_key_callback) return
def create_ticket_cb(action, success, incident, results, handle): if not success: return phantom.debug("results: {0}".format(json.dumps(results))) data = results[0]['action_results'][0]['data'] id = data[0]['id'] phantom.act('get ticket', parameters=[{ "id" : id}], assets=["rt"], callback=get_ticket_cb) return
def detonate_file_cb(action, success, incident, results, handle): phantom.debug('ThreatGrid action to detonate file,'+(' SUCCEEDED' if success else ' FAILED')) if not success: return score = results[0]['action_results'][0]['data'][0]['threat']['score'] phantom.debug('ThreatGrid threat score for this file: '+str(score)) if score > 60: for mac_addr in phantom.collect(incident,'artifact:event.cef.sourceMacAddress'): phantom.act('terminate session', parameters=[{'macaddress':mac_addr}], assets=['ciscoise'], callback=generic_cb) for a_ip in phantom.attacker_ips(incident): params = [{'src':'any','direction':'out','dest':a_ip,'interface':'outside','access-list':'inside_access_out'}] phantom.act('block ip', parameters=params, assets=['ciscoasa'], callback=generic_cb) for v_ip in phantom.victim_ips(incident): phantom.act('terminate process', parameters=[{'name':'*infostealer*','ip_hostname':v_ip}], assets=['domainctrl1'], callback=terminate_process_cb)
def locate_device_cb(action, success, container, results, handle): if not success: return paths = ['action_result.data.*.client.mac', 'action_result.data.*.client.description', 'action_result.data.*.device', 'action_result.data.*.network', 'action_result.data.*.organization'] data = phantom.collect(results, paths) phantom.debug(data) return
def on_start(incident): ip_hostnames = set(phantom.collect(incident, 'artifact:*.cef.sourceAddress', scope='all')) parameters = [] for ip_hostname in ip_hostnames: if (re.match(internal_ip, ip_hostname)): phantom.debug("ip: {0} is internal, will be executing the action".format(ip_hostname)) parameters.append({ "ip_hostname" : ip_hostname, "name" : "infostealer*.exe" }) if parameters: phantom.act('get process file', parameters=parameters, assets=["domainctrl1"], callback=get_process_file_cb) return
def on_start(container): ips = set(phantom.collect(container, 'artifact:*.cef.sourceAddress')) boiler_plate = { "action" : "reject", "policy" : None, "rule name" : None, "partition" : "Common"} for ip in ips: parameters = boiler_plate parameters["policy"] = "Phantom_Inbound" # Policy name must exist on the F5 BIG-IP parameters["source"] = ip # Source IP we are blocking parameters["rule name"] = "Phantom" + ip # Make the rule name based on the source IP address phantom.debug("PARAMETERS \n%s" % parameters) phantom.act('block ip', parameters=[parameters], assets=["f5"], callback=block_IP_cb) return
def list_questions_cb(action, success, incident, results, handle): if not success: return succ_results = phantom.get_successful_action_results_v2(results) results = succ_results[0]['data'] for result in results: query = result['name'] phantom.debug('query: {0}'.format(query)) params=[{'query':query}] phantom.act('run query', parameters=params, assets=['tanium'], name="Query: {0}".format(query)) return
def unquarantine_device_cb(action, success, container, results, handle): if not success: return input_parameters = get_parameters(success, results) parameters = [] for parameter in input_parameters: parameters.append({"macaddress": parameter["ip_macaddress"]}) phantom.debug(json.dumps(parameters, indent=4)) phantom.act('terminate session', parameters=parameters, assets=["ciscoise"], callback=terminate_session_cb) return
def get_ticket_cb(action, success, incident, results, handle): if not success: return phantom.debug("results: {0}".format(json.dumps(results))) data = results[0]['action_results'][0]['data'] id = data[0]['sys_id'] # stringized version of a dictionary fields_to_update = '{"short_description": "Zeus, Run file reputation actions only", "made_sla": false}' phantom.act('update ticket', parameters=[{ "id" : id, "fields": fields_to_update}], assets=["servicenow"], callback=update_ticket_cb) return
def on_start(email): # #phantom.debug('Email container data:\n {}\n\n'.format(email)) email_to = "email_to@my_enterprise.com" email_from = "*****@*****.**" smtp_asset = "smtp" # these keys are used to save persistent data across the playbook, # they must be unique by rule run ID, otherwise its possible the data # could be clobbered in another playbook running at the same time setupkey = 'setup_data' + str(email['current_rule_run_id']) collectkey = 'collect_data' + str(email['current_rule_run_id']) phantom.save_data([email_to, email_from, smtp_asset], key=setupkey) # collected_results = dict() collected_vault_items = dict() container_owner = "None" container_url = phantom.get_base_url() + 'container/' + str(email['id']) ## # we needed to get the vault_id for the email attachment to be detonated and pass that to the detonate action # so we use phantom.collect to grab the cef field (cs6) where we place the vault_id on the artifact vaultid = phantom.collect(email, 'artifact:*.cef.cs6', scope='new') # if len(vaultid) > 0: # we have at least one item to process # lets grab the owner of the container and make it something useful if blank if email['owner'] == '': container_owner = 'None' else: container_owner = email['owner'] phantom.debug('url: {}'.format(phantom.get_base_url())) email_body = "\nStarted file detonations on container_id: {} - Owner: {}\nURL: {}\nvault_item_info:\n".format(email['id'], container_owner, container_url) for vault_item in vaultid: vaultinfo = phantom.get_vault_item_info(vault_item) for vault_item_info in vaultinfo: collected_vault_items[vault_item] = vault_item_info email_body = email_body + pprint.pformat(vault_item_info, indent=4) + '\n' phantom.act('detonate file', parameters=[{'vault_id':vault_item}], assets=["threatgrid"], callback=detonate_file_cb) email_subject = "Running: Detonating files from ingest" # save modified data phantom.save_data([collected_results, collected_vault_items, container_owner], key=collectkey) # send email phantom.act('send email', parameters=[{ "from" : email_from, "to" : email_to, "subject" : email_subject, "body" : email_body }], assets=[smtp_asset], callback=send_email_cb) else: # no artifacts run on phantom.debug('No artifacts to process, ending on_start without running any actions. \n{}'.format(email)) return
def get_command_history_callback(action, success, incident, results, handle): if not success: phantom.debug('get command history action failed') return vault_id = results[0]['action_results'][0]['data'][0]['vault_id'] my_vault_file = phantom.get_vault_file(vault_id) data = my_vault_file.read() phantom.debug(data) phantom.act('get registry hives' , parameters=[{ "profile" : results[0]['action_results'][0]['summary']['vol_profile_used'], "vault_id" : results[0]['action_results'][0]['parameter']['vault_id']}], assets=["volatility"], callback=get_registry_hives_callback) return
def change_system_ou_cb(action_name, status, incident, results, handle): """Callback for the change system ou action""" phantom.debug('Action: {0} {1}'.format(action_name, (' SUCCEEDED' if status else ' FAILED'))) if (status == False): return # get the handle which is the machine info machine = eval(handle) phantom.debug("Working on '{0}' with ip '{1}'".format(machine['name'], machine['ip'])) # Now mark the system inactive, use the ip address here. params = [] params.append({'ip_hostname':machine['ip']}) phantom.act('deactivate partition', parameters=params, assets=['domainctrl2'], callback=sys_part_inactive_cb, handle=handle) return
def detonate_file_cb(action, success, email, results, handle): collectkey = 'collect_data' + str(email['current_rule_run_id']) if not success: phantom.debug("Error running detonate action.\n{}".format(json.dumps(results))) return # grab just the results url from the threatgrid return data, perhaps send the entire results dict # later as an email attachment? #result_url = results[0]['action_results'][0]['summary']['results_url'] # get the app run ID, and use it as a key to the dictionary we build with results app_run_id = results[0]['app_run_id'] collected_results, collected_vault_items, container_owner = phantom.get_data(collectkey, clear_data=False) collected_results[app_run_id] = dict() collected_results[app_run_id]['asset'] = results[0]['asset'] collected_results[app_run_id]['message'] = results[0]['message'] collected_results[app_run_id]['summary'] = results[0]['summary'] collected_results[app_run_id]['detonate_summary'] = results[0]['action_results'][0]['summary'] phantom.save_data([collected_results, collected_vault_items, container_owner], key=collectkey) return
def set_system_attrib_cb(action, status, incident, results, handle): """Callback for the set system attribute action""" phantom.debug('Action: {0} {1}'.format(action['action_name'], (' SUCCEEDED' if status else ' FAILED'))) if (status == False): return # get the handle which is the machine info machine = eval(handle) phantom.debug("Working on '{0}' with ip '{1}'".format(machine['name'], machine['ip'])) # Now we have to move the machine to another OU params = [] params.append({'ou':'staging', 'hostname':machine['name']}) phantom.act('change system ou', parameters=params, assets=['domainctrl2'], callback=change_system_ou_cb, handle=handle) return
def sys_part_inactive_cb(action, status, incident, results, handle): """Callback for the deactivate partition action""" phantom.debug('Action: {0} {1}'.format(action['action_name'], (' SUCCEEDED' if status else ' FAILED'))) if (status == False): return # get the handle which is the machine info machine = eval(handle) phantom.debug("Working on '{0}' with ip '{1}'".format(machine['name'], machine['ip'])) # Now reboot the system that was marked inactive params = [] params.append({'ip_hostname':machine['ip']}) phantom.act('reboot system', parameters=params, assets=['domainctrl2'], callback=reboot_system_cb, handle=handle) return
def on_start(incident): machines = list() # get the artifacts, which is of type 'event' events = phantom.get_artifacts(incident, artifact_label='event') # loop through each event for i, event in enumerate(events): phantom.debug('Working on event # {0}'.format(i)) phantom.debug('Event: \n{0}'.format(event)) # Create the dictionary, that will serve as the handle for a machine machine = {'ip':event['cef']['sourceAddress'], 'name':event['cef']['sourceHostName']} # Add it to the list if not present if machine not in machines: machines.append(machine) # Dump it phantom.debug('Found {0} machines, details: {1}'.format(len(machines), machines)) if (len(machines) == 0): # Nothing to do phantom.debug('No machines found Returned') return # Now go through each machine and work on them for i, machine in enumerate(machines): phantom.debug("Working on Machine # {0} with ip: '{1}' and name '{2}'".format( i, machine['ip'], machine['name'])) # params list for getting the attributes params = [] params.append({'hostname':machine['name']}) phantom.act("get system attributes", parameters=params, assets=['domainctrl2'], callback=get_system_attrib_cb, handle=str(machine)) return
def add_note_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None): phantom.debug('add_note_1() called') #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED'))) source_data_identifier_value = container.get('source_data_identifier', None) # collect data for 'add_note_1' call formatted_data_1 = phantom.get_format_data(name='format_note') parameters = [] # build parameters list for 'add_note_1' call parameters.append({ 'note': formatted_data_1, 'findings_id': source_data_identifier_value, 'overwrite': "", }) phantom.act("add note", parameters=parameters, assets=['aws_security_hub'], name="add_note_1") return
def update_list(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None): phantom.debug('update_list() called') template = """{0}""" # parameter list for template variable replacement parameters = [ "", ] phantom.format(container=container, template=template, parameters=parameters, name="update_list") return
def l5_cf_create_containers_from_list_py3_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): phantom.debug("l5_cf_create_containers_from_list_py3_1() called") playbook_input_mylist = phantom.collect2( container=container, datapath=["playbook_input:mylist"]) playbook_input_mylist_values = [item[0] for item in playbook_input_mylist] parameters = [] parameters.append({ "to_be_containerized": playbook_input_mylist_values, "container_label": "malware", }) ################################################################################ ## Custom Code Start ################################################################################ # Write your custom code here... ################################################################################ ## Custom Code End ################################################################################ phantom.custom_function( custom_function="chris/L5_CF_Create_Containers_From_List_py3", parameters=parameters, name="l5_cf_create_containers_from_list_py3_1") return
def Format_the_summarized_information(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): phantom.debug('Format_the_summarized_information() called') template = """{0} ------------ {1} ------------ {2} ------------ {3}""" # parameter list for template variable replacement parameters = [ "Capture_object:custom_function:file", "Capture_object:custom_function:ip", "Capture_object:custom_function:domain", "Capture_object:custom_function:url", ] phantom.format(container=container, template=template, parameters=parameters, name="Format_the_summarized_information") return
def process_responses(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): phantom.debug("process_responses() called") ################################################################################ # Produces an output list of containers that the user decided to merge. ################################################################################ event_details_result_data = phantom.collect2(container=container, datapath=["event_details:action_result.summary.responses"], action_results=results) event_details_summary_responses = [item[0] for item in event_details_result_data] process_responses__container_list = None process_responses__should_merge = None ################################################################################ ## Custom Code Start ################################################################################ process_responses__should_merge = "false" responses = event_details_summary_responses[0] # Grab run_key and convert to list container_list = json.loads(phantom.get_run_data(key='container_list')) if 'Merge Into Case' in responses: process_responses__container_list = [] for container_id, response in zip(container_list, responses): if response.lower() == 'merge into case': process_responses__container_list.append(container_id) process_responses__should_merge = "true" ################################################################################ ## Custom Code End ################################################################################ phantom.save_run_data(key="process_responses:container_list", value=json.dumps(process_responses__container_list)) phantom.save_run_data(key="process_responses:should_merge", value=json.dumps(process_responses__should_merge)) merge_any_decision(container=container) return
def Add_Note_Format(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): phantom.debug('Add_Note_Format() called') template = """|dvc|asset_type|asset_model|asset_status|priority|asset_zone|asset_system|location|user|count| |--|--|--|--|--|--|--|--|--|--| %% |{0}|{1}|{2}|{3}|{4}|{5}|{6}|{7}|{8}|{9}| %%""" # parameter list for template variable replacement parameters = [ "Check_Access_Policy_Violations:action_result.data.*.dvc", "Check_Access_Policy_Violations:action_result.data.*.asset_type", "Check_Access_Policy_Violations:action_result.data.*.asset_model", "Check_Access_Policy_Violations:action_result.data.*.asset_status", "Check_Access_Policy_Violations:action_result.data.*.priority", "Check_Access_Policy_Violations:action_result.data.*.asset_zone", "Check_Access_Policy_Violations:action_result.data.*.asset_system", "Check_Access_Policy_Violations:action_result.data.*.location", "Check_Access_Policy_Violations:action_result.data.*.user", "Check_Access_Policy_Violations:action_result.data.*.count", ] phantom.format(container=container, template=template, parameters=parameters, name="Add_Note_Format") add_note_3(container=container) return
def format_host_list_prompt(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): phantom.debug("format_host_list_prompt() called") ################################################################################ # Format a list of the hosts. This will feed both env var prompt and shut down # prompts. ################################################################################ template = """%%\n- {0}\n%%""" # parameter list for template variable replacement parameters = ["dedup_hostnames:custom_function_result.data.*.item"] ################################################################################ ## Custom Code Start ################################################################################ # Write your custom code here... ################################################################################ ## Custom Code End ################################################################################ phantom.format(container=container, template=template, parameters=parameters, name="format_host_list_prompt") quarantine_prompt(container=container) return
def file_search_decision(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): phantom.debug("file_search_decision() called") ################################################################################ # Determine if at least one file was found ################################################################################ # check for 'if' condition 1 found_match_1 = phantom.decision( container=container, conditions=[[ "true", "in", "locate_files:action_result.data.*.std_out" ]]) # call connected blocks if condition 1 matched if found_match_1: generate_deletion_commands(action=action, success=success, container=container, results=results, handle=handle) return # check for 'else' condition 2 join_dedup_hostnames(action=action, success=success, container=container, results=results, handle=handle) return
def Summer_save_object(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): phantom.debug('Summer_save_object() called') id_value = container.get('id', None) formatted_data_1 = phantom.get_format_data( name='Summery_Domain_Reputation') Summer_save_object__output_playbook = None ################################################################################ ## Custom Code Start ################################################################################ # Write your custom code here... container_id = container['id'] pb_info = phantom.get_playbook_info() playbook_name = pb_info[0].get('name', None) phantom.save_object(key=playbook_name, value={'feedback': formatted_data_1}, auto_delete=True, container_id=container_id) ################################################################################ ## Custom Code End ################################################################################ phantom.save_run_data( key='Summer_save_object:output_playbook', value=json.dumps(Summer_save_object__output_playbook)) return
def format_es_note(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): phantom.debug("format_es_note() called") ################################################################################ # Format a note with the current event information. ################################################################################ template = """SOAR event created: {0}\nComplete details can be found here: {1}/summary/evidence""" # parameter list for template variable replacement parameters = ["container:id", "container:url"] ################################################################################ ## Custom Code Start ################################################################################ # Write your custom code here... ################################################################################ ## Custom Code End ################################################################################ phantom.format(container=container, template=template, parameters=parameters, name="format_es_note", scope="all") update_notable(container=container) return
def url_reputation_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None): phantom.debug('url_reputation_1() called') # collect data for 'url_reputation_1' call AllContainerArtifacts__results_url = json.loads( phantom.get_run_data(key='AllContainerArtifacts:results_url')) # collect data for 'lookup_domain_1' call if len(AllContainerArtifacts__results_url) > 0: parameters = AllContainerArtifacts__results_url phantom.act("url reputation", parameters=parameters, callback=join_Initial_filtering, name="url_reputation_1") return
def get_file_2(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None): phantom.debug('get_file_2() called') #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED'))) # collect data for 'get_file_2' call filtered_results_data_1 = phantom.collect2(container=container, datapath=["filtered-data:filter_1:condition_1:file_reputation_1:action_result.parameter.hash", "filtered-data:filter_1:condition_1:file_reputation_1:action_result.parameter.context.artifact_id"]) parameters = [] # build parameters list for 'get_file_2' call for filtered_results_item_1 in filtered_results_data_1: if filtered_results_item_1[0]: parameters.append({ 'hash': filtered_results_item_1[0], # context (artifact id) is added to associate results with the artifact 'context': {'artifact_id': filtered_results_item_1[1]}, }) phantom.act("get file", parameters=parameters, assets=['carbonblack'], name="get_file_2") return
def file_reputation_2(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None): phantom.debug('file_reputation_2() called') #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED'))) # collect data for 'file_reputation_2' call filtered_artifacts_data_1 = phantom.collect2( container=container, datapath=[ 'filtered-data:filter_9:condition_1:artifact:*.cef.fileHashMd5', 'filtered-data:filter_9:condition_1:artifact:*.id' ]) parameters = [] # build parameters list for 'file_reputation_2' call for filtered_artifacts_item_1 in filtered_artifacts_data_1: if filtered_artifacts_item_1[0]: parameters.append({ 'hash': filtered_artifacts_item_1[0], # context (artifact id) is added to associate results with the artifact 'context': { 'artifact_id': filtered_artifacts_item_1[1] }, }) phantom.act("file reputation", parameters=parameters, assets=['virustotal'], callback=filter_5, name="file_reputation_2") return
def prompt_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None): phantom.debug('prompt_1() called') # set user and message variables for phantom.prompt call user = "******" message = """The following Hash is malicious {1}{0}{3}{2} {4}{6}{5}{7} Do you want to block this Hash?""" # parameter list for template variable replacement parameters = [ "artifact:*.cef.fileHashSha1", "artifact:*.cef.fileHashMd5", "artifact:*.cef.fileHashSha256", "artifact:*.cef.fileHashSha512", "file_reputation_SHA1:action_result.data.*.positives", "file_reputation_MD5:action_result.data.*.positives", "file_reputation_SHA256:action_result.data.*.positives", "file_reputation_SHA512:action_result.data.*.positives", ] #responses: response_types = [ { "prompt": "", "options": { "type": "list", "choices": [ "Yes", "No", ] }, }, ] phantom.prompt2(container=container, user=user, message=message, respond_in_mins=30, name="prompt_1", parameters=parameters, response_types=response_types, callback=filter_5) return
def reset_password_2(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None): phantom.debug('reset_password_2() called') #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED'))) # collect data for 'reset_password_2' call filtered_results_data_1 = phantom.collect2( container=container, datapath=[ "filtered-data:filter_3:condition_2:get_user_attributes_1:action_result.parameter.username", "filtered-data:filter_3:condition_2:get_user_attributes_1:action_result.parameter.context.artifact_id" ]) parameters = [] # build parameters list for 'reset_password_2' call for filtered_results_item_1 in filtered_results_data_1: if filtered_results_item_1[0]: parameters.append({ 'username': filtered_results_item_1[0], # context (artifact id) is added to associate results with the artifact 'context': { 'artifact_id': filtered_results_item_1[1] }, }) phantom.act("reset password", parameters=parameters, assets=['domainctrl1'], callback=format_4, name="reset_password_2") return
def detonate_file_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None): phantom.debug('detonate_file_1() called') #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED'))) # collect data for 'detonate_file_1' call container_data = phantom.collect2(container=container, datapath=['artifact:*.cef.cs6', 'artifact:*.id']) parameters = [] # build parameters list for 'detonate_file_1' call for container_item in container_data: if container_item[0]: parameters.append({ 'vault_id': container_item[0], # context (artifact id) is added to associate results with the artifact 'context': {'artifact_id': container_item[1]}, }) phantom.act("detonate file", parameters=parameters, assets=['virustotal_api'], callback=filter_3, name="detonate_file_1") return
def Store_Country_Name(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None): phantom.debug('Store_Country_Name() called') filtered_results_data_1 = phantom.collect2( container=container, datapath=[ "filtered-data:Filter_Banned_Countries:condition_1:geolocate_ip_1:action_result.data.*.country_name" ]) filtered_results_item_1_0 = [item[0] for item in filtered_results_data_1] ################################################################################ ## Custom Code Start ################################################################################ # Write your custom code here... # clean up input parameter url = '' for item in filtered_results_data_1: if item[0]: url = item[0] # store country name into object db phantom.save_object(key="country_name_Email_Notify", value={'value': "'" + url + "'"}, auto_delete=True, container_id=container['id']) ################################################################################ ## Custom Code End ################################################################################ Promote_to_Case(container=container) return
def merge_notes(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): phantom.debug("merge_notes() called") ################################################################################ # Merge available notes based on which format block was triggered. ################################################################################ template = """{0}{1}""" # parameter list for template variable replacement parameters = [ "format_error_note:formatted_data", "format_final_note:formatted_data" ] ################################################################################ ## Custom Code Start ################################################################################ # Write your custom code here... ################################################################################ ## Custom Code End ################################################################################ phantom.format(container=container, template=template, parameters=parameters, name="merge_notes", drop_none=True) return
def whois_ip_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None): phantom.debug('whois_ip_1() called') #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED'))) # collect data for 'whois_ip_1' call results_data_1 = phantom.collect2( container=container, datapath=[ 'geolocate_ip_1:action_result.parameter.ip', 'geolocate_ip_1:action_result.parameter.context.artifact_id' ], action_results=results) parameters = [] # build parameters list for 'whois_ip_1' call for results_item_1 in results_data_1: if results_item_1[0]: parameters.append({ 'ip': results_item_1[0], # context (artifact id) is added to associate results with the artifact 'context': { 'artifact_id': results_item_1[1] }, }) phantom.act("whois ip", parameters=parameters, assets=['whois'], name="whois_ip_1") return
def playbook_decision(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): phantom.debug("playbook_decision() called") ################################################################################ # Determine if any protect playbooks exist. ################################################################################ # check for 'if' condition 1 found_match_1 = phantom.decision( container=container, logical_operator="or", conditions= [[ "list_asset_playbooks:custom_function_result.data.*.full_name", "!=", "" ], [ "list_identity_playbooks:custom_function_result.data.*.full_name", "!=", "" ]]) # call connected blocks if condition 1 matched if found_match_1: collect_type_user(action=action, success=success, container=container, results=results, handle=handle) return return
def post_data_2(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): phantom.debug('post_data_2() called') #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED'))) # collect data for 'post_data_2' call formatted_data_1 = phantom.get_format_data(name='format_13') formatted_data_2 = phantom.get_format_data(name='format_14') parameters = [] # build parameters list for 'post_data_2' call parameters.append({ 'body': formatted_data_1, 'headers': "", 'location': formatted_data_2, 'verify_certificate': False, }) phantom.act(action="post data", parameters=parameters, assets=['http'], callback=join_service_path, name="post_data_2") return
def url_reputation_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): phantom.debug('url_reputation_1() called') #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED'))) # collect data for 'url_reputation_1' call container_data = phantom.collect2(container=container, datapath=['artifact:*.cef.requestURL', 'artifact:*.id']) parameters = [] # build parameters list for 'url_reputation_1' call for container_item in container_data: if container_item[0]: parameters.append({ 'url': container_item[0], # context (artifact id) is added to associate results with the artifact 'context': {'artifact_id': container_item[1]}, }) phantom.act(action="url reputation", parameters=parameters, app={ "name": 'VirusTotal' }, callback=url_reputation_1_callback, name="url_reputation_1") return
def describe_instance_before(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None): phantom.debug('describe_instance_before() called') # collect data for 'describe_instance_before' call filtered_artifacts_data_1 = phantom.collect2(container=container, datapath=['filtered-data:filter_ec2_resource:condition_1:artifact:*.cef.InstanceId', 'filtered-data:filter_ec2_resource:condition_1:artifact:*.id']) parameters = [] # build parameters list for 'describe_instance_before' call for filtered_artifacts_item_1 in filtered_artifacts_data_1: parameters.append({ 'limit': "", 'filters': "", 'instance_ids': filtered_artifacts_item_1[0], 'dry_run': "", # context (artifact id) is added to associate results with the artifact 'context': {'artifact_id': filtered_artifacts_item_1[1]}, }) phantom.act("describe instance", parameters=parameters, assets=['aws_ec2'], callback=add_isolation_SG, name="describe_instance_before") return
def file_reputation_4(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): phantom.debug('file_reputation_4() called') # collect data for 'file_reputation_4' call filtered_artifacts_data_1 = phantom.collect2( container=container, datapath=[ 'filtered-data:filter_1:condition_1:artifact:*.cef.fileHash', 'filtered-data:filter_1:condition_1:artifact:*.id' ]) parameters = [] # build parameters list for 'file_reputation_4' call for filtered_artifacts_item_1 in filtered_artifacts_data_1: if filtered_artifacts_item_1[0]: parameters.append({ 'hash': filtered_artifacts_item_1[0], # context (artifact id) is added to associate results with the artifact 'context': { 'artifact_id': filtered_artifacts_item_1[1] }, }) phantom.act(action="file reputation", parameters=parameters, assets=['virustotal'], callback=decision_1, name="file_reputation_4") return
def format_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None): phantom.debug('format_1() called') container_data = phantom.collect2( container=container, datapath=[ 'filtered-data:filter_1:condition_1:artifact:*.cef.emailHeaders.Subject' ]) command = "" for result in container_data: if result[0] and "Service Alert" in result[0]: parts = result[0].split("** PROBLEM Service Alert: ") hostname_ip = parts[1].split('/')[0] success, message, whitelist = phantom.get_list( "nagios_service_monitoring_hostname_ip_whitelist") if [hostname_ip] in whitelist: phantom.debug("hostname whitelist check passed") else: phantom.error("hostname whitelist check failed") phantom.comment(container=container, comment="hostname whitelist check failed") hostname_ip = "hostname whitelist check failed" phantom.format(container=container, template=hostname_ip, parameters=[""], name="format_1") #join_execute_program_1(container=container) return
def pin_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): phantom.debug('pin_1() called') formatted_data_1 = phantom.get_format_data(name='Text_Domain') formatted_data_2 = phantom.get_format_data(name='HUD_header') phantom.pin(container=container, data=formatted_data_1, message=formatted_data_2, pin_type="card", pin_style="red", name=None) return
def disable_user_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None): phantom.debug('disable_user_1() called') #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED'))) # collect data for 'disable_user_1' call results_data_1 = phantom.collect2(container=container, datapath=['hunt_file_2:action_result.data.*.process.results.*.username', 'hunt_file_2:action_result.parameter.context.artifact_id'], action_results=results) parameters = [] # build parameters list for 'disable_user_1' call for results_item_1 in results_data_1: if results_item_1[0]: parameters.append({ 'username': results_item_1[0], # context (artifact id) is added to associate results with the artifact 'context': {'artifact_id': results_item_1[1]}, }) phantom.act("disable user", parameters=parameters, assets=['domainctrl1'], callback=join_filter_2, name="disable_user_1", parent_action=action) return
def get_suspect_indicators(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): phantom.debug("get_suspect_indicators() called") id_value = container.get("id", None) parameters = [] parameters.append({ "tags_or": "suspicious, malicious", "tags_and": None, "container": id_value, "tags_exclude": "blocked, safe, marked_for_block", "indicator_timerange": None, }) ################################################################################ ## Custom Code Start ################################################################################ # Write your custom code here... ################################################################################ ## Custom Code End ################################################################################ phantom.custom_function(custom_function="community/indicator_get_by_tag", parameters=parameters, name="get_suspect_indicators", callback=indicators_decision) return
def ip_reputation_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None): phantom.debug('ip_reputation_1() called') #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED'))) # collect data for 'ip_reputation_1' call filtered_results_data_1 = phantom.collect2( container=container, datapath=[ "filtered-data:filter_2:condition_1:geolocate_ip_1:action_result.parameter.ip", "filtered-data:filter_2:condition_1:geolocate_ip_1:action_result.parameter.context.artifact_id" ]) parameters = [] # build parameters list for 'ip_reputation_1' call for filtered_results_item_1 in filtered_results_data_1: if filtered_results_item_1[0]: parameters.append({ 'ip': filtered_results_item_1[0], # context (artifact id) is added to associate results with the artifact 'context': { 'artifact_id': filtered_results_item_1[1] }, }) phantom.act("ip reputation", parameters=parameters, assets=['virustotal'], callback=join_format_1, name="ip_reputation_1") return
def geolocate_ip_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None): phantom.debug('geolocate_ip_1() called') # collect data for 'geolocate_ip_1' call container_data = phantom.collect2(container=container, datapath=['artifact:*.cef.destinationAddress', 'artifact:*.id']) phantom.debug(container_data) parameters = [] # build parameters list for 'geolocate_ip_1' call for container_item in container_data: if container_item[0]: parameters.append({ 'ip': container_item[0], # context (artifact id) is added to associate results with the artifact 'context': {'artifact_id': container_item[1]}, }) phantom.act("geolocate ip", parameters=parameters, assets=['maxmind'], callback=decision_1, name="geolocate_ip_1") return