mail_to_misp/mail_to_misp.py

177 lines
5.5 KiB
Python
Raw Normal View History

2017-04-27 13:58:49 +02:00
#!/usr/bin/python
import urlmarker
2017-04-28 10:00:58 +02:00
import hashmarker
2017-04-27 13:58:49 +02:00
import sys
import re
from pyfaup.faup import Faup
from pymisp import PyMISP
from defang import refang
import dns.resolver
import mail_to_misp_config as config
2017-05-23 15:09:25 +02:00
import email
from email.generator import Generator
2017-04-27 13:58:49 +02:00
debug = config.debug
2017-05-23 15:09:25 +02:00
stdin_used = False
2017-04-27 13:58:49 +02:00
if debug:
debug_out_file = config.debug_out_file
target = open(debug_out_file, 'w')
target.write("New debug session opened")
2017-05-23 15:09:25 +02:00
try:
email_subject = "M2M - "
email_data = ""
mailcontent = "".join(sys.stdin)
msg = email.message_from_string(mailcontent)
mail_subject = msg.get('Subject')
for part in msg.walk():
if part.get_content_maintype() == 'multipart':
continue
2017-05-23 15:56:13 +02:00
if part.get_content_maintype() == 'text':
email_data += part.get_payload(decode=True)
2017-05-23 15:09:25 +02:00
email_subject += mail_subject
stdin_used = True
except Exception as e:
print e
pass
2017-04-27 13:58:49 +02:00
try:
2017-05-23 15:09:25 +02:00
if not stdin_used:
email_data = str(sys.argv[1])
email_subject = str(sys.argv[2])
2017-04-27 13:58:49 +02:00
except:
if debug:
target.write("FATAL ERROR: Not all required input received")
sys.exit(1)
if debug:
target.write(email_subject)
target.write(email_data)
misp_url = config.misp_url
misp_key = config.misp_key
misp_verifycert = config.misp_verifycert
resolver = dns.resolver.Resolver(configure=False)
resolver.nameservers = config.nameservers
excludelist = config.excludelist
externallist = config.externallist
2017-04-28 10:00:58 +02:00
noidsflaglist = config.noidsflaglist
2017-04-27 13:58:49 +02:00
malwaretags = config.malwaretags
dependingtags = config.dependingtags
tlptag_default = config.tlptag_default
2017-05-17 09:51:47 +02:00
stopword = config.stopword
hash_only_tags = config.hash_only_tags
2017-04-27 13:58:49 +02:00
# Ignore lines in body of message
email_data = re.sub(".*From: .*\n?","", email_data)
email_data = re.sub(".*Sender: .*\n?","", email_data)
2017-05-08 15:47:47 +02:00
email_data = re.sub(".*Received: .*\n?","", email_data)
2017-04-27 13:58:49 +02:00
email_data = re.sub(".*Sender IP: .*\n?","", email_data)
email_data = re.sub(".*Reply-To: .*\n?","", email_data)
email_data = re.sub(".*Registrar WHOIS Server: .*\n?","", email_data)
email_data = re.sub(".*Registrar: .*\n?","", email_data)
email_data = re.sub(".*Domain Status: .*\n?","", email_data)
email_data = re.sub(".*Registrant Email: .*\n?","", email_data)
email_data = re.sub(".*IP Location: .*\n?","", email_data)
# Remove tags from subject
email_subject = re.sub("[\(\[].*?[\)\]]", "", email_subject)
# Remove "Re: " from subject
email_subject = re.sub("Re: ", "", email_subject)
def init(url, key):
return PyMISP(url, key, misp_verifycert, 'json')
# Evaluate classification
tlp_tag = tlptag_default
2017-04-27 13:58:49 +02:00
tlptags = config.tlptags
for tag in tlptags:
for alternativetag in tlptags[tag]:
if alternativetag in email_data.lower():
tlp_tag = tag
# Create the MISP event
misp = init(misp_url, misp_key)
new_event = misp.new_event(info=email_subject, distribution=0, threat_level_id=3, analysis=1)
misp.add_tag(new_event, tlp_tag)
# Add additional tags depending on others
for tag in dependingtags:
if tag in tlp_tag:
for dependingtag in dependingtags[tag]:
misp.add_tag(new_event, dependingtag)
# Extract IOCs
2017-05-17 09:51:47 +02:00
email_data = email_data.split(stopword, 1)[0]
2017-04-27 13:58:49 +02:00
email_data = refang(email_data)
2017-04-28 10:00:58 +02:00
urllist = re.findall(urlmarker.WEB_URL_REGEX, email_data)
urllist += re.findall(urlmarker.IP_REGEX, email_data)
2017-04-27 13:58:49 +02:00
if debug:
target.write(str(urllist))
# Init Faup
f = Faup()
2017-04-27 17:50:50 +02:00
# Add tags according to configuration
2017-04-27 13:58:49 +02:00
for malware in malwaretags:
if malware in email_subject.lower():
for tag in malwaretags[malware]:
misp.add_tag(new_event, tag)
2017-04-28 10:00:58 +02:00
# Extract and add hashes
hashlist_md5 = re.findall(hashmarker.MD5_REGEX, email_data)
hashlist_sha1 = re.findall(hashmarker.SHA1_REGEX, email_data)
hashlist_sha256 = re.findall(hashmarker.SHA256_REGEX, email_data)
for h in hashlist_md5:
misp.add_hashes(new_event, md5=h)
for h in hashlist_sha1:
misp.add_hashes(new_event, sha1=h)
for h in hashlist_sha256:
misp.add_hashes(new_event, sha256=h)
if (len(hashlist_md5) > 0) or (len(hashlist_sha1) > 0) or (len(hashlist_sha256) > 0):
for tag in hash_only_tags:
misp.add_tag(new_event, tag)
2017-04-27 13:58:49 +02:00
# Add IOCs and expanded information to MISP
for entry in urllist:
2017-04-28 10:00:58 +02:00
ids_flag = True
2017-04-27 13:58:49 +02:00
f.decode(entry)
domainname = f.get_domain().lower()
2017-04-28 10:00:58 +02:00
hostname = f.get_host().lower()
2017-04-27 13:58:49 +02:00
if debug:
target.write(domainname + "\n")
if domainname not in excludelist:
if domainname in externallist:
2017-05-08 15:47:47 +02:00
misp.add_named_attribute(new_event, 'link', entry, category='External analysis', to_ids=False)
2017-04-27 13:58:49 +02:00
else:
2017-04-28 10:00:58 +02:00
if (domainname in noidsflaglist) or (hostname in noidsflaglist):
ids_flag = False
2017-04-27 13:58:49 +02:00
if debug:
target.write(entry + "\n")
2017-04-28 10:00:58 +02:00
target.write(str(ids_flag))
2017-05-22 14:24:16 +02:00
misp.add_url(new_event, entry, category='Network activity', to_ids=ids_flag)
2017-04-27 13:58:49 +02:00
if debug:
target.write(hostname + "\n")
port = f.get_port()
comment = ""
if port:
comment = "on port: " + str(port)
2017-05-22 14:24:16 +02:00
misp.add_hostname(new_event, hostname, comment=comment, category='Network activity', to_ids=ids_flag)
2017-04-27 13:58:49 +02:00
try:
for rdata in dns.resolver.query(hostname, 'A'):
if debug:
target.write(str(rdata) + "\n")
2017-05-22 14:24:16 +02:00
misp.add_ipdst(new_event, str(rdata), category='Network activity', to_ids=ids_flag, comment=hostname)
2017-04-27 13:58:49 +02:00
except:
if debug:
target.write("DNS unsuccessful\n")
if debug:
target.close()