df9db42c32
[#36737359] The merging of reload_module and the various load_module methods resulted in the module loading from disk, but because the Hash entry in the module manager was not deleted before on_module_load was called, the newly reloaded module was logged as an ambiguous module name instead of a reload. In order to report the reload errors correctly, I determined that module_load_error_by_reference_name should really be module_load_error_by_path. I eliminated faild in favor of this new name since failed was just calling the attribute and the attribute's name is clearer about the format of the data. Tested by run rexploit and then exiting over and over with ms08_067_netapi. When I messed up the file so it couldn't load, by adding `inclde Exploit` (note mispelling of `include`), it reported the error to msfconsole. When I removed the bad line and added a puts "RELOADING <n>", where I kept incrementing n and saving the file, the new number appeared during each rexploit.
262 lines
7.4 KiB
Ruby
Executable File
262 lines
7.4 KiB
Ruby
Executable File
#!/usr/bin/env ruby
|
|
# -*- coding: binary -*-
|
|
#
|
|
# $Id$
|
|
#
|
|
# This user interface allows users to interact with the framework through a
|
|
# command line interface (CLI) rather than having to use a prompting console
|
|
# or web-based interface.
|
|
#
|
|
# $Revision$
|
|
#
|
|
|
|
msfbase = __FILE__
|
|
while File.symlink?(msfbase)
|
|
msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase))
|
|
end
|
|
|
|
$:.unshift(File.expand_path(File.join(File.dirname(msfbase), 'lib')))
|
|
require 'fastlib'
|
|
require 'msfenv'
|
|
|
|
|
|
$:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB']
|
|
|
|
require 'rex'
|
|
require 'msf/ui'
|
|
require 'msf/base'
|
|
|
|
Indent = ' '
|
|
|
|
|
|
def usage (str = nil, extra = nil)
|
|
tbl = Rex::Ui::Text::Table.new(
|
|
'Header' => "Usage: #{$0} <exploit_name> <option=value> [mode]",
|
|
'Indent' => 4,
|
|
'Columns' => ['Mode', 'Description']
|
|
)
|
|
|
|
tbl << ['(H)elp', "You're looking at it baby!"]
|
|
tbl << ['(S)ummary', 'Show information about this module']
|
|
tbl << ['(O)ptions', 'Show available options for this module']
|
|
tbl << ['(A)dvanced', 'Show available advanced options for this module']
|
|
tbl << ['(I)DS Evasion', 'Show available ids evasion options for this module']
|
|
tbl << ['(P)ayloads', 'Show available payloads for this module']
|
|
tbl << ['(T)argets', 'Show available targets for this exploit module']
|
|
tbl << ['(AC)tions', 'Show available actions for this auxiliary module']
|
|
tbl << ['(C)heck', 'Run the check routine of the selected module']
|
|
tbl << ['(E)xecute', 'Execute the selected module']
|
|
|
|
$stdout.puts "Error: #{str}\n\n" if str
|
|
$stdout.puts tbl.to_s + "\n"
|
|
$stdout.puts extra + "\n" if extra
|
|
|
|
exit
|
|
end
|
|
|
|
# Handle the help option before loading modules
|
|
exploit_name = ARGV.shift
|
|
exploit = nil
|
|
module_class = "exploit"
|
|
|
|
if(exploit_name == "-h")
|
|
usage()
|
|
end
|
|
|
|
# Initialize the simplified framework instance.
|
|
$stderr.puts "[*] Please wait while we load the module tree..."
|
|
$framework = Msf::Simple::Framework.create
|
|
|
|
if ($framework.modules.module_load_error_by_path.length > 0)
|
|
print("Warning: The following modules could not be loaded!\n\n")
|
|
|
|
$framework.modules.module_load_error_by_path.each do |path, error|
|
|
print("\t#{path}: #{error}\n\n")
|
|
end
|
|
end
|
|
|
|
if (not exploit_name)
|
|
ext = ''
|
|
|
|
tbl = Rex::Ui::Text::Table.new(
|
|
'Header' => 'Exploits',
|
|
'Indent' => 4,
|
|
'Columns' => [ 'Name', 'Description' ])
|
|
|
|
$framework.exploits.each_module { |name, mod|
|
|
tbl << [ 'exploit/' + name, mod.new.name ]
|
|
}
|
|
ext << tbl.to_s + "\n"
|
|
|
|
tbl = Rex::Ui::Text::Table.new(
|
|
'Header' => 'Auxiliary',
|
|
'Indent' => 4,
|
|
'Columns' => [ 'Name', 'Description' ])
|
|
|
|
$framework.auxiliary.each_module { |name, mod|
|
|
tbl << [ 'auxiliary/' + name, mod.new.name ]
|
|
}
|
|
|
|
ext << tbl.to_s + "\n"
|
|
|
|
usage(nil, ext)
|
|
end
|
|
|
|
|
|
# Process special var/val pairs...
|
|
Msf::Ui::Common.process_cli_arguments($framework, ARGV)
|
|
|
|
# Determine what type of module it is
|
|
case exploit_name
|
|
when /exploit\/(.*)/
|
|
exploit = $framework.exploits.create($1)
|
|
module_class = 'exploit'
|
|
|
|
when /auxiliary\/(.*)/
|
|
exploit = $framework.auxiliary.create($1)
|
|
module_class = 'auxiliary'
|
|
|
|
else
|
|
exploit = $framework.exploits.create(exploit_name)
|
|
if exploit == nil
|
|
# Try falling back on aux modules
|
|
exploit = $framework.auxiliary.create(exploit_name)
|
|
module_class = 'auxiliary'
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if (exploit == nil)
|
|
usage("Invalid module: #{exploit_name}")
|
|
end
|
|
|
|
exploit.init_ui(
|
|
Rex::Ui::Text::Input::Stdio.new,
|
|
Rex::Ui::Text::Output::Stdio.new
|
|
)
|
|
|
|
# Evalulate the command (default to "help")
|
|
mode = ARGV.pop || 'h'
|
|
|
|
# Import options
|
|
exploit.datastore.import_options_from_s(ARGV.join('_|_'), '_|_')
|
|
|
|
|
|
# Initialize associated modules
|
|
payload = nil
|
|
encoder = nil
|
|
nop = nil
|
|
|
|
if (exploit.datastore['PAYLOAD'])
|
|
payload = $framework.payloads.create(exploit.datastore['PAYLOAD'])
|
|
if (payload != nil)
|
|
payload.datastore.import_options_from_s(ARGV.join('_|_'), '_|_')
|
|
end
|
|
end
|
|
|
|
if (exploit.datastore['ENCODER'])
|
|
encoder = $framework.encoders.create(exploit.datastore['ENCODER'])
|
|
if (encoder != nil)
|
|
encoder.datastore.import_options_from_s(ARGV.join('_|_'), '_|_')
|
|
end
|
|
end
|
|
|
|
if (exploit.datastore['NOP'])
|
|
nop = $framework.nops.create(exploit.datastore['NOP'])
|
|
if (nop != nil)
|
|
nop.datastore.import_options_from_s(ARGV.join('_|_'), '_|_')
|
|
end
|
|
end
|
|
|
|
case mode.downcase
|
|
when 'h'
|
|
usage
|
|
when "s"
|
|
$stdout.puts("\n" + Msf::Serializer::ReadableText.dump_module(exploit, Indent))
|
|
$stdout.puts("\n" + Msf::Serializer::ReadableText.dump_module(payload, Indent)) if payload
|
|
$stdout.puts("\n" + Msf::Serializer::ReadableText.dump_module(encoder, Indent)) if encoder
|
|
$stdout.puts("\n" + Msf::Serializer::ReadableText.dump_module(nop, Indent)) if nop
|
|
|
|
when "o"
|
|
$stdout.puts("\n" + Msf::Serializer::ReadableText.dump_options(exploit, Indent))
|
|
$stdout.puts("\n" + Msf::Serializer::ReadableText.dump_options(payload, Indent)) if payload
|
|
$stdout.puts("\n" + Msf::Serializer::ReadableText.dump_options(encoder, Indent)) if encoder
|
|
$stdout.puts("\n" + Msf::Serializer::ReadableText.dump_options(nop, Indent)) if nop
|
|
when "a"
|
|
$stdout.puts("\n" + Msf::Serializer::ReadableText.dump_advanced_options(exploit, Indent))
|
|
$stdout.puts("\n" + Msf::Serializer::ReadableText.dump_advanced_options(payload, Indent)) if payload
|
|
$stdout.puts("\n" + Msf::Serializer::ReadableText.dump_advanced_options(encoder, Indent)) if encoder
|
|
$stdout.puts("\n" + Msf::Serializer::ReadableText.dump_advanced_options(nop, Indent)) if nop
|
|
when "i"
|
|
$stdout.puts("\n" + Msf::Serializer::ReadableText.dump_evasion_options(exploit, Indent))
|
|
$stdout.puts("\n" + Msf::Serializer::ReadableText.dump_evasion_options(payload, Indent)) if payload
|
|
$stdout.puts("\n" + Msf::Serializer::ReadableText.dump_evasion_options(encoder, Indent)) if encoder
|
|
$stdout.puts("\n" + Msf::Serializer::ReadableText.dump_evasion_options(nop, Indent)) if nop
|
|
when "p"
|
|
if (module_class == 'exploit')
|
|
$stdout.puts("\n" + Msf::Serializer::ReadableText.dump_compatible_payloads(exploit, Indent, "Compatible payloads"))
|
|
else
|
|
$stdout.puts("\nError: This type of module does not support payloads")
|
|
end
|
|
when "t"
|
|
if (module_class == 'exploit')
|
|
$stdout.puts("\n" + Msf::Serializer::ReadableText.dump_exploit_targets(exploit, Indent))
|
|
else
|
|
$stdout.puts("\nError: This type of module does not support targets")
|
|
end
|
|
when "ac"
|
|
if (module_class == 'auxiliary')
|
|
$stdout.puts("\n" + Msf::Serializer::ReadableText.dump_auxiliary_actions(exploit, Indent))
|
|
else
|
|
$stdout.puts("\nError: This type of module does not support actions")
|
|
end
|
|
when "c"
|
|
if (module_class == 'exploit')
|
|
begin
|
|
if (code = exploit.check_simple(
|
|
'LocalInput' => Rex::Ui::Text::Input::Stdio.new,
|
|
'LocalOutput' => Rex::Ui::Text::Output::Stdio.new))
|
|
stat = (code == Msf::Exploit::CheckCode::Vulnerable) ? '[+]' : '[*]'
|
|
|
|
$stdout.puts("#{stat} #{code[1]}")
|
|
else
|
|
$stderr.puts("Check failed: The state could not be determined.")
|
|
end
|
|
rescue
|
|
$stderr.puts("Check failed: #{$!}")
|
|
end
|
|
else
|
|
$stdout.puts("\nError: This type of module does not support the check feature")
|
|
end
|
|
when "e"
|
|
con = Msf::Ui::Console::Driver.new(
|
|
Msf::Ui::Console::Driver::DefaultPrompt,
|
|
Msf::Ui::Console::Driver::DefaultPromptChar,
|
|
{
|
|
'Framework' => $framework
|
|
}
|
|
)
|
|
con.run_single("use #{module_class}/#{exploit.refname}")
|
|
|
|
ARGV.each do |arg|
|
|
k,v = arg.split("=", 2)
|
|
con.run_single("set #{k} #{v}")
|
|
end
|
|
|
|
con.run_single("exploit")
|
|
|
|
# If we have sessions or jobs, keep running
|
|
if $framework.sessions.length > 0 or $framework.jobs.length > 0
|
|
con.run
|
|
else
|
|
con.run_single("quit")
|
|
end
|
|
|
|
else
|
|
usage("Invalid mode #{mode}")
|
|
end
|
|
|
|
$stdout.puts
|