Пример #1
0
 def _search_local_hashes(self, event, open_session=True):
     local = []
     samples_count = 0
     if isinstance(event, MISPEvent):
         misp_event = event
     elif event.get('Event') is None:
         self.log('error', event)
         return
     else:
         misp_event = MISPEvent()
         misp_event.load(event)
     if not hasattr(misp_event, 'id'):
         # The event doesn't exists upstream, breaking.
         return
     for a in misp_event.attributes + [
             attribute for obj in misp_event.objects
             for attribute in obj.attributes
     ]:
         row = None
         if a.type == 'malware-sample':
             samples_count += 1
         if a.type in ('md5', 'sha1', 'sha256'):
             row = Database().find(key=a.type, value=a.value)
         elif a.type in ('filename|md5', 'filename|sha1',
                         'filename|sha256'):
             row = Database().find(key=a.type.split('|')[1],
                                   value=a.value.split('|')[1])
         elif a.type == 'malware-sample':
             row = Database().find(key='md5', value=a.value.split('|')[1])
         if row:
             local.append(row[0])
     self.log(
         'info',
         'Event {} contains {} samples.'.format(misp_event.id,
                                                samples_count))
     if not open_session:
         return
     shas = set([l.sha256 for l in local])
     if len(shas) == 1:
         __sessions__.new(get_sample_path(shas.pop()),
                          MispEvent(misp_event, self.offline_mode))
     elif len(shas) > 1:
         self.log('success',
                  'The following samples are in this viper instance:')
         __sessions__.new(
             misp_event=MispEvent(misp_event, self.offline_mode))
         for s in shas:
             self.log('item', s)
     else:
         __sessions__.new(
             misp_event=MispEvent(misp_event, self.offline_mode))
         self.log('info', 'No known (in Viper) samples in that event.')
Пример #2
0
 def test_mispevent(self, capsys, filename):
     mispevent = MispEvent(os.path.join(FIXTURE_DIR, filename))
     mispevent.online()
     mispevent.offline()
     ips = mispevent.get_all_ips()
     domains = mispevent.get_all_domains()
     urls = mispevent.get_all_urls()
     hashes = mispevent.get_all_hashes()
     assert '191.101.230.149' in ips
     assert not domains
     assert not urls
     assert '722050c1b3f110c0ac9f80bc80723407' in hashes[0]
     assert not hashes[1]
Пример #3
0
    def misp(self, option, verbose=False, submit=False):
        if option == 'download_all':
            for event in self._get_local_events(
                    os.path.join(self.cur_path, 'misp_events')):
                self._download_hashes(MispEvent(event), False)
            return

        if not __sessions__.is_attached_misp():
            return

        if option == 'hashes':
            ehashes, shashes = __sessions__.current.misp_event.get_all_hashes()
            to_scan = sorted(ehashes + shashes, key=len)
            while to_scan:
                h = to_scan.pop()
                response = self.scan(h, verbose)
                if response and not isinstance(response, bool):
                    to_scan = [eh for eh in to_scan if eh not in response]
        elif option == 'download':
            self._download_hashes(__sessions__.current.misp_event, verbose)
        elif option == "ips":
            ips = __sessions__.current.misp_event.get_all_ips()
            for ip in ips:
                self.pdns_ip(ip, verbose)
        elif option == "domains":
            domains = __sessions__.current.misp_event.get_all_domains()
            for d in domains:
                self.pdns_domain(d, verbose)
        elif option == "urls":
            urls = __sessions__.current.misp_event.get_all_urls()
            for u in urls:
                self.url(u, verbose, submit)
Пример #4
0
 def publish(self):
     current_event = copy.deepcopy(__sessions__.current.misp_event.event)
     event = self.misp.publish(current_event)
     if not self._has_error_message(event):
         self.log('success',
                  'Event {} published.'.format(event['Event']['id']))
         __sessions__.new(misp_event=MispEvent(event))
