Path: blob/master/spec/lib/metasploit/framework/credential_collection_spec.rb
19534 views
require 'spec_helper'1require 'metasploit/framework/credential_collection'23RSpec.describe Metasploit::Framework::CredentialCollection do45subject(:collection) do6described_class.new(7nil_passwords: nil_passwords,8blank_passwords: blank_passwords,9pass_file: pass_file,10password: password,11user_as_pass: user_as_pass,12user_file: user_file,13username: username,14userpass_file: userpass_file,15prepended_creds: prepended_creds,16additional_privates: additional_privates,17additional_publics: additional_publics,18password_spray: password_spray,19ignore_public: ignore_public,20ignore_private: ignore_private21)22end2324before(:each) do25# The test suite overrides File.open(...) calls; fall back to the normal behavior for any File.open calls that aren't explicitly mocked26allow(File).to receive(:open).with(anything).and_call_original27allow(File).to receive(:open).with(anything, anything).and_call_original28allow(File).to receive(:open).with(anything, anything, anything).and_call_original29end3031let(:nil_passwords) { nil }32let(:blank_passwords) { nil }33let(:username) { "user" }34let(:password) { "pass" }35let(:user_file) { nil }36let(:pass_file) { nil }37let(:user_as_pass) { nil }38let(:userpass_file) { nil }39let(:prepended_creds) { [] }40let(:additional_privates) { [] }41let(:additional_publics) { [] }42let(:password_spray) { false }43let(:ignore_public) { nil }44let(:ignore_private) { nil }4546describe "#each" do47specify do48expect { |b| collection.each(&b) }.to yield_with_args(Metasploit::Framework::Credential)49end5051context "when given a user_file and password" do52let(:username) { nil }53let(:user_file) do54filename = "foo"55stub_file = StringIO.new("asdf\njkl\n")56allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file5758filename59end6061specify do62expect { |b| collection.each(&b) }.to yield_successive_args(63Metasploit::Framework::Credential.new(public: "asdf", private: password),64Metasploit::Framework::Credential.new(public: "jkl", private: password),65)66end67end6869context "when given a pass_file and username" do70let(:password) { nil }71let(:pass_file) do72filename = "foo"73stub_file = StringIO.new("asdf\njkl\n")74allow(File).to receive(:open).with(filename,/^r/).and_return stub_file7576filename77end7879specify do80expect { |b| collection.each(&b) }.to yield_successive_args(81Metasploit::Framework::Credential.new(public: username, private: "asdf"),82Metasploit::Framework::Credential.new(public: username, private: "jkl"),83)84end85end8687context "when given a userspass_file" do88let(:username) { nil }89let(:password) { nil }90let(:userpass_file) do91filename = "foo"92stub_file = StringIO.new("asdf jkl\nfoo bar\n")93allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file9495filename96end9798specify do99expect { |b| collection.each(&b) }.to yield_successive_args(100Metasploit::Framework::Credential.new(public: "asdf", private: "jkl"),101Metasploit::Framework::Credential.new(public: "foo", private: "bar"),102)103end104end105106context "when given a pass_file and user_file" do107let(:password) { nil }108let(:username) { nil }109let(:user_file) do110filename = "user_file"111stub_file = StringIO.new("asdf\njkl\n")112allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file113114filename115end116let(:pass_file) do117filename = "pass_file"118stub_file = StringIO.new("asdf\njkl\n")119allow(File).to receive(:open).with(filename,/^r/).and_return stub_file120121filename122end123124specify do125expect { |b| collection.each(&b) }.to yield_successive_args(126Metasploit::Framework::Credential.new(public: "asdf", private: "asdf"),127Metasploit::Framework::Credential.new(public: "asdf", private: "jkl"),128Metasploit::Framework::Credential.new(public: "jkl", private: "asdf"),129Metasploit::Framework::Credential.new(public: "jkl", private: "jkl"),130)131end132end133134context "when given a pass_file and user_file and password spray" do135let(:password) { nil }136let(:username) { nil }137let(:password_spray) { true }138let(:pass_file) do139filename = "pass_file"140stub_file = StringIO.new("password1\npassword2\n")141allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file142143filename144end145let(:user_file) do146filename = "user_file"147stub_file = StringIO.new("user1\nuser2\nuser3\n")148allow(File).to receive(:open).with(filename,/^r/).and_return stub_file149150filename151end152153specify do154expect { |b| collection.each(&b) }.to yield_successive_args(155Metasploit::Framework::Credential.new(public: "user1", private: "password1"),156Metasploit::Framework::Credential.new(public: "user2", private: "password1"),157Metasploit::Framework::Credential.new(public: "user3", private: "password1"),158Metasploit::Framework::Credential.new(public: "user1", private: "password2"),159Metasploit::Framework::Credential.new(public: "user2", private: "password2"),160Metasploit::Framework::Credential.new(public: "user3", private: "password2"),161)162end163164context 'when :user_as_pass is true' do165let(:user_as_pass) { true }166167specify do168expect { |b| collection.each(&b) }.to yield_successive_args(169Metasploit::Framework::Credential.new(public: "user1", private: "user1"),170Metasploit::Framework::Credential.new(public: "user2", private: "user2"),171Metasploit::Framework::Credential.new(public: "user3", private: "user3"),172Metasploit::Framework::Credential.new(public: "user1", private: "password1"),173Metasploit::Framework::Credential.new(public: "user2", private: "password1"),174Metasploit::Framework::Credential.new(public: "user3", private: "password1"),175Metasploit::Framework::Credential.new(public: "user1", private: "password2"),176Metasploit::Framework::Credential.new(public: "user2", private: "password2"),177Metasploit::Framework::Credential.new(public: "user3", private: "password2"),178)179end180end181end182183context 'when given a username and password' do184let(:password) { 'password' }185let(:username) { 'root' }186187specify do188expected = [189Metasploit::Framework::Credential.new(public: 'root', private: 'password'),190]191expect { |b| collection.each(&b) }.to yield_successive_args(*expected)192end193end194195context 'when given a pass_file, user_file, password spray and a default username' do196let(:password) { nil }197let(:username) { 'root' }198let(:password_spray) { true }199let(:pass_file) do200filename = "pass_file"201stub_file = StringIO.new("password1\npassword2\n")202allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file203204filename205end206let(:user_file) do207filename = "user_file"208stub_file = StringIO.new("user1\nuser2\nuser3\n")209allow(File).to receive(:open).with(filename,/^r/).and_return stub_file210211filename212end213214specify do215expected = [216Metasploit::Framework::Credential.new(public: "root", private: "password1"),217Metasploit::Framework::Credential.new(public: "user1", private: "password1"),218Metasploit::Framework::Credential.new(public: "user2", private: "password1"),219Metasploit::Framework::Credential.new(public: "user3", private: "password1"),220Metasploit::Framework::Credential.new(public: "root", private: "password2"),221Metasploit::Framework::Credential.new(public: "user1", private: "password2"),222Metasploit::Framework::Credential.new(public: "user2", private: "password2"),223Metasploit::Framework::Credential.new(public: "user3", private: "password2"),224]225expect { |b| collection.each(&b) }.to yield_successive_args(*expected)226end227end228229context 'when given a pass_file, user_file, password spray and additional privates' do230let(:password) { nil }231let(:username) { 'root' }232let(:password_spray) { true }233let(:additional_privates) { ['foo'] }234let(:pass_file) do235filename = "pass_file"236stub_file = StringIO.new("password1\npassword2\n")237allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file238239filename240end241let(:user_file) do242filename = "user_file"243stub_file = StringIO.new("user1\nuser2\nuser3\n")244allow(File).to receive(:open).with(filename,/^r/).and_return stub_file245246filename247end248249specify do250expected = [251Metasploit::Framework::Credential.new(public: "root", private: "password1"),252Metasploit::Framework::Credential.new(public: "user1", private: "password1"),253Metasploit::Framework::Credential.new(public: "user2", private: "password1"),254Metasploit::Framework::Credential.new(public: "user3", private: "password1"),255Metasploit::Framework::Credential.new(public: "root", private: "password2"),256Metasploit::Framework::Credential.new(public: "user1", private: "password2"),257Metasploit::Framework::Credential.new(public: "user2", private: "password2"),258Metasploit::Framework::Credential.new(public: "user3", private: "password2"),259Metasploit::Framework::Credential.new(public: "root", private: "foo"),260Metasploit::Framework::Credential.new(public: "user1", private: "foo"),261Metasploit::Framework::Credential.new(public: "user2", private: "foo"),262Metasploit::Framework::Credential.new(public: "user3", private: "foo"),263]264expect { |b| collection.each(&b) }.to yield_successive_args(*expected)265end266end267268context 'when given a username, user_file and pass_file' do269let(:password) { nil }270let(:username) { 'my_username' }271let(:user_file) do272filename = "user_file"273stub_file = StringIO.new("asdf\njkl\n")274allow(File).to receive(:open).with(filename, /^r/).and_yield stub_file275276filename277end278279let(:pass_file) do280filename = "pass_file"281stub_file = StringIO.new("asdf\njkl\n")282allow(File).to receive(:open).with(filename, /^r/).and_return stub_file283284filename285end286287it do288expect { |b| collection.each(&b) }.to yield_successive_args(289Metasploit::Framework::Credential.new(public: "my_username", private: "asdf"),290Metasploit::Framework::Credential.new(public: "my_username", private: "jkl"),291Metasploit::Framework::Credential.new(public: "asdf", private: "asdf"),292Metasploit::Framework::Credential.new(public: "asdf", private: "jkl"),293Metasploit::Framework::Credential.new(public: "jkl", private: "asdf"),294Metasploit::Framework::Credential.new(public: "jkl", private: "jkl")295)296end297end298299context "when :user_as_pass is true" do300let(:user_as_pass) { true }301specify do302expect { |b| collection.each(&b) }.to yield_successive_args(303Metasploit::Framework::Credential.new(public: username, private: password),304Metasploit::Framework::Credential.new(public: username, private: username),305)306end307end308309context "when :nil_passwords is true" do310let(:nil_passwords) { true }311specify do312expect { |b| collection.each(&b) }.to yield_successive_args(313Metasploit::Framework::Credential.new(public: username, private: nil),314Metasploit::Framework::Credential.new(public: username, private: password),315)316end317end318319context "when :blank_passwords is true" do320let(:blank_passwords) { true }321specify do322expect { |b| collection.each(&b) }.to yield_successive_args(323Metasploit::Framework::Credential.new(public: username, private: password),324Metasploit::Framework::Credential.new(public: username, private: ""),325)326end327end328329context 'when :ignore_public is true and :username is nil' do330let(:ignore_public) { true }331let(:username) { nil }332specify do333expect { |b| collection.each(&b) }.to_not yield_control334end335end336337context 'when :ignore_private is true and password is nil' do338let(:ignore_private) { true }339let(:password) { nil }340specify do341expect { |b| collection.each(&b) }.to yield_successive_args(342Metasploit::Framework::Credential.new(public: username, private: nil)343)344end345346context 'when :ignore_public is also true and username is nil' do347let(:ignore_public) { true }348let(:username) { nil }349specify do350expect { |b| collection.each(&b) }.to yield_successive_args(351Metasploit::Framework::Credential.new(public: nil, private: nil)352)353end354end355end356357end358359describe "#empty?" do360context "when only :userpass_file is set" do361let(:username) { nil }362let(:password) { nil }363let(:userpass_file) { "test_file" }364specify do365expect(collection.empty?).to eq false366end367end368369context "when :username is set" do370context "and :password is set" do371specify do372expect(collection.empty?).to eq false373end374end375376context "and :password is not set" do377let(:password) { nil }378specify do379expect(collection.empty?).to eq true380end381382context "and :nil_passwords is true" do383let(:nil_passwords) { true }384specify do385expect(collection.empty?).to eq false386end387end388389context "and :blank_passwords is true" do390let(:blank_passwords) { true }391specify do392expect(collection.empty?).to eq false393end394end395end396end397398context "when :username is not set" do399context "and :password is not set" do400let(:username) { nil }401let(:password) { nil }402specify do403expect(collection.empty?).to eq true404end405406context "and :prepended_creds is not empty" do407let(:prepended_creds) { [ "test" ] }408specify do409expect(collection.empty?).to eq false410end411end412413context "and :additional_privates is not empty" do414let(:additional_privates) { [ "test_private" ] }415specify do416expect(collection.empty?).to eq true417end418end419420context "and :additional_publics is not empty" do421let(:additional_publics) { [ "test_public" ] }422specify do423expect(collection.empty?).to eq true424end425end426427context "and :ignore_public is set" do428let(:ignore_public) { true }429specify do430expect(collection.empty?).to eq true431end432433context "and :ignore_private is also set" do434let(:ignore_private) { true }435specify do436expect(collection.empty?).to eq false437end438end439end440441end442end443end444445describe "#prepend_cred" do446specify do447prep = Metasploit::Framework::Credential.new(public: "foo", private: "bar")448collection.prepend_cred(prep)449expect { |b| collection.each(&b) }.to yield_successive_args(450prep,451Metasploit::Framework::Credential.new(public: username, private: password),452)453end454end455456end457458459