62413df04f
Avoid catching all exceptions, that way we don't actually shut up other possible errors that are actually bugs.
265 lines
7.5 KiB
Ruby
Executable File
265 lines
7.5 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
|
|
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("\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
|