Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wpscanteam
GitHub Repository: wpscanteam/wpscan
Path: blob/master/spec/app/controllers/password_attack_spec.rb
486 views
1
# frozen_string_literal: true
2
3
XMLRPC_FAILED_BODY = '
4
<?xml version="1.0" encoding="UTF-8"?>
5
<methodResponse>
6
<fault>
7
<value>
8
<struct>
9
<member>
10
<name>faultCode</name>
11
<value><int>405</int></value>
12
</member>
13
<member>
14
<name>faultString</name>
15
<value><string>%s</string></value>
16
</member>
17
</struct>
18
</value>
19
</fault>
20
</methodResponse>'
21
22
describe WPScan::Controller::PasswordAttack do
23
subject(:controller) { described_class.new }
24
let(:target_url) { 'http://ex.lo/' }
25
let(:cli_args) { "--url #{target_url}" }
26
27
before do
28
WPScan::ParsedCli.options = rspec_parsed_options(cli_args)
29
end
30
31
describe '#cli_options' do
32
its(:cli_options) { should_not be_empty }
33
its(:cli_options) { should be_a Array }
34
35
it 'contains to correct options' do
36
expect(controller.cli_options.map(&:to_sym))
37
.to eq(%i[passwords usernames multicall_max_passwords password_attack login_uri])
38
end
39
end
40
41
describe '#users' do
42
context 'when no --usernames' do
43
it 'calls target.users' do
44
expect(controller.target).to receive(:users)
45
controller.users
46
end
47
end
48
49
context 'when --usernames' do
50
let(:cli_args) { "#{super()} --usernames admin,editor" }
51
52
it 'returns an array with the users' do
53
expected = %w[admin editor].reduce([]) do |a, e|
54
a << WPScan::Model::User.new(e)
55
end
56
57
expect(controller.users).to eql expected
58
end
59
end
60
end
61
62
describe '#run' do
63
context 'when no --passwords is supplied' do
64
it 'does not run the attacker' do
65
expect(controller.run).to eql nil
66
end
67
end
68
end
69
70
describe '#xmlrpc_get_users_blogs_enabled?' do
71
before { expect(controller.target).to receive(:xmlrpc).and_return(xmlrpc) }
72
73
context 'when xmlrpc not found' do
74
let(:xmlrpc) { nil }
75
76
its(:xmlrpc_get_users_blogs_enabled?) { should be false }
77
end
78
79
context 'when xmlrpc not enabled' do
80
let(:xmlrpc) { WPScan::Model::XMLRPC.new("#{target_url}xmlrpc.php") }
81
82
it 'returns false' do
83
expect(xmlrpc).to receive(:enabled?).and_return(false)
84
85
expect(controller.xmlrpc_get_users_blogs_enabled?).to be false
86
end
87
end
88
89
context 'when xmlrpc enabled' do
90
let(:xmlrpc) { WPScan::Model::XMLRPC.new("#{target_url}xmlrpc.php") }
91
92
before { expect(xmlrpc).to receive(:enabled?).and_return(true) }
93
94
context 'when wp.getUsersBlogs methods not listed' do
95
it 'returns false' do
96
expect(xmlrpc).to receive(:available_methods).and_return(%w[m1 m2])
97
98
expect(controller.xmlrpc_get_users_blogs_enabled?).to be false
99
end
100
end
101
102
context 'when wp.getUsersBlogs method listed' do
103
before do
104
expect(xmlrpc).to receive(:available_methods).and_return(%w[wp.getUsersBlogs m2])
105
106
stub_request(:post, xmlrpc.url).to_return(body: body)
107
end
108
109
context 'when wp.getUsersBlogs method disabled' do
110
context 'when blog is in EN' do
111
let(:body) { format(XMLRPC_FAILED_BODY, 'XML-RPC services are disabled on this site.') }
112
113
it 'returns false' do
114
expect(controller.xmlrpc_get_users_blogs_enabled?).to be false
115
end
116
end
117
118
context 'when blog is in FR' do
119
let(:body) { format(XMLRPC_FAILED_BODY, 'Les services XML-RPC sont désactivés sur ce site.') }
120
121
it 'returns false' do
122
expect(controller.xmlrpc_get_users_blogs_enabled?).to be false
123
end
124
end
125
end
126
127
context 'when wp.getUsersBlogs method enabled' do
128
let(:body) { 'Incorrect username or password.' }
129
130
it 'returns true' do
131
expect(controller.xmlrpc_get_users_blogs_enabled?).to be true
132
end
133
end
134
end
135
end
136
end
137
138
describe '#attacker' do
139
before do
140
allow(controller.target).to receive(:sub_dir)
141
controller.target.instance_variable_set(:@login_url, nil)
142
end
143
144
context 'when --password-attack provided' do
145
let(:cli_args) { "#{super()} --password-attack #{attack}" }
146
147
context 'when wp-login' do
148
before { stub_request(:get, controller.target.url('wp-login.php')).to_return(status: status) }
149
150
let(:attack) { 'wp-login' }
151
152
context 'when available' do
153
let(:status) { 200 }
154
155
it 'returns the correct object' do
156
expect(controller.attacker).to be_a WPScan::Finders::Passwords::WpLogin
157
expect(controller.attacker.target).to be_a WPScan::Target
158
end
159
end
160
161
context 'when not available (404)' do
162
let(:status) { 404 }
163
164
it 'raises an error' do
165
expect { controller.attacker }.to raise_error(WPScan::Error::NoLoginInterfaceDetected)
166
end
167
end
168
end
169
170
context 'when xmlrpc' do
171
context 'when xmlrpc not detected on target' do
172
before do
173
expect(controller.target).to receive(:xmlrpc).and_return(nil)
174
end
175
176
context 'when single xmlrpc' do
177
let(:attack) { 'xmlrpc' }
178
179
it 'raises an error' do
180
expect { controller.attacker }.to raise_error(WPScan::Error::XMLRPCNotDetected)
181
end
182
end
183
184
context 'when xmlrpc-multicall' do
185
let(:attack) { 'xmlrpc-multicall' }
186
187
it 'raises an error' do
188
expect { controller.attacker }.to raise_error(WPScan::Error::XMLRPCNotDetected)
189
end
190
end
191
end
192
193
context 'when xmlrpc detected on target' do
194
before do
195
expect(controller.target)
196
.to receive(:xmlrpc)
197
.and_return(WPScan::Model::XMLRPC.new("#{target_url}xmlrpc.php"))
198
end
199
200
context 'when single xmlrpc' do
201
let(:attack) { 'xmlrpc' }
202
203
it 'returns the correct object' do
204
expect(controller.attacker).to be_a WPScan::Finders::Passwords::XMLRPC
205
expect(controller.attacker.target).to be_a WPScan::Model::XMLRPC
206
end
207
end
208
209
context 'when xmlrpc-multicall' do
210
let(:attack) { 'xmlrpc-multicall' }
211
212
it 'returns the correct object' do
213
expect(controller.attacker).to be_a WPScan::Finders::Passwords::XMLRPCMulticall
214
expect(controller.attacker.target).to be_a WPScan::Model::XMLRPC
215
end
216
end
217
end
218
end
219
end
220
221
context 'when automatic detection' do
222
context 'when xmlrpc_get_users_blogs_enabled? is false' do
223
before do
224
expect(controller).to receive(:xmlrpc_get_users_blogs_enabled?).and_return(false)
225
stub_request(:get, controller.target.url('wp-login.php')).to_return(status: status)
226
end
227
228
context 'when wp-login available' do
229
let(:status) { 200 }
230
231
it 'returns the WpLogin' do
232
expect(controller.attacker).to be_a WPScan::Finders::Passwords::WpLogin
233
expect(controller.attacker.target).to be_a WPScan::Target
234
end
235
end
236
237
context 'when wp-login.php not available' do
238
let(:status) { 404 }
239
240
it 'raises an error' do
241
expect { controller.attacker }.to raise_error(WPScan::Error::NoLoginInterfaceDetected)
242
end
243
end
244
end
245
246
context 'when xmlrpc_get_users_blogs_enabled? is true' do
247
before do
248
expect(controller).to receive(:xmlrpc_get_users_blogs_enabled?).and_return(true)
249
250
expect(controller.target)
251
.to receive(:xmlrpc).and_return(WPScan::Model::XMLRPC.new("#{target_url}xmlrpc.php"))
252
end
253
254
context 'when WP version not found' do
255
it 'returns the XMLRPC' do
256
expect(controller.target).to receive(:wp_version).and_return(false)
257
258
expect(controller.attacker).to be_a WPScan::Finders::Passwords::XMLRPC
259
expect(controller.attacker.target).to be_a WPScan::Model::XMLRPC
260
end
261
end
262
263
context 'when WP version found' do
264
before { expect(controller.target).to receive(:wp_version).and_return(wp_version) }
265
266
context 'when WP < 4.4' do
267
let(:wp_version) { WPScan::Model::WpVersion.new('3.8.1') }
268
269
it 'returns the XMLRPCMulticall' do
270
expect(controller.attacker).to be_a WPScan::Finders::Passwords::XMLRPCMulticall
271
expect(controller.attacker.target).to be_a WPScan::Model::XMLRPC
272
end
273
end
274
275
context 'when WP >= 4.4' do
276
let(:wp_version) { WPScan::Model::WpVersion.new('4.4') }
277
278
it 'returns the XMLRPC' do
279
expect(controller.attacker).to be_a WPScan::Finders::Passwords::XMLRPC
280
expect(controller.attacker.target).to be_a WPScan::Model::XMLRPC
281
end
282
end
283
end
284
end
285
end
286
end
287
end
288
289