Skip to content

Instantly share code, notes, and snippets.

@hasherezade
Created January 2, 2015 13:02
Show Gist options
  • Save hasherezade/219e18a1c7a79cc2386f to your computer and use it in GitHub Desktop.
Save hasherezade/219e18a1c7a79cc2386f to your computer and use it in GitHub Desktop.
This module is just a test of Joomla authentication.
##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
#
# This module is just a test of Joomla authentication;
# can be used in exploits that require user to be logged in.
##
require 'msf/core'
class Metasploit4 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
# util:
def fetchMd5(my_string)
if my_string =~ /([0-9a-fA-F]{32})/
return $1
end
return nil
end
def send_request_login(url, cookie, user, pass, uniq_token)
print_status("Trying to auth as user: #{user}")
if not url or not user or not pass or not cookie or not uniq_token
print_error("Invalid params to sessin_request")
return nil
end
res = send_request_cgi(
'uri' => url,
'method' => 'POST',
'cookie' => cookie,
'headers' =>
{
'Referer' => url
},
'vars_post' => {
'username' => user,
'passwd' => pass,
'option' => 'com_login',
'task' => 'login',
'return' => 'aW5kZXgucGhw',
uniq_token => 1
}
)
return res
end
def establish_session(url, user, pass)
res = send_request_cgi({
'method' => 'GET',
'uri' => url
})
return nil if not res
print_status( "Initial res code: #{res.code}")
if res.code != 200
return nil
end
sess = res.get_cookies
print_status("Cookie: #{sess}")
token_pattern = /(<input type=\"hidden\" name=\"[a-zA-Z0-9]*\" value=\"1\")/
return nil if not res
uniq_token = ''
if res.body =~ token_pattern
uniq_token = $1
uniq_token = fetchMd5(uniq_token)
print_good( "Found token: #{uniq_token}")
end
res = send_request_login(url, sess, datastore["USERNAME"], datastore["PASSWORD"], uniq_token)
if not res
return nil
end
print_status( "Initial res code: #{res.code}")
res = send_request_cgi({
'method' => 'GET',
'uri' => url,
'cookie' => sess,
'headers' =>
{
'Referer' => url
}
})
print_status( "Final res code: #{res.code}")
if res.body =~ token_pattern
#login page appeared again
print_error("Unable to authenticate!")
return nil
end
# optionaly: doublecheck if really logged in
successp = datastore['SUCCESS_PATTERN']
if successp and "#{successp}".length() > 0
if res.body =~ successp
return sess
end
print_error('Success pattern NOT found')
return nil
end
return sess
end
# MSF api:
def initialize(info = {})
super(update_info(info,
'Name' => 'Joomla Mini Auth',
'Description' => %q{
This module is just a test of Joomla authentication.
},
'Author' =>
[
'hAsh'
],
'License' => MSF_LICENSE,
'References' =>
[
],
'Privileged' => false,
'Platform' => ['php'],
'Arch' => ARCH_PHP,
'Payload' =>
{
'BadChars' => "&\n=+%",
},
'Targets' =>
[
[ 'Automatic', { } ],
],
'DefaultTarget' => 0))
register_options(
[
OptString.new('TARGETURI', [ true, "Base Joomla directory path", 'joomla']),
OptString.new('USERNAME', [ true, "Username to authenticate with", 'admin']),
OptString.new('PASSWORD', [ false, "Password to authenticate with", 'admin']),
OptRegexp.new('SUCCESS_PATTERN', [false, 'Pattern returned in response on login success', '/Log out/'] ),
], self.class)
end
def exploit
admin_path = 'administrator/index.php'
proto = 'http'
if datastore['SSL'] == true
proto ='https'
end
url = "#{proto}:/" + normalize_uri("#{datastore['RHOST']}//#{datastore['TARGETURI']}//#{admin_path}")
print_status("GET url: #{url}")
sess = establish_session(url, datastore['USERNAME'], datastore['PASSWORD'])
if not sess
fail_with('Cannot establish session')
return nil
end
print_good("Logged as: #{datastore['USERNAME']}, Cookie: #{sess}")
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment