Skip to content

Commit 0388c02

Browse files
committed
Land rapid7#7887, Meterpreter script deprecation fixes
2 parents f580627 + b44e7ff commit 0388c02

36 files changed

+6570
-4
lines changed

lib/msf/base/sessions/scriptable.rb

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ def execute_file
5353

5454
#
5555
# Maps legacy Meterpreter script names to replacement post modules
56+
#
5657
def legacy_script_to_post_module(script_name)
5758
{
5859
'autoroute' => 'post/windows/manage/autoroute',
@@ -66,11 +67,11 @@ def legacy_script_to_post_module(script_name)
6667
'enum_shares' => 'post/windows/gather/enum_shares',
6768
'file_collector' => 'post/windows/gather/enum_files',
6869
'get_application_list' => 'post/windows/gather/enum_applications',
69-
'getcountermeasure' => 'post/windows/manage/killav',
7070
'get_filezilla_creds' => 'post/windows/gather/credentials/filezilla_server',
71-
'getgui' => 'post/windows/manage/enable_rdp',
7271
'get_local_subnets' => 'post/windows/manage/autoroute',
7372
'get_valid_community' => 'post/windows/gather/enum_snmp',
73+
'getcountermeasure' => 'post/windows/manage/killav',
74+
'getgui' => 'post/windows/manage/enable_rdp',
7475
'getvncpw' => 'post/windows/gather/credentials/vnc',
7576
'hashdump' => 'post/windows/gather/smart_hashdump',
7677
'hostsedit' => 'post/windows/manage/inject_host',
@@ -83,8 +84,8 @@ def legacy_script_to_post_module(script_name)
8384
'prefetchtool' => 'post/windows/gather/enum_prefetch',
8485
'remotewinenum' => 'post/windows/gather/wmic_command',
8586
'schelevator' => 'exploit/windows/local/ms10_092_schelevator',
86-
'screenspy' => 'post/windows/gather/screen_spy',
8787
'screen_unlock' => 'post/windows/escalate/screen_unlock',
88+
'screenspy' => 'post/windows/gather/screen_spy',
8889
'search_dwld' => 'post/windows/gather/enum_files',
8990
'service_permissions_escalate' => 'exploits/windows/local/service_permissions',
9091
'uploadexec' => 'post/windows/manage/download_exec',
@@ -101,7 +102,12 @@ def legacy_script_to_post_module(script_name)
101102
#
102103
def execute_script(script_name, *args)
103104
post_module = legacy_script_to_post_module(script_name)
104-
script_name = post_module if !post_module.nil?
105+
106+
if post_module
107+
print_warning("Meterpreter scripts are deprecated. Try #{post_module}.")
108+
print_warning("Example: run #{post_module} OPTION=value [...]")
109+
end
110+
105111
mod = framework.modules.create(script_name)
106112
if mod
107113
# Don't report module run events here as it will be taken care of

scripts/meterpreter/autoroute.rb

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
##
2+
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
3+
# If you'd like to improve this script, please try to port it as a post
4+
# module instead. Thank you.
5+
##
6+
7+
8+
#
9+
# Meterpreter script for setting up a route from within a
10+
# Meterpreter session, without having to background the
11+
# current session.
12+
13+
# Default options
14+
session = client
15+
subnet = nil
16+
netmask = "255.255.255.0"
17+
print_only = false
18+
remove_route = false
19+
remove_all_routes = false
20+
21+
# Options parsing
22+
@@exec_opts = Rex::Parser::Arguments.new(
23+
"-h" => [false, "Help and usage"],
24+
"-s" => [true, "Subnet (IPv4, for example, 10.10.10.0)"],
25+
"-n" => [true, "Netmask (IPv4, for example, 255.255.255.0"],
26+
"-p" => [false, "Print active routing table. All other options are ignored"],
27+
"-d" => [false, "Delete the named route instead of adding it"],
28+
"-D" => [false, "Delete all routes (does not require a subnet)"]
29+
)
30+
31+
@@exec_opts.parse(args) { |opt, idx, val|
32+
v = val.to_s.strip
33+
case opt
34+
when "-h"
35+
usage
36+
raise Rex::Script::Completed
37+
when "-s"
38+
if v =~ /[0-9\x2e]+\x2f[0-9]{1,2}/
39+
subnet,cidr = v.split("\x2f")
40+
netmask = Rex::Socket.addr_ctoa(cidr.to_i)
41+
else
42+
subnet = v
43+
end
44+
when "-n"
45+
if (0..32) === v.to_i
46+
netmask = Rex::Socket.addr_ctoa(v.to_i)
47+
else
48+
netmask = v
49+
end
50+
when "-p"
51+
print_only = true
52+
when "-d"
53+
remove_route = true
54+
when "-D"
55+
remove_all_routes = true
56+
end
57+
}
58+
59+
def delete_all_routes
60+
if Rex::Socket::SwitchBoard.routes.size > 0
61+
routes = []
62+
Rex::Socket::SwitchBoard.each do |route|
63+
routes << {:subnet => route.subnet, :netmask => route.netmask}
64+
end
65+
routes.each {|route_opts| delete_route(route_opts)}
66+
67+
print_status "Deleted all routes"
68+
else
69+
print_status "No routes have been added yet"
70+
end
71+
raise Rex::Script::Completed
72+
end
73+
74+
# Identical functionality to command_dispatcher/core.rb, and
75+
# nearly identical code
76+
def print_routes
77+
if Rex::Socket::SwitchBoard.routes.size > 0
78+
tbl = Msf::Ui::Console::Table.new(
79+
Msf::Ui::Console::Table::Style::Default,
80+
'Header' => "Active Routing Table",
81+
'Prefix' => "\n",
82+
'Postfix' => "\n",
83+
'Columns' =>
84+
[
85+
'Subnet',
86+
'Netmask',
87+
'Gateway',
88+
],
89+
'ColProps' =>
90+
{
91+
'Subnet' => { 'MaxWidth' => 17 },
92+
'Netmask' => { 'MaxWidth' => 17 },
93+
})
94+
ret = []
95+
96+
Rex::Socket::SwitchBoard.each { |route|
97+
if (route.comm.kind_of?(Msf::Session))
98+
gw = "Session #{route.comm.sid}"
99+
else
100+
gw = route.comm.name.split(/::/)[-1]
101+
end
102+
tbl << [ route.subnet, route.netmask, gw ]
103+
}
104+
print tbl.to_s
105+
else
106+
print_status "No routes have been added yet"
107+
end
108+
raise Rex::Script::Completed
109+
end
110+
111+
# Yet another IP validator. I'm sure there's some Rex
112+
# function that can just do this.
113+
def check_ip(ip=nil)
114+
return false if(ip.nil? || ip.strip.empty?)
115+
begin
116+
rw = Rex::Socket::RangeWalker.new(ip.strip)
117+
(rw.valid? && rw.length == 1) ? true : false
118+
rescue
119+
false
120+
end
121+
end
122+
123+
# Adds a route to the framework instance
124+
def add_route(opts={})
125+
subnet = opts[:subnet]
126+
netmask = opts[:netmask] || "255.255.255.0" # Default class C
127+
Rex::Socket::SwitchBoard.add_route(subnet, netmask, session)
128+
end
129+
130+
# Removes a route to the framework instance
131+
def delete_route(opts={})
132+
subnet = opts[:subnet]
133+
netmask = opts[:netmask] || "255.255.255.0" # Default class C
134+
Rex::Socket::SwitchBoard.remove_route(subnet, netmask, session)
135+
end
136+
137+
138+
# Defines usage
139+
def usage()
140+
print_status "Usage: run autoroute [-r] -s subnet -n netmask"
141+
print_status "Examples:"
142+
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"
143+
print_status " run autoroute -s 10.10.10.1 # Netmask defaults to 255.255.255.0"
144+
print_status " run autoroute -s 10.10.10.1/24 # CIDR notation is also okay"
145+
print_status " run autoroute -p # Print active routing table"
146+
print_status " run autoroute -d -s 10.10.10.1 # Deletes the 10.10.10.1/255.255.255.0 route"
147+
print_status "Use the \"route\" and \"ipconfig\" Meterpreter commands to learn about available routes"
148+
print_error "Deprecation warning: This script has been replaced by the post/windows/manage/autoroute module"
149+
end
150+
151+
# Validates the command options
152+
def validate_cmd(subnet=nil,netmask=nil)
153+
if subnet.nil?
154+
print_error "Missing -s (subnet) option"
155+
return false
156+
end
157+
158+
unless(check_ip(subnet))
159+
print_error "Subnet invalid (must be IPv4)"
160+
usage
161+
return false
162+
end
163+
164+
if(netmask and !(Rex::Socket.addr_atoc(netmask)))
165+
print_error "Netmask invalid (must define contiguous IP addressing)"
166+
usage
167+
return false
168+
end
169+
170+
if(netmask and !check_ip(netmask))
171+
print_error "Netmask invalid"
172+
return usage
173+
end
174+
true
175+
end
176+
177+
if print_only
178+
print_routes()
179+
raise Rex::Script::Completed
180+
end
181+
182+
if remove_all_routes
183+
delete_all_routes()
184+
raise Rex::Script::Completed
185+
end
186+
187+
raise Rex::Script::Completed unless validate_cmd(subnet,netmask)
188+
189+
if remove_route
190+
print_status("Deleting route to %s/%s..." % [subnet,netmask])
191+
route_result = delete_route(:subnet => subnet, :netmask => netmask)
192+
else
193+
print_status("Adding a route to %s/%s..." % [subnet,netmask])
194+
route_result = add_route(:subnet => subnet, :netmask => netmask)
195+
end
196+
197+
if route_result
198+
print_good "%s route to %s/%s via %s" % [
199+
(remove_route ? "Deleted" : "Added"),
200+
subnet,netmask,client.sock.peerhost
201+
]
202+
else
203+
print_error "Could not %s route" % [(remove_route ? "delete" : "add")]
204+
end
205+
206+
if Rex::Socket::SwitchBoard.routes.size > 0
207+
print_status "Use the -p option to list all active routes"
208+
end
209+

0 commit comments

Comments
 (0)