diff --git a/scripts/mrinfo.nse b/scripts/mrinfo.nse index 623146760..12522a2f4 100644 --- a/scripts/mrinfo.nse +++ b/scripts/mrinfo.nse @@ -3,52 +3,81 @@ local packet = require "packet" local ipOps = require "ipOps" local bin = require "bin" local stdnse = require "stdnse" -local string = require "string" local target = require "target" local table = require "table" description = [[ -Queries a target router for multicast information. +Queries targets for multicast routing information. This works by sending a DVMRP Ask Neighbors 2 request to the target and -listening for the DVMRP Neighbors 2 response that contains local addresses and -the multicast neighbors on each one. It is similar to the mrinfo utility included with Windows (Linux/UNIX versions are also available). +listening for DVMRP Neighbors 2 responses that are sent back and which contain +local addresses and the multicast neighbors on each interface of the target. If +no specific target is specified, the request will be sent to the 224.0.0.1 All +Hosts multicast address. +This script is similar somehow to the mrinfo utility included with Windows and +Cisco IOS. ]] - --- --- @args mrinfo.timeout Time to wait for a response in seconds. +-- @args mrinfo.target Host to which the request is sent. If not set, the +-- request will be sent to 224.0.0.1. +-- +-- @args mrinfo.timeout Time to wait for responses in seconds. -- Defaults to 5 seconds. -- --@usage --- nmap --script mrinfo +-- nmap --script mrinfo +-- nmap --script mrinfo -e eth1 +-- nmap --script mrinfo --script-args 'mrinfo.target=172.16.0.4' -- --@output --- Host script results: +-- Pre-scan script results: -- | mrinfo: --- | Version 12.4 --- | Local address: 192.168.2.2 --- | Neighbor: 192.168.2.4 --- | Neighbor: 192.168.2.3 --- | Local address: 192.168.13.1 --- | Neighbor: 192.168.13.3 --- |_ Use the newtargets script-arg to add the results as targets +-- | Source: 224.0.0.1 +-- | Version 12.4 +-- | Local address: 172.16.0.2 +-- | Neighbor: 172.16.0.4 +-- | Neighbor: 172.16.0.3 +-- | Local address: 172.17.0.1 +-- | Neighbor: 172.17.0.2 +-- | Local address: 172.18.0.1 +-- | Neighbor: 172.18.0.2 +-- | Source: 224.0.0.1 +-- | Version 12.4 +-- | Local address: 172.16.0.4 +-- | Neighbor: 172.16.0.3 +-- | Neighbor: 172.16.0.2 +-- | Local address: 172.17.0.2 +-- | Neighbor: 172.17.0.1 +-- | Source: 224.0.0.1 +-- | Version 12.4 +-- | Local address: 172.16.0.3 +-- | Neighbor: 172.16.0.4 +-- | Neighbor: 172.16.0.2 +-- | Local address: 172.18.0.2 +-- | Neighbor: 172.18.0.1 +-- |_ Use the newtargets script-arg to add the responses as targets +-- author = "Hani Benhabiles" license = "Same as Nmap--See http://nmap.org/book/man-legal.html" -categories = {"discovery", "safe"} +categories = {"discovery", "safe", "broadcast"} -hostrule = function(host) +prerule = function() if nmap.address_family() ~= 'inet' then stdnse.print_verbose("%s is IPv4 only.", SCRIPT_NAME) return false end + if not nmap.is_privileged() then + stdnse.print_verbose("%s not running for lack of privileges.", SCRIPT_NAME) + return false + end return true end @@ -56,11 +85,11 @@ end -- a structured response. -- @param data raw data. local mrinfoParse = function(data) - local index, interface, neighbor + local index, address, neighbor local response = {} - -- first byte should be IGMP type == 0x013 (DVMRP) - if data:byte(1) ~= 0x013 then return end + -- first byte should be IGMP type == 0x13 (DVMRP) + if data:byte(1) ~= 0x13 then return end -- DVMRP Code index, response.code = bin.unpack(">C", data, 2) @@ -71,49 +100,47 @@ local mrinfoParse = function(data) -- Major and minor version index, response.minver = bin.unpack(">C", data, index) index, response.majver = bin.unpack(">C", data, index) - response.interfaces = {} + response.addresses = {} -- Iterate over target local addresses (interfaces) while index < #data do if data:byte(index) == 0x00 then break end - interface = {} + address = {} -- Local address - index, interface.address = bin.unpack("C", data, index) + index, address.metric = bin.unpack(">C", data, index) -- Treshold - index, interface.treshold= bin.unpack(">C", data, index) + index, address.treshold= bin.unpack(">C", data, index) -- Flags - index, interface.flags = bin.unpack(">C", data, index) + index, address.flags = bin.unpack(">C", data, index) -- Number of neighbors - index, interface.ncount = bin.unpack(">C", data, index) + index, address.ncount = bin.unpack(">C", data, index) - interface.neighbors = {} + address.neighbors = {} -- Iterate over neighbors - for i = 1, interface.ncount do + for i = 1, address.ncount do index, neighbor = bin.unpack(" 0 then + if #responses > 0 then local output, ifoutput = {} - local response = results[1] - table.insert(output, ("Version %s.%s"):format(response.majver, response.minver)) - for _, interface in pairs(response.interfaces) do - ifoutput = {} - ifoutput.name = "Local address: " .. interface.address - for _, neighbor in pairs(interface.neighbors) do - if target.ALLOW_NEW_TARGETS then target.add(neighbor) end - table.insert(ifoutput, "Neighbor: " .. neighbor) + for _, response in pairs(responses) do + result = {} + result.name = "Source: " .. response.srcip + table.insert(result, ("Version %s.%s"):format(response.majver, response.minver)) + for _, address in pairs(response.addresses) do + ifoutput = {} + ifoutput.name = "Local address: " .. address.ip + for _, neighbor in pairs(address.neighbors) do + if target.ALLOW_NEW_TARGETS then target.add(neighbor) end + table.insert(ifoutput, "Neighbor: " .. neighbor) + end + table.insert(result, ifoutput) end - table.insert(output, ifoutput) + table.insert(output, result) end if not target.ALLOW_NEW_TARGETS then table.insert(output,"Use the newtargets script-arg to add the results as targets")