1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 04:31:29 +00:00

Use stdnse.get_script_interfaces() for all relevant scripts

This commit is contained in:
dmiller
2024-05-24 19:01:16 +00:00
parent 4ee4d9ea27
commit 453f9a7e25
30 changed files with 297 additions and 522 deletions

View File

@@ -30,7 +30,13 @@ license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"broadcast", "safe"} categories = {"broadcast", "safe"}
prerule = function() return true end prerule = function()
if ( not(nmap.is_privileged()) ) then
stdnse.verbose1("not running for lack of privileges")
return false
end
return true
end
-- The minimalistic ATAoE interface -- The minimalistic ATAoE interface
ATAoE = { ATAoE = {
@@ -118,18 +124,15 @@ end
action = function() action = function()
local iname = nmap.get_interface() local iface
if ( not(iname) ) then local collect_interface = function (if_table)
stdnse.verbose1("No interface supplied, use -e") if not iface and if_table.up == "up" and if_table.link == "ethernet" then
return iface = if_table
end
end end
if ( not(nmap.is_privileged()) ) then stdnse.get_script_interfaces(collect_interface)
stdnse.verbose1("not running for lack of privileges")
return
end
local iface = nmap.get_interface_info(iname)
if ( not(iface) ) then if ( not(iface) ) then
return stdnse.format_output(false, "Failed to retrieve interface information") return stdnse.format_output(false, "Failed to retrieve interface information")
end end

View File

@@ -100,29 +100,9 @@ prerule = function()
return true return true
end end
-- Gets a list of available interfaces based on link and up filters
--
-- @param link string containing the link type to filter
-- @param up string containing the interface status to filter
-- @return result table containing the matching interfaces
local function getInterfaces(link, up)
if( not(nmap.list_interfaces) ) then return end
local interfaces, err = nmap.list_interfaces()
local result
if ( not(err) ) then
for _, iface in ipairs(interfaces) do
if ( iface.link == link and iface.up == up ) then
result = result or {}
result[iface.device] = true
end
end
end
return result
end
-- Listens for an incoming dhcp response -- Listens for an incoming dhcp response
-- --
-- @param iface string with the name of the interface to listen to -- @param iface description table of the interface to listen to
-- @param macaddr client hardware address -- @param macaddr client hardware address
-- @param options DHCP options to include in the request -- @param options DHCP options to include in the request
-- @param timeout number of ms to wait for a response -- @param timeout number of ms to wait for a response
@@ -144,7 +124,7 @@ local function dhcp_listener(sock, iface, macaddr, options, timeout, xid, result
nil, -- lease time nil, -- lease time
xid) xid)
if not status then if not status then
stdnse.debug1("Failed to build packet for %s: %s", iface, pkt) stdnse.debug1("Failed to build packet for %s: %s", iface.device, pkt)
condvar "signal" condvar "signal"
return return
end end
@@ -167,15 +147,15 @@ local function dhcp_listener(sock, iface, macaddr, options, timeout, xid, result
-- Add the Ethernet header -- Add the Ethernet header
frame:build_ether_frame( frame:build_ether_frame(
"\xff\xff\xff\xff\xff\xff", "\xff\xff\xff\xff\xff\xff",
nmap.get_interface_info(iface).mac, -- can't use macaddr or we won't see response iface.mac, -- can't use macaddr or we won't see response
packet.ETHER_TYPE_IPV4) packet.ETHER_TYPE_IPV4)
local dnet = nmap.new_dnet() local dnet = nmap.new_dnet()
dnet:ethernet_open(iface) dnet:ethernet_open(iface.device)
local status, err = dnet:ethernet_send(frame.frame_buf) local status, err = dnet:ethernet_send(frame.frame_buf)
dnet:ethernet_close() dnet:ethernet_close()
if not status then if not status then
stdnse.debug1("Failed to send frame for %s: %s", iface, err) stdnse.debug1("Failed to send frame for %s: %s", iface.device, err)
condvar "signal" condvar "signal"
return return
end end
@@ -192,7 +172,7 @@ local function dhcp_listener(sock, iface, macaddr, options, timeout, xid, result
local data = data:sub(p.udp_offset + 9) local data = data:sub(p.udp_offset + 9)
local status, response = dhcp.dhcp_parse(data, xid) local status, response = dhcp.dhcp_parse(data, xid)
if ( status ) then if ( status ) then
response.iface = iface response.iface = iface.device
table.insert( result, response ) table.insert( result, response )
end end
end end
@@ -243,20 +223,15 @@ action = function()
table.insert(options, {number = 61, type = "string", value = clientid }) table.insert(options, {number = 61, type = "string", value = clientid })
end end
local interfaces local interfaces = {}
local collect_interfaces = function (if_table)
-- first check if the user supplied an interface if if_table and if_table.up == "up" and if_table.link=="ethernet" then
if ( nmap.get_interface() ) then interfaces[if_table.device] = if_table
interfaces = { [nmap.get_interface()] = true } end
else
-- As the response will be sent to the "offered" ip address we need
-- to use pcap to pick it up. However, we don't know what interface
-- our packet went out on, so lets get a list of all interfaces and
-- run pcap on all of them, if they're a) up and b) ethernet.
interfaces = getInterfaces("ethernet", "up")
end end
stdnse.get_script_interfaces(collect_interfaces)
if( not(interfaces) ) then return fail("Failed to retrieve interfaces (try setting one explicitly using -e)") end if not next(interfaces) then return fail("Failed to retrieve interfaces (try setting one explicitly using -e)") end
local transaction_id = math.random(0, 0x7F000000) local transaction_id = math.random(0, 0x7F000000)
@@ -265,13 +240,13 @@ action = function()
local condvar = nmap.condvar(result) local condvar = nmap.condvar(result)
-- start a listening thread for each interface -- start a listening thread for each interface
for iface, _ in pairs(interfaces) do for if_name, iface in pairs(interfaces) do
transaction_id = transaction_id + 1 transaction_id = transaction_id + 1
local xid = string.pack(">I4", transaction_id) local xid = string.pack(">I4", transaction_id)
local sock, co local sock, co
sock = nmap.new_socket() sock = nmap.new_socket()
sock:pcap_open(iface, 1500, true, "ip && udp dst port 68") sock:pcap_open(if_name, 1500, true, "ip && udp dst port 68")
co = stdnse.new_thread( dhcp_listener, sock, iface, macaddr, options, timeout, xid, result ) co = stdnse.new_thread( dhcp_listener, sock, iface, macaddr, options, timeout, xid, result )
threads[co] = true threads[co] = true
end end

View File

@@ -52,26 +52,6 @@ prerule = function()
return true return true
end end
-- Gets a list of available interfaces based on link and up filters
--
-- @param link string containing the link type to filter
-- @param up string containing the interface status to filter
-- @return result table containing the matching interfaces
local function getInterfaces(link, up)
if( not(nmap.list_interfaces) ) then return end
local interfaces, err = nmap.list_interfaces()
local result
if ( not(err) ) then
for _, iface in ipairs(interfaces) do
if ( iface.link == link and iface.up == up ) then
result = result or {}
result[iface.device] = true
end
end
end
return result
end
local function solicit(iface, result) local function solicit(iface, result)
local condvar = nmap.condvar(result) local condvar = nmap.condvar(result)
local helper = dhcp6.Helper:new(iface) local helper = dhcp6.Helper:new(iface)
@@ -90,15 +70,16 @@ end
action = function(host, port) action = function(host, port)
local iface = nmap.get_interface()
local ifs, result, threads = {}, {}, {} local ifs, result, threads = {}, {}, {}
local condvar = nmap.condvar(result) local condvar = nmap.condvar(result)
if ( iface ) then local ifs = {}
ifs[iface] = true local collect_interfaces = function (if_table)
else if if_table and if_table.up == "up" and if_table.link=="ethernet" then
ifs = getInterfaces("ethernet", "up") ifs[if_table.device] = if_table
end
end end
stdnse.get_script_interfaces(collect_interfaces)
for iface in pairs(ifs) do for iface in pairs(ifs) do
local co = stdnse.new_thread( solicit, iface, result ) local co = stdnse.new_thread( solicit, iface, result )

View File

@@ -199,7 +199,6 @@ action = function()
local as = stdnse.get_script_args(SCRIPT_NAME .. ".as") local as = stdnse.get_script_args(SCRIPT_NAME .. ".as")
local kparams = stdnse.get_script_args(SCRIPT_NAME .. ".kparams") or "101000" local kparams = stdnse.get_script_args(SCRIPT_NAME .. ".kparams") or "101000"
local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout")) local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout"))
local interface = stdnse.get_script_args(SCRIPT_NAME .. ".interface")
local output, responses, interfaces, lthreads = {}, {}, {}, {} local output, responses, interfaces, lthreads = {}, {}, {}, {}
local result, response, route, eigrp_hello, k local result, response, route, eigrp_hello, k
local timeout = (timeout or 10) * 1000 local timeout = (timeout or 10) * 1000
@@ -218,27 +217,13 @@ action = function()
k[6] = string.sub(kparams, 6) k[6] = string.sub(kparams, 6)
end end
interface = interface or nmap.get_interface() local collect_interfaces = function (if_table)
if interface then if if_table and if_table.up == "up" and if_table.link=="ethernet"
-- If an interface was provided, get its information and if_table.address:match("%d+%.%d+%.%d+%.%d+") then
interface = nmap.get_interface_info(interface) interfaces[#interfaces+1] = if_table
if not interface then
return fail(("Failed to retrieve %s interface information."):format(interface))
end
interfaces = {interface}
stdnse.debug1("Will use %s interface.", interface.shortname)
else
local ifacelist = nmap.list_interfaces()
for _, iface in ipairs(ifacelist) do
-- Match all ethernet interfaces
if iface.address and iface.link=="ethernet" and
iface.address:match("%d+%.%d+%.%d+%.%d+") then
stdnse.debug1("Will use %s interface.", iface.shortname)
table.insert(interfaces, iface)
end
end end
end end
stdnse.get_script_interfaces(collect_interfaces)
-- If user didn't provide an Autonomous System value, we listen fro multicast -- If user didn't provide an Autonomous System value, we listen fro multicast
-- HELLO router announcements to get one. -- HELLO router announcements to get one.

View File

@@ -302,7 +302,6 @@ end
action = function(host, port) action = function(host, port)
local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout")) local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout"))
local version = stdnse.get_script_args(SCRIPT_NAME .. ".version") or 2 local version = stdnse.get_script_args(SCRIPT_NAME .. ".version") or 2
local interface = stdnse.get_script_args(SCRIPT_NAME .. ".interface")
timeout = (timeout or 7) * 1000 timeout = (timeout or 7) * 1000
if version ~= 'all' then if version ~= 'all' then
version = tonumber(version) version = tonumber(version)
@@ -315,29 +314,13 @@ action = function(host, port)
nmap.fetchfile("nselib/data/mgroupnames.db") nmap.fetchfile("nselib/data/mgroupnames.db")
local mg_names_db = group_names_fname and mgroup_names_fetch(group_names_fname) local mg_names_db = group_names_fname and mgroup_names_fetch(group_names_fname)
-- Check the interface local collect_interfaces = function (if_table)
interface = interface or nmap.get_interface() if if_table and if_table.up == "up" and if_table.link=="ethernet"
if interface then and if_table.address:match("%d+%.%d+%.%d+%.%d+") then
-- Get the interface information interfaces[#interfaces+1] = if_table
interface = nmap.get_interface_info(interface)
if not interface then
return stdnse.format_output(false, ("Failed to retrieve %s interface information."):format(interface))
end
interfaces = {interface}
stdnse.debug1("Will use %s interface.", interface.shortname)
else
local ifacelist = nmap.list_interfaces()
for _, iface in ipairs(ifacelist) do
-- Match all ethernet interfaces
if iface.address and iface.link=="ethernet" and
iface.address:match("%d+%.%d+%.%d+%.%d+") then
stdnse.debug1("Will use %s interface.", iface.shortname)
table.insert(interfaces, iface)
end
end end
end end
stdnse.get_script_interfaces(collect_interfaces)
-- We should iterate over interfaces -- We should iterate over interfaces
for _, interface in pairs(interfaces) do for _, interface in pairs(interfaces) do

View File

@@ -126,7 +126,7 @@ end
-- Starts sniffing the selected interface for packets with a destination that -- Starts sniffing the selected interface for packets with a destination that
-- is not explicitly ours (broadcast, multicast etc.) -- is not explicitly ours (broadcast, multicast etc.)
-- --
-- @param iface table containing <code>name</code> and <code>address</code> -- @param iface table containing <code>device</code> and <code>address</code>
-- @param Decoders the decoders class loaded externally -- @param Decoders the decoders class loaded externally
-- @param decodertab the "result" table to which all discovered items are -- @param decodertab the "result" table to which all discovered items are
-- reported -- reported
@@ -139,7 +139,7 @@ sniffInterface = function(iface, Decoders, decodertab)
timeout = (timeout or 30) * 1000 timeout = (timeout or 30) * 1000
-- We want all packets that aren't explicitly for us -- We want all packets that aren't explicitly for us
sock:pcap_open(iface.name, 1500, true, ("!host %s"):format(iface.address)) sock:pcap_open(iface.device, 1500, true, ("!host %s"):format(iface.address))
-- Set a short timeout so that we can timeout in time if needed -- Set a short timeout so that we can timeout in time if needed
sock:set_timeout(100) sock:set_timeout(100)
@@ -193,58 +193,20 @@ sniffInterface = function(iface, Decoders, decodertab)
condvar "signal" condvar "signal"
end end
---
-- Gets a list of available interfaces based on link and up filters
-- Interfaces are only added if they've got an ipv4 address
--
-- @param link string containing the link type to filter
-- @param up string containing the interface status to filter
-- @return result table containing tables of interfaces
-- each interface table has the following fields:
-- <code>name</code> containing the device name
-- <code>address</code> containing the device address
getInterfaces = function(link, up)
if( not(nmap.list_interfaces) ) then return end
local interfaces, err = nmap.list_interfaces()
local result = {}
if ( not(err) ) then
for _, iface in ipairs(interfaces) do
if ( iface.link == link and
iface.up == up and
iface.address ) then
-- exclude ipv6 addresses for now
if ( not(iface.address:match(":")) ) then
table.insert(result, { name = iface.device,
address = iface.address } )
end
end
end
end
return result
end
local function fail (err) return stdnse.format_output(false, err) end local function fail (err) return stdnse.format_output(false, err) end
local filter_interfaces = function (iface)
if (iface.up == "up" and iface.link=="ethernet" and iface.address
-- exclude ipv6 addresses for now
and not iface.address:match(":")) then
return iface
end
end
action = function() action = function()
local DECODERFILE = "nselib/data/packetdecoders.lua" local DECODERFILE = "nselib/data/packetdecoders.lua"
local iface = nmap.get_interface() local interfaces = stdnse.get_script_interfaces(filter_interfaces)
local interfaces = {}
-- was an interface supplied using the -e argument?
if ( iface ) then
local iinfo, err = nmap.get_interface_info(iface)
if ( not(iinfo.address) ) then
return fail("The IP address of the interface could not be determined")
end
interfaces = { { name = iface, address = iinfo.address } }
else
-- no interface was supplied, attempt autodiscovery
interfaces = getInterfaces("ethernet", "up")
end
-- make sure we have at least one interface to start sniffing -- make sure we have at least one interface to start sniffing
if ( #interfaces == 0 ) then if ( #interfaces == 0 ) then

View File

@@ -62,7 +62,19 @@ action = function()
local results = {} local results = {}
local ip = ( nmap.address_family() == "inet" ) and "255.255.255.255" or "ff02::202" local ip = ( nmap.address_family() == "inet" ) and "255.255.255.255" or "ff02::202"
local iface = nmap.get_interface() local iface
local collect_interface = function (if_table)
if not iface and if_table.up == "up" and if_table.link == "ethernet"
and if_table.address and (
(nmap.address_family() == "inet" and if_table.address:match("^%d+%.%d+%.%d+%.%d+$"))
or (nmap.address_family() == "inet6" and if_table.address:match(":"))
)
then
iface = if_table.device
end
end
stdnse.get_script_interfaces(collect_interface)
-- handle problematic sends on OS X requiring the interface to be -- handle problematic sends on OS X requiring the interface to be
-- supplied as part of IPv6 -- supplied as part of IPv6

View File

@@ -389,42 +389,31 @@ local ospfListen = function(interface, timeout)
listener:pcap_close() listener:pcap_close()
end end
local filter_interfaces = function (if_table)
if if_table.up == "up" and if_table.link=="ethernet" and
if_table.address:match("%d+%.%d+%.%d+%.%d+") then
return if_table
end
end
action = function() action = function()
-- Get script arguments -- Get script arguments
md5_key = stdnse.get_script_args(SCRIPT_NAME .. ".md5_key") or false md5_key = stdnse.get_script_args(SCRIPT_NAME .. ".md5_key") or false
router_id = stdnse.get_script_args(SCRIPT_NAME .. ".router_id") or "0.0.0.1" router_id = stdnse.get_script_args(SCRIPT_NAME .. ".router_id") or "0.0.0.1"
local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout")) or 10 local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout")) or 10
local interface = stdnse.get_script_args(SCRIPT_NAME .. ".interface")
stdnse.print_debug("Value for router ID argument: %s.", router_id) stdnse.print_debug("Value for router ID argument: %s.", router_id)
stdnse.print_debug("Value for timeout argument: %s.", timeout) stdnse.print_debug("Value for timeout argument: %s.", timeout)
-- Determine interface to use -- Determine interface to use
interface = interface or nmap.get_interface() local interface
if interface then local interface_good = stdnse.get_script_interfaces(filter_interfaces)
interface = nmap.get_interface_info(interface) if #interface_good == 1 then
if not interface then interface = interface_good[1]
return fail(("Failed to retrieve %s interface information."):format(interface))
end
stdnse.print_debug("Will use %s interface.", interface.shortname) stdnse.print_debug("Will use %s interface.", interface.shortname)
elseif #interface_good == 0 then
return fail("Source interface not found.")
else else
local interface_list = nmap.list_interfaces() return fail("Ambiguous source interface, please specify it with -e or interface parameter.")
local interface_good = {}
for _, os_interface in ipairs(interface_list) do
if os_interface.address and os_interface.link == "ethernet" and
os_interface.address:match("%d+%.%d+%.%d+%.%d+") then
stdnse.print_debug(2, "Found usable interface: %s.", os_interface.shortname)
table.insert(interface_good, os_interface)
end
end
if #interface_good == 1 then
interface = interface_good[1]
stdnse.print_debug("Will use %s interface.", interface.shortname)
elseif #interface_good == 0 then
return fail("Source interface not found.")
else
return fail("Ambiguous source interface, please specify it with -e or interface parameter.")
end
end end
return ospfListen(interface, timeout) return ospfListen(interface, timeout)

