Files
metasploit-gs/spec/support/shared/examples/payload_can_be_instantiated.rb
T
Luke Imhoff 45fea32c77 Use 'Metasploit::Simple::Framework#modules loading' in 'payloads can be instantiated'
MSP-11130

Use `expect_to_load_module_ancestor` and `load_and_create_module` in
favor of the custom code in 'payloads can be instantiated'.
2014-11-04 13:06:52 -06:00

111 lines
4.4 KiB
Ruby

# @note Requires use of 'untested payloads' shared context for tracking of `@actual_ancestor_reference_name_set`.
#
# Tests that the `:ancestor_reference_names` can be loaded from `:modules_pathname` and once the ancestors are loaded
# that `:reference_name` can be instantiated.
#
# # Payload Reference Name Derivation
# You can see this naming logic [here](https://github.com/rapid7/metasploit-framework/blob/1508be6254f698f345616d14415bce164bf377f9/lib/msf/core/payload_set.rb#L132-L148).
#
# ## Single
# 1. Remove the payload type prefix, `modules/payloads/singles`, from the path.
# 2. Remove the file extension, `.rb` from the path
#
# This is <reference_name>
#
# ## Staged
#
# ### Stager
# Determine if the stager module has a `handler_type_alias`
# No) Use stager's handler's `handler_type` as `<handler_type>`.
# Yes) Use the return value from `handler_type_alias` as `<handler_type>`.
#
# ### Stage
# 1. Remove the payload type prefix, `modules/payloads/stages`, from the path.
# 2. Remove the file extension, `.rb` from the path.
#
# This is <stage_reference_name>.
#
# ### Combining
# The final staged module's combined `<reference_name>` is `<stage_reference_name>/<handler_type>`.
#
# @example Using 'payload can be instantiated' with `Metasploit::Framework::Spec::UntestedPayloads.define_task` and 'untested payloads' shared context
# # Rakefile
# require 'metasploit/framework/spec/untested_payloads'
#
# # defined spec task with rspec-rails
# My::Application.load_tasks
# # extends spec task to fail when there are untested payloads
# Metasploit::Framework::Spec::UntestedPayloads.define_task
#
# # spec/modules/payloads_spec.rb
# require 'spec_helper'
#
# describe 'modules/payloads' do
# modules_pathname = Pathname.new(__FILE__).parent.parent.parent.join('modules')
#
# include_context 'untested payloads', modules_pathname: modules_pathname
#
# context 'my/staged/payload/handler' do
# it_should_behave_like 'payload can be instantiated',
# ancestor_reference_names: [
# 'stages/my/payload',
# 'stagers/my/payload/handler'
# ],
# modules_pathname: modules_pathname,
# reference_name: 'my/staged/payload/handler'
# end
# end
#
# @param options [Hash{Symbol => Array<String>, Pathname, String}]
# @option options [Array<String>] :ancestor_reference_names The reference names of the payload modules that are included
# in {Msf::Payload} to make the `:reference_name` payload. Ancestor reference names are the names of the files under
# `modules/payloads` without the extension `.rb` that are mixed together to form a payload module `Class`. For
# single payloads, there will be one ancestor reference name from `modules/payloads/singles`, while for staged
# payloads there with be one ancestor reference name from `modules/payloads/stagers` and one ancestor reference name
# from `modules/payloads/stages`.
# @option options [Pathname] :modules_pathname The `modules` directory from which to load `:ancestor_reference_names`.
# @option options [String] :reference_name The reference name for payload class that should be instantiated from mixing
# `:ancestor_reference_names`.
# @return [void]
shared_examples_for 'payload can be instantiated' do |options|
options.assert_valid_keys(:ancestor_reference_names, :modules_pathname, :reference_name)
ancestor_reference_names = options.fetch(:ancestor_reference_names)
modules_pathname = options.fetch(:modules_pathname)
modules_path = modules_pathname.to_path
reference_name = options.fetch(:reference_name)
module_type = 'payload'
include_context 'Msf::Simple::Framework#modules loading'
#
# lets
#
context reference_name do
ancestor_reference_names.each do |ancestor_reference_name|
it "can load '#{module_type}/#{ancestor_reference_name}'" do
@actual_ancestor_reference_name_set.add(ancestor_reference_name)
expect_to_load_module_ancestor(
ancestor_reference_name: ancestor_reference_name,
module_type: module_type,
modules_path: modules_path
)
end
end
it 'can be instantiated' do
load_and_create_module(
ancestor_reference_names: ancestor_reference_names,
module_type: module_type,
modules_path: modules_path,
reference_name: reference_name
)
end
end
end