mirror of https://github.com/MISP/misp-modules
Add additional email parsing and tests
Added additional attribute parsing and corresponding unit-tests. E-mail attachment and url extraction added in this commit. This includes unpacking zipfiles and simple password cracking of encrypted zipfiles.pull/62/head
parent
0ff270a3be
commit
1a7973bc06
|
@ -21,12 +21,10 @@ moduleinfo = {'version': '0.1',
|
||||||
'description': 'Email import module for MISP',
|
'description': 'Email import module for MISP',
|
||||||
'module-type': ['import']}
|
'module-type': ['import']}
|
||||||
|
|
||||||
# treat_attachments_as_malware : This treats all attachments as malware. This will zip all attachments and password protect using the password 'infected'
|
|
||||||
# unzip_attachments : Unzip all zip files that are not password protected
|
# unzip_attachments : Unzip all zip files that are not password protected
|
||||||
# guess_zip_attachment_passwords : This attempts to unzip all password protected zip files using all the strings found in the email body and subject
|
# guess_zip_attachment_passwords : This attempts to unzip all password protected zip files using all the strings found in the email body and subject
|
||||||
# extract_urls : This attempts to extract all URL's from text/html parts of the email
|
# extract_urls : This attempts to extract all URL's from text/html parts of the email
|
||||||
moduleconfig = ["treat_attachments_as_malware",
|
moduleconfig = ["unzip_attachments",
|
||||||
"unzip_attachments",
|
|
||||||
"guess_zip_attachment_passwords",
|
"guess_zip_attachment_passwords",
|
||||||
"extract_urls"]
|
"extract_urls"]
|
||||||
|
|
||||||
|
@ -45,7 +43,7 @@ def handler(q=False):
|
||||||
# Extract all header information
|
# Extract all header information
|
||||||
all_headers = ""
|
all_headers = ""
|
||||||
for k, v in message.items():
|
for k, v in message.items():
|
||||||
all_headers += "\n{0}: {1}".format(k, v)
|
all_headers += "{0}: {1}\n".format(k, v)
|
||||||
results.append({"values": all_headers,
|
results.append({"values": all_headers,
|
||||||
"types": ['email-header']})
|
"types": ['email-header']})
|
||||||
|
|
||||||
|
@ -77,14 +75,10 @@ def handler(q=False):
|
||||||
from_addr = message.get('From')
|
from_addr = message.get('From')
|
||||||
results.append({"values": parseaddr(from_addr)[1],
|
results.append({"values": parseaddr(from_addr)[1],
|
||||||
"types": ['email-src'],
|
"types": ['email-src'],
|
||||||
"comment": "From: {0}".format(re.sub('["\']',
|
"comment": "From: {0}".format(from_addr)})
|
||||||
'',
|
results.append({"values": parseaddr(from_addr)[0],
|
||||||
from_addr))})
|
|
||||||
results.append({"values": parseaddr(from_addr)[1],
|
|
||||||
"types": ['email-src-display-name'],
|
"types": ['email-src-display-name'],
|
||||||
"comment": "From: {0}".format(re.sub('["\']',
|
"comment": "From: {0}".format(from_addr)})
|
||||||
'',
|
|
||||||
from_addr))})
|
|
||||||
|
|
||||||
# Return Path
|
# Return Path
|
||||||
return_path = message.get('Return-Path')
|
return_path = message.get('Return-Path')
|
||||||
|
@ -111,15 +105,11 @@ def handler(q=False):
|
||||||
results.append({"values": parsed_addr[1],
|
results.append({"values": parsed_addr[1],
|
||||||
"types": ["email-dst"],
|
"types": ["email-dst"],
|
||||||
"comment": "{0}: {1}".format(hdr_val,
|
"comment": "{0}: {1}".format(hdr_val,
|
||||||
re.sub('["\']',
|
addr)})
|
||||||
'',
|
|
||||||
addr))})
|
|
||||||
results.append({"values": parsed_addr[0],
|
results.append({"values": parsed_addr[0],
|
||||||
"types": ["email-dst-display-name"],
|
"types": ["email-dst-display-name"],
|
||||||
"comment": "{0}: {1}".format(hdr_val,
|
"comment": "{0}: {1}".format(hdr_val,
|
||||||
re.sub('["\']',
|
addr)})
|
||||||
'',
|
|
||||||
addr))})
|
|
||||||
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
continue
|
continue
|
||||||
|
@ -127,45 +117,45 @@ def handler(q=False):
|
||||||
# Get E-Mail Targets
|
# Get E-Mail Targets
|
||||||
# Get the addresses that received the email.
|
# Get the addresses that received the email.
|
||||||
# As pulled from the Received header
|
# As pulled from the Received header
|
||||||
received = message.get_all('received')
|
received = message.get_all('Received')
|
||||||
email_targets = set()
|
email_targets = set()
|
||||||
for rec in received:
|
try:
|
||||||
try:
|
for rec in received:
|
||||||
email_check = re.search("for\s(.*@.*);", rec).group(1)
|
try:
|
||||||
email_check = email_check.strip(' <>')
|
email_check = re.search("for\s(.*@.*);", rec).group(1)
|
||||||
email_targets.add(parseaddr(email_check)[1])
|
email_check = email_check.strip(' <>')
|
||||||
except (AttributeError):
|
email_targets.add(parseaddr(email_check)[1])
|
||||||
continue
|
except (AttributeError):
|
||||||
for tar in email_targets:
|
continue
|
||||||
results.append({"values": tar,
|
for tar in email_targets:
|
||||||
"types": ["target-email"],
|
results.append({"values": tar,
|
||||||
"comment": "Extracted from email 'Received' header"})
|
"types": ["target-email"],
|
||||||
|
"comment": "Extracted from email 'Received' header"})
|
||||||
|
except TypeError:
|
||||||
|
pass # If received header is missing we can't iterate over NoneType
|
||||||
|
|
||||||
# Check if we were given a configuration
|
# Check if we were given a configuration
|
||||||
config = request.get("config", {})
|
config = request.get("config", {})
|
||||||
# Don't be picky about how the user chooses to say yes to these
|
# Don't be picky about how the user chooses to say yes to these
|
||||||
acceptable_config_yes = ['y', 'yes', 'true', 't']
|
acceptable_config_yes = ['y', 'yes', 'true', 't']
|
||||||
|
|
||||||
# Do we treat all attachments as malware
|
|
||||||
treat_attachments_as_malware = config.get("treat_attachments_as_malware",
|
|
||||||
"false")
|
|
||||||
if treat_attachments_as_malware.lower() in acceptable_config_yes:
|
|
||||||
treat_attachments_as_malware = True
|
|
||||||
|
|
||||||
# Do we unzip attachments we find?
|
# Do we unzip attachments we find?
|
||||||
unzip = config.get("unzip_attachments", "false")
|
unzip = config.get("unzip_attachments", None)
|
||||||
if unzip.lower() in acceptable_config_yes:
|
if (unzip is not None and
|
||||||
|
unzip.lower() in acceptable_config_yes):
|
||||||
unzip = True
|
unzip = True
|
||||||
|
|
||||||
# Do we try to find passwords for protected zip files?
|
# Do we try to find passwords for protected zip files?
|
||||||
zip_pass_crack = config.get("guess_zip_attachment_passwords", "false")
|
zip_pass_crack = config.get("guess_zip_attachment_passwords", None)
|
||||||
if zip_pass_crack.lower() in acceptable_config_yes:
|
if (zip_pass_crack is not None and
|
||||||
|
zip_pass_crack.lower() in acceptable_config_yes):
|
||||||
zip_pass_crack = True
|
zip_pass_crack = True
|
||||||
password_list = None # Only want to collect password list once
|
password_list = None # Only want to collect password list once
|
||||||
|
|
||||||
# Do we extract URL's from the email.
|
# Do we extract URL's from the email.
|
||||||
extract_urls = config.get("extract_urls", "false")
|
extract_urls = config.get("extract_urls", None)
|
||||||
if extract_urls.lower() in acceptable_config_yes:
|
if (extract_urls is not None and
|
||||||
|
extract_urls.lower() in acceptable_config_yes):
|
||||||
extract_urls = True
|
extract_urls = True
|
||||||
|
|
||||||
# Get Attachments
|
# Get Attachments
|
||||||
|
@ -174,41 +164,35 @@ def handler(q=False):
|
||||||
filename = part.get_filename()
|
filename = part.get_filename()
|
||||||
if filename is not None:
|
if filename is not None:
|
||||||
attachment_data = part.get_payload(decode=True)
|
attachment_data = part.get_payload(decode=True)
|
||||||
|
# Base attachment data is default
|
||||||
|
attachment_files = [{"values": filename,
|
||||||
|
"data" : base64.b64encode(attachment_data).decode()}]
|
||||||
if unzip is True: # Attempt to unzip the attachment and return its files
|
if unzip is True: # Attempt to unzip the attachment and return its files
|
||||||
try:
|
try:
|
||||||
attachment_files = get_zipped_contents(filename,
|
attachment_files += get_zipped_contents(filename,
|
||||||
attachment_data)
|
attachment_data)
|
||||||
except RuntimeError: # File is encrypted with a password
|
except RuntimeError: # File is encrypted with a password
|
||||||
if zip_pass_crack is True:
|
if zip_pass_crack is True:
|
||||||
if password_list is None:
|
if password_list is None:
|
||||||
password_list = get_zip_passwords(message)
|
password_list = get_zip_passwords(message)
|
||||||
password = test_zip_passwords(attachment_data, password_list)
|
password = test_zip_passwords(attachment_data, password_list)
|
||||||
# If we don't guess the password just use the zip
|
if password is None: # Inform the analyst that we could not crack password
|
||||||
if password is None:
|
attachment_files[0]['comment'] = "Encrypted Zip: Password could not be cracked from message"
|
||||||
attachment_files = [{"values": filename,
|
|
||||||
"data" : base64.b64encode(attachment_data),
|
|
||||||
"comment":"Password could not be cracked from message"}]
|
|
||||||
else:
|
else:
|
||||||
attachment_files = get_zipped_contents(filename,
|
attachment_files[0]['comment'] = """Original Zipped Attachment with Password {0}""".format(password)
|
||||||
|
attachment_files += get_zipped_contents(filename,
|
||||||
attachment_data,
|
attachment_data,
|
||||||
password=password)
|
password=password)
|
||||||
|
|
||||||
except zipfile.BadZipFile: # Attachment is not a zipfile
|
except zipfile.BadZipFile: # Attachment is not a zipfile
|
||||||
attachment_files = [{"values": filename,
|
attachment_files += [{"values": filename,
|
||||||
"data" : base64.b64encode(attachment_data)}]
|
"data" : base64.b64encode(attachment_data).decode()}]
|
||||||
else:
|
|
||||||
attachment_files = [{"values": filename,
|
|
||||||
"data" : base64.b64encode(attachment_data)}]
|
|
||||||
for attch_item in attachment_files:
|
for attch_item in attachment_files:
|
||||||
if treat_attachments_as_malware is True: # Malware-samples are encrypted by server
|
attch_item["types"] = ['attachment']
|
||||||
attch_item["types"] = ['malware-sample']
|
|
||||||
else:
|
|
||||||
attch_item["types"] = ['attachment']
|
|
||||||
results.append(attch_item)
|
results.append(attch_item)
|
||||||
else: # Check email body part for urls
|
else: # Check email body part for urls
|
||||||
if (extract_urls is True and part.get_content_type() == 'text/html'):
|
if (extract_urls is True and part.get_content_type() == 'text/html'):
|
||||||
url_parser = HTMLURLParser()
|
url_parser = HTMLURLParser()
|
||||||
charset = get_charset(i, get_charset(message))
|
charset = get_charset(part, get_charset(message))
|
||||||
url_parser.feed(part.get_payload(decode=True).decode(charset))
|
url_parser.feed(part.get_payload(decode=True).decode(charset))
|
||||||
urls = url_parser.urls
|
urls = url_parser.urls
|
||||||
for url in urls:
|
for url in urls:
|
||||||
|
@ -235,11 +219,11 @@ def get_zipped_contents(filename, data, password=None):
|
||||||
unzipped_files = []
|
unzipped_files = []
|
||||||
if password is not None:
|
if password is not None:
|
||||||
password = str.encode(password) # Byte encoded password required
|
password = str.encode(password) # Byte encoded password required
|
||||||
for zip_file_name in zf: # Get all files in the zip file
|
for zip_file_name in zf.namelist(): # Get all files in the zip file
|
||||||
|
with zf.open(zip_file_name, mode='rU', pwd=password) as fp:
|
||||||
|
file_data = fp.read()
|
||||||
unzipped_files.append({"values": zip_file_name,
|
unzipped_files.append({"values": zip_file_name,
|
||||||
"data" : base64.b64encode(zf.open(zip_file_name,
|
"data" : base64.b64encode(file_data).decode(), # Any password works when not encrypted
|
||||||
mode='rU',
|
|
||||||
pwd=password)), # Any password works when not encrypted
|
|
||||||
"comment": "Extracted from {0}".format(filename)})
|
"comment": "Extracted from {0}".format(filename)})
|
||||||
return unzipped_files
|
return unzipped_files
|
||||||
|
|
||||||
|
@ -256,11 +240,12 @@ def test_zip_passwords(data, test_passwords):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
with zipfile.ZipFile(io.BytesIO(data), "r") as zf:
|
with zipfile.ZipFile(io.BytesIO(data), "r") as zf:
|
||||||
|
firstfile = zf.namelist()[0]
|
||||||
for pw_test in test_passwords:
|
for pw_test in test_passwords:
|
||||||
byte_pwd = str.encode(pw_test)
|
byte_pwd = str.encode(pw_test)
|
||||||
try:
|
try:
|
||||||
zf.testzip()
|
zf.open(firstfile, pwd=byte_pwd)
|
||||||
return byte_pwd
|
return pw_test
|
||||||
except RuntimeError: # Incorrect Password
|
except RuntimeError: # Incorrect Password
|
||||||
continue
|
continue
|
||||||
return None
|
return None
|
||||||
|
@ -315,10 +300,10 @@ def get_zip_passwords(message):
|
||||||
raw_text += subject
|
raw_text += subject
|
||||||
|
|
||||||
# Grab any strings that are marked off by special chars
|
# Grab any strings that are marked off by special chars
|
||||||
marking_chars = [["'", "'"], ['"', '"'], ['[', ']'], ['(', ')']]
|
marking_chars = [["\'", "\'"], ['"', '"'], ['[', ']'], ['(', ')']]
|
||||||
for char_set in marking_chars:
|
for char_set in marking_chars:
|
||||||
regex = re.compile("'{0}([^{1}]*){1}'".format(char_set[0],
|
regex = re.compile("""\{0}([^\{1}]*)\{1}""".format(char_set[0],
|
||||||
char_set[1]))
|
char_set[1]))
|
||||||
marked_off = re.findall(regex, raw_text)
|
marked_off = re.findall(regex, raw_text)
|
||||||
possible_passwords += marked_off
|
possible_passwords += marked_off
|
||||||
|
|
||||||
|
@ -350,7 +335,7 @@ class HTMLURLParser(HTMLParser):
|
||||||
if urls is None:
|
if urls is None:
|
||||||
self.urls = []
|
self.urls = []
|
||||||
else:
|
else:
|
||||||
self.urls = output_list
|
self.urls = urls
|
||||||
def handle_starttag(self, tag, attrs):
|
def handle_starttag(self, tag, attrs):
|
||||||
if tag == 'a':
|
if tag == 'a':
|
||||||
self.urls.append(dict(attrs).get('href'))
|
self.urls.append(dict(attrs).get('href'))
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
467
tests/test.py
467
tests/test.py
|
@ -5,8 +5,11 @@ import unittest
|
||||||
import requests
|
import requests
|
||||||
import base64
|
import base64
|
||||||
import json
|
import json
|
||||||
import os
|
import io
|
||||||
import urllib
|
import zipfile
|
||||||
|
from email.mime.application import MIMEApplication
|
||||||
|
from email.mime.text import MIMEText
|
||||||
|
from email.mime.multipart import MIMEMultipart
|
||||||
|
|
||||||
|
|
||||||
class TestModules(unittest.TestCase):
|
class TestModules(unittest.TestCase):
|
||||||
|
@ -53,164 +56,298 @@ class TestModules(unittest.TestCase):
|
||||||
assert("eu-society.com" in values)
|
assert("eu-society.com" in values)
|
||||||
|
|
||||||
def test_email_headers(self):
|
def test_email_headers(self):
|
||||||
with open("tests/test_no_attach.eml", "r") as f:
|
query = {"module":"email_import"}
|
||||||
data = json.dumps({"module":"email_import",
|
query["config"] = {"unzip_attachments": None,
|
||||||
"data":str(base64.b64encode(bytes(f.read(), 'utf8')),
|
"guess_zip_attachment_passwords": None,
|
||||||
'utf8')}).encode('utf8')
|
"extract_urls": None}
|
||||||
response = requests.post(self.url + "query", data=data)
|
message = get_base_email()
|
||||||
response.connection.close()
|
text = """I am a test e-mail"""
|
||||||
print(response.json())
|
message.attach(MIMEText(text, 'plain'))
|
||||||
|
query['data'] = decode_email(message)
|
||||||
|
data = json.dumps(query)
|
||||||
|
response = requests.post(self.url + "query", data=data)
|
||||||
|
results = response.json()['results']
|
||||||
|
values = [x["values"] for x in results]
|
||||||
|
types = {}
|
||||||
|
for i in results:
|
||||||
|
types.setdefault(i["types"][0], 0)
|
||||||
|
types[i["types"][0]] += 1
|
||||||
|
# Check that there are the appropriate number of items
|
||||||
|
# Check that all the items were correct
|
||||||
|
self.assertEqual(types['target-email'], 1)
|
||||||
|
self.assertIn('test@domain.com', values)
|
||||||
|
self.assertEqual(types['email-dst-display-name'], 4)
|
||||||
|
self.assertIn('Last One', values)
|
||||||
|
self.assertIn('Other Friend', values)
|
||||||
|
self.assertIn('Second Person', values)
|
||||||
|
self.assertIn('Testy Testerson', values)
|
||||||
|
self.assertEqual(types['email-dst'], 4)
|
||||||
|
self.assertIn('test@domain.com', values)
|
||||||
|
self.assertIn('second@domain.com', values)
|
||||||
|
self.assertIn('other@friend.net', values)
|
||||||
|
self.assertIn('last_one@finally.com', values)
|
||||||
|
self.assertEqual(types['email-src-display-name'], 2)
|
||||||
|
self.assertIn("Innocent Person", values)
|
||||||
|
self.assertEqual(types['email-src'], 2)
|
||||||
|
self.assertIn("evil_spoofer@example.com", values)
|
||||||
|
self.assertIn("IgnoreMeImInnocent@sender.com", values)
|
||||||
|
self.assertEqual(types['email-thread-index'], 1)
|
||||||
|
self.assertIn('AQHSR8Us3H3SoaY1oUy9AAwZfMF922bnA9GAgAAi9s4AAGvxAA==', values)
|
||||||
|
self.assertEqual(types['email-message-id'], 1)
|
||||||
|
self.assertIn("<4988EF2D.40804@example.com>", values)
|
||||||
|
self.assertEqual(types['email-subject'], 1)
|
||||||
|
self.assertIn("Example Message", values)
|
||||||
|
self.assertEqual(types['email-header'], 1)
|
||||||
|
self.assertEqual(types['email-x-mailer'], 1)
|
||||||
|
self.assertIn("mlx 5.1.7", values)
|
||||||
|
self.assertEqual(types['email-reply-to'], 1)
|
||||||
|
# The parser inserts a newline that I can't diagnose.
|
||||||
|
# It does not impact analysis since the interface strips it.
|
||||||
|
# But, I'm leaving this test failing
|
||||||
|
self.assertIn("<CI7DgL-A6dm92s7gf4-88g@E_0x238G4K2H08H9SDwsw8b6LwuA@mail.example.com>", values)
|
||||||
|
#self.assertIn("\n <CI7DgL-A6dm92s7gf4-88g@E_0x238G4K2H08H9SDwsw8b6LwuA@mail.example.com>", values)
|
||||||
|
|
||||||
def test_email_attachment_basic(self):
|
def test_email_attachment_basic(self):
|
||||||
with open("tests/test_attachment.eml", "r") as f:
|
query = {"module":"email_import"}
|
||||||
data = json.dumps({"module":"email_import",
|
query["config"] = {"unzip_attachments": None,
|
||||||
"data":str(base64.b64encode(bytes(f.read(), 'utf8')),
|
"guess_zip_attachment_passwords": None,
|
||||||
'utf8')}).encode('utf8')
|
"extract_urls": None}
|
||||||
response = requests.post(self.url + "query", data=data)
|
message = get_base_email()
|
||||||
response.connection.close()
|
text = """I am a test e-mail"""
|
||||||
print(response.json())
|
message.attach(MIMEText(text, 'plain'))
|
||||||
|
with open("tests/EICAR.com", "rb") as fp:
|
||||||
|
eicar_mime = MIMEApplication(fp.read(), 'com')
|
||||||
|
eicar_mime.add_header('Content-Disposition', 'attachment', filename="EICAR.com")
|
||||||
|
message.attach(eicar_mime)
|
||||||
|
query['data'] = decode_email(message)
|
||||||
|
data = json.dumps(query)
|
||||||
|
response = requests.post(self.url + "query", data=data)
|
||||||
|
values = [x["values"] for x in response.json()['results']]
|
||||||
|
self.assertIn('EICAR.com', values)
|
||||||
|
for i in response.json()['results']:
|
||||||
|
if i["types"][0] == 'attachment':
|
||||||
|
self.assertEqual(i["values"], "EICAR.com")
|
||||||
|
attch_data = base64.b64decode(i["data"])
|
||||||
|
self.assertEqual(attch_data,
|
||||||
|
b'X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-')
|
||||||
|
|
||||||
|
|
||||||
def test_email_attachment_unpack(self):
|
def test_email_attachment_unpack(self):
|
||||||
raise NotImplementedError("NOT IMPLEMENTED")
|
query = {"module":"email_import"}
|
||||||
with open("tests/test_attachment.eml", "r") as f:
|
query["config"] = {"unzip_attachments": "true",
|
||||||
data = json.dumps({"module":"email_import",
|
"guess_zip_attachment_passwords": None,
|
||||||
"data":str(base64.b64encode(bytes(f.read(), 'utf8')),
|
"extract_urls": None}
|
||||||
'utf8')}).encode('utf8')
|
message = get_base_email()
|
||||||
response = requests.post(self.url + "query", data=data)
|
text = """I am a test e-mail"""
|
||||||
response.connection.close()
|
message.attach(MIMEText(text, 'plain'))
|
||||||
print(response.json())
|
with open("tests/EICAR.com.zip", "rb") as fp:
|
||||||
|
eicar_mime = MIMEApplication(fp.read(), 'zip')
|
||||||
def test_email_attachment_as_malware(self):
|
eicar_mime.add_header('Content-Disposition', 'attachment', filename="EICAR.com.zip")
|
||||||
raise NotImplementedError("NOT IMPLEMENTED")
|
message.attach(eicar_mime)
|
||||||
with open("tests/test_attachment.eml", "r") as f:
|
query['data'] = decode_email(message)
|
||||||
data = json.dumps({"module":"email_import",
|
data = json.dumps(query)
|
||||||
"data":str(base64.b64encode(bytes(f.read(), 'utf8')),
|
response = requests.post(self.url + "query", data=data)
|
||||||
'utf8')}).encode('utf8')
|
values = [x["values"] for x in response.json()["results"]]
|
||||||
response = requests.post(self.url + "query", data=data)
|
self.assertIn('EICAR.com', values)
|
||||||
response.connection.close()
|
self.assertIn('EICAR.com.zip', values)
|
||||||
print(response.json())
|
for i in response.json()['results']:
|
||||||
|
if i["values"] == 'EICAR.com.zip':
|
||||||
def test_email_attachment_as_malware_password_in_body(self):
|
with zipfile.ZipFile(io.BytesIO(base64.b64decode(i["data"])), 'r') as zf:
|
||||||
raise NotImplementedError("NOT IMPLEMENTED")
|
with zf.open("EICAR.com") as ec:
|
||||||
test_email = helper_create_email({"body":"""The password is infected
|
attch_data = ec.read()
|
||||||
|
self.assertEqual(attch_data,
|
||||||
Best,
|
b'X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-')
|
||||||
"some random malware researcher who thinks he is slick." """})
|
if i["values"] == 'EICAR.com':
|
||||||
|
attch_data = base64.b64decode(i["data"])
|
||||||
with open("tests/test_attachment.eml", "r") as f:
|
self.assertEqual(attch_data,
|
||||||
data = json.dumps({"module":"email_import",
|
b'X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-')
|
||||||
"data":str(base64.b64encode(test_email)).encode('utf8')})
|
|
||||||
response = requests.post(self.url + "query", data=data)
|
|
||||||
response.connection.close()
|
|
||||||
print(response.json())
|
|
||||||
|
|
||||||
def test_email_attachment_as_malware_password_in_body_sentance(self):
|
|
||||||
raise NotImplementedError("NOT IMPLEMENTED")
|
|
||||||
test_email = helper_create_email({"body":"""The password is infected.
|
|
||||||
|
|
||||||
Best,
|
|
||||||
"some random malware researcher who thinks he is slick." """})
|
|
||||||
|
|
||||||
with open("tests/test_attachment.eml", "r") as f:
|
|
||||||
data = json.dumps({"module":"email_import",
|
|
||||||
"data":str(base64.b64encode(test_email)}).encode('utf8')
|
|
||||||
response = requests.post(self.url + "query", data=data)
|
|
||||||
response.connection.close()
|
|
||||||
print(response.json())
|
|
||||||
|
|
||||||
def test_email_attachment_as_malware_password_in_html_body(self):
|
|
||||||
raise NotImplementedError("NOT IMPLEMENTED")
|
|
||||||
# TODO Encrypt baseline attachment with "i like pineapples!!!"
|
|
||||||
# TODO Figure out how to set HTML body
|
|
||||||
test_email = helper_create_email({"body":"""The password is found in this email.
|
|
||||||
It is "i like pineapples!!!".
|
|
||||||
|
|
||||||
Best,
|
|
||||||
"some random malware researcher who thinks he is slick." """})
|
|
||||||
response = requests.post(self.url + "query", data=data)
|
|
||||||
response.connection.close()
|
|
||||||
print(response.json())
|
|
||||||
|
|
||||||
def test_email_attachment_as_malware_password_in_subject(self):
|
|
||||||
raise NotImplementedError("NOT IMPLEMENTED")
|
|
||||||
with open("tests/test_attachment.eml", "r") as f:
|
|
||||||
data = json.dumps({"module":"email_import",
|
|
||||||
"data":str(base64.b64encode(bytes(f.read(), 'utf8')),
|
|
||||||
'utf8')}).encode('utf8')
|
|
||||||
response = requests.post(self.url + "query", data=data)
|
|
||||||
response.connection.close()
|
|
||||||
print(response.json())
|
|
||||||
|
|
||||||
def test_email_attachment_as_malware_passphraise_in_quotes(self):
|
|
||||||
raise NotImplementedError("NOT IMPLEMENTED")
|
|
||||||
# TODO Encrypt baseline attachment with "i like pineapples!!!"
|
|
||||||
test_email = helper_create_email({"body":"""The password is found in this email.
|
|
||||||
It is "i like pineapples!!!".
|
|
||||||
|
|
||||||
Best,
|
|
||||||
"some random malware researcher who thinks he is slick." """})
|
|
||||||
with open("tests/test_attachment.eml", "r") as f:
|
|
||||||
data = json.dumps({"module":"email_import",
|
|
||||||
"data":str(base64.b64encode(test_email)}).encode('utf8')
|
|
||||||
response = requests.post(self.url + "query", data=data)
|
|
||||||
response.connection.close()
|
|
||||||
print(response.json())
|
|
||||||
|
|
||||||
def test_email_attachment_as_malware_passphraise_in_brackets(self):
|
|
||||||
raise NotImplementedError("NOT IMPLEMENTED")
|
|
||||||
# TODO Encrypt baseline attachment with "i like pineapples!!!"
|
|
||||||
test_email = helper_create_email({"body":"""The password is found in this email.
|
|
||||||
It is [i like pineapples!!!].
|
|
||||||
|
|
||||||
Best,
|
|
||||||
"some random malware researcher who thinks he is slick." """})
|
|
||||||
|
|
||||||
with open("tests/test_attachment.eml", "r") as f:
|
|
||||||
data = json.dumps({"module":"email_import",
|
|
||||||
"data":str(base64.b64encode(test_email)}).encode('utf8')
|
|
||||||
response = requests.post(self.url + "query", data=data)
|
|
||||||
response.connection.close()
|
|
||||||
print(response.json())
|
|
||||||
|
|
||||||
def test_email_attachment_unpack_and_as_malware(self):
|
|
||||||
raise NotImplementedError("NOT IMPLEMENTED")
|
|
||||||
with open("tests/test_attachment.eml", "r") as f:
|
|
||||||
data = json.dumps({"module":"email_import",
|
|
||||||
"data":str(base64.b64encode(bytes(f.read(), 'utf8')),
|
|
||||||
'utf8')}).encode('utf8')
|
|
||||||
response = requests.post(self.url + "query", data=data)
|
|
||||||
response.connection.close()
|
|
||||||
print(response.json())
|
|
||||||
|
|
||||||
def test_virustotal(self):
|
|
||||||
# This can't actually be tested without disclosing a private
|
|
||||||
# API key. This will attempt to run with a .gitignored keyfile
|
|
||||||
# and pass if it can't find one
|
|
||||||
|
|
||||||
if not os.path.exists("tests/bodyvirustotal.json"):
|
|
||||||
return
|
|
||||||
|
|
||||||
with open("tests/bodyvirustotal.json", "r") as f:
|
|
||||||
response = requests.post(self.url + "query", data=f.read()).json()
|
|
||||||
assert(response)
|
|
||||||
response.connection.close()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def helper_create_email(**conf):
|
|
||||||
raise NotImplementedError("NOT IMPLEMENTED")
|
|
||||||
attachment_name = conf.get("attachment_name", None)
|
|
||||||
subject = conf.get("subject", "Hello friend this is a test email")
|
|
||||||
subject = conf.get("subject", "Hello friend this is a test email")
|
|
||||||
received = conf.get("Received", ["""Received: via dmail-2008.19 for +INBOX;\n\tTue, 3 Feb 2009 19:29:12 -0600 (CST)""","""Received: from abc.luxsci.com ([10.10.10.10])\n\tby xyz.luxsci.com (8.13.7/8.13.7) with\n\tESMTP id n141TCa7022588\n\tfor <test@domain.com>;\n\tTue, 3 Feb 2009 19:29:12 -0600""", """Received: from [192.168.0.3] (verizon.net [44.44.44.44])\n\t(user=test@sender.com mech=PLAIN bits=2)\n\tby abc.luxsci.com (8.13.7/8.13.7) with\n\tESMTP id n141SAfo021855\n\t(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA\n\tbits=256 verify=NOT) for <test@domain.com>;\n\tTue, 3 Feb 2009 19:28:10 -0600"""])
|
|
||||||
return_path = conf.get("Return-Path", "Return-Path: evil_spoofer@example.com")
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_email_attachment_unpack_with_password(self):
|
||||||
|
query = {"module":"email_import"}
|
||||||
|
query["config"] = {"unzip_attachments": "true",
|
||||||
|
"guess_zip_attachment_passwords": 'true',
|
||||||
|
"extract_urls": None}
|
||||||
|
message = get_base_email()
|
||||||
|
text = """I am a test e-mail"""
|
||||||
|
message.attach(MIMEText(text, 'plain'))
|
||||||
|
with open("tests/infected.zip", "rb") as fp:
|
||||||
|
eicar_mime = MIMEApplication(fp.read(), 'zip')
|
||||||
|
eicar_mime.add_header('Content-Disposition', 'attachment', filename="EICAR.com.zip")
|
||||||
|
message.attach(eicar_mime)
|
||||||
|
query['data'] = decode_email(message)
|
||||||
|
data = json.dumps(query)
|
||||||
|
response = requests.post(self.url + "query", data=data)
|
||||||
|
values = [x["values"] for x in response.json()["results"]]
|
||||||
|
self.assertIn('EICAR.com', values)
|
||||||
|
self.assertIn('EICAR.com.zip', values)
|
||||||
|
for i in response.json()['results']:
|
||||||
|
if i["values"] == 'EICAR.com.zip':
|
||||||
|
with zipfile.ZipFile(io.BytesIO(base64.b64decode(i["data"])), 'r') as zf:
|
||||||
|
# Make sure password was set and still in place
|
||||||
|
self.assertRaises(RuntimeError, zf.open, "EICAR.com")
|
||||||
|
if i["values"] == 'EICAR.com':
|
||||||
|
attch_data = base64.b64decode(i["data"])
|
||||||
|
self.assertEqual(attch_data,
|
||||||
|
b'X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-')
|
||||||
|
|
||||||
|
|
||||||
|
def test_email_attachment_password_in_body(self):
|
||||||
|
query = {"module":"email_import"}
|
||||||
|
query["config"] = {"unzip_attachments": "true",
|
||||||
|
"guess_zip_attachment_passwords": 'true',
|
||||||
|
"extract_urls": None}
|
||||||
|
message = get_base_email()
|
||||||
|
text = """I am a -> STRINGS <- test e-mail"""
|
||||||
|
message.attach(MIMEText(text, 'plain'))
|
||||||
|
with open("tests/short_password.zip", "rb") as fp:
|
||||||
|
eicar_mime = MIMEApplication(fp.read(), 'zip')
|
||||||
|
eicar_mime.add_header('Content-Disposition', 'attachment', filename="EICAR.com.zip")
|
||||||
|
message.attach(eicar_mime)
|
||||||
|
query['data'] = decode_email(message)
|
||||||
|
data = json.dumps(query)
|
||||||
|
response = requests.post(self.url + "query", data=data)
|
||||||
|
values = [x["values"] for x in response.json()["results"]]
|
||||||
|
self.assertIn('EICAR.com', values)
|
||||||
|
for i in response.json()['results']:
|
||||||
|
if i["values"] == 'EICAR.com':
|
||||||
|
attch_data = base64.b64decode(i["data"]).decode()
|
||||||
|
self.assertEqual(attch_data,
|
||||||
|
'X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-')
|
||||||
|
|
||||||
|
def test_email_attachment_password_in_body_quotes(self):
|
||||||
|
query = {"module":"email_import"}
|
||||||
|
query["config"] = {"unzip_attachments": "true",
|
||||||
|
"guess_zip_attachment_passwords": 'true',
|
||||||
|
"extract_urls": None}
|
||||||
|
message = get_base_email()
|
||||||
|
text = """I am a test e-mail
|
||||||
|
the password is "a long password".
|
||||||
|
|
||||||
|
That is all.
|
||||||
|
"""
|
||||||
|
message.attach(MIMEText(text, 'plain'))
|
||||||
|
with open("tests/longer_password.zip", "rb") as fp:
|
||||||
|
eicar_mime = MIMEApplication(fp.read(), 'zip')
|
||||||
|
eicar_mime.add_header('Content-Disposition', 'attachment', filename="EICAR.com.zip")
|
||||||
|
message.attach(eicar_mime)
|
||||||
|
query['data'] = decode_email(message)
|
||||||
|
data = json.dumps(query)
|
||||||
|
response = requests.post(self.url + "query", data=data)
|
||||||
|
values = [x["values"] for x in response.json()["results"]]
|
||||||
|
self.assertIn('EICAR.com', values)
|
||||||
|
for i in response.json()['results']:
|
||||||
|
# Check that it could be extracted.
|
||||||
|
if i["values"] == 'EICAR.com':
|
||||||
|
attch_data = base64.b64decode(i["data"]).decode()
|
||||||
|
self.assertEqual(attch_data,
|
||||||
|
'X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-')
|
||||||
|
|
||||||
|
def test_email_attachment_password_in_html_body(self):
|
||||||
|
query = {"module":"email_import"}
|
||||||
|
query["config"] = {"unzip_attachments": "true",
|
||||||
|
"guess_zip_attachment_passwords": 'true',
|
||||||
|
"extract_urls": None}
|
||||||
|
message = get_base_email()
|
||||||
|
text = """I am a test e-mail
|
||||||
|
the password is NOT "this string".
|
||||||
|
|
||||||
|
That is all.
|
||||||
|
"""
|
||||||
|
html = """\
|
||||||
|
<html>
|
||||||
|
<head></head>
|
||||||
|
<body>
|
||||||
|
<p>Hi!<br>
|
||||||
|
This is the real password?<br>
|
||||||
|
It is "a long password".
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
message.attach(MIMEText(text, 'plain'))
|
||||||
|
message.attach(MIMEText(html, 'html'))
|
||||||
|
with open("tests/longer_password.zip", "rb") as fp:
|
||||||
|
eicar_mime = MIMEApplication(fp.read(), 'zip')
|
||||||
|
eicar_mime.add_header('Content-Disposition', 'attachment', filename="EICAR.com.zip")
|
||||||
|
message.attach(eicar_mime)
|
||||||
|
query['data'] = decode_email(message)
|
||||||
|
data = json.dumps(query)
|
||||||
|
response = requests.post(self.url + "query", data=data)
|
||||||
|
#print(response.json())
|
||||||
|
values = [x["values"] for x in response.json()["results"]]
|
||||||
|
self.assertIn('EICAR.com', values)
|
||||||
|
for i in response.json()['results']:
|
||||||
|
# Check that it could be extracted.
|
||||||
|
if i["values"] == 'EICAR.com':
|
||||||
|
attch_data = base64.b64decode(i["data"]).decode()
|
||||||
|
self.assertEqual(attch_data,
|
||||||
|
'X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-')
|
||||||
|
|
||||||
|
def test_email_attachment_password_in_subject(self):
|
||||||
|
query = {"module":"email_import"}
|
||||||
|
query["config"] = {"unzip_attachments": "true",
|
||||||
|
"guess_zip_attachment_passwords": 'true',
|
||||||
|
"extract_urls": None}
|
||||||
|
message = get_base_email()
|
||||||
|
message.replace_header("Subject", 'I contain the -> "a long password" <- that is the password')
|
||||||
|
text = """I am a test e-mail
|
||||||
|
the password is NOT "this string".
|
||||||
|
|
||||||
|
That is all.
|
||||||
|
"""
|
||||||
|
message.attach(MIMEText(text, 'plain'))
|
||||||
|
with open("tests/longer_password.zip", "rb") as fp:
|
||||||
|
eicar_mime = MIMEApplication(fp.read(), 'zip')
|
||||||
|
eicar_mime.add_header('Content-Disposition', 'attachment', filename="EICAR.com.zip")
|
||||||
|
message.attach(eicar_mime)
|
||||||
|
query['data'] = decode_email(message)
|
||||||
|
data = json.dumps(query)
|
||||||
|
response = requests.post(self.url + "query", data=data)
|
||||||
|
values = [x["values"] for x in response.json()["results"]]
|
||||||
|
self.assertIn('EICAR.com', values)
|
||||||
|
self.assertIn('I contain the -> "a long password" <- that is the password', values)
|
||||||
|
for i in response.json()['results']:
|
||||||
|
# Check that it could be extracted.
|
||||||
|
if i["values"] == 'EICAR.com':
|
||||||
|
attch_data = base64.b64decode(i["data"]).decode()
|
||||||
|
self.assertEqual(attch_data,
|
||||||
|
'X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-')
|
||||||
|
|
||||||
|
|
||||||
|
def test_email_extract_html_body_urls(self):
|
||||||
|
query = {"module":"email_import"}
|
||||||
|
query["config"] = {"unzip_attachments": None,
|
||||||
|
"guess_zip_attachment_passwords": None,
|
||||||
|
"extract_urls": "true"}
|
||||||
|
message = get_base_email()
|
||||||
|
text = """I am a test e-mail
|
||||||
|
|
||||||
|
That is all.
|
||||||
|
"""
|
||||||
|
html = """\
|
||||||
|
<html>
|
||||||
|
<head></head>
|
||||||
|
<body>
|
||||||
|
<p>Hi!<br>
|
||||||
|
<p>MISP modules are autonomous modules that can be used for expansion and other services in <a href="https://github.com/MISP/MISP">MISP</a>.</p>
|
||||||
|
<p>The modules are written in Python 3 following a simple API interface. The objective is to ease the extensions of MISP functionalities
|
||||||
|
without modifying core components. The API is available via a simple REST API which is independent from MISP installation or configuration.</p>
|
||||||
|
<p>MISP modules support is included in MISP starting from version 2.4.28.</p>
|
||||||
|
<p>For more information: <a href="https://www.circl.lu/assets/files/misp-training/3.1-MISP-modules.pdf">Extending MISP with Python modules</a> slides from MISP training.</p>
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
message.attach(MIMEText(text, 'plain'))
|
||||||
|
message.attach(MIMEText(html, 'html'))
|
||||||
|
query['data'] = decode_email(message)
|
||||||
|
data = json.dumps(query)
|
||||||
|
response = requests.post(self.url + "query", data=data)
|
||||||
|
#print(response.json())
|
||||||
|
values = [x["values"] for x in response.json()["results"]]
|
||||||
|
self.assertIn("https://github.com/MISP/MISP", values)
|
||||||
|
self.assertIn("https://www.circl.lu/assets/files/misp-training/3.1-MISP-modules.pdf", values)
|
||||||
|
|
||||||
#def test_domaintools(self):
|
#def test_domaintools(self):
|
||||||
# query = {'config': {'username': 'test_user', 'api_key': 'test_key'}, 'module': 'domaintools', 'domain': 'domaintools.com'}
|
# query = {'config': {'username': 'test_user', 'api_key': 'test_key'}, 'module': 'domaintools', 'domain': 'domaintools.com'}
|
||||||
|
@ -221,6 +358,38 @@ def helper_create_email(**conf):
|
||||||
# response = requests.post(self.url + "query", data=json.dumps(query)).json()
|
# response = requests.post(self.url + "query", data=json.dumps(query)).json()
|
||||||
# print(response)
|
# print(response)
|
||||||
|
|
||||||
|
def decode_email(message):
|
||||||
|
message64 = base64.b64encode(message.as_bytes()).decode()
|
||||||
|
return message64
|
||||||
|
|
||||||
|
|
||||||
|
def get_base_email():
|
||||||
|
headers = {"Received":"via dmail-2008.19 for +INBOX; Tue, 3 Feb 2009 19:29:12 -0600 (CST)",
|
||||||
|
"Received":"from abc.luxsci.com ([10.10.10.10]) by xyz.luxsci.com (8.13.7/8.13.7) with ESMTP id n141TCa7022588 for <test@domain.com>; Tue, 3 Feb 2009 19:29:12 -0600",
|
||||||
|
"Received":"from [192.168.0.3] (verizon.net [44.44.44.44]) (user=test@sender.com mech=PLAIN bits=2) by abc.luxsci.com (8.13.7/8.13.7) with ESMTP id n141SAfo021855 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT) for <test@domain.com>; Tue, 3 Feb 2009 19:28:10 -0600",
|
||||||
|
"X-Received":"by 192.168.0.45 with SMTP id q4mr156123401yw1g.911.1912342394963; Tue, 3 Feb 2009 19:32:15 -0600 (PST)",
|
||||||
|
"Message-ID":"<4988EF2D.40804@example.com>",
|
||||||
|
"Date":"Tue, 03 Feb 2009 20:28:13 -0500",
|
||||||
|
"From":'"Innocent Person" <IgnoreMeImInnocent@sender.com>',
|
||||||
|
"User-Agent":'Thunderbird 2.0.0.19 (Windows/20081209)',
|
||||||
|
"Sender":'"Malicious MailAgent" <mailagent@example.com>',
|
||||||
|
"References":"<CI7DgL-A6dm92s7gf4-88g@E_0x238G4K2H08H9SDwsw8b6LwuA@mail.example.com>",
|
||||||
|
"In-Reply-To":"<CI7DgL-A6dm92s7gf4-88g@E_0x238G4K2H08H9SDwsw8b6LwuA@mail.example.com>",
|
||||||
|
"Accept-Language":'en-US',
|
||||||
|
"X-Mailer":'mlx 5.1.7',
|
||||||
|
"Return-Path": "evil_spoofer@example.com",
|
||||||
|
"Thread-Topic":'This is a thread.',
|
||||||
|
"Thread-Index":'AQHSR8Us3H3SoaY1oUy9AAwZfMF922bnA9GAgAAi9s4AAGvxAA==',
|
||||||
|
"Content-Language":'en-US',
|
||||||
|
"To":'"Testy Testerson" <test@domain.com>',
|
||||||
|
"Cc":'"Second Person" <second@domain.com>, "Other Friend" <other@friend.net>, "Last One" <last_one@finally.com>',
|
||||||
|
"Subject":'Example Message',
|
||||||
|
"MIME-Version":'1.0'}
|
||||||
|
msg = MIMEMultipart()
|
||||||
|
for key, val in headers.items():
|
||||||
|
msg.add_header(key, val)
|
||||||
|
return msg
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -1,167 +0,0 @@
|
||||||
Received: via dmail-2008.19 for +INBOX;
|
|
||||||
Tue, 3 Feb 2009 19:29:12 -0600 (CST)
|
|
||||||
Received: from abc.luxsci.com ([10.10.10.10])
|
|
||||||
by xyz.luxsci.com (8.13.7/8.13.7) with
|
|
||||||
ESMTP id n141TCa7022588
|
|
||||||
for <test@domain.com>;
|
|
||||||
Tue, 3 Feb 2009 19:29:12 -0600
|
|
||||||
Return-Path: evil_spoofer@example.com
|
|
||||||
Received: from [192.168.0.3] (verizon.net [44.44.44.44])
|
|
||||||
(user=test@sender.com mech=PLAIN bits=2)
|
|
||||||
by abc.luxsci.com (8.13.7/8.13.7) with
|
|
||||||
ESMTP id n141SAfo021855
|
|
||||||
(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA
|
|
||||||
bits=256 verify=NOT) for <test@domain.com>;
|
|
||||||
Tue, 3 Feb 2009 19:28:10 -0600
|
|
||||||
Message-ID: <4988EF2D.40804@domain.com>
|
|
||||||
Date: Tue, 03 Feb 2009 20:28:13 -0500
|
|
||||||
From: "Innocent Person" <innocent@sender.com>
|
|
||||||
User-Agent: Thunderbird 2.0.0.19 (Windows/20081209)
|
|
||||||
MIME-Version: 1.0
|
|
||||||
To: "Testy Testerson" <test@domain.com>
|
|
||||||
Cc: "Second Person" <second@domain.com>, "Other Friend" <other@friend.net>, "Last One" <last_one@finally.com>
|
|
||||||
Subject: Example Message
|
|
||||||
Content-Type: multipart/mixed; boundary=047d7b2edc8d80dac9053f7a3f8d
|
|
||||||
|
|
||||||
--047d7b2edc8d80dac9053f7a3f8d
|
|
||||||
Content-Type: multipart/alternative; boundary=047d7b2edc8d80dac4053f7a3f8b
|
|
||||||
|
|
||||||
--047d7b2edc8d80dac4053f7a3f8b
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: base64
|
|
||||||
|
|
||||||
TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwg
|
|
||||||
c2VkIGRvIGVpdXNtb2QNCnRlbXBvciBpbmNpZGlkdW50IHV0IGxhYm9yZSBldCBkb2xvcmUgbWFn
|
|
||||||
bmEgYWxpcXVhLiBVdCBlbmltIGFkIG1pbmltDQp2ZW5pYW0sIHF1aXMgbm9zdHJ1ZCBleGVyY2l0
|
|
||||||
YXRpb24gdWxsYW1jbyBsYWJvcmlzIG5pc2kgdXQgYWxpcXVpcCBleCBlYQ0KY29tbW9kbyBjb25z
|
|
||||||
ZXF1YXQuIER1aXMgYXV0ZSBpcnVyZSBkb2xvciBpbiByZXByZWhlbmRlcml0IGluIHZvbHVwdGF0
|
|
||||||
ZQ0KdmVsaXQgZXNzZSBjaWxsdW0gZG9sb3JlIGV1IGZ1Z2lhdCBudWxsYSBwYXJpYXR1ci4gRXhj
|
|
||||||
ZXB0ZXVyIHNpbnQgb2NjYWVjYXQNCmN1cGlkYXRhdCBub24gcHJvaWRlbnQsIHN1bnQgaW4gY3Vs
|
|
||||||
cGEgcXVpIG9mZmljaWEgZGVzZXJ1bnQgbW9sbGl0IGFuaW0gaWQNCmVzdCBsYWJvcnVtLg0KDQrQ
|
|
||||||
ndCw0Lwg0LvRjNCw0LHQvtGA0Y0g0L/QvtGI0LbQuNC8INC10LQsINC80Y3Qu9GMINC90L4g0L7Q
|
|
||||||
sdC70YzQudC60LLRjtGNINGN0YDRgNC+0YDQuNCx0YPQtyDQsNCx0YXQvtGA0YDRjdCw0L3Rgiwg
|
|
||||||
0LDRgiDQu9Cw0LHQvtGA0LDQvNGO0LcNCtCy0Y7Qu9GM0L/Rg9GC0LDRgtGLINCy0Y3Quy4g0JnQ
|
|
||||||
vSDRg9C90Y7QvCDRjtGA0LHQsNC90LnRgtCw0LYg0LLQtdC60LYsINC50L0g0Y3QvtC2INGB0YrR
|
|
||||||
jtC80LzQviDQtNC10LrRgtCw0LYuINCQ0LvQuNGRINC80Y7QvdGL0YDRjQ0K0ZHRg9C00ZHQutCw
|
|
||||||
0LHQtdGCINC90YvQuiDRjdGOLCDRg9GCINC30LDQu9GM0Ysg0L/QvtGA0YDQviDQtNC50LrQuNGC
|
|
||||||
INCy0LjQvC4g0J3QviDQv9C+0L3QtNGN0YDRjtC8INC30LrRgNC40L/RgtC+0YDRjdC8INGL0LDQ
|
|
||||||
vC4NCg0K54mh5pyI5YWD5L2P6YCj5Yud6KuW5pyd56Wd5aSJ6ZmN5b6X44CC5Lq65q2j6IGe5LqL
|
|
||||||
6KaW57aZ55S755m65p2l5Yui5bee5ZaE5pyA6JGJ6ICF55u444CC55+l6KW/5Zu95pKy55Sf5riI
|
|
||||||
5YWD5YCN56aP5Zuz57SE5pyI5YiG546L44CC5aWz5ryU6KaL5Y2U5rK75Yqg6K2w5b+F6YKj6KiY
|
|
||||||
6aOy5LiN5Z6L6KeS5rOo6YCy5q6L5LiW44CCDQroppbmlq3pn7PntLDooZfov5Hlkb3mlq3mpJzl
|
|
||||||
p7/nlJ/lhYXmsr/lpKfmsZDku67liIDjgILokZfoirjms5XmnaXploDlhYjlsJHlt53mtojnqJrn
|
|
||||||
ooHogZ7lrrnnrKznmYLmuKzlsI/nlbPokYnjgILmlZnmpJznkIPmraLmjZzluLjoq77npoHlspDk
|
|
||||||
u5Xph5HovInlkajmvZ/lhKrjgILnlLvoqq3otorooYDmpa3plbflgaXmj5DlsZ7pg6jkv53kuIfl
|
|
||||||
vqnkuIfnj77muIvoqKrlrq7lrrnov5HjgIINCuaYjuW/heWbsumDteaBteW6g+acgOa0l+Wunei8
|
|
||||||
iei/lOmDqOOAgg0KDQrgpLngpYvgpJfgpL4g4KS44KSC4KSq4KS+4KSm4KSVIOCkheCkqOClgeCk
|
|
||||||
leClguCksiDgpLjgpL7gpLDgpY3gpLXgpJzgpKjgpL/gpJUg4KS14KS/4KSt4KS+4KSXIOCkhuCk
|
|
||||||
nOCkquCksCDgpLjgpYHgpJrgpKjgpL4g4KS44KWN4KSl4KS/4KSk4KS/IOCkteCkvuCksOCljeCk
|
|
||||||
pOCkvuCksuCkvuCkqiDgpKrgpYHgpLfgpY3gpJ/gpL/gpJXgpLDgpY3gpKTgpL4NCuCkruClgeCk
|
|
||||||
luCljeCkr+CkpOCkuSDgpLXgpL7gpLDgpY3gpKTgpL7gpLLgpL7gpKog4KSq4KWN4KSw4KWL4KSk
|
|
||||||
4KWN4KS44KS+4KS54KS/4KSkIOCkieCkuOCkleClhyDgpLjgpK7gpL7gpJzgpYsg4KWt4KS54KSy
|
|
||||||
IOCknOCkv+CkruCljeCkruClhyDgpJTgpLDgpY3gpargpavgpaYg4KSm4KS44KWN4KSk4KS+4KS1
|
|
||||||
4KWH4KScIOCkueCkruCkvuCksOClgA0K4KSc4KS/4KS44KSV4KWAIOCkuOCkruCkvuCknCDgpKzg
|
|
||||||
pL/gpKjgpY3gpKbgpYHgpJMg4KS44KWL4KWe4KWN4KSf4KS14KWH4KSwIOCkteCljeCkr+CkvuCk
|
|
||||||
luCljeCkr+CkvuCkqCDgpK7gpYfgpILgpK3gpJ/gpYMg4KS14KS+4KS44KWN4KSk4KS1IOCkquCl
|
|
||||||
jeCksOClh+CksOCkqOCkviDgpLjgpYDgpK7gpL/gpKQg4KSc4KWI4KS44KWHIOCkquCkueCli+Ck
|
|
||||||
mg0K4KSo4KSv4KWH4KSy4KS/4KSPIOCkueCliOClpOCkheCkreClgCDgpLjgpK3gpL/gpLjgpK7g
|
|
||||||
pJwg4KS14KS/4KS14KSw4KSjIOCkluCksOCkv+CkpuCkqOClhyDgpKjgpL/gpLDgpY3gpKbgpYfg
|
|
||||||
pLYg4KS14KWN4KSv4KS14KS54KS+4KSwIOCkreCkvuCkpOCkvyDgpLXgpL/gpLbgpY3gpLUg4KS5
|
|
||||||
4KWA4KSV4KSuIOCknOCkvuCkqOCkpOClhw0K4KSJ4KSm4KWN4KSv4KWL4KSXIOCkquCkpOCljeCk
|
|
||||||
sOCkv+CkleCkviDgpLXgpY3gpLDgpYHgpKbgpY3gpKfgpL8g4KS54KS+4KSw4KWN4KSh4KS14KWH
|
|
||||||
4KSwIOCkheCkqOCljeCkpOCksOCksOCkvuCkt+CljeCkn+CljeCksOClgOCkr+CkleCksOCkqCDg
|
|
||||||
pKfgpY3gpLXgpKjgpL8g4KSP4KS14KSu4KWNIOCkpuCljeCkteCkvuCksOCkviDgpI7gpLjgpL7g
|
|
||||||
pJzgpYDgpLgNCuCkquClgeCkt+CljeCkn+Ckv+CkleCksOCljeCkpOCkviDgpLXgpL/gpLbgpY3g
|
|
||||||
pLUg4KSw4KSa4KSo4KS+DQoNCtmIINit2YrYqyDZgtix2LHYqiDZh9in2LHYqNixINin2YTZhtiy
|
|
||||||
2KfYuSwg2LPYp9i52Kkg2KfZhNmH2KfYr9mKINil2LAg2YjZgdmKLCDYudmGINmF2YXYpyDZiNiy
|
|
||||||
2KfYsdipINmI2YfZiNmE2YbYr9in2IwuINil2LANCtin2YTYo9mI2YQg2KjZhdio2KfYsdmD2Kkg
|
|
||||||
2YTZhdmRLiDYqNit2Ksg2YrYt9mI2YQg2YjYp9mE2YXYudiv2KfYqiDZo9mgLCDZgdmKINmF2KfZ
|
|
||||||
itmIINmE2YTYrNiy2LEg2YjYs9mF2ZHZitiqINmB2YLYry4g2YXYpw0K2YHYsdmG2LPZitipINis
|
|
||||||
2LLZitix2KrZiiDYp9mE2KvYp9mE2Ksg2YjZhdmGLiDZhdmD2YYg2YfZiCDZhNmD2YjZhiDZhdiv
|
|
||||||
2YrZhtipINmI2KjYsdmK2LfYp9mG2YrYpy4g2aPZoCDZiNmE2YUg2KfZhNmE2Ycg2KfZhNmF2KrY
|
|
||||||
rdiv2KkuDQrYqtmE2YMg2YjYqtix2YMg2YTYqNmI2YTZhtiv2KfYjCDZgtivLCDZh9iw2Kcg2YjY
|
|
||||||
rNmH2KfZhiDYp9mE2K7Yp9i32YHYqSDYp9mE2YjYstix2KfYoSDYudmGLg0KDQpCZXN0LA0KWW91
|
|
||||||
ciBGcmllbmQNCg==
|
|
||||||
--047d7b2edc8d80dac4053f7a3f8b
|
|
||||||
Content-Type: text/html; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: base64
|
|
||||||
|
|
||||||
PGRpdiBkaXI9Imx0ciI+PGRpdiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI+TG9yZW0gaXBzdW0g
|
|
||||||
ZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwgc2VkIGRvIGVpdXNt
|
|
||||||
b2Q8L2Rpdj48ZGl2IHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij50ZW1wb3IgaW5jaWRpZHVudCB1
|
|
||||||
dCBsYWJvcmUgZXQgZG9sb3JlIG1hZ25hIGFsaXF1YS4gVXQgZW5pbSBhZCBtaW5pbTwvZGl2Pjxk
|
|
||||||
aXYgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPnZlbmlhbSwgcXVpcyBub3N0cnVkIGV4ZXJjaXRh
|
|
||||||
dGlvbiB1bGxhbWNvIGxhYm9yaXMgbmlzaSB1dCBhbGlxdWlwIGV4IGVhPC9kaXY+PGRpdiBzdHls
|
|
||||||
ZT0iZm9udC1zaXplOjEyLjhweCI+Y29tbW9kbyBjb25zZXF1YXQuIER1aXMgYXV0ZSBpcnVyZSBk
|
|
||||||
b2xvciBpbiByZXByZWhlbmRlcml0IGluIHZvbHVwdGF0ZTwvZGl2PjxkaXYgc3R5bGU9ImZvbnQt
|
|
||||||
c2l6ZToxMi44cHgiPnZlbGl0IGVzc2UgY2lsbHVtIGRvbG9yZSBldSBmdWdpYXQgbnVsbGEgcGFy
|
|
||||||
aWF0dXIuIEV4Y2VwdGV1ciBzaW50IG9jY2FlY2F0PC9kaXY+PGRpdiBzdHlsZT0iZm9udC1zaXpl
|
|
||||||
OjEyLjhweCI+Y3VwaWRhdGF0IG5vbiBwcm9pZGVudCwgc3VudCBpbiBjdWxwYSBxdWkgb2ZmaWNp
|
|
||||||
YSBkZXNlcnVudCBtb2xsaXQgYW5pbSBpZDwvZGl2PjxkaXYgc3R5bGU9ImZvbnQtc2l6ZToxMi44
|
|
||||||
cHgiPmVzdCBsYWJvcnVtLjwvZGl2PjxkaXYgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxicj48
|
|
||||||
L2Rpdj48ZGl2IHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij7QndCw0Lwg0LvRjNCw0LHQvtGA0Y0g
|
|
||||||
0L/QvtGI0LbQuNC8INC10LQsINC80Y3Qu9GMINC90L4g0L7QsdC70YzQudC60LLRjtGNINGN0YDR
|
|
||||||
gNC+0YDQuNCx0YPQtyDQsNCx0YXQvtGA0YDRjdCw0L3Rgiwg0LDRgiDQu9Cw0LHQvtGA0LDQvNGO
|
|
||||||
0Lc8L2Rpdj48ZGl2IHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij7QstGO0LvRjNC/0YPRgtCw0YLR
|
|
||||||
iyDQstGN0LsuINCZ0L0g0YPQvdGO0Lwg0Y7RgNCx0LDQvdC50YLQsNC2INCy0LXQutC2LCDQudC9
|
|
||||||
INGN0L7QtiDRgdGK0Y7QvNC80L4g0LTQtdC60YLQsNC2LiDQkNC70LjRkSDQvNGO0L3Ri9GA0Y08
|
|
||||||
L2Rpdj48ZGl2IHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij7RkdGD0LTRkdC60LDQsdC10YIg0L3R
|
|
||||||
i9C6INGN0Y4sINGD0YIg0LfQsNC70YzRiyDQv9C+0YDRgNC+INC00LnQutC40YIg0LLQuNC8LiDQ
|
|
||||||
ndC+INC/0L7QvdC00Y3RgNGO0Lwg0LfQutGA0LjQv9GC0L7RgNGN0Lwg0YvQsNC8LjwvZGl2Pjxk
|
|
||||||
aXYgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxicj48L2Rpdj48ZGl2IHN0eWxlPSJmb250LXNp
|
|
||||||
emU6MTIuOHB4Ij7niaHmnIjlhYPkvY/pgKPli53oq5bmnJ3npZ3lpInpmY3lvpfjgILkurrmraPo
|
|
||||||
gZ7kuovoppbntpnnlLvnmbrmnaXli6Llt57lloTmnIDokYnogIXnm7jjgII8d2JyPuefpeilv+Wb
|
|
||||||
veaSsueUn+a4iOWFg+WAjeemj+Wbs+e0hOaciOWIhueOi+OAgjx3YnI+5aWz5ryU6KaL5Y2U5rK7
|
|
||||||
5Yqg6K2w5b+F6YKj6KiY6aOy5LiN5Z6L6KeS5rOo6YCy5q6L5LiW44CCPHdicj7oppbmlq3pn7Pn
|
|
||||||
tLDooZfov5Hlkb3mlq3mpJzlp7/nlJ/lhYXmsr/lpKfmsZDku67liIDjgII8d2JyPuiRl+iKuOaz
|
|
||||||
leadpemWgOWFiOWwkeW3nea2iOeomueigeiBnuWuueesrOeZgua4rOWwj+eVs+iRieOAgjx3YnI+
|
|
||||||
5pWZ5qSc55CD5q2i5o2c5bi46Ku+56aB5bKQ5LuV6YeR6LyJ5ZGo5r2f5YSq44CCPHdicj7nlLvo
|
|
||||||
qq3otorooYDmpa3plbflgaXmj5DlsZ7pg6jkv53kuIflvqnkuIfnj77muIvoqKrlrq7lrrnov5Hj
|
|
||||||
gII8d2JyPuaYjuW/heWbsumDteaBteW6g+acgOa0l+Wunei8iei/lOmDqOOAgjwvZGl2PjxkaXYg
|
|
||||||
c3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPjxicj48L2Rpdj48ZGl2IHN0eWxlPSJmb250LXNpemU6
|
|
||||||
MTIuOHB4Ij7gpLngpYvgpJfgpL4g4KS44KSC4KSq4KS+4KSm4KSVIOCkheCkqOClgeCkleClguCk
|
|
||||||
siDgpLjgpL7gpLDgpY3gpLXgpJzgpKjgpL/gpJUg4KS14KS/4KSt4KS+4KSXIOCkhuCknOCkquCk
|
|
||||||
sCDgpLjgpYHgpJrgpKjgpL4g4KS44KWN4KSl4KS/4KSk4KS/IOCkteCkvuCksOCljeCkpOCkvuCk
|
|
||||||
suCkvuCkqiDgpKrgpYHgpLfgpY3gpJ/gpL/gpJXgpLDgpY3gpKTgpL48L2Rpdj48ZGl2IHN0eWxl
|
|
||||||
PSJmb250LXNpemU6MTIuOHB4Ij7gpK7gpYHgpJbgpY3gpK/gpKTgpLkg4KS14KS+4KSw4KWN4KSk
|
|
||||||
4KS+4KSy4KS+4KSqIOCkquCljeCksOCli+CkpOCljeCkuOCkvuCkueCkv+CkpCDgpIngpLjgpJXg
|
|
||||||
pYcg4KS44KSu4KS+4KSc4KWLIOClreCkueCksiDgpJzgpL/gpK7gpY3gpK7gpYcg4KSU4KSw4KWN
|
|
||||||
4KWq4KWr4KWmIOCkpuCkuOCljeCkpOCkvuCkteClh+CknCDgpLngpK7gpL7gpLDgpYA8L2Rpdj48
|
|
||||||
ZGl2IHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij7gpJzgpL/gpLjgpJXgpYAg4KS44KSu4KS+4KSc
|
|
||||||
IOCkrOCkv+CkqOCljeCkpuClgeCkkyDgpLjgpYvgpZ7gpY3gpJ/gpLXgpYfgpLAg4KS14KWN4KSv
|
|
||||||
4KS+4KSW4KWN4KSv4KS+4KSoIOCkruClh+CkguCkreCkn+ClgyDgpLXgpL7gpLjgpY3gpKTgpLUg
|
|
||||||
4KSq4KWN4KSw4KWH4KSw4KSo4KS+IOCkuOClgOCkruCkv+CkpCDgpJzgpYjgpLjgpYcg4KSq4KS5
|
|
||||||
4KWL4KSaPC9kaXY+PGRpdiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI+4KSo4KSv4KWH4KSy4KS/
|
|
||||||
4KSPIOCkueCliOClpOCkheCkreClgCDgpLjgpK3gpL/gpLjgpK7gpJwg4KS14KS/4KS14KSw4KSj
|
|
||||||
IOCkluCksOCkv+CkpuCkqOClhyDgpKjgpL/gpLDgpY3gpKbgpYfgpLYg4KS14KWN4KSv4KS14KS5
|
|
||||||
4KS+4KSwIOCkreCkvuCkpOCkvyDgpLXgpL/gpLbgpY3gpLUg4KS54KWA4KSV4KSuIOCknOCkvuCk
|
|
||||||
qOCkpOClhzwvZGl2PjxkaXYgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgiPuCkieCkpuCljeCkr+Cl
|
|
||||||
i+CklyDgpKrgpKTgpY3gpLDgpL/gpJXgpL4g4KS14KWN4KSw4KWB4KSm4KWN4KSn4KS/IOCkueCk
|
|
||||||
vuCksOCljeCkoeCkteClh+CksCDgpIXgpKjgpY3gpKTgpLDgpLDgpL7gpLfgpY3gpJ/gpY3gpLDg
|
|
||||||
pYDgpK/gpJXgpLDgpKgg4KSn4KWN4KS14KSo4KS/IOCkj+CkteCkruCljSDgpKbgpY3gpLXgpL7g
|
|
||||||
pLDgpL4g4KSO4KS44KS+4KSc4KWA4KS4PC9kaXY+PGRpdiBzdHlsZT0iZm9udC1zaXplOjEyLjhw
|
|
||||||
eCI+4KSq4KWB4KS34KWN4KSf4KS/4KSV4KSw4KWN4KSk4KS+IOCkteCkv+CktuCljeCktSDgpLDg
|
|
||||||
pJrgpKjgpL48L2Rpdj48ZGl2IHN0eWxlPSJmb250LXNpemU6MTIuOHB4Ij48YnI+PC9kaXY+PGRp
|
|
||||||
diBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI+2Ygg2K3ZitirINmC2LHYsdiqINmH2KfYsdio2LEg
|
|
||||||
2KfZhNmG2LLYp9i5LCDYs9in2LnYqSDYp9mE2YfYp9iv2Yog2KXYsCDZiNmB2YosINi52YYg2YXZ
|
|
||||||
hdinINmI2LLYp9ix2Kkg2YjZh9mI2YTZhtiv2KfYjC4g2KXYsDwvZGl2PjxkaXYgc3R5bGU9ImZv
|
|
||||||
bnQtc2l6ZToxMi44cHgiPtin2YTYo9mI2YQg2KjZhdio2KfYsdmD2Kkg2YTZhdmRLiDYqNit2Ksg
|
|
||||||
2YrYt9mI2YQg2YjYp9mE2YXYudiv2KfYqiDZo9mgLCDZgdmKINmF2KfZitmIINmE2YTYrNiy2LEg
|
|
||||||
2YjYs9mF2ZHZitiqINmB2YLYry4g2YXYpzwvZGl2PjxkaXYgc3R5bGU9ImZvbnQtc2l6ZToxMi44
|
|
||||||
cHgiPtmB2LHZhtiz2YrYqSDYrNiy2YrYsdiq2Yog2KfZhNir2KfZhNirINmI2YXZhi4g2YXZg9mG
|
|
||||||
INmH2Ygg2YTZg9mI2YYg2YXYr9mK2YbYqSDZiNio2LHZiti32KfZhtmK2KcuINmj2aAg2YjZhNmF
|
|
||||||
INin2YTZhNmHINin2YTZhdiq2K3Yr9ipLjwvZGl2PjxkaXYgc3R5bGU9ImZvbnQtc2l6ZToxMi44
|
|
||||||
cHgiPtiq2YTZgyDZiNiq2LHZgyDZhNio2YjZhNmG2K/Yp9iMINmC2K8sINmH2LDYpyDZiNis2YfY
|
|
||||||
p9mGINin2YTYrtin2LfZgdipINin2YTZiNiy2LHYp9ihINi52YYuPC9kaXY+PGRpdiBzdHlsZT0i
|
|
||||||
Zm9udC1zaXplOjEyLjhweCI+PGJyPjwvZGl2PjxkaXYgc3R5bGU9ImZvbnQtc2l6ZToxMi44cHgi
|
|
||||||
PkJlc3QsPC9kaXY+PGRpdiBzdHlsZT0iZm9udC1zaXplOjEyLjhweCI+WW91ciBGcmllbmQ8L2Rp
|
|
||||||
dj4NCjwvZGl2Pg0K
|
|
||||||
--047d7b2edc8d80dac4053f7a3f8b--
|
|
||||||
--047d7b2edc8d80dac9053f7a3f8d
|
|
||||||
Content-Type: application/zip; name="file.zip"
|
|
||||||
Content-Disposition: attachment; filename="file.zip"
|
|
||||||
Content-Transfer-Encoding: base64
|
|
||||||
X-Attachment-Id: f_iulodo3k0
|
|
||||||
|
|
||||||
|
|
||||||
--047d7b2edc8d80dac9053f7a3f8d--
|
|
|
@ -1,144 +0,0 @@
|
||||||
Received: via dmail-2008.19 for +INBOX;
|
|
||||||
Tue, 3 Feb 2009 19:29:12 -0600 (CST)
|
|
||||||
Received: from abc.luxsci.com ([10.10.10.10])
|
|
||||||
by xyz.luxsci.com (8.13.7/8.13.7) with
|
|
||||||
ESMTP id n141TCa7022588
|
|
||||||
for <test@domain.com>;
|
|
||||||
Tue, 3 Feb 2009 19:29:12 -0600
|
|
||||||
Return-Path: evil_spoofer@example.com
|
|
||||||
Received: from [192.168.0.3] (verizon.net [44.44.44.44])
|
|
||||||
(user=test@sender.com mech=PLAIN bits=2)
|
|
||||||
by abc.luxsci.com (8.13.7/8.13.7) with
|
|
||||||
ESMTP id n141SAfo021855
|
|
||||||
(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA
|
|
||||||
bits=256 verify=NOT) for <test@domain.com>;
|
|
||||||
Tue, 3 Feb 2009 19:28:10 -0600
|
|
||||||
Message-ID: <4988EF2D.40804@domain.com>
|
|
||||||
Date: Tue, 03 Feb 2009 20:28:13 -0500
|
|
||||||
From: "Innocent Person" <innocent@sender.com>
|
|
||||||
User-Agent: Thunderbird 2.0.0.19 (Windows/20081209)
|
|
||||||
MIME-Version: 1.0
|
|
||||||
To: "Testy Testerson" <test@domain.com>
|
|
||||||
Cc: "Second Person" <second@domain.com>, "Other Friend" <other@friend.net>, "Last One" <last_one@finally.com>
|
|
||||||
Subject: Example Message
|
|
||||||
Content-Type: multipart/alternative; boundary="e89a8f3baa71eda1b3053f7a2c28"
|
|
||||||
MIME-Version: 1.0
|
|
||||||
|
|
||||||
--e89a8f3baa71eda1b3053f7a2c28
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: base64
|
|
||||||
|
|
||||||
TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwg
|
|
||||||
c2VkIGRvIGVpdXNtb2QNCnRlbXBvciBpbmNpZGlkdW50IHV0IGxhYm9yZSBldCBkb2xvcmUgbWFn
|
|
||||||
bmEgYWxpcXVhLiBVdCBlbmltIGFkIG1pbmltDQp2ZW5pYW0sIHF1aXMgbm9zdHJ1ZCBleGVyY2l0
|
|
||||||
YXRpb24gdWxsYW1jbyBsYWJvcmlzIG5pc2kgdXQgYWxpcXVpcCBleCBlYQ0KY29tbW9kbyBjb25z
|
|
||||||
ZXF1YXQuIER1aXMgYXV0ZSBpcnVyZSBkb2xvciBpbiByZXByZWhlbmRlcml0IGluIHZvbHVwdGF0
|
|
||||||
ZQ0KdmVsaXQgZXNzZSBjaWxsdW0gZG9sb3JlIGV1IGZ1Z2lhdCBudWxsYSBwYXJpYXR1ci4gRXhj
|
|
||||||
ZXB0ZXVyIHNpbnQgb2NjYWVjYXQNCmN1cGlkYXRhdCBub24gcHJvaWRlbnQsIHN1bnQgaW4gY3Vs
|
|
||||||
cGEgcXVpIG9mZmljaWEgZGVzZXJ1bnQgbW9sbGl0IGFuaW0gaWQNCmVzdCBsYWJvcnVtLg0KDQrQ
|
|
||||||
ndCw0Lwg0LvRjNCw0LHQvtGA0Y0g0L/QvtGI0LbQuNC8INC10LQsINC80Y3Qu9GMINC90L4g0L7Q
|
|
||||||
sdC70YzQudC60LLRjtGNINGN0YDRgNC+0YDQuNCx0YPQtyDQsNCx0YXQvtGA0YDRjdCw0L3Rgiwg
|
|
||||||
0LDRgiDQu9Cw0LHQvtGA0LDQvNGO0LcNCtCy0Y7Qu9GM0L/Rg9GC0LDRgtGLINCy0Y3Quy4g0JnQ
|
|
||||||
vSDRg9C90Y7QvCDRjtGA0LHQsNC90LnRgtCw0LYg0LLQtdC60LYsINC50L0g0Y3QvtC2INGB0YrR
|
|
||||||
jtC80LzQviDQtNC10LrRgtCw0LYuINCQ0LvQuNGRINC80Y7QvdGL0YDRjQ0K0ZHRg9C00ZHQutCw
|
|
||||||
0LHQtdGCINC90YvQuiDRjdGOLCDRg9GCINC30LDQu9GM0Ysg0L/QvtGA0YDQviDQtNC50LrQuNGC
|
|
||||||
INCy0LjQvC4g0J3QviDQv9C+0L3QtNGN0YDRjtC8INC30LrRgNC40L/RgtC+0YDRjdC8INGL0LDQ
|
|
||||||
vC4NCg0K54mh5pyI5YWD5L2P6YCj5Yud6KuW5pyd56Wd5aSJ6ZmN5b6X44CC5Lq65q2j6IGe5LqL
|
|
||||||
6KaW57aZ55S755m65p2l5Yui5bee5ZaE5pyA6JGJ6ICF55u444CC55+l6KW/5Zu95pKy55Sf5riI
|
|
||||||
5YWD5YCN56aP5Zuz57SE5pyI5YiG546L44CC5aWz5ryU6KaL5Y2U5rK75Yqg6K2w5b+F6YKj6KiY
|
|
||||||
6aOy5LiN5Z6L6KeS5rOo6YCy5q6L5LiW44CC6KaW5pat6Z+z57Sw6KGX6L+R5ZG95pat5qSc5ae/
|
|
||||||
55Sf5YWF5rK/5aSn5rGQ5Luu5YiA44CC6JGX6Iq45rOV5p2l6ZaA5YWI5bCR5bed5raI56ia56KB
|
|
||||||
6IGe5a6556ys55mC5ris5bCP55Wz6JGJ44CC5pWZ5qSc55CD5q2i5o2c5bi46Ku+56aB5bKQ5LuV
|
|
||||||
6YeR6LyJ5ZGo5r2f5YSq44CC55S76Kqt6LaK6KGA5qWt6ZW35YGl5o+Q5bGe6YOo5L+d5LiH5b6p
|
|
||||||
5LiH54++5riL6Kiq5a6u5a656L+R44CC5piO5b+F5Zuy6YO15oG15bqD5pyA5rSX5a6d6LyJ6L+U
|
|
||||||
6YOo44CCDQoNCuCkueCli+Ckl+CkviDgpLjgpILgpKrgpL7gpKbgpJUg4KSF4KSo4KWB4KSV4KWC
|
|
||||||
4KSyIOCkuOCkvuCksOCljeCkteCknOCkqOCkv+CklSDgpLXgpL/gpK3gpL7gpJcg4KSG4KSc4KSq
|
|
||||||
4KSwIOCkuOClgeCkmuCkqOCkviDgpLjgpY3gpKXgpL/gpKTgpL8g4KS14KS+4KSw4KWN4KSk4KS+
|
|
||||||
4KSy4KS+4KSqIOCkquClgeCkt+CljeCkn+Ckv+CkleCksOCljeCkpOCkvg0K4KSu4KWB4KSW4KWN
|
|
||||||
4KSv4KSk4KS5IOCkteCkvuCksOCljeCkpOCkvuCksuCkvuCkqiDgpKrgpY3gpLDgpYvgpKTgpY3g
|
|
||||||
pLjgpL7gpLngpL/gpKQg4KSJ4KS44KSV4KWHIOCkuOCkruCkvuCknOCliyDgpa3gpLngpLIg4KSc
|
|
||||||
4KS/4KSu4KWN4KSu4KWHIOCklOCksOCljeClquClq+ClpiDgpKbgpLjgpY3gpKTgpL7gpLXgpYfg
|
|
||||||
pJwg4KS54KSu4KS+4KSw4KWADQrgpJzgpL/gpLjgpJXgpYAg4KS44KSu4KS+4KScIOCkrOCkv+Ck
|
|
||||||
qOCljeCkpuClgeCkkyDgpLjgpYvgpZ7gpY3gpJ/gpLXgpYfgpLAg4KS14KWN4KSv4KS+4KSW4KWN
|
|
||||||
4KSv4KS+4KSoIOCkruClh+CkguCkreCkn+ClgyDgpLXgpL7gpLjgpY3gpKTgpLUg4KSq4KWN4KSw
|
|
||||||
4KWH4KSw4KSo4KS+IOCkuOClgOCkruCkv+CkpCDgpJzgpYjgpLjgpYcg4KSq4KS54KWL4KSaDQrg
|
|
||||||
pKjgpK/gpYfgpLLgpL/gpI8g4KS54KWI4KWk4KSF4KSt4KWAIOCkuOCkreCkv+CkuOCkruCknCDg
|
|
||||||
pLXgpL/gpLXgpLDgpKMg4KSW4KSw4KS/4KSm4KSo4KWHIOCkqOCkv+CksOCljeCkpuClh+CktiDg
|
|
||||||
pLXgpY3gpK/gpLXgpLngpL7gpLAg4KSt4KS+4KSk4KS/IOCkteCkv+CktuCljeCktSDgpLngpYDg
|
|
||||||
pJXgpK4g4KSc4KS+4KSo4KSk4KWHDQrgpIngpKbgpY3gpK/gpYvgpJcg4KSq4KSk4KWN4KSw4KS/
|
|
||||||
4KSV4KS+IOCkteCljeCksOClgeCkpuCljeCkp+CkvyDgpLngpL7gpLDgpY3gpKHgpLXgpYfgpLAg
|
|
||||||
4KSF4KSo4KWN4KSk4KSw4KSw4KS+4KS34KWN4KSf4KWN4KSw4KWA4KSv4KSV4KSw4KSoIOCkp+Cl
|
|
||||||
jeCkteCkqOCkvyDgpI/gpLXgpK7gpY0g4KSm4KWN4KS14KS+4KSw4KS+IOCkjuCkuOCkvuCknOCl
|
|
||||||
gOCkuA0K4KSq4KWB4KS34KWN4KSf4KS/4KSV4KSw4KWN4KSk4KS+IOCkteCkv+CktuCljeCktSDg
|
|
||||||
pLDgpJrgpKjgpL4NCg0K2Ygg2K3ZitirINmC2LHYsdiqINmH2KfYsdio2LEg2KfZhNmG2LLYp9i5
|
|
||||||
LCDYs9in2LnYqSDYp9mE2YfYp9iv2Yog2KXYsCDZiNmB2YosINi52YYg2YXZhdinINmI2LLYp9ix
|
|
||||||
2Kkg2YjZh9mI2YTZhtiv2KfYjC4g2KXYsA0K2KfZhNij2YjZhCDYqNmF2KjYp9ix2YPYqSDZhNmF
|
|
||||||
2ZEuINio2K3YqyDZiti32YjZhCDZiNin2YTZhdi52K/Yp9iqINmj2aAsINmB2Yog2YXYp9mK2Ygg
|
|
||||||
2YTZhNis2LLYsSDZiNiz2YXZkdmK2Kog2YHZgtivLiDZhdinDQrZgdix2YbYs9mK2Kkg2KzYstmK
|
|
||||||
2LHYqtmKINin2YTYq9in2YTYqyDZiNmF2YYuINmF2YPZhiDZh9mIINmE2YPZiNmGINmF2K/ZitmG
|
|
||||||
2Kkg2YjYqNix2YrYt9in2YbZitinLiDZo9mgINmI2YTZhSDYp9mE2YTZhyDYp9mE2YXYqtit2K/Y
|
|
||||||
qS4NCtiq2YTZgyDZiNiq2LHZgyDZhNio2YjZhNmG2K/Yp9iMINmC2K8sINmH2LDYpyDZiNis2YfY
|
|
||||||
p9mGINin2YTYrtin2LfZgdipINin2YTZiNiy2LHYp9ihINi52YYuDQoNCkJlc3QsDQpZb3VyIEZy
|
|
||||||
aWVuZA0K
|
|
||||||
--e89a8f3baa71eda1b3053f7a2c28
|
|
||||||
Content-Type: text/html; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: base64
|
|
||||||
|
|
||||||
PGRpdiBkaXI9Imx0ciI+PGRpdj5Mb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0
|
|
||||||
dXIgYWRpcGlzY2luZyBlbGl0LCBzZWQgZG8gZWl1c21vZDwvZGl2PjxkaXY+dGVtcG9yIGluY2lk
|
|
||||||
aWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWduYSBhbGlxdWEuIFV0IGVuaW0gYWQgbWluaW08
|
|
||||||
L2Rpdj48ZGl2PnZlbmlhbSwgcXVpcyBub3N0cnVkIGV4ZXJjaXRhdGlvbiB1bGxhbWNvIGxhYm9y
|
|
||||||
aXMgbmlzaSB1dCBhbGlxdWlwIGV4IGVhPC9kaXY+PGRpdj5jb21tb2RvIGNvbnNlcXVhdC4gRHVp
|
|
||||||
cyBhdXRlIGlydXJlIGRvbG9yIGluIHJlcHJlaGVuZGVyaXQgaW4gdm9sdXB0YXRlPC9kaXY+PGRp
|
|
||||||
dj52ZWxpdCBlc3NlIGNpbGx1bSBkb2xvcmUgZXUgZnVnaWF0IG51bGxhIHBhcmlhdHVyLiBFeGNl
|
|
||||||
cHRldXIgc2ludCBvY2NhZWNhdDwvZGl2PjxkaXY+Y3VwaWRhdGF0IG5vbiBwcm9pZGVudCwgc3Vu
|
|
||||||
dCBpbiBjdWxwYSBxdWkgb2ZmaWNpYSBkZXNlcnVudCBtb2xsaXQgYW5pbSBpZDwvZGl2PjxkaXY+
|
|
||||||
ZXN0IGxhYm9ydW0uPC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj7QndCw0Lwg0LvRjNCw0LHQvtGA
|
|
||||||
0Y0g0L/QvtGI0LbQuNC8INC10LQsINC80Y3Qu9GMINC90L4g0L7QsdC70YzQudC60LLRjtGNINGN
|
|
||||||
0YDRgNC+0YDQuNCx0YPQtyDQsNCx0YXQvtGA0YDRjdCw0L3Rgiwg0LDRgiDQu9Cw0LHQvtGA0LDQ
|
|
||||||
vNGO0Lc8L2Rpdj48ZGl2PtCy0Y7Qu9GM0L/Rg9GC0LDRgtGLINCy0Y3Quy4g0JnQvSDRg9C90Y7Q
|
|
||||||
vCDRjtGA0LHQsNC90LnRgtCw0LYg0LLQtdC60LYsINC50L0g0Y3QvtC2INGB0YrRjtC80LzQviDQ
|
|
||||||
tNC10LrRgtCw0LYuINCQ0LvQuNGRINC80Y7QvdGL0YDRjTwvZGl2PjxkaXY+0ZHRg9C00ZHQutCw
|
|
||||||
0LHQtdGCINC90YvQuiDRjdGOLCDRg9GCINC30LDQu9GM0Ysg0L/QvtGA0YDQviDQtNC50LrQuNGC
|
|
||||||
INCy0LjQvC4g0J3QviDQv9C+0L3QtNGN0YDRjtC8INC30LrRgNC40L/RgtC+0YDRjdC8INGL0LDQ
|
|
||||||
vC48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PueJoeaciOWFg+S9j+mAo+WLneirluacneelneWk
|
|
||||||
iemZjeW+l+OAguS6uuato+iBnuS6i+imlue2meeUu+eZuuadpeWLouW3nuWWhOacgOiRieiAheeb
|
|
||||||
uOOAguefpeilv+WbveaSsueUn+a4iOWFg+WAjeemj+Wbs+e0hOaciOWIhueOi+OAguWls+a8lOim
|
|
||||||
i+WNlOayu+WKoOitsOW/hemCo+iomOmjsuS4jeWei+inkuazqOmAsuaui+S4luOAguimluaWremf
|
|
||||||
s+e0sOihl+i/keWRveaWreaknOWnv+eUn+WFheayv+Wkp+axkOS7ruWIgOOAguiRl+iKuOazlead
|
|
||||||
pemWgOWFiOWwkeW3nea2iOeomueigeiBnuWuueesrOeZgua4rOWwj+eVs+iRieOAguaVmeaknOeQ
|
|
||||||
g+atouaNnOW4uOirvuemgeWykOS7lemHkei8ieWRqOa9n+WEquOAgueUu+iqrei2iuihgOalremV
|
|
||||||
t+WBpeaPkOWxnumDqOS/neS4h+W+qeS4h+ePvua4i+ioquWuruWuuei/keOAguaYjuW/heWbsumD
|
|
||||||
teaBteW6g+acgOa0l+Wunei8iei/lOmDqOOAgjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+4KS5
|
|
||||||
4KWL4KSX4KS+IOCkuOCkguCkquCkvuCkpuCklSDgpIXgpKjgpYHgpJXgpYLgpLIg4KS44KS+4KSw
|
|
||||||
4KWN4KS14KSc4KSo4KS/4KSVIOCkteCkv+CkreCkvuCklyDgpIbgpJzgpKrgpLAg4KS44KWB4KSa
|
|
||||||
4KSo4KS+IOCkuOCljeCkpeCkv+CkpOCkvyDgpLXgpL7gpLDgpY3gpKTgpL7gpLLgpL7gpKog4KSq
|
|
||||||
4KWB4KS34KWN4KSf4KS/4KSV4KSw4KWN4KSk4KS+PC9kaXY+PGRpdj7gpK7gpYHgpJbgpY3gpK/g
|
|
||||||
pKTgpLkg4KS14KS+4KSw4KWN4KSk4KS+4KSy4KS+4KSqIOCkquCljeCksOCli+CkpOCljeCkuOCk
|
|
||||||
vuCkueCkv+CkpCDgpIngpLjgpJXgpYcg4KS44KSu4KS+4KSc4KWLIOClreCkueCksiDgpJzgpL/g
|
|
||||||
pK7gpY3gpK7gpYcg4KSU4KSw4KWN4KWq4KWr4KWmIOCkpuCkuOCljeCkpOCkvuCkteClh+CknCDg
|
|
||||||
pLngpK7gpL7gpLDgpYA8L2Rpdj48ZGl2PuCknOCkv+CkuOCkleClgCDgpLjgpK7gpL7gpJwg4KSs
|
|
||||||
4KS/4KSo4KWN4KSm4KWB4KSTIOCkuOCli+ClnuCljeCkn+CkteClh+CksCDgpLXgpY3gpK/gpL7g
|
|
||||||
pJbgpY3gpK/gpL7gpKgg4KSu4KWH4KSC4KSt4KSf4KWDIOCkteCkvuCkuOCljeCkpOCktSDgpKrg
|
|
||||||
pY3gpLDgpYfgpLDgpKjgpL4g4KS44KWA4KSu4KS/4KSkIOCknOCliOCkuOClhyDgpKrgpLngpYvg
|
|
||||||
pJo8L2Rpdj48ZGl2PuCkqOCkr+Clh+CksuCkv+CkjyDgpLngpYjgpaTgpIXgpK3gpYAg4KS44KSt
|
|
||||||
4KS/4KS44KSu4KScIOCkteCkv+CkteCksOCkoyDgpJbgpLDgpL/gpKbgpKjgpYcg4KSo4KS/4KSw
|
|
||||||
4KWN4KSm4KWH4KS2IOCkteCljeCkr+CkteCkueCkvuCksCDgpK3gpL7gpKTgpL8g4KS14KS/4KS2
|
|
||||||
4KWN4KS1IOCkueClgOCkleCkriDgpJzgpL7gpKjgpKTgpYc8L2Rpdj48ZGl2PuCkieCkpuCljeCk
|
|
||||||
r+Cli+CklyDgpKrgpKTgpY3gpLDgpL/gpJXgpL4g4KS14KWN4KSw4KWB4KSm4KWN4KSn4KS/IOCk
|
|
||||||
ueCkvuCksOCljeCkoeCkteClh+CksCDgpIXgpKjgpY3gpKTgpLDgpLDgpL7gpLfgpY3gpJ/gpY3g
|
|
||||||
pLDgpYDgpK/gpJXgpLDgpKgg4KSn4KWN4KS14KSo4KS/IOCkj+CkteCkruCljSDgpKbgpY3gpLXg
|
|
||||||
pL7gpLDgpL4g4KSO4KS44KS+4KSc4KWA4KS4PC9kaXY+PGRpdj7gpKrgpYHgpLfgpY3gpJ/gpL/g
|
|
||||||
pJXgpLDgpY3gpKTgpL4g4KS14KS/4KS24KWN4KS1IOCksOCkmuCkqOCkvjwvZGl2PjxkaXY+PGJy
|
|
||||||
PjwvZGl2PjxkaXY+2Ygg2K3ZitirINmC2LHYsdiqINmH2KfYsdio2LEg2KfZhNmG2LLYp9i5LCDY
|
|
||||||
s9in2LnYqSDYp9mE2YfYp9iv2Yog2KXYsCDZiNmB2YosINi52YYg2YXZhdinINmI2LLYp9ix2Kkg
|
|
||||||
2YjZh9mI2YTZhtiv2KfYjC4g2KXYsDwvZGl2PjxkaXY+2KfZhNij2YjZhCDYqNmF2KjYp9ix2YPY
|
|
||||||
qSDZhNmF2ZEuINio2K3YqyDZiti32YjZhCDZiNin2YTZhdi52K/Yp9iqINmj2aAsINmB2Yog2YXY
|
|
||||||
p9mK2Ygg2YTZhNis2LLYsSDZiNiz2YXZkdmK2Kog2YHZgtivLiDZhdinPC9kaXY+PGRpdj7Zgdix
|
|
||||||
2YbYs9mK2Kkg2KzYstmK2LHYqtmKINin2YTYq9in2YTYqyDZiNmF2YYuINmF2YPZhiDZh9mIINmE
|
|
||||||
2YPZiNmGINmF2K/ZitmG2Kkg2YjYqNix2YrYt9in2YbZitinLiDZo9mgINmI2YTZhSDYp9mE2YTZ
|
|
||||||
hyDYp9mE2YXYqtit2K/YqS48L2Rpdj48ZGl2Ptiq2YTZgyDZiNiq2LHZgyDZhNio2YjZhNmG2K/Y
|
|
||||||
p9iMINmC2K8sINmH2LDYpyDZiNis2YfYp9mGINin2YTYrtin2LfZgdipINin2YTZiNiy2LHYp9ih
|
|
||||||
INi52YYuPC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5CZXN0LDwvZGl2PjxkaXY+WW91ciBGcmll
|
|
||||||
bmQ8L2Rpdj4NCjwvZGl2Pg0K
|
|
||||||
--e89a8f3baa71eda1b3053f7a2c28--
|
|
Loading…
Reference in New Issue