View File

@@ -124,7 +124,7 @@ end
--- Returns the network interface used to send packets to the destination host. --- Returns the network interface used to send packets to the destination host.
--@param destination host to which the interface is used. --@param destination host to which the interface is used.
--@return interface Network interface used for destination host. --@return interface Network interface used for destination host.
local getInterface = function(destination) local getInterface = function(interfaces, destination)
-- First, create dummy UDP connection to get interface -- First, create dummy UDP connection to get interface
local sock = nmap.new_socket() local sock = nmap.new_socket()
local status, err = sock:connect(destination, "12345", "udp") local status, err = sock:connect(destination, "12345", "udp")
@@ -137,13 +137,19 @@ local getInterface = function(destination)
stdnse.verbose1("%s", err) stdnse.verbose1("%s", err)
return return
end end
for _, interface in pairs(nmap.list_interfaces()) do for _, interface in ipairs(interfaces) do
if interface.address == address then if interface.address == address then
return interface return interface
end end
end end
end end
local filter_interfaces = function (if_table)
if if_table.up == "up" and if_table.address:match("%d+%.%d+%.%d+%.%d+") then
return if_table
end
end
action = function() action = function()
local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout")) local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout"))
local responses = {} local responses = {}
@@ -151,12 +157,15 @@ action = function()
local mcast = "224.0.0.13" local mcast = "224.0.0.13"
-- Get the network interface to use -- Get the network interface to use
local interface = nmap.get_interface() local interface
if interface then local interfaces = stdnse.get_script_interfaces(filter_interfaces)
interface = nmap.get_interface_info(interface) if #interfaces > 1 then
else -- TODO: send on multiple interfaces
interface = getInterface(mcast) interface = getInterface(interfaces, mcast)
elseif #interfaces == 1 then
interface = interfaces[1]
end end
if not interface then if not interface then
return stdnse.format_output(false, ("Couldn't get interface for %s"):format(mcast)) return stdnse.format_output(false, ("Couldn't get interface for %s"):format(mcast))
end end

