Exemple #1
0
 def __init__(self, webhook, cfg):
     logger.info('Initiating AzureSentinel Automation')
     self.TheHiveConnector = TheHiveConnector(cfg)
     self.AzureSentinelConnector = AzureSentinelConnector(cfg)
     self.webhook = webhook
     self.cfg = cfg
     self.report_action = report_action
Exemple #2
0
    def __init__(self, webhook, cfg, automation_config):
        """
            Class constructor

            :return: use case report
            :rtype: API call
        """
        self.logger = logging.getLogger(__name__)
        self.logger.info('Initiating Siem Integration')

        self.cfg = cfg
        self.app_dir = os.path.dirname(os.path.abspath(__file__)) + "/.."
        self.automation_config = automation_config
        self.TheHiveConnector = TheHiveConnector(cfg)
        self.webhook = webhook

        if cfg.getboolean('Automation', 'enable_customer_list',
                          fallback=False):
            self.logger.info('Loading Customer configuration')
            #Load optional customer config
            self.customer_cfg = ConfigParser(
                converters={
                    'list': lambda x: [i.strip() for i in x.split(';')]
                })
            self.confPath = self.app_dir + '/conf/customers.conf'
            try:
                self.logger.debug('Loading configuration from %s' %
                                  self.confPath)
                self.customer_cfg.read(self.confPath)
                self.customers = self.customer_cfg.sections()
                self.logger.debug('Loaded configuration for %s' %
                                  self.customers)
            except Exception as e:
                self.logger.error('%s', __name__, exc_info=True)
Exemple #3
0
 def __init__(self, webhook, cfg):
     logger.info('Initiating QRadarAutomation')
     self.TheHiveConnector = TheHiveConnector(cfg)
     self.QRadarConnector = QRadarConnector(cfg)
     self.webhook = webhook
     self.cfg = cfg
     self.report_action = report_action
Exemple #4
0
 def __init__(self, webhook, cfg):
     self.logger = logger
     self.logger.info('Initiating RD Automation')
     self.TheHiveConnector = TheHiveConnector(cfg)
     self.webhook = webhook
     self.cfg = cfg
     self.report_action = report_action
     self.RDConnector = RDConnector(cfg)
Exemple #5
0
    def __init__(self, cfg, use_case_config):
        self.logger = logging.getLogger(__name__)
        self.logger.info('Initiating QRadar Automators')

        self.cfg = cfg
        self.use_case_config = use_case_config
        self.TheHiveConnector = TheHiveConnector(cfg)
        self.TheHiveAutomators = TheHiveAutomators(cfg, use_case_config)
        self.QRadarConnector = QRadarConnector(cfg)
Exemple #6
0
 def __init__(self, webhook, cfg):
     logger.info('Initiating MISPautomation')
     self.TheHiveConnector = TheHiveConnector(cfg)
     if self.cfg.getboolean('Cortex', 'enabled'):
         self.CortexConnector = CortexConnector(cfg)
     self.webhook = webhook
     self.report_action = report_action
     self.qr_config = {}
     for key, value in cfg.items('QRadar'):
         self.qr_config[key] = value
Exemple #7
0
    def __init__(self, cfg, use_case_config):
        self.logger = logging.getLogger(__name__)
        self.logger.info('Initiating The Hive Automator')

        self.cfg = cfg
        self.TheHiveConnector = TheHiveConnector(cfg)
        if self.cfg.getboolean('Cortex', 'enabled'):
            self.CortexConnector = CortexConnector(cfg)

        #Read mail config
        self.mailsettings = self.cfg.get('TheHive', 'mail')
Exemple #8
0
 def __init__(self, webhook, cfg):
     logger.info('Initiating AzureSentinel Automation')
     self.TheHiveConnector = TheHiveConnector(cfg)
     self.AzureSentinelConnector = AzureSentinelConnector(cfg)
     self.webhook = webhook
     self.cfg = cfg
     self.report_action = report_action
     self.closure_status = {
         "Indeterminate": "Undetermined",
         "FalsePositive": "FalsePositive",
         "TruePositive": "TruePositive",
         "Other": "BenignPositive"
     }
    def __init__(self, webhookData, cfg):
        """
            Class constructor

            :param cfg: Synapse's config
            :type cfg: ConfigParser

            :param webhookData: the json webhook from TheHive
            :type webhookData: dict

            :return: Object Webhook
            :rtype: Webhook
        """

        self.logger = logging.getLogger('workflows.' + __name__)
        # One liner to generate a sha1 hash from the data to use as an id. Requires json to create a byte array from the dict
        self.id = hashlib.sha1(json.dumps(webhookData).encode('utf-8')).hexdigest()
        self.data = webhookData
        self.TheHiveConnector = TheHiveConnector(cfg)
        self.ext_alert_ids = []
