-
Notifications
You must be signed in to change notification settings - Fork 233
/
threatStream_misp_export.py
executable file
·114 lines (95 loc) · 3.65 KB
/
threatStream_misp_export.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
"""
Export module for coverting MISP events into ThreatStream Structured Import files. Based of work by the CenturyLink CIRT.
Source: https://github.com/MISP/misp-modules/blob/master/misp_modules/modules/export_mod/threat_connect_export.py
"""
import base64
import csv
import io
import json
import logging
misperrors = {"error": "Error"}
moduleinfo = {
'version': '1.0',
'author': 'Robert Nixon, based off of the ThreatConnect MISP Module written by the CenturyLink CIRT',
'description': 'Module to export a structured CSV file for uploading to threatStream.',
'module-type': ['export'],
'name': 'ThreatStream Export',
'logo': 'threatstream.png',
'requirements': ['csv'],
'features': 'The module takes a MISP event in input, to look every attribute. Each attribute matching with some predefined types is then exported in a CSV format recognized by ThreatStream.',
'references': ['https://www.anomali.com/platform/threatstream', 'https://github.com/threatstream'],
'input': 'MISP Event attributes',
'output': 'ThreatStream CSV format file',
}
moduleconfig = []
# Map of MISP fields => ThreatStream itypes, you can modify this to your liking
fieldmap = {
"domain": "mal_domain",
"hostname": "mal_domain",
"ip-src": "mal_ip",
"ip-dst": "mal_ip",
"email-src": "phish_email",
"url": "mal_url",
"md5": "mal_md5",
}
# combine all the MISP fields from fieldmap into one big list
mispattributes = {
"input": list(fieldmap.keys())
}
def handler(q=False):
"""
Convert a MISP query into a CSV file matching the ThreatStream Structured Import file format.
Input
q: Query dictionary
"""
if q is False or not q:
return False
request = json.loads(q)
response = io.StringIO()
writer = csv.DictWriter(response, fieldnames=["value", "itype", "tags"])
writer.writeheader()
# start parsing MISP data
for event in request["data"]:
for attribute in event["Attribute"]:
if attribute["type"] in mispattributes["input"]:
logging.debug("Adding %s to structured CSV export of ThreatStream Export", attribute["value"])
if "|" in attribute["type"]:
# if the attribute type has multiple values, line it up with the corresponding ThreatStream values in fieldmap
indicators = tuple(attribute["value"].split("|"))
ts_types = tuple(fieldmap[attribute["type"]].split("|"))
for i, indicator in enumerate(indicators):
writer.writerow({
"value": indicator,
"itype": ts_types[i],
"tags": attribute["comment"]
})
else:
writer.writerow({
"itype": fieldmap[attribute["type"]],
"value": attribute["value"],
"tags": attribute["comment"]
})
return {"response": [], "data": str(base64.b64encode(bytes(response.getvalue(), 'utf-8')), 'utf-8')}
def introspection():
"""
Relay the supported attributes to MISP.
No Input
Output
Dictionary of supported MISP attributes
"""
modulesetup = {
"responseType": "application/txt",
"outputFileExtension": "csv",
"userConfig": {},
"inputSource": []
}
return modulesetup
def version():
"""
Relay module version and associated metadata to MISP.
No Input
Output
moduleinfo: metadata output containing all potential configuration values
"""
moduleinfo["config"] = moduleconfig
return moduleinfo