View File

@@ -212,33 +212,17 @@ local broadcast_if = function(if_table,icmp_responders)
end end
local filter_interfaces = function (if_table)
if if_table.up == "up" and if_table.link=="ethernet" and if_table.address and
if_table.address:match("%d+%.%d+%.%d+%.%d+") then
return if_table
end
end
action = function() action = function()
--get interface script-args, if any
local interface_arg = stdnse.get_script_args(SCRIPT_NAME .. ".interface")
local interface_opt = nmap.get_interface()
-- interfaces list (decide which interfaces to broadcast on) -- interfaces list (decide which interfaces to broadcast on)
local interfaces ={} local interfaces = stdnse.get_script_interfaces(filter_interfaces)
if interface_opt or interface_arg then
-- single interface defined
local interface = interface_opt or interface_arg
local if_table = nmap.get_interface_info(interface)
if not (if_table and if_table.address and if_table.link=="ethernet") then
stdnse.debug1("Interface not supported or not properly configured.")
return false
end
table.insert(interfaces, if_table)
else
local tmp_ifaces = nmap.list_interfaces()
for _, if_table in ipairs(tmp_ifaces) do
if if_table.address and
if_table.link=="ethernet" and
if_table.address:match("%d+%.%d+%.%d+%.%d+") then
table.insert(interfaces, if_table)
end
end
end
if #interfaces == 0 then if #interfaces == 0 then
stdnse.debug1("No interfaces found.") stdnse.debug1("No interfaces found.")

