def hive_create_case(hive_tlp, threat_level, hive_description, hive_case_title, l_tags, path): ail_uuid = r_serv_db.get('ail:uuid') source = path.split('/')[-6:] source = '/'.join(source)[:-3] # get paste date var = path.split('/') last_seen = "{0}-{1}-{2}".format(var[-4], var[-3], var[-2]) case = Case(title=hive_case_title, tlp=hive_tlp, severity=threat_level, flag=False, tags=l_tags, description='hive_description') # Create the case id = None response = HiveApi.create_case(case) if response.status_code == 201: id = response.json()['id'] observ_sensor = CaseObservable(dataType="other", data=[ail_uuid], message="sensor") observ_file = CaseObservable(dataType="file", data=[path], tags=l_tags) observ_source = CaseObservable(dataType="other", data=[source], message="source") observ_last_seen = CaseObservable(dataType="other", data=[last_seen], message="last-seen") res = HiveApi.create_case_observable(id, observ_sensor) if res.status_code != 201: print('ko: {}/{}'.format(res.status_code, res.text)) res = HiveApi.create_case_observable(id, observ_source) if res.status_code != 201: print('ko: {}/{}'.format(res.status_code, res.text)) res = HiveApi.create_case_observable(id, observ_file) if res.status_code != 201: print('ko: {}/{}'.format(res.status_code, res.text)) res = HiveApi.create_case_observable(id, observ_last_seen) if res.status_code != 201: print('ko: {}/{}'.format(res.status_code, res.text)) r_serv_metadata.set('hive_cases:' + path, id) return hive_case_url.replace('id_here', id) else: print('ko: {}/{}'.format(response.status_code, response.text)) return False
async def update_case_observable(self, url, api_key, case_id, obs_id, description=None, tlp=0, is_ioc=False, is_sighted=False, tags=None, tags_mode=None): self.logger.info(f'Updating observable {obs_id} in case {case_id} in TheHive...') if not url.startswith("http"): url = f"http://{url}" api = TheHiveApi(url, api_key) obs_list = api.get_case_observables(case_id).json() obs_json = [obs for obs in obs_list if obs["id"] == obs_id][0] obs = CaseObservable(**obs_json) obs.id = obs_id if description: obs.description = description if tlp: obs.tlp = tlp if is_ioc is not None: obs.ioc = is_ioc if is_sighted is not None: obs.sighted = is_sighted if tags is not None: if tags_mode == "append": tags = obs.tags + tags obs.tags = tags r = api.update_case_observables(obs) if r.status_code == 200: return r.json() else: raise IOError(r.text)
def auto_run_analyzers(event, thehive, cortex): # Build CaseObservable object observable = CaseObservable(json=event["object"]) # Skip any observables that contain the "no-analyze" tag if "no-analyze" in observable.tags: logger.debug("Skipped analyzer jobs for Observable '%s'", observable.id) return # Run each available analyzer against the observable for analyzer in cortex.analyzers.get_by_type(observable.dataType): # Skip any analyzers that were defined above if analyzer.name in SKIP_ANALYZERS or analyzer.id in SKIP_ANALYZERS: logger.debug("Skipping Analyzer '%s'", analyzer.name) continue # Run the analyzer res = thehive.run_analyzer(CORTEX_ID, observable.id, analyzer.id) logger.debug(res.json()) if res.status_code in [200, 201]: logger.info( "Started '%s' job for Observable '%s'", analyzer.name, observable.id ) else: logger.warn( "Error occurred when starting '%s' job for Observable '%s'", analyzer.name, observable.id, ) time.sleep(0.5)
def addObservable(self, caseid, dataType, data, tags=[], tlp=2, ioc=False, message=""): self.logger.info('%s.addObservable starts', __name__) observable = CaseObservable(dataType=dataType, data=data, tlp=tlp, ioc=ioc, tags=tags, message=message) response = self.theHiveApi.create_case_observable(caseid, observable) if response.status_code == 201: esObservableId = response.json()['id'] return esObservableId else: self.logger.error('Observable creation failed') raise ValueError( json.dumps(response.json(), indent=4, sort_keys=True))
def prepare_url_observable(id, url_array): hive_address = ''.join(settings.stored_hive_address[0]) hive_api = ''.join(settings.stored_api_key[0]) #We will need to run through the arrays to extract the values. #Define the connection to thehive installation (including the generated API key). api = TheHiveApi(hive_address, hive_api, None, {'http': '', 'https': ''}) for urladdress in url_array: print( str(datetime.datetime.now()) + " Creating url observable:" + urladdress) domain = CaseObservable(dataType='url', data=[urladdress], tlp=0, ioc=False, tags=['ExtractedUrls'], message='Urls Extracted') response = api.create_case_observable(id, domain) if response.status_code == 201: # print(json.dumps(response.json(), indent=4, sort_keys=True)) print( str(datetime.datetime.now()) + " Observable succesfully created.") elif response.status_code == 400: print( str(datetime.datetime.now()) + " URL Observable already exists") else: print( str(datetime.datetime.now()) + " Error creating URL Observables.") print('ko: {}/{}'.format(response.status_code, response.text)) sys.exit(0)
def unblock_messages(self, case_id): """Delete a previous created filter by filter ID """ gmail_observables = self.__get_gmail_subjects( case_id, query=And(Eq("dataType", "mail"), And(EndsWith("data", self.__gmail_domain)))) for observable in gmail_observables: tag = self.__get_filter_tag( observable["tags"] ) # a tag should look like gmail_filters:domain:1235123121 resource = self.gmail_impersonate(observable["data"]) try: print("deleteing: {}".format(tag.split(":")[-1])) resource.users().settings().filters().delete( userId=observable["data"], id=tag.split(":")[-1]).execute() except GoogleAuthError as e: self.error("Gmail oauth failed: {}".format(e)) except HttpError as e: self.error("Gmail api failed: {}".format(e)) observable["tags"].remove(tag) for observable in gmail_observables: self.__hive_service.update_case_observables( CaseObservable(**observable), fields=["tags"]) self.report({'message': "Removed filters"})
def block_messages(self, case_id, query): """Automatically labels matching emails according to query argument. gmail search syntax can be used in query. https://support.google.com/mail/answer/7190?hl=en """ new_filter = { "criteria": { "query": query }, "action": { # based on https://developers.google.com/gmail/api/guides/labels "addLabelIds": ["TRASH"], "removeLabelIds": ["INBOX"] } } gmail_observables = self.__get_gmail_subjects( case_id, And(Eq("dataType", "mail"), EndsWith("data", self.__gmail_domain))) for observable in gmail_observables: resource = self.gmail_impersonate(observable["data"]) try: gmail_filter = resource.users().settings().filters().create( userId=observable["data"], body=new_filter).execute() except GoogleAuthError as e: self.error("Gmail oauth failed: {}".format(e)) except HttpError as e: self.error("Gmail api failed: {}".format(e)) observable["tags"].append("gmail_filter:{}:{}".format( self.get_param("data.data"), gmail_filter["id"])) for observable in gmail_observables: self.__hive_service.update_case_observables( CaseObservable(**observable), fields=["tags"]) self.report({'message': "Added filters"})
def trash_message(self, case_id, query): """Moves specified message into trash. this emails can be recovered if false-positive """ gmail_observables = self.__get_gmail_subjects( case_id, And(Eq("dataType", "mail"), EndsWith("data", self.__gmail_domain))) for observable in gmail_observables: resource = self.gmail_impersonate(observable["data"]) try: response = resource.users().messages().list( userId=observable["data"], q=query).execute() for message in response.get("messages", []): resource.users().messages().delete( userId=observable["data"], id=message["id"]).execute() observable["tags"].append("gmail_delete:{}".format( message["id"])) except GoogleAuthError as e: self.error("Gmail oauth failed: {}".format(e)) except HttpError as e: self.error("Gmail api failed: {}".format(e)) for observable in gmail_observables: self.__hive_service.update_case_observables( CaseObservable(**observable), fields=["tags"]) self.report({'message': "Deleted message"})
def prepare_subject_observable(id, subject): hive_address = ''.join(settings.stored_hive_address[0]) hive_api = ''.join(settings.stored_api_key[0]) #Define the connection to thehive installation (including the generated API key). api = TheHiveApi(hive_address, hive_api, None, {'http': '', 'https': ''}) print(subject) print('Create subject observable') print('---------------------') domain = CaseObservable(dataType='subject', data=[subject], tlp=0, ioc=False, tags=['ExtractedSubject'], message='Subject Extracted') response = api.create_case_observable(id, domain) if response.status_code == 201: # print(json.dumps(response.json(), indent=4, sort_keys=True)) print( str(datetime.datetime.now()) + " Observable succesfully created.") elif response.status.code == 400: print( str(datetime.datetime.now()) + " Subject Observable already exists") else: print( str(datetime.datetime.now()) + " Error creating Subject Observables.") print('ko: {}/{}'.format(response.status_code, response.text)) sys.exit(0)
def addObservable(self, esCaseId, value, type, comment, tags, tlp=2, ioc=True): ''' added to work with JUDAS :param esCaseId: case ID :param value: value to be added :param type: type of the observable (e.g., ip, mail, uri, user-agent, domain, hash, other) :param comment: any comment :return: ''' self.logger.info('%s.addFileObservable starts', __name__) my_observable = CaseObservable(dataType=type, data=[value], tlp=tlp, ioc=ioc, tags=tags, message=comment) response = self.theHiveApi.create_case_observable( esCaseId, my_observable) if response.status_code == 201: esObservableId = response.json()[0]['id'] return esObservableId else: self.logger.error('Observable upload failed') raise ValueError( json.dumps(response.json(), indent=4, sort_keys=True))
def add_observable_data(self, case_id, observables, datatype, data, category): observable_items = [] data_items = [] tags = [str(data["id"])] tags.extend(category) for item in observables: observable = CaseObservable( dataType=datatype, data=item, tlp=0, ioc=True, tags=tags, message="Possible IoC" ) # Creates the observable ret = self.hive.create_case_observable(case_id, observable) if ret.ok: observable_items.append(ret.json()) data_items.append(item) else: continue if data_items: self.cortex_listener.run_cortex_analyzer(datatype, data_items, observable_items)
async def create_case_observable(self, case_id, url, api_key, data_type, data, description=None, tlp=0, is_ioc=False, is_sighted=False, tags=None): tags = tags if tags is not None else [] self.logger.info(f'Creating observable for {case_id} in TheHive...') if not url.startswith("http"): url = f"http://{url}" api = TheHiveApi(url, api_key) obs = CaseObservable(dataType=data_type, message=description, tlp=tlp, tags=tags, ioc=is_ioc, sighted=is_sighted, data=data) r = api.create_case_observable(case_id, obs) if r.status_code == 201: return r.json() else: raise IOError(r.text)
def case_observable_model(event): return CaseObservable( dataType=event['observable']['type'], message=(event['observable']['description'] + ' ' + event['observable']['url']), tags=[event['observable']['id'], event['case']['id']], data=str(uuid.uuid4()))
def postUpdate(string, i): file_observable = CaseObservable( dataType='filename', data=[(threats.json['data'][i]['filePath'])], tlp=1, ioc=False, tags=['Auto Imported', 'Filename', 'Suspicious'], message='Filepath Observable from Sentinel One Alert') response = api.create_case_observable(string, file_observable) return response
def postUpdate(api, string, threat): file_observable = CaseObservable( dataType="filename", data=[threat["filePath"]], tlp=1, ioc=False, tags=["Auto Imported", "Filename", "Suspicious"], message="Filepath Observable from Sentinel One Alert", ) response = api.create_case_observable(string, file_observable) return response
def upload_observable(case_no, file_location, file_name): file_observable = CaseObservable( dataType='file', data=[file_location], tlp=1, ioc=False, message='uploaded bgit staty evidence puller script') response = api.create_case_observable(case_no, file_observable) if response.status_code == 201: #print(json.dumps(response.json(), indent=4, sort_keys=True)) print("Uploaded " + file_location + " to case " + str(case_no)) else: print('ko: {}/{}'.format(response.status_code, response.text)) sys.exit(0)
def create_osservables(self): for oss in self.osservable_data: domain = CaseObservable(dataType=exchange[oss[2]], tlp=1, ioc=True, tags=['thehive4py'], data=oss[3]) response = self.api.create_case_observable(self.case_id, domain) if response.status_code == 201: print(json.dumps(response.json(), indent=4, sort_keys=True)) print('') else: print('ko: {}/{}'.format(response.status_code, response.text)) print("adding OSSERVABLE", oss[2], "-", oss[3], "to", self.case_id)
def create_observables(items_dict, case_id): for k, v in items_dict.items(): observable = CaseObservable( dataType=k, data=[v], ioc=True, ) try: resp = hive_api.create_case_observable(case_id, observable) if resp.status_code == 201: id = resp.json()['id'] return id except Exception as err: logger.error( 'Error at observable creation.Case Id::{} - Err:[]'.format( case_id, err))
def hiveupdate(thehive_api_url, thehive_api_password, thehive_caseId, thehive_observableId, artifactList, sortedList, dt): api=TheHiveApi(thehive_api_url,thehive_api_password,cert=DHCPConf.ssl_cert_path) curlMsgString='' testString='' # Build the message-String for the original observable (The one that the responder was run on) for entry in sortedList: if (dt=='hostname'): testString=str(entry['host']['name'] + ':') elif(dt=='ip'): testString=str(entry['source']['ip'] + ':') if(testString not in curlMsgString): curlMsgString+='{0} \n\n'.format(testString) curlMsgString+=' {0}'.format(DHCPConf.msgStrBuilder(str(entry['event']['action']), str(entry['source']['ip']), str(entry['host']['hostname']), str(entry['@timestamp']))) # Build message-String, and create a new observable per entry in artifactList for artifact in artifactList: msgString='' for entry in sortedList: if(dt=='hostname'): testString=str(entry['host']['name']) elif(dt=='ip'): testString=str(entry['host']['name']) if(testString==artifact): msgString+=DHCPConf.msgStrBuilder(str(entry['event']['action']), str(entry['source']['ip']), str(entry['host']['hostname']), str(entry['@timestamp'])) domain=CaseObservable(dataType=dt,data=str(artifact),tlp=DHCPConf.defaultTlp,ioc=DHCPConf.defaultIoc,tags=DHCPConf.defaultTags,message=msgString) response=api.create_case_observable(thehive_caseId,domain) # Because it is not possible to edit existing observables through TheHive4py, # We edit the original observable (the one that started the DHCP_Responder), # through a HTTP.Patch call: headers={'Authorization': 'Bearer {0}'.format(thehive_api_password)} data={'message':curlMsgString} urlString='{0}/api/case/artifact/{1}'.format(thehive_api_url,thehive_observableId) response=requests.patch(urlString, headers=headers, data=data, verify=DHCPConf.ssl_cert_path)
def addFileObservable(self, esCaseId, filepath, comment): self.logger.debug('%s.addFileObservable starts', __name__) file_observable = CaseObservable(dataType='file', data=[filepath], tlp=2, ioc=False, tags=['Synapse'], message=comment) response = self.theHiveApi.create_case_observable( esCaseId, file_observable) if response.status_code == 201: esObservableId = response.json()['id'] return esObservableId else: self.handleErrors('File observable upload failed', response)
def add_case_artifact(artifacts, data_type, data, tags, tlp): """ :param artifacts: array :param data_type: string :param data: string :param tags: array :param tlp: int :return: array :rtype: array """ if data is not None: return artifacts.append( CaseObservable(tags=tags, dataType=data_type, data=str(data), message="From Cyrating", tlp=tlp))
def addObservable(self, esCaseId, datatype, ioc_list, tags, comment): self.logger.debug('%s.addObservable starts', __name__) ioc_observable = CaseObservable(dataType=datatype, data=ioc_list, tlp=2, ioc=True, tags=tags, message=comment ) response = self.theHiveApi.create_case_observable( esCaseId, ioc_observable) if response.status_code == 201: esObservableId = response.json()['id'] return esObservableId else: self.handleErrors('IOC observable upload failed', response)
def addFileObservable(self, esCaseId, filepath, comment, tags=['Synapse']): self.logger.info('%s.addFileObservable starts', __name__) file_observable = CaseObservable(dataType='file', data=[filepath], tlp=2, ioc=False, tags=tags, message=comment) response = self.theHiveApi.create_case_observable( esCaseId, file_observable) if response.status_code == 201: esObservableId = response.json()[0]['id'] return esObservableId else: self.logger.error('File observable upload failed') raise ValueError( json.dumps(response.json(), indent=4, sort_keys=True))
def addIPObservable(self, esCaseId, ip, comment): self.logger.info('%s.addIPObservable starts', __name__) observable = CaseObservable(dataType='ip', data=ip, tlp=2, ioc=False, tags=['Synapse'], message=comment ) response = self.theHiveApi.create_case_observable( esCaseId, observable) if response.status_code == 201: esObservableId = response.json()['id'] return esObservableId else: self.logger.error('Failed to create observable from IP') raise ValueError(json.dumps(response.json(), indent=4, sort_keys=True))
def Add_Obser(the_id, obs_data_type, data_val, case_tlp, case_ioc=False, case_tags=None, case_message=None): print('-------------') print('Adding observable to case....') sus_observable = CaseObservable( dataType=obs_data_type, data=data_val, tlp=case_tlp, ioc=case_ioc, ## indicator of comprimise tags=case_tags, message=case_message) response2 = api.create_case_observable(the_id, sus_observable) if response2.status_code == 201: print(json.dumps(response.json(), indent=4, sort_keys=True)) else: print('ko: {}/{}'.format(response.status_code, response.text))
def create_case_observable(self, data_type: HiveDataType, value: list, tlp=TLP.AMBER, ioc=True, additional_tags=None, description='LogRhythm IoC'): ioc_tags = self.ioc_tags.copy() if additional_tags is not None: for additional_tag in additional_tags: ioc_tags.append(additional_tag) hive_observable = CaseObservable(data_type=data_type.value, data=value, tlp=tlp.value, ioc=ioc, tags=ioc_tags, message=description) return hive_observable
def addFileObservable(self, esCaseId, filepath, comment): self.logger.info('%s.addFileObservable starts', __name__) file_observable = CaseObservable(dataType='file', data=[filepath], tlp=2, ioc=False, tags=['Synapse'], message=comment ) response = self.theHiveApi.create_case_observable( esCaseId, file_observable) if response.status_code == 201: esObservableId = response.json()['id'] return esObservableId # ignores the attachment if is already in the case elif response.status_code == 400 and response.json().get('message', '') == 'Artifact already exists': return None else: self.logger.error('File observable upload failed') raise ValueError(json.dumps(response.json(), indent=4, sort_keys=True))
def run(self, params={}): client = self.connection.client self.logger.info(params) observable = CaseObservable( dataType=params.get("observable").get("dataType", None), data=params.get("observable").get("data", None), tlp=params.get("observable").get("tlp", 2), ioc=params.get("observable").get("ioc", None), tags=params.get("observable").get("tags", []), message=params.get("observable").get("message", None), ) try: observable = client.create_case_observable(params.get("id"), observable) observable.raise_for_status() except requests.exceptions.HTTPError: self.logger.error(observable.json()) raise except: self.logger.error("Failed to create observable") raise return {"case": observable.json()}
def run(self, params={}): client = self.connection.client self.logger.info(params) observable = CaseObservable( dataType=params.get('observable').get('dataType', None), data=params.get('observable').get('data', None), tlp=params.get('observable').get('tlp', 2), ioc=params.get('observable').get('ioc', None), tags=params.get('observable').get('tags', []), message=params.get('observable').get('message', None)) try: observable = client.create_case_observable(params.get('id'), observable) observable.raise_for_status() except requests.exceptions.HTTPError: self.logger.error(observable.json()) raise except: self.logger.error('Failed to create observable') raise return {'case': observable.json()}
response = api.create_case(case) if response.status_code == 201: print(json.dumps(response.json(), indent=4, sort_keys=True)) print('') id = response.json()['id'] else: print('ko: {}/{}'.format(response.status_code, response.text)) sys.exit(0) print('Create domain observable') print('-----------------------------') domain = CaseObservable(dataType='filename', data=['pic.png'], tlp=1, ioc=True, sighted=True, tags=['thehive4py'], message='test') response = api.create_case_observable(id, domain) if response.status_code == 201: print(json.dumps(response.json(), indent=4, sort_keys=True)) print('') else: print('ko: {}/{}'.format(response.status_code, response.text)) sys.exit(0) print('Create file observable') print('-----------------------------') file_observable = CaseObservable(dataType='file', data=['pic.png'],