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.
- pymisp/api.py +1 -0
- pymisp/data/misp-objects/objects/github-repo/definition.json +142 -0
- {pymisp-2.5.7.1.dist-info → pymisp-2.5.8.1.dist-info}/METADATA +4 -4
- {pymisp-2.5.7.1.dist-info → pymisp-2.5.8.1.dist-info}/RECORD +6 -68
- CHANGELOG.txt +0 -5393
- 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
- {pymisp-2.5.7.1.dist-info → pymisp-2.5.8.1.dist-info}/LICENSE +0 -0
- {pymisp-2.5.7.1.dist-info → pymisp-2.5.8.1.dist-info}/WHEEL +0 -0
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
'''
|
|
4
|
-
Koen Van Impe
|
|
5
|
-
|
|
6
|
-
Disable the to_ids flag of an attribute when there are to many false positives
|
|
7
|
-
Put this script in crontab to run every /15 or /60
|
|
8
|
-
*/5 * * * * mispuser /usr/bin/python3 /home/mispuser/PyMISP/examples/falsepositive_disabletoids.py
|
|
9
|
-
|
|
10
|
-
Do inline config in "main"
|
|
11
|
-
|
|
12
|
-
'''
|
|
13
|
-
|
|
14
|
-
from pymisp import ExpandedPyMISP, MISPEvent
|
|
15
|
-
from keys import misp_url, misp_key, misp_verifycert
|
|
16
|
-
from datetime import datetime
|
|
17
|
-
from datetime import date
|
|
18
|
-
|
|
19
|
-
import datetime as dt
|
|
20
|
-
import smtplib
|
|
21
|
-
import mimetypes
|
|
22
|
-
from email.mime.multipart import MIMEMultipart
|
|
23
|
-
from email import encoders
|
|
24
|
-
from email.mime.base import MIMEBase
|
|
25
|
-
from email.mime.text import MIMEText
|
|
26
|
-
import argparse
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
def init(url, key, verifycert):
|
|
30
|
-
'''
|
|
31
|
-
Template to get MISP module started
|
|
32
|
-
'''
|
|
33
|
-
return ExpandedPyMISP(url, key, verifycert, 'json')
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if __name__ == '__main__':
|
|
37
|
-
|
|
38
|
-
minimal_fp = 0
|
|
39
|
-
threshold_to_ids = .50
|
|
40
|
-
minimal_date_sighting_date = '1970-01-01 00:00:00'
|
|
41
|
-
|
|
42
|
-
smtp_from = 'INSERT_FROM'
|
|
43
|
-
smtp_to = 'INSERT_TO'
|
|
44
|
-
smtp_server = 'localhost'
|
|
45
|
-
report_changes = ''
|
|
46
|
-
ts_format = '%Y-%m-%d %H:%M:%S'
|
|
47
|
-
|
|
48
|
-
parser = argparse.ArgumentParser(description="Disable the to_ids flag of attributes with a certain number of false positives above a threshold.")
|
|
49
|
-
parser.add_argument('-m', '--mail', action='store_true', help='Mail the report')
|
|
50
|
-
parser.add_argument('-o', '--mailoptions', action='store', help='mailoptions: \'smtp_from=INSERT_FROM;smtp_to=INSERT_TO;smtp_server=localhost\'')
|
|
51
|
-
parser.add_argument('-b', '--minimal-fp', default=minimal_fp, type=int, help='Minimal number of false positive (default: %(default)s )')
|
|
52
|
-
parser.add_argument('-t', '--threshold', default=threshold_to_ids, type=float, help='Threshold false positive/true positive rate (default: %(default)s )')
|
|
53
|
-
parser.add_argument('-d', '--minimal-date-sighting', default=minimal_date_sighting_date, help='Minimal date for sighting (false positive / true positive) (default: %(default)s )')
|
|
54
|
-
|
|
55
|
-
args = parser.parse_args()
|
|
56
|
-
misp = init(misp_url, misp_key, misp_verifycert)
|
|
57
|
-
|
|
58
|
-
minimal_fp = int(args.minimal_fp)
|
|
59
|
-
threshold_to_ids = args.threshold
|
|
60
|
-
minimal_date_sighting_date = args.minimal_date_sighting
|
|
61
|
-
minimal_date_sighting = int(dt.datetime.strptime(minimal_date_sighting_date, '%Y-%m-%d %H:%M:%S').strftime("%s"))
|
|
62
|
-
|
|
63
|
-
# Fetch all the attributes
|
|
64
|
-
result = misp.search('attributes', to_ids=1, include_sightings=1)
|
|
65
|
-
|
|
66
|
-
if 'Attribute' in result:
|
|
67
|
-
for attribute in result['Attribute']:
|
|
68
|
-
true_positive = 0
|
|
69
|
-
false_positive = 0
|
|
70
|
-
compute_threshold = 0
|
|
71
|
-
attribute_id = attribute['id']
|
|
72
|
-
attribute_value = attribute['value']
|
|
73
|
-
attribute_uuid = attribute['uuid']
|
|
74
|
-
event_id = attribute['event_id']
|
|
75
|
-
|
|
76
|
-
# Only do something if there is a sighting
|
|
77
|
-
if 'Sighting' in attribute:
|
|
78
|
-
|
|
79
|
-
for sighting in attribute['Sighting']:
|
|
80
|
-
if int(sighting['date_sighting']) > minimal_date_sighting:
|
|
81
|
-
if int(sighting['type']) == 0:
|
|
82
|
-
true_positive = true_positive + 1
|
|
83
|
-
elif int(sighting['type']) == 1:
|
|
84
|
-
false_positive = false_positive + 1
|
|
85
|
-
|
|
86
|
-
if false_positive > minimal_fp:
|
|
87
|
-
compute_threshold = false_positive / (true_positive + false_positive)
|
|
88
|
-
|
|
89
|
-
if compute_threshold >= threshold_to_ids:
|
|
90
|
-
# Fetch event title for report text
|
|
91
|
-
event_details = misp.get_event(event_id)
|
|
92
|
-
event_info = event_details['Event']['info']
|
|
93
|
-
|
|
94
|
-
misp.update_attribute( { 'uuid': attribute_uuid, 'to_ids': 0})
|
|
95
|
-
|
|
96
|
-
report_changes = report_changes + 'Disable to_ids for [%s] (%s) in event [%s] (%s) - FP: %s TP: %s \n' % (attribute_value, attribute_id, event_info, event_id, false_positive, true_positive)
|
|
97
|
-
|
|
98
|
-
# Changing the attribute to_ids flag sets the event to unpublished
|
|
99
|
-
misp.publish(event_id)
|
|
100
|
-
|
|
101
|
-
# Only send/print the report if it contains content
|
|
102
|
-
if report_changes:
|
|
103
|
-
if args.mail:
|
|
104
|
-
if args.mailoptions:
|
|
105
|
-
mailoptions = args.mailoptions.split(';')
|
|
106
|
-
for s in mailoptions:
|
|
107
|
-
if s.split('=')[0] == 'smtp_from':
|
|
108
|
-
smtp_from = s.split('=')[1]
|
|
109
|
-
if s.split('=')[0] == 'smtp_to':
|
|
110
|
-
smtp_to = s.split('=')[1]
|
|
111
|
-
if s.split('=')[0] == 'smtp_server':
|
|
112
|
-
smtp_server = s.split('=')[1]
|
|
113
|
-
|
|
114
|
-
now = datetime.now()
|
|
115
|
-
current_date = now.strftime(ts_format)
|
|
116
|
-
report_changes_body = 'MISP Disable to_ids flags for %s on %s\n-------------------------------------------------------------------------------\n\n' % (misp_url, current_date)
|
|
117
|
-
report_changes_body = report_changes_body + 'Minimal number of false positives before considering threshold: %s\n' % (minimal_fp)
|
|
118
|
-
report_changes_body = report_changes_body + 'Threshold false positives/true positives to disable to_ids flag: %s\n' % (threshold_to_ids)
|
|
119
|
-
report_changes_body = report_changes_body + 'Minimal date for sighting false positives: %s\n\n' % (minimal_date_sighting_date)
|
|
120
|
-
report_changes_body = report_changes_body + report_changes
|
|
121
|
-
report_changes_body = report_changes_body + '\nEvents that have attributes with changed to_ids flag have been republished, without e-mail notification.'
|
|
122
|
-
report_changes_body = report_changes_body + '\n\nMISP Disable to_ids Finished\n'
|
|
123
|
-
|
|
124
|
-
subject = 'Report of disable to_ids flag for false positives sightings of %s' % (current_date)
|
|
125
|
-
msg = MIMEMultipart()
|
|
126
|
-
msg['From'] = smtp_from
|
|
127
|
-
msg['To'] = smtp_to
|
|
128
|
-
msg['Subject'] = subject
|
|
129
|
-
|
|
130
|
-
msg.attach(MIMEText(report_changes_body, 'text'))
|
|
131
|
-
print(report_changes_body)
|
|
132
|
-
server = smtplib.SMTP(smtp_server)
|
|
133
|
-
server.sendmail(smtp_from, smtp_to, msg.as_string())
|
|
134
|
-
|
|
135
|
-
else:
|
|
136
|
-
print(report_changes)
|
examples/fetch_events_feed.py
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
from keys import misp_url, misp_key, misp_verifycert
|
|
5
|
-
import argparse
|
|
6
|
-
from pymisp import ExpandedPyMISP
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if __name__ == '__main__':
|
|
10
|
-
parser = argparse.ArgumentParser(description='Fetch all events from a feed.')
|
|
11
|
-
parser.add_argument("-f", "--feed", required=True, help="feed's ID to be fetched.")
|
|
12
|
-
args = parser.parse_args()
|
|
13
|
-
|
|
14
|
-
misp = ExpandedPyMISP(misp_url, misp_key, misp_verifycert)
|
|
15
|
-
misp.fetch_feed(args.feed)
|
|
@@ -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
|
|
6
|
-
import argparse
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def init(url, key):
|
|
10
|
-
return PyMISP(url, key)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def loop_attributes(elem):
|
|
14
|
-
if 'Attribute' in elem.keys():
|
|
15
|
-
for attribute in elem['Attribute']:
|
|
16
|
-
if 'warnings' in attribute.keys():
|
|
17
|
-
for warning in attribute['warnings']:
|
|
18
|
-
print("Value {} has a hit in warninglist with name '{}' and id '{}'".format(warning['value'],
|
|
19
|
-
warning[
|
|
20
|
-
'warninglist_name'],
|
|
21
|
-
warning[
|
|
22
|
-
'warninglist_id']))
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if __name__ == '__main__':
|
|
26
|
-
parser = argparse.ArgumentParser(description='Print all warninglist hits for an event.')
|
|
27
|
-
parser.add_argument("eventid", type=str, help="The event id of the event to get info of")
|
|
28
|
-
args = parser.parse_args()
|
|
29
|
-
misp = init(misp_url, misp_key)
|
|
30
|
-
evt = misp.search('events', eventid=args.eventid, includeWarninglistHits=1)['response'][0]['Event']
|
|
31
|
-
if 'warnings' in evt.keys():
|
|
32
|
-
print('warnings in entire event:')
|
|
33
|
-
print(str(evt['warnings']) + '\n')
|
|
34
|
-
print('Warnings at attribute levels:')
|
|
35
|
-
loop_attributes(evt)
|
|
36
|
-
if 'Object' in evt.keys():
|
|
37
|
-
for obj in evt['Object']:
|
|
38
|
-
loop_attributes(obj)
|
examples/freetext.py
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
from pymisp import ExpandedPyMISP
|
|
5
|
-
from keys import misp_url, misp_key, misp_verifycert
|
|
6
|
-
import argparse
|
|
7
|
-
|
|
8
|
-
from io import open
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if __name__ == '__main__':
|
|
12
|
-
parser = argparse.ArgumentParser(description="Update a MISP event.")
|
|
13
|
-
parser.add_argument("-e", "--event", required=True, help="Event ID to update.")
|
|
14
|
-
parser.add_argument("-i", "--input", required=True, help="Input file")
|
|
15
|
-
|
|
16
|
-
args = parser.parse_args()
|
|
17
|
-
|
|
18
|
-
pymisp = PyMISP(misp_url, misp_key, misp_verifycert)
|
|
19
|
-
|
|
20
|
-
with open(args.input, 'r') as f:
|
|
21
|
-
result = pymisp.freetext(args.event, f.read())
|
|
22
|
-
print(result)
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
import argparse
|
|
5
|
-
import json
|
|
6
|
-
|
|
7
|
-
try:
|
|
8
|
-
from pymisp import pymisp_json_default, AbstractMISP
|
|
9
|
-
from pymisp.tools import make_binary_objects
|
|
10
|
-
except ImportError:
|
|
11
|
-
pass
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def check():
|
|
15
|
-
missing_dependencies = {'pydeep': False, 'lief': False, 'magic': False, 'pymisp': False}
|
|
16
|
-
try:
|
|
17
|
-
import pymisp # noqa
|
|
18
|
-
except ImportError:
|
|
19
|
-
missing_dependencies['pymisp'] = 'Please install pydeep: pip install pymisp'
|
|
20
|
-
try:
|
|
21
|
-
import pydeep # noqa
|
|
22
|
-
except ImportError:
|
|
23
|
-
missing_dependencies['pydeep'] = 'Please install pydeep: pip install git+https://github.com/kbandla/pydeep.git'
|
|
24
|
-
try:
|
|
25
|
-
import lief # noqa
|
|
26
|
-
except ImportError:
|
|
27
|
-
missing_dependencies['lief'] = 'Please install lief, documentation here: https://github.com/lief-project/LIEF'
|
|
28
|
-
try:
|
|
29
|
-
import magic # noqa
|
|
30
|
-
except ImportError:
|
|
31
|
-
missing_dependencies['magic'] = 'Please install python-magic: pip install python-magic.'
|
|
32
|
-
return json.dumps(missing_dependencies)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def make_objects(path):
|
|
36
|
-
to_return = {'objects': [], 'references': []}
|
|
37
|
-
fo, peo, seos = make_binary_objects(path)
|
|
38
|
-
|
|
39
|
-
if seos:
|
|
40
|
-
for s in seos:
|
|
41
|
-
to_return['objects'].append(s)
|
|
42
|
-
if s.ObjectReference:
|
|
43
|
-
to_return['references'] += s.ObjectReference
|
|
44
|
-
|
|
45
|
-
if peo:
|
|
46
|
-
if hasattr(peo, 'certificates') and hasattr(peo, 'signers'):
|
|
47
|
-
# special authenticode case for PE objects
|
|
48
|
-
for c in peo.certificates:
|
|
49
|
-
to_return['objects'].append(c)
|
|
50
|
-
for s in peo.signers:
|
|
51
|
-
to_return['objects'].append(s)
|
|
52
|
-
del peo.certificates
|
|
53
|
-
del peo.signers
|
|
54
|
-
del peo.sections
|
|
55
|
-
to_return['objects'].append(peo)
|
|
56
|
-
if peo.ObjectReference:
|
|
57
|
-
to_return['references'] += peo.ObjectReference
|
|
58
|
-
|
|
59
|
-
if fo:
|
|
60
|
-
to_return['objects'].append(fo)
|
|
61
|
-
if fo.ObjectReference:
|
|
62
|
-
to_return['references'] += fo.ObjectReference
|
|
63
|
-
return json.dumps(to_return, default=pymisp_json_default)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if __name__ == '__main__':
|
|
67
|
-
parser = argparse.ArgumentParser(description='Extract indicators out of binaries and returns MISP objects.')
|
|
68
|
-
group = parser.add_mutually_exclusive_group()
|
|
69
|
-
group.add_argument("-p", "--path", help="Path to process.")
|
|
70
|
-
group.add_argument("-c", "--check", action='store_true', help="Check the dependencies.")
|
|
71
|
-
args = parser.parse_args()
|
|
72
|
-
a = AbstractMISP()
|
|
73
|
-
|
|
74
|
-
if args.check:
|
|
75
|
-
print(check())
|
|
76
|
-
if args.path:
|
|
77
|
-
obj = make_objects(args.path)
|
|
78
|
-
print(obj)
|
examples/generate_meta_feed.py
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
from pymisp.tools import feed_meta_generator
|
|
5
|
-
import argparse
|
|
6
|
-
from pathlib import Path
|
|
7
|
-
|
|
8
|
-
if __name__ == '__main__':
|
|
9
|
-
parser = argparse.ArgumentParser(description='Build meta files for feed')
|
|
10
|
-
parser.add_argument("--feed", required=True, help="Path to directory containing the feed.")
|
|
11
|
-
args = parser.parse_args()
|
|
12
|
-
|
|
13
|
-
feed = Path(args.feed)
|
|
14
|
-
|
|
15
|
-
feed_meta_generator(feed)
|
examples/get.py
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
from pymisp import ExpandedPyMISP
|
|
5
|
-
from keys import misp_url, misp_key, misp_verifycert
|
|
6
|
-
import argparse
|
|
7
|
-
import os
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
proxies = {
|
|
11
|
-
'http': 'http://127.0.0.1:8123',
|
|
12
|
-
'https': 'http://127.0.0.1:8123',
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
proxies = None
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if __name__ == '__main__':
|
|
19
|
-
|
|
20
|
-
parser = argparse.ArgumentParser(description='Get an event from a MISP instance.')
|
|
21
|
-
parser.add_argument("-e", "--event", required=True, help="Event ID to get.")
|
|
22
|
-
parser.add_argument("-o", "--output", help="Output file")
|
|
23
|
-
|
|
24
|
-
args = parser.parse_args()
|
|
25
|
-
|
|
26
|
-
if args.output is not None and os.path.exists(args.output):
|
|
27
|
-
print('Output file already exists, abort.')
|
|
28
|
-
exit(0)
|
|
29
|
-
|
|
30
|
-
misp = ExpandedPyMISP(misp_url, misp_key, misp_verifycert, proxies=proxies)
|
|
31
|
-
|
|
32
|
-
event = misp.get_event(args.event, pythonify=True)
|
|
33
|
-
if args.output:
|
|
34
|
-
with open(args.output, 'w') as f:
|
|
35
|
-
f.write(event.to_json())
|
|
36
|
-
else:
|
|
37
|
-
print(event.to_json())
|
examples/get_csv.py
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
import argparse
|
|
5
|
-
|
|
6
|
-
from pymisp import ExpandedPyMISP
|
|
7
|
-
from keys import misp_url, misp_key, misp_verifycert
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if __name__ == '__main__':
|
|
11
|
-
parser = argparse.ArgumentParser(description='Get MISP stuff as CSV.')
|
|
12
|
-
parser.add_argument("--controller", default='attributes', help="Attribute to use for the search (events, objects, attributes)")
|
|
13
|
-
parser.add_argument("-e", "--event_id", help="Event ID to fetch. Without it, it will fetch the whole database.")
|
|
14
|
-
parser.add_argument("-a", "--attribute", nargs='+', help="Attribute column names")
|
|
15
|
-
parser.add_argument("-o", "--object_attribute", nargs='+', help="Object attribute column names")
|
|
16
|
-
parser.add_argument("-t", "--misp_types", nargs='+', help="MISP types to fetch (ip-src, hostname, ...)")
|
|
17
|
-
parser.add_argument("-c", "--context", action='store_true', help="Add event level context (tags...)")
|
|
18
|
-
parser.add_argument("-f", "--outfile", help="Output file to write the CSV.")
|
|
19
|
-
|
|
20
|
-
args = parser.parse_args()
|
|
21
|
-
pymisp = ExpandedPyMISP(misp_url, misp_key, misp_verifycert, debug=True)
|
|
22
|
-
attr = []
|
|
23
|
-
if args.attribute:
|
|
24
|
-
attr += args.attribute
|
|
25
|
-
if args.object_attribute:
|
|
26
|
-
attr += args.object_attribute
|
|
27
|
-
if not attr:
|
|
28
|
-
attr = None
|
|
29
|
-
print(args.context)
|
|
30
|
-
response = pymisp.search(return_format='csv', controller=args.controller, eventid=args.event_id, requested_attributes=attr,
|
|
31
|
-
type_attribute=args.misp_types, include_context=args.context)
|
|
32
|
-
|
|
33
|
-
if args.outfile:
|
|
34
|
-
with open(args.outfile, 'w') as f:
|
|
35
|
-
f.write(response)
|
|
36
|
-
else:
|
|
37
|
-
print(response)
|
examples/get_network_activity.py
DELETED
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
"""
|
|
5
|
-
Python script to extract network activity from MISP database
|
|
6
|
-
|
|
7
|
-
Koen Van Impe 20141116
|
|
8
|
-
netflow 20150804
|
|
9
|
-
Feed it a list of event_id's (1 id per line) with the option "-f".
|
|
10
|
-
Use --no-comment to get a flat list of entries without event id and title information
|
|
11
|
-
|
|
12
|
-
Usage
|
|
13
|
-
./get_network_activity.py --netflow --event 8
|
|
14
|
-
get netflow filter for event 8
|
|
15
|
-
|
|
16
|
-
./get_network_activity.py -f get_network_activity.event_id --netflow
|
|
17
|
-
get netflow filter for events in id file
|
|
18
|
-
|
|
19
|
-
./get_network_activity.py -f get_network_activity.event_id
|
|
20
|
-
get output with comments
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
from pymisp import PyMISP
|
|
24
|
-
|
|
25
|
-
from keys import misp_key
|
|
26
|
-
from keys import misp_url
|
|
27
|
-
from keys import misp_verifycert
|
|
28
|
-
|
|
29
|
-
source = None
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def init():
|
|
33
|
-
"""
|
|
34
|
-
Initialize PyMISP
|
|
35
|
-
Get configuration settings from config file
|
|
36
|
-
"""
|
|
37
|
-
global source
|
|
38
|
-
source = PyMISP(misp_url, misp_key, misp_verifycert, 'json')
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def get_event(event_id):
|
|
42
|
-
"""
|
|
43
|
-
Get details of an event and add it to the result arrays
|
|
44
|
-
:event_id the id of the event
|
|
45
|
-
"""
|
|
46
|
-
global network_ip_src, network_ip_dst, network_hostname, network_domain
|
|
47
|
-
global app_hostname, app_domain, app_ip_src, app_ip_dst, app_ids_only, app_printcomment, app_netflow
|
|
48
|
-
|
|
49
|
-
event_id = int(event_id)
|
|
50
|
-
if event_id > 0:
|
|
51
|
-
event_json = source.get_event(event_id)
|
|
52
|
-
event_core = event_json["Event"]
|
|
53
|
-
# event_threatlevel_id = event_core["threat_level_id"]
|
|
54
|
-
|
|
55
|
-
# attribute_count = event_core["attribute_count"]
|
|
56
|
-
attribute = event_core["Attribute"]
|
|
57
|
-
|
|
58
|
-
for attribute in event_core["Attribute"]:
|
|
59
|
-
if app_ids_only and not attribute["to_ids"]:
|
|
60
|
-
continue
|
|
61
|
-
|
|
62
|
-
value = attribute["value"]
|
|
63
|
-
title = event_core["info"]
|
|
64
|
-
if app_netflow:
|
|
65
|
-
app_printcomment = False
|
|
66
|
-
if attribute["type"] == "ip-dst" and app_ip_dst:
|
|
67
|
-
network_ip_dst.append([build_entry(value, event_id, title, "ip-dst")])
|
|
68
|
-
else:
|
|
69
|
-
if attribute["type"] == "ip-src" and app_ip_src:
|
|
70
|
-
network_ip_src.append([build_entry(value, event_id, title, "ip-src")])
|
|
71
|
-
elif attribute["type"] == "ip-dst" and app_ip_dst:
|
|
72
|
-
network_ip_dst.append([build_entry(value, event_id, title, "ip-dst")])
|
|
73
|
-
elif attribute["type"] == "domain" and app_domain:
|
|
74
|
-
network_domain.append([build_entry(value, event_id, title, "domain")])
|
|
75
|
-
elif attribute["type"] == "hostname" and app_hostname:
|
|
76
|
-
network_hostname.append([build_entry(value, event_id, title, "hostname")])
|
|
77
|
-
else:
|
|
78
|
-
continue
|
|
79
|
-
else:
|
|
80
|
-
print("Not a valid ID")
|
|
81
|
-
return
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
def build_entry(value, event_id, title, source):
|
|
85
|
-
"""
|
|
86
|
-
Build the line containing the entry
|
|
87
|
-
|
|
88
|
-
:value the datavalue of the entry
|
|
89
|
-
:event_id id of the event
|
|
90
|
-
:title name of the event
|
|
91
|
-
:source from which set was the entry retrieved
|
|
92
|
-
"""
|
|
93
|
-
global app_printcomment
|
|
94
|
-
|
|
95
|
-
if app_printcomment:
|
|
96
|
-
if app_printtitle:
|
|
97
|
-
return "%s # Event: %s / %s (from %s) " % (value, event_id, title, source)
|
|
98
|
-
else:
|
|
99
|
-
return "%s # Event: %s (from %s) " % (value, event_id, source)
|
|
100
|
-
else:
|
|
101
|
-
return value
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
def print_events():
|
|
105
|
-
"""
|
|
106
|
-
Print the events from the result arrays
|
|
107
|
-
"""
|
|
108
|
-
global network_ip_src, network_ip_dst, network_domain, network_hostname
|
|
109
|
-
global app_hostname, app_domain, app_ip_src, app_ip_dst, app_ids_only, app_printcomment, app_printtitle, app_netflow
|
|
110
|
-
|
|
111
|
-
if app_netflow:
|
|
112
|
-
firsthost = True
|
|
113
|
-
for ip in network_ip_dst:
|
|
114
|
-
if firsthost:
|
|
115
|
-
firsthost = False
|
|
116
|
-
else:
|
|
117
|
-
print(" or ")
|
|
118
|
-
print("host %s" % ip[0])
|
|
119
|
-
else:
|
|
120
|
-
if app_ip_src:
|
|
121
|
-
for ip in network_ip_src:
|
|
122
|
-
print(ip[0])
|
|
123
|
-
if app_ip_dst:
|
|
124
|
-
for ip in network_ip_dst:
|
|
125
|
-
print(ip[0])
|
|
126
|
-
if app_domain:
|
|
127
|
-
for ip in network_domain:
|
|
128
|
-
print(ip[0])
|
|
129
|
-
if app_hostname:
|
|
130
|
-
for ip in network_hostname:
|
|
131
|
-
print(ip[0])
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if __name__ == '__main__':
|
|
135
|
-
import argparse
|
|
136
|
-
|
|
137
|
-
network_ip_src = []
|
|
138
|
-
network_ip_dst = []
|
|
139
|
-
network_domain = []
|
|
140
|
-
network_hostname = []
|
|
141
|
-
|
|
142
|
-
parser = argparse.ArgumentParser(
|
|
143
|
-
description='Download network activity information from MISP.')
|
|
144
|
-
parser.add_argument('-f', '--filename', type=str,
|
|
145
|
-
help='File containing a list of event id.')
|
|
146
|
-
parser.add_argument('--hostname', action='store_true', default=False,
|
|
147
|
-
help='Include hostnames.')
|
|
148
|
-
parser.add_argument('--no-ip-src', action='store_true', default=False,
|
|
149
|
-
help='Do not include ip-src.')
|
|
150
|
-
parser.add_argument('--no-ip-dst', action='store_true', default=False,
|
|
151
|
-
help='Do not include ip-dst.')
|
|
152
|
-
parser.add_argument('--domain', action='store_true', default=False,
|
|
153
|
-
help='Include domains.')
|
|
154
|
-
parser.add_argument('--no-comment', action='store_false', default=True,
|
|
155
|
-
help='Do not include comment in the output.')
|
|
156
|
-
parser.add_argument('--no-ids-only', action='store_true', default=False,
|
|
157
|
-
help='Include IDS and non-IDS attribures.')
|
|
158
|
-
parser.add_argument('--no-titles', action='store_true', default=False,
|
|
159
|
-
help='Do not include titles')
|
|
160
|
-
parser.add_argument('--netflow', action='store_true', default=False,
|
|
161
|
-
help='Netflow (nfdump) output')
|
|
162
|
-
parser.add_argument('--event', type=int, default=0,
|
|
163
|
-
help='EventID to parse (not using filename)')
|
|
164
|
-
args = parser.parse_args()
|
|
165
|
-
|
|
166
|
-
init()
|
|
167
|
-
app_printcomment = args.no_comment
|
|
168
|
-
app_hostname = args.hostname
|
|
169
|
-
app_domain = args.domain
|
|
170
|
-
app_ip_src = not(args.no_ip_src)
|
|
171
|
-
app_ip_dst = not(args.no_ip_dst)
|
|
172
|
-
app_ids_only = args.no_ids_only
|
|
173
|
-
app_printtitle = not(args.no_titles)
|
|
174
|
-
app_netflow = args.netflow
|
|
175
|
-
app_event = args.event
|
|
176
|
-
|
|
177
|
-
if app_event > 0:
|
|
178
|
-
get_event(app_event)
|
|
179
|
-
print_events()
|
|
180
|
-
elif args.filename is not None:
|
|
181
|
-
# print "app_printcomment %s app_hostname %s app_domain %s app_ip_src %s app_ip_dst %s app_ids_only %s app_printtitle %s" % (app_printcomment,app_hostname, app_domain, app_ip_src, app_ip_dst, app_ids_only, app_printtitle)
|
|
182
|
-
with open(args.filename, 'r') as line:
|
|
183
|
-
for event_id in line:
|
|
184
|
-
get_event(event_id.strip())
|
|
185
|
-
print_events()
|
|
186
|
-
else:
|
|
187
|
-
print("No filename given, stopping.")
|
examples/last.py
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
from pymisp import ExpandedPyMISP
|
|
5
|
-
from keys import misp_url, misp_key, misp_verifycert
|
|
6
|
-
try:
|
|
7
|
-
from keys import misp_client_cert
|
|
8
|
-
except ImportError:
|
|
9
|
-
misp_client_cert = ''
|
|
10
|
-
import argparse
|
|
11
|
-
import os
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
# Usage for pipe masters: ./last.py -l 5h | jq .
|
|
15
|
-
# Usage in case of large data set and pivoting page by page: python3 last.py -l 48h -m 10 -p 2 | jq .[].Event.info
|
|
16
|
-
|
|
17
|
-
if __name__ == '__main__':
|
|
18
|
-
parser = argparse.ArgumentParser(description='Download latest events from a MISP instance.')
|
|
19
|
-
parser.add_argument("-l", "--last", required=True, help="can be defined in days, hours, minutes (for example 5d or 12h or 30m).")
|
|
20
|
-
parser.add_argument("-m", "--limit", required=False, default="10", help="Add the limit of records to get (by default, the limit is set to 10)")
|
|
21
|
-
parser.add_argument("-p", "--page", required=False, default="1", help="Add the page to request to paginate over large dataset (by default page is set to 1)")
|
|
22
|
-
parser.add_argument("-o", "--output", help="Output file")
|
|
23
|
-
|
|
24
|
-
args = parser.parse_args()
|
|
25
|
-
|
|
26
|
-
if args.output is not None and os.path.exists(args.output):
|
|
27
|
-
print('Output file already exists, aborted.')
|
|
28
|
-
exit(0)
|
|
29
|
-
|
|
30
|
-
if misp_client_cert == '':
|
|
31
|
-
misp_client_cert = None
|
|
32
|
-
else:
|
|
33
|
-
misp_client_cert = (misp_client_cert)
|
|
34
|
-
|
|
35
|
-
misp = ExpandedPyMISP(misp_url, misp_key, misp_verifycert, cert=misp_client_cert)
|
|
36
|
-
result = misp.search(publish_timestamp=args.last, limit=args.limit, page=args.page, pythonify=True)
|
|
37
|
-
|
|
38
|
-
if not result:
|
|
39
|
-
print('No results for that time period')
|
|
40
|
-
exit(0)
|
|
41
|
-
|
|
42
|
-
if args.output:
|
|
43
|
-
with open(args.output, 'w') as f:
|
|
44
|
-
for r in result:
|
|
45
|
-
f.write(r.to_json() + '\n')
|
|
46
|
-
else:
|
|
47
|
-
for r in result:
|
|
48
|
-
print(r.to_json())
|