Skip to content

Commit ff3a21b

Browse files
committed
Refactor do_web_login
1 parent 22f41e4 commit ff3a21b

File tree

1 file changed

+95
-91
lines changed

1 file changed

+95
-91
lines changed

modules/auxiliary/scanner/http/joomla_bruteforce_login.rb

Lines changed: 95 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -126,64 +126,84 @@ def do_web_login(user, pass)
126126

127127
referer_var = "http://#{rhost}/administrator/index.php"
128128

129-
uid, cval, hidden_value = get_login_cookie
129+
vprint_status("#{target_url} - Searching Joomla Login Response...")
130+
res = get_login_response
130131

131-
if uid
132-
index_cookie = 0
133-
value_cookie = ""
132+
unless res && res.code = 200 && res.headers['Set-Cookie']
133+
vprint_error("#{target_url} - Failed to find Joomla Login Response")
134+
return nil
135+
end
134136

135-
uid.each do |val_uid|
136-
value_cookie = value_cookie + "#{val_uid.strip}=#{cval[index_cookie].strip};"
137-
index_cookie = index_cookie + 1
138-
end
137+
vprint_status("#{target_url} - Searching Joomla Login Form...")
138+
hidden_value = get_login_hidden(res)
139+
if hidden_value.nil?
140+
vprint_error("#{target_url} - Failed to find Joomla Login Form")
141+
return
142+
end
139143

140-
value_cookie = value_cookie
141-
vprint_status("#{target_url} - Login with cookie ( #{value_cookie} ) and Hidden ( #{hidden_value}=1 )")
142-
response = send_request_cgi({
143-
'uri' => @uri,
144-
'method' => 'POST',
145-
'cookie' => "#{value_cookie}",
146-
'headers' =>
147-
{
148-
'Referer' => referer_var
149-
},
150-
'vars_post' => {
151-
user_var => user,
152-
pass_var => pass,
153-
'lang' => '',
154-
'option' => 'com_login',
155-
'task' => 'login',
156-
'return' => 'aW5kZXgucGhw',
157-
hidden_value => 1
158-
}
159-
})
144+
vprint_status("#{target_url} - Searching Joomla Login Cookies...")
145+
cookie = get_login_cookie(res)
146+
if cookie.blank?
147+
vprint_error("#{target_url} - Failed to find Joomla Login Cookies")
148+
return
149+
end
160150

161-
if response
162-
vprint_status("#{target_url} - Login Response #{response.code}")
151+
vprint_status("#{target_url} - Login with cookie ( #{cookie} ) and Hidden ( #{hidden_value}=1 )")
152+
res = send_request_login({
153+
'user_var' => user_var,
154+
'pass_var' => pass_var,
155+
'cookie' => cookie,
156+
'referer_var' => referer_var,
157+
'user' => user,
158+
'pass' => pass,
159+
'hidden_value' => hidden_value
160+
})
163161

164-
if response.redirect? && response.headers['Location']
165-
path = response.headers['Location']
166-
vprint_status("#{target_url} - Following redirect to #{path}...")
162+
if res
163+
vprint_status("#{target_url} - Login Response #{res.code}")
167164

168-
response = send_request_raw({
169-
'uri' => path,
170-
'method' => 'GET',
171-
'cookie' => "#{value_cookie}"
172-
})
173-
end
174-
end
165+
if res.redirect? && res.headers['Location']
166+
path = res.headers['Location']
167+
vprint_status("#{target_url} - Following redirect to #{path}...")
175168

176-
return response
177-
else
178-
print_error("#{target_url} - Failed to get Cookies")
179-
return nil
169+
res = send_request_raw({
170+
'uri' => path,
171+
'method' => 'GET',
172+
'cookie' => "#{cookie}"
173+
})
174+
end
180175
end
181-
rescue ::Rex::ConnectionError
182-
vprint_error("#{target_url} - Failed to connect to the web server")
183-
return nil
176+
177+
return res
178+
rescue ::Rex::ConnectionError
179+
vprint_error("#{target_url} - Failed to connect to the web server")
180+
return nil
184181
end
185182
end
186183

