2013-07-18 12:46:23 -05:00
|
|
|
# -*- coding:binary -*-
|
|
|
|
|
require 'spec_helper'
|
2013-07-18 13:35:04 -05:00
|
|
|
|
2015-10-16 15:57:04 -05:00
|
|
|
RSpec.describe Msf::Module do
|
2014-11-12 11:08:18 -06:00
|
|
|
subject(:msf_module) {
|
|
|
|
|
described_class.new
|
|
|
|
|
}
|
2014-10-27 19:39:32 -05:00
|
|
|
|
2022-08-08 01:40:15 +01:00
|
|
|
let(:module_with_options) do
|
|
|
|
|
msf_module.instance_eval do
|
|
|
|
|
register_options(
|
|
|
|
|
[
|
|
|
|
|
Msf::Opt::RHOSTS,
|
|
|
|
|
Msf::Opt::RPORT(3000),
|
|
|
|
|
] + Msf::Opt::stager_retry_options
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
msf_module
|
|
|
|
|
end
|
|
|
|
|
|
2014-10-15 14:39:21 -05:00
|
|
|
it { is_expected.to respond_to :debugging? }
|
|
|
|
|
it { is_expected.to respond_to :fail_with }
|
|
|
|
|
it { is_expected.to respond_to :file_path }
|
|
|
|
|
it { is_expected.to respond_to :framework }
|
|
|
|
|
it { is_expected.to respond_to :orig_cls }
|
|
|
|
|
it { is_expected.to respond_to :owner }
|
|
|
|
|
it { is_expected.to respond_to :platform? }
|
|
|
|
|
it { is_expected.to respond_to :platform_to_s }
|
|
|
|
|
it { is_expected.to respond_to :register_parent }
|
|
|
|
|
it { is_expected.to respond_to :replicant }
|
2014-11-12 11:08:18 -06:00
|
|
|
it { is_expected.to respond_to_protected :set_defaults }
|
2014-10-15 14:39:21 -05:00
|
|
|
it { is_expected.to respond_to :workspace }
|
|
|
|
|
|
2014-10-16 13:16:57 -05:00
|
|
|
it_should_behave_like 'Msf::Module::Arch'
|
2014-10-16 09:29:31 -05:00
|
|
|
it_should_behave_like 'Msf::Module::Compatibility'
|
2014-10-16 08:35:15 -05:00
|
|
|
it_should_behave_like 'Msf::Module::DataStore'
|
2014-10-16 15:33:13 -05:00
|
|
|
it_should_behave_like 'Msf::Module::FullName'
|
2014-10-16 13:10:15 -05:00
|
|
|
it_should_behave_like 'Msf::Module::ModuleInfo'
|
2014-10-16 08:20:55 -05:00
|
|
|
it_should_behave_like 'Msf::Module::ModuleStore'
|
2014-10-16 15:54:35 -05:00
|
|
|
it_should_behave_like 'Msf::Module::Network'
|
2014-10-16 11:24:03 -05:00
|
|
|
it_should_behave_like 'Msf::Module::Options'
|
2014-10-17 11:48:36 -05:00
|
|
|
it_should_behave_like 'Msf::Module::Privileged'
|
2014-10-17 13:39:53 -05:00
|
|
|
it_should_behave_like 'Msf::Module::Ranking'
|
2014-10-16 14:28:43 -05:00
|
|
|
it_should_behave_like 'Msf::Module::Type'
|
2014-10-16 09:45:17 -05:00
|
|
|
it_should_behave_like 'Msf::Module::UI'
|
2014-10-17 11:34:35 -05:00
|
|
|
it_should_behave_like 'Msf::Module::UUID'
|
2014-10-15 14:59:44 -05:00
|
|
|
|
2014-10-15 14:39:21 -05:00
|
|
|
context 'class' do
|
|
|
|
|
subject {
|
|
|
|
|
described_class
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
it { is_expected.to respond_to :cached? }
|
2019-08-22 18:03:13 -05:00
|
|
|
it { is_expected.to respond_to :usable? }
|
2013-07-18 12:46:23 -05:00
|
|
|
end
|
2014-12-02 12:18:30 -06:00
|
|
|
|
2022-08-08 01:40:15 +01:00
|
|
|
describe '#register_options' do
|
|
|
|
|
subject { module_with_options }
|
|
|
|
|
|
|
|
|
|
it 'should register the options' do
|
|
|
|
|
expected_options = hash_including(
|
|
|
|
|
{
|
|
|
|
|
'RHOSTS' => an_instance_of(Msf::OptRhosts),
|
|
|
|
|
'RPORT' => an_instance_of(Msf::OptPort),
|
|
|
|
|
'StagerRetryCount' => an_instance_of(Msf::OptInt),
|
|
|
|
|
'StagerRetryWait' => an_instance_of(Msf::OptInt),
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
expect(subject.options).to match(expected_options)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should set defaults on the datastore' do
|
|
|
|
|
expect(subject.datastore['RHOSTS']).to be(nil)
|
|
|
|
|
expect(subject.datastore['RPORT']).to eq(3000)
|
|
|
|
|
expect(subject.datastore['StagerRetryCount']).to eq(10)
|
|
|
|
|
expect(subject.datastore['StagerRetryWait']).to eq(5)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe '#deregister_options' do
|
|
|
|
|
subject { module_with_options }
|
|
|
|
|
|
|
|
|
|
context 'when the options have previously been registered' do
|
|
|
|
|
before(:each) do
|
|
|
|
|
subject.instance_eval do
|
|
|
|
|
deregister_options('RHOSTS', 'RPORT', 'StagerRetryCount', 'StagerRetryWait')
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should unregister the options' do
|
|
|
|
|
expect(subject.options).to_not have_key('RHOSTS')
|
|
|
|
|
expect(subject.options).to_not have_key('RPORT')
|
|
|
|
|
expect(subject.options).to_not have_key('StagerRetryCount')
|
|
|
|
|
expect(subject.options).to_not have_key('StagerRetryWait')
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should remove the values from the datastore' do
|
|
|
|
|
expect(subject.datastore['RHOSTS']).to be(nil)
|
|
|
|
|
expect(subject.datastore['RPORT']).to be(nil)
|
|
|
|
|
expect(subject.datastore['StagerRetryCount']).to be(nil)
|
|
|
|
|
expect(subject.datastore['StagerRetryWait']).to be(nil)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when the using an alias to unregister options' do
|
|
|
|
|
before(:each) do
|
|
|
|
|
subject.instance_eval do
|
|
|
|
|
deregister_options(
|
|
|
|
|
# An alias of RHOSTS
|
|
|
|
|
'RHOST',
|
|
|
|
|
'RPORT',
|
|
|
|
|
# An alias of StagerRetryCount
|
|
|
|
|
'ReverseConnectRetries',
|
|
|
|
|
'StagerRetryWait'
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should unregister the options' do
|
|
|
|
|
expect(subject.options).to_not have_key('RHOSTS')
|
|
|
|
|
expect(subject.options).to_not have_key('RPORT')
|
|
|
|
|
expect(subject.options).to_not have_key('StagerRetryCount')
|
|
|
|
|
expect(subject.options).to_not have_key('StagerRetryWait')
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should remove the values from the datastore' do
|
|
|
|
|
expect(subject.datastore['RHOSTS']).to be(nil)
|
|
|
|
|
expect(subject.datastore['RPORT']).to be(nil)
|
|
|
|
|
expect(subject.datastore['StagerRetryCount']).to be(nil)
|
|
|
|
|
expect(subject.datastore['StagerRetryWait']).to be(nil)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2014-12-02 12:18:30 -06:00
|
|
|
describe "cloning modules into replicants" do
|
|
|
|
|
module MsfExtensionTestFoo; def my_test1; true; end; end;
|
|
|
|
|
module MsfExtensionTestBar; def my_test2; true; end; end;
|
|
|
|
|
|
|
|
|
|
describe "#perform_extensions" do
|
|
|
|
|
describe "when there are extensions registered" do
|
2015-12-31 16:56:13 -06:00
|
|
|
before(:example) do
|
2014-12-02 12:18:30 -06:00
|
|
|
msf_module.register_extensions(MsfExtensionTestFoo, MsfExtensionTestBar)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should extend the module replicant with the constants referenced in the datastore' do
|
|
|
|
|
expect(msf_module.replicant).to respond_to(:my_test1)
|
|
|
|
|
expect(msf_module.replicant).to respond_to(:my_test2)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe "when the datastore key has invalid data" do
|
2015-12-31 16:56:13 -06:00
|
|
|
before(:example) do
|
2014-12-02 12:18:30 -06:00
|
|
|
msf_module.datastore[Msf::Module::REPLICANT_EXTENSION_DS_KEY] = "invalid"
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should raise an exception' do
|
|
|
|
|
expect{msf_module.replicant}.to raise_error(RuntimeError)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe "#register_extensions" do
|
|
|
|
|
describe "with single module" do
|
|
|
|
|
it 'should place the named module in the datastore' do
|
|
|
|
|
msf_module.register_extensions(MsfExtensionTestFoo)
|
2014-12-02 13:12:53 -06:00
|
|
|
expect(msf_module.replicant.datastore[Msf::Module::REPLICANT_EXTENSION_DS_KEY]).to eql([MsfExtensionTestFoo])
|
2014-12-02 12:18:30 -06:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe "with multiple modules" do
|
|
|
|
|
it 'should place the named modules in the datastore' do
|
|
|
|
|
msf_module.register_extensions(MsfExtensionTestFoo, MsfExtensionTestBar)
|
2014-12-02 13:12:53 -06:00
|
|
|
expect(msf_module.replicant.datastore[Msf::Module::REPLICANT_EXTENSION_DS_KEY]).to eql([MsfExtensionTestFoo, MsfExtensionTestBar])
|
2014-12-02 12:18:30 -06:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
end
|
2013-07-18 12:46:23 -05:00
|
|
|
end
|