Exemple #10
0
def ml2Alert(mlalert):
    """
       Parse the received ml watcher notification
       Original example Watch Actions:
       
        "TheHive": {
            "webhook": {
                "scheme": "http",
                "host": "machine.domain.com",
                "port": 5000,
                "method": "post",
                "path": "/ELK2alert",
                "params": {},
                "headers": {
                    "Authorization": "Bearer 2WTbTHH8iaSeoo8yk8y0GA96dX7/Tz7s",
                    "Cookie": "cookie=no",
                    "Content-Type": "application/json"
                },
                "body": "{\"ml_job_id\": \"{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0._source.job_id}}\",\n\"description\": \"some description\",\n\"start_time\": \"{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0.fields.timestamp_iso8601.0}}\",\n\"anomaly_score\": \"{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0.fields.score.0}}\",\n\"url\": \"https://machine.domain.com:5601/app/ml#/explorer/?_g=(ml:(jobIds:!('{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0._source.job_id}}')),refreshInterval:(display:Off,pause:!f,value:0),time:(from:'{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0.fields.start.0}}',mode:absolute,to:'{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0.fields.end.0}}'))&_a=(filters:!(),mlAnomaliesTable:(intervalValue:auto,thresholdValue:0),mlExplorerSwimlane:(selectedLane:Overall,selectedTime:{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0.fields.timestamp_epoch.0}},selectedType:overall),query:(query_string:(analyze_wildcard:!t,query:'**')))\",\n\"influencers\": \"{{ctx.payload.aggregations.record_results.top_record_hits.hits.hits}}\\n{{_source.function}}({{_source.field_name}}) {{_source.by_field_value}} {{_source.over_field_value}} {{_source.partition_field_value}} [{{fields.score.0}}]\\n{{ctx.payload.aggregations.record_results.top_record_hits.hits.hits}}\",\n\"type\": \"asml\",\n\"source\": \"Elastic\",\n\"sourceRef\": \"{{ctx.payload.as_watch_id}}\"}"
            }
        }

       Nice example input:
        "{
            \"ml_job_id\": \"{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0._source.job_id}}\",\n
            \"description\": \"some description\",\n
            \"start_time\": \"{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0.fields.timestamp_iso8601.0}}\",\n
            \"anomaly_score\": \"{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0.fields.score.0}}\",\n
            \"url\": \"https://machine.domain.com:5601/app/ml#/explorer/?_g=(ml:(jobIds:!('{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0._source.job_id}}')),refreshInterval:(display:Off,pause:!f,value:0),time:(from:'{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0.fields.start.0}}',mode:absolute,to:'{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0.fields.end.0}}'))&_a=(filters:!(),mlAnomaliesTable:(intervalValue:auto,thresholdValue:0),mlExplorerSwimlane:(selectedLane:Overall,selectedTime:{{ctx.payload.aggregations.bucket_results.top_bucket_hits.hits.hits.0.fields.timestamp_epoch.0}},selectedType:overall),query:(query_string:(analyze_wildcard:!t,query:'**')))\",\n
            \"influencers\": \"{{ctx.payload.aggregations.record_results.top_record_hits.hits.hits}}\\n
                               {{_source.function}}({{_source.field_name}}) {{_source.by_field_value}} {{_source.over_field_value}} {{_source.partition_field_value}} [{{fields.score.0}}]\\n
                               {{ctx.payload.aggregations.record_results.top_record_hits.hits.hits}}\",\n
            \"type\": \"asml\",\n
            \"source\": \"Elastic\",\n
            \"sourceRef\": \"{{ctx.payload.as_watch_id}}\"
        }"
    """
    #logger = logging.getLogger(__name__)
    logger.info('%s.ml2Alert starts', __name__)

    report = dict()
    report['success'] = True

    try:
        cfg = getConf()

        theHiveConnector = TheHiveConnector(cfg)

        #Map the ml watcher alert to the alert that will be enhanced
        logger.info('Looking for ML Alert %s in TheHive alerts',
                    str(mlalert['sourceRef']))

        #I should see if we can find a way to generate a shorter more useful sourceRef from within Synapse
        q = dict()
        q['sourceRef'] = str(mlalert['sourceRef'])
        results = theHiveConnector.findAlert(q)
        if len(results) == 0:
            logger.info('ML Alert %s not found in TheHive alerts, creating it',
                        str(mlalert['sourceRef']))
            mlalert_report = dict()

            #Set generic parameters
            mlalert['title'] = "ML: " + mlalert['ml_job_id']
            mlalert['description'] = craftMLAlertDescription(mlalert)
            mlalert['case_template'] = "ELK-ML"

            #Enrichment is not in scope yet
            #enrichedAlert = enrichAlert(elkConnector, mlalert)

            try:
                theHiveAlert = ELKToHiveAlert(theHiveConnector, mlalert)
                theHiveEsAlertId = theHiveConnector.createAlert(theHiveAlert)

                mlalert_report['raised_alert_id'] = theHiveEsAlertId
                mlalert_report['ml_alert_id'] = mlalert['sourceRef']
                mlalert_report['success'] = True

            except Exception as e:
                logger.error('%s.ml2Alert failed', __name__, exc_info=True)
                mlalert_report['success'] = False
                if isinstance(e, ValueError):
                    errorMessage = json.loads(str(e))['message']
                    mlalert_report['message'] = errorMessage
                else:
                    mlalert_report['message'] = str(
                        e) + ": Couldn't raise alert in TheHive"
                mlalert_report['ml_alert_id'] = mlalert['sourceRef']
                # Set overall success if any fails
                report['success'] = False

            report['mlalert'] = mlalert_report
        else:
            logger.info('ML Alert %s already imported as alert',
                        str(mlalert['sourceRef']))

    except Exception as e:

        logger.error('Failed to create alert from ML Alert', exc_info=True)
        report['success'] = False
        report['message'] = "%s: Failed to create alert from ML Alert" % str(e)

    return report
