## # 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. # CC-BY: hasherezade (hasherezade.net) ## 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 = /( '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