Пример #5
0
def open_samples(self):
    if self.args.list:
        self._display_tmp_files()
    elif self.args.delete:
        if self.args.delete != 'all':
            try:
                int(self.args.delete)
            except Exception:
                self.log(
                    'error',
                    'You can only delete all the samples of the samples of a specific event ID.'
                )
                return
        if self._clean_tmp_samples(self.args.delete):
            self.log('success', 'Successfully removed.')
        else:
            self.log('error', 'Nothing to remove.')
    else:
        tmp_samples = self._load_tmp_samples()
        try:
            eid, path, name = tmp_samples[int(self.args.sid)]
        except IndexError:
            self.log('error', 'Invalid sid, please use misp open -l.')
            return
        event = self.misp.get(eid)
        if not self._has_error_message(event):
            return __sessions__.new(path, MispEvent(event, self.offline_mode))
Пример #6
0
    def download(self):
        ok = False
        data = None
        if self.args.hash:
            ok, data = self.misp.download_samples(sample_hash=self.args.hash)
        else:
            event_id = self._get_eventid()
            if event_id is None:
                return
            ok, data = self.misp.download_samples(event_id=event_id)

        if not ok:
            self.log('error', data)
            return
        to_print = []
        for d in data:
            eid, filename, payload = d
            path = os.path.join(tempfile.gettempdir(), filename)
            with open(path, 'w') as f:
                f.write(payload.getvalue())
            to_print.append((eid, path))

        if len(to_print) == 1:
            self.log(
                'success',
                'The sample has been downloaded from Event {}'.format(
                    to_print[0][0]))
            event = self.misp.get(to_print[0][0])
            if not self._has_error_message(event):
                return __sessions__.new(to_print[0][1], MispEvent(event))
        else:
            self.log('success', 'The following files have been downloaded:')
            for p in to_print:
                self.log('success', '\tEventID: {} - {}'.format(*p))
Пример #7
0
 def upload(self):
     if self.offline_mode:
         self.log('error', 'Offline mode, unable to upload a sample')
         return
     categ = self.categories.get(self.args.categ)
     if self.args.info is not None:
         info = ' '.join(self.args.info)
     else:
         info = None
     if self.args.comment is not None:
         comment = ' '.join(self.args.comment)
     else:
         comment = None
     # No need to check the output: is the event_id is none, we create a new one.
     event_id = self._get_eventid(True)
     try:
         result = self.misp.upload_sample(__sessions__.current.file.name, __sessions__.current.file.path,
                                          event_id, self.args.distrib, self.args.ids, categ, info, comment,
                                          self.args.analysis, self.args.threat)
     except Exception as e:
         self.log('error', e)
         return
     if not self._has_error_message(result):
         self.log('success', "File uploaded successfully")
         if event_id is None:
             event_id = result['id']
         full_event = self.misp.get(event_id)
         if not self._has_error_message(full_event):
             return __sessions__.new(misp_event=MispEvent(full_event, self.offline_mode))
Пример #8
0
def create_event(self):
    if self.args.threat is not None:
        # Dirty trick to keep consistency in the module: the threat level in the upload
        # API can go from 0 import to 3 but it is 1 to 4 in the event mgmt API.
        # It will be fixed in a near future, in the meantime, we do that:
        self.args.threat += 1

    if not self.args.info:
        self.log('error', 'Info field is required for a new event')
    info = ' '.join(self.args.info)

    # Check if the following arguments have been set (and correctly set). If not, take the config values
    self.args.distrib = self.distribution if self.args.distrib is None else self.args.distrib
    self.args.sharing = self.sharinggroup if self.args.sharing is None else self.args.sharing

    if self.args.sharing and self.args.distrib != 4:
        self.args.sharing = None
        self.log('info', "Sharing group can only be set if distribution is 4. Clearing set value")

    misp_event = MISPEvent()
    misp_event.from_dict(info=info, distribution=self.args.distrib,
                         sharing_group_id=self.args.sharing, threat_level_id=self.args.threat,
                         analysis=self.args.analysis, date=self.args.date)
    self._search_local_hashes(misp_event)
    if self.offline_mode:
        # New event created locally, no ID
        __sessions__.current.misp_event.current_dump_file = self._dump()
        __sessions__.current.misp_event.offline()
    else:
        misp_event = self.misp.add_event(misp_event)
        if self._has_error_message(misp_event):
            return
        __sessions__.new(misp_event=MispEvent(misp_event, self.offline_mode))
        self._dump()
