Esempio n. 1
0
class MispConnector():  # TODO: Switch to ExpandedPyMISP
    misp = None
    tagsGenerated = False
    tags = None

    def __init__(self, url, apiKey):
        self.misp = ExpandedPyMISP(url, apiKey, MISP_VERIFYCERT, debug=False)
        self.tags = self.generate_misp_tags()

    def generate_misp_tags(self) -> List[MISPTag]:
        tagList = []
        tags = [
            {
                'name': 'AutoGenerated',
                'colour': '#00ace6',
                'exportable': True
            },
            {
                'name': 'HoneytrapEvent',
                'colour': '#581845',
                'exportable': True
            },
            {
                'name': 'ModSecurity',
                'colour': '#a04000',
                'exportable': True
            },
        ]
        try:
            for item in tags:
                tag = MISPTag()
                for key in item:
                    tag[key] = item[key]
                self.misp.add_tag(tag, pythonify=True)
                tagList.append(tag)
            log.info("MISP tags generated")
            return tagList
        except PyMISPError as e:
            raise RuntimeError("Failed to initialise MISP tags")

    def send_misp_event(self, json_log):
        logEvent = ModsecLog(json_log)
        event = self.generate_event(logEvent)
        self.misp.add_event(event)
        log.debug(event)

    def generate_event(self, modsecLog: ModsecLog) -> MISPEvent:
        event = MISPEvent()
        event.info = modsecLog.generateInfoLine()
        [http_method, url, http_version] = modsecLog.getRequestLine()
        event.add_attribute(
            type='ip-src|port',
            value=str(modsecLog.log['transaction']['remote_address']) + "|" +
            str(modsecLog.log['transaction']['remote_port']),
            comment="Attacker",
            pythonify=True)
        event.add_attribute(
            type='ip-dst|port',
            value=str(modsecLog.log['transaction']['local_address']) + "|" +
            str(modsecLog.log['transaction']['local_port']),
            comment="Server",
            pythonify=True)
        event.add_attribute(type='http-method',
                            value=http_method,
                            pythonify=True)
        event.add_attribute(type='url', value=url, pythonify=True)
        event.add_attribute(type='datetime',
                            value=modsecLog.log['@timestamp'],
                            pythonify=True)
        event.add_attribute(type='other',
                            value=modsecLog.log['audit_data']['producer'],
                            comment="Producer",
                            pythonify=True)
        event.add_attribute(type='text',
                            value=json.dumps(modsecLog.log, indent=2),
                            comment="Json log",
                            pythonify=True)
        #event.add_attribute(type='vulnerability', value=json_log['transaction']['time'], pythonify=True)
        for tag in self.tags:
            event.add_tag(tag)
        log.debug("elasticsearch data")
        log.debug(json.dumps(modsecLog.log, indent=2))
        return event
