Multi Manage Network Route via Meterpreter Session - Metasploit


This page contains detailed information about how to use the post/multi/manage/autoroute metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.

Module Overview


Name: Multi Manage Network Route via Meterpreter Session
Module: post/multi/manage/autoroute
Source code: modules/post/multi/manage/autoroute.rb
Disclosure date: -
Last modification time: 2021-10-06 13:43:31 +0000
Supported architecture(s): -
Supported platform(s): -
Target service / protocol: -
Target network port(s): -
List of CVEs: -

This module manages session routing via an existing Meterpreter session. It enables other modules to 'pivot' through a compromised host when connecting to the named NETWORK and SUBMASK. Autoadd will search a session for valid subnets from the routing table and interface list then add routes to them. Default will add a default route so that all TCP/IP traffic not specified in the MSF routing table will be routed through the session when pivoting. See documentation for more 'info -d' and click 'Knowledge Base'

Module Ranking and Traits


Module Ranking:

  • normal: The exploit is otherwise reliable, but depends on a specific version and can't (or doesn't) reliably autodetect. More information about ranking can be found here.

Basic Usage


There are two ways to execute this post module.

From the Meterpreter prompt

The first is by using the "run" command at the Meterpreter prompt. It allows you to run the post module against that specific session:

meterpreter > run post/multi/manage/autoroute

From the msf prompt

The second is by using the "use" command at the msf prompt. You will have to figure out which session ID to set manually. To list all session IDs, you can use the "sessions" command.

msf > use post/multi/manage/autoroute
msf post(autoroute) > show options
    ... show and set options ...
msf post(autoroute) > set SESSION session-id
msf post(autoroute) > exploit

If you wish to run the post against all sessions from framework, here is how:

1 - Create the following resource script:


framework.sessions.each_pair do |sid, session|
  run_single("use post/multi/manage/autoroute")
  run_single("set SESSION #{sid}")
  run_single("run")
end

2 - At the msf prompt, execute the above resource script:

msf > resource path-to-resource-script

Required Options


  • SESSION: The session to run this module on.

Knowledge Base


Overview


This module is used to add routes associated with the specified Meterpreter session to Metasploit's routing table. These routes can be used to pivot to private networks and resources that can be accessed by the compromised machine. This module can search for routes and add them automatically. Routes can also be added manually, deleted, or displayed.

CMD Options


This module has several command "CMD" options that are used to control the module's behavior.

autoadd

This is the default behavior for this module. When this CMD option is used, the module searches the compromised machine's routing table and network interface list looking for networks that the machine can access. Once found, the module automatically adds routes to the networks to Metasploit's routing table. Duplicate routes from new sessions are not added.

add

This CMD option is used to manually add routes to Metasploit's routing table. An IPv4 subnet and netmask (IPv4 or CIDR) are required to add routes manually. The session number of the Meterpreter session to run the module on is also required.

Subnet Example set SUBNET 192.168.1.0

Netmask Examples set NETMASK 255.255.255.0 or set NETMASK /24

delete

This CMD option is used to remove a route from Metasploit's routing table. The IPv4 subnet and netmask (IPv4 or CIDR) of the route to be removed are required. The session number of the Meterpreter session to run the module on is also required. Use route print or the print CMD option to display the current Metasploit routing table.

To remove all routes associated with the specified session, use CMD delete and leave the subnet option blank.

print

This CMD option is used to display Metasploit's routing table. This option has the same functionality as the route print command.

default

This CMD option is used to add a default route to Metasploit's routing table that routes all TCP/IP traffic; not otherwise covered in other routes, through the specified session when pivoting.

Use this option with caution.

This option is useful in special situations. An example would be when the compromised host is using a full traffic VPN where the VPN server does the routing to private networks. In this case, the routing table of the compromised host would likely not have entries for these private networks. Adding a default route would push the routing off to the VPN server, and those networks would likely become accessible.

Additionally, the default route combined with a Socks proxy server and Proxychains can be used to browse the Internet as the compromised host. Instructions for this are below.

Pivoting


