Skip to content

Commit

Permalink
Adding colorama
Browse files Browse the repository at this point in the history
  • Loading branch information
mikechabot committed Aug 2, 2018
1 parent 9bcf712 commit a8a2088
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 155 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# email-spoofer-py
Simple Python script to spoof emails
# smtp-spoofer
Simple Python script to spoof emails
61 changes: 0 additions & 61 deletions raw.py

This file was deleted.

2 changes: 0 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
colorama==0.3.9
freeze==1.0.10
six==1.11.0
62 changes: 62 additions & 0 deletions scripts/get_raw.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from scripts import util as u

PORT_OUT_OF_RANGE = 'SMTP port is out-of-range (0-65535)'
PORT_NAN = 'SMTP port must be a number'


def get_port():
while True:
try:
port = int(u.get_required_prompt('SMTP port: '))
if port < 0:
print(PORT_OUT_OF_RANGE)
elif port > 65535:
print(PORT_OUT_OF_RANGE)
else:
return str(port)
except ValueError:
print(PORT_NAN)


def get_from_address():
return u.get_required_prompt('Sender address (e.g. [email protected]): ')


def get_from_name():
return u.get_required_prompt('Sender name (e.g. John Smith): ')


def get_subject():
return u.get_required_prompt('Subject line: ')


def get_to_addresses():
to_address = u.get_required_prompt('Recipient address (e.g. [email protected]): ')
to_addresses = [to_address]
if is_multi_address():
while to_address:
to_address = u.get_optional_prompt('Recipient address (blank to continue): ', None)
if to_address:
to_addresses.append(to_address)
return to_addresses


def is_multi_address():
is_multi = u.get_optional_prompt('Enter additional recipients (Y/N)?: ', 'N')
return u.convert_answer_to_int(is_multi)


def load_body_from_file():
load_from_file = u.get_optional_prompt('Load message body from file (Y/N)?: ', 'n')
return u.convert_answer_to_int(load_from_file)


def get_body_filename():
return u.get_required_prompt('Filename: ')


def do_send_mail():
send_mail = u.get_required_prompt('Send message (Y/N)?: ')
return u.convert_answer_to_int(send_mail)


19 changes: 19 additions & 0 deletions scripts/pretty_print.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from colorama import init, Fore, Style

init()

def header(line):
print(Fore.LIGHTBLACK_EX + line + Style.RESET_ALL)


def info(line):
print(Fore.LIGHTCYAN_EX + line + Style.RESET_ALL)


def success(line):
print(Fore.LIGHTGREEN_EX + line + Style.RESET_ALL)


def error(line):
print(Fore.LIGHTRED_EX + line + Style.RESET_ALL)

48 changes: 21 additions & 27 deletions smtp.py → scripts/smtp.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import smtplib
import util as u
from scripts import util as u, pretty_print as l
from socket import gaierror

AUTH = 'auth'
Expand All @@ -11,45 +11,44 @@
NO_SMTP_FEATURES = u.generate_fatal('No SMTP features detected.')
NO_AUTH_FEATURES = u.generate_fatal('No AUTH types detected.')
NO_PLAIN_OR_LOGIN_FEATURE = u.generate_fatal('SMTP server does not support AUTH PLAIN or AUTH LOGIN.')
UNABLE_TO_CONNECT = u.generate_fatal('Unable to connect to SMTP server. Check hostname and port.')
UNABLE_TO_CONNECT = u.generate_fatal('Unable to establish connection to SMTP socket.')

INVALID_CREDENTIALS = 'Error: The server did not accept the username/password combination'
AUTH_NOT_SUPPORTED = 'Error: The AUTH command is not supported by the server'
GENERIC_AUTHENTICATION_EXCEPTION = 'Error: Encountered an error during authentication'
INVALID_CREDENTIALS = u.generate_error('The server did not accept the username/password combination')
AUTH_NOT_SUPPORTED = u.generate_error('The AUTH command is not supported by the server')
GENERIC_AUTHENTICATION_EXCEPTION = u.generate_error('Encountered an error during authentication')


def connect(host, port, debug):
def connect(host, port):
socket = host + ':' + port
print('\nAttempting connection to socket (' + socket + ')...')
l.info(' > Attempting connection to SMTP socket (' + socket + ')...')
try:
server = smtplib.SMTP(host, port)
server.set_debuglevel(debug)
print('--> Successfully connected to SMTP server!\n')
l.success(' > Successfully connected to SMTP server!')
return server
except (gaierror, OSError):
print(UNABLE_TO_CONNECT)
l.error(UNABLE_TO_CONNECT)
exit(1)


def start_tls(server):
server.ehlo()
if not server.has_extn(STARTTLS):
print(TLS_NOT_SUPPORTED)
l.error(TLS_NOT_SUPPORTED)
exit(1)
else:
server.starttls()


