Skip to content

Commit 47df88a

Browse files
committed
Make SMTP delivery work with a range of server SSL
1 parent fa016de commit 47df88a

File tree

1 file changed

+37
-12
lines changed

1 file changed

+37
-12
lines changed

lib/msf/core/exploit/smtp_deliver.rb

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,32 @@ def connect(global = true)
7171
# This method currently only knows about PLAIN authentication.
7272
#
7373
def connect_login(global = true)
74-
vprint_status("Connecting to SMTP server #{rhost}:#{rport}...")
75-
nsock = connect(global)
76-
77-
if datastore['DOMAIN'] and not datastore['DOMAIN'] == ''
74+
if datastore['DOMAIN'] && datastore['DOMAIN'] != ''
7875
domain = datastore['DOMAIN']
7976
else
8077
domain = Rex::Text.rand_text_alpha(rand(32)+1)
8178
end
8279

83-
res = raw_send_recv("EHLO #{domain}\r\n", nsock)
80+
nsock, res = connect_ehlo(global, domain)
81+
8482
if res =~ /STARTTLS/
8583
print_status("Starting tls")
8684
raw_send_recv("STARTTLS\r\n", nsock)
87-
swap_sock_plain_to_ssl(nsock)
85+
86+
[:high, :medium, :default].each do |level|
87+
begin
88+
swap_sock_plain_to_ssl(nsock, level)
89+
break
90+
rescue OpenSSL::SSL::SSLError
91+
# Perform manual fallback for servers that can't
92+
print_status 'Could not negotiate SSL, falling back to older ciphers'
93+
nsock.close
94+
nsock, res = connect_ehlo(global)
95+
raw_send_recv("STARTTLS\r\n", nsock)
96+
raise if level == :default
97+
end
98+
end
99+
88100
res = raw_send_recv("EHLO #{domain}\r\n", nsock)
89101
end
90102

@@ -122,6 +134,12 @@ def connect_login(global = true)
122134
return nsock
123135
end
124136

137+
def connect_ehlo(global = true, domain)
138+
vprint_status("Connecting to SMTP server #{rhost}:#{rport}...")
139+
nsock = connect(global)
140+
141+
[nsock, raw_send_recv("EHLO #{domain}\r\n", nsock)]
142+
end
125143

126144
#
127145
# Sends an email message, connecting to the server first if a connection is
@@ -216,8 +234,8 @@ def raw_send_recv(cmd, nsock=self.sock)
216234
# Create a new SSL session on the existing socket. Used for STARTTLS
217235
# support.
218236
#
219-
def swap_sock_plain_to_ssl(nsock=self.sock)
220-
ctx = generate_ssl_context()
237+
def swap_sock_plain_to_ssl(nsock=self.sock, security=:high)
238+
ctx = generate_ssl_context(security)
221239
ssl = OpenSSL::SSL::SSLSocket.new(nsock, ctx)
222240

223241
ssl.connect
@@ -227,10 +245,17 @@ def swap_sock_plain_to_ssl(nsock=self.sock)
227245
nsock.sslctx = ctx
228246
end
229247

230-
def generate_ssl_context
231-
ctx = OpenSSL::SSL::SSLContext.new(:SSLv23)
232-
ctx.ciphers = "ALL:!ADH:!EXPORT:!SSLv2:!SSLv3:+HIGH:+MEDIUM"
233-
ctx
248+
def generate_ssl_context(security=:high)
249+
case security
250+
when :high
251+
ctx = OpenSSL::SSL::SSLContext.new(:SSLv23)
252+
ctx.ciphers = "ALL:!ADH:!EXPORT:!SSLv2:!SSLv3:+HIGH:+MEDIUM"
253+
ctx
254+
when :medium
255+
OpenSSL::SSL::SSLContext.new(:TLSv1)
256+
when :default
257+
OpenSSL::SSL::SSLContext.new
258+
end
234259
end
235260

236261
end

0 commit comments

Comments
 (0)