Lucene search

K
nmapPatrik KarlssonNMAP:BROADCAST-RIP-DISCOVER.NSE
HistoryNov 02, 2011 - 10:23 a.m.

broadcast-rip-discover NSE Script

2011-11-0210:23:50
Patrik Karlsson
nmap.org
112

9.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

10 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:N/C:C/I:C/A:C

0.973 High

EPSS

Percentile

99.8%

Discovers hosts and routing information from devices running RIPv2 on the LAN. It does so by sending a RIPv2 Request command and collects the responses from all devices responding to the request.

Script Arguments

broadcast-rip-discover.timeout

timespec defining how long to wait for a response. (default 5s)

Example Usage

nmap --script broadcast-rip-discover

Script Output

Pre-scan script results:
| broadcast-rip-discover:
| Discovered RIPv2 devices
|   10.0.200.107
|     ip           netmask        nexthop       metric
|     10.46.100.0  255.255.255.0  0.0.0.0       1
|     10.46.110.0  255.255.255.0  0.0.0.0       1
|     10.46.120.0  255.255.255.0  0.0.0.0       1
|     10.46.123.0  255.255.255.0  10.0.200.123  1
|     10.46.124.0  255.255.255.0  10.0.200.124  1
|     10.46.125.0  255.255.255.0  10.0.200.125  1
|   10.0.200.101
|     ip       netmask  nexthop     metric
|_    0.0.0.0  0.0.0.0  10.0.200.1  1

Requires


local ipOps = require "ipOps"
local nmap = require "nmap"
local stdnse = require "stdnse"
local string = require "string"
local tab = require "tab"
local table = require "table"

description=[[
Discovers hosts and routing information from devices running RIPv2 on the
LAN. It does so by sending a RIPv2 Request command and collects the responses
from all devices responding to the request.
]]

---
-- @usage
-- nmap --script broadcast-rip-discover
--
-- @output
-- Pre-scan script results:
-- | broadcast-rip-discover:
-- | Discovered RIPv2 devices
-- |   10.0.200.107
-- |     ip           netmask        nexthop       metric
-- |     10.46.100.0  255.255.255.0  0.0.0.0       1
-- |     10.46.110.0  255.255.255.0  0.0.0.0       1
-- |     10.46.120.0  255.255.255.0  0.0.0.0       1
-- |     10.46.123.0  255.255.255.0  10.0.200.123  1
-- |     10.46.124.0  255.255.255.0  10.0.200.124  1
-- |     10.46.125.0  255.255.255.0  10.0.200.125  1
-- |   10.0.200.101
-- |     ip       netmask  nexthop     metric
-- |_    0.0.0.0  0.0.0.0  10.0.200.1  1
--
-- @args broadcast-rip-discover.timeout timespec defining how long to wait for
--       a response. (default 5s)

--
-- Version 0.1
-- Created 29/10/2011 - v0.1 - created by Patrik Karlsson <[email protected]>
--

author = "Patrik Karlsson"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"broadcast", "safe"}


prerule = function() return not( nmap.address_family() == "inet6") end

RIPv2 = {

  Command = {
    Request = 1,
    Response = 2,
  },

  AddressFamily = {
    IP = 2,
  },

  -- The Request class contains functions to build a RIPv2 Request
  Request = {

    -- Creates a new Request instance
    --
    -- @param command number containing the RIPv2 Command to use
    -- @return o instance of request
    new = function(self, command)
      local o = {
        version = 2,
        command = command,
        domain = 0,
        family = 0,
        tag =  0,
        address = 0,
        subnet = 0,
        nexthop = 0,
        metric = 16
      }
      setmetatable(o, self)
      self.__index = self
      return o
    end,

    -- Converts the whole request to a string
    __tostring = function(self)
      assert(self.command, "No command was supplied")
      assert(self.metric, "No metric was supplied")
      assert(self.address, "No address was supplied")
      local RESERVED = 0
      -- RIPv2 stuff, should be 0 for RIPv1
      local tag, subnet, nexthop = 0, 0, 0

      local data = string.pack(">BB I2 I2 I2 I4 I4 I4 I4",
        self.command, self.version, self.domain, self.family, self.tag,
        self.address, self.subnet, self.nexthop, self.metric)

      return data
    end,

  },

  -- The Response class contains code needed to parse a RIPv2 response
  Response = {

    -- Creates a new Response instance based on raw socket data
    --
    -- @param data string containing the raw socket response
    -- @return o Response instance
    new = function(self, data)
      local o = { data = data }

      if ( not(data) or #data < 3 ) then
        return
      end
      local pos, _
      o.command, o.version, _, pos = string.unpack(">BBI2", data)
      if ( o.command ~= RIPv2.Command.Response or o.version ~= 2 ) then
        return
      end

      local routes = tab.new(2)
      tab.addrow(routes, "ip", "netmask", "nexthop", "metric")

      while( #data - pos >= 20 ) do
        local family, address, metric, netmask, nexthop
        family, _, address, netmask, nexthop,
          metric, pos = string.unpack(">I2 I2 I4 I4 I4 I4", data, pos)

        if ( family == RIPv2.AddressFamily.IP ) then
          local ip = ipOps.fromdword(address)
          netmask = ipOps.fromdword(netmask)
          nexthop = ipOps.fromdword(nexthop)
          tab.addrow(routes, ip, netmask, nexthop, metric)
        end
      end

      if ( #routes > 1 ) then o.routes = routes end

      setmetatable(o, self)
      self.__index = self
      return o
    end,

  }

}


action = function()
  local timeout = stdnse.parse_timespec(stdnse.get_script_args('broadcast-rip-discover.timeout'))
  timeout = (timeout or 5) * 1000

  local socket = nmap.new_socket("udp")
  socket:set_timeout(timeout)

  local rip = RIPv2.Request:new(RIPv2.Command.Request)
  local status, err = socket:sendto("224.0.0.9",
    { number = 520, protocol = "udp" },
    tostring(rip))
  local result = {}
  repeat
    local data
    status, data = socket:receive()
    if ( status ) then
      local status, _, _, rhost, _ = socket:get_info()
      local response = RIPv2.Response:new(data)
      table.insert(result, rhost)

      if ( response and response.routes and #response.routes > 0 ) then
        --response.routes.name = "Routes"
        table.insert(result, { tab.dump(response.routes) } )
      end

    end
  until( not(status) )

  if ( #result > 0 ) then
    result.name = "Discovered RIPv2 devices"
  end
  return stdnse.format_output(true, result)
end

9.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

10 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:N/C:C/I:C/A:C

0.973 High

EPSS

Percentile

99.8%

Related for NMAP:BROADCAST-RIP-DISCOVER.NSE