184+
def send_request_login(opts = {})
185+
res = send_request_cgi({
186+
'uri' => @uri,
187+
'method' => 'POST',
188+
'cookie' => "#{opts['cookie']}",
189+
'headers' =>
190+
{
191+
'Referer' => opts['referer_var']
192+
},
193+
'vars_post' => {
194+
opts['user_var'] => opts['user'],
195+
opts['pass_var'] => opts['pass'],
196+
'lang' => '',
197+
'option' => 'com_login',
198+
'task' => 'login',
199+
'return' => 'aW5kZXgucGhw',
200+
opts['hidden_value'] => 1
201+
}
202+
})
203+
204+
res
205+
end
206+
187207
def determine_result(response)
188208
return :abort unless response.kind_of? Rex::Proto::Http::Response
189209
return :abort unless response.code
@@ -199,63 +219,47 @@ def determine_result(response)
199219
return :fail
200220
end
201221

202-
def get_login_cookie
203-
222+
def get_login_response
204223
uri = normalize_uri(datastore['FORM_URI'])
205-
uid = Array.new
206-
cval = Array.new
207-
valor_input_id = ''
224+
res = send_request_cgi!({'uri' => uri, 'method' => 'GET'})
208225

209-
res = send_request_cgi({'uri' => uri, 'method' => 'GET'})
226+
res
227+
end
210228

211-
if(res.code == 301)
212-
path = res.headers['Location']
213-
vprint_status("Following redirect: #{path}")
214-
res = send_request_cgi({
215-
'uri' => path,
216-
'method' => 'GET'
217-
})
218-
end
229+
def get_login_cookie(res)
230+
return nil unless res.kind_of?(Rex::Proto::Http::Response)
219231

220-
#print_status("Response Get login cookie: #{res.to_s}")
232+
res.get_cookies
233+
end
221234

222-
if res && res.code == 200 && res.headers['Set-Cookie']
223-
#Identify login form and get the session variable validation of Joomla
224-
if res.body && res.body =~ /<form action=([^\>]+)\>(.*)<\/form>/mi
235+
def get_login_hidden(res)
236+
return nil unless res.kind_of?(Rex::Proto::Http::Response)
225237

226-
form = res.body.split(/<form action=([^\>]+) method="post" id="form-login"\>(.*)<\/form>/mi)
238+
if res.body && res.body.to_s =~ /<form action=([^\>]+)\>(.*)<\/form>/mi
227239

228-
if form.length == 1 #is not Joomla 2.5
229-
print_error("Testing Form Joomla 3.0")
230-
form = res.body.split(/<form action=([^\>]+) method="post" id="form-login" class="form-inline"\>(.*)<\/form>/mi)
231-
end
240+
vprint_status("#{target_url} - Testing Joomla 2.5 Form...")
241+
form = res.body.split(/<form action=([^\>]+) method="post" id="form-login"\>(.*)<\/form>/mi)
232242

233-
unless form
234-
print_error("Joomla Form Not Found")
235-
form = res.body.split(/<form id="login-form" action=([^\>]+)\>(.*)<\/form>/mi)
236-
end
237-
238-
input_hidden = form[2].split(/<input type="hidden"([^\>]+)\/>/mi)
243+
if form.length == 1 #is not Joomla 2.5
244+
vprint_status("#{target_url} - Testing Form Joomla 3.0 Form...")
245+
form = res.body.split(/<form action=([^\>]+) method="post" id="form-login" class="form-inline"\>(.*)<\/form>/mi)
246+
end
239247

240-
print_status("--------> Joomla Form Found <--------")
248+
unless form
249+
vprint_error("#{target_url} - Joomla Authentication Form Not Found")
250+
form = res.body.split(/<form id="login-form" action=([^\>]+)\>(.*)<\/form>/mi)
251+
end
241252

242-
input_id = input_hidden[7].split("\"")
253+
input_hidden = form[2].split(/<input type="hidden"([^\>]+)\/>/mi)
243254

244-
valor_input_id = input_id[1]
245-
end
255+
input_id = input_hidden[7].split("\"")
246256

247-
#Get the name of the cookie variable Joomla
257+
valor_input_id = input_id[1]
248258

249-
print_status("cookie = #{res.headers['Set-Cookie']}")
250-
print_status("cookie 2 = #{res.get_cookies}")
251-
res.headers['Set-Cookie'].split(';').each {|c|
252-
if c.split('=')[0].length > 10
253-
uid.push(c.split('=')[0])
254-
cval.push(c.split('=')[1])
255-
end
256-
}
257-
return uid, cval, valor_input_id.strip
259+
return valor_input_id
258260
end
259-
return nil
261+
262+
nil
260263
end
264+
261265
end

0 commit comments

Comments
 (0)