metasploit-framework/lib/rex/post/meterpreter/client.rb

138 lines
3.2 KiB
Ruby
Raw Normal View History

#!/usr/bin/ruby
require 'socket'
require 'Rex/Post/Meterpreter/ClientCore'
require 'Rex/Post/Meterpreter/Channel'
require 'Rex/Post/Meterpreter/ChannelContainer'
require 'Rex/Post/Meterpreter/Dependencies'
require 'Rex/Post/Meterpreter/ObjectAliases'
require 'Rex/Post/Meterpreter/Packet'
require 'Rex/Post/Meterpreter/PacketParser'
require 'Rex/Post/Meterpreter/PacketDispatcher'
module Rex
module Post
module Meterpreter
###
#
# Client
# ------
#
# The logical meterpreter client class. This class manages a single session
# with a meterpreter server instance.
#
###
class Client
include Rex::Post::Meterpreter::PacketDispatcher
include Rex::Post::Meterpreter::ChannelContainer
# Initializes the client context with the supplied socket through
# which communication with the server will be performed
def initialize(sock)
self.sock = sock
self.parser = PacketParser.new
self.ext = ObjectAliases.new
self.ext_aliases = ObjectAliases.new
register_extension_alias('core', ClientCore.new(self))
initialize_inbound_handlers
initialize_channels
# Register the channel inbound packet handler
register_inbound_handler(Rex::Post::Meterpreter::Channel)
monitor_socket
end
##
#
# Accessors
#
##
# Returns the default timeout that request packets will use when
# waiting for a response
def Client.default_timeout
return 30
end
##
#
# Alias processor
#
##
# Translates unhandled methods into registered extension aliases
# if a matching extension alias exists for the supplied symbol
def method_missing(symbol, *args)
return self.ext_aliases.aliases[symbol.to_s];
end
##
#
# Extension registration
#
##
# Loads the client half of the supplied extension and initializes it as a
# registered extension that can be reached through client.ext.[extension].
def add_extension(name)
Kernel.require("Rex/Post/Meterpreter/Extensions/#{name}/#{name}")
# XXX might want to be safer and catch the exception here?
# maybe not since we are just going to reraise right away...
ext = Rex::Post::Meterpreter::Extensions.const_get(name).const_get(name).new(self)
self.ext.aliases[ext.name] = ext
return true
end
# Deregisters an extension alias of the supplied name
def deregister_extension(name)
self.ext.aliases.delete(name)
end
# Enumerates all of the loaded extensions
def each_extension(&block)
self.ext.aliases.each(block)
end
# Registers an aliased extension that can be referenced through
# client.name
def register_extension_alias(name, ext)
self.ext_aliases.aliases[name] = ext
end
# Registers zero or more aliases that are provided in an array
def register_extension_aliases(aliases)
aliases.each { |a|
register_extension_alias(a['name'], a['ext'])
}
end
# Deregisters a previously registered extension alias
def deregister_extension_alias(name)
self.ext_aliases.aliases.delete(name)
end
# Dumps the extension tree
def dump_extension_tree()
items = []
items.concat(self.ext.dump_alias_tree('client.ext'))
items.concat(self.ext_aliases.dump_alias_tree('client'))
return items.sort
end
attr_reader :ext, :sock
protected
attr_accessor :parser, :ext_aliases
attr_writer :ext, :sock
end
end; end; end