9aaf6af072
Solves #6525 on Vista+. Win2k still works using the old MIB method (which doesn't support ipv6). Win2k3 and XP are still busted for unknown reasons.
178 lines
4.0 KiB
Ruby
178 lines
4.0 KiB
Ruby
#!/usr/bin/env ruby
|
|
|
|
require 'rex/post/meterpreter/extensions/stdapi/tlv'
|
|
require 'rex/post/meterpreter/extensions/stdapi/net/route'
|
|
require 'rex/post/meterpreter/extensions/stdapi/net/interface'
|
|
|
|
module Rex
|
|
module Post
|
|
module Meterpreter
|
|
module Extensions
|
|
module Stdapi
|
|
module Net
|
|
|
|
###
|
|
#
|
|
# This class provides an interface to the network configuration
|
|
# that exists on the remote machine, such as interfaces, and
|
|
# routes.
|
|
#
|
|
###
|
|
class Config
|
|
|
|
##
|
|
#
|
|
# Constructor
|
|
#
|
|
##
|
|
|
|
#
|
|
# Initializes a Config instance that is used to get information about the
|
|
# network configuration of the remote machine.
|
|
#
|
|
def initialize(client)
|
|
self.client = client
|
|
end
|
|
|
|
##
|
|
#
|
|
# Interfaces
|
|
#
|
|
##
|
|
|
|
#
|
|
# Enumerates each interface.
|
|
#
|
|
def each_interface(&block)
|
|
get_interfaces().each(&block)
|
|
end
|
|
|
|
#
|
|
# Returns an array of network interfaces with each element.
|
|
#
|
|
# being an Interface
|
|
def get_interfaces
|
|
request = Packet.create_request('stdapi_net_config_get_interfaces')
|
|
ifaces = []
|
|
|
|
response = client.send_request(request)
|
|
|
|
response.each(TLV_TYPE_NETWORK_INTERFACE) { |iface|
|
|
addrs = []
|
|
netmasks = []
|
|
scopes = []
|
|
while (a = iface.get_tlv_value(TLV_TYPE_IP, addrs.length))
|
|
# Netmasks aren't tightly associated with addresses, they're
|
|
# just thrown all together in the interface TLV ordered to
|
|
# match up. This could be done better by creating another
|
|
# GroupTlv type for addresses containing an address, a netmask,
|
|
# and possibly a scope.
|
|
n = iface.get_tlv_value(TLV_TYPE_NETMASK, addrs.length)
|
|
if (n.nil?)
|
|
# Some systems can't report a netmask, only a network
|
|
# prefix, so figure out the netmask from that.
|
|
n = iface.get_tlv_value(TLV_TYPE_IP_PREFIX, addrs.length)
|
|
if n
|
|
n = Rex::Socket.bit2netmask(n, !!(a.length == 16))
|
|
end
|
|
else
|
|
n = Rex::Socket.addr_ntoa(n)
|
|
end
|
|
s = iface.get_tlv_value(TLV_TYPE_IP6_SCOPE, addrs.length)
|
|
scopes[addrs.length] = s if s
|
|
netmasks[addrs.length] = n if n
|
|
addrs << Rex::Socket.addr_ntoa(a)
|
|
end
|
|
ifaces << Interface.new(
|
|
:index => iface.get_tlv_value(TLV_TYPE_INTERFACE_INDEX),
|
|
:mac_addr => iface.get_tlv_value(TLV_TYPE_MAC_ADDRESS),
|
|
:mac_name => iface.get_tlv_value(TLV_TYPE_MAC_NAME),
|
|
:mtu => iface.get_tlv_value(TLV_TYPE_INTERFACE_MTU),
|
|
:flags => iface.get_tlv_value(TLV_TYPE_INTERFACE_FLAGS),
|
|
:addrs => addrs,
|
|
:netmasks => netmasks,
|
|
:scopes => scopes
|
|
)
|
|
}
|
|
|
|
return ifaces
|
|
end
|
|
|
|
alias interfaces get_interfaces
|
|
|
|
##
|
|
#
|
|
# Routing
|
|
#
|
|
##
|
|
|
|
#
|
|
# Enumerates each route.
|
|
#
|
|
def each_route(&block)
|
|
get_routes().each(&block)
|
|
end
|
|
|
|
#
|
|
# Returns an array of routes with each element being a Route.
|
|
#
|
|
def get_routes
|
|
request = Packet.create_request('stdapi_net_config_get_routes')
|
|
routes = []
|
|
|
|
response = client.send_request(request)
|
|
|
|
# Build out the array of routes
|
|
# Note: This will include both IPv4 and IPv6 routes
|
|
response.each(TLV_TYPE_NETWORK_ROUTE) { |route|
|
|
routes << Route.new(
|
|
route.get_tlv_value(TLV_TYPE_SUBNET),
|
|
route.get_tlv_value(TLV_TYPE_NETMASK),
|
|
route.get_tlv_value(TLV_TYPE_GATEWAY),
|
|
route.get_tlv_value(TLV_TYPE_STRING),
|
|
route.get_tlv_value(TLV_TYPE_ROUTE_METRIC))
|
|
}
|
|
|
|
return routes
|
|
end
|
|
|
|
alias routes get_routes
|
|
|
|
#
|
|
# Adds a route to the target machine.
|
|
#
|
|
def add_route(subnet, netmask, gateway)
|
|
request = Packet.create_request('stdapi_net_config_add_route')
|
|
|
|
request.add_tlv(TLV_TYPE_SUBNET_STRING, subnet)
|
|
request.add_tlv(TLV_TYPE_NETMASK_STRING, netmask)
|
|
request.add_tlv(TLV_TYPE_GATEWAY_STRING, gateway)
|
|
|
|
response = client.send_request(request)
|
|
|
|
return true
|
|
end
|
|
|
|
#
|
|
# Removes a route from the target machine.
|
|
#
|
|
def remove_route(subnet, netmask, gateway)
|
|
request = Packet.create_request('stdapi_net_config_remove_route')
|
|
|
|
request.add_tlv(TLV_TYPE_SUBNET_STRING, subnet)
|
|
request.add_tlv(TLV_TYPE_NETMASK_STRING, netmask)
|
|
request.add_tlv(TLV_TYPE_GATEWAY_STRING, gateway)
|
|
|
|
response = client.send_request(request)
|
|
|
|
return true
|
|
end
|
|
|
|
protected
|
|
|
|
attr_accessor :client # :nodoc:
|
|
|
|
end
|
|
|
|
end; end; end; end; end; end
|