## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Post include Msf::Auxiliary::Report def initialize(info = {}) super(update_info(info, 'Name' => 'Multi Recon Local Exploit Suggester', 'Description' => %q{ This module suggests local meterpreter exploits that can be used. The exploits are suggested based on the architecture and platform that the user has a shell opened as well as the available exploits in meterpreter. It's important to note that not all local exploits will be fired. Exploits are chosen based on these conditions: session type, platform, architecture, and required default options. }, 'License' => MSF_LICENSE, 'Author' => [ 'sinn3r', 'Mo' ], 'Platform' => all_platforms, 'SessionTypes' => [ 'meterpreter', 'shell' ])) register_options [ Msf::OptInt.new('SESSION', [ true, 'The session to run this module on' ]), Msf::OptBool.new('SHOWDESCRIPTION', [true, 'Displays a detailed description for the available exploits', false]) ] end def all_platforms Msf::Module::Platform.subclasses.collect { |c| c.realname.downcase } end def is_module_arch?(mod) mod_arch = mod.target.arch || mod.arch mod_arch.include? session.arch end def is_module_options_ready?(mod) mod.options.each_pair do |option_name, option| return false if option.required && option.default.nil? && mod.datastore[option_name].blank? end true end def is_module_platform?(mod) platform_obj = Msf::Module::Platform.find_platform session.platform module_platforms = mod.target.platform ? mod.target.platform.platforms : mod.platform.platforms module_platforms.include? platform_obj rescue ArgumentError => e # When not found, find_platform raises an ArgumentError elog "#{e.class} #{e.message}\n#{e.backtrace * "\n"}" return false end def is_session_type_compat?(mod) mod.session_compatible? session.sid end def set_module_options(mod) datastore.each_pair do |k, v| mod.datastore[k] = v end if !mod.datastore['SESSION'] && session.present? mod.datastore['SESSION'] = session.sid end end def is_module_wanted?(mod) ( mod.kind_of?(Msf::Exploit::Local) && mod.respond_to?(:check) && is_session_type_compat?(mod) && is_module_platform?(mod) && is_module_arch?(mod) && is_module_options_ready?(mod) ) end def setup print_status "Collecting local exploits for #{session.session_type}..." # Initializes an array @local_exploits = [] # Collects exploits into an array framework.exploits.each do |name, _obj| mod = framework.exploits.create name next unless mod set_module_options mod next unless is_module_wanted? mod @local_exploits << mod end end def show_found_exploits unless datastore['VERBOSE'] print_status "#{@local_exploits.length} exploit checks are being tried..." return end vprint_status "The following #{@local_exploits.length} exploit checks are being tried:" @local_exploits.each do |x| vprint_status x.fullname end end def run if @local_exploits.empty? print_error 'No suggestions available.' return end show_found_exploits results = [] @local_exploits.each do |m| begin checkcode = m.check if checkcode.nil? vprint_error "#{m.fullname}: Check failed" next end # See def is_check_interesting? unless is_check_interesting? checkcode vprint_status "#{m.fullname}: #{checkcode.second}" next end # Prints the full name and the checkcode message for the exploit print_good "#{m.fullname}: #{checkcode.second}" results << [m.fullname, checkcode.second] # If the datastore option is true, a detailed description will show next unless datastore['SHOWDESCRIPTION'] # Formatting for the description text Rex::Text.wordwrap(Rex::Text.compress(m.description), 2, 70).split(/\n/).each do |line| print_line line end rescue Rex::Post::Meterpreter::RequestError => e # Creates a log record in framework.log elog "#{e.class} #{e.message}\n#{e.backtrace * "\n"}" vprint_error "#{e.class} #{m.shortname} failed to run: #{e.message}" end end report_note( :host => rhost, :type => 'local.suggested_exploits', :data => results ) end def is_check_interesting?(checkcode) [ Msf::Exploit::CheckCode::Vulnerable, Msf::Exploit::CheckCode::Appears, Msf::Exploit::CheckCode::Detected ].include? checkcode end def print_status(msg='') super("#{session.session_host} - #{msg}") end def print_good(msg='') super("#{session.session_host} - #{msg}") end def print_error(msg='') super("#{session.session_host} - #{msg}") end end