Land #10094, Improve network interface support for LHOST

4.x
Brent Cook 2018-05-29 23:07:30 -05:00 committed by Metasploit
parent 122af6b143
commit 87c6befb45
No known key found for this signature in database
GPG Key ID: CDFB5FA52007B954
4 changed files with 38 additions and 31 deletions

View File

@ -25,8 +25,8 @@ module Msf
Msf::OptPort.new(__method__.to_s, [ required, desc, default ]) Msf::OptPort.new(__method__.to_s, [ required, desc, default ])
end end
# @return [OptAddress] # @return [OptAddressLocal]
def self.LHOST(default=nil, required=true, desc="The listen address") def self.LHOST(default=nil, required=true, desc="The listen address (an interface may be specified)")
Msf::OptAddressLocal.new(__method__.to_s, [ required, desc, default ]) Msf::OptAddressLocal.new(__method__.to_s, [ required, desc, default ])
end end

View File

@ -5,36 +5,39 @@ module Msf
### ###
# #
# Network address option. # Local network address option.
# #
### ###
class OptAddressLocal < OptAddress class OptAddressLocal < OptAddress
def normalize(value) def interfaces
return nil unless value.kind_of?(String) NetworkInterface.interfaces || []
end
if NetworkInterface.interfaces.include?(value) def normalize(value)
ip_address = NetworkInterface.addresses(value).values.flatten.collect{|x| x['addr']}.select do |addr| return unless value.kind_of?(String)
return value unless interfaces.include?(value)
addrs = NetworkInterface.addresses(value).values.flatten
# Strip interface name from address (see getifaddrs(3))
addrs = addrs.map { |x| x['addr'].split('%').first }.select do |addr|
begin begin
IPAddr.new(addr).ipv4? IPAddr.new(addr)
rescue IPAddr::InvalidAddressError => e rescue IPAddr::InvalidAddressError
false false
end end
end end
return false if ip_address.blank? addrs.any? ? addrs.first : ''
return ip_address.first
end
return value
end end
def valid?(value, check_empty: true) def valid?(value, check_empty: true)
return false if check_empty && empty_required_value?(value) return false if check_empty && empty_required_value?(value)
return false unless value.kind_of?(String) or value.kind_of?(NilClass) return false unless value.kind_of?(String) || value.kind_of?(NilClass)
return true if NetworkInterface.interfaces.include?(value) return true if interfaces.include?(value)
return super super
end end
end end

View File

@ -2189,6 +2189,12 @@ class Core
return res return res
end end
# XXX: We repurpose OptAddressLocal#interfaces, so we can't put this in Rex
def tab_complete_source_interface(o)
return [] unless o.is_a?(Msf::OptAddressLocal)
o.interfaces
end
# #
# Provide possible option values based on type # Provide possible option values based on type
# #
@ -2210,8 +2216,8 @@ class Core
res << Rex::Socket.source_address(rh) res << Rex::Socket.source_address(rh)
else else
res += tab_complete_source_address res += tab_complete_source_address
res += tab_complete_source_interface(o)
end end
else
end end
when Msf::OptAddressRange when Msf::OptAddressRange

View File

@ -289,11 +289,9 @@ module DispatcherShell
def tab_complete_source_address def tab_complete_source_address
addresses = [Rex::Socket.source_address] addresses = [Rex::Socket.source_address]
# getifaddrs was introduced in 2.1.2 # getifaddrs was introduced in 2.1.2
if Socket.respond_to?(:getifaddrs) if ::Socket.respond_to?(:getifaddrs)
ifaddrs = Socket.getifaddrs.find_all do |ifaddr| ifaddrs = ::Socket.getifaddrs.select do |ifaddr|
((ifaddr.flags & Socket::IFF_LOOPBACK) == 0) && ifaddr.addr && ifaddr.addr.ip?
ifaddr.addr &&
ifaddr.addr.ip?
end end
addresses += ifaddrs.map { |ifaddr| ifaddr.addr.ip_address } addresses += ifaddrs.map { |ifaddr| ifaddr.addr.ip_address }
end end