pymisp 2.5.7.1__py3-none-any.whl → 2.5.8.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pymisp might be problematic. Click here for more details.

Files changed (69) hide show
  1. pymisp/api.py +1 -0
  2. pymisp/data/misp-objects/objects/github-repo/definition.json +142 -0
  3. {pymisp-2.5.7.1.dist-info → pymisp-2.5.8.1.dist-info}/METADATA +4 -4
  4. {pymisp-2.5.7.1.dist-info → pymisp-2.5.8.1.dist-info}/RECORD +6 -68
  5. CHANGELOG.txt +0 -5393
  6. examples/__init__.py +0 -0
  7. examples/add_attributes_from_csv.py +0 -74
  8. examples/add_email_object.py +0 -29
  9. examples/add_fail2ban_object.py +0 -86
  10. examples/add_feed.py +0 -25
  11. examples/add_file_object.py +0 -47
  12. examples/add_filetype_object_from_csv.py +0 -53
  13. examples/add_generic_object.py +0 -26
  14. examples/add_github_user.py +0 -65
  15. examples/add_gitlab_user.py +0 -56
  16. examples/add_named_attribute.py +0 -25
  17. examples/add_organisations.py +0 -57
  18. examples/add_ssh_authorized_keys.py +0 -29
  19. examples/add_user.py +0 -22
  20. examples/add_vehicle_object.py +0 -22
  21. examples/addtag2.py +0 -45
  22. examples/asciidoc_generator.py +0 -114
  23. examples/cache_all.py +0 -10
  24. examples/copyTagsFromAttributesToEvent.py +0 -68
  25. examples/copy_list.py +0 -93
  26. examples/create_events.py +0 -26
  27. examples/cytomic_orion.py +0 -549
  28. examples/del.py +0 -22
  29. examples/delete_user.py +0 -16
  30. examples/edit_organisation.py +0 -20
  31. examples/edit_user.py +0 -20
  32. examples/falsepositive_disabletoids.py +0 -136
  33. examples/fetch_events_feed.py +0 -15
  34. examples/fetch_warninglist_hits.py +0 -38
  35. examples/freetext.py +0 -22
  36. examples/generate_file_objects.py +0 -78
  37. examples/generate_meta_feed.py +0 -15
  38. examples/get.py +0 -37
  39. examples/get_csv.py +0 -37
  40. examples/get_network_activity.py +0 -187
  41. examples/last.py +0 -48
  42. examples/load_csv.py +0 -94
  43. examples/lookup.py +0 -28
  44. examples/misp2cef.py +0 -71
  45. examples/misp2clamav.py +0 -52
  46. examples/openioc_to_misp.py +0 -27
  47. examples/proofpoint_tap.py +0 -203
  48. examples/proofpoint_vap.py +0 -65
  49. examples/search.py +0 -48
  50. examples/search_attributes_yara.py +0 -40
  51. examples/search_sighting.py +0 -42
  52. examples/server_sync_check_conn.py +0 -32
  53. examples/sharing_groups.py +0 -15
  54. examples/show_sightings.py +0 -168
  55. examples/stats_report.py +0 -405
  56. examples/sync_sighting.py +0 -171
  57. examples/tags.py +0 -25
  58. examples/test_sign.py +0 -19
  59. examples/trustar_misp.py +0 -59
  60. examples/up.py +0 -21
  61. examples/upload.py +0 -60
  62. examples/users_list.py +0 -15
  63. examples/vmray_automation.py +0 -281
  64. examples/vt_to_misp.py +0 -182
  65. examples/warninglists.py +0 -22
  66. examples/yara.py +0 -38
  67. examples/yara_dump.py +0 -98
  68. {pymisp-2.5.7.1.dist-info → pymisp-2.5.8.1.dist-info}/LICENSE +0 -0
  69. {pymisp-2.5.7.1.dist-info → pymisp-2.5.8.1.dist-info}/WHEEL +0 -0