View File

@@ -66,36 +66,15 @@ local function discoverPPPoE(helper)
return true, pado return true, pado
end end
-- Gets a list of available interfaces based on link and up filters
--
-- @param link string containing the link type to filter
-- @param up string containing the interface status to filter
-- @return result table containing the matching interfaces
local function getInterfaces(link, up)
if( not(nmap.list_interfaces) ) then return end
local interfaces, err = nmap.list_interfaces()
local result
if ( not(err) ) then
for _, iface in ipairs(interfaces) do
if ( iface.link == link and iface.up == up ) then
result = result or {}
result[iface.device] = true
end
end
end
return result
end
action = function() action = function()
local interfaces local interfaces = {}
local collect_interfaces = function (if_table)
-- first check if the user supplied an interface if if_table.up == "up" and if_table.link=="ethernet" then
if ( nmap.get_interface() ) then interfaces[if_table.device] = true
interfaces = { [nmap.get_interface()] = true } end
else
interfaces = getInterfaces("ethernet", "up")
end end
stdnse.get_script_interfaces(collect_interfaces)
for iface in pairs(interfaces) do for iface in pairs(interfaces) do
local helper, err = pppoe.Helper:new(iface) local helper, err = pppoe.Helper:new(iface)

View File

@@ -170,7 +170,14 @@ action = function()
local req = RIPng.Request:new( { RIPng.RTE:new("0::", 0, 0, 16) } ) local req = RIPng.Request:new( { RIPng.RTE:new("0::", 0, 0, 16) } )
local host, port = "FF02::9", { number = 521, protocol = "udp" } local host, port = "FF02::9", { number = 521, protocol = "udp" }
local iface = nmap.get_interface() local iface
local collect_interface = function (if_table)
if not iface and if_table.up == "up" and if_table.link == "ethernet"
and if_table.address and if_table.address:match(":") then
iface = if_table.device
end
end
stdnse.get_script_interfaces(collect_interface)
local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME..".timeout")) local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME..".timeout"))
timeout = (timeout or 5) * 1000 timeout = (timeout or 5) * 1000

View File

@@ -36,24 +36,33 @@ license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"broadcast", "safe"} categories = {"broadcast", "safe"}
-- preliminary checks
local interface = stdnse.get_script_args(SCRIPT_NAME .. ".interface") or nmap.get_interface()
prerule = function() prerule = function()
if not nmap.is_privileged() then if not nmap.is_privileged() then
stdnse.verbose1("Not running for lack of privileges.") stdnse.verbose1("Not running for lack of privileges.")
return false return false
end end
if nmap.address_family() ~= "inet" then
local has_interface = ( interface ~= nil ) stdnse.verbose1("Script is IPv4-only")
if ( not(has_interface) ) then
stdnse.verbose1("No network interface was supplied, aborting.")
return false return false
end end
return true return true
end end
action = function(host, port) action = function(host, port)
-- preliminary checks
local interface
local collect_interface = function (if_table)
if not interface and if_table.up == "up" and
if_table.address and if_table.address:match("^%d+%.%d+%.%d+%.%d+$") then
interface = if_table.device
end
end
stdnse.get_script_interfaces(collect_interface)
if not interface then
stdnse.verbose1("No network interface was supplied, aborting.")
return false
end
local sock, co local sock, co
sock = nmap.new_socket() sock = nmap.new_socket()

View File

@@ -52,27 +52,12 @@ local function createRequestList(req_list)
end end
-- Gets a list of available interfaces based on link and up filters local function filter_interfaces(iface)
-- if ( iface.link == "ethernet" and iface.up == "up" ) then
-- @param link string containing the link type to filter return iface
-- @param up string containing the interface status to filter
-- @return result table containing the matching interfaces
local function getInterfaces(link, up)
if( not(nmap.list_interfaces) ) then return end
local interfaces, err = nmap.list_interfaces()
local result
if ( not(err) ) then
for _, iface in ipairs(interfaces) do
if ( iface.link == link and iface.up == up ) then
result = result or {}
result[iface.device] = true
end
end
end end
return result
end end
local function parseDHCPResponse(response) local function parseDHCPResponse(response)
for _, v in ipairs(response.options) do for _, v in ipairs(response.options) do
if ( "WPAD" == v.name ) then if ( "WPAD" == v.name ) then
@@ -135,7 +120,7 @@ local function enumWPADNames(domain)
end end
local function dnsDiscover() local function dnsDiscover(interfaces)
-- first try a domain if it was supplied -- first try a domain if it was supplied
if ( arg_domain ) then if ( arg_domain ) then
local status, response = enumWPADNames(arg_domain) local status, response = enumWPADNames(arg_domain)
@@ -147,9 +132,7 @@ local function dnsDiscover()
-- if no domain was supplied, attempt to reverse lookup every ip on each -- if no domain was supplied, attempt to reverse lookup every ip on each
-- interface to find our FQDN hostname, once we do, try to query for WPAD -- interface to find our FQDN hostname, once we do, try to query for WPAD
for i in pairs(getInterfaces("ethernet", "up") or {}) do for _, iface in ipairs(interfaces) do
local iface, err = nmap.get_interface_info(i)
if ( iface ) then
local status, response = dns.query( dns.reverse(iface.address), { dtype = 'PTR', retAll = true } ) local status, response = dns.query( dns.reverse(iface.address), { dtype = 'PTR', retAll = true } )
-- did we get a name back from dns? -- did we get a name back from dns?
@@ -175,19 +158,16 @@ local function dnsDiscover()
end end
end
end end
return false, "Failed to find WPAD using DNS" return false, "Failed to find WPAD using DNS"
end end
local function dhcpDiscover() local function dhcpDiscover(interfaces)
-- send a DHCP discover on all ethernet interfaces that are up -- send a DHCP discover on all ethernet interfaces that are up
for i in pairs(getInterfaces("ethernet", "up") or {}) do for _, iface in ipairs(interfaces) do
local iface, err = nmap.get_interface_info(i)
if ( iface ) then
local req_list = createRequestList( { 1, 15, 3, 6, 44, 46, 47, 31, 33, 249, 43, 252 } ) local req_list = createRequestList( { 1, 15, 3, 6, 44, 46, 47, 31, 33, 249, 43, 252 } )
local status, response = dhcp.make_request("255.255.255.255", dhcp.request_types["DHCPDISCOVER"], "0.0.0.0", iface.mac, nil, req_list, { flags = 0x8000 } ) local status, response = dhcp.make_request("255.255.255.255", dhcp.request_types["DHCPDISCOVER"], "0.0.0.0", iface.mac, nil, req_list, { flags = 0x8000 } )
@@ -195,7 +175,6 @@ local function dhcpDiscover()
if (status) then if (status) then
return status, response return status, response
end end
end
end end
end end
@@ -204,6 +183,7 @@ local function fail (err) return stdnse.format_output(false, err) end
action = function() action = function()
local interfaces = stdnse.get_script_interfaces(filter_interfaces)
local status, response, wpad local status, response, wpad
if ( arg_nodhcp and arg_nodns ) then if ( arg_nodhcp and arg_nodns ) then
@@ -212,7 +192,7 @@ action = function()
end end
if ( nmap.is_privileged() and not(arg_nodhcp) ) then if ( nmap.is_privileged() and not(arg_nodhcp) ) then
status, response = dhcpDiscover() status, response = dhcpDiscover(interfaces)
if ( status ) then if ( status ) then
status, wpad = parseDHCPResponse(response) status, wpad = parseDHCPResponse(response)
end end
@@ -220,7 +200,7 @@ action = function()
-- if the DHCP did not get a result, fallback to DNS -- if the DHCP did not get a result, fallback to DNS
if (not(status) and not(arg_nodns) ) then if (not(status) and not(arg_nodns) ) then
status, response = dnsDiscover() status, response = dnsDiscover(interfaces)
if ( not(status) ) then if ( not(status) ) then
local services = "DNS" .. ( nmap.is_privileged() and "/DHCP" or "" ) local services = "DNS" .. ( nmap.is_privileged() and "/DHCP" or "" )
return fail(("Could not find WPAD using %s"):format(services)) return fail(("Could not find WPAD using %s"):format(services))

