Skip to content

Commit 8c5bead

Browse files
committed
Added spec to reproduce the username/password generation error in case PASSWORD_SPRAY and USER_AS_PASS are both enabled
Added minimal code to fix the issue, extracting the code to generate username:username credentials in the PASSWORD_SPRAY case
1 parent 93344df commit 8c5bead

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

lib/metasploit/framework/credential_collection.rb

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,16 @@ def each_unfiltered_password_first
280280
yield Metasploit::Framework::Credential.new(public: '', private: '', realm: realm, private_type: :password)
281281
end
282282

283+
if user_as_pass
284+
if user_fd
285+
user_fd.each_line do |user_from_file|
286+
user_from_file.chomp!
287+
yield Metasploit::Framework::Credential.new(public: user_from_file, private: user_from_file, realm: realm, private_type: private_type(password))
288+
end
289+
user_fd.seek(0)
290+
end
291+
end
292+
283293
if password.present?
284294
if nil_passwords
285295
yield Metasploit::Framework::Credential.new(public: username, private: nil, realm: realm, private_type: :password)
@@ -309,9 +319,6 @@ def each_unfiltered_password_first
309319
if username.present?
310320
yield Metasploit::Framework::Credential.new(public: username, private: pass_from_file, realm: realm, private_type: :password)
311321
end
312-
if user_as_pass
313-
yield Metasploit::Framework::Credential.new(public: pass_from_file, private: pass_from_file, realm: realm, private_type: :password)
314-
end
315322
next unless user_fd
316323

317324
user_fd.each_line do |user_from_file|

spec/lib/metasploit/framework/credential_collection_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,24 @@
157157
Metasploit::Framework::Credential.new(public: "user3", private: "password2"),
158158
)
159159
end
160+
161+
context 'when :user_as_pass is true' do
162+
let(:user_as_pass) { true }
163+
164+
specify do
165+
expect { |b| collection.each(&b) }.to yield_successive_args(
166+
Metasploit::Framework::Credential.new(public: "user1", private: "user1"),
167+
Metasploit::Framework::Credential.new(public: "user2", private: "user2"),
168+
Metasploit::Framework::Credential.new(public: "user3", private: "user3"),
169+
Metasploit::Framework::Credential.new(public: "user1", private: "password1"),
170+
Metasploit::Framework::Credential.new(public: "user2", private: "password1"),
171+
Metasploit::Framework::Credential.new(public: "user3", private: "password1"),
172+
Metasploit::Framework::Credential.new(public: "user1", private: "password2"),
173+
Metasploit::Framework::Credential.new(public: "user2", private: "password2"),
174+
Metasploit::Framework::Credential.new(public: "user3", private: "password2"),
175+
)
176+
end
177+
end
160178
end
161179

162180
context 'when given a username and password' do

0 commit comments

Comments
 (0)