Skip to content

Commit 8f0c434

Browse files
committed
Add specs for the new method
1 parent 376bf13 commit 8f0c434

File tree

2 files changed

+162
-4
lines changed

2 files changed

+162
-4
lines changed

lib/msf/base/sessions/meterpreter.rb

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,9 @@ def load_session_info()
323323
nhost = find_internet_connected_address
324324

325325
original_session_host = self.session_host
326-
# If we found a better IP address for this session, change it up
327-
# only handle cases where the DB is not connected here
328-
if !(framework.db && framework.db.active)
326+
# If we found a better IP address for this session, change it
327+
# up. Only handle cases where the DB is not connected here
328+
if nhost && !(framework.db && framework.db.active)
329329
self.session_host = nhost
330330
end
331331

@@ -461,6 +461,8 @@ def create(param)
461461
# @see Rex::Post::Meterpreter::Extensions::Stdapi::Net::Config#get_routes
462462
# @return [String] The address from which this host reaches the
463463
# internet, as ASCII. e.g.: "192.168.100.156"
464+
# @return [nil] If there is an interface with an address that matches
465+
# {#session_host}
464466
def find_internet_connected_address
465467

466468
ifaces = self.net.config.get_interfaces().flatten rescue []
@@ -497,7 +499,9 @@ def find_internet_connected_address
497499
end
498500

499501
if !nhost
500-
# Find the first non-loopback address
502+
# No internal address matches what we see externally and no
503+
# interface has a default route. Fall back to the first
504+
# non-loopback address
501505
non_loopback = ifaces.find { |i| i.ip != "127.0.0.1" && i.ip != "::1" }
502506
if non_loopback
503507
nhost = non_loopback.ip
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
require 'spec_helper'
2+
require 'msf/base/sessions/meterpreter'
3+
require 'rex/post/meterpreter/extensions/stdapi/net/interface'
4+
require 'rex/post/meterpreter/extensions/stdapi/net/route'
5+
6+
describe Msf::Sessions::Meterpreter do
7+
subject(:meterpreter) { described_class.new(StringIO.new(""), skip_ssl: true) }
8+
9+
let(:v6_gateway) { "2607:f8b0:4004:0802::1014" }
10+
let(:v4_gateway) { "192.168.3.1" }
11+
12+
let(:v6_linklocal) { "fe80::d6c9:efff:fe53:53ff" }
13+
14+
let(:routes) do
15+
[
16+
Rex::Post::Meterpreter::Extensions::Stdapi::Net::Route.new(
17+
IPAddr.new("0.0.0.0").hton, # Subnet
18+
IPAddr.new("0.0.0.0").hton, # Netmask
19+
IPAddr.new("192.168.3.1").hton # Gateway
20+
),
21+
Rex::Post::Meterpreter::Extensions::Stdapi::Net::Route.new(
22+
IPAddr.new("::").hton, # Subnet
23+
IPAddr.new("::").hton, # Netmask
24+
IPAddr.new(v6_gateway).hton # Gateway
25+
)
26+
]
27+
end
28+
29+
it { should respond_to(:find_internet_connected_address) }
30+
31+
describe "#find_internet_connected_address" do
32+
33+
subject(:connected_address) do
34+
m = described_class.new(StringIO.new(""), skip_ssl: true)
35+
m.stub_chain(:net, :config, :get_interfaces).and_return(interfaces)
36+
m.stub_chain(:net, :config, :get_routes).and_return(routes)
37+
m.session_host = session_host
38+
39+
m.send(:find_internet_connected_address)
40+
end
41+
42+
let(:interfaces) do
43+
ifaces = []
44+
interface_config.each_with_index { |iface_hash, idx|
45+
ifaces << Rex::Post::Meterpreter::Extensions::Stdapi::Net::Interface.new(
46+
index: idx,
47+
mac_addr: "00:11:22:33:44:%02x"%idx,
48+
mac_name: "eth0",
49+
mtu: 1500,
50+
flags: 0,
51+
addrs: iface_hash[:ips],
52+
netmasks: iface_hash[:masks],
53+
scopes: [ "" ]
54+
)
55+
}
56+
57+
ifaces
58+
end
59+
60+
let(:session_host) { "99.99.99.99" }
61+
62+
context "with an address that matches #session_host" do
63+
let(:interface_config) do
64+
[
65+
{ ips: [ "192.168.10.1" ], masks: [ "255.255.255.0" ], },
66+
{ ips: [ "192.168.11.1" ], masks: [ "255.255.255.0" ], },
67+
{ ips: [ "192.168.12.1" ], masks: [ "255.255.255.0" ], },
68+
{ ips: [ session_host ], masks: [ "255.255.255.0" ], },
69+
{ ips: [ "192.168.14.1" ], masks: [ "255.255.255.0" ], },
70+
{ ips: [ "192.168.16.1" ], masks: [ "255.255.255.0" ], },
71+
]
72+
end
73+
it "returns nil" do
74+
expect(connected_address).to be_nil
75+
end
76+
end
77+
78+
# All the rest of these assume session_host does not match any
79+
# interface's addresses
80+
81+
context "one interface with one IPv4 address" do
82+
let(:interface_config) do
83+
[ { ips: [ "10.2.3.4" ], masks: [ "255.255.255.0" ], } ]
84+
end
85+
it "returns that address" do
86+
expect(connected_address).to eq("10.2.3.4")
87+
end
88+
end
89+
90+
context "one interface with one IPv6 address" do
91+
let(:interface_config) do
92+
[
93+
{ ips: [ v6_linklocal ], masks: [ "ffff:ffff:ffff:ffff::" ], },
94+
]
95+
end
96+
it "returns that address" do
97+
expect(connected_address).to eq(v6_linklocal)
98+
end
99+
end
100+
101+
context "one interface with mixed IP versions" do
102+
context "first is correct" do
103+
let(:interface_config) do
104+
[
105+
{ ips: [ "192.168.3.4" ], masks: [ "255.255.255.0" ], },
106+
{ ips: [ v6_linklocal ], masks: [ "ffff:ffff:ffff:ffff::" ], },
107+
]
108+
end
109+
it "returns first address" do
110+
expect(connected_address).to eq("192.168.3.4")
111+
end
112+
end
113+
context "second address is correct" do
114+
let(:interface_config) do
115+
[
116+
{ ips: [ v6_linklocal ], masks: [ "ffff:ffff:ffff:ffff::" ], },
117+
{ ips: [ "192.168.3.4" ], masks: [ "255.255.255.0" ], },
118+
]
119+
end
120+
it "returns second address" do
121+
expect(connected_address).to eq("192.168.3.4")
122+
end
123+
end
124+
end
125+
126+
context "one interface with multiple IPv4 addresses" do
127+
context "first address is correct" do
128+
let(:interface_config) do
129+
[ {
130+
ips: ["192.168.3.4", "10.2.3.4"],
131+
masks: [ "255.255.255.0", "255.0.0.0"],
132+
} ]
133+
end
134+
it "returns first address" do
135+
expect(connected_address).to eq("192.168.3.4")
136+
end
137+
end
138+
context "second address is correct" do
139+
let(:interface_config) do
140+
[ {
141+
ips: [ "10.2.3.4", "192.168.3.4" ],
142+
masks: [ "255.0.0.0", "255.255.255.0" ],
143+
} ]
144+
end
145+
it "returns second address" do
146+
expect(connected_address).to eq("192.168.3.4")
147+
end
148+
end
149+
end
150+
151+
end
152+
153+
end
154+

0 commit comments

Comments
 (0)