metasploit-framework/lib/msf/core/post.rb

180 lines
3.8 KiB
Ruby

require 'msf/core'
require 'msf/core/module'
module Msf
class Post < Msf::Module
include Msf::Auxiliary::Report
include Msf::Module::HasActions
def self.type
MODULE_POST
end
def type
MODULE_POST
end
def initialize(info={})
super
register_options( [
OptInt.new('SESSION', [ true, "The session to run this module on." ])
] , Msf::Post)
# Default stance is active
self.passive = (info['Passive'] and info['Passive'] == true) || false
end
#
# Grabs a session object from the framework or raises OptionValidateError
# if one doesn't exist. Initializes user input and output on the session.
#
def setup
@sysinfo = nil
if not session
raise Msf::OptionValidateError.new(["SESSION"])
end
@session.init_ui(self.user_input, self.user_output)
end
#
# Default cleanup handler does nothing
#
def cleanup
end
#
# Return the associated session or nil if there isn't one
#
def session
# Try the cached one
return @session if @session and not session_changed?
if datastore["SESSION"]
@session = framework.sessions[datastore["SESSION"].to_i]
else
@session = nil
end
@session
end
alias :client :session
#
# Cached sysinfo, returns nil for non-meterpreter sessions
#
def sysinfo
begin
@sysinfo ||= session.sys.config.sysinfo
rescue NoMethodError
@sysinfo = nil
end
@sysinfo
end
#
# Can be overridden by individual modules to add new commands
#
def post_commands
{}
end
def passive?
self.passive
end
#
# Return a (possibly empty) list of all compatible sessions
#
def compatible_sessions
sessions = []
framework.sessions.each do |sid, s|
sessions << sid if session_compatible?(s)
end
sessions
end
#
# Return false if the given session is not compatible with this module
#
# Checks the session's type against this module's
# +module_info["SessionTypes"]+ as well as examining platform
# compatibility. +sess_or_sid+ can be a Session object, Fixnum, or String.
# In the latter cases it sould be a key in in +framework.sessions+.
#
# NOTE: because it errs on the side of compatibility, a true return value
# from this method does not guarantee the module will work with the
# session.
#
def session_compatible?(sess_or_sid)
# Normalize the argument to an actual Session
case sess_or_sid
when ::Fixnum, ::String
s = framework.sessions[sess_or_sid.to_i]
when ::Msf::Session
s = sess_or_sid
end
# Can't do anything without a session
return false if s.nil?
# Can't be compatible if it's the wrong type
if self.module_info["SessionTypes"]
return false unless self.module_info["SessionTypes"].include?(s.type)
end
# Types are okay, check the platform. This is kind of a ghetto
# workaround for session platforms being ad-hoc and Platform being
# inflexible.
if self.platform and self.platform.kind_of?(Msf::Module::PlatformList)
[
# Add as necessary
"win", "linux", "osx"
].each do |name|
if s.platform =~ /#{name}/
p = Msf::Module::PlatformList.transform(name)
return false unless self.platform.supports? p
end
end
elsif self.platform and self.platform.kind_of?(Msf::Module::Platform)
p_klass = Msf::Module::Platform
case s.platform
when /win/
return false unless self.platform.kind_of?(p_klass::Windows)
when /osx/
return false unless self.platform.kind_of?(p_klass::OSX)
when /linux/
return false unless self.platform.kind_of?(p_klass::Linux)
end
end
# If we got here, we haven't found anything that definitely
# disqualifies this session. Assume that means we can use it.
return true
end
#
# True when this module is passive, false when active
#
attr_reader :passive
protected
attr_writer :passive
def session_changed?
@ds_session ||= datastore["SESSION"]
if (@ds_session != datastore["SESSION"])
@ds_session = nil
return true
else
return false
end
end
end
end