diff --git a/spec/lib/metasploit/framework/credential_collection_spec.rb b/spec/lib/metasploit/framework/credential_collection_spec.rb index 3fd679966d..a4d3cc3650 100644 --- a/spec/lib/metasploit/framework/credential_collection_spec.rb +++ b/spec/lib/metasploit/framework/credential_collection_spec.rb @@ -16,9 +16,7 @@ RSpec.describe Metasploit::Framework::CredentialCollection do prepended_creds: prepended_creds, additional_privates: additional_privates, additional_publics: additional_publics, - password_spray: password_spray, - ignore_public: ignore_public, - ignore_private: ignore_private + password_spray: password_spray ) end @@ -41,8 +39,6 @@ RSpec.describe Metasploit::Framework::CredentialCollection do let(:additional_privates) { [] } let(:additional_publics) { [] } let(:password_spray) { false } - let(:ignore_public) { nil } - let(:ignore_private) { nil } describe "#each" do specify do @@ -72,7 +68,7 @@ RSpec.describe Metasploit::Framework::CredentialCollection do let(:pass_file) do filename = "foo" stub_file = StringIO.new("asdf\njkl\n") - allow(File).to receive(:open).with(filename,/^r/).and_return stub_file + allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file filename end @@ -85,7 +81,7 @@ RSpec.describe Metasploit::Framework::CredentialCollection do end end - context "when given a userspass_file" do + context "when given a userpass_file" do let(:username) { nil } let(:password) { nil } let(:userpass_file) do @@ -117,7 +113,7 @@ RSpec.describe Metasploit::Framework::CredentialCollection do let(:pass_file) do filename = "pass_file" stub_file = StringIO.new("asdf\njkl\n") - allow(File).to receive(:open).with(filename,/^r/).and_return stub_file + allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file filename end @@ -146,7 +142,7 @@ RSpec.describe Metasploit::Framework::CredentialCollection do 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 + allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file filename end @@ -161,23 +157,40 @@ RSpec.describe Metasploit::Framework::CredentialCollection do Metasploit::Framework::Credential.new(public: "user3", private: "password2"), ) end + end - context 'when :user_as_pass is true' do - let(:user_as_pass) { true } + context 'when given a pass_file and user_file and password spray and :user_as_pass is true' do + let(:password) { nil } + let(:username) { nil } + 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 - specify do - expect { |b| collection.each(&b) }.to yield_successive_args( - Metasploit::Framework::Credential.new(public: "user1", private: "user1"), - Metasploit::Framework::Credential.new(public: "user2", private: "user2"), - Metasploit::Framework::Credential.new(public: "user3", private: "user3"), - 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: "user1", private: "password2"), - Metasploit::Framework::Credential.new(public: "user2", private: "password2"), - Metasploit::Framework::Credential.new(public: "user3", private: "password2"), - ) - end + 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_yield stub_file + + filename + end + let(:user_as_pass) { true } + + specify do + expect { |b| collection.each(&b) }.to yield_successive_args( + Metasploit::Framework::Credential.new(public: "user1", private: "user1"), + Metasploit::Framework::Credential.new(public: "user2", private: "user2"), + Metasploit::Framework::Credential.new(public: "user3", private: "user3"), + 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: "user1", private: "password2"), + Metasploit::Framework::Credential.new(public: "user2", private: "password2"), + Metasploit::Framework::Credential.new(public: "user3", private: "password2"), + ) end end @@ -207,7 +220,7 @@ RSpec.describe Metasploit::Framework::CredentialCollection do 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 + allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file filename end @@ -242,7 +255,7 @@ RSpec.describe Metasploit::Framework::CredentialCollection do 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 + allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file filename end @@ -280,7 +293,7 @@ RSpec.describe Metasploit::Framework::CredentialCollection do let(:pass_file) do filename = "pass_file" stub_file = StringIO.new("asdf\njkl\n") - allow(File).to receive(:open).with(filename, /^r/).and_return stub_file + allow(File).to receive(:open).with(filename, /^r/).and_yield stub_file filename end @@ -317,6 +330,20 @@ RSpec.describe Metasploit::Framework::CredentialCollection do end end + context "when using password spraying and :nil_passwords is true" do + let(:password_spray) { true } + let(:nil_passwords) { true } + + context "without password" do + let(:password) { nil } + specify do + expect { |b| collection.each(&b) }.to yield_successive_args( + Metasploit::Framework::Credential.new(public: username, private: nil) + ) + end + end + end + context "when :blank_passwords is true" do let(:blank_passwords) { true } specify do @@ -327,34 +354,244 @@ RSpec.describe Metasploit::Framework::CredentialCollection do end end - context 'when :ignore_public is true and :username is nil' do - let(:ignore_public) { true } + context "when given additional_publics and :user_as_pass is true" do let(:username) { nil } - specify do - expect { |b| collection.each(&b) }.to_not yield_control - end - end - - context 'when :ignore_private is true and password is nil' do - let(:ignore_private) { true } let(:password) { nil } - specify do + let(:additional_publics) { [ "test_public" ] } + let(:user_as_pass) { true } + + specify do expect { |b| collection.each(&b) }.to yield_successive_args( - Metasploit::Framework::Credential.new(public: username, private: nil) + Metasploit::Framework::Credential.new(public: "test_public", private: "test_public") ) end + end - context 'when :ignore_public is also true and username is nil' do - let(:ignore_public) { true } - let(:username) { nil } - specify do - expect { |b| collection.each(&b) }.to yield_successive_args( - Metasploit::Framework::Credential.new(public: nil, private: nil) - ) - end + context "when given additional_publics, :user_as_pass is true and using password spraying" do + let(:username) { nil } + let(:password) { nil } + let(:additional_publics) { [ "test_public" ] } + let(:user_as_pass) { true } + let(:password_spray) { true } + + specify do + expect { |b| collection.each(&b) }.to yield_successive_args( + Metasploit::Framework::Credential.new(public: "test_public", private: "test_public") + ) end end + context "when given additional_publics and :nil_password is true" do + let(:username) { nil } + let(:password) { nil } + let(:additional_publics) { [ "test_public" ] } + let(:nil_passwords) { true } + + specify do + expect { |b| collection.each(&b) }.to yield_successive_args( + Metasploit::Framework::Credential.new(public: "test_public", private: nil) + ) + end + end + + context "when given additional_publics, :nil_password is true, :blank_passwords is true and using password spraying" do + let(:username) { nil } + let(:password) { nil } + let(:additional_publics) { [ "test_public1", "test_public2" ] } + let(:nil_passwords) { true } + let(:blank_passwords) { true } + let(:password_spray) { true } + + specify do + expect { |b| collection.each(&b) }.to yield_successive_args( + Metasploit::Framework::Credential.new(public: "test_public1", private: nil), + Metasploit::Framework::Credential.new(public: "test_public2", private: nil), + Metasploit::Framework::Credential.new(public: "test_public1", private: ""), + Metasploit::Framework::Credential.new(public: "test_public2", private: "") + ) + end + end + + context "when given additional_publics, a user_file, a password and using password spraying" do + let(:username) { nil } + let(:password) { "password" } + let(:additional_publics) { [ "test_public" ] } + let(:user_file) do + filename = "user_file" + stub_file = StringIO.new("asdf\njkl\n") + allow(File).to receive(:open).with(filename, /^r/).and_yield stub_file + + filename + end + + specify do + expect { |b| collection.each(&b) }.to yield_successive_args( + Metasploit::Framework::Credential.new(public: "asdf", private: "password"), + Metasploit::Framework::Credential.new(public: "jkl", private: "password"), + Metasploit::Framework::Credential.new(public: "test_public", private: "password") + ) + end + end + + context "when using password spraying with blank_passwords and a password (but no username)" do + let(:password_spray) { true } + let(:blank_passwords) { true } + let(:username) { nil } + let(:password) { "pass" } + + specify do + expect { |b| collection.each(&b) }.to yield_successive_args() + end + end + + context "when using password spraying with blank_passwords and a username (but no password)" do + let(:password_spray) { true } + let(:blank_passwords) { true } + let(:username) { "user" } + let(:password) { nil } + + specify do + expect { |b| collection.each(&b) }.to yield_successive_args( + Metasploit::Framework::Credential.new(public: username, private: '') + ) + end + end + + context "when using password spraying with blank_passwords and given a user_file" do + let(:password_spray) { true } + let(:blank_passwords) { true } + let(:username) { nil } + let(:password) { nil } + let(:user_file) do + filename = "foo" + stub_file = StringIO.new("asdf\njkl\n") + allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file + + filename + end + + specify do + expect { |b| collection.each(&b) }.to yield_successive_args( + Metasploit::Framework::Credential.new(public: "asdf", private: ''), + Metasploit::Framework::Credential.new(public: "jkl", private: '') + ) + end + end + + context "when every possible option is used" do + let(:nil_passwords) { true } + let(:blank_passwords) { true } + let(:username) { "user" } + let(:password) { "pass" } + let(:user_file) do + filename = "user_file" + stub_file = StringIO.new("userfile") + allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file + + filename + end + let(:pass_file) do + filename = "pass_file" + stub_file = StringIO.new("passfile\n") + allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file + + filename + end + let(:user_as_pass) { true } + let(:userpass_file) do + filename = "userpass_file" + stub_file = StringIO.new("userpass_user userpass_pass\n") + allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file + + filename + end + let(:prepended_creds) { ['test_prepend'] } + let(:additional_privates) { ['test_private'] } + let(:additional_publics) { ['test_public'] } + + specify do + expect { |b| collection.each(&b) }.to yield_successive_args( + "test_prepend", + Metasploit::Framework::Credential.new(public: "user", private: nil), + Metasploit::Framework::Credential.new(public: "user", private: "pass"), + Metasploit::Framework::Credential.new(public: "user", private: "user"), + Metasploit::Framework::Credential.new(public: "user", private: ""), + Metasploit::Framework::Credential.new(public: "user", private: "passfile"), + Metasploit::Framework::Credential.new(public: "user", private: "test_private"), + Metasploit::Framework::Credential.new(public: "userfile", private: nil), + Metasploit::Framework::Credential.new(public: "userfile", private: "pass"), + Metasploit::Framework::Credential.new(public: "userfile", private: "userfile"), + Metasploit::Framework::Credential.new(public: "userfile", private: ""), + Metasploit::Framework::Credential.new(public: "userfile", private: "passfile"), + Metasploit::Framework::Credential.new(public: "userfile", private: "test_private"), + Metasploit::Framework::Credential.new(public: "userpass_user", private: "userpass_pass"), + Metasploit::Framework::Credential.new(public: "test_public", private: nil), # missing this case + Metasploit::Framework::Credential.new(public: "test_public", private: "pass"), + Metasploit::Framework::Credential.new(public: "test_public", private: "test_public"), + Metasploit::Framework::Credential.new(public: "test_public", private: ""), + Metasploit::Framework::Credential.new(public: "test_public", private: "passfile"), + Metasploit::Framework::Credential.new(public: "test_public", private: "test_private") + ) + end + end + + context "when using password spraying in combination with every other option" do + let(:password_spray) { true } + let(:nil_passwords) { true } + let(:blank_passwords) { true } + let(:username) { "user" } + let(:password) { "pass" } + let(:user_file) do + filename = "user_file" + stub_file = StringIO.new("userfile") + allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file + + filename + end + let(:pass_file) do + filename = "pass_file" + stub_file = StringIO.new("passfile\n") + allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file + + filename + end + let(:user_as_pass) { true } + let(:userpass_file) do + filename = "userpass_file" + stub_file = StringIO.new("userpass_user userpass_pass\n") + allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file + + filename + end + let(:prepended_creds) { ['test_prepend'] } + let(:additional_privates) { ['test_private'] } + let(:additional_publics) { ['test_public'] } + + specify do + expect { |b| collection.each(&b) }.to yield_successive_args( + "test_prepend", + Metasploit::Framework::Credential.new(public: "user", private: nil), + Metasploit::Framework::Credential.new(public: "userfile", private: nil), + Metasploit::Framework::Credential.new(public: "test_public", private: nil), + Metasploit::Framework::Credential.new(public: "user", private: "pass"), + Metasploit::Framework::Credential.new(public: "userfile", private: "pass"), + Metasploit::Framework::Credential.new(public: "test_public", private: "pass"), + Metasploit::Framework::Credential.new(public: "user", private: "user"), + Metasploit::Framework::Credential.new(public: "userfile", private: "userfile"), + Metasploit::Framework::Credential.new(public: "test_public", private: "test_public"), + Metasploit::Framework::Credential.new(public: "user", private: ""), + Metasploit::Framework::Credential.new(public: "userfile", private: ""), + Metasploit::Framework::Credential.new(public: "test_public", private: ""), + Metasploit::Framework::Credential.new(public: "user", private: "passfile"), + Metasploit::Framework::Credential.new(public: "userfile", private: "passfile"), + Metasploit::Framework::Credential.new(public: "test_public", private: "passfile"), + Metasploit::Framework::Credential.new(public: "userpass_user", private: "userpass_pass"), + Metasploit::Framework::Credential.new(public: "user", private: "test_private"), + Metasploit::Framework::Credential.new(public: "userfile", private: "test_private"), + Metasploit::Framework::Credential.new(public: "test_public", private: "test_private") + ) + end + end end describe "#empty?" do @@ -424,21 +661,6 @@ RSpec.describe Metasploit::Framework::CredentialCollection do expect(collection.empty?).to eq true end end - - context "and :ignore_public is set" do - let(:ignore_public) { true } - specify do - expect(collection.empty?).to eq true - end - - context "and :ignore_private is also set" do - let(:ignore_private) { true } - specify do - expect(collection.empty?).to eq false - end - end - end - end end end