pymisp 2.5.7__py3-none-any.whl → 2.5.8__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.
- pymisp/api.py +1 -0
- pymisp/data/misp-objects/objects/rmm/definition.json +1 -1
- {pymisp-2.5.7.dist-info → pymisp-2.5.8.dist-info}/METADATA +4 -4
- {pymisp-2.5.7.dist-info → pymisp-2.5.8.dist-info}/RECORD +6 -135
- CHANGELOG.txt +0 -5380
- examples/__init__.py +0 -0
- examples/add_attributes_from_csv.py +0 -74
- examples/add_email_object.py +0 -29
- examples/add_fail2ban_object.py +0 -86
- examples/add_feed.py +0 -25
- examples/add_file_object.py +0 -47
- examples/add_filetype_object_from_csv.py +0 -53
- examples/add_generic_object.py +0 -26
- examples/add_github_user.py +0 -65
- examples/add_gitlab_user.py +0 -56
- examples/add_named_attribute.py +0 -25
- examples/add_organisations.py +0 -57
- examples/add_ssh_authorized_keys.py +0 -29
- examples/add_user.py +0 -22
- examples/add_vehicle_object.py +0 -22
- examples/addtag2.py +0 -45
- examples/asciidoc_generator.py +0 -114
- examples/cache_all.py +0 -10
- examples/copyTagsFromAttributesToEvent.py +0 -68
- examples/copy_list.py +0 -93
- examples/create_events.py +0 -26
- examples/cytomic_orion.py +0 -549
- examples/del.py +0 -22
- examples/delete_user.py +0 -16
- examples/edit_organisation.py +0 -20
- examples/edit_user.py +0 -20
- examples/falsepositive_disabletoids.py +0 -136
- examples/fetch_events_feed.py +0 -15
- examples/fetch_warninglist_hits.py +0 -38
- examples/freetext.py +0 -22
- examples/generate_file_objects.py +0 -78
- examples/generate_meta_feed.py +0 -15
- examples/get.py +0 -37
- examples/get_csv.py +0 -37
- examples/get_network_activity.py +0 -187
- examples/last.py +0 -48
- examples/load_csv.py +0 -94
- examples/lookup.py +0 -28
- examples/misp2cef.py +0 -71
- examples/misp2clamav.py +0 -52
- examples/openioc_to_misp.py +0 -27
- examples/proofpoint_tap.py +0 -203
- examples/proofpoint_vap.py +0 -65
- examples/search.py +0 -48
- examples/search_attributes_yara.py +0 -40
- examples/search_sighting.py +0 -42
- examples/server_sync_check_conn.py +0 -32
- examples/sharing_groups.py +0 -15
- examples/show_sightings.py +0 -168
- examples/stats_report.py +0 -405
- examples/sync_sighting.py +0 -171
- examples/tags.py +0 -25
- examples/test_sign.py +0 -19
- examples/trustar_misp.py +0 -59
- examples/up.py +0 -21
- examples/upload.py +0 -60
- examples/users_list.py +0 -15
- examples/vmray_automation.py +0 -281
- examples/vt_to_misp.py +0 -182
- examples/warninglists.py +0 -22
- examples/yara.py +0 -38
- examples/yara_dump.py +0 -98
- tests/57c4445b-c548-4654-af0b-4be3950d210f.json +0 -1
- tests/__init__.py +0 -0
- tests/csv_testfiles/invalid_fieldnames.csv +0 -11
- tests/csv_testfiles/valid_fieldnames.csv +0 -4
- tests/email_testfiles/mail_1.eml.zip +0 -0
- tests/email_testfiles/mail_1.msg +0 -0
- tests/email_testfiles/mail_1_bom.eml +0 -858
- tests/email_testfiles/mail_1_headers_only.eml +0 -28
- tests/email_testfiles/mail_2.eml +0 -32
- tests/email_testfiles/mail_3.eml +0 -170
- tests/email_testfiles/mail_3.msg +0 -0
- tests/email_testfiles/mail_4.msg +0 -0
- tests/email_testfiles/mail_5.msg +0 -0
- tests/email_testfiles/mail_multiple_to.eml +0 -15
- tests/email_testfiles/source +0 -1
- tests/git-vuln-finder-quagga.json +0 -1493
- tests/misp_event.json +0 -76
- tests/mispevent_testfiles/attribute.json +0 -21
- tests/mispevent_testfiles/attribute_del.json +0 -23
- tests/mispevent_testfiles/def_param.json +0 -53
- tests/mispevent_testfiles/event.json +0 -8
- tests/mispevent_testfiles/event_obj_attr_tag.json +0 -57
- tests/mispevent_testfiles/event_obj_def_param.json +0 -62
- tests/mispevent_testfiles/event_obj_tag.json +0 -29
- tests/mispevent_testfiles/event_tags.json +0 -18
- tests/mispevent_testfiles/existing_event.json +0 -4599
- tests/mispevent_testfiles/existing_event_edited.json +0 -4601
- tests/mispevent_testfiles/galaxy.json +0 -25
- tests/mispevent_testfiles/malware.json +0 -19
- tests/mispevent_testfiles/malware_exist.json +0 -163
- tests/mispevent_testfiles/misp_custom_obj.json +0 -38
- tests/mispevent_testfiles/overwrite_file/definition.json +0 -457
- tests/mispevent_testfiles/proposals.json +0 -35
- tests/mispevent_testfiles/shadow.json +0 -148
- tests/mispevent_testfiles/sighting.json +0 -5
- tests/mispevent_testfiles/simple.json +0 -2
- tests/mispevent_testfiles/test_object_template/definition.json +0 -29
- tests/new_misp_event.json +0 -34
- tests/reportlab_testfiles/HTML_event.json +0 -1
- tests/reportlab_testfiles/galaxy_1.json +0 -1250
- tests/reportlab_testfiles/image_event.json +0 -2490
- tests/reportlab_testfiles/japanese_test.json +0 -156
- tests/reportlab_testfiles/japanese_test_heavy.json +0 -318
- tests/reportlab_testfiles/long_event.json +0 -3730
- tests/reportlab_testfiles/mainly_objects_1.json +0 -1092
- tests/reportlab_testfiles/mainly_objects_2.json +0 -977
- tests/reportlab_testfiles/sighting_1.json +0 -305
- tests/reportlab_testfiles/sighting_2.json +0 -221
- tests/reportlab_testfiles/to_delete1.json +0 -804
- tests/reportlab_testfiles/to_delete2.json +0 -1
- tests/reportlab_testfiles/to_delete3.json +0 -1
- tests/reportlab_testfiles/very_long_event.json +0 -1006
- tests/reportlab_testoutputs/to_delete1.json.pdf +0 -391
- tests/reportlab_testoutputs/to_delete2.json.pdf +0 -506
- tests/reportlab_testoutputs/to_delete3.json.pdf +0 -277
- tests/search_index_result.json +0 -69
- tests/sharing_groups.json +0 -98
- tests/stix1.xml-utf8 +0 -110
- tests/stix2.json +0 -1
- tests/test_analyst_data.py +0 -123
- tests/test_emailobject.py +0 -157
- tests/test_fileobject.py +0 -20
- tests/test_mispevent.py +0 -473
- tests/test_reportlab.py +0 -431
- tests/testlive_comprehensive.py +0 -3734
- tests/testlive_sync.py +0 -474
- {pymisp-2.5.7.dist-info → pymisp-2.5.8.dist-info}/LICENSE +0 -0
- {pymisp-2.5.7.dist-info → pymisp-2.5.8.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))
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"Event": {"info": "Ransomware - Xorist", "publish_timestamp": "1472548231", "timestamp": "1472541011", "analysis": "2", "Attribute": [{"category": "External analysis", "comment": "Imported via the Freetext Import Tool - Xchecked via VT: b3c4ae251f8094fa15b510051835c657eaef2a6cea46075d3aec964b14a99f68", "uuid": "57c5300c-0560-4146-bfaa-40e802de0b81", "timestamp": "1472540684", "to_ids": false, "value": "https://www.virustotal.com/file/b3c4ae251f8094fa15b510051835c657eaef2a6cea46075d3aec964b14a99f68/analysis/1469554268/", "type": "link"}, {"category": "External analysis", "comment": "", "uuid": "57c5310b-dc34-43cb-8b8e-4846950d210f", "timestamp": "1472541011", "to_ids": false, "value": "http://www.xylibox.com/2011/06/have-fun-with-trojan-ransomwin32xorist.html", "type": "link"}, {"category": "Other", "comment": "", "uuid": "57c444c0-8004-48fa-9c33-8aca950d210f", "timestamp": "1472480448", "to_ids": false, "value": "UPX packed", "type": "comment"}, {"category": "Other", "comment": "", "uuid": "57c44648-96f4-45d4-a8eb-453e950d210f", "timestamp": "1472480840", "to_ids": false, "value": "Key: 85350044dF4AC3518D185678A9414A7F,\r\nEncryption rounds:8,\r\nStart offset: 64,\r\nAlgorithm: TEA", "type": "text"}, {"category": "Payload delivery", "comment": "Imported via the Freetext Import Tool", "uuid": "57c4448a-fb04-457d-87e7-4127950d210f", "timestamp": "1472480394", "to_ids": true, "value": "3Z4wnG9603it23y.exe", "type": "filename"}, {"category": "Payload delivery", "comment": "Imported via the Freetext Import Tool", "uuid": "57c4448b-454c-4d17-90d1-4d2f950d210f", "timestamp": "1472480395", "to_ids": true, "value": "0749bae92ca336a02c83d126e04ec628", "type": "md5"}, {"category": "Payload delivery", "comment": "Imported via the Freetext Import Tool", "uuid": "57c4448a-bef0-4ba7-a071-444e950d210f", "timestamp": "1472480394", "to_ids": true, "value": "77b0c41b7d340b8a3d903f21347bbf06aa766b5b", "type": "sha1"}, {"category": "Payload delivery", "comment": "Imported via the Freetext Import Tool", "uuid": "57c4448b-3fa4-4d65-9ccc-4afa950d210f", "timestamp": "1472480395", "to_ids": true, "value": "b3c4ae251f8094fa15b510051835c657eaef2a6cea46075d3aec964b14a99f68", "type": "sha256"}, {"category": "Persistence mechanism", "comment": "", "uuid": "57c54b0f-27a4-458b-8e63-4455950d210f", "timestamp": "1472547599", "to_ids": true, "value": "Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run|%TEMP%\\3Z4wnG9603it23y.exe", "type": "regkey|value"}], "Tag": [{"colour": "#ffffff", "exportable": true, "name": "tlp:white"}, {"colour": "#3d7a00", "exportable": true, "name": "circl:incident-classification=\"malware\""}, {"colour": "#420053", "exportable": true, "name": "ms-caro-malware:malware-type=\"Ransom\""}, {"colour": "#2c4f00", "exportable": true, "name": "malware_classification:malware-category=\"Ransomware\""}], "published": true, "date": "2016-08-29", "Orgc": {"name": "CIRCL", "uuid": "55f6ea5e-2c60-40e5-964f-47a8950d210f"}, "threat_level_id": "3", "uuid": "57c4445b-c548-4654-af0b-4be3950d210f"}}
|
tests/__init__.py
DELETED
|
File without changes
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
SHA1,fileName,size
|
|
2
|
-
2a030cc6d84d5785f5e84d0f5888a411d4b06d01,soft.exe,45568
|
|
3
|
-
2abae839362edfe52d9ebe282fb61113d22b331f,sttager.exe,20480
|
|
4
|
-
6995a32e0a4d4f6d0c9b2a00a96d69bff4b83ea7,test443.exe,373911
|
|
5
|
-
87b1f17fbb4a1e8eef4cb31c1c0194b1426c868c,veil.exe,345761
|
|
6
|
-
afc36916a4df934446681ea28bef6add4decb98a,80_http.exe.exe,411850
|
|
7
|
-
f832d94391a8d2d5cf92773e6c912905ec7c40c7,test1.exe,406636
|
|
8
|
-
056823c7891a04b2fec8903eb401ae3291743a54,beca.exe.exe,23808
|
|
9
|
-
b7afa7acf1b7ded2c4e3d0884b5cdaa230d9f82e,shell1.exe,24576
|
|
10
|
-
4b50b6b9157026ab408d966ece02d1cef8045f82,starggge.exe,27136
|
|
11
|
-
6042dfd50d33da40e383baec4a7ef7c75bf17481,8_32.exe,24064
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
md5, sha1, sha256
|
|
2
|
-
644087ccca16d2a728ef7685a4106f09, eabd6974ac71efd72d9e0688d5a6131f336d169c, 385e31c97e3a07bbb81513f0cd0979e64e6b014943902efd002f57b21eadd41e
|
|
3
|
-
34187a34d0a3c5d63016c26346371b54, ce8209ff9828aa8cb095bd7d1589fc4d394c298c, 5f815b8a8e77731c9ca2b3a07a27f880ef24d54e458d77bdabbbaf2269fe96c3
|
|
4
|
-
871aa15f4d61c85e1284e1be3f99f705, 236eac0b19f91117b27f1b198a4d8490d99ec2e5, b434bccf0a5ff75b27184e661df751466aef69f35fbd7b8b8692302b8b886262
|
|
Binary file
|
tests/email_testfiles/mail_1.msg
DELETED
|
Binary file
|