View File

@@ -49,24 +49,17 @@ local UNKNOWN = "unknown"
action = function() action = function()
local arg_interface = stdnse.get_script_args(SCRIPT_NAME .. ".interface")
local arg_identity = stdnse.get_script_args(SCRIPT_NAME .. ".identity") local arg_identity = stdnse.get_script_args(SCRIPT_NAME .. ".identity")
local arg_scan = stdnse.get_script_args(SCRIPT_NAME .. ".scan") local arg_scan = stdnse.get_script_args(SCRIPT_NAME .. ".scan")
local arg_timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout")) local arg_timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout"))
local iface local iface
-- trying with provided interface name local collect_interface = function (if_table)
if arg_interface then if not iface and if_table.up == "up" and if_table.link == "ethernet" then
iface = nmap.get_interface_info(arg_interface) iface = if_table
end
-- trying with default nmap interface
if not iface then
local iname = nmap.get_interface()
if iname then
iface = nmap.get_interface_info(iname)
end end
end end
stdnse.get_script_interfaces(collect_interface)
-- failed -- failed
if not iface then if not iface then

View File

@@ -38,10 +38,19 @@ categories = {"safe", "discovery"}
local arg_target = stdnse.get_script_args(SCRIPT_NAME .. ".target") local arg_target = stdnse.get_script_args(SCRIPT_NAME .. ".target")
hostrule = function(host) hostrule = function(host)
if nmap.address_family() ~= 'inet' then
stdnse.verbose1("Script is IPv4-only")
return false
end
if ( not(host.mac_addr) ) then if ( not(host.mac_addr) ) then
stdnse.debug1("Failed to determine hosts remote MAC address" ) stdnse.debug1("Failed to determine hosts remote MAC address" )
return false
end end
return (arg_target ~= nil and host.mac_addr ~= nil) if not arg_target then
stdnse.verbose1("Required argument %s.target not given", SCRIPT_NAME)
return false
end
return true
end end

View File

@@ -248,20 +248,12 @@ do
table.sort(multicast_ranges, sort_ip_ascending) table.sort(multicast_ranges, sort_ip_ascending)
end end
local function get_interfaces() local function filter_interfaces(if_nfo)
local if_list = nmap.list_interfaces() if (if_nfo.link == "ethernet" -- not the loopback interface
local if_ret = {}
local arg_interface = stdnse.get_script_args(SCRIPT_NAME .. ".interface") or nmap.get_interface()
for _, if_nfo in pairs(if_list) do
if (arg_interface == nil or if_nfo.device == arg_interface) -- check for correct interface
and ipOps.ip_in_range(if_nfo.address, "fe80::/10") -- link local address and ipOps.ip_in_range(if_nfo.address, "fe80::/10") -- link local address
and if_nfo.link == "ethernet" then -- not the loopback interface ) then
table.insert(if_ret, if_nfo) return if_nfo
end
end end
return if_ret
end end
local function single_interface_broadcast(if_nfo, results) local function single_interface_broadcast(if_nfo, results)
@@ -327,7 +319,7 @@ action = function()
local threads = {} local threads = {}
local condvar = nmap.condvar(results) local condvar = nmap.condvar(results)
for _, if_nfo in ipairs(get_interfaces()) do for _, if_nfo in ipairs(stdnse.get_script_interfaces(filter_interfaces)) do
-- create a thread for each interface -- create a thread for each interface
local co = stdnse.new_thread(single_interface_broadcast, if_nfo, results) local co = stdnse.new_thread(single_interface_broadcast, if_nfo, results)
threads[co] = true threads[co] = true

View File

@@ -58,23 +58,12 @@ prerule = function()
return false return false
end end
if not stdnse.get_script_args(SCRIPT_NAME .. ".interface") and not nmap.get_interface() then
stdnse.debug1("No interface was selected, aborting...")
return false
end
return true return true
end end
local function get_interface() local function filter_interfaces(if_table)
local arg_interface = stdnse.get_script_args(SCRIPT_NAME .. ".interface") or nmap.get_interface() if if_table.up == "up" and ipOps.ip_to_str(if_table.address) and if_table.link == "ethernet" then
local if_table = nmap.get_interface_info(arg_interface)
if if_table and ipOps.ip_to_str(if_table.address) and if_table.link == "ethernet" then
return if_table.device return if_table.device
else
stdnse.debug1("Interface %s not supported or not properly configured, exiting...", arg_interface)
end end
end end
@@ -191,7 +180,14 @@ local function broadcast_on_interface(iface)
end end
function action() function action()
local interface = get_interface() local interface
local interfaces = stdnse.get_script_interfaces(filter_interfaces)
if #interfaces == 1 then
interface = interfaces[1]
else
stdnse.debug1("No interface was selected, aborting...")
return nil
end
broadcast_on_interface(interface) broadcast_on_interface(interface)
end end

View File

