initial commit

pull/4/head
Sascha Rommelfangen 2017-04-27 13:58:49 +02:00
commit 97e5dddc61
4 changed files with 180 additions and 0 deletions

View File

@ -0,0 +1 @@
/Users/rommelfs/Library/Application Scripts/com.apple.mail/MISP Mail Rule Action.scptd

126
mail_to_misp.py Executable file
View File

@ -0,0 +1,126 @@
#!/usr/bin/python
import urlmarker
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
debug = config.debug
if debug:
debug_out_file = config.debug_out_file
target = open(debug_out_file, 'w')
target.write("New debug session opened")
try:
email_data = str(sys.argv[1])
email_subject = str(sys.argv[2])
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
malwaretags = config.malwaretags
dependingtags = config.dependingtags
# Ignore lines in body of message
email_data = re.sub(".*From: .*\n?","", email_data)
email_data = re.sub(".*Sender: .*\n?","", email_data)
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
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
email_data = refang(email_data)
urllist = re.findall(urlmarker.WEB_URL_REGEX,email_data)
urllist += re.findall(urlmarker.IP_REGEX,email_data)
if debug:
target.write(str(urllist))
# Init Faup
f = Faup()
for malware in malwaretags:
if malware in email_subject.lower():
for tag in malwaretags[malware]:
misp.add_tag(new_event, tag)
# Add IOCs and expanded information to MISP
for entry in urllist:
f.decode(entry)
domainname = f.get_domain().lower()
if debug:
target.write(domainname + "\n")
if domainname not in excludelist:
if domainname in externallist:
misp.add_named_attribute(new_event, 'link', entry, category='External analysis', to_ids=False)
else:
if debug:
target.write(entry + "\n")
misp.add_url(new_event, entry, category='Network activity', to_ids=True)
hostname = f.get_host().lower()
if debug:
target.write(hostname + "\n")
port = f.get_port()
comment = ""
if port:
comment = "on port: " + str(port)
misp.add_hostname(new_event, hostname, comment=comment, category='Network activity', to_ids=True)
try:
for rdata in dns.resolver.query(hostname, 'A'):
if debug:
target.write(str(rdata) + "\n")
misp.add_ipdst(new_event, str(rdata), category='Network activity', to_ids=True, comment=hostname)
except:
if debug:
target.write("DNS unsuccessful\n")
if debug:
target.close()

View File

@ -0,0 +1,28 @@
#!/usr/bin/python
misp_url = 'YOUR_MISP_URL'
misp_key = 'YOUR_KEY_HERE' # The MISP auth key can be found on the MISP web interface under the automation section
misp_verifycert = True
debug = True
debug_out_file = '/tmp/mail_to_misp-debug.txt'
nameservers = ['149.13.33.69']
excludelist = ('google.com', 'microsoft.com')
externallist = ('virustotal.com', 'malwr.com', 'hybrid-analysis.com', 'emergingthreats.net')
# TLP tag setup
# Tuples contain different variations of spelling
tlptags = { 'tlp:white': [ 'tlp:white', 'tlp: white' ],
'tlp:green': [ 'tlp:green', 'tlp: green' ],
'tlp:amber': [ 'tlp:amber', 'tlp: amber' ]
}
malwaretags = { 'locky': [ 'ecsirt:malicious-code="ransomware"', 'misp-galaxy:ransomware="Locky"' ],
'dridex': [ 'misp-galaxy:tool="dridex"' ],
'netwire': [ 'Netwire RAT' ]
}
# Tags to be set depending on the presence of other tags
dependingtags = { 'tlp:white': [ 'circl:osint-feed' ]
}

25
urlmarker.py Executable file
View File

@ -0,0 +1,25 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
url matching regex
http://daringfireball.net/2010/07/improved_regex_for_matching_urls
"""
"""
The regex patterns in this gist are intended to match any URLs,
including "mailto:foo@example.com", "x-whatever://foo", etc. For a
pattern that attempts only to match web URLs (http, https), see:
https://gist.github.com/gruber/8891611
"""
ANY_URL_REGEX = r"""(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))"""
"""
The regex patterns in this gist are intended only to match web URLs -- http,
https, and naked domains like "example.com". For a pattern that attempts to
match all URLs, regardless of protocol, see: https://gist.github.com/gruber/249502
"""
WEB_URL_REGEX = r"""(?i)\b((?:https?:(?:/{1,3}|[a-z0-9%])|[a-z0-9.\-]+[.](?:com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|Ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)/)(?:[^\s()<>{}\[\]]+|\([^\s()]*?\([^\s()]+\)[^\s()]*?\)|\([^\s]+?\))+(?:\([^\s()]*?\([^\s()]+\)[^\s()]*?\)|\([^\s]+?\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’])|(?:(?<!@)[a-z0-9]+(?:[.\-][a-z0-9]+)*[.](?:com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|Ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)\b/?(?!@)))"""
IP_REGEX = r"""[0-9]+(?:\.[0-9]+){3}:[0-9]+"""