Exemple #11
0
def connectEws():
    logger = logging.getLogger(__name__)
    logger.info('%s.connectEws starts', __name__)

    report = dict()
    report['success'] = bool()

    try:
        cfg = getConf()

        ewsConnector = EwsConnector(cfg)
        folder_name = cfg.get('EWS', 'folder_name')
        unread = ewsConnector.scan(folder_name)

        TheHiveConnector = TheHiveConnector(cfg)

        for msg in unread:
            #type(msg)
            #<class 'exchangelib.folders.Message'>
            conversationId = msg.conversation_id.id

            #searching if case has already been created from the email
            #conversation
            esCaseId = TheHiveConnector.searchCaseByDescription(conversationId)

            if esCaseId is None:
                #no case previously created from the conversation
                caseTitle = str(msg.subject)
                caseDescription = ('```\n' + 'Case created by Synapse\n' +
                                   'conversation_id: "' +
                                   str(msg.conversation_id.id) + '"\n' + '```')
                if msg.categories:
                    assignee = msg.categories[0]
                else:
                    assignee = 'synapse'

                case = TheHiveConnector.craftCase(caseTitle, caseDescription)
                createdCase = TheHiveConnector.createCase(case)
                caseUpdated = TheHiveConnector.assignCase(
                    createdCase, assignee)

                commTask = TheHiveConnector.craftCommTask()
                esCaseId = caseUpdated.id
                commTaskId = TheHiveConnector.createTask(esCaseId, commTask)

            else:
                #case previously created from the conversation
                commTaskId = TheHiveConnector.getTaskIdByTitle(
                    esCaseId, 'Communication')

                if commTaskId != None:
                    pass
                else:
                    #case already exists but no Communication task found
                    #creating comm task
                    commTask = TheHiveConnector.craftCommTask()
                    commTaskId = TheHiveConnector.createTask(
                        esCaseId, commTask)

            fullBody = getEmailBody(msg)
            taskLog = TheHiveConnector.craftTaskLog(fullBody)
            createdTaskLogId = TheHiveConnector.addTaskLog(commTaskId, taskLog)

            readMsg = ewsConnector.markAsRead(msg)

            for attachmentLvl1 in msg.attachments:
                #uploading the attachment as file observable
                #is the attachment is a .msg, the eml version
                #of the file is uploaded
                tempAttachment = TempAttachment(attachmentLvl1)

                if not tempAttachment.isInline:
                    #adding the attachment only if it is not inline
                    #inline attachments are pictures in the email body
                    tmpFilepath = tempAttachment.writeFile()
                    to = str()
                    for recipient in msg.to_recipients:
                        to = to + recipient.email_address + ' '
                    comment = 'Attachment from email sent by '
                    comment += str(msg.author.email_address).lower()
                    comment += ' and received by '
                    comment += str(to).lower()
                    comment += ' with subject: <'
                    comment += msg.subject
                    comment += '>'
                    TheHiveConnector.addFileObservable(esCaseId, tmpFilepath,
                                                       comment)

                    if tempAttachment.isEmailAttachment:
                        #if the attachment is an email
                        #attachments of this email are also
                        #uploaded to TheHive
                        for attachmentLvl2 in tempAttachment.attachments:
                            tempAttachmentLvl2 = TempAttachment(attachmentLvl2)
                            tmpFilepath = tempAttachmentLvl2.writeFile()
                            comment = 'Attachment from the email attached'
                            TheHiveConnector.addFileObservable(
                                esCaseId, tmpFilepath, comment)

        report['success'] = True
        return report

    except Exception as e:
        logger.error('Failed to create case from email', exc_info=True)
        report['success'] = False
        return report