@@ -215,7 +215,7 @@ end
--- Returns the network interface used to send packets to a target host. --- Returns the network interface used to send packets to a target host.
-- @param target host to which the interface is used. -- @param target host to which the interface is used.
-- @return interface Network interface used for target host. -- @return interface Network interface used for target host.
local getInterface = function(target) local getInterface = function(interfaces, target)
-- First, create dummy UDP connection to get interface -- First, create dummy UDP connection to get interface
local sock = nmap.new_socket() local sock = nmap.new_socket()
local status, err = sock:connect(target, "12345", "udp") local status, err = sock:connect(target, "12345", "udp")
@@ -228,13 +228,19 @@ local getInterface = function(target)
stdnse.verbose1("%s", err) stdnse.verbose1("%s", err)
return return
end end
for _, interface in pairs(nmap.list_interfaces()) do for _, interface in ipairs(interfaces) do
if interface.address == address then if interface.address == address then
return interface return interface
end end
end end
end end
local filter_interfaces = function (if_table)
if if_table.up == "up" and if_table.address:match("%d+%.%d+%.%d+%.%d+") then
return if_table
end
end
--- Make a dummy connection and return a free source port --- Make a dummy connection and return a free source port
-- @param target host to which the interface is used. -- @param target host to which the interface is used.
-- @return lport Local port which can be used in KNX messages. -- @return lport Local port which can be used in KNX messages.
@@ -254,12 +260,15 @@ action = function()
local lport = getSourcePort(mcast) local lport = getSourcePort(mcast)
-- Check if a valid interface was provided -- Check if a valid interface was provided
local interface = nmap.get_interface() local interface
if interface then local interfaces = stdnse.get_script_interfaces(filter_interfaces)
interface = nmap.get_interface_info(interface) if #interfaces > 1 then
else -- TODO: send on multiple interfaces
interface = getInterface(mcast) interface = getInterface(interfaces, mcast)
elseif #interfaces == 1 then
interface = interfaces[1]
end end
if not interface then if not interface then
return ("\n ERROR: Couldn't get interface for %s"):format(mcast) return ("\n ERROR: Couldn't get interface for %s"):format(mcast)
end end

View File

@@ -135,7 +135,7 @@ end
-- Returns the network interface used to send packets to a target host. -- Returns the network interface used to send packets to a target host.
--@param target host to which the interface is used. --@param target host to which the interface is used.
--@return interface Network interface used for target host. --@return interface Network interface used for target host.
local getInterface = function(target) local getInterface = function(interfaces, target)
-- First, create dummy UDP connection to get interface -- First, create dummy UDP connection to get interface
local sock = nmap.new_socket() local sock = nmap.new_socket()
local status, err = sock:connect(target, "12345", "udp") local status, err = sock:connect(target, "12345", "udp")
@@ -148,13 +148,19 @@ local getInterface = function(target)
stdnse.verbose1("%s", err) stdnse.verbose1("%s", err)
return return
end end
for _, interface in pairs(nmap.list_interfaces()) do for _, interface in pairs(interfaces) do
if interface.address == address then if interface.address == address then
return interface return interface
end end
end end
end end
local filter_interfaces = function (if_table)
if if_table.up == "up" and if_table.address:match("%d+%.%d+%.%d+%.%d+") then
return if_table
end
end
action = function() action = function()
local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout")) local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout"))
@@ -171,12 +177,15 @@ action = function()
end end
-- Check if a valid interface was provided -- Check if a valid interface was provided
local interface = nmap.get_interface() local interface
if interface then local interfaces = stdnse.get_script_interfaces(filter_interfaces)
interface = nmap.get_interface_info(interface) if #interfaces > 1 then
else -- TODO: send on multiple interfaces
interface = getInterface(mcast) interface = getInterface(interfaces, mcast)
elseif #interfaces == 1 then
interface = interfaces[1]
end end
if not interface then if not interface then
return stdnse.format_output(false, ("Couldn't get interface for %s"):format(mcast)) return stdnse.format_output(false, ("Couldn't get interface for %s"):format(mcast))
end end

View File

@@ -244,38 +244,18 @@ local LLTDDiscover = function(if_table, lltd_responders, timeout)
condvar("signal") condvar("signal")
end end
local function filter_interfaces (if_table)
if if_table and if_table.up == "up" and if_table.link=="ethernet" then
return if_table
end
return nil
end
action = function() action = function()
local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME..".timeout")) local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME..".timeout"))
timeout = timeout or 30 timeout = timeout or 30
--get interface script-args, if any
local interface_arg = stdnse.get_script_args(SCRIPT_NAME .. ".interface")
local interface_opt = nmap.get_interface()
-- interfaces list (decide which interfaces to broadcast on) -- interfaces list (decide which interfaces to broadcast on)
local interfaces ={} local interfaces = {}
if interface_opt or interface_arg then local collect_interfaces = function (if_table)
-- single interface defined if if_table.up == "up" and if_table.link=="ethernet" then
local interface = interface_opt or interface_arg interfaces[if_table.device] = if_table
local if_table = filter_interfaces(nmap.get_interface_info(interface))
if not if_table then
stdnse.debug1("Interface not supported or not properly configured.")
return false
end
interfaces[if_table.device] = if_table
else
local tmp_ifaces = nmap.list_interfaces()
for _, if_table in ipairs(tmp_ifaces) do
interfaces[if_table.device] = filter_interfaces(if_table)
end end
end end
stdnse.get_script_interfaces(collect_interfaces)
if not next(interfaces) then if not next(interfaces) then
stdnse.debug1("No interfaces found.") stdnse.debug1("No interfaces found.")

View File

@@ -216,7 +216,7 @@ end
-- Returns the network interface used to send packets to a target host. -- Returns the network interface used to send packets to a target host.
--@param target host to which the interface is used. --@param target host to which the interface is used.
--@return interface Network interface used for target host. --@return interface Network interface used for target host.
local getInterface = function(target) local getInterface = function(interfaces, target)
-- First, create dummy UDP connection to get interface -- First, create dummy UDP connection to get interface
local sock = nmap.new_socket() local sock = nmap.new_socket()
local status, err = sock:connect(target, "12345", "udp") local status, err = sock:connect(target, "12345", "udp")
@@ -229,13 +229,19 @@ local getInterface = function(target)
stdnse.verbose1("%s", err) stdnse.verbose1("%s", err)
return return
end end
for _, interface in pairs(nmap.list_interfaces()) do for _, interface in ipairs(interfaces) do
if interface.address == address then if interface.address == address then
return interface return interface
end end
end end
end end
local filter_interfaces = function (if_table)
if if_table.up == "up" and if_table.address:match("%d+%.%d+%.%d+%.%d+") then
return if_table
end
end
action = function() action = function()
local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout")) local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout"))
timeout = (timeout or 5) * 1000 timeout = (timeout or 5) * 1000
@@ -243,12 +249,14 @@ action = function()
local responses = {} local responses = {}
local interface, result local interface, result
interface = nmap.get_interface() local interfaces = stdnse.get_script_interfaces(filter_interfaces)
if interface then if #interfaces > 1 then
interface = nmap.get_interface_info(interface) -- TODO: send on multiple interfaces
else interface = getInterface(interfaces, target)
interface = getInterface(target) elseif #interfaces == 1 then
interface = interfaces[1]
end end
if not interface then if not interface then
return stdnse.format_output(false, ("Couldn't get interface for %s"):format(target)) return stdnse.format_output(false, ("Couldn't get interface for %s"):format(target))
end end

View File

