Tab completion is about 90% done :-)
git-svn-id: file:///home/svn/incoming/trunk@3062 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
cad67cec49
commit
2f0b44adf6
|
@ -153,6 +153,14 @@ class Core
|
|||
end
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Tab completion for the info command (same as use)
|
||||
#
|
||||
def cmd_info_tabs(str, words)
|
||||
cmd_use_tabs(str, words)
|
||||
end
|
||||
|
||||
|
||||
alias cmd_? cmd_help
|
||||
|
||||
|
@ -187,7 +195,19 @@ class Core
|
|||
end
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Tab completion for the jobs command
|
||||
#
|
||||
def cmd_jobs_tabs(str, words)
|
||||
if(not words[1])
|
||||
return %w{-l -k -h}
|
||||
end
|
||||
if (words[1] == '-k')
|
||||
# XXX return the list of job values
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Loads a plugin from the supplied path. If no absolute path is supplied,
|
||||
# the framework root plugin directory is used.
|
||||
|
@ -216,6 +236,23 @@ class Core
|
|||
print_error("Failed to load plugin from #{arg[0]}")
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Tab completion for the load command
|
||||
#
|
||||
def cmd_load_tabs(str, words)
|
||||
if(not words[1] or not words[1].match(/^\//))
|
||||
begin
|
||||
return Dir.new(Msf::Config.plugin_directory).find_all { |e|
|
||||
path = Msf::Config.plugin_directory + File::SEPARATOR + e
|
||||
File.file?(path) and File.readable?(path)
|
||||
}.map { |e|
|
||||
e.sub!(/\.rb$/, '')
|
||||
}
|
||||
rescue Exception
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# This method persists or restores framework state from a persistent
|
||||
|
@ -261,6 +298,15 @@ class Core
|
|||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Tab completion for the persist command
|
||||
#
|
||||
def cmd_persist_tabs(str, words)
|
||||
if (not words[1])
|
||||
return %w{-s -r -h}
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# This method handles the route command which allows a user to specify
|
||||
# which session a given subnet should route through.
|
||||
|
@ -383,6 +429,15 @@ class Core
|
|||
print(tbl.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Tab completion for the route command
|
||||
#
|
||||
def cmd_route_tabs(str, words)
|
||||
if (not words[1])
|
||||
return %w{add remove get flush print}
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Saves the active datastore contents to disk for automatic use across
|
||||
|
@ -446,8 +501,6 @@ class Core
|
|||
}
|
||||
|
||||
print(added)
|
||||
|
||||
recalculate_tab_complete
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -523,6 +576,15 @@ class Core
|
|||
return true
|
||||
end
|
||||
|
||||
#
|
||||
# Tab completion for the route command
|
||||
#
|
||||
def cmd_session_tabs(str, words)
|
||||
if (not words[1])
|
||||
return %w{-q -i -l -h}
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Sets a name to a value in a context aware environment.
|
||||
#
|
||||
|
@ -582,6 +644,47 @@ class Core
|
|||
print_line("#{name} => #{value}")
|
||||
end
|
||||
|
||||
#
|
||||
# Tab completion for the set command
|
||||
#
|
||||
def cmd_set_tabs(str, words)
|
||||
|
||||
# A value has already been specified
|
||||
if (words[2])
|
||||
return nil
|
||||
end
|
||||
|
||||
# A value needs to be specified
|
||||
if(words[1])
|
||||
return tab_complete_option(words[1])
|
||||
end
|
||||
|
||||
res = cmd_unset_tabs(str, words) || [ ]
|
||||
mod = active_module
|
||||
|
||||
if (not mod)
|
||||
return res
|
||||
end
|
||||
|
||||
mod.options.sorted.each { |e|
|
||||
name, opt = e
|
||||
res << name
|
||||
}
|
||||
|
||||
if (mod.exploit? and mod.datastore['PAYLOAD'])
|
||||
p = framework.modules.create(mod.datastore['PAYLOAD'])
|
||||
if (p)
|
||||
p.options.sorted.each { |e|
|
||||
name, opt = e
|
||||
res << name
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Sets the supplied variables in the global datastore.
|
||||
#
|
||||
|
@ -590,7 +693,14 @@ class Core
|
|||
|
||||
cmd_set(*args)
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Tab completion for the setg command
|
||||
#
|
||||
def cmd_setg_tabs(str, words)
|
||||
res = cmd_set_tabs(str, words) || [ ]
|
||||
end
|
||||
|
||||
#
|
||||
# Displays the list of modules based on their type, or all modules if
|
||||
# no type is provided.
|
||||
|
@ -829,13 +939,6 @@ class Core
|
|||
return true
|
||||
end
|
||||
|
||||
#
|
||||
# Internal routine to recalculate tab complete.
|
||||
#
|
||||
def cmd__recalculate_tc(*args)
|
||||
recalculate_tab_complete
|
||||
end
|
||||
|
||||
#
|
||||
# Provide command-specific tab completion
|
||||
#
|
||||
|
@ -856,16 +959,115 @@ class Core
|
|||
|
||||
return items
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
#
|
||||
# Recalculates the tab completion list.
|
||||
# Provide tab completion for option values
|
||||
#
|
||||
def recalculate_tab_complete
|
||||
self.tab_complete_items = []
|
||||
# wont be needed much longer
|
||||
def tab_complete_option(opt)
|
||||
res = []
|
||||
mod = active_module
|
||||
|
||||
# With no active module, we have nothing to compare
|
||||
if (not mod)
|
||||
return res
|
||||
end
|
||||
|
||||
# Well-known option names specific to exploits
|
||||
if (mod.exploit?)
|
||||
return option_values_payloads() if opt == 'PAYLOAD'
|
||||
return option_values_targets() if opt == 'TARGET'
|
||||
return option_values_nops() if opt == 'NOPS'
|
||||
end
|
||||
|
||||
# The ENCODER option works for payloads and exploits
|
||||
if ((mod.exploit? or mod.payload?) and opt == 'ENCODER')
|
||||
return option_values_encoders()
|
||||
end
|
||||
|
||||
# Is this option used by the active module?
|
||||
if (mod.options.include?(opt))
|
||||
res.concat(option_values_dispatch(mod.options[opt]))
|
||||
end
|
||||
|
||||
# How about the selected payload?
|
||||
if (mod.exploit? and mod.datastore['PAYLOAD'])
|
||||
p = framework.modules.create(mod.datastore['PAYLOAD'])
|
||||
if (p and p.options.include?(opt))
|
||||
res.concat(option_values_dispatch(p.options[opt]))
|
||||
end
|
||||
end
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
#
|
||||
# Provide possible option values based on type
|
||||
#
|
||||
def option_values_dispatch(o)
|
||||
res = []
|
||||
res << o.default.to_s if o.default
|
||||
|
||||
case o.class.to_s
|
||||
|
||||
when 'Msf::OptAddress'
|
||||
case o.name
|
||||
when 'RHOST'
|
||||
res << option_values_last_target()
|
||||
when 'LHOST'
|
||||
res << Rex::Socket.source_address()
|
||||
else
|
||||
end
|
||||
|
||||
when 'Msf::OptPort'
|
||||
if (res.empty?)
|
||||
res << (rand(65534)+1).to_S
|
||||
end
|
||||
end
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
#
|
||||
# Provide valid payload options for the current exploit
|
||||
#
|
||||
def option_values_payloads
|
||||
active_module.compatible_payloads.map { |refname, payload| refname }
|
||||
end
|
||||
|
||||
#
|
||||
# Provide valid target options for the current exploit
|
||||
#
|
||||
def option_values_targets
|
||||
res = []
|
||||
if (active_module.targets)
|
||||
1.upto(active_module.targets.length) { |i| res << (i-1).to_s }
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
#
|
||||
# Provide valid nops options for the current exploit
|
||||
#
|
||||
def option_values_nops
|
||||
framework.nops.map { |refname, mod| refname }
|
||||
end
|
||||
|
||||
#
|
||||
# Provide valid encoders options for the current exploit or payload
|
||||
#
|
||||
def option_values_encoders
|
||||
framework.encoders.map { |refname, mod| refname }
|
||||
end
|
||||
|
||||
#
|
||||
# Provide the last target address
|
||||
#
|
||||
def option_values_last_target
|
||||
# Replace this once we start tracking these things...
|
||||
return Rex::Socket.source_address()
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
#
|
||||
# Module list enumeration
|
||||
|
|
|
@ -145,9 +145,6 @@ class Driver < Msf::Ui::Driver
|
|||
# displayed, scripts can be processed, and other fun can be had.
|
||||
#
|
||||
def on_startup
|
||||
# Recalculate tab completion
|
||||
run_single("_recalculate_tc")
|
||||
|
||||
# Build the banner message
|
||||
run_single("banner")
|
||||
end
|
||||
|
@ -278,7 +275,7 @@ protected
|
|||
str_trail = (str_match.nil?) ? '' : str_match[0]
|
||||
|
||||
# Split the line up by whitespace into words
|
||||
str_words = str.split(/[\s\t\n]/)
|
||||
str_words = str.split(/[\s\t\n]+/)
|
||||
|
||||
# Append an empty word if we had trailing whitespace
|
||||
str_words << '' if str_trail.length > 0
|
||||
|
|
|
@ -139,6 +139,20 @@ module Socket
|
|||
[ (~((2 ** (32 - bitmask)) - 1)) & 0xffffffff ].pack('N').unpack('CCCC').join('.')
|
||||
end
|
||||
|
||||
##
|
||||
#
|
||||
# Utility class methods
|
||||
#
|
||||
##
|
||||
|
||||
def self.source_address(dest='1.2.3.4')
|
||||
self.create_udp(
|
||||
'PeerHost' => dest,
|
||||
'PeerPort' => 31337
|
||||
).getsockname[1]
|
||||
end
|
||||
|
||||
|
||||
##
|
||||
#
|
||||
# Class initialization
|
||||
|
|
Loading…
Reference in New Issue