CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/rex/post/meterpreter/extensions/stdapi/net/config.rb
Views: 1904
1
# -*- coding: binary -*-
2
3
require 'rex/post/meterpreter/extensions/stdapi/tlv'
4
require 'rex/post/meterpreter/extensions/stdapi/net/arp'
5
require 'rex/post/meterpreter/extensions/stdapi/net/route'
6
require 'rex/post/meterpreter/extensions/stdapi/net/netstat'
7
require 'rex/post/meterpreter/extensions/stdapi/net/interface'
8
9
module Rex
10
module Post
11
module Meterpreter
12
module Extensions
13
module Stdapi
14
module Net
15
16
###
17
#
18
# This class provides an interface to the network configuration
19
# that exists on the remote machine, such as interfaces, and
20
# routes.
21
#
22
###
23
class Config
24
25
##
26
#
27
# Constructor
28
#
29
##
30
31
#
32
# Initializes a Config instance that is used to get information about the
33
# network configuration of the remote machine.
34
#
35
def initialize(client)
36
self.client = client
37
end
38
39
##
40
#
41
# Interfaces
42
#
43
##
44
45
#
46
# Enumerates each interface.
47
#
48
def each_interface(&block)
49
get_interfaces().each(&block)
50
end
51
52
# Returns an array of network interfaces with each element.
53
#
54
# @return [Array<Interface>]
55
def get_interfaces
56
request = Packet.create_request(COMMAND_ID_STDAPI_NET_CONFIG_GET_INTERFACES)
57
ifaces = []
58
59
response = client.send_request(request)
60
61
response.each(TLV_TYPE_NETWORK_INTERFACE) { |iface|
62
addrs = []
63
netmasks = []
64
scopes = []
65
while (a = iface.get_tlv_value(TLV_TYPE_IP, addrs.length))
66
# Netmasks aren't tightly associated with addresses, they're
67
# just thrown all together in the interface TLV ordered to
68
# match up. This could be done better by creating another
69
# GroupTlv type for addresses containing an address, a netmask,
70
# and possibly a scope.
71
n = iface.get_tlv_value(TLV_TYPE_NETMASK, addrs.length)
72
if (n.nil?)
73
# Some systems can't report a netmask, only a network
74
# prefix, so figure out the netmask from that.
75
n = iface.get_tlv_value(TLV_TYPE_IP_PREFIX, addrs.length)
76
if n
77
n = Rex::Socket.bit2netmask(n, !!(a.length == 16))
78
end
79
else
80
n = Rex::Socket.addr_ntoa(n)
81
end
82
s = iface.get_tlv_value(TLV_TYPE_IP6_SCOPE, addrs.length)
83
scopes[addrs.length] = s if s
84
netmasks[addrs.length] = n if n
85
addrs << Rex::Socket.addr_ntoa(a)
86
end
87
ifaces << Interface.new(
88
:index => iface.get_tlv_value(TLV_TYPE_INTERFACE_INDEX),
89
:mac_addr => iface.get_tlv_value(TLV_TYPE_MAC_ADDRESS),
90
:mac_name => iface.get_tlv_value(TLV_TYPE_MAC_NAME),
91
:mtu => iface.get_tlv_value(TLV_TYPE_INTERFACE_MTU),
92
:flags => iface.get_tlv_value(TLV_TYPE_INTERFACE_FLAGS),
93
:addrs => addrs,
94
:netmasks => netmasks,
95
:scopes => scopes
96
)
97
}
98
99
return ifaces
100
end
101
102
alias interfaces get_interfaces
103
104
##
105
#
106
# Network connections
107
#
108
##
109
110
#
111
# Returns an array of network connection entries with each element being a Netstat.
112
#
113
114
def get_netstat
115
request = Packet.create_request(COMMAND_ID_STDAPI_NET_CONFIG_GET_NETSTAT)
116
netstat = []
117
118
response = client.send_request(request)
119
120
# Build out the array of netstat
121
response.each(TLV_TYPE_NETSTAT_ENTRY) { |connection|
122
netstat << Netstat.new(
123
:local_addr => connection.get_tlv_value(TLV_TYPE_LOCAL_HOST_RAW),
124
:remote_addr => connection.get_tlv_value(TLV_TYPE_PEER_HOST_RAW),
125
:local_port => connection.get_tlv_value(TLV_TYPE_LOCAL_PORT),
126
:remote_port => connection.get_tlv_value(TLV_TYPE_PEER_PORT),
127
:protocol => connection.get_tlv_value(TLV_TYPE_MAC_NAME), # tcp/tcp6/udp/udp6
128
:state => connection.get_tlv_value(TLV_TYPE_SUBNET_STRING),
129
:uid => connection.get_tlv_value(TLV_TYPE_PID),
130
:inode => connection.get_tlv_value(TLV_TYPE_ROUTE_METRIC),
131
:pid_name => connection.get_tlv_value(TLV_TYPE_PROCESS_NAME)
132
)
133
}
134
135
return netstat
136
end
137
138
alias netstat get_netstat
139
140
##
141
#
142
# Routing
143
#
144
##
145
146
#
147
# Returns an array of arp entries with each element being an Arp.
148
#
149
150
def get_arp_table
151
request = Packet.create_request(COMMAND_ID_STDAPI_NET_CONFIG_GET_ARP_TABLE)
152
arps = []
153
154
response = client.send_request(request)
155
156
# Build out the array of arp
157
response.each(TLV_TYPE_ARP_ENTRY) { |arp|
158
arps << Arp.new(
159
:ip_addr => arp.get_tlv_value(TLV_TYPE_IP),
160
:mac_addr => arp.get_tlv_value(TLV_TYPE_MAC_ADDRESS),
161
:interface => arp.get_tlv_value(TLV_TYPE_MAC_NAME)
162
)
163
}
164
165
return arps
166
end
167
168
alias arp_table get_arp_table
169
170
#
171
# Enumerates each route.
172
#
173
def each_route(&block)
174
get_routes().each(&block)
175
end
176
177
#
178
# Returns an array of routes with each element being a Route.
179
#
180
def get_routes
181
request = Packet.create_request(COMMAND_ID_STDAPI_NET_CONFIG_GET_ROUTES)
182
routes = []
183
184
response = client.send_request(request)
185
186
# Build out the array of routes
187
# Note: This will include both IPv4 and IPv6 routes
188
response.each(TLV_TYPE_NETWORK_ROUTE) { |route|
189
routes << Route.new(
190
route.get_tlv_value(TLV_TYPE_SUBNET),
191
route.get_tlv_value(TLV_TYPE_NETMASK),
192
route.get_tlv_value(TLV_TYPE_GATEWAY),
193
route.get_tlv_value(TLV_TYPE_STRING),
194
route.get_tlv_value(TLV_TYPE_ROUTE_METRIC))
195
}
196
197
return routes
198
end
199
200
alias routes get_routes
201
202
#
203
# Adds a route to the target machine.
204
#
205
def add_route(subnet, netmask, gateway)
206
request = Packet.create_request(COMMAND_ID_STDAPI_NET_CONFIG_ADD_ROUTE)
207
208
request.add_tlv(TLV_TYPE_SUBNET_STRING, subnet)
209
request.add_tlv(TLV_TYPE_NETMASK_STRING, netmask)
210
request.add_tlv(TLV_TYPE_GATEWAY_STRING, gateway)
211
212
client.send_request(request)
213
214
return true
215
end
216
217
#
218
# Removes a route from the target machine.
219
#
220
def remove_route(subnet, netmask, gateway)
221
request = Packet.create_request(COMMAND_ID_STDAPI_NET_CONFIG_REMOVE_ROUTE)
222
223
request.add_tlv(TLV_TYPE_SUBNET_STRING, subnet)
224
request.add_tlv(TLV_TYPE_NETMASK_STRING, netmask)
225
request.add_tlv(TLV_TYPE_GATEWAY_STRING, gateway)
226
227
client.send_request(request)
228
229
return true
230
end
231
232
#
233
# Gets the current proxy configuration
234
#
235
def get_proxy_config()
236
request = Packet.create_request(COMMAND_ID_STDAPI_NET_CONFIG_GET_PROXY)
237
238
response = client.send_request(request)
239
240
proxy_config = {
241
:autodetect => response.get_tlv_value(TLV_TYPE_PROXY_CFG_AUTODETECT),
242
:autoconfigurl => response.get_tlv_value(TLV_TYPE_PROXY_CFG_AUTOCONFIGURL),
243
:proxy => response.get_tlv_value(TLV_TYPE_PROXY_CFG_PROXY),
244
:proxybypass => response.get_tlv_value(TLV_TYPE_PROXY_CFG_PROXYBYPASS)
245
}
246
247
return proxy_config
248
end
249
250
protected
251
252
attr_accessor :client # :nodoc:
253
254
end
255
256
end; end; end; end; end; end
257
258