examples/vt_to_misp.py DELETED
@@ -1,182 +0,0 @@
1
- ''' Convert a VirusTotal report into MISP objects '''
2
- import argparse
3
- import json
4
- import logging
5
- from datetime import datetime
6
- from urllib.parse import urlsplit
7
-
8
- import pymisp
9
- from pymisp.tools import VTReportObject
10
-
11
- logging.basicConfig(level=logging.INFO, format="%(asctime)s | %(levelname)s | %(module)s.%(funcName)s.%(lineno)d | %(message)s")
12
-
13
-
14
- def build_cli():
15
- '''
16
- Build the command-line arguments
17
- '''
18
- desc = "Take an indicator or list of indicators to search VT for and import the results into MISP"
19
- post_desc = """
20
- config.json: Should be a JSON file containing MISP and VirusTotal credentials with the following format:
21
- {"misp": {"url": "<url_to_misp>", "key": "<misp_api_key>"}, "virustotal": {"key": "<vt_api_key>"}}
22
- Please note: Only public API features work in the VTReportObject for now. I don't have a quarter million to spare ;)
23
-
24
- Example:
25
- python vt_to_misp.py -i 719c97a8cd8db282586c1416894dcaf8 -c ./config.json
26
- """
27
- parser = argparse.ArgumentParser(description=desc, epilog=post_desc, formatter_class=argparse.RawTextHelpFormatter)
28
- parser.add_argument("-e", "--event", help="MISP event id to add to")
29
- parser.add_argument("-c", "--config", default="config.json", help="Path to JSON configuration file to read")
30
- indicators = parser.add_mutually_exclusive_group(required=True)
31
- indicators.add_argument("-i", "--indicator", help="Single indicator to look up")
32
- indicators.add_argument("-f", "--file", help="File of indicators to look up - one on each line")
33
- indicators.add_argument("-l", "--link", help="Link to a VirusTotal report")
34
- return parser.parse_args()
35
-
36
-
37
- def build_config(path=None):
38
- '''
39
- Read a configuration file path. File is expected to be
40
-
41
- :path: Path to a configuration file
42
- '''
43
- try:
44
- with open(path, "r") as ifile:
45
- return json.load(ifile)
46
- except OSError:
47
- raise OSError("Couldn't find path to configuration file: %s", path)
48
- except json.JSONDecodeError:
49
- raise IOError("Couldn't parse configuration file. Please make sure it is a proper JSON document")
50
-
51
-
52
- def generate_report(indicator, apikey):
53
- '''
54
- Build our VirusTotal report object, File object, and AV signature objects
55
- and link them appropriately
56
-
57
- :indicator: Indicator hash to search in VT for
58
- '''
59
- report_objects = []
60
- vt_report = VTReportObject(apikey, indicator)
61
- report_objects.append(vt_report)
62
- raw_report = vt_report._report
63
- if vt_report._resource_type == "file":
64
- file_object = pymisp.MISPObject(name="file")
65
- file_object.add_attribute("md5", value=raw_report["md5"])
66
- file_object.add_attribute("sha1", value=raw_report["sha1"])
67
- file_object.add_attribute("sha256", value=raw_report["sha256"])
68
- vt_report.add_reference(referenced_uuid=file_object.uuid, relationship_type="report of")
69
- report_objects.append(file_object)
70
- elif vt_report._resource_type == "url":
71
- parsed = urlsplit(indicator)
72
- url_object = pymisp.MISPObject(name="url")
73
- url_object.add_attribute("url", value=parsed.geturl())
74
- url_object.add_attribute("host", value=parsed.hostname)
75
- url_object.add_attribute("scheme", value=parsed.scheme)
76
- url_object.add_attribute("port", value=parsed.port)
77
- vt_report.add_reference(referenced_uuid=url_object.uuid, relationship_type="report of")
78
- report_objects.append(url_object)
79
- for antivirus in raw_report["scans"]:
80
- if raw_report["scans"][antivirus]["detected"]:
81
- av_object = pymisp.MISPObject(name="av-signature")
82
- av_object.add_attribute("software", value=antivirus)
83
- signature_name = raw_report["scans"][antivirus]["result"]
84
- av_object.add_attribute("signature", value=signature_name, disable_correlation=True)
85
- vt_report.add_reference(referenced_uuid=av_object.uuid, relationship_type="included-in")
86
- report_objects.append(av_object)
87
- return report_objects
88
-
89
-
90
- def get_misp_event(event_id=None, info=None):
91
- '''
92
- Smaller helper function for generating a new MISP event or using a preexisting one
93
-
94
- :event_id: The event id of the MISP event to upload objects to
95
-
96
- :info: The event's title/info
97
- '''
98
- if event_id:
99
- event = misp.get_event(event_id)
100
- elif info:
101
- event = misp.new_event(info=info)
102
- else:
103
- event = misp.new_event(info="VirusTotal Report")
104
- misp_event = pymisp.MISPEvent()
105
- misp_event.load(event)
106
- return misp_event
107
-
108
-
109
- def main(misp, config, args):
110
- '''
111
- Main program logic
112
-
113
- :misp: PyMISP API object for interfacing with MISP
114
-
115
- :config: Configuration dictionary
116
-
117
- :args: Argparse CLI object
118
- '''
119
- if args.indicator:
120
- misp_objects = generate_report(args.indicator, config["virustotal"]["key"])
121
- if misp_objects:
122
- misp_event = get_misp_event(args.event, "VirusTotal Report for {}".format(args.indicator))
123
- submit_to_misp(misp, misp_event, misp_objects)
124
- elif args.file:
125
- try:
126
- reports = []
127
- with open(args.file, "r") as ifile:
128
- for indicator in ifile:
129
- try:
130
- misp_objects = generate_report(indicator, config["virustotal"]["key"])
131
- if misp_objects:
132
- reports.append(misp_objects)
133
- except pymisp.exceptions.InvalidMISPObject as err:
134
- logging.error(err)
135
- if reports:
136
- current_time = datetime.now().strftime("%x %X")
137
- misp_event = get_misp_event(args.event, "VirusTotal Reports: {}".format(current_time))
138
- for report in reports:
139
- submit_to_misp(misp, misp_event, report)
140
- except OSError:
141
- logging.error("Couldn't open indicators file at '%s'. Check path", args.file)
142
- elif args.link:
143
- # https://www.virustotal.com/#/file/<ioc>/detection
144
- indicator = args.link.split("/")[5]
145
- misp_objects = generate_report(indicator, config["virustotal"]["key"])
146
- if misp_objects:
147
- misp_event = get_misp_event(args.event, "VirusTotal Report for {}".format(indicator))
148
- submit_to_misp(misp, misp_event, misp_objects)
149
-
150
-
151
- def submit_to_misp(misp, misp_event, misp_objects):
152
- '''
153
- Submit a list of MISP objects to a MISP event
154
-
155
- :misp: PyMISP API object for interfacing with MISP
156
-
157
- :misp_event: MISPEvent object
158
-
159
- :misp_objects: List of MISPObject objects. Must be a list
160
- '''
161
- # go through round one and only add MISP objects
162
- for misp_object in misp_objects:
163
- template_id = misp.get_object_template_id(misp_object.template_uuid)
164
- misp.add_object(misp_event.id, template_id, misp_object)
165
- # go through round two and add all the object references for each object
166
- for misp_object in misp_objects:
167
- for reference in misp_object.ObjectReference:
168
- misp.add_object_reference(reference)
169
-
170
-
171
- if __name__ == "__main__":
172
- try:
173
- args = build_cli()
174
- config = build_config(args.config)
175
- # change the 'ssl' value if you want to verify your MISP's SSL instance
176
- misp = pymisp.PyMISP(url=config["misp"]["url"], key=config["misp"]["key"], ssl=False)
177
- # finally, let's start checking VT and converting the reports
178
- main(misp, config, args)
179
- except KeyboardInterrupt:
180
- print("Bye Felicia")
181
- except pymisp.exceptions.InvalidMISPObject as err:
182
- logging.error(err)
examples/warninglists.py DELETED
@@ -1,22 +0,0 @@
1
- #!/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
-
4
- from pymisp import PyMISP
5
- from pymisp.tools import load_warninglists
6
- import argparse
7
- from keys import misp_url, misp_key, misp_verifycert
8
-
9
-
10
- if __name__ == '__main__':
11
-
12
- parser = argparse.ArgumentParser(description='Load the warninglists.')
13
- parser.add_argument("-p", "--package", action='store_true', help="from the PyMISPWarninglists package.")
14
- parser.add_argument("-r", "--remote", action='store_true', help="from the MISP instance.")
15
-
16
- args = parser.parse_args()
17
-
18
- if args.package:
19
- print(load_warninglists.from_package())
20
- elif args.remote:
21
- pm = PyMISP(misp_url, misp_key, misp_verifycert)
22
- print(load_warninglists.from_instance(pm))
examples/yara.py DELETED
@@ -1,38 +0,0 @@
1
- #!/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
-
4
- from pymisp import PyMISP
5
- from keys import misp_url, misp_key,misp_verifycert
6
- import argparse
7
- import os
8
-
9
-
10
- def init(url, key):
11
- return PyMISP(url, key, misp_verifycert, 'json')
12
-
13
-
14
- def get_yara(m, event_id, out=None):
15
- ok, rules = m.get_yara(event_id)
16
- if not ok:
17
- print(rules)
18
- elif out is None:
19
- print(rules)
20
- else:
21
- with open(out, 'w') as f:
22
- f.write(rules)
23
-
24
-
25
- if __name__ == '__main__':
26
- parser = argparse.ArgumentParser(description='Get yara rules from an event.')
27
- parser.add_argument("-e", "--event", required=True, help="Event ID.")
28
- parser.add_argument("-o", "--output", help="Output file")
29
-
30
- args = parser.parse_args()
31
-
32
- if args.output is not None and os.path.exists(args.output):
33
- print('Output file already exists, abord.')
34
- exit(0)
35
-
36
- misp = init(misp_url, misp_key)
37
-
38
- get_yara(misp, args.event, args.output)
examples/yara_dump.py DELETED
@@ -1,98 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- '''
4
- YARA dumper for MISP
5
- by Christophe Vandeplas
6
- '''
7
-
8
- import keys
9
- from pymisp import PyMISP
10
- import yara
11
- import re
12
-
13
-
14
- def dirty_cleanup(value):
15
- changed = False
16
- substitutions = (('”', '"'),
17
- ('“', '"'),
18
- ('″', '"'),
19
- ('`', "'"),
20
- ('\r', ''),
21
- ('Rule ', 'rule ') # some people write this with the wrong case
22
- # ('$ ', '$'), # this breaks rules
23
- # ('\t\t', '\n'), # this breaks rules
24
- )
25
- for substitution in substitutions:
26
- if substitution[0] in value:
27
- changed = True
28
- value = value.replace(substitution[0], substitution[1])
29
- return value, changed
30
-
31
-
32
- misp = PyMISP(keys.misp_url, keys.misp_key, keys.misp_verify, 'json')
33
- result = misp.search(controller='attributes', type_attribute='yara')
34
-
35
- attr_cnt = 0
36
- attr_cnt_invalid = 0
37
- attr_cnt_duplicate = 0
38
- attr_cnt_changed = 0
39
- yara_rules = []
40
- yara_rule_names = []
41
- if result.get('Attribute'):
42
- for attribute in result.get('Attribute'):
43
- value = attribute['value']
44
- event_id = attribute['event_id']
45
- attribute_id = attribute['id']
46
-
47
- value = re.sub('^[ \t]*rule ', 'rule misp_e{}_'.format(event_id), value, flags=re.MULTILINE)
48
- value, changed = dirty_cleanup(value)
49
- if changed:
50
- attr_cnt_changed += 1
51
- if 'global rule' in value: # refuse any global rules as they might disable everything
52
- continue
53
- if 'private rule' in value: # private rules need some more rewriting
54
- priv_rules = re.findall('private rule (\w+)', value, flags=re.MULTILINE)
55
- for priv_rule in priv_rules:
56
- value = re.sub(priv_rule, 'misp_e{}_{}'.format(event_id, priv_rule), value, flags=re.MULTILINE)
57
-
58
- # compile the yara rule to confirm it's validity
59
- # if valid, ignore duplicate rules
60
- try:
61
- attr_cnt += 1
62
- yara.compile(source=value)
63
- yara_rules.append(value)
64
- # print("Rule e{} a{} OK".format(event_id, attribute_id))
65
- except yara.SyntaxError as e:
66
- attr_cnt_invalid += 1
67
- # print("Rule e{} a{} NOK - {}".format(event_id, attribute_id, e))
68
- except yara.Error as e:
69
- attr_cnt_invalid += 1
70
- print(e)
71
- import traceback
72
- print(traceback.format_exc())
73
-
74
- # remove duplicates - process the full yara rule list and process errors to eliminate duplicate rule names
75
- all_yara_rules = '\n'.join(yara_rules)
76
- while True:
77
- try:
78
- yara.compile(source=all_yara_rules)
79
- except yara.SyntaxError as e:
80
- if 'duplicated identifier' in e.args[0]:
81
- duplicate_rule_names = re.findall('duplicated identifier "(.*)"', e.args[0])
82
- for item in duplicate_rule_names:
83
- all_yara_rules = all_yara_rules.replace('rule {}'.format(item), 'rule duplicate_{}'.format(item), 1)
84
- attr_cnt_duplicate += 1
85
- continue
86
- else:
87
- # This should never happen as all rules were processed before separately. So logically we should only have duplicates.
88
- exit("ERROR SyntaxError in rules: {}".format(e.args))
89
- break
90
-
91
- # save to a file
92
- fname = 'misp.yara'
93
- with open(fname, 'w') as f_out:
94
- f_out.write(all_yara_rules)
95
-
96
- print("")
97
- print("MISP attributes with YARA rules: total={} valid={} invalid={} duplicate={} changed={}.".format(attr_cnt, attr_cnt - attr_cnt_invalid, attr_cnt_invalid, attr_cnt_duplicate, attr_cnt_changed))
98
- print("Valid YARA rule file save to file '{}'. Invalid rules/attributes were ignored.".format(fname))