@@ -283,7 +283,7 @@ end
-- Returns the network interface used to send packets to a target host. -- Returns the network interface used to send packets to a target host.
--@param target host to which the interface is used. --@param target host to which the interface is used.
--@return interface Network interface used for target host. --@return interface Network interface used for target host.
local getInterface = function(target) local getInterface = function(interfaces, target)
-- First, create dummy UDP connection to get interface -- First, create dummy UDP connection to get interface
local sock = nmap.new_socket() local sock = nmap.new_socket()
local status, err = sock:connect(target, "12345", "udp") local status, err = sock:connect(target, "12345", "udp")
@@ -296,13 +296,19 @@ local getInterface = function(target)
stdnse.verbose1("%s", err) stdnse.verbose1("%s", err)
return return
end end
for _, interface in pairs(nmap.list_interfaces()) do for _, interface in pairs(interfaces) do
if interface.address == address then if interface.address == address then
return interface return interface
end end
end end
end end
local filter_interfaces = function (if_table)
if if_table.up == "up" and if_table.address:match("%d+%.%d+%.%d+%.%d+") then
return if_table
end
end
action = function() action = function()
local fromip = stdnse.get_script_args(SCRIPT_NAME .. ".fromip") local fromip = stdnse.get_script_args(SCRIPT_NAME .. ".fromip")
@@ -320,11 +326,13 @@ action = function()
end end
-- Get network interface to use -- Get network interface to use
local interface = nmap.get_interface() local interface
if interface then local interfaces = stdnse.get_script_interfaces(filter_interfaces)
interface = nmap.get_interface_info(interface) if #interfaces > 1 then
else -- TODO: send on multiple interfaces
interface = getInterface(firsthop) interface = getInterface(interfaces, firsthop)
elseif #interfaces == 1 then
interface = interfaces[1]
end end
if not interface then if not interface then
return stdnse.format_output(false, ("Couldn't get interface for %s"):format(firsthop)) return stdnse.format_output(false, ("Couldn't get interface for %s"):format(firsthop))

View File

@@ -298,38 +298,6 @@ parse_pndcp = function(eth_data, pn_data)
return device return device
end end
-- get all possible interfaces
--@param link type of interface e.g. "ethernet"
--@param up status of the interface
--@return result table with all interfaces which match the given requirements
getInterfaces = function(link, up)
if( not(nmap.list_interfaces) ) then return end
local interfaces, err = nmap.list_interfaces()
local result = {}
if ( not(err) ) then
for _, iface in ipairs(interfaces) do
if ( iface.link == link and
iface.up == up and
iface.mac ) then
if #result == 0 then
table.insert(result, iface)
else
local exists = false
for _, intface in ipairs(result) do
if intface.mac == iface.mac then
exists = true
end
end
if not exists then
table.insert(result, iface)
end
end
end
end
end
return result
end
-- helpfunction for thread call -- helpfunction for thread call
--@param iface interface table --@param iface interface table
@@ -369,8 +337,6 @@ end
--@return 0 if no devices were found --@return 0 if no devices were found
--@return output_tab table for nmap to show the gathered information --@return output_tab table for nmap to show the gathered information
action = function() action = function()
local interface_e = nmap.get_interface()
local interfaces = {}
local output_tab = stdnse.output_table() local output_tab = stdnse.output_table()
output_tab.devices = {} output_tab.devices = {}
@@ -381,17 +347,15 @@ action = function()
local pcap_s = nmap.new_socket() local pcap_s = nmap.new_socket()
pcap_s:set_timeout(4000) pcap_s:set_timeout(4000)
local macs = {}
if(interface_e) then -- interface supplied with -e local filter_interfaces = function (iface)
local iface = nmap.get_interface_info(interface_e) if iface.link == "ethernet" and iface.up == "up" and
if not (iface and iface.link == 'ethernet') then iface.mac and not macs[iface.mac] then
stdnse.debug(1, "%s not supported with %s", iface, SCRIPT_NAME) macs[iface.mac] = true
return false return iface
end end
table.insert(interfaces, iface)
else -- discover interfaces
interfaces = getInterfaces("ethernet", "up")
end end
local interfaces = stdnse.get_script_interfaces(filter_interfaces)
-- check if at least one interface is available -- check if at least one interface is available
if #interfaces == 0 then if #interfaces == 0 then

View File