Once routes are established, Metasploit modules can access the IP range specified in the routes. Scans and exploits can be directed at machines that would otherwise be unreachable from the outside. For other applications to access the routes, a little bit more setup is necessary. This involves setting up the Socks4a Metasploit module and using Proxychains in conjunction with the other applications.

Socks 4a Server Module Setup

Metasploit can launch a Socks 4a Proxy server using the module: auxiliary/server/socks4a. When set up to bind to a local loopback adapter, applications can be directed to use the proxy to route TCP/IP traffic through Metasploit's routing tables. Below are the steps to initiate this module.

use auxiliary/server/socks4a
set SRVHOST 127.0.0.1
set SRVPORT 1080
exploit -j

Proxychains Setup

First, make sure that you have Proxychains.

sudo apt-get update
sudo apt-get install proxychains

Now edit the Proxychains configuration file located at /etc/proxychains.conf. Add the below line to the end of the file to set Proxychains to use the Socks 4a server that you just set up.

socks4 127.0.0.1 1080

Note: If there are other proxy entries in the configuration file, you may need to comment them out as they may interfere with proper routing.

Using Proxychains

Now you can combine Proxychains with other application like Nmap, Nessus, Firefox and more to scan or access machines and resources through the Metasploit routes. All you need to do is call proxychains before the needed application. No need to change the proxy settings in Firefox of Iceweasel.

$ proxychains firefox

Scanning

For scanning with Nmap, Zenmap, Nessus and others, keep in mind that ICMP and UPD traffic cannot tunnel through the proxy. So you cannot perform ping or UDP scans.

For Nmap and Zenmap, the below example shows the commands can be used. It is best to be selective on ports to scan since scanning through the proxy tunnel can be slow.

$ sudo proxychains nmap -n -sT -sV -PN -p 445 10.10.125.0/24

Combined With Default Route

Using the default route option along with the Socks proxy and Proxychains, you can browse the internet as the compromised host. This is possible because adding a default route to a Meterpeter session will cause all TCP/IP traffic; that is not otherwise specified in Metasploit's routing table, to route through that session. This is easy to set up and test.

You need a Windows Meterpreter session on a host that has a different public IP address than your attacking machine.

First set up a default route for the Meterpreter session.

meterpreter > run post/multi/manage/autoroute CMD=default

or

msf > use post/multi/manage/autoroute
msf post(autoroute) > set SESSION session-id
msf post(autoroute) > set CMD default
msf post(autoroute) > exploit

Then open Firefox or Iceweasel without invoking Proxychains.

$ firefox

Go to www.ipchicken.com

This displays your current public IP address. The one that is logged when you visit a website.

Now open Firefox or Iceweasel with Proxychains.

$ proxychains firefox

Go to www.ipchicken.com

Now you will see the public IP address of the compromised host. You are essentially using the compromised host as a proxy to browse the Internet.

This does not guarantee anonymity! Your browser, and its setting may still give you away.

Go back to menu.

Msfconsole Usage


Here is how the multi/manage/autoroute post exploitation module looks in the msfconsole:

msf6 > use post/multi/manage/autoroute

msf6 post(multi/manage/autoroute) > show info

       Name: Multi Manage Network Route via Meterpreter Session
     Module: post/multi/manage/autoroute
   Platform: 
       Arch: 
       Rank: Normal

Provided by:
  todb <[email protected]>
  Josh Hale "sn0wfa11" <[email protected]>

Compatible session types:
  Meterpreter