Пример #9
0
 def store(self):
     try:
         event_path = os.path.join(self.cur_path, 'misp_events')
         if not os.path.exists(event_path):
             os.mkdir(event_path)
         if self.args.list:
             header = ['Event ID', 'Title']
             rows = []
             for eid, path, title in self._get_local_events(event_path):
                 rows.append((eid, title))
             self.log('table', dict(header=header, rows=sorted(rows, key=lambda i: (int(i[0])))))
         elif self.args.update:
             for eid, path, title in self._get_local_events(event_path):
                 event = self.misp.get(eid)
                 with open(path, 'w') as f:
                     f.write(json.dumps(event))
                 self.log('success', '{} updated successfully.'.format(eid))
         elif self.args.delete:
             path = os.path.join(event_path, '{}.json'.format(self.args.delete))
             if os.path.exists(path):
                 os.remove(path)
                 self.log('success', '{} removed successfully.'.format(self.args.delete))
             else:
                 self.log('error', '{} does not exists.'.format(self.args.delete))
         elif self.args.open:
             path = os.path.join(event_path, '{}.json'.format(self.args.open))
             if os.path.exists(path):
                 e_json = json.loads(open(path, 'r').read())
                 __sessions__.new(misp_event=MispEvent(e_json))
             else:
                 self.log('error', '{} does not exists.'.format(self.args.open))
         elif __sessions__.is_attached_misp():
             self._dump(__sessions__.current.misp_event.event)
     except IOError as e:
         self.log('error', e.strerror)
Пример #10
0
 def test_mispevent(self, capsys, filename):
     mispevent = MispEvent(os.path.join(FIXTURE_DIR, filename))
     mispevent.online()
     mispevent.offline()
     ips = mispevent.get_all_ips()
     domains = mispevent.get_all_domains()
     urls = mispevent.get_all_urls()
     hashes = mispevent.get_all_hashes()
     assert '191.101.230.149' in ips
     assert not domains
     assert not urls
     assert '722050c1b3f110c0ac9f80bc80723407' in hashes[0]
     assert not hashes[1]
Пример #11
0
    def download(self):
        ok = False
        data = None
        if self.args.hash:
            ok, data = self.misp.download_samples(sample_hash=self.args.hash)
        elif self.args.list is not None:
            list_events = []
            if len(self.args.list) == 0:
                event_path = os.path.join(self.cur_path, 'misp_events')
                for eid, path, title in self._get_local_events(event_path):
                    list_events.append(eid)
            else:
                list_events = self.args.list

            all_data = []
            for eid in list_events:
                event = self.misp.get(eid)
                ok, data = self.misp.download_samples(
                    event_id=event['Event']['id'])
                if not ok:
                    self.log('error', data)
                    continue
                if data:
                    all_data += data
            data = all_data
        else:
            event_id = self._get_eventid()
            if event_id is None:
                return
            ok, data = self.misp.download_samples(event_id=event_id)

            if not ok:
                self.log('error', data)
                return
        to_print = []
        samples_path = os.path.join(self.cur_path, 'misp_samples')
        for d in data:
            eid, filename, payload = d
            path = os.path.join(samples_path, eid, filename)
            if not os.path.exists(os.path.dirname(path)):
                os.makedirs(os.path.dirname(path))
            with open(path, 'w') as f:
                f.write(payload.getvalue())
            to_print.append((eid, path))

        if len(to_print) == 1:
            self.log(
                'success',
                'The sample has been downloaded from Event {}'.format(
                    to_print[0][0]))
            event = self.misp.get(to_print[0][0])
            if not self._has_error_message(event):
                return __sessions__.new(to_print[0][1], MispEvent(event))
        elif len(to_print) > 1:
            self.log('success', 'The following files have been downloaded:')
            self._display_tmp_files()
        else:
            self.log('warning', 'No samples available.')
