def phishingAlert(): report = dict() report['success'] = bool() tempAttachment = None cfg = getConf() ewsConnector = EwsConnector(cfg) folder_name = cfg.get('EWS', 'folder_name') unread = ewsConnector.scan(folder_name) theHiveConnector = TheHiveConnector(cfg) for email in unread: conversationId = email.conversation_id.id alertTitle = str(email.subject) alertDescription = ('```\n' + 'Alert created by Synapse\n' + 'conversation_id: "' + str(email.conversation_id.id) + '"\n' + '```') alertArtifacts = [] alertTags = ['CAT 7'] for msg in email.attachments: try: #print(type(msg)) q = dict() q['sourceRef'] = str(conversationId) esAlertId = theHiveConnector.findAlert(q) tempAttachment = TempAttachment(msg) if not tempAttachment.isInline: #print('here') tmpFilepath = tempAttachment.writeFile() with open(tmpFilepath, 'rb') as fhdl: raw_email = fhdl.read() parsed_eml = eml_parser.eml_parser.decode_email_b( raw_email) #print(parsed_eml['header']['header']['to']) #print(json.dumps(parsed_eml, default=json_serial, indent=4, sort_keys=True)) alertArtifacts.append( theHiveConnector.craftAlertArtifact( dataType='file', message="Phishing Email", data=tmpFilepath, tags=['Synapse'])) alertArtifacts.append( theHiveConnector.craftAlertArtifact( dataType='other', message="Message Id", data=parsed_eml['header']['header']['message-id'] [0], tags=['Synapse'])) for i in parsed_eml['header']['received_ip']: alertArtifacts.append( theHiveConnector.craftAlertArtifact( dataType='ip', message="Source IP", data=i, tags=['Synapse'])) alertArtifacts.append( theHiveConnector.craftAlertArtifact( dataType='mail_subject', message="Phishing Email Subject", data=parsed_eml['header']['subject'], tags=['Synapse'])) for i in parsed_eml['header']['to']: alertArtifacts.append( theHiveConnector.craftAlertArtifact( dataType='mail', message="Recipients", data=i, tags=['Synapse'])) for i in parsed_eml['header']['header']['return-path']: alertArtifacts.append( theHiveConnector.craftAlertArtifact( dataType='mail', message="Return Path", data=i, tags=['Synapse'])) if 'x-originating-ip' in parsed_eml['header']['header']: alertArtifacts.append( theHiveConnector.craftAlertArtifact( dataType='mail', message="Origin IP", data=parsed_eml['header']['header'] ['x-originating-ip'], tags=['Synapse'])) alert = theHiveConnector.craftAlert( alertTitle, alertDescription, severity=2, tlp=2, status="New", date=(int(time.time() * 1000)), tags=alertTags, type="Phishing", source="Phishing Mailbox", sourceRef=email.conversation_id.id, artifacts=alertArtifacts, caseTemplate="Category 7 - Phishing") theHiveEsAlertId = theHiveConnector.createAlert( alert)['id'] except Exception as e: #msg_obj = msg_parser.msg_parser.Message(msg) #print(msg_obj.get_message_as_json()) #msg_properties_dict = msg_obj.get_properties() print('Failed to create alert from attachment') readMsg = ewsConnector.markAsRead(email)
def rapid7IDRAlerts2Alerts(alert_data, org_name): logger = logging.getLogger('workflows.' + __name__) logger.info('%s.rapid7IDRAlerts2Alert starts', __name__) result = {} result['success'] = bool() conf = getConf() theHiveConnector = TheHiveConnector(conf) logger.info("Building custom fields ...") customFields = CustomFieldHelper()\ .add_string('client', org_name)\ .build() tags = [] now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M") alert_date = dateutil_parser.parse(alert_data.get('timestamp', now)) for user in alert_data.get('actors', {}).get('users', []): tags.append(user.get('name', "")) for asset in alert_data.get('actors', {}).get('assets', []): tags.append(asset.get('shortname', "")) logger.info("Building description ...") description = descriptionCrafter(alert_data, org_name) logger.info("Building alert ...") alert = theHiveConnector.craftAlert( title=alert_data.get( 'title', alert_data.get('name', "New alert from Rapid7 Insight IDR")), description=description, severity=2, #is there a way to determine efficiently this thing ? date=int(alert_date.timestamp()) * 1000, tags=tags, tlp=2, status="New", type="SIEM", source="Rapid7 Insight IDR", sourceRef=alert_data.get('investigationId', str(uuid.uuid4())), artifacts=artifactsCrafter(alert_data), caseTemplate="Insight IDR Case", customFields=customFields) logger.info("Sending alert to TheHive ...") try: ret = theHiveConnector.createAlert(alert) logger.info("Alert {} created in TheHive".format(str(ret['id']))) result['success'] = True except ValueError: logger.warning("Alert creation failed, trying to update ...") try: ret = theHiveConnector.updateAlert(alert.sourceRef, alert) logger.info("Alert {} updated in TheHive".format(str(ret['id']))) result['success'] = True except Exception as error: logger.error("Alert update failed ! {}".format(error)) result['success'] = False return result
def connectEws(): report = dict() report['success'] = bool() clients = None with open('/opt/Synapse/conf/mailboxes.json') as f: clients = json.load(f) mailboxes = clients['mailboxes'] cfg = getConf() theHiveConnector = TheHiveConnector(cfg) for mailbox in mailboxes: ewsConnector = EwsConnector(username=mailbox['username'], password=mailbox['password'], auth_type=mailbox['auth_type'], server=mailbox['server'], smtp_address=mailbox['smtp_address']) unread = ewsConnector.scan(mailbox['folder_name']) for msg in unread: #type(msg) #<class 'exchangelib.folders.Message'> conversationId = msg.conversation_id.id origin_mail = msg.attachments[0].item fullBody = getEmailBody(msg) alertTitle = "{}; {}".format( msg.subject, ''.join( [i if ord(i) < 128 else '' for i in origin_mail.subject])) alertDescription = ('```\n' + 'Alert created by Synapse\n' + 'conversation_id: "' + str(msg.conversation_id.id) + '"\n\n' + 'Original mail:\n\n' + fullBody[3:]) # rapporteur reporter = str(msg.sender.email_address).lower() # expéditeur sender = str(origin_mail.sender.email_address).lower() # date de réception originale et en-tant que spam rcv_date_timestamp = origin_mail.datetime_received.timestamp( ) * 1000 # date de signalement à la boîte support rpt_date_timestamp = msg.datetime_received.timestamp() * 1000 customFields = CustomFieldHelper()\ .add_string('reporter', reporter)\ .add_string('sender', sender)\ .add_date('receivedDate', rcv_date_timestamp)\ .add_date('reportedDate', rpt_date_timestamp)\ .add_string('client', mailbox['name'])\ .build() file_paths = [] artifacts = [] artifacts.append( AlertArtifact(dataType='mail', data=reporter, ignoreSimilarity=True, tags=['Synapse'])) artifacts.append( AlertArtifact(dataType='mail', data=sender, message="Original sender of the e-mail", tags=['Synapse', 'Sender'])) artifacts.append( AlertArtifact(dataType='mail_subject', data=str(origin_mail.subject), message="Original subject of the e-mail", tags=['Synapse'])) attachedFiles = getFileAttachments(msg) for attached in attachedFiles: artifacts.append( AlertArtifact(dataType='file', data=[attached['path']], tags=['Attachment', 'Synapse'])) file_paths.append(attached['path']) alert = Alert(title=alertTitle, description=alertDescription, severity=2, date=rcv_date_timestamp, tags=[], tlp=2, status="New", type="Phishing", source="BAL Phishing", sourceRef="{}-{}".format( mailbox['short_name'], str(uuid.uuid4())[24:].upper()), artifacts=artifacts, caseTemplate="Suspicious Email Case", customFields=customFields) theHiveConnector.createAlert(alert) ewsConnector.markAsRead(msg) logger.info("Cleaning temp files ...") for temp_file in file_paths: try: os.remove(temp_file) except OSError as errRm: logger.error("'{}' could not be removed.{}".format( temp_file, errRm)) report['success'] = True return report
def createQradarAlert(): logger = logging.getLogger(__name__) logger.info('%s.createQradarAlert starts', __name__) report = dict() report['success'] = bool() try: cfg = getConf() qradarConnector = QRadarConnector(cfg) theHiveConnector = TheHiveConnector(cfg) #Retrieve QRadar offenses with "OPEN" status response = qradarConnector.getOffenses() for offense in response: #Check if offense is already imported in TheHive theHive_alert = theHiveConnector.getAlerts({ 'sourceRef': 'QR' + str(offense['id']) }).json() if theHive_alert == []: print('QR' + str(offense['id']) + ' not imported') #Import opened offense in TheHive ##Create a list of AlertArtifact objects artifact_fields = { 'source_network': ('domain', 'STRING'), 'destination_networks': ('domain', 'STRING_LIST'), 'offense_source': ('ip', 'STRING') } artifacts_dict = defaultdict(list) for field in artifact_fields: if artifact_fields[field][1] == 'STRING_LIST': for elmt in offense[field]: artifacts_dict[artifact_fields[field][0]].append( elmt) elif artifact_fields[field][1] == 'STRING': artifacts_dict[artifact_fields[field][0]].append( offense[field]) artifacts_list = theHiveConnector.craftAlertArtifact( artifacts_dict) print(artifacts_dict) print(artifacts_list) ##Prepare other fields for an alert title = "#" + str( offense['id']) + " QRadar - " + offense['description'] description = ' / '.join(offense['categories']) if offense['severity'] < 3: severity = 1 elif offense['severity'] > 6: severity = 3 else: severity = 2 date = offense['start_time'] tags = [ 'Synapse', 'src:QRadar', 'QRadarID:' + str(offense['id']) ] sourceRef = 'QR' + str(offense['id']) ##Create Alert object and send it to TheHive alert = theHiveConnector.craftAlert(title, description, severity, date, tags, sourceRef, artifacts_list) theHiveConnector.createAlert(alert) else: print('QR' + str(offense['id']) + ' already imported') report['success'] = True return report except Exception as e: logger.error('Failed to create alert from QRadar offense', exc_info=True) report['success'] = False return report
def allOffense2Alert(timerange): """ Get all openned offense created within the last <timerange> minutes and creates alerts for them in TheHive """ logger = logging.getLogger(__name__) logger.info('%s.allOffense2Alert starts', __name__) report = dict() report['success'] = True report['offenses'] = list() try: cfg = getConf() qradarConnector = QRadarConnector(cfg) theHiveConnector = TheHiveConnector(cfg) offensesList = qradarConnector.getOffenses(timerange) #each offenses in the list is represented as a dict #we enrich this dict with additional details for offense in offensesList: #searching if the offense has already been converted to alert q = dict() q['sourceRef'] = str(offense['id']) logger.info('Looking for offense %s in TheHive alerts', str(offense['id'])) results = theHiveConnector.findAlert(q) if len(results) == 0: logger.info( 'Offense %s not found in TheHive alerts, creating it', str(offense['id'])) offense_report = dict() enrichedOffense = enrichOffense(qradarConnector, offense) try: theHiveAlert = qradarOffenseToHiveAlert( theHiveConnector, enrichedOffense) theHiveEsAlertId = theHiveConnector.createAlert( theHiveAlert)['id'] offense_report['raised_alert_id'] = theHiveEsAlertId offense_report['qradar_offense_id'] = offense['id'] offense_report['success'] = True except Exception as e: logger.error('%s.allOffense2Alert failed', __name__, exc_info=True) offense_report['success'] = False if isinstance(e, ValueError): errorMessage = json.loads(str(e))['message'] offense_report['message'] = errorMessage else: offense_report['message'] = str( e) + ": Couldn't raise alert in TheHive" offense_report['offense_id'] = offense['id'] # Set overall success if any fails report['success'] = False report['offenses'].append(offense_report) else: logger.info('Offense %s already imported as alert', str(offense['id'])) except Exception as e: logger.error( 'Failed to create alert from QRadar offense (retrieving offenses failed)', exc_info=True) report['success'] = False report['message'] = "%s: Failed to create alert from offense" % str(e) return report
def allOffense2Alert(timerange): """ Get all openned offense created within the last <timerange> minutes and creates alerts for them in TheHive """ logger = logging.getLogger(__name__) logger.info('%s.allOffense2Alert starts', __name__) report = dict() report['success'] = True report['offenses'] = list() try: cfg = getConf() qradarConnector = QRadarConnector(cfg) theHiveConnector = TheHiveConnector(cfg) offensesList = qradarConnector.getOffenses(timerange) #each offenses in the list is represented as a dict #we enrich this dict with additional details for offense in offensesList: #searching if the offense has already been converted to alert logger.info('Looking for offense %s in TheHive alerts', str(offense['id'])) # Update only new Alerts, as Ignored it will be closed on QRadar and should not be updated, # as Imported we will do a responder to fetch latest info in the case results = theHiveConnector.findAlert( Eq("sourceRef", str(offense['id']))) offense_report = dict() try: if len(results) == 0: logger.info( 'Offense %s not found in TheHive alerts, creating it', str(offense['id'])) enrichedOffense = enrichOffense(qradarConnector, offense) theHiveAlert = qradarOffenseToHiveAlert( theHiveConnector, enrichedOffense) theHiveEsAlertId = theHiveConnector.createAlert( theHiveAlert)['id'] offense_report['type'] = "Creation" offense_report['raised_alert_id'] = theHiveEsAlertId offense_report['qradar_offense_id'] = offense['id'] offense_report['success'] = True report['offenses'].append(offense_report) elif results[0]['status'] not in ['Ignored', 'Imported']: # update alert if alert is not imported and not dimissed # will only update 'lastEventCount' and 'lastUpdatedTime' custom fields logger.info('Updating offense %s', str(offense['id'])) alert = Alert(json=results[0]) cf = CustomFieldHelper() alert.title = offense['description'] if 'lastEventCount' not in alert.customFields: alert.customFields['lastEventCount'] = {} if 'lastUpdated' not in alert.customFields: alert.customFields['lastUpdated'] = {} if 'offenseSource' not in alert.customFields: alert.customFields['offenseSource'] = {} alert.customFields['lastEventCount']['number'] = offense[ 'event_count'] alert.customFields['lastUpdated']['date'] = offense[ 'last_updated_time'] alert.customFields['offenseSource']['string'] = offense[ 'offense_source'] # updated maybe ? # should improve TheHiveConnector.updateAlert() rather than using this updatedAlert = theHiveConnector.theHiveApi.update_alert( results[0]['id'], alert, fields=['customFields', 'title']) if not updatedAlert.ok: raise ValueError(json.dumps(updatedAlert.json())) offense_report['type'] = "Update" offense_report['updated_alert_id'] = updatedAlert.json( )['id'] offense_report['qradar_offense_id'] = offense['id'] offense_report['success'] = True report['offenses'].append(offense_report) else: logger.info("Offense already exists") except Exception as e: logger.error('%s.allOffense2Alert failed', __name__, exc_info=True) offense_report['success'] = False if isinstance(e, ValueError): errorMessage = json.loads(str(e))['message'] offense_report['message'] = errorMessage else: offense_report['message'] = str( e) + ": Couldn't raise alert in TheHive" offense_report['offense_id'] = offense['id'] # Set overall success if any fails report['success'] = False except Exception as e: logger.error( 'Failed to create alert from QRadar offense (retrieving offenses failed)', exc_info=True) report['success'] = False report['message'] = "%s: Failed to create alert from offense" % str(e) return report
def allNotifs2Alert(): logger = logging.getLogger('workflows.' + __name__) logger.info('%s.allNotifs2Alert starts', __name__) result = dict() result['success'] = bool() result['message'] = str() try: carbonBlack = CBConnector() # DEBUG PURPOSES ONLY ! #logger.info(str(allNotifications)) conf = getConf() theHiveConnector = TheHiveConnector(conf) with open(os.path.join(current_dir, "..", "conf", "carbonblack.json")) as fd: organizations = json.load(fd)['orgs'] for org in organizations: notifications = carbonBlack.getAllNotifications( org['notifications_profile'], org['alerts_profile']) for notification in notifications: #TODO: maybe we should set ALL the variables containing relevant info here to avoid .get() everywhere, btw is .get() actually usefull ? #TODO: maybe cut a lot of this variable process in a few (or a lot of) functions, juste like "descriptionCrafter" and "artifactCrafter" # This and the next try...catch is to avoid backslashes '\' in a tag, as it is breaking TheHive sorting mechanism orgName = org['name'] orgTagName = org['tag-name'] orgShortName = org['short-name'] orgId = org['orgId'] client = org['jira-project'] deviceName = str(notification['deviceInfo']['deviceName']) summary = str(notification['threatInfo']['summary']) severity = int(SEVERITIES[int( notification['threatInfo']['score'])]) date_created = int(notification['eventTime']) source_ref = "{}-{}".format( orgShortName, str(notification['threatInfo']['incidentId'])) sensor_id = str(notification['deviceInfo']['deviceId']) offense_id = str(notification['threatInfo']['incidentId']) tags = [] customFields = CustomFieldHelper()\ .add_string('client', client)\ .add_string('sensorID', sensor_id)\ .add_string('hostname', deviceName)\ .build() artifacts = artifactCrafter(notification, theHiveConnector, tags) artifacts.append( AlertArtifact(dataType='carbon_black_alert_id', data=offense_id, message="ID of alert in Carbon Black", tags=[offense_id], ignoreSimilarity=True)) alert = theHiveConnector.craftAlert( title=summary, description=descriptionCrafter(notification, orgName, orgId), severity=severity, date=date_created, tags=tags, tlp=2, status="New", type='EDR', source='Carbon Black', sourceRef=source_ref, artifacts=artifacts, caseTemplate='Carbon Black Case', customFields=customFields) try: ret = theHiveConnector.createAlert(alert) logger.info('Alert {} created in TheHive'.format( str(ret['id']))) except ValueError: logger.warning('Failed to create alert trying to update') try: ret = theHiveConnector.updateAlert( alert.sourceRef, alert) logger.info('Alert {} updated in TheHive'.format( str(ret['id']))) except ValueError as error: logger.error( "Failed to create alert ! {}".format(error)) result['success'] = True except Exception as error: result['success'] = False result['message'] = str(error) return result