Exemple #12
0
 def __init__(self):
     super().__init__()
     self.mlabsConnector = MLabsConnector(self.cfg)
     self.theHiveConnector = TheHiveConnector(self.cfg)
Exemple #13
0
 def __init__(self):
     super().__init__()
     self.qradarConnector = QRadarConnector(self.cfg)
     self.TheHiveConnector = TheHiveConnector(self.cfg)
Exemple #14
0
 def __init__(self):
     super().__init__()
     self.lexsi = LexsiConnector(self.cfg)
     self.TheHiveConnector = TheHiveConnector(self.cfg)
Exemple #15
0
def logstash2Alert(event):
    """
       Parse the received ml watcher notification
       Original example logstash output:

       Nice example input:
        
    """
    #logger = logging.getLogger(__name__)
    logger.info('%s.logstash2Alert starts', __name__)

    report = dict()
    report['success'] = True

    try:
        cfg = getConf()

        theHiveConnector = TheHiveConnector(cfg)

        #Map the ml watcher alert to the alert that will be enhanced
        logger.info('Looking for Logstash Alert %s in TheHive alerts',
                    str(event['sourceRef']))

        #I should see if we can find a way to generate a shorter more useful sourceRef from within Synapse
        q = dict()
        q['sourceRef'] = str(event['sourceRef'])
        results = theHiveConnector.findAlert(q)
        if len(results) == 0:
            logger.info(
                'Logstash Alert %s not found in TheHive alerts, creating it',
                str(event['sourceRef']))
            event_report = dict()

            event['case_template'] = "ELK-Anomalies"

            #Enrichment is not in scope yet
            #enrichedAlert = enrichAlert(elkConnector, event)

            try:
                theHiveAlert = ELKToHiveAlert(theHiveConnector, event)
                theHiveEsAlertId = theHiveConnector.createAlert(theHiveAlert)

                event_report['raised_alert_id'] = theHiveEsAlertId
                event_report['alert_id'] = event['sourceRef']
                event_report['success'] = True

            except Exception as e:
                logger.error('%s.logstash2Alert failed',
                             __name__,
                             exc_info=True)
                event_report['success'] = False
                if isinstance(e, ValueError):
                    errorMessage = json.loads(str(e))['message']
                    event_report['message'] = errorMessage
                else:
                    event_report['message'] = str(
                        e) + ": Couldn't raise alert in TheHive"
                event_report['alert_id'] = event['sourceRef']
                # Set overall success if any fails
                report['success'] = False

            report['event'] = event_report
        else:
            logger.info('Logstash Alert %s already imported as alert',
                        str(event['sourceRef']))

    except Exception as e:

        logger.error('Failed to create alert from Logstash Alert',
                     exc_info=True)
        report['success'] = False
        report[
            'message'] = "%s: Failed to create alert from Logstash Alert" % str(
                e)

    return report
Exemple #16
0
 def __init__(self):
     super().__init__()
     self.azureSentinelConnector = AzureSentinelConnector(self.cfg)
     self.theHiveConnector = TheHiveConnector(self.cfg)
Exemple #17
0
 def __init__(self):
     super().__init__()
     self.RDConnector = RDConnector(self.cfg)
     self.TheHiveConnector = TheHiveConnector(self.cfg)
Exemple #18
0
 def __init__(self, webhook, cfg):
     logger.info('Initiating ELKAutomation')
     self.TheHiveConnector = TheHiveConnector(cfg)
     self.webhook = webhook
     self.report_action = report_action
     self.webhook = webhook