Added smtp client and server modules
parent
a9448c51e7
commit
a744b90349
|
@ -0,0 +1,3 @@
|
||||||
|
# Compiled source #
|
||||||
|
###################
|
||||||
|
*.pyc
|
|
@ -1,3 +1,6 @@
|
||||||
|
[1.4.2014]
|
||||||
|
Added...: SMTP Client and Server modules have been added
|
||||||
|
|
||||||
[1.3.2015]
|
[1.3.2015]
|
||||||
Added...: SFTP Server module has been added to the framework!
|
Added...: SFTP Server module has been added to the framework!
|
||||||
Added...: SFTP Client module has been added to the framework.
|
Added...: SFTP Client module has been added to the framework.
|
||||||
|
|
|
@ -64,7 +64,7 @@ def cli_parser():
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
if ((args.server == "ftp" or "sftp") or (args.client == "ftp" or "ftp"))\
|
if ((args.server == "ftp" or args.server == "sftp") or (args.client == "ftp" or args.client == "sftp"))\
|
||||||
and (args.username is None or args.password is None):
|
and (args.username is None or args.password is None):
|
||||||
print "[*] Error: FTP or SFTP connections require \
|
print "[*] Error: FTP or SFTP connections require \
|
||||||
a username and password!".replace(' ', '')
|
a username and password!".replace(' ', '')
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
'''
|
||||||
|
|
||||||
|
This is the template that should be used for client modules.
|
||||||
|
A brief description of the client module can/should be placed
|
||||||
|
up here. All necessary imports should be placed between the
|
||||||
|
comments and class declaration.
|
||||||
|
|
||||||
|
Finally, be sure to rename your client module to a .py file
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
import paramiko
|
||||||
|
import os
|
||||||
|
from common import helpers
|
||||||
|
|
||||||
|
|
||||||
|
class Client:
|
||||||
|
|
||||||
|
def __init__(self, cli_object):
|
||||||
|
self.protocol = "sftp"
|
||||||
|
self.username = cli_object.username
|
||||||
|
self.password = cli_object.password
|
||||||
|
self.remote_system = cli_object.ip
|
||||||
|
|
||||||
|
def transmit(self, data_to_transmit):
|
||||||
|
|
||||||
|
print "[*][*] WARNING: Currently only works with root user account!"
|
||||||
|
print "[*][*] WARNING: This should be fixed when SFTP server module \
|
||||||
|
is released!".replace(' ', '')
|
||||||
|
|
||||||
|
print "[*] Transmitting data..."
|
||||||
|
|
||||||
|
sftp_file_name = helpers.writeout_text_data(data_to_transmit)
|
||||||
|
full_path = helpers.ea_path() + "/" + sftp_file_name
|
||||||
|
|
||||||
|
transport = paramiko.Transport(self.remote_system)
|
||||||
|
transport.connect(username=self.username, password=self.password)
|
||||||
|
sftp = paramiko.SFTPClient.from_transport(transport)
|
||||||
|
sftp.put(full_path, '/' + sftp_file_name)
|
||||||
|
|
||||||
|
# close sftp connection
|
||||||
|
sftp.close()
|
||||||
|
transport.close()
|
||||||
|
|
||||||
|
os.remove(sftp_file_name)
|
||||||
|
|
||||||
|
print "[*] Data sent!"
|
||||||
|
|
||||||
|
return
|
|
@ -0,0 +1,48 @@
|
||||||
|
'''
|
||||||
|
|
||||||
|
This is a SMTP client module. Sample code came from:
|
||||||
|
http://pymotw.com/2/smtpd/
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
import smtplib
|
||||||
|
import email.utils
|
||||||
|
from email.mime.text import MIMEText
|
||||||
|
|
||||||
|
|
||||||
|
class Client:
|
||||||
|
|
||||||
|
# Within __init__, you have access to everything passed in
|
||||||
|
# via the command line. self.protocol is the variable listed
|
||||||
|
# when running --list-clients and is what is used in conjunction
|
||||||
|
# with --client <client>. self.protocol is the only required attribute
|
||||||
|
# of the object.
|
||||||
|
def __init__(self, cli_object):
|
||||||
|
self.protocol = "smtp"
|
||||||
|
self.remote_server = cli_object.ip
|
||||||
|
|
||||||
|
# transmit is the only required function within the object. It is what
|
||||||
|
# called by the framework to transmit data. However, you can create as
|
||||||
|
# many "sub functions" for transmit to invoke as needed. "data_to_transmit"
|
||||||
|
# is a variable passed in by the framework which contains the data that
|
||||||
|
# is to be sent out by the client.
|
||||||
|
def transmit(self, data_to_transmit):
|
||||||
|
|
||||||
|
print "[*] Sending data over e-mail..."
|
||||||
|
|
||||||
|
# Create the message
|
||||||
|
msg = MIMEText('This is the data to exfil:\n\n' + data_to_transmit)
|
||||||
|
msg['To'] = email.utils.formataddr(('Server', 'server@egress-assess.com'))
|
||||||
|
msg['From'] = email.utils.formataddr(('Tester', 'tester@egress-assess.com'))
|
||||||
|
msg['Subject'] = 'Egress-Assess Exfil Data'
|
||||||
|
|
||||||
|
server = smtplib.SMTP(self.remote_server, 25)
|
||||||
|
server.set_debuglevel(False)
|
||||||
|
try:
|
||||||
|
server.sendmail('tester@egress-assess.com', ['server@egress-assess.com'], msg.as_string())
|
||||||
|
finally:
|
||||||
|
server.quit()
|
||||||
|
|
||||||
|
print "[*] Data transmitted!"
|
||||||
|
|
||||||
|
return
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Code from http://pymotw.com/2/smtpd/
|
||||||
|
|
||||||
|
import smtpd
|
||||||
|
import time
|
||||||
|
from common import helpers
|
||||||
|
|
||||||
|
|
||||||
|
class CustomSMTPServer(smtpd.SMTPServer):
|
||||||
|
|
||||||
|
def process_message(self, peer, mailfrom, rcpttos, data):
|
||||||
|
print 'Receiving message from:', peer
|
||||||
|
print 'Message addressed from:', mailfrom
|
||||||
|
print 'Message addressed to :', rcpttos
|
||||||
|
print 'Message length :', len(data)
|
||||||
|
|
||||||
|
loot_directory = helpers.ea_path() + '/data'
|
||||||
|
|
||||||
|
current_date = time.strftime("%m/%d/%Y")
|
||||||
|
current_time = time.strftime("%H:%M:%S")
|
||||||
|
file_name = current_date.replace("/", "") +\
|
||||||
|
"_" + current_time.replace(":", "") + "email_data.txt"
|
||||||
|
|
||||||
|
with open(loot_directory + "/" + file_name, 'w') as email_file:
|
||||||
|
email_file.write(data)
|
||||||
|
|
||||||
|
return
|
|
@ -0,0 +1,44 @@
|
||||||
|
'''
|
||||||
|
|
||||||
|
This is a SMTP server module. This was based on code made available at:
|
||||||
|
http://pymotw.com/2/smtpd/
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
import asyncore
|
||||||
|
import os
|
||||||
|
import socket
|
||||||
|
import sys
|
||||||
|
from common import helpers
|
||||||
|
from protocols.servers.serverlibs.smtp import smtp_class
|
||||||
|
|
||||||
|
|
||||||
|
class Server:
|
||||||
|
|
||||||
|
def __init__(self, cli_object):
|
||||||
|
|
||||||
|
self.protocol = "smtp"
|
||||||
|
|
||||||
|
def serve(self):
|
||||||
|
|
||||||
|
exfil_directory = os.path.join(helpers.ea_path(), "data/")
|
||||||
|
|
||||||
|
if not os.path.isdir(exfil_directory):
|
||||||
|
os.makedirs(exfil_directory)
|
||||||
|
|
||||||
|
print "[*] Started SMTP server..."
|
||||||
|
|
||||||
|
try:
|
||||||
|
smtp_server = smtp_class.CustomSMTPServer(('0.0.0.0', 25), None)
|
||||||
|
except socket.error:
|
||||||
|
print "[*] Error: Port 25 is currently in use!"
|
||||||
|
print "[*] Error: Please re-start when not in use."
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
try:
|
||||||
|
asyncore.loop()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print "[*] Shutting down SMTP server..."
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
return
|
Loading…
Reference in New Issue