def register_misp(misp: ExpandedPyMISP, misp_event_dict: dict) -> None: """ MISPイベントデータを受け取り、MISPに登録する """ misp_event = MISPEvent() misp_event.from_dict(**misp_event_dict) threat_level_id = misp_event.get('threat_level_id') threat_level = f'anyrun:threat_level:{threat_level_id}' misp_event.add_tag('anyrun') misp_event.add_tag(threat_level) retry_count = 0 while True: try: # pymispをインスタンス化してイベント登録 event_data = misp.add_event(misp_event) if event_data.get('errors'): raise Exception(event_data['errors']) # MISPに登録されるイベントIDを取得し、出力 event_id = event_data['Event']['id'] print(f'新規に登録されたEvent_ID: {event_id}') return except: except_return = traceback.format_exc() # インポート済みの場合 if const.DUPLICATE_EVENT_CONFIRM_WORD in except_return: print('Importを行おうとしたイベントは既にMISPに登録されています') return # リトライ回数チェック retry_count += 1 if retry_count >= const.RETRY_MAXIMUM_LIMIT: raise # インターバル処理 print('MISPへのイベントインポートをリトライします') time.sleep(const.COMMAND_INTERVAL_TIME)
# a dict of samples in the Event, keyed with <k>sha256 containing <v>MISP-Object Files samples={} # a cache of all the attributes in the event attributes={} #misp setup pm = PyMISP(misp_url, misp_key, ssl=misp_check_cert) misp_event=MISPEvent() search=pm.search(controller='events', eventinfo=misp_event_name) if ( len(search) == 1): misp_event.load(search[0]) #load 'samples' dictionary from misp_event for obj in misp_event.get('Object'): if (obj.name == "file"): existing_hash = obj.get_attributes_by_relation("sha256")[0]['value'] samples.update({existing_hash : obj}) #reload 'attributes' dictionary from misp_event for attr in misp_event.get('Attribute'): attributes.update({attr.value : attr}) else: misp_event.info=misp_event_name pm.add_event(misp_event) #bazaar setup r = requests.post(bazaar_url, data=bazaar_query) bazaardata = json.loads(r.text)
def misp_send(self, strMISPEventID, strInput, strInfo, strUsername): """ send an event to MISP """ try: objects = [] #get comments and tags from string input str_comment, tags = self.get_comm_and_tags(strInput) print(tags) if tags is None: self.misp_logger.info('Irate not in Tags: %s equals None', tags) response = None return response #setup misp objects mispobj_email = MISPObject(name="email") mispobj_file = MISPObject(name="file") mispobj_files = {} mispobj_domainip = MISPObject(name="domain-ip") url_no = 0 file_no = 0 mispobj_urls = {} #process input for line in strInput.splitlines(): if "domain:" in line.lower( ): #Catch domain and add to domain/IP object mispobj_domainip = MISPObject(name="domain-ip") vals = line.split(":", 1) mispobj_domainip.add_attribute("domain", value=vals[1].strip(), comment=str_comment) objects.append(mispobj_domainip) elif "ip:" in line.lower() or "ip-dst:" in line.lower( ) or "ip-src:" in line.lower( ): #Catch IP and add to domain/IP object if "domain:" in strInput.splitlines(): mispobj_domainip = MISPObject(name="domain-ip") vals = line.split(":", 1) mispobj_domainip.add_attribute("ip", value=vals[1].strip(), comment=str_comment) objects.append(mispobj_domainip) else: mispobj_network_connection = MISPObject( name="network-connection") vals = line.split(":", 1) if ("ip:" in line.lower()) or ("ip-dst:" in line.lower()): mispobj_network_connection.add_attribute( "ip-dst", type="ip-dst", value=vals[1].strip(), comment=str_comment) else: mispobj_network_connection.add_attribute( "ip-src", type="ip-src", value=vals[1].strip(), comment=str_comment) objects.append(mispobj_network_connection) elif "source-email:" in line.lower( ) or "email-source" in line.lower() or "from:" in line.lower( ): #Catch email and add to email object vals = line.split(":", 1) mispobj_email.add_attribute("from", value=vals[1].strip(), comment=str_comment) elif "url:" in line.lower() or ( ('kit:' in line.lower() or ('creds:' in line.lower())) and (('hxxp' in line.lower()) or ('http' in line.lower())) ): #Catch URL and add to URL object vals = line.split(":", 1) url = vals[1].strip() url = refang(url) parsed = urlparse(url) mispobj_url = MISPObject(name="url") mispobj_url.add_attribute("url", value=parsed.geturl(), category="Payload delivery", comment=str_comment) if parsed.hostname: mispobj_url.add_attribute("host", value=parsed.hostname, comment=str_comment) if parsed.scheme: mispobj_url.add_attribute("scheme", value=parsed.scheme, comment=str_comment) if parsed.port: mispobj_url.add_attribute("port", value=parsed.port, comment=str_comment) mispobj_urls[url_no] = mispobj_url url_no += 1 #Catch different hashes and add to file object elif "sha1:" in line.lower(): vals = line.split(":", 1) mispobj_file.add_attribute("sha1", value=vals[1].strip(), comment=str_comment) elif "sha256:" in line.lower(): vals = line.split(":", 1) mispobj_file.add_attribute("sha256", value=vals[1].strip(), comment=str_comment) elif "md5:" in line.lower(): vals = line.split(":", 1) mispobj_file.add_attribute("md5", value=vals[1].strip(), comment=str_comment) elif "subject:" in line.lower( ): #or ("subject:" in line): #Catch subject and add to email object vals = line.split(":", 1) self.misp_logger.info(f"adding subject: {vals[1].strip()}") mispobj_email.add_attribute("subject", value=vals[1].strip(), comment=str_comment) elif "hash|filename:" in line.lower( ): #catch hash|filename pair and add to file object vals = line.split(":", 1) val = vals[1].split("|") l_hash = val[0] l_filename = val[1] l_mispobj_file = MISPObject(name="file") if len(re.findall(r"\b[a-fA-F\d]{32}\b", l_hash)) > 0: l_mispobj_file.add_attribute("md5", value=l_hash.strip(), comment=str_comment) l_mispobj_file.add_attribute("filename", value=l_filename.strip(), comment=str_comment) mispobj_files[file_no] = l_mispobj_file elif len(re.findall(r'\b[0-9a-f]{40}\b', l_hash)) > 0: l_mispobj_file.add_attribute("sha1", value=l_hash.strip(), comment=str_comment) l_mispobj_file.add_attribute("filename", value=l_filename.strip(), comment=str_comment) mispobj_files[file_no] = l_mispobj_file elif len(re.findall(r'\b[A-Fa-f0-9]{64}\b', l_hash)) > 0: l_mispobj_file.add_attribute("sha256", value=l_hash.strip(), comment=str_comment) l_mispobj_file.add_attribute("filename", value=l_filename.strip(), comment=str_comment) mispobj_files[file_no] = l_mispobj_file file_no += 1 #add all misp objects to List to be processed and submitted to MISP server as one. if len(mispobj_file.attributes) > 0: objects.append(mispobj_file) if len(mispobj_email.attributes) > 0: objects.append(mispobj_email) for u_key, u_value in mispobj_urls.items(): if len(u_value.attributes) > 0: objects.append(u_value) for f_key, f_value in mispobj_files.items(): if len(f_value.attributes) > 0: objects.append(f_value) # Update timestamp and event except Exception as e: error = traceback.format_exc() response = f"Error occured when converting string to misp objects:\n{error}" self.misp_logger.error(response) return response if not self.check_object_length(objects): self.misp_logger.error( 'Input from %s did not contain accepted tags.\n Input: \n%s', (strUsername, strInput)) return "Error in the tags you entered. Please see the guide for accepted tags: (https://github.com/IRATEAU/sam-bot/blob/master/README.md)" try: # self.misp_logger.error(dir(self.misp)) misp_event = MISPEvent() misp_event.info = strInfo misp_event.distribution = 0 misp_event.analysis = 2 misp_event.threat_level_id = 3 # event.add_attribute('md5', '678ff97bf16d8e1c95679c4681834c41') #event = self.misp.new_event(info=strInfo, distribution='0', analysis='2', threat_level_id='3', published=False) #misp_event = MISPEvent() #misp_event.load(event) add = self.misp.add_event(misp_event) self.misp_logger.info("Added event %s", add) if objects: self.misp_logger.info("Adding objects to event...") objects, references = self.submit_to_misp( self.misp, misp_event, objects) self.misp_logger.info("References: %s", references) for tag in tags: self.misp_logger.info("Adding tag %s", tag) self.misp.tag(misp_event.uuid, tag) #self.misp.add_internal_comment(misp_event.id, reference="Author: " + strUsername, comment=str_comment) self.misp_logger.info("Publishing event...") publish_result = self.misp.publish(misp_event, alert=False) self.misp_logger.info("Publish result: %s", publish_result) if 'errors' in publish_result and publish_result.get('errors'): return_value = ("Submission error: " + repr(publish_result.get('errors'))) else: if misp_event.get('Event', {}).get('RelatedEvent'): e_related = "" for each in misp_event['Event']['RelatedEvent']: e_related = e_related + each['Event']['id'] + ", " return_value = "Created ID: " + str( misp_event['Event'] ['id']) + "\nRelated Events: " + ''.join(e_related) else: return_value = "Created ID: " + str( misp_event['Event']['id']) return return_value except Exception as e: error = traceback.format_exc() response = "Error occured when submitting to MISP:\n %s" % error self.misp_logger.error(response) return response