|
|
|
@ -7,15 +7,30 @@ from subprocess import run, PIPE |
|
|
|
|
from aiosmtpd.controller import Controller |
|
|
|
|
from aiosmtpd.smtp import SMTP |
|
|
|
|
import subprocess |
|
|
|
|
import argparse |
|
|
|
|
|
|
|
|
|
key_path = Path('certs', 'key.pem') |
|
|
|
|
cert_path = Path('certs', 'cert.pem') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_context(): |
|
|
|
|
if not cert_path.exists() and not key_path.exists(): |
|
|
|
|
subprocess.call(f'openssl req -x509 -newkey rsa:4096 -keyout {key_path.as_posix()} -out {cert_path.as_posix()} -days 365 -nodes -subj "/CN=localhost"', shell=True) |
|
|
|
|
|
|
|
|
|
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) |
|
|
|
|
context.load_cert_chain(cert_path.as_posix(), key_path.as_posix()) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Pass SSL context to aiosmtpd |
|
|
|
|
class ControllerStarttls(Controller): |
|
|
|
|
class ControllerSSL(Controller): |
|
|
|
|
def factory(self): |
|
|
|
|
return SMTP(self.handler, require_starttls=False, tls_context=context) |
|
|
|
|
return SMTP(self.handler, ssl_context=get_context()) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Pass SSL context to aiosmtpd |
|
|
|
|
class ControllerSTARTTLS(Controller): |
|
|
|
|
def factory(self): |
|
|
|
|
return SMTP(self.handler, require_starttls=False, tls_context=get_context()) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CustomSMTPHandler: |
|
|
|
@ -30,27 +45,38 @@ class CustomSMTPHandler: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
|
|
configmodule = Path(__file__).as_posix().replace('.py', '_config') |
|
|
|
|
if Path(f'{configmodule}.py').exists(): |
|
|
|
|
config = importlib.import_module(configmodule) |
|
|
|
|
else: |
|
|
|
|
print("Couldn't locate config file {0}".format(f'{configmodule}.py')) |
|
|
|
|
sys.exit(-1) |
|
|
|
|
|
|
|
|
|
smtp_addr = config.smtp_addr |
|
|
|
|
smtp_port = config.smtp_port |
|
|
|
|
binpath = config.binpath |
|
|
|
|
parser = argparse.ArgumentParser(description='Launch a fake SMTP server to push SPAMs to a MISP instance') |
|
|
|
|
parser.add_argument("--path", default='./mail_to_misp.py', help="Path to the mail_to_misp.py script.") |
|
|
|
|
parser.add_argument("--host", default='127.0.0.1', help="IP to attach the SMTP server to.") |
|
|
|
|
parser.add_argument("--port", default='2525', help="Port of the SMTP server") |
|
|
|
|
parser.add_argument("--ssl", action='store_true', help="Pure SMTPs.") |
|
|
|
|
args = parser.parse_args() |
|
|
|
|
|
|
|
|
|
if not cert_path.exists() and not key_path.exists(): |
|
|
|
|
subprocess.call(f'openssl req -x509 -newkey rsa:4096 -keyout {key_path.as_posix()} -out {cert_path.as_posix()} -days 365 -nodes -subj "/CN=localhost"', shell=True) |
|
|
|
|
if not args.path and not args.host and not args.port and not args.ssl: |
|
|
|
|
configmodule = Path(__file__).as_posix().replace('.py', '_config') |
|
|
|
|
if Path(f'{configmodule}.py').exists(): |
|
|
|
|
config = importlib.import_module(configmodule) |
|
|
|
|
else: |
|
|
|
|
print("Couldn't locate config file {0}".format(f'{configmodule}.py')) |
|
|
|
|
sys.exit(-1) |
|
|
|
|
|
|
|
|
|
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) |
|
|
|
|
context.load_cert_chain(cert_path.as_posix(), key_path.as_posix()) |
|
|
|
|
binpath = config.binpath |
|
|
|
|
smtp_addr = config.smtp_addr |
|
|
|
|
smtp_port = config.smtp_port |
|
|
|
|
smtps = config.ssl |
|
|
|
|
else: |
|
|
|
|
binpath = args.path |
|
|
|
|
smtp_addr = args.host |
|
|
|
|
smtp_port = args.port |
|
|
|
|
smtps = args.ssl |
|
|
|
|
|
|
|
|
|
print("Starting Fake-SMTP-to-MISP server") |
|
|
|
|
|
|
|
|
|
handler = CustomSMTPHandler() |
|
|
|
|
server = ControllerStarttls(handler, hostname=smtp_addr, port=smtp_port) |
|
|
|
|
if smtps: |
|
|
|
|
server = ControllerSSL(handler, hostname=smtp_addr, port=smtp_port) |
|
|
|
|
else: |
|
|
|
|
server = ControllerSTARTTLS(handler, hostname=smtp_addr, port=smtp_port) |
|
|
|
|
server.start() |
|
|
|
|
input("Server started. Press Return to quit.") |
|
|
|
|
server.stop() |
|
|
|
|