@@ -34,29 +34,10 @@ prerule = function()
return nmap.is_privileged() return nmap.is_privileged()
end end
local function get_interfaces() local function filter_interfaces(if_table)
local interface_name = stdnse.get_script_args(SCRIPT_NAME .. ".interface") if ipOps.ip_to_str(if_table.address) and if_table.link == "ethernet" then
or nmap.get_interface() return if_table
-- interfaces list (decide which interfaces to broadcast on)
local interfaces = {}
if interface_name then
-- single interface defined
local if_table = nmap.get_interface_info(interface_name)
if if_table and ipOps.ip_to_str(if_table.address) and if_table.link == "ethernet" then
interfaces[#interfaces + 1] = if_table
else
stdnse.debug1("Interface not supported or not properly configured.")
end
else
for _, if_table in ipairs(nmap.list_interfaces()) do
if ipOps.ip_to_str(if_table.address) and if_table.link == "ethernet" then
table.insert(interfaces, if_table)
end
end
end end
return interfaces
end end
local function single_interface_broadcast(if_nfo, results) local function single_interface_broadcast(if_nfo, results)
@@ -150,7 +131,7 @@ action = function()
local results = {} local results = {}
local condvar = nmap.condvar(results) local condvar = nmap.condvar(results)
for _, if_nfo in ipairs(get_interfaces()) do for _, if_nfo in ipairs(stdnse.get_script_interfaces(filter_interfaces)) do
-- create a thread for each interface -- create a thread for each interface
local co = stdnse.new_thread(single_interface_broadcast, if_nfo, results) local co = stdnse.new_thread(single_interface_broadcast, if_nfo, results)
threads[co] = true threads[co] = true

View File

@@ -49,29 +49,10 @@ local function build_invalid_extension_header(nxt_hdr)
"\x80\x01\x00\x00\x00\x00" "\x80\x01\x00\x00\x00\x00"
end end
local function get_interfaces() local function filter_interfaces(if_table)
local interface_name = stdnse.get_script_args(SCRIPT_NAME .. ".interface") if ipOps.ip_to_str(if_table.address) and if_table.link == "ethernet" then
or nmap.get_interface() return if_table
-- interfaces list (decide which interfaces to broadcast on)
local interfaces = {}
if interface_name then
-- single interface defined
local if_table = nmap.get_interface_info(interface_name)
if if_table and ipOps.ip_to_str(if_table.address) and if_table.link == "ethernet" then
interfaces[#interfaces + 1] = if_table
else
stdnse.debug1("Interface not supported or not properly configured.")
end
else
for _, if_table in ipairs(nmap.list_interfaces()) do
if ipOps.ip_to_str(if_table.address) and if_table.link == "ethernet" then
table.insert(interfaces, if_table)
end
end
end end
return interfaces
end end
local function single_interface_broadcast(if_nfo, results) local function single_interface_broadcast(if_nfo, results)
@@ -179,7 +160,7 @@ action = function()
local results = {} local results = {}
local condvar = nmap.condvar(results) local condvar = nmap.condvar(results)
for _, if_nfo in ipairs(get_interfaces()) do for _, if_nfo in ipairs(stdnse.get_script_interfaces(filter_interfaces)) do
-- create a thread for each interface -- create a thread for each interface
local co = stdnse.new_thread(single_interface_broadcast, if_nfo, results) local co = stdnse.new_thread(single_interface_broadcast, if_nfo, results)
threads[co] = true threads[co] = true

View File

@@ -64,21 +64,11 @@ prerule = function()
end end
local function get_interfaces() local function filter_interfaces(if_table)
local interface_name = stdnse.get_script_args(SCRIPT_NAME .. ".interface") if ipOps.ip_in_range(if_table.address, "fe80::/10") -- link local address
or nmap.get_interface() and if_table.link == "ethernet" then -- not the loopback interface
return if_table
-- interfaces list (decide which interfaces to broadcast on)
local interfaces = {}
for _, if_table in pairs(nmap.list_interfaces()) do
if (interface_name == nil or if_table.device == interface_name) -- check for correct interface
and ipOps.ip_in_range(if_table.address, "fe80::/10") -- link local address
and if_table.link == "ethernet" then -- not the loopback interface
table.insert(interfaces, if_table)
end
end end
return interfaces
end end
local function single_interface_broadcast(if_nfo, results) local function single_interface_broadcast(if_nfo, results)
@@ -127,7 +117,7 @@ action = function()
local results = {} local results = {}
local condvar = nmap.condvar(results) local condvar = nmap.condvar(results)
for _, if_nfo in ipairs(get_interfaces()) do for _, if_nfo in ipairs(stdnse.get_script_interfaces(filter_interfaces)) do
-- create a thread for each interface -- create a thread for each interface
local co = stdnse.new_thread(single_interface_broadcast, if_nfo, results) local co = stdnse.new_thread(single_interface_broadcast, if_nfo, results)
threads[co] = true threads[co] = true

View File

@@ -95,29 +95,10 @@ local function build_router_advert(mac_src,prefix,prefix_len,valid_time,preferre
return icmpv6_payload return icmpv6_payload
end end
local function get_interfaces() local function filter_interfaces(if_table)
local interface_name = stdnse.get_script_args(SCRIPT_NAME .. ".interface") if ipOps.ip_to_str(if_table.address) and if_table.link == "ethernet" then
or nmap.get_interface() return if_table
-- interfaces list (decide which interfaces to broadcast on)
local interfaces = {}
if interface_name then
-- single interface defined
local if_table = nmap.get_interface_info(interface_name)
if if_table and ipOps.ip_to_str(if_table.address) and if_table.link == "ethernet" then
interfaces[#interfaces + 1] = if_table
else
stdnse.debug1("Interface not supported or not properly configured.")
end
else
for _, if_table in ipairs(nmap.list_interfaces()) do
if ipOps.ip_to_str(if_table.address) and if_table.link == "ethernet" then
table.insert(interfaces, if_table)
end
end
end end
return interfaces
end end
local function single_interface_broadcast(if_nfo, results) local function single_interface_broadcast(if_nfo, results)
@@ -235,7 +216,7 @@ action = function()
local results = {} local results = {}
local condvar = nmap.condvar(results) local condvar = nmap.condvar(results)
for _, if_nfo in ipairs(get_interfaces()) do for _, if_nfo in ipairs(stdnse.get_script_interfaces(filter_interfaces)) do
-- create a thread for each interface -- create a thread for each interface
if ipOps.ip_in_range(if_nfo.address, "fe80::/10") then if ipOps.ip_in_range(if_nfo.address, "fe80::/10") then
local co = stdnse.new_thread(single_interface_broadcast, if_nfo, results) local co = stdnse.new_thread(single_interface_broadcast, if_nfo, results)

View File

@@ -15,15 +15,15 @@ by default) and prints discovered addresses. If the
<code>newtargets</code> script argument is set, discovered addresses <code>newtargets</code> script argument is set, discovered addresses
are added to the scan queue. are added to the scan queue.
Requires root privileges. Either the <code>targets-sniffer.iface</code> script Requires root privileges. Either the <code>targets-sniffer.interface</code> script
argument or <code>-e</code> Nmap option to define which interface to use. argument or <code>-e</code> Nmap option to define which interface to use.
]] ]]
--- ---
-- @usage -- @usage
-- nmap -sL --script=targets-sniffer --script-args=newtargets,targets-sniffer.timeout=5s,targets-sniffer.iface=eth0 -- nmap -sL --script=targets-sniffer --script-args=newtargets,targets-sniffer.timeout=5s,targets-sniffer.interface=eth0
-- @args targets-sniffer.timeout The amount of time to listen for packets. Default <code>10s</code>. -- @args targets-sniffer.timeout The amount of time to listen for packets. Default <code>10s</code>.
-- @args targets-sniffer.iface The interface to use for sniffing. -- @args targets-sniffer.interface The interface to use for sniffing.
-- @output -- @output
-- Pre-scan script results: -- Pre-scan script results:
-- | targets-sniffer: -- | targets-sniffer:
@@ -65,10 +65,14 @@ local function get_ip_addresses(layer3)
end end
prerule = function() prerule = function()
return nmap.is_privileged() and return nmap.is_privileged()
(stdnse.get_script_args("targets-sniffer.iface") or nmap.get_interface())
end end
local function collect_interface(if_table)
if not interface_info and if_table.up == "up" and if_table.link ~= "loopback" then
interface_info = if_table
end
end
action = function() action = function()
@@ -77,11 +81,17 @@ action = function()
local ip_counter = 0 local ip_counter = 0
local timeout = stdnse.parse_timespec(stdnse.get_script_args("targets-sniffer.timeout")) local timeout = stdnse.parse_timespec(stdnse.get_script_args("targets-sniffer.timeout"))
timeout = (timeout or 10) * 1000 timeout = (timeout or 10) * 1000
local interface = stdnse.get_script_args("targets-sniffer.iface") or nmap.get_interface() -- TODO: sniff on all interfaces
interface_info = nmap.get_interface_info(interface) -- NOTE: targets-sniffer.iface script-arg name is non-standard, but left for compatibility.
local interface = stdnse.get_script_args("targets-sniffer.iface")
if interface then
interface_info = nmap.get_interface_info(interface)
else
stdnse.get_script_interfaces(collect_interface)
end
if interface_info==nil then -- Check if we have the interface information if interface_info==nil then -- Check if we have the interface information
stdnse.debug1("Error: Unable to get interface info. Did you specify the correct interface using 'targets-sniffer.iface=<interface>' or '-e <interface>'?") stdnse.debug1("Error: Unable to get interface info. Did you specify the correct interface using 'targets-sniffer.interface=<interface>' or '-e <interface>'?")
return return
end end

View File

@@ -37,18 +37,11 @@ license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"safe"} categories = {"safe"}
local arg_iface = nmap.get_interface() or stdnse.get_script_args(SCRIPT_NAME .. ".interface")
prerule = function() prerule = function()
local has_interface = ( arg_iface ~= nil )
if not nmap.is_privileged() then if not nmap.is_privileged() then
stdnse.verbose1("not running for lack of privileges.") stdnse.verbose1("not running for lack of privileges.")
return false return false
end end
if ( not(has_interface) ) then
stdnse.verbose1("no network interface was supplied, aborting ...")
return false
end
return true return true
end end
@@ -102,6 +95,19 @@ local function log_entry(src_ip, url)
end end
action = function() action = function()
local arg_iface
local collect_interface = function (if_table)
if not arg_iface and if_table.up == "up" and if_table.link ~= "loopback" then
arg_iface = if_table.device
end
end
stdnse.get_script_interfaces(collect_interface)
if not arg_iface then
stdnse.verbose1("no network interface was supplied, aborting ...")
return false
end
local counter = 0 local counter = 0
if ( arg_outfile ) then if ( arg_outfile ) then