Land #5006 @jlee-r7 adds meterpreter specs

bug/bundler_fix
Brent Cook 2015-04-01 11:05:47 -05:00
commit f4977bf606
No known key found for this signature in database
GPG Key ID: 1FFAA0B24B708F96
2 changed files with 164 additions and 4 deletions

View File

@ -323,9 +323,9 @@ class Meterpreter < Rex::Post::Meterpreter::Client
nhost = find_internet_connected_address
original_session_host = self.session_host
# If we found a better IP address for this session, change it up
# only handle cases where the DB is not connected here
if !(framework.db && framework.db.active)
# If we found a better IP address for this session, change it
# up. Only handle cases where the DB is not connected here
if nhost && !(framework.db && framework.db.active)
self.session_host = nhost
end
@ -461,6 +461,8 @@ protected
# @see Rex::Post::Meterpreter::Extensions::Stdapi::Net::Config#get_routes
# @return [String] The address from which this host reaches the
# internet, as ASCII. e.g.: "192.168.100.156"
# @return [nil] If there is an interface with an address that matches
# {#session_host}
def find_internet_connected_address
ifaces = self.net.config.get_interfaces().flatten rescue []
@ -497,7 +499,9 @@ protected
end
if !nhost
# Find the first non-loopback address
# No internal address matches what we see externally and no
# interface has a default route. Fall back to the first
# non-loopback address
non_loopback = ifaces.find { |i| i.ip != "127.0.0.1" && i.ip != "::1" }
if non_loopback
nhost = non_loopback.ip

View File

@ -0,0 +1,156 @@
require 'spec_helper'
require 'msf/base/sessions/meterpreter'
require 'rex/post/meterpreter/extensions/stdapi/net/interface'
require 'rex/post/meterpreter/extensions/stdapi/net/route'
describe Msf::Sessions::Meterpreter do
before do
allow_any_instance_of(Rex::Post::Meterpreter::PacketDispatcher).to receive(:monitor_socket)
end
subject(:meterpreter) { described_class.new(StringIO.new(""), skip_ssl: true) }
let(:v6_gateway) { "2607:f8b0:4004:0802::1014" }
let(:v4_gateway) { "192.168.3.1" }
let(:v6_linklocal) { "fe80::d6c9:efff:fe53:53ff" }
let(:routes) do
[
Rex::Post::Meterpreter::Extensions::Stdapi::Net::Route.new(
IPAddr.new("0.0.0.0").hton, # Subnet
IPAddr.new("0.0.0.0").hton, # Netmask
IPAddr.new("192.168.3.1").hton # Gateway
),
Rex::Post::Meterpreter::Extensions::Stdapi::Net::Route.new(
IPAddr.new("::").hton, # Subnet
IPAddr.new("::").hton, # Netmask
IPAddr.new(v6_gateway).hton # Gateway
)
]
end
describe "#find_internet_connected_address" do
subject(:connected_address) do
m = described_class.new(StringIO.new(""), skip_ssl: true)
m.stub_chain(:net, :config, :get_interfaces).and_return(interfaces)
m.stub_chain(:net, :config, :get_routes).and_return(routes)
m.session_host = session_host
m.send(:find_internet_connected_address)
end
let(:interfaces) do
ifaces = []
interface_config.each_with_index { |iface_hash, idx|
ifaces << Rex::Post::Meterpreter::Extensions::Stdapi::Net::Interface.new(
index: idx,
mac_addr: "00:11:22:33:44:%02x"%idx,
mac_name: "eth0",
mtu: 1500,
flags: 0,
addrs: iface_hash[:ips],
netmasks: iface_hash[:masks],
scopes: [ "" ]
)
}
ifaces
end
let(:session_host) { "99.99.99.99" }
context "with an address that matches #session_host" do
let(:interface_config) do
[
{ ips: [ "192.168.10.1" ], masks: [ "255.255.255.0" ], },
{ ips: [ "192.168.11.1" ], masks: [ "255.255.255.0" ], },
{ ips: [ "192.168.12.1" ], masks: [ "255.255.255.0" ], },
{ ips: [ session_host ], masks: [ "255.255.255.0" ], },
{ ips: [ "192.168.14.1" ], masks: [ "255.255.255.0" ], },
{ ips: [ "192.168.16.1" ], masks: [ "255.255.255.0" ], },
]
end
it "returns nil" do
expect(connected_address).to be_nil
end
end
# All the rest of these assume session_host does not match any
# interface's addresses
context "one interface with one IPv4 address" do
let(:interface_config) do
[ { ips: [ "10.2.3.4" ], masks: [ "255.255.255.0" ], } ]
end
it "returns that address" do
expect(connected_address).to eq("10.2.3.4")
end
end
context "one interface with one IPv6 address" do
let(:interface_config) do
[
{ ips: [ v6_linklocal ], masks: [ "ffff:ffff:ffff:ffff::" ], },
]
end
it "returns that address" do
expect(connected_address).to eq(v6_linklocal)
end
end
context "one interface with mixed IP versions" do
context "first is correct" do
let(:interface_config) do
[
{ ips: [ "192.168.3.4" ], masks: [ "255.255.255.0" ], },
{ ips: [ v6_linklocal ], masks: [ "ffff:ffff:ffff:ffff::" ], },
]
end
it "returns first address" do
expect(connected_address).to eq("192.168.3.4")
end
end
context "second address is correct" do
let(:interface_config) do
[
{ ips: [ v6_linklocal ], masks: [ "ffff:ffff:ffff:ffff::" ], },
{ ips: [ "192.168.3.4" ], masks: [ "255.255.255.0" ], },
]
end
it "returns second address" do
expect(connected_address).to eq("192.168.3.4")
end
end
end
context "one interface with multiple IPv4 addresses" do
context "first address is correct" do
let(:interface_config) do
[ {
ips: ["192.168.3.4", "10.2.3.4"],
masks: [ "255.255.255.0", "255.0.0.0"],
} ]
end
it "returns first address" do
expect(connected_address).to eq("192.168.3.4")
end
end
context "second address is correct" do
let(:interface_config) do
[ {
ips: [ "10.2.3.4", "192.168.3.4" ],
masks: [ "255.0.0.0", "255.255.255.0" ],
} ]
end
it "returns second address" do
expect(connected_address).to eq("192.168.3.4")
end
end
end
end
end