def _list_switches(self, url, param): action_result = ActionResult(param) self.add_action_result(action_result) try: self.save_progress(phantom.APP_PROG_CONNECTING_TO_ELLIPSES, url) # switch_list = floodlight_rest.FloodlightRest(url=url).get('switches') self.save_progress("done.") if switch_list is None: return action_result.set_status(phantom.APP_ERROR, OC2SDN_ERR_NO_DATA) except Exception as e: return action_result.set_status(phantom.APP_ERROR, OC2SDN_ERR_SERVER_CONNECTION, e) # Rearrange into a table-friendly format here. # This should definitely change if we ever get a "tree" render type result = {"switches": [], "success": True} for switch in switch_list: addrmatch = re.match("/([^:]+):([0-9]+)", switch["inetAddress"]) if not addrmatch: return action_result.set_status(phantom.APP_ERROR, OC2SDN_ERR_PARSE, switch["inetAddress"]) result["switches"].append( { "ip": addrmatch.group(1), "port": addrmatch.group(2), "connectedSince": datetime.fromtimestamp(int(switch["connectedSince"]) / 1000).strftime('%Y-%m-%d %H:%M:%S'), "switchDPID": "dpid:{}".format(switch["switchDPID"]) }) action_result.add_data(result) return action_result.set_status(phantom.APP_SUCCESS, OC2SDN_SUCC)
def unblock_ip(self, param): """ Allow the IP address by deleting the rule which originally blocked the source IP address. URL https://10.255.111.100/mgmt/tm/security/firewall/policy/~Common~Phantom_Inbound/rules/sourceIP_8.8.8.8 """ config = self.get_config() self.debug_print("%s UNBLOCK_IP parameters:\n%s \nconfig:%s" % (F5_Connector.BANNER, param, config)) action_result = ActionResult(dict(param)) # Add an action result to the App Run self.add_action_result(action_result) URL = "/mgmt/tm/security/firewall/policy/~%s~%s/rules/%s" % (param["partition"], param["policy"], param["rule name"]) self.debug_print("%s UNBLOCK_IP URL: %s" % (F5_Connector.BANNER, URL)) F5 = iControl.BIG_IP(host=config.get("device"), username=config.get("username"), password=config.get("password"), uri=URL, method="DELETE") if F5.genericDELETE(): action_result.set_status(phantom.APP_SUCCESS) else: action_result.set_status(phantom.APP_ERROR) action_result.add_data(F5.response) self.debug_print("%s UNBLOCK_IP code: %s \nresponse: %s" % (F5_Connector.BANNER, F5.status_code, F5.response)) return
def locate_device(self, param): """ Locating client devices means walking a tree based on the API Key. The key is associated with one or more organizations, an organization can have one or more networks, each network can have multiple devices, and each device can have one or more client machines. Depending on the timespan specified, you may see differing results. Larger timespans may show the same client connected to multiple devices. Small timespans, may not return any results. """ self.debug_print("%s LOCATE_DEVICE parameters:\n%s" % (Meraki_Connector.BANNER, param)) action_result = ActionResult(dict(param)) # Add an action result to the App Run self.add_action_result(action_result) try: param["search_string"] # User left search_string empty except KeyError: param["search_string"] = "*" org_id_list = self.get_org_ids() for organization in org_id_list: networks_list = self.get_networks(organization["id"]) for network in networks_list: device_list = self.get_devices(network["id"]) for device in device_list: client_list = self.get_clients(device["serial"], param["timespan"]) for client in client_list: response = self.build_output_record(param["search_string"], organization, network, device, client) if response: action_result.add_data(response) if action_result.get_data_size() > 0: action_result.set_status(phantom.APP_SUCCESS) self.set_status_save_progress(phantom.APP_SUCCESS, "Returned: %s clients" % action_result.get_data_size()) else: action_result.set_status(phantom.APP_ERROR) self.set_status_save_progress(phantom.APP_ERROR, "Returned: %s clients" % action_result.get_data_size()) self.debug_print("%s Data size: %s" % (Meraki_Connector.BANNER, action_result.get_data_size())) return action_result.get_status()
def _delete_firewall_rule(self, url, param): action_result = ActionResult(param) self.add_action_result(action_result) try: self.save_progress(phantom.APP_PROG_CONNECTING_TO_ELLIPSES, url) # result = floodlight_firewall.delete_rule(url, None, param) self.save_progress("done.") if result is None: return action_result.set_status(phantom.APP_ERROR, OC2SDN_ERR_NO_DATA) action_result.add_data(result) if result.get("success") is not True: return action_result.set_status(phantom.APP_ERROR, result.get("status")) return action_result.set_status(phantom.APP_SUCCESS, OC2SDN_SUCC) except Exception as e: return action_result.set_status(phantom.APP_ERROR, OC2SDN_ERR_SERVER_CONNECTION, e)
def _call_function_as_action(self, url, funct, param={}): action_result = ActionResult(param) self.add_action_result(action_result) try: self.save_progress(phantom.APP_PROG_CONNECTING_TO_ELLIPSES, url) result = funct() self.save_progress("done.") if result is None: return action_result.set_status(phantom.APP_ERROR, OC2SDN_ERR_NO_DATA) action_result.add_data(result) return action_result.set_status(phantom.APP_SUCCESS, OC2SDN_SUCC) except Exception as e: return action_result.set_status(phantom.APP_ERROR, OC2SDN_ERR_SERVER_CONNECTION, e)
def _block_flow(self, url, param): action_result = ActionResult(dict(param)) self.add_action_result(action_result) try: self.save_progress(phantom.APP_PROG_CONNECTING_TO_ELLIPSES, url) # result = floodlight_firewall.add_rule(url, "deny", param) self.save_progress("done.") msg = result.get("status", OC2SDN_ERR_NO_STATUS) if msg == u'Rule added': action_result.add_data({"activityid": result["activityid"]}) return action_result.set_status(phantom.APP_SUCCESS, msg) return action_result.set_status(phantom.APP_ERROR, msg) except Exception as e: return action_result.set_status(phantom.APP_ERROR, OC2SDN_ERR_SERVER_CONNECTION, e)
def _list_devices(self, url, param): action_result = ActionResult(param) self.add_action_result(action_result) try: self.save_progress(phantom.APP_PROG_CONNECTING_TO_ELLIPSES, url) # device_list = floodlight_rest.FloodlightRest(url=url).get('devices') self.save_progress("done.") if device_list is None: return action_result.set_status(phantom.APP_ERROR, OC2SDN_ERR_NO_DATA) except Exception as e: return action_result.set_status(phantom.APP_ERROR, OC2SDN_ERR_SERVER_CONNECTION, e) # Floodlight v1.2 and earlier returns a list. Later versions return a root object containing a list. if isinstance(device_list, dict): device_list = device_list["devices"] # Rearrange into a table-friendly format here. # This should definitely change if we ever get a "tree" render type result = {"devices": [], "success": True} for device in device_list: for mac in device["mac"]: for vlan in device["vlan"]: for ap in device["attachmentPoint"]: for ip4 in device["ipv4"]: result["devices"].append( {"mac": mac, "vlan": vlan, "ip": ip4, "lastSeen": datetime.utcfromtimestamp(int(device["lastSeen"]) / 1000) .strftime('%Y-%m-%d %H:%M:%S UTC'), "attachmentPoint": {"port": ap["port"], "switchDPID": "dpid:{}".format(ap["switchDPID"])} }) for ip6 in device["ipv6"]: result["devices"].append( {"mac": mac, "vlan": vlan, "ip": ip6, "lastSeen": datetime.utcfromtimestamp(int(device["lastSeen"]) / 1000) .strftime('%Y-%m-%d %H:%M:%S UTC'), "attachmentPoint": {"port": ap["port"], "switchDPID": "dpid:{}".format(ap["switchDPID"])} }) action_result.add_data(result) return action_result.set_status(phantom.APP_SUCCESS, OC2SDN_SUCC)
def block_ip(self, param): """ Block a source IP address, a simple call to update a security policy in place. The firewall policy is called "Phantom_Inbound" which currently is tied to an inbound VIP in the "Common" partition. POST URL https://10.255.111.100/mgmt/tm/security/firewall/policy/~Common~Phantom_Inbound/rules body {"name":"DYNAMIC_BLOCK_NAME","action":"reject","place-after":"first","source":{"addresses":[{"name": "8.8.8.8/32"}" """ config = self.get_config() self.debug_print("%s BLOCK_IP parameters:\n%s \nconfig:%s" % (F5_Connector.BANNER, param, config)) action_result = ActionResult(dict(param)) # Add an action result to the App Run self.add_action_result(action_result) URL = "/mgmt/tm/security/firewall/policy/~%s~%s/rules" % (param["partition"], param["policy"]) body = '{"name":"%s","action":"%s","place-after":"first","source":{"addresses":[{"name":"%s/32"}]}}' \ % (param["rule name"], param["action"], param["source"]) self.debug_print("%s BLOCK_IP URL: %s \nbody:%s" % (F5_Connector.BANNER, URL, body)) F5 = iControl.BIG_IP(host=config.get("device"), username=config.get("username"), password=config.get("password"), uri=URL, method="POST") if F5.genericPOST(body): action_result.set_status(phantom.APP_SUCCESS) else: action_result.set_status(phantom.APP_ERROR) action_result.add_data(F5.response) self.debug_print("%s BLOCK_IP code: %s \nresponse: %s" % (F5_Connector.BANNER, F5.status_code, F5.response)) return
def _get_uptime(self, url, param): action_result = ActionResult(param) self.add_action_result(action_result) try: self.save_progress(phantom.APP_PROG_CONNECTING_TO_ELLIPSES, url) # result = floodlight_rest.FloodlightRest(url=url).get("uptime") self.save_progress("done.") if result is None: return action_result.set_status(phantom.APP_ERROR, OC2SDN_ERR_NO_DATA) except Exception as e: return action_result.set_status(phantom.APP_ERROR, OC2SDN_ERR_SERVER_CONNECTION, e) # Add a human-readable timestamp uptime = datetime.utcfromtimestamp(0) + timedelta(microseconds=int(result["systemUptimeMsec"]) * 1000) result["hhmmss"] = uptime.strftime('%H:%M:%S.%f')[:-3] result["success"] = True action_result.add_data(result) return action_result.set_status(phantom.APP_SUCCESS, OC2SDN_SUCC)
def _list_external_links(self, url, param): action_result = ActionResult(param) self.add_action_result(action_result) try: self.save_progress(phantom.APP_PROG_CONNECTING_TO_ELLIPSES, url) # link_list = floodlight_rest.FloodlightRest(url=url).get('external_links') self.save_progress("done.") if link_list is None: return action_result.set_status(phantom.APP_ERROR, OC2SDN_ERR_NO_DATA) except Exception as e: return action_result.set_status(phantom.APP_ERROR, OC2SDN_ERR_SERVER_CONNECTION, e) result = {"links": link_list, "success": True} # Add "dpid" namespaces to src-switch and dst-switch. for link in link_list: link["src-switch"] = "dpid:{}".format(link["src-switch"]) link["dst-switch"] = "dpid:{}".format(link["dst-switch"]) action_result.add_data(result) return action_result.set_status(phantom.APP_SUCCESS, OC2SDN_SUCC)
def _handle_on_poll(self, param): """ This function is used to handle on_poll. :param param: Dictionary of input parameters :return: status success/failure """ self.debug_print("In action handler for: {0}".format( self.get_action_identifier())) self.save_progress("In action handler for: {0}".format( self.get_action_identifier())) action_result = self.add_action_result(ActionResult(dict(param))) if phantom.is_fail(self._create_client(action_result)): return action_result.get_status() config = self.get_config() days = config.get('poll_now_days', AWSGUARDDUTY_POLL_NOW_DAYS) filter_name = config.get('filter_name') # Validation of the poll_now_days if (days and not str(days).isdigit()) or days == 0: return action_result.set_status( phantom.APP_ERROR, AWSGUARDDUTY_INVALID_LIMIT.format( param_name='poll_now_days in asset configuration')) container_count = int(param.get(phantom.APP_JSON_CONTAINER_COUNT)) end_time = datetime.now() # Fetch the start_time of polling for the first run initial_time = int( time.mktime((end_time - timedelta(int(days))).timetuple()) * 1000) if self._state.get('first_run', True) or self.is_poll_now() or ( (filter_name or self._state.get('filter_name')) and filter_name != self._state.get('filter_name')): criteria_dict = {'updatedAt': {'Gt': initial_time}} if not self.is_poll_now() and self._state.get('first_run', True): self._state['first_run'] = False # Store the poll_now_days in state file to determine if the value of this parameter gets changed at an interim state if filter_name: self._state['filter_name'] = filter_name elif not filter_name and self._state.get('filter_name'): self._state.pop('filter_name') else: start_time = self._state.get('last_updated_time', initial_time) # Adding 1000 milliseconds for next scheduled run as the Gt filter operator fetches # based on Gteq at an accuracy of 1000 milliseconds due to some bug in AWS GuardDuty API criteria_dict = {'updatedAt': {'Gt': start_time + 1000}} if not self._state.get('detector_id'): # Getting the detectors ID list_detectors = self._paginator('list_detectors', None, action_result) if not list_detectors: self.save_progress('No detectors found for AWS GuardDuty') return action_result.get_status() detector_id = list_detectors[0] self._state['detector_id'] = detector_id else: detector_id = self._state.get('detector_id') # Fetching the filter details finding_criteria = dict() if filter_name: ret_val, response = self._make_boto_call(action_result, 'get_filter', DetectorId=detector_id, FilterName=filter_name) if phantom.is_fail(ret_val): return action_result.get_status() finding_criteria = response.get('FindingCriteria', {}) # Removing the existing filter criteria of updatedAt and explicitly using the start_time calculated above for the OnPoll logic try: finding_criteria['Criterion'].pop('updatedAt') except KeyError: pass # Creating the sorting criteria according to the polling method(poll now / scheduling) sort_criteria = {'AttributeName': 'updatedAt', 'OrderBy': 'ASC'} if self.is_poll_now(): sort_criteria = {'AttributeName': 'updatedAt', 'OrderBy': 'DESC'} kwargs = {'DetectorId': detector_id, 'SortCriteria': sort_criteria} # Updates the Criterion by adding criteria_dict if finding_criteria: finding_criteria['Criterion'].update(criteria_dict) else: finding_criteria['Criterion'] = criteria_dict kwargs['FindingCriteria'] = finding_criteria list_findings = self._paginator('list_findings', None, action_result, **kwargs) if list_findings is None: self.save_progress('No findings found') return action_result.get_status() self.save_progress('Ingesting data') all_findings = list() # Fetches the details of finding in a bunch of 50 findings while list_findings: ret_val, res = self._make_boto_call( action_result, 'get_findings', DetectorId=detector_id, FindingIds=list_findings[:min(50, len(list_findings))], SortCriteria=sort_criteria) if phantom.is_fail(ret_val): return action_result.get_status() try: del res['ResponseMetadata'] except: pass findings_data = res.get('Findings') if not findings_data: self.save_progress('No findings found') return action_result.get_status() for finding in findings_data: if finding.get('Severity'): finding[ 'Severity'] = AWSGUARDDUTY_SEVERITY_REVERSE_MAP.get( finding.get('Severity')) all_findings.extend(findings_data) del list_findings[:min(50, len(list_findings))] if not all_findings: self.save_progress('No new findings found to poll') return action_result.set_status(phantom.APP_SUCCESS) # Updates the last_update_time in the state file if not self.is_poll_now(): last_finding = all_findings[ (min(len(all_findings), container_count)) - 1] last_updated_at_datetime = datetime.strptime( str(last_finding.get('UpdatedAt')), AWSGUARDDUTY_DATETIME_FORMAT) self._state['last_updated_time'] = int( time.mktime(last_updated_at_datetime.timetuple())) * 1000 for finding in all_findings[:container_count]: container_id = self._create_container(finding) if not container_id: continue artifacts_creation_status, artifacts_creation_msg = self._create_artifacts( finding=finding, container_id=container_id) if phantom.is_fail(artifacts_creation_status): self.debug_print( 'Error while creating artifacts for container with ID {container_id}. {error_msg}' .format(container_id=container_id, error_msg=artifacts_creation_msg)) self.save_progress( 'Total findings available on the UI of AWS GuardDuty: {}'.format( len(all_findings))) return action_result.set_status(phantom.APP_SUCCESS)
def _lookup_domain(self, param): action_result = self.add_action_result(ActionResult(dict(param))) # Getting mandatory input parameters domain = param[DNSDB_JSON_DOMAIN] # Getting optional input parameters record_type = param.get(DNSDB_JSON_TYPE, 'ANY') zone = param.get(DNSDB_JSON_ZONE) summary_data = action_result.update_summary({}) # Constructing request parameters based on input # Validating the input parameters provided # Would be used during REST call ret_val, url_params = self._get_url_params(param, action_result) # Something went wrong while validing input parameters if phantom.is_fail(ret_val): return action_result.get_status() # Endpoint as per parameter given if zone: endpoint = (DNSDB_ENDPOINT_DOMAIN_TYPE_ZONE).format( domain=domain, type=record_type, zone=zone) else: endpoint = (DNSDB_ENDPOINT_DOMAIN_TYPE).format(domain=domain, type=record_type) ret_val, response = self._make_rest_call(endpoint, action_result, params=url_params) # Something went wrong with the request if phantom.is_fail(ret_val): return action_result.get_status() # No data is considered as app success if (response.get(DNSDB_REST_RESP_RESOURCE_NOT_FOUND_MSG)): return action_result.set_status(phantom.APP_SUCCESS, DNSDB_DATA_NOT_AVAILABLE_MSG) json_resp = response.get(DNSDB_JSON_RESPONSE) for resp in json_resp: rdata = resp.get('rdata', []) for i, curr_rdata in enumerate(rdata): # if type is SOA, split the data and strip it, even if . is not present, this # will still execute without an error if resp.get('rrtype') == 'SOA': temp_res = curr_rdata.split(' ') temp_res = [x.rstrip('.') for x in temp_res] temp_header = [ 'rdata_origin', 'rdata_mail_addr', 'rdata_serial', 'rdata_refresh', 'rdata_retry', 'rdata_expire', 'rdata_minimum' ] rdata[i] = dict(zip(temp_header, temp_res)) # if type is MX, split the data and strip it, even if . is not present, this # will still execute without an error elif resp.get('rrtype') == 'MX': temp_res = curr_rdata.split(' ') temp_res = [x.rstrip('.') for x in temp_res] temp_header = ['rdata_preference', 'rdata_mail_exchange'] rdata[i] = dict(zip(temp_header, temp_res)) # for other types, first strip it, even if . is not present, this # will still execute without an error else: curr_rdata = curr_rdata.rstrip('.') rdata[i] = curr_rdata if ('rrname' in resp): resp['rrname'] = resp['rrname'].rstrip('.') if ('bailiwick' in resp): resp['bailiwick'] = resp['bailiwick'].rstrip('.') # Response from the API is list of rrset. # Adding Each data of list to action_result action_result.add_data(resp) summary_data['total_items'] = len(json_resp) return action_result.set_status(phantom.APP_SUCCESS)
def _lookup_ip(self, param): action_result = self.add_action_result(ActionResult(dict(param))) # Getting mandatory input parameter ip = param[DNSDB_JSON_IP] # Getting optional input parameter network_prefix = param.get(DNSDB_JSON_NETWORK_PREFIX) summary_data = action_result.update_summary({}) if network_prefix: # Validate network prefix # network prefix valid if between 0 and 32 for ipv4 if phantom.is_ip(ip): net_prefix_valid = 0 <= int(network_prefix) <= 32 else: # network prefix valid if between 0 and 128 for ipv6 net_prefix_valid = 0 <= int(network_prefix) <= 128 if not net_prefix_valid: self.debug_print( DNSDB_ERR_INVALID_NETWORK_PREFIX.format( prefix=network_prefix)) return action_result.set_status( phantom.APP_ERROR, DNSDB_ERR_INVALID_NETWORK_PREFIX.format( prefix=network_prefix)) # Endpoint as per parameter given if network_prefix: endpoint = (DNSDB_ENDPOINT_IP_PREFIX).format(ip=ip, prefix=network_prefix) else: endpoint = (DNSDB_ENDPOINT_IP).format(ip=ip) # Constructing request parameters based on input # Validating the input parameters provided # Would be used during REST call ret_val, url_params = self._get_url_params(param, action_result) # Something went wrong while validing input parameters if phantom.is_fail(ret_val): return action_result.get_status() ret_val, response = self._make_rest_call(endpoint, action_result, params=url_params) # Something went wrong with the request if phantom.is_fail(ret_val): return action_result.get_status() # No data is considered as app success if (response.get(DNSDB_REST_RESP_RESOURCE_NOT_FOUND_MSG)): return action_result.set_status(phantom.APP_SUCCESS, DNSDB_DATA_NOT_AVAILABLE_MSG) json_resp = response.get(DNSDB_JSON_RESPONSE) # To display count of domains in summary data count_domain = set() for resp in json_resp: if ('rrname' in resp): resp['rrname'] = resp['rrname'].rstrip('.') count_domain.add(resp['rrname']) # Response from the API is list of rdata. # Adding Each data of list to action_result action_result.add_data(resp) summary_data['total_domains'] = len(count_domain) return action_result.set_status(phantom.APP_SUCCESS)
def _handle_load_demo_data(self, param): self.save_progress("In action handler for: {0}".format( self.get_action_identifier())) config = self.get_config() action_result = self.add_action_result(ActionResult(dict(param))) status, response = self._get_github_data() if not (status): return action_result.set_status(phantom.APP_ERROR, response) status, untar_response = self._save_github_data(response) if not (status): return action_result.set_status(phantom.APP_ERROR, response) object_list = [ 'roles', 'users', 'assets', 'compiled_apps', 'demo_config__containers', 'playbooks', 'response_templates', 'seed_containers', 'custom_functions' ] object_types = param.get('object_types', '').split(',') exclude_object_list = param.get('exclude_object_types', '').split(',') if len([type_ for type_ in object_types if type_]) > 0: object_list = [ type_.strip().lower() for type_ in object_types if type_ ] object_list = [ type_ for type_ in object_list if type_ not in [item.strip().lower() for item in exclude_object_list] ] summary = {} if 'roles' in object_list: self.save_progress('Loading role data') status, message = self.update_roles(untar_response) if not (status): return action_result.set_status(phantom.APP_ERROR, message) summary['roles_message'] = message if 'users' in object_list: self.save_progress('Loading user data') status, message = self.update_users(untar_response) if not (status): return action_result.set_status(phantom.APP_ERROR, message) summary['users_message'] = message if 'demo_config__containers' in object_list: self.save_progress('Loading demo configuration container data') status, message = self.update_containers(untar_response) if not (status): return action_result.set_status(phantom.APP_ERROR, message) summary['demo_config__containers_message'] = message if 'compiled_apps' in object_list: self.save_progress('Loading demo app data') status, message = self.update_apps(untar_response) if not (status): return action_result.set_status(phantom.APP_ERROR, message) summary['compiled_apps_message'] = message if 'assets' in object_list: self.save_progress('Loading demo asset data') status, message = self.update_assets(untar_response) if not (status): return action_result.set_status(phantom.APP_ERROR, message) summary['assets_message'] = message if 'playbooks' in object_list: self.save_progress('Loading demo playbook data') status, message = self.update_playbooks(untar_response) if not (status): return action_result.set_status(phantom.APP_ERROR, message) summary['playbooks_message'] = message if 'custom_functions' in object_list: self.save_progress('Loading demo custom function data') status, message = self.update_custom_functions(untar_response) if not (status): return action_result.set_status(phantom.APP_ERROR, message) summary['custom_functions_message'] = message if 'response_templates' in object_list: self.save_progress('Loading response templates') status, message = self.update_response_templates(untar_response) if not (status): return action_result.set_status(phantom.APP_ERROR, message) summary['response_templates_message'] = message if 'seed_containers' in object_list: self.save_progress('Loading seed container data') status, message = self.update_containers( untar_response, github_path='seed_containers', do_not_destroy=False) if not (status): return action_result.set_status(phantom.APP_ERROR, message) summary['seed_containers_message'] = message action_result.update_summary(summary) return action_result.set_status( phantom.APP_SUCCESS, "Successfully loaded phantom demo data")
def _handle_test_connectivity(self, param): # Add an action result object to self (BaseConnector) to represent the action for this param action_result = self.add_action_result(ActionResult(dict(param))) self.save_progress( "C\'mon man. Roll the dice, and don\'t EVER doubt me again!!!!") self.save_progress( r'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ') self.save_progress( r'\\\\\\\\\\\\\\\\\\//////\\\\\\\\\\\\\\\\\///\\\\\\\\\\\\\\\\ ') self.save_progress( r'\\\\\\\\\\\\\\\\//\\\\\\/\\\\\\\\\\\\\///\\///\\\\\\\\\\\\\\ ') self.save_progress( r'\\\\\\\\\\\\\\\\/\\\\\\\//\\\\\\\\\\\//\\\\\\//\\\\\\\\\\\\\ ') self.save_progress( r'\\\\\\\\\\\\\\\/\\\\\/\\\/\\\\\\\\\\\/\\\//\\\//\\\\\\\\\\\\ ') self.save_progress( r'\\\\\\\\\/\\\\\/\\\\\/\\\/\\\\\\\\\\\/\\\//\\\\/\\\\\\\\\\\\ ') self.save_progress( r'\\\\\\\\\/\\\//\\\\\\/\\\/\\\\\\\\\\\/\\\//\\\\/\/\\\\\\\\\\ ') self.save_progress( r'\\\\\\\\\/\\\\/\\\\\\/\\\/\\\\\\\\\\/\\\\//\\\\//\\\/\\\\\\\ ') self.save_progress( r'\\\\\\\\\/\\\\/\\\\\//\\\/\\\\\\\\\\//\\\//\\\\/\\\\/\\\\\\\ ') self.save_progress( r'\\\\\\\\\/\\\\\/\\\\\\\\//\\\\\\\\\\//\\\/\\\\\/\\\\/\\\\\\\ ') self.save_progress( r'\\\\\\\\\/\\\\\//\\\\\\///\\\\\\\\\///\\\\\\\\/\\\\\/\\\\\\\ ') self.save_progress( r'\\\\\\\\\/\\\\\\//\\\\/\\\\\\\\\\\\\\\//\\\\\/\\\\\//\\\\\\\ ') self.save_progress( r'\\\\\\\\\//\\\\\\\////\\\\\\\\\\\\\\\\\\/////\\\\\\//\\\\\\\ ') self.save_progress( r'\\\\\\\\\/\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\//\\\\\\\ ') self.save_progress( r'\\\\\\\\\//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\//\\\\\\\ ') self.save_progress( r'\\\\\\\\\//\\\\\\\\\\\\\\\\////////\\\\\\\\\\\\\\\\\/\\\\\\\ ') self.save_progress( r'\\\\\\\\\\//\\\\\\\\\\\\\\\\\//\/\\\\\\\\\\\\\\\\\//\\\\\\\\ ') self.save_progress( r'\\\\\\\\\\//\\\\\\\\\\\\\\\\\\//\\\\\\\\\\\\\\\\\\//\\\\\\\\ ') self.save_progress( r'\\\\\\\\\\//\\\\\\\\\\\\\\\\\\//\\\\\\\\\\\\\\\\///\\\\\\\\\ ') self.save_progress( r'\\\\\\\\\\\//\/\\\\\\\\\\\\\\\/\\\\\\\\\\\\\\\\\///\\\\\\\\\ ') self.save_progress( r'\\\\\\\\\\\\///\\\\/\\\\\\\\/////\\\\\\\\\\\\\\///\\\\\\\\\\ ') self.save_progress( r'\\\\\\\\\\\\\//\\/\\\\//////\\\\\////\\//\\\\/\//\\\\\\\\\\\ ') self.save_progress( r'\\\\\\\\\\\\\\//\/\/\\\\\/\/\\/\\/\/\\\\\\/\\///\\\\\\\\\\\\ ') self.save_progress( r'\\\\\\\\\\\\\\\/////\//\\/\//\/\\/\/\\/\\\/\\//\\\\\\\\\\\\\ ') self.save_progress( r'\\\\\\\\\\\\\\\\\\//\///\\///\/\////\\/\/////\\\\\\\\\\\\\\\ ') self.save_progress( r'\\\\\\\\\\\\\\\\\\\\\/\//\/\/\/\/\/\\\/\///\\\\\\\\\\\\\\\\\ ') self.save_progress( r'\\\\\\\\\\\\\\\\\\\\\\\\/\/\/\\\/\///\/\\\\\\\\\\\\\\\\\\\\\ ') self.save_progress( r'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ') return action_result.set_status( phantom.APP_SUCCESS, "C\'mon man. Roll the dice, and don\'t EVER doubt me again!!!!")
def _handle_run_query(self, param): """ Fetches all the findings controlled by the filters which provided as input :param detector_id: The ID of the detector :param instance_id: The ID of the EC2 instance :param severity: The severity of a finding :param public_ip: Public IP address of the EC2 instance :param private_ip: Private IP address of the EC2 instance :param limit: Maximum results to be fetched """ action_result = self.add_action_result(ActionResult(dict(param))) if phantom.is_fail(self._create_client(action_result)): return action_result.get_status() detector_id = param['detector_id'] instance_id = param.get('instance_id') if param.get('severity'): severity = AWSGUARDDUTY_SEVERITY_MAP.get(param.get('severity')) else: severity = None public_ip = param.get('public_ip') private_ip = param.get('private_ip') limit = param.get('limit') if (limit and not str(limit).isdigit()) or limit == 0: return action_result.set_status( phantom.APP_ERROR, AWSGUARDDUTY_INVALID_LIMIT.format(param_name='limit')) criterion = {} finding_criteria = {"Criterion": criterion} if instance_id: criterion.update( {'resource.instanceDetails.instanceId': { 'Eq': [instance_id] }}) if severity: criterion.update({'severity': {'Eq': [severity]}}) if public_ip: criterion.update({ 'resource.instanceDetails.networkInterfaces.publicIp': { 'Eq': [public_ip] } }) if private_ip: criterion.update({ 'resource.instanceDetails.networkInterfaces.privateIpAddresses.privateIpAddress': { 'Eq': [private_ip] } }) kwargs = { 'DetectorId': detector_id, 'FindingCriteria': finding_criteria } list_findings = self._paginator('list_findings', limit, action_result, **kwargs) if list_findings is None: return action_result.get_status() while list_findings: ret_val, res = self._make_boto_call( action_result, 'get_findings', DetectorId=detector_id, FindingIds=list_findings[:min(50, len(list_findings))]) if phantom.is_fail(ret_val): return action_result.get_status() try: del res['ResponseMetadata'] except: pass findings_data = res.get('Findings') for finding in findings_data: if finding.get('Severity'): finding[ 'Severity'] = AWSGUARDDUTY_SEVERITY_REVERSE_MAP.get( finding.get('Severity')) action_result.add_data(finding) del list_findings[:min(50, len(list_findings))] summary = action_result.update_summary({}) summary['total_findings'] = action_result.get_data_size() return action_result.set_status(phantom.APP_SUCCESS)
def modify_smartflow_policy(self, param, LADS, CRUD): " Modify the Smartflow Policy " action_result = ActionResult(dict(param)) # Add an action result to the App Run self.add_action_result(action_result) source_ip = self.normalize_ip(param["source"]) # 8.8.8.8/32 or 192.0.2.0/24 or 4.4.4.4 app_name = param["application"] # WWT-API host_name = param["host"] # default-host service_name = param["service"] # default-service smartflow_name = param["smartflow"] # default-smartflow try: rule_action = param["action"] # 'deny' or 'allow', not specified for unblock except KeyError: rule_action = None uri = "/api/v2/applications/%s/hosts/%s/services/%s/smartflows/%s/policies" % (app_name, host_name, service_name, smartflow_name) if LADS.genericGET(uri=uri): # Successfully retrieved the Smartflow policy LADS.separate_access_policy(LADS.response) if LADS.modify_access_policy(CRUD, rule_action, source_ip): LADS.include_access_policy() uri += "/_import" if LADS.genericPOST(uri=uri, body=json.dumps(LADS.smartflow_policies)): action_result.set_status(phantom.APP_SUCCESS) LADS.separate_access_policy(LADS.response) # Isolate the access policy else: action_result.set_status(phantom.APP_ERROR) else: action_result.set_status(phantom.APP_ERROR) # Failure in modifying access policy else: action_result.set_status(phantom.APP_ERROR) # Failed to retrieve Smartflow policy action_result.add_data(LADS.access_policy) # Put the current access policy in the result data self.debug_print("%s modify_smartflow_policy code: %s \nresponse: %s" % (A10_LADS_Connector.BANNER, LADS.status_code, LADS.response)) return
def _create_ticket(self, param): action_result = self.add_action_result(ActionResult(param)) ret_val = self._login(action_result) if (phantom.is_fail(ret_val)): self.save_progress("Unable to Login") return action_result.get_status() parent_group = param.get(ARCSIGHT_JSON_PARENT_GROUP, ARCSIGHT_DEFAULT_PARENT_GROUP) if (not parent_group.startswith('/')): parent_group = '/' + parent_group parent_group = parent_group.rstrip('/') case_name = param[ARCSIGHT_JSON_CASE_NAME] # First get the id of the group ret_val, group_details = self._get_group_details( parent_group, action_result) if (phantom.is_fail(ret_val)): return action_result.get_status() group_id = group_details.get('resourceid') if (not group_id): return action_result.set_status( phantom.APP_ERROR, "Unable to get the group id of Group: '{0}'".format( parent_group)) self.save_progress('Got parent group ID: {0}'.format(group_id)) # init the summary as if the case was created summary = action_result.set_summary({'case_created': True}) # Try to see if there is already a case with that name ret_val, case_id = self._get_child_id_by_name(group_id, case_name, action_result) if (phantom.is_fail(ret_val)): return action_result.get_status() if (case_id): # Child is already present summary['case_created'] = False ret_val, case_details = self._get_case_details( case_id, action_result) if (phantom.is_fail(ret_val)): action_result.append_to_message( "Unable to get case information, cannot continue") return action_result.get_status() case_id = case_details.get('resourceid') if (case_id): summary['case_id'] = case_id action_result.add_data(case_details) return action_result.set_status(phantom.APP_SUCCESS, "Case already existed") # Child not present, let's insert it endpoint = "{0}/insertResource".format(ARCSIGHT_CASESERVICE_ENDPOINT) request_data = { "cas.insertResource": { "cas.authToken": self._auth_token, "cas.resource": { 'name': case_name }, "cas.parentId": group_id } } ret_val, resp = self._make_rest_call(endpoint, action_result, json=request_data, method="post") if (phantom.is_fail(ret_val)): summary['case_created'] = False return action_result.get_status() summary['case_created'] = True case_details = resp.get('cas.insertResourceResponse', {}).get('cas.return', {}) case_id = case_details.get('resourceid') if (case_id): summary['case_id'] = case_id action_result.add_data(case_details) return action_result.set_status(phantom.APP_SUCCESS, "New case created")
def _handle_get_screenshot(self, param): self.save_progress("In action handler for: {0}".format( self.get_action_identifier())) action_result = self.add_action_result(ActionResult(dict(param))) s_url = self._handle_py_ver_compat_for_input_str(param['url']) ftype = self._handle_py_ver_compat_for_input_str(param['type']) quality = param['quality'] # Validation of the quality parameter ret_val, quality = self._validate_integer(action_result, quality, QUALITY_KEY) if phantom.is_fail(ret_val): return action_result.get_status() fullpage = param.get('fullpage', True) followRefresh = param.get('followrefresh', True) jpeg_query = { "url": s_url, "options": { "type": ftype, "quality": "{}".format(quality), "fullPage": "{}".format(fullpage) } } png_query = { "url": s_url, "options": { "type": ftype, "fullPage": "{}".format(fullpage) } } if ftype == "png": query = png_query elif ftype == "jpeg": query = jpeg_query else: return action_result.set_status( phantom.APP_ERROR, "Invalid input. The 'type' parameter value should be either png or jpeg" ) if followRefresh: query["gotoOptions"] = {"waitUntil": "networkidle2"} # make rest call ret_val, response = self._make_rest_call('/screenshot', action_result, data=json.dumps(query)) if phantom.is_fail(ret_val): return action_result.get_status() try: file_name = "{}_screenshot.{}".format(s_url, ftype) if hasattr(Vault, 'create_attachment'): vault_ret = Vault.create_attachment(response, self.get_container_id(), file_name=file_name) else: if hasattr(Vault, 'get_vault_tmp_dir'): temp_dir = Vault.get_vault_tmp_dir() else: temp_dir = '/opt/phantom/vault/tmp' temp_dir = '{}/{}'.format(temp_dir, hashlib.md5(file_name).hexdigest()) os.makedirs(temp_dir) file_path = os.path.join(temp_dir, 'tmpfile') with open(file_path, 'wb') as f: f.write(response) vault_ret = Vault.add_attachment(file_path, self.get_container_id(), file_name=file_name) if vault_ret.get('succeeded'): action_result.set_status(phantom.APP_SUCCESS, 'Downloaded Screenshot') summary = { phantom.APP_JSON_VAULT_ID: vault_ret[phantom.APP_JSON_HASH], phantom.APP_JSON_NAME: file_name, 'vault_file_path': Vault.get_file_path(vault_ret[phantom.APP_JSON_HASH]), phantom.APP_JSON_SIZE: vault_ret.get(phantom.APP_JSON_SIZE) } action_result.update_summary(summary) except Exception as e: err_msg = self._get_error_message_from_exception(e) return action_result.set_status(phantom.APP_ERROR, err_msg) return action_result.get_status()
def _handle_get_pdf(self, param): self.save_progress("In action handler for: {0}".format( self.get_action_identifier())) action_result = self.add_action_result(ActionResult(dict(param))) s_url = self._handle_py_ver_compat_for_input_str(param['url']) headerfooter = param.get('headerfooter', True) printbackground = param.get('printbackground', False) landscape = param.get('landscape', False) followRefresh = param.get('followrefresh', True) query = { "url": s_url, "options": { "displayHeaderFooter": "{}".format(headerfooter), "printBackground": "{}".format(printbackground), "landscape": "{}".format(landscape) } } if followRefresh: query["gotoOptions"] = {"waitUntil": "networkidle2"} # make rest call ret_val, response = self._make_rest_call('/pdf', action_result, data=json.dumps(query)) if phantom.is_fail(ret_val): return action_result.get_status() try: file_name = "{}_screenshot.pdf".format(s_url) if hasattr(Vault, 'create_attachment'): vault_ret = Vault.create_attachment(response, self.get_container_id(), file_name=file_name) else: if hasattr(Vault, 'get_vault_tmp_dir'): temp_dir = Vault.get_vault_tmp_dir() else: temp_dir = '/opt/phantom/vault/tmp' temp_dir = '{}/{}'.format(temp_dir, hashlib.md5(file_name).hexdigest()) os.makedirs(temp_dir) file_path = os.path.join(temp_dir, 'tmpfile') with open(file_path, 'wb') as f: f.write(response) vault_ret = Vault.add_attachment(file_path, self.get_container_id(), file_name=file_name) if vault_ret.get('succeeded'): action_result.set_status(phantom.APP_SUCCESS, 'Downloaded PDF') summary = { phantom.APP_JSON_VAULT_ID: vault_ret[phantom.APP_JSON_HASH], phantom.APP_JSON_NAME: file_name, 'vault_file_path': Vault.get_file_path(vault_ret[phantom.APP_JSON_HASH]), phantom.APP_JSON_SIZE: vault_ret.get(phantom.APP_JSON_SIZE) } action_result.update_summary(summary) except Exception as e: err_msg = self._get_error_message_from_exception(e) return action_result.set_status(phantom.APP_ERROR, err_msg) return action_result.get_status()