diff --git a/examples/get_csv.py b/examples/get_csv.py new file mode 100755 index 0000000..33baf62 --- /dev/null +++ b/examples/get_csv.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import argparse + +from pymisp import PyMISP +from keys import misp_url, misp_key, misp_verifycert + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Get MISP stuff as CSV.') + parser.add_argument("-e", "--event_id", help="Event ID to fetch. Without it, it will fetch the whole database.") + parser.add_argument("-a", "--attribute", nargs='+', help="Attribute column names") + parser.add_argument("-o", "--object_attribute", nargs='+', help="Object attribute column names") + parser.add_argument("-t", "--misp_types", nargs='+', help="MISP types to fetch (ip-src, hostname, ...)") + parser.add_argument("-c", "--context", action='store_true', help="Add event level context (tags...)") + parser.add_argument("-i", "--ignore", action='store_true', help="Returns the attributes even if the event isn't published, or the attribute doesn't have the to_ids flag") + parser.add_argument("-f", "--outfile", help="Output file to write the CSV.") + + args = parser.parse_args() + pymisp = PyMISP(misp_url, misp_key, misp_verifycert, debug=True) + response = pymisp.get_csv(args.event_id, args.attribute, args.object_attribute, args.misp_types, args.context, args.ignore) + + if args.outfile: + with open(args.outfile, 'w') as f: + f.write(response) + else: + print(response) diff --git a/pymisp/api.py b/pymisp/api.py index c7b43ef..0ce9eaf 100644 --- a/pymisp/api.py +++ b/pymisp/api.py @@ -515,8 +515,6 @@ class PyMISP(object): event_id = e.uuid return event_id - - def add_named_attribute(self, event, type_value, value, category=None, to_ids=False, comment=None, distribution=None, proposal=False, **kwargs): """Add one or more attributes to an existing event""" attributes = [] @@ -1329,7 +1327,7 @@ class PyMISP(object): edit_user = MISPUser() edit_user.from_dict(**kwargs) url = urljoin(self.root_url, 'admin/users/edit/{}'.format(user_id)) - response = self.__prepare_request('POST', url, json.dumps(edit_user)) + response = self.__prepare_request('POST', url, edit_user.to_json()) return self._check_response(response) def edit_user_json(self, json_file, user_id): @@ -1367,7 +1365,7 @@ class PyMISP(object): if 'uuid' not in new_org: raise PyMISPError('A remote org MUST have a valid uuid') url = urljoin(self.root_url, 'admin/organisations/add/') - response = self.__prepare_request('POST', url, json.dumps(new_org)) + response = self.__prepare_request('POST', url, new_org.to_json()) return self._check_response(response) def add_organisation_json(self, json_file): @@ -1386,7 +1384,7 @@ class PyMISP(object): edit_org = MISPOrganisation() edit_org.from_dict(**kwargs) url = urljoin(self.root_url, 'admin/organisations/edit/{}'.format(org_id)) - response = self.__prepare_request('POST', url, json.dumps(edit_org)) + response = self.__prepare_request('POST', url, edit_org.to_json()) return self._check_response(response) def edit_organisation_json(self, json_file, org_id): @@ -1550,6 +1548,38 @@ class PyMISP(object): def get_stix(self, **kwargs): return self.get_stix_event(**kwargs) + def get_csv(self, eventid=None, attributes=[], object_attributes=[], misp_types=[], context=False, ignore=False): + """Get MISP values in CSV format + :param eventid: The event ID to query + :param attributes: The column names to export from normal attributes (i.e. uuid, value, type, ...) + :param object_attributes: The column names to export from attributes within objects (i.e. uuid, value, type, ...) + :param misp_types: MISP types to get (i.e. ip-src, hostname, ...) + :param context: Add event level context (event_info,event_member_org,event_source_org,event_distribution,event_threat_level_id,event_analysis,event_date,event_tag) + :param ignore: Returns the attributes even if the event isn't published, or the attribute doesn't have the to_ids flag set + """ + url = urljoin(self.root_url, '/events/csv/download') + to_post = {} + if eventid: + to_post['eventid'] = eventid + if attributes: + to_post['attributes'] = attributes + if object_attributes: + to_post['object_attributes'] = object_attributes + if misp_types: + for t in misp_types: + if t not in self.types: + logger.warning('{} is not a valid type'.format(t)) + to_post['type'] = misp_types + if context: + to_post['includeContext'] = True + if ignore: + to_post['ignore'] = True + if to_post: + response = self.__prepare_request('POST', url, json.dumps(to_post), output_type='json') + else: + response = self.__prepare_request('POST', url, output_type='json') + return response.text + # ########################### # ######## Feed ######### # ###########################