Basic options:
  Name     Current Setting  Required  Description
  ----     ---------------  --------  -----------
  CMD      autoadd          yes       Specify the autoroute command (Accepted: add, autoadd, print, delete, default)
  NETMASK  255.255.255.0    no        Netmask (IPv4 as "255.255.255.0" or CIDR as "/24"
  SESSION                   yes       The session to run this module on.
  SUBNET                    no        Subnet (IPv4, for example, 10.10.10.0)

Description:
  This module manages session routing via an existing Meterpreter 
  session. It enables other modules to 'pivot' through a compromised 
  host when connecting to the named NETWORK and SUBMASK. Autoadd will 
  search a session for valid subnets from the routing table and 
  interface list then add routes to them. Default will add a default 
  route so that all TCP/IP traffic not specified in the MSF routing 
  table will be routed through the session when pivoting. See 
  documentation for more 'info -d' and click 'Knowledge Base'

Module Options


This is a complete list of options available in the multi/manage/autoroute post exploitation module:

msf6 post(multi/manage/autoroute) > show options

Module options (post/multi/manage/autoroute):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   CMD      autoadd          yes       Specify the autoroute command (Accepted: add, autoadd, print, delete, default)
   NETMASK  255.255.255.0    no        Netmask (IPv4 as "255.255.255.0" or CIDR as "/24"
   SESSION                   yes       The session to run this module on.
   SUBNET                    no        Subnet (IPv4, for example, 10.10.10.0)

Advanced Options


Here is a complete list of advanced options supported by the multi/manage/autoroute post exploitation module:

msf6 post(multi/manage/autoroute) > show advanced

Module advanced options (post/multi/manage/autoroute):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   VERBOSE    false            no        Enable detailed status messages
   WORKSPACE                   no        Specify the workspace for this module

Post Actions


This is a list of all post exploitation actions which the multi/manage/autoroute module can do:

msf6 post(multi/manage/autoroute) > show actions

Post actions:

   Name  Description
   ----  -----------

Evasion Options


Here is the full list of possible evasion options supported by the multi/manage/autoroute post exploitation module in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):

msf6 post(multi/manage/autoroute) > show evasion

Module evasion options:

   Name  Current Setting  Required  Description
   ----  ---------------  --------  -----------

Go back to menu.

Error Messages


This module may fail with the following error messages:

Check for the possible causes from the code snippets below found in the module source code. This can often times help in identifying the root cause of the problem.

No routes associated with this session to delete.


Here is a relevant code snippet related to the "No routes associated with this session to delete." error message:

107:	        end
108:	        break if count == 0
109:	      end
110:	      print_status("Deleted all routes")
111:	    else
112:	      print_status("No routes associated with this session to delete.")
113:	    end
114:	  end
115:	
116:	  # Print all of the active routes defined on the framework
117:	  #

There are currently no routes defined.


Here is a relevant code snippet related to the "There are currently no routes defined." error message:

172:	
173:	    # Print Route Tables
174:	    print_status(tbl_ipv4.to_s) if tbl_ipv4.rows.length > 0
175:	    print_status(tbl_ipv6.to_s) if tbl_ipv6.rows.length > 0
176:	    if (tbl_ipv4.rows.length + tbl_ipv6.rows.length) < 1
177:	      print_status("There are currently no routes defined.")
178:	    elsif (tbl_ipv4.rows.length < 1) && (tbl_ipv6.rows.length > 0)
179:	      print_status("There are currently no IPv4 routes defined.")
180:	    elsif (tbl_ipv4.rows.length > 0) && (tbl_ipv6.rows.length < 1)
181:	      print_status("There are currently no IPv6 routes defined.")
182:	    end

There are currently no IPv4 routes defined.


Here is a relevant code snippet related to the "There are currently no IPv4 routes defined." error message:

174:	    print_status(tbl_ipv4.to_s) if tbl_ipv4.rows.length > 0
175:	    print_status(tbl_ipv6.to_s) if tbl_ipv6.rows.length > 0
176:	    if (tbl_ipv4.rows.length + tbl_ipv6.rows.length) < 1
177:	      print_status("There are currently no routes defined.")
178:	    elsif (tbl_ipv4.rows.length < 1) && (tbl_ipv6.rows.length > 0)
179:	      print_status("There are currently no IPv4 routes defined.")
180:	    elsif (tbl_ipv4.rows.length > 0) && (tbl_ipv6.rows.length < 1)
181:	      print_status("There are currently no IPv6 routes defined.")
182:	    end
183:	  end
184:	

There are currently no IPv6 routes defined.


Here is a relevant code snippet related to the "There are currently no IPv6 routes defined." error message:

176:	    if (tbl_ipv4.rows.length + tbl_ipv6.rows.length) < 1
177:	      print_status("There are currently no routes defined.")
178:	    elsif (tbl_ipv4.rows.length < 1) && (tbl_ipv6.rows.length > 0)
179:	      print_status("There are currently no IPv4 routes defined.")
180:	    elsif (tbl_ipv4.rows.length > 0) && (tbl_ipv6.rows.length < 1)
181:	      print_status("There are currently no IPv6 routes defined.")
182:	    end
183:	  end
184:	
185:	  # Validation check on an IPv4 address
186:	  #

Could not add route to subnet <SUBNET>/<NETMASK><ORIGIN>.


Here is a relevant code snippet related to the "Could not add route to subnet <SUBNET>/<NETMASK><ORIGIN>." error message:

239:	    begin
240:	      if Rex::Socket::SwitchBoard.add_route(subnet, netmask, session)
241:	        print_good("Route added to subnet #{subnet}/#{netmask}#{origin}.")
242:	        return true
243:	      else
244:	        print_error("Could not add route to subnet #{subnet}/#{netmask}#{origin}.")
245:	        return false
246:	      end
247:	    rescue ::Rex::Post::Meterpreter::RequestError => re
248:	      print_error("Could not add route to subnet #{subnet}/#{netmask}#{origin}.")
249:	      print_error("#{re.class} #{re.message}\n#{re.backtrace * "\n"}")

Could not add route to subnet <SUBNET>/<NETMASK><ORIGIN>.


Here is a relevant code snippet related to the "Could not add route to subnet <SUBNET>/<NETMASK><ORIGIN>." error message:

243:	      else
244:	        print_error("Could not add route to subnet #{subnet}/#{netmask}#{origin}.")
245:	        return false
246:	      end
247:	    rescue ::Rex::Post::Meterpreter::RequestError => re
248:	      print_error("Could not add route to subnet #{subnet}/#{netmask}#{origin}.")
249:	      print_error("#{re.class} #{re.message}\n#{re.backtrace * "\n"}")
250:	      return false
251:	    end
252:	  end
253:	

<RE.CLASS> <RE.MESSAGE>n<VALUE>


Here is a relevant code snippet related to the "<RE.CLASS> <RE.MESSAGE>n<VALUE>" error message:

244:	        print_error("Could not add route to subnet #{subnet}/#{netmask}#{origin}.")
245:	        return false
246:	      end
247:	    rescue ::Rex::Post::Meterpreter::RequestError => re
248:	      print_error("Could not add route to subnet #{subnet}/#{netmask}#{origin}.")
249:	      print_error("#{re.class} #{re.message}\n#{re.backtrace * "\n"}")
250:	      return false
251:	    end
252:	  end
253:	
254:	  # This function removes a route to the framework routing table

Could not remove route to subnet <SUBNET>/<NETMASK>


Here is a relevant code snippet related to the "Could not remove route to subnet <SUBNET>/<NETMASK>" error message:

261:	  # @return [false] If not
262:	  def delete_route(subnet, netmask)
263:	    begin
264:	      Rex::Socket::SwitchBoard.remove_route(subnet, netmask, session)
265:	    rescue ::Rex::Post::Meterpreter::RequestError => re
266:	      print_error("Could not remove route to subnet #{subnet}/#{netmask}")
267:	      print_error("#{re.class} #{re.message}\n#{re.backtrace * "\n"}")
268:	      return false
269:	    end
270:	  end
271:	

<RE.CLASS> <RE.MESSAGE>n<VALUE>


Here is a relevant code snippet related to the "<RE.CLASS> <RE.MESSAGE>n<VALUE>" error message:

262:	  def delete_route(subnet, netmask)
263:	    begin
264:	      Rex::Socket::SwitchBoard.remove_route(subnet, netmask, session)
265:	    rescue ::Rex::Post::Meterpreter::RequestError => re
266:	      print_error("Could not remove route to subnet #{subnet}/#{netmask}")
267:	      print_error("#{re.class} #{re.message}\n#{re.backtrace * "\n"}")
268:	      return false
269:	    end
270:	  end
271:	
272:	  # This function will exclude loopback, multicast, and default routes

Unable to get routes from session, trying interface list.


Here is a relevant code snippet related to the "Unable to get routes from session, trying interface list." error message:

308:	        if !Rex::Socket::SwitchBoard.route_exists?(subnet, route.netmask)
309:	          found = true if add_route(subnet, route.netmask, "host's routing table")
310:	        end
311:	      end
312:	    rescue ::Rex::Post::Meterpreter::RequestError => re
313:	      print_status("Unable to get routes from session, trying interface list.")
314:	    end
315:	
316:	    if !autoadd_interface_routes && !found # Check interface list for more possible routes
317:	      print_status("Did not find any new subnets to add.")
318:	    end

Did not find any new subnets to add.


Here is a relevant code snippet related to the "Did not find any new subnets to add." error message:

312:	    rescue ::Rex::Post::Meterpreter::RequestError => re
313:	      print_status("Unable to get routes from session, trying interface list.")
314:	    end
315:	
316:	    if !autoadd_interface_routes && !found # Check interface list for more possible routes
317:	      print_status("Did not find any new subnets to add.")
318:	    end
319:	  end
320:	
321:	  # Look at network interfaces as options for additional routes.
322:	  # If the routes are not already included they will be added.

Unable to get interface information from session.


Here is a relevant code snippet related to the "Unable to get interface information from session." error message:

345:	            end
346:	          end
347:	        end
348:	      end
349:	    rescue ::Rex::Post::Meterpreter::RequestError => error
350:	      print_error("Unable to get interface information from session.")
351:	    end
352:	    return found
353:	  end
354:	
355:	  # Take an IP address and a netmask and return the appropreate subnet "Network"

Session is not yet fully established. Try again in a bit.


Here is a relevant code snippet related to the "Session is not yet fully established. Try again in a bit." error message:

428:	  #
429:	  # @return [true class] Session is good
430:	  # @return [false class] Session is not
431:	  def session_good?
432:	    if !session.info
433:	      print_error("Session is not yet fully established. Try again in a bit.")
434:	      return false
435:	    end
436:	    return true
437:	  end
438:	

Missing subnet option


Here is a relevant code snippet related to the "Missing subnet option" error message:

458:	  #
459:	  # @return [true class] Everything is good
460:	  # @return [false class] Not so much
461:	  def validate_cmd(subnet = nil, netmask = nil)
462:	    if subnet.nil?
463:	      print_error "Missing subnet option"
464:	      return false
465:	    end
466:	
467:	    unless (check_ip(subnet))
468:	      print_error "Subnet invalid (must be IPv4)"

Subnet invalid (must be IPv4)


Here is a relevant code snippet related to the "Subnet invalid (must be IPv4)" error message:

463:	      print_error "Missing subnet option"
464:	      return false
465:	    end
466:	
467:	    unless (check_ip(subnet))
468:	      print_error "Subnet invalid (must be IPv4)"
469:	      return false
470:	    end
471:	
472:	    if (netmask and !(Rex::Socket.addr_atoc(netmask)))
473:	      print_error "Netmask invalid (must define contiguous IP addressing)"

Netmask invalid (must define contiguous IP addressing)


Here is a relevant code snippet related to the "Netmask invalid (must define contiguous IP addressing)" error message:

468:	      print_error "Subnet invalid (must be IPv4)"
469:	      return false
470:	    end
471:	
472:	    if (netmask and !(Rex::Socket.addr_atoc(netmask)))
473:	      print_error "Netmask invalid (must define contiguous IP addressing)"
474:	      return false
475:	    end
476:	
477:	    if (netmask and !check_ip(netmask))
478:	      print_error "Netmask invalid"

Netmask invalid


Here is a relevant code snippet related to the "Netmask invalid" error message:

473:	      print_error "Netmask invalid (must define contiguous IP addressing)"
474:	      return false
475:	    end
476:	
477:	    if (netmask and !check_ip(netmask))
478:	      print_error "Netmask invalid"
479:	      return false
480:	    end
481:	    return true
482:	  end
483:	end

Go back to menu.


Go back to menu.

See Also


Check also the following modules related to this module:

Authors


  • todb
  • Josh Hale "sn0wfa11" <jhale85446[at]gmail.com>

Version


This page has been produced using Metasploit Framework version 6.1.24-dev. For more modules, visit the Metasploit Module Library.

Go back to menu.