mirror of https://github.com/MISP/mail_to_misp
93 lines
3.4 KiB
Python
93 lines
3.4 KiB
Python
|
#!/usr/bin/env python3
|
||
|
# -*- coding: utf-8 -*-
|
||
|
import argparse
|
||
|
import importlib
|
||
|
import os
|
||
|
import sys
|
||
|
import syslog
|
||
|
from datetime import datetime, timedelta, timezone
|
||
|
from itertools import tee
|
||
|
from pathlib import Path
|
||
|
|
||
|
from mail2misp import Mail2MISP
|
||
|
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
parser = argparse.ArgumentParser(description='Push mail from O365 into a MISP instance')
|
||
|
group = parser.add_mutually_exclusive_group(required=True)
|
||
|
group.add_argument('-nd', '--days', help='Number of days to search back in inbox')
|
||
|
group.add_argument('-nh', '--hours', help='Number of hours to search back in inbox')
|
||
|
parser.add_argument('-f', '--folder', help='Folder name that contains email messages to parse')
|
||
|
args = parser.parse_args()
|
||
|
|
||
|
syslog.openlog(logoption=syslog.LOG_PID, facility=syslog.LOG_USER)
|
||
|
syslog.syslog("[+] O365 job started.")
|
||
|
|
||
|
# import config module
|
||
|
os.chdir(Path(__file__).parent)
|
||
|
|
||
|
configmodule = Path(__file__).name.replace('o365.py', 'config')
|
||
|
if Path(f"{configmodule}.py").exists():
|
||
|
config = importlib.import_module(configmodule)
|
||
|
try:
|
||
|
misp_url = config.misp_url
|
||
|
misp_key = config.misp_key
|
||
|
misp_verifycert = config.misp_verifycert
|
||
|
o365_client_id = config.o365_client_id
|
||
|
o365_client_secret = config.o365_client_secret
|
||
|
o365_tenant_id = config.o365_tenant_id
|
||
|
o365_resource = config.o365_resource
|
||
|
o365_scopes = config.o365_scopes
|
||
|
debug = config.debug
|
||
|
except Exception as ex:
|
||
|
print("There is a problem with the configuration. A mandatory configuration variable is not set.")
|
||
|
print("Did you just update? mail_to_misp might have new configuration variables.")
|
||
|
print("Please compare with the configuration example.")
|
||
|
print("\nTrace:")
|
||
|
print(ex)
|
||
|
sys.exit(-2)
|
||
|
else:
|
||
|
print(f"Couldn't locate config file {configmodule}.py")
|
||
|
sys.exit(-1)
|
||
|
|
||
|
# set message search period to look for emails
|
||
|
to_time = datetime.now(timezone.utc)
|
||
|
|
||
|
if args.days:
|
||
|
from_time = (to_time - timedelta(days=int(args.days)))
|
||
|
else:
|
||
|
from_time = (to_time - timedelta(hours=int(args.hours)))
|
||
|
|
||
|
# initialize Mail2MISP
|
||
|
m2m = Mail2MISP(misp_url, misp_key, misp_verifycert, config=config)
|
||
|
|
||
|
# initialize O365MISPClient
|
||
|
o365 = m2m.O365MISPClient(
|
||
|
client_id=o365_client_id,
|
||
|
client_secret=o365_client_secret,
|
||
|
tenant_id=o365_tenant_id,
|
||
|
resource=o365_resource,
|
||
|
scopes=o365_scopes,
|
||
|
token_backend=None # if not supplied will default to using FileSystemTokenBackend, which stores the token in a
|
||
|
# txt file on disk in the directory the script is executed from
|
||
|
)
|
||
|
|
||
|
messages = o365.get_email_messages(
|
||
|
from_time=from_time,
|
||
|
to_time=to_time,
|
||
|
folder=args.folder if args.folder else None # defaults to searching the resource's inbox folder if None
|
||
|
)
|
||
|
|
||
|
messages1, messages2 = tee(messages, 2)
|
||
|
|
||
|
syslog.syslog(f"[*] Found {len(list(messages1))} messages to process and send to MISP!")
|
||
|
|
||
|
for msg in messages2:
|
||
|
m2m.load_o365_email(msg)
|
||
|
if debug:
|
||
|
syslog.syslog(f"[*] Processing email with subject: {m2m.subject}")
|
||
|
m2m.process_o365_email_body()
|
||
|
m2m.process_body_iocs()
|
||
|
m2m.add_event()
|
||
|
syslog.syslog("[-] O365 job finished.")
|