CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/spec/lib/msf/base/sessions/meterpreter_spec.rb
Views: 11765
1
require 'spec_helper'
2
require 'rex/post/meterpreter/extensions/stdapi/net/interface'
3
require 'rex/post/meterpreter/extensions/stdapi/net/route'
4
5
RSpec.describe Msf::Sessions::Meterpreter do
6
before do
7
allow_any_instance_of(Rex::Post::Meterpreter::PacketDispatcher).to receive(:monitor_socket)
8
end
9
10
subject(:meterpreter) { described_class.new(StringIO.new(""), skip_ssl: true) }
11
12
let(:v6_gateway) { "2607:f8b0:4004:0802::1014" }
13
let(:v4_gateway) { "192.168.3.1" }
14
15
let(:v6_linklocal) { "fe80::d6c9:efff:fe53:53ff" }
16
17
let(:routes) do
18
[
19
Rex::Post::Meterpreter::Extensions::Stdapi::Net::Route.new(
20
IPAddr.new("0.0.0.0").hton, # Subnet
21
IPAddr.new("0.0.0.0").hton, # Netmask
22
IPAddr.new("192.168.3.1").hton # Gateway
23
),
24
Rex::Post::Meterpreter::Extensions::Stdapi::Net::Route.new(
25
IPAddr.new("::").hton, # Subnet
26
IPAddr.new("::").hton, # Netmask
27
IPAddr.new(v6_gateway).hton # Gateway
28
)
29
]
30
end
31
32
describe "#find_internet_connected_address" do
33
34
subject(:connected_address) do
35
allow_message_expectations_on_nil
36
m = described_class.new(StringIO.new(""), skip_ssl: true)
37
allow(m).to receive_message_chain(:private_methods, :net)
38
allow(m).to receive_message_chain(:private_methods, :net, :config, :get_interfaces).and_return(interfaces)
39
allow(m).to receive_message_chain(:private_methods, :net, :config, :get_routes).and_return(routes)
40
m.session_host = session_host
41
42
m.send(:find_internet_connected_address)
43
end
44
45
let(:interfaces) do
46
ifaces = []
47
interface_config.each_with_index { |iface_hash, idx|
48
ifaces << Rex::Post::Meterpreter::Extensions::Stdapi::Net::Interface.new(
49
index: idx,
50
mac_addr: "00:11:22:33:44:%02x"%idx,
51
mac_name: "eth0",
52
mtu: 1500,
53
flags: 0,
54
addrs: iface_hash[:ips],
55
netmasks: iface_hash[:masks],
56
scopes: [ "" ]
57
)
58
}
59
60
ifaces
61
end
62
63
let(:session_host) { "99.99.99.99" }
64
65
context "with an address that matches #session_host" do
66
let(:interface_config) do
67
[
68
{ ips: [ "192.168.10.1" ], masks: [ "255.255.255.0" ], },
69
{ ips: [ "192.168.11.1" ], masks: [ "255.255.255.0" ], },
70
{ ips: [ "192.168.12.1" ], masks: [ "255.255.255.0" ], },
71
{ ips: [ session_host ], masks: [ "255.255.255.0" ], },
72
{ ips: [ "192.168.14.1" ], masks: [ "255.255.255.0" ], },
73
{ ips: [ "192.168.16.1" ], masks: [ "255.255.255.0" ], },
74
]
75
end
76
it "returns nil" do
77
expect(connected_address).to be_nil
78
end
79
end
80
81
# All the rest of these assume session_host does not match any
82
# interface's addresses
83
84
context "one interface with one IPv4 address" do
85
let(:interface_config) do
86
[ { ips: [ "10.2.3.4" ], masks: [ "255.255.255.0" ], } ]
87
end
88
it "returns that address" do
89
expect(connected_address).to eq("10.2.3.4")
90
end
91
end
92
93
context "one interface with one IPv6 address" do
94
let(:interface_config) do
95
[
96
{ ips: [ v6_linklocal ], masks: [ "ffff:ffff:ffff:ffff::" ], },
97
]
98
end
99
it "returns that address" do
100
expect(connected_address).to eq(v6_linklocal)
101
end
102
end
103
104
context "one interface with mixed IP versions" do
105
context "first is correct" do
106
let(:interface_config) do
107
[
108
{ ips: [ "192.168.3.4" ], masks: [ "255.255.255.0" ], },
109
{ ips: [ v6_linklocal ], masks: [ "ffff:ffff:ffff:ffff::" ], },
110
]
111
end
112
it "returns first address" do
113
expect(connected_address).to eq("192.168.3.4")
114
end
115
end
116
context "second address is correct" do
117
let(:interface_config) do
118
[
119
{ ips: [ v6_linklocal ], masks: [ "ffff:ffff:ffff:ffff::" ], },
120
{ ips: [ "192.168.3.4" ], masks: [ "255.255.255.0" ], },
121
]
122
end
123
it "returns second address" do
124
expect(connected_address).to eq("192.168.3.4")
125
end
126
end
127
end
128
129
context "one interface with multiple IPv4 addresses" do
130
context "first address is correct" do
131
let(:interface_config) do
132
[ {
133
ips: ["192.168.3.4", "10.2.3.4"],
134
masks: [ "255.255.255.0", "255.0.0.0"],
135
} ]
136
end
137
it "returns first address" do
138
expect(connected_address).to eq("192.168.3.4")
139
end
140
end
141
context "second address is correct" do
142
let(:interface_config) do
143
[ {
144
ips: [ "10.2.3.4", "192.168.3.4" ],
145
masks: [ "255.0.0.0", "255.255.255.0" ],
146
} ]
147
end
148
it "returns second address" do
149
expect(connected_address).to eq("192.168.3.4")
150
end
151
end
152
end
153
154
end
155
156
describe '#exit' do
157
it 'shuts down the session' do
158
allow(subject).to receive(:core).and_return(double('core'))
159
allow(subject).to receive(:console).and_return(double('console'))
160
161
expect(subject.core).to receive(:shutdown)
162
expect(subject).to receive(:shutdown_passive_dispatcher)
163
expect(subject.console).to receive(:stop)
164
subject.exit
165
end
166
end
167
168
end
169
170