-
Notifications
You must be signed in to change notification settings - Fork 0
/
event_forwarder_slack.py
114 lines (91 loc) · 4.49 KB
/
event_forwarder_slack.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
# Example of how to build a custom integration for event forwarding, in this
# example reading events using the REST API and forwarding them to Slack using
# a Slack Incoming Webhook.
#
# USAGE
# 1. Save the latest version of both this file (event_forwarder_slack.py) and
# the DI API Wrapper (deepinstinct3.py) to the same folder on disk.
# 2. Review and adjust configuration in-line below, then save changes.
# 3. By default the script will pull all events matching your configured search
# parameters. To start at a specific event ID, save that ID as a file
# 'event_forwarder_slack.conf' in the same directory as the script.
# 3. Execute the script with this command: python event_forwarder_slack.py
# NOTE: In order to avoid re-sending the same events, the script maintains a
# record of the last event previously sent on disk. This is stored in
# 'event_forwarder_slack.conf' in the same directory as the script. This
# allows preservation of this "high water mark" even if the script is
# killed and restarted. Be cautious not to delete/rename/move the .conf
# file. Doing so will cause the script to re-send all events.
#---import required libraries---
import time, json, requests, datetime, deepinstinct30 as di
#---configuration---
di.fqdn = 'FOO.customers.deepinstinctweb.com'
di.key = 'BAR'
# Define sleep time between queries to server in seconds (default 5 minutes)
sleep_time_in_seconds = 300
# Define a webhook URL for sending event data to Slack
webhook_url = 'https://hooks.slack.com/workflows/REDACTED'
# Define a list of fields to remove from events before sending to Slack
fields_to_remove = ['msp_name', 'msp_id', 'tenant_name', 'tenant_id',
'mitre_classifications',
'recorded_device_info',
'file_status', 'sandbox_status']
# Define search parameters when querying DI server for new events
search_parameters = {}
#search_parameters['status'] = ['OPEN', 'CLOSED']
#search_parameters['type'] = ['STATIC_ANALYSIS', 'RANSOMWARE_FILE_ENCRYPTION']
#search_parameters['threat_severity'] = ['HIGH', 'VERY_HIGH']
#---define methods used at runtime---
# a method for forwarding a single event to Slack using the provided webhook_url
def send_event_to_slack(event):
slack_data = {'event_data': json.dumps(event, indent=4)}
response = requests.post(webhook_url, json=slack_data, headers={'Content-Type': 'application/json'})
# a method to remove a key from a dictionary if it is present
def remove_key(dict, key):
if key in dict:
dict.pop(key)
# a method to remove unwanted fields from event data
def sanitize_event(event):
for field in fields_to_remove:
remove_key(event, field)
# a method to read config from .conf file on disk
def get_config():
try:
with open('event_forwarder_slack.conf', 'r') as f:
return int(f.read())
except OSError as e:
return 0
# a method to write config to .conf file on disk
def save_config(event_id):
try:
with open('event_forwarder_slack.conf', 'w') as f:
f.write(str(event_id))
except OSError as e:
now = datetime.datetime.now()
print(now.strftime("%H:%M"), 'ERROR:', e)
#---runtime---
while True:
max_event_processed_previously = get_config()
print('Getting new events with id greater than', max_event_processed_previously)
try:
new_events = di.get_events(minimum_event_id=max_event_processed_previously, search=search_parameters)
except requests.exceptions.RequestException as e:
now = datetime.datetime.now()
print(now.strftime("%H:%M"), 'ERROR:', e)
new_events = []
print(len(new_events), 'events were returned')
if len(new_events) > 0:
for event in new_events:
sanitize_event(event)
print('Sending event', event['id'], 'to Slack')
try:
send_event_to_slack(event)
except requests.exceptions.RequestException as e:
now = datetime.datetime.now()
print(now.strftime("%H:%M"), 'ERROR:', e)
if event['id'] > max_event_processed_previously:
max_event_processed_previously = event['id']
print('max_event_processed_previously is now', max_event_processed_previously)
save_config(max_event_processed_previously)
print('Sleeping for', sleep_time_in_seconds, 'seconds')
time.sleep(sleep_time_in_seconds)