Skip to content

Commit

Permalink
Land #19156, Fixes password_spray not using additional_privates and d…
Browse files Browse the repository at this point in the history
…efault username
  • Loading branch information
adfoster-r7 authored May 2, 2024
2 parents 4c7f1e6 + d105ae1 commit fd10f4d
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 9 deletions.
29 changes: 20 additions & 9 deletions lib/metasploit/framework/credential_collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -282,19 +282,19 @@ def each_unfiltered_password_first
File.open(pass_file, 'r:binary') do |pass_fd|
pass_fd.each_line do |pass_from_file|
pass_from_file.chomp!
if username.present?
yield Metasploit::Framework::Credential.new(public: username, private: pass_from_file, realm: realm, private_type: :password)
end
if user_as_pass
yield Metasploit::Framework::Credential.new(public: pass_from_file, private: pass_from_file, realm: realm, private_type: :password)
end
if user_fd
user_fd.each_line do |user_from_file|
user_from_file.chomp!
yield Metasploit::Framework::Credential.new(public: user_from_file, private: pass_from_file, realm: realm, private_type: private_type(pass_from_file))
end
user_fd.seek(0)
end
additional_privates.each do |add_private|
yield Metasploit::Framework::Credential.new(public: user_from_file, private: add_private, realm: realm, private_type: private_type(add_private))
next unless user_fd

user_fd.each_line do |user_from_file|
user_from_file.chomp!
yield Metasploit::Framework::Credential.new(public: user_from_file, private: pass_from_file, realm: realm, private_type: private_type(pass_from_file))
end
user_fd.seek(0)
end
end
end
Expand All @@ -313,6 +313,17 @@ def each_unfiltered_password_first
end
end

additional_privates.each do |add_private|
if username.present?
yield Metasploit::Framework::Credential.new(public: username, private: add_private, realm: realm, private_type: private_type(add_private))
end
user_fd.each_line do |user_from_file|
user_from_file.chomp!
yield Metasploit::Framework::Credential.new(public: user_from_file, private: add_private, realm: realm, private_type: private_type(add_private))
end
user_fd.seek(0)
end

additional_publics.each do |add_public|
if password.present?
yield Metasploit::Framework::Credential.new(public: add_public, private: password, realm: realm, private_type: private_type(password) )
Expand Down
85 changes: 85 additions & 0 deletions spec/lib/metasploit/framework/credential_collection_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,91 @@
end
end

context 'when given a username and password' do
let(:password) { 'password' }
let(:username) { 'root' }

specify do
expected = [
Metasploit::Framework::Credential.new(public: 'root', private: 'password'),
]
expect { |b| collection.each(&b) }.to yield_successive_args(*expected)
end
end

context 'when given a pass_file, user_file, password spray and a default username' do
let(:password) { nil }
let(:username) { 'root' }
let(:password_spray) { true }
let(:pass_file) do
filename = "pass_file"
stub_file = StringIO.new("password1\npassword2\n")
allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file

filename
end
let(:user_file) do
filename = "user_file"
stub_file = StringIO.new("user1\nuser2\nuser3\n")
allow(File).to receive(:open).with(filename,/^r/).and_return stub_file

filename
end

specify do
expected = [
Metasploit::Framework::Credential.new(public: "root", private: "password1"),
Metasploit::Framework::Credential.new(public: "user1", private: "password1"),
Metasploit::Framework::Credential.new(public: "user2", private: "password1"),
Metasploit::Framework::Credential.new(public: "user3", private: "password1"),
Metasploit::Framework::Credential.new(public: "root", private: "password2"),
Metasploit::Framework::Credential.new(public: "user1", private: "password2"),
Metasploit::Framework::Credential.new(public: "user2", private: "password2"),
Metasploit::Framework::Credential.new(public: "user3", private: "password2"),
]
expect { |b| collection.each(&b) }.to yield_successive_args(*expected)
end
end

context 'when given a pass_file, user_file, password spray and additional privates' do
let(:password) { nil }
let(:username) { 'root' }
let(:password_spray) { true }
let(:additional_privates) { ['foo'] }
let(:pass_file) do
filename = "pass_file"
stub_file = StringIO.new("password1\npassword2\n")
allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file

filename
end
let(:user_file) do
filename = "user_file"
stub_file = StringIO.new("user1\nuser2\nuser3\n")
allow(File).to receive(:open).with(filename,/^r/).and_return stub_file

filename
end

specify do
expected = [
Metasploit::Framework::Credential.new(public: "root", private: "password1"),
Metasploit::Framework::Credential.new(public: "user1", private: "password1"),
Metasploit::Framework::Credential.new(public: "user2", private: "password1"),
Metasploit::Framework::Credential.new(public: "user3", private: "password1"),
Metasploit::Framework::Credential.new(public: "root", private: "password2"),
Metasploit::Framework::Credential.new(public: "user1", private: "password2"),
Metasploit::Framework::Credential.new(public: "user2", private: "password2"),
Metasploit::Framework::Credential.new(public: "user3", private: "password2"),
Metasploit::Framework::Credential.new(public: "root", private: "foo"),
Metasploit::Framework::Credential.new(public: "user1", private: "foo"),
Metasploit::Framework::Credential.new(public: "user2", private: "foo"),
Metasploit::Framework::Credential.new(public: "user3", private: "foo"),
]
expect { |b| collection.each(&b) }.to yield_successive_args(*expected)
end
end

context 'when given a username, user_file and pass_file' do
let(:password) { nil }
let(:username) { 'my_username' }
Expand Down

0 comments on commit fd10f4d

Please sign in to comment.