def verify_auth_feature(features):
if not features:
print(NO_SMTP_FEATURES)
l.error(NO_SMTP_FEATURES)
exit(1)
elif not features[AUTH]:
print(NO_AUTH_FEATURES)
l.error(NO_AUTH_FEATURES)
exit(1)


def get_supported_server_auth_types(features):
def verify_auth_types(features):
server_auth_types = features[AUTH].strip().split()

auth_types = []
Expand All @@ -58,33 +57,28 @@ def get_supported_server_auth_types(features):
auth_types.append(auth_type)

if not auth_types:
print(NO_PLAIN_OR_LOGIN_FEATURE)
l.error(NO_PLAIN_OR_LOGIN_FEATURE)
exit(1)
else:
return auth_types


def evaluate_server(server):
server.ehlo()
verify_auth_feature(server.esmtp_features)

print('Listing supported AUTH types...')
for auth_type in get_supported_server_auth_types(server.esmtp_features):
print("--> " + auth_type)
verify_auth_types(server.esmtp_features)


def login(server):
login_attempt = None
while not login_attempt:
try:
username = u.get_required_prompt('\nEnter username: ')
password = u.get_required_prompt('Enter password: ')
username = u.get_required_prompt('Username: ')
password = u.get_required_prompt('Password: ')
login_attempt = server.login(username, password)
except smtplib.SMTPAuthenticationError:
print(INVALID_CREDENTIALS)
l.error(INVALID_CREDENTIALS)
except smtplib.SMTPNotSupportedError:
print(AUTH_NOT_SUPPORTED)
l.error(AUTH_NOT_SUPPORTED)
except smtplib.SMTPException:
print(GENERIC_AUTHENTICATION_EXCEPTION)
l.error(GENERIC_AUTHENTICATION_EXCEPTION)

print('--> ' + login_attempt[1].decode())
l.success(' > ' + login_attempt[1].decode())
17 changes: 13 additions & 4 deletions util.py → scripts/util.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from colorama import init
init()
from colorama import Fore, Style

AFFIRMATIVE_RESPONSES = {'y', 'ye', 'yes'}
ERROR = 'Error: '
Expand All @@ -13,25 +12,35 @@ def prompt(text):


def get_required_prompt(text):
print(Fore.WHITE, end='')
var = None
while not var:
var = prompt(text)
print(Style.RESET_ALL, end='')
return var


def get_optional_prompt(text, default_value):
print(Fore.WHITE, end='')
var = prompt(text)
print(Style.RESET_ALL, end='')
if var:
return var
else:
return default_value


def convert_answer_to_int(answer):
if answer in AFFIRMATIVE_RESPONSES:
if answer.lower() in AFFIRMATIVE_RESPONSES:
return 1
return 0


def generate_error(message):
return ' > ' + ERROR + message


def generate_fatal(message):
return ERROR + message + EXITING
return generate_error(message) + EXITING


71 changes: 71 additions & 0 deletions spoof.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import smtplib
from scripts import get_raw as r, smtp as s, util as u, pretty_print as p

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

p.header('==================================================')
p.header(' email-spoofer-py v0.0.2 ')
p.header(' Python 3.x based email spoofer ')
p.header(' https://github.com/mikechabot/email-spoofer-py ')
p.header('==================================================')

smtp_host = u.get_required_prompt('\nSMTP host: ')
smtp_port = r.get_port()

server = s.connect(smtp_host, smtp_port)

s.start_tls(server)
s.evaluate_server(server)
s.login(server)

from_address = r.get_from_address()
from_name = r.get_from_name()
to_addresses = r.get_to_addresses()
subject = r.get_subject()

msg = MIMEMultipart('alternative')
msg.set_charset("utf-8")

msg["From"] = from_name + "<" + from_address + ">"
msg['Subject'] = subject
msg["To"] = u.COMMASPACE.join(to_addresses)

load_body_from_file = r.load_body_from_file()

if load_body_from_file:
filename = r.get_body_filename()
with open(filename) as file:
body = MIMEText(file.read(), 'html')
msg.attach(body)
else:
p.info(' > Enter HTML line by line')
p.info(' > To finish, press CTRL+D (*nix) or CTRL-Z (win) on an *empty* line')
html = u.EMPTY_STRING
while True:
try:
line = input(' | ')
html += line + '\n'
except EOFError:
p.success(' > HTML captured.')
break
body = MIMEText(html, 'html')
msg.attach(body)

p.info(' > Send from ' + from_address + ' as ' + from_name)
p.info(' > Send to ' + u.COMMASPACE.join(to_addresses))

if r.do_send_mail():
try:
p.info(' > Sending spoofed message...')
server.sendmail(from_address, to_addresses, msg.as_string())
p.success(' > Successfully sent message!')
except smtplib.SMTPException:
p.error(' > Error: Unable to send message. Check TO/FROM and Message body')
else:
p.info(' > Send message cancelled')





Loading

0 comments on commit a8a2088

Please sign in to comment.