2b70ec2e08
[#47720609] Msf::PayloadSet#add_module does NOT return an annotated module class as Msf::ModuleSet#add_module does because a payload module is defined as a ruby Module instead of a ruby Class. Since add_module doesn't always return an annotated_class, the logic in Msf::ModuleManager#on_module_load needed to change to NOT use annotated_class and create #add_module as return [void]. Thus, it is necessary to pass in all the metasploit module metadata to Msf::ModuleManager#cache_in_memory instead of assuming they can be derived from the (payload) Module or (other) Class.
162 lines
4.0 KiB
Ruby
162 lines
4.0 KiB
Ruby
shared_examples_for 'Msf::ModuleManager::Loading' do
|
|
context '#file_changed?' do
|
|
let(:module_basename) do
|
|
[basename_prefix, '.rb']
|
|
end
|
|
|
|
it 'should return true if module info is not cached' do
|
|
Tempfile.open(module_basename) do |tempfile|
|
|
module_path = tempfile.path
|
|
|
|
subject.send(:module_info_by_path)[module_path].should be_nil
|
|
subject.file_changed?(module_path).should be_true
|
|
end
|
|
end
|
|
|
|
it 'should return true if the cached type is Msf::MODULE_PAYLOAD' do
|
|
Tempfile.open(module_basename) do |tempfile|
|
|
module_path = tempfile.path
|
|
modification_time = File.mtime(module_path)
|
|
|
|
subject.send(:module_info_by_path)[module_path] = {
|
|
# :modification_time must match so that it is the :type that is causing the `true` and not the
|
|
# :modification_time causing the `true`.
|
|
:modification_time => modification_time,
|
|
:type => Msf::MODULE_PAYLOAD
|
|
}
|
|
|
|
subject.file_changed?(module_path).should be_true
|
|
end
|
|
end
|
|
|
|
context 'with cache module info and not a payload module' do
|
|
it 'should return true if the file does not exist on the file system' do
|
|
tempfile = Tempfile.new(module_basename)
|
|
module_path = tempfile.path
|
|
modification_time = File.mtime(module_path).to_i
|
|
|
|
subject.send(:module_info_by_path)[module_path] = {
|
|
:modification_time => modification_time
|
|
}
|
|
|
|
tempfile.unlink
|
|
|
|
File.exist?(module_path).should be_false
|
|
subject.file_changed?(module_path).should be_true
|
|
end
|
|
|
|
it 'should return true if modification time does not match the cached modification time' do
|
|
Tempfile.open(module_basename) do |tempfile|
|
|
module_path = tempfile.path
|
|
modification_time = File.mtime(module_path).to_i
|
|
cached_modification_time = (modification_time * rand).to_i
|
|
|
|
subject.send(:module_info_by_path)[module_path] = {
|
|
:modification_time => cached_modification_time
|
|
}
|
|
|
|
cached_modification_time.should_not == modification_time
|
|
subject.file_changed?(module_path).should be_true
|
|
end
|
|
end
|
|
|
|
it 'should return false if modification time does match the cached modification time' do
|
|
Tempfile.open(module_basename) do |tempfile|
|
|
module_path = tempfile.path
|
|
modification_time = File.mtime(module_path).to_i
|
|
cached_modification_time = modification_time
|
|
|
|
subject.send(:module_info_by_path)[module_path] = {
|
|
:modification_time => cached_modification_time
|
|
}
|
|
|
|
cached_modification_time.should == modification_time
|
|
subject.file_changed?(module_path).should be_false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context '#on_module_load' do
|
|
def on_module_load
|
|
module_manager.on_module_load(klass, type, reference_name, options)
|
|
end
|
|
|
|
let(:klass) do
|
|
Class.new(Msf::Auxiliary)
|
|
end
|
|
|
|
let(:module_set) do
|
|
module_manager.module_set(type)
|
|
end
|
|
|
|
let(:namespace_module) do
|
|
mock('Namespace Module', :parent_path => parent_path)
|
|
end
|
|
|
|
let(:options) do
|
|
{
|
|
'files' => [
|
|
path
|
|
],
|
|
'paths' => [
|
|
reference_name
|
|
],
|
|
'type' => type
|
|
}
|
|
end
|
|
|
|
let(:parent_path) do
|
|
Metasploit::Framework.root.join('modules')
|
|
end
|
|
|
|
let(:path) do
|
|
type_directory = Mdm::Module::Detail::DIRECTORY_BY_TYPE[type]
|
|
|
|
File.join(parent_path, type_directory, "#{reference_name}.rb")
|
|
end
|
|
|
|
let(:reference_name) do
|
|
'admin/2wire/xslt_password_reset'
|
|
end
|
|
|
|
let(:type) do
|
|
klass.type
|
|
end
|
|
|
|
before(:each) do
|
|
klass.stub(:parent => namespace_module)
|
|
end
|
|
|
|
it "should add module to type's module_set" do
|
|
module_set.should_receive(:add_module).with(
|
|
klass,
|
|
reference_name,
|
|
options
|
|
)
|
|
|
|
on_module_load
|
|
end
|
|
|
|
it 'should call cache_in_memory' do
|
|
module_manager.should_receive(:cache_in_memory)
|
|
|
|
on_module_load
|
|
end
|
|
|
|
it 'should pass class to #auto_subscribe_module' do
|
|
module_manager.should_receive(:auto_subscribe_module).with(klass)
|
|
|
|
on_module_load
|
|
end
|
|
|
|
it 'should fire on_module_load event with class' do
|
|
framework.events.should_receive(:on_module_load).with(
|
|
reference_name,
|
|
klass
|
|
)
|
|
|
|
on_module_load
|
|
end
|
|
end
|
|
end |