Пример #12
0
 def _search_local_hashes(self, event, open_session=True):
     local = []
     samples_count = 0
     if event.get('Event') is None:
         self.log('error', event)
         return
     for a in event['Event']['Attribute']:
         row = None
         if a['type'] == 'malware-sample':
             samples_count += 1
         if a['type'] in ('malware-sample', 'filename|md5', 'md5'):
             h = a['value']
             if '|' in a['type']:
                 h = a['value'].split('|')[1]
             row = Database().find(key='md5', value=h)
         elif a['type'] in ('sha1', 'filename|sha1'):
             h = a['value']
             if '|' in a['type']:
                 h = a['value'].split('|')[1]
             row = Database().find(key='sha1', value=h)
         elif a['type'] in ('sha256', 'filename|sha256'):
             h = a['value']
             if '|' in a['type']:
                 h = a['value'].split('|')[1]
             row = Database().find(key='sha256', value=h)
         if row:
             local.append(row[0])
     self.log(
         'info',
         'Event {} contains {} samples.'.format(event['Event']['id'],
                                                samples_count))
     if not open_session:
         return
     shas = set([l.sha256 for l in local])
     if len(shas) == 1:
         __sessions__.new(get_sample_path(shas.pop()), MispEvent(event))
     elif len(shas) > 1:
         self.log('success',
                  'The following samples are in this viper instance:')
         __sessions__.new(misp_event=MispEvent(event))
         for s in shas:
             self.log('item', s)
     else:
         __sessions__.new(misp_event=MispEvent(event))
         self.log('info', 'No known (in Viper) samples in that event.')
Пример #13
0
def _populate(self, event, original_attributes):
    if len(event.attributes) == original_attributes:
        self.log('info', "No new attributes to add.")
        return
    event.timestamp = int(time.time())
    result = self.misp.update(event._json())
    if not self._has_error_message(result):
        self.log('success', "All attributes updated successfully")
        __sessions__.new(misp_event=MispEvent(result, self.offline_mode))
Пример #14
0
 def publish(self):
     __sessions__.current.misp_event.event.publish()
     if self.offline_mode:
         self._dump()
     else:
         event = self.misp.update(__sessions__.current.misp_event.event)
         if not self._has_error_message(event):
             self.log('success', 'Event {} published.'.format(event['Event']['id']))
             __sessions__.new(misp_event=MispEvent(event, self.offline_mode))
Пример #15
0
def _populate(self, event):
    result = self.misp.update(event)

    if not self._has_error_message(result):
        self.log('success', "All attributes updated successfully")
        event_id = self._get_eventid()
        if event_id is None:
            return
        event = self.misp.get(event_id)
        if self._has_error_message(event):
            return
        __sessions__.new(misp_event=MispEvent(event, self.offline_mode))
Пример #16
0
 def _populate(self, event, attributes):
     if len(attributes) == 0:
         self.log('info', "No new attributes to add.")
         return
     to_send = {'Event': {'id': int(event['id']), 'uuid': event['uuid'],
                          'date': event['date'], 'distribution': event['distribution'],
                          'threat_level_id': event['threat_level_id'],
                          'analysis': event['analysis'], 'Attribute': attributes,
                          'timestamp': int(time.time())}}
     result = self.misp.update(to_send)
     if not self._has_error_message(result):
         self.log('success', "All attributes updated sucessfully")
         __sessions__.new(misp_event=MispEvent(result))
Пример #17
0
 def _check_add(self, new_event):
     if not new_event.get('Event'):
         self.log('error', new_event)
         return
     old_related = self._find_related_id(__sessions__.current.misp_event.event.get('Event'))
     new_related = self._find_related_id(new_event.get('Event'))
     old_related_ids = [i[0] for i in old_related]
     for related, title in new_related:
         if related not in old_related_ids:
             self.log('success', u'New related event: {}/events/view/{} - {}'.format(self.url.rstrip('/'), related, title))
         else:
             self.log('info', 'Related event: {}/events/view/{} - {}'.format(self.url.rstrip('/'), related, title))
     __sessions__.new(misp_event=MispEvent(new_event))
