mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-10-29 18:07:27 +01:00
0035f2ee64
If the user only wants to see help, then no point to load things that will actually never be used by msfcli. Only rex is needed.
263 lines
7.6 KiB
Ruby
Executable File
263 lines
7.6 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 'rex'
|
|
|
|
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()
|
|
else
|
|
$:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB']
|
|
require 'fastlib'
|
|
require 'msfenv'
|
|
require 'msf/ui'
|
|
require 'msf/base'
|
|
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
|
|
begin
|
|
exploit.datastore.import_options_from_s(ARGV.join('_|_'), '_|_')
|
|
rescue Rex::ArgumentParseError => e
|
|
puts "[!] Error: #{e.message}\n\n"
|
|
exit
|
|
end
|
|
|
|
# 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("\nPayload:\n\n" + Msf::Serializer::ReadableText.dump_options(payload, Indent)) if payload
|
|
$stdout.puts("\nEncoder:\n\n" + Msf::Serializer::ReadableText.dump_options(encoder, Indent)) if encoder
|
|
$stdout.puts("\nNOP\n\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("\nPayload:\n\n" + Msf::Serializer::ReadableText.dump_advanced_options(payload, Indent)) if payload
|
|
$stdout.puts("\nEncoder:\n\n" + Msf::Serializer::ReadableText.dump_advanced_options(encoder, Indent)) if encoder
|
|
$stdout.puts("\nNOP:\n\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("\nPayload:\n\n" + Msf::Serializer::ReadableText.dump_evasion_options(payload, Indent)) if payload
|
|
$stdout.puts("\nEncoder:\n\n" + Msf::Serializer::ReadableText.dump_evasion_options(encoder, Indent)) if encoder
|
|
$stdout.puts("\nNOP:\n\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
|