Adding an autoroute meterpreter script, and enabling route housekeeping to be stored and retrived via Sessions directly, rather than through Rex::Socket::SwitchBoard.
git-svn-id: file:///home/svn/framework3/trunk@9663 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
07ef50e4e1
commit
01139ed655
|
@ -22,7 +22,8 @@ class Session < Base
|
||||||
'target_host' => s.target_host.to_s,
|
'target_host' => s.target_host.to_s,
|
||||||
'username' => s.username.to_s,
|
'username' => s.username.to_s,
|
||||||
'uuid' => s.uuid.to_s,
|
'uuid' => s.uuid.to_s,
|
||||||
'exploit_uuid' => s.exploit_uuid.to_s
|
'exploit_uuid' => s.exploit_uuid.to_s,
|
||||||
|
'routes' => s.routes.join(",")
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
res
|
res
|
||||||
|
|
|
@ -79,6 +79,7 @@ module Session
|
||||||
def initialize
|
def initialize
|
||||||
self.alive = true
|
self.alive = true
|
||||||
self.uuid = Rex::Text.rand_text_alphanumeric(8).downcase
|
self.uuid = Rex::Text.rand_text_alphanumeric(8).downcase
|
||||||
|
self.routes = []
|
||||||
end
|
end
|
||||||
|
|
||||||
# Direct descendents
|
# Direct descendents
|
||||||
|
@ -306,6 +307,10 @@ module Session
|
||||||
# The associated username
|
# The associated username
|
||||||
#
|
#
|
||||||
attr_accessor :username
|
attr_accessor :username
|
||||||
|
#
|
||||||
|
# An array of routes associated with this session
|
||||||
|
#
|
||||||
|
attr_accessor :routes
|
||||||
protected
|
protected
|
||||||
|
|
||||||
attr_accessor :via # :nodoc:
|
attr_accessor :via # :nodoc:
|
||||||
|
|
|
@ -74,7 +74,10 @@ class SwitchBoard
|
||||||
# instance.
|
# instance.
|
||||||
#
|
#
|
||||||
def self.add_route(subnet, mask, comm)
|
def self.add_route(subnet, mask, comm)
|
||||||
self.instance.add_route(subnet, mask, comm)
|
ret = self.instance.add_route(subnet, mask, comm)
|
||||||
|
if ret && comm.respond_to?(:routes) && comm.routes.kind_of?(Array)
|
||||||
|
comm.routes << "#{subnet}/#{mask}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -82,14 +85,20 @@ class SwitchBoard
|
||||||
# subnet routing through the supplied Comm instance.
|
# subnet routing through the supplied Comm instance.
|
||||||
#
|
#
|
||||||
def self.remove_route(subnet, mask, comm)
|
def self.remove_route(subnet, mask, comm)
|
||||||
self.instance.remove_route(subnet, mask, comm)
|
ret = self.instance.remove_route(subnet, mask, comm)
|
||||||
|
if ret && comm.respond_to?(:routes) && comm.routes.kind_of?(Array)
|
||||||
|
comm.routes.delete "#{subnet}/#{mask}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Flush all the routes from the switch board routing table.
|
# Flush all the routes from the switch board routing table.
|
||||||
#
|
#
|
||||||
def self.flush_routes
|
def self.flush_routes
|
||||||
self.instance.flush_routes
|
ret = self.instance.flush_routes
|
||||||
|
if ret && comm.respond_to?(:routes) && comm.routes.kind_of?(Array)
|
||||||
|
comm.routes.clear
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
# $Id$
|
||||||
|
|
||||||
|
#
|
||||||
|
# Meterpreter script for setting up a route from within a
|
||||||
|
# Meterpreter session, without having to background the
|
||||||
|
# current session.
|
||||||
|
|
||||||
|
# Default options
|
||||||
|
session = client
|
||||||
|
subnet = nil
|
||||||
|
netmask = "255.255.255.0"
|
||||||
|
print_only = false
|
||||||
|
remove_route = false
|
||||||
|
|
||||||
|
# Options parsing
|
||||||
|
@@exec_opts = Rex::Parser::Arguments.new(
|
||||||
|
"-h" => [false, "Help and usage"],
|
||||||
|
"-s" => [true, "Subnet (IPv4, for example, 10.10.10.0)"],
|
||||||
|
"-n" => [true, "Netmask (IPv4, for example, 255.255.255.0"],
|
||||||
|
"-p" => [false, "Print active routing table. All other options are ignored"],
|
||||||
|
"-d" => [false, "Delete the named route instead of adding it"],
|
||||||
|
)
|
||||||
|
|
||||||
|
@@exec_opts.parse(args) { |opt, idx, val|
|
||||||
|
v = val.to_s.strip
|
||||||
|
case opt
|
||||||
|
when "-h"
|
||||||
|
usage
|
||||||
|
return false
|
||||||
|
when "-s"
|
||||||
|
subnet = v
|
||||||
|
when "-n"
|
||||||
|
netmask = v
|
||||||
|
when "-p"
|
||||||
|
print_only = true
|
||||||
|
when "-d"
|
||||||
|
remove_route = true
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
# Identical functionality to command_dispatcher/core.rb, and
|
||||||
|
# nearly identical code
|
||||||
|
def print_routes
|
||||||
|
tbl = Msf::Ui::Console::Table.new(
|
||||||
|
Msf::Ui::Console::Table::Style::Default,
|
||||||
|
'Header' => "Active Routing Table",
|
||||||
|
'Prefix' => "\n",
|
||||||
|
'Postfix' => "\n",
|
||||||
|
'Columns' =>
|
||||||
|
[
|
||||||
|
'Subnet',
|
||||||
|
'Netmask',
|
||||||
|
'Gateway',
|
||||||
|
],
|
||||||
|
'ColProps' =>
|
||||||
|
{
|
||||||
|
'Subnet' => { 'MaxWidth' => 17 },
|
||||||
|
'Netmask' => { 'MaxWidth' => 17 },
|
||||||
|
})
|
||||||
|
ret = []
|
||||||
|
|
||||||
|
Rex::Socket::SwitchBoard.each { |route|
|
||||||
|
|
||||||
|
if (route.comm.kind_of?(Msf::Session))
|
||||||
|
gw = "Session #{route.comm.sid}"
|
||||||
|
else
|
||||||
|
gw = route.comm.name.split(/::/)[-1]
|
||||||
|
end
|
||||||
|
|
||||||
|
tbl << [ route.subnet, route.netmask, gw ]
|
||||||
|
}
|
||||||
|
if Rex::Socket::SwitchBoard.routes.size > 0
|
||||||
|
print tbl.to_s
|
||||||
|
return Rex::Socket::SwitchBoard.routes
|
||||||
|
else
|
||||||
|
print_status "No routes have been added yet"
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Yet another IP validator. I'm sure there's some Rex
|
||||||
|
# function that can just do this.
|
||||||
|
def check_ip(ip=nil)
|
||||||
|
return false if(ip.nil? || ip.strip.empty?)
|
||||||
|
begin
|
||||||
|
rw = Rex::Socket::RangeWalker.new(ip.strip)
|
||||||
|
(rw.valid? && rw.length == 1) ? true : false
|
||||||
|
rescue
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Adds a route to the framework instance
|
||||||
|
def add_route(opts={})
|
||||||
|
subnet = opts[:subnet]
|
||||||
|
netmask = opts[:netmask] || "255.255.255.0" # Default class C
|
||||||
|
Rex::Socket::SwitchBoard.add_route(subnet, netmask, session)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Removes a route to the framework instance
|
||||||
|
def delete_route(opts={})
|
||||||
|
subnet = opts[:subnet]
|
||||||
|
netmask = opts[:netmask] || "255.255.255.0" # Default class C
|
||||||
|
Rex::Socket::SwitchBoard.remove_route(subnet, netmask, session)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# Defines usage
|
||||||
|
def usage()
|
||||||
|
print_status "Usage: run autoroute [-r] -s subnet -n netmask"
|
||||||
|
print_status "Examples:"
|
||||||
|
print_status " run autoroute -s 10.1.1.0 -n 255.255.255.0 # Add a route to 10.10.10.1/255.255.255.0"
|
||||||
|
print_status " run autoroute -s 10.10.10.1 # Netmask defaults to 255.255.255.0"
|
||||||
|
print_status " run autoroute -p # Print active routing table"
|
||||||
|
print_status " run autoroute -d -s 10.10.10.1 # Deletes the 10.10.10.1/255.255.255.0 route"
|
||||||
|
print_status "Use the \"route\" and \"ipconfig\" Meterpreter commands to learn about available routes"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Validates the command options
|
||||||
|
def validate_cmd(subnet=nil,netmask=nil)
|
||||||
|
if subnet.nil?
|
||||||
|
print_error "Missing -s (subnet) option"
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
unless(check_ip(subnet))
|
||||||
|
print_error "Subnet invalid"
|
||||||
|
usage
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if(netmask and !check_ip(netmask))
|
||||||
|
print_error "Netmask invalid"
|
||||||
|
return usage
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
if print_only
|
||||||
|
return print_routes
|
||||||
|
end
|
||||||
|
|
||||||
|
return false unless validate_cmd(subnet,netmask)
|
||||||
|
|
||||||
|
if remove_route
|
||||||
|
print_status("Deleting route to %s/%s..." % [subnet,netmask])
|
||||||
|
route_result = delete_route(:subnet => subnet, :netmask => netmask)
|
||||||
|
else
|
||||||
|
print_status("Adding a route to %s/%s..." % [subnet,netmask])
|
||||||
|
route_result = add_route(:subnet => subnet, :netmask => netmask)
|
||||||
|
end
|
||||||
|
|
||||||
|
if route_result
|
||||||
|
print_good "%s route to %s/%s via %s" % [
|
||||||
|
(remove_route ? "Deleted" : "Added"),
|
||||||
|
subnet,netmask,client.sock.peerhost
|
||||||
|
]
|
||||||
|
else
|
||||||
|
print_error "Could not %s route" % [(remove_route ? "delete" : "add")]
|
||||||
|
end
|
||||||
|
|
||||||
|
if Rex::Socket::SwitchBoard.routes.size > 0
|
||||||
|
print_status "Use the -p option to list all active routes"
|
||||||
|
end
|
||||||
|
|
||||||
|
return [subnet,netmask,session]
|
Loading…
Reference in New Issue