Пример #18
0
def _check_add(self, new_event):
    old_related = self._find_related_id(__sessions__.current.misp_event.event)
    new_related = self._find_related_id(new_event)
    old_related_ids = [i[0] for i in old_related]
    for related, title in new_related:
        if related not in old_related_ids:
            self.log(
                'success', 'New related event: {}/events/view/{} - {}'.format(
                    self.url.rstrip('/'), related, title))
        else:
            self.log(
                'info', 'Related event: {}/events/view/{} - {}'.format(
                    self.url.rstrip('/'), related, title))
    __sessions__.new(misp_event=MispEvent(new_event, self.offline_mode))
Пример #19
0
 def test_opened_session(self, capsys, filename, command, expected):
     if filename == "chromeinstall-8u31.exe":
         __sessions__.new(path=os.path.join(FIXTURE_DIR, filename))
     elif filename == '58e902cd-dae8-49b9-882b-186c02de0b81.json':
         me = MispEvent(os.path.join(FIXTURE_DIR, filename), True)
         __sessions__.new(misp_event=me)
     instance = console.Console()
     if sys.version_info <= (3, 0):
         in_fct = 'viper.core.ui.console.input'
     else:
         in_fct = 'builtins.input'
     with mock.patch(in_fct, return_value='{};exit'.format(command)):
         instance.start()
     out, err = capsys.readouterr()
     assert re.search(r".*{}.*".format(expected), out)
Пример #20
0
def store(self):
    try:
        event_path = os.path.join(self.cur_path, 'misp_events')
        if not os.path.exists(event_path):
            os.mkdir(event_path)
        if self.args.list:
            header = ['Event ID', 'Title']
            rows = []
            for eid, path, title in self._get_local_events(event_path):
                rows.append((eid, title))
            self.log(
                'table',
                dict(header=header,
                     rows=sorted(rows,
                                 key=lambda i: (int(i[0].split('_')[-1])))))
        elif self.args.update:
            if self.offline_mode:
                self.log('error',
                         'Offline mode, cannot update locally stored events.')
                return
            for eid, path, title in self._get_local_events(event_path):
                event = self.misp.get(eid)
                with open(path, 'w') as f:
                    f.write(json.dumps(event))
                self.log('success', '{} updated successfully.'.format(eid))
        elif self.args.sync:
            if self.offline_mode:
                self.log(
                    'error',
                    'Offline mode, cannot synchronize locally stored events.')
                return
            for eid, path, title in self._get_local_events(event_path):
                __sessions__.close()
                event = MISPEvent()
                event.load(path)
                if 'new_event_' in path:
                    event = self.misp.add_event(event.to_json())
                    try:
                        self._dump(event)
                        os.remove(path)
                    except Exception as e:
                        self.log('error',
                                 'Unable to create new event: {}.'.format(e))
                else:
                    eid = event.id
                    try:
                        event = self.misp.update(event._json())
                    except Exception as e:
                        self.log(
                            'error',
                            'Unable to update event {}: {}.'.format(eid, e))

                if self._has_error_message(event):
                    return
        elif self.args.delete:
            path = os.path.join(event_path, '{}.json'.format(self.args.delete))
            if os.path.exists(path):
                os.remove(path)
                self.log('success',
                         '{} removed successfully.'.format(self.args.delete))
            else:
                self.log('error',
                         '{} does not exists.'.format(self.args.delete))
        elif self.args.open:
            filename = '{}.json'.format(self.args.open)
            path = os.path.join(event_path, filename)
            if os.path.exists(path):
                try:
                    with open(path, 'r') as f:
                        e_json = json.load(f)
                    __sessions__.new(
                        misp_event=MispEvent(e_json, self.offline_mode))
                    __sessions__.current.misp_event.current_dump_file = filename
                except Exception as e:
                    self.log('error', 'Unable to open {}: {}'.format(path, e))
            else:
                self.log('error', '{} does not exists.'.format(self.args.open))
        elif __sessions__.is_attached_misp():
            self._dump()
    except IOError as e:
        self.log('error', e.strerror)