Esempio n. 2
0
class MISPController(object):
    ''' MISP Controller '''
    def __init__(self, misp_param, debug=False):
        self.misp_param = misp_param
        self.debug = debug

        if misp_param.get('connect_immediately', False):
            self._connect()
        else:
            self.misp = None

    def import_event(self, event_data):
        ''' Import event '''

        # Check registered same event info
        print('importing: {}'.format(event_data['title']))
        events = self._search_event(eventinfo=event_data['title'])
        if events != None:
            for event in events:
                if event_data['title'] == event['Event']['info']:
                    self._remove_event(event['Event']['id'])

        event = self._add_event(event_data)
        if event:
            print('created event: {}'.format(event.id))
        else:
            print("Import failed.Please retry: {}".format(event_data['title']))

    def _connect(self):
        self.debug_print('URL: {}'.format(self.misp_param['url']))
        self.debug_print('authkey: {}'.format(self.misp_param['authkey']))
        self.misp = ExpandedPyMISP(self.misp_param['url'],
                                   self.misp_param['authkey'],
                                   ssl=False,
                                   debug=False)
        self._registered_tags = self.misp.tags()

    def _check_tag(self, target_tag):

        if self.misp == None:
            self._connect()

        if self._registered_tags == None:
            self._get_tags()

        for tag_info in self._registered_tags:
            if tag_info.get('name', '') == target_tag:
                return True

        self.debug_print('new tag: {}'.format(target_tag))

        cnt = 0
        while True:
            try:
                if self.misp == None:
                    self._connect()

                tmp = MISPTag()
                tmp.from_dict(name=target_tag)
                self.misp.add_tag(tmp)
                self._get_tags()
                return True

            except:
                print(traceback.format_exc())

                if cnt < int(self.misp_param.get('max_retry_count', '0')):
                    print('add new tag retry: {}'.format(cnt))
                    cnt = cnt + 1
                    time.sleep(10)
                else:
                    return False

    def _add_event(self, value):

        for tag in value['event_tags']:
            self._check_tag(tag)

        for attribute in value['attributes']:
            for tag in attribute['tags']:
                self._check_tag(tag)

        cnt = 0
        while True:
            try:

                if self.misp == None:
                    self._connect()

                tmp = MISPEvent()
                tmp.from_dict(
                    distribution=self.misp_param['distribution'],
                    threat_level_id=self.misp_param['threat_level_id'],
                    analysis=self.misp_param['analysis'],
                    info=value['title'],
                    date=value['date'],
                    published=False)
                response = self.misp.add_event(tmp)
                if response.get('errors'):
                    raise Exception(str(response['errors']))

                event = MISPEvent()
                event.load(response)
                break

            except:
                print(traceback.format_exc())

                if cnt < int(self.misp_param.get('max_retry_count', '0')):
                    print('add new event retry: {}'.format(cnt))
                    cnt = cnt + 1
                    time.sleep(10)
                else:
                    return None

        self.debug_print(event.id)

        for tag in value['event_tags']:
            event.add_tag(tag)

        for attribute in value['attributes']:
            attribute_tags = []

            event.add_attribute(type=attribute['type'],
                                value=attribute['value'],
                                category=attribute['category'],
                                comment=attribute.get('comment', ''),
                                distribution=self.misp_param['distribution'],
                                Tag=self._create_tags(attribute['tags']))

        event.published = True

        if self._update_event(event):
            self.debug_print('completed')
            return event
        else:
            self.debug_print('add failed')
            return None

    def _get_event(self, id):

        cnt = 0
        while True:
            try:
                if self.misp == None:
                    self._connect()

                self.debug_print('get event start: {}'.format(id))
                event = self.misp.get_event(id)
                if event.get('errors'):
                    raise Exception(str(event['errors']))

                self.debug_print('get event end: {}'.format(id))

                return event

            except:
                print(traceback.format_exc())

                if cnt < int(self.misp_param.get('max_retry_count', '0')):
                    print('get event retry: {}'.format(cnt))
                    cnt = cnt + 1
                    time.sleep(10)
                else:
                    return None

    def _remove_event(self, id):

        if id:
            print('delete event: {}'.format(id))
            cnt = 0
            while True:
                try:
                    if self.misp == None:
                        self._connect()

                    response = self.misp.delete_event(id)
                    if response.get('errors'):
                        raise Exception(str(response['errors']))

                    return True

                except:
                    print(traceback.format_exc())

                    if cnt < int(self.misp_param.get('max_retry_count', '0')):
                        print('remove event retry: {}'.format(cnt))
                        cnt = cnt + 1
                        time.sleep(10)
                    else:
                        return False

    def _search_event(self, **cons):

        cnt = 0
        while True:
            try:
                if self.misp == None:
                    self._connect()

                self.debug_print('search event start')
                response = self.misp.search_index(**cons)
                self.debug_print('search event end')

                results = []
                for json in response:

                    if json.get('id', ''):
                        results.append(self._get_event(json['id']))
                    else:
                        print('no event ID')
                        print(json)

                return results

            except:
                print(traceback.format_exc())

                if cnt < int(self.misp_param.get('max_retry_count', '0')):
                    print('search event retry: {}'.format(cnt))
                    cnt = cnt + 1
                    time.sleep(10)
                else:
                    return None

    def _update_event(self, event):
        cnt = 0

        while True:
            try:
                if self.misp == None:
                    self._connect()

                self.debug_print('event update start: {}'.format(event.id))
                response = self.misp.update_event(event)
                if response.get('errors'):
                    raise Exception(str(response['errors']))

                self.debug_print('{} updated'.format(event.id))
                return True

            except:
                print(traceback.format_exc())

                if cnt < int(self.misp_param.get('max_retry_count', '0')):
                    print('retry: {}'.format(cnt))
                    cnt = cnt + 1
                    time.sleep(10)
                else:
                    print('event update failed: {}'.format(event.info))
                    try:
                        self._remove_event(event.id)
                    except:
                        pass
                    return False

    def _create_tags(self, values):
        tags = []

        for value in values:
            if value:
                tags.append({'name': value})

        return tags

    def debug_print(self, message):
        if self.debug == False:
            return
#		nowstr = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        nowstr = datetime.datetime.now().strftime('%H:%M:%S')

        print('{}\t{}'.format(nowstr, message))