Lucene search

K
nmapPatrik KarlssonNMAP:REVERSE-INDEX.NSE
HistoryNov 29, 2011 - 12:48 a.m.

reverse-index NSE Script

2011-11-2900:48:59
Patrik Karlsson
nmap.org
61

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%

Creates a reverse index at the end of scan output showing which hosts run a particular service. This is in addition to Nmap’s normal output listing the services on each host.

Script Arguments

reverse-index.mode

the output display mode, can be either horizontal or vertical (default: horizontal)

reverse-index.names

If set, index results by service name instead of port number. Unknown services will be listed by port number.

Example Usage

nmap --script reverse-index <hosts/networks>

Script Output

Post-scan script results:
| reverse-index:
|   22/tcp: 192.168.0.60
|   23/tcp: 192.168.0.100
|   80/tcp: 192.168.0.70
|   445/tcp: 192.168.0.1
|   53/udp: 192.168.0.1, 192.168.0.60, 192.168.0.70, 192.168.0.105
|_  5353/udp: 192.168.0.1, 192.168.0.60, 192.168.0.70, 192.168.0.105

Requires


local ipOps = require "ipOps"
local nmap = require "nmap"
local outlib = require "outlib"
local stdnse = require "stdnse"
local table = require "table"
local tableaux = require "tableaux"

description = [[
Creates a reverse index at the end of scan output showing which hosts run a
particular service.  This is in addition to Nmap's normal output listing the
services on each host.
]]

---
-- @usage
-- nmap --script reverse-index <hosts/networks>
--
-- @output
-- Post-scan script results:
-- | reverse-index:
-- |   22/tcp: 192.168.0.60
-- |   23/tcp: 192.168.0.100
-- |   80/tcp: 192.168.0.70
-- |   445/tcp: 192.168.0.1
-- |   53/udp: 192.168.0.1, 192.168.0.60, 192.168.0.70, 192.168.0.105
-- |_  5353/udp: 192.168.0.1, 192.168.0.60, 192.168.0.70, 192.168.0.105
--
-- @args reverse-index.mode the output display mode, can be either horizontal
--       or vertical (default: horizontal)
-- @args reverse-index.names If set, index results by service name instead of
--       port number. Unknown services will be listed by port number.
--
-- @xmloutput
-- <table key="ftp/tcp">
--   <elem>127.0.0.1</elem>
-- </table>
-- <table key="http/tcp">
--   <elem>45.33.32.156</elem>
--   <elem>127.0.0.1</elem>
--   <elem>172.217.9.174</elem>
-- </table>
-- <table key="https/tcp">
--   <elem>172.217.9.174</elem>
-- </table>
-- <table key="smtp/tcp">
--   <elem>127.0.0.1</elem>
-- </table>
-- <table key="ssh/tcp">
--   <elem>45.33.32.156</elem>
--   <elem>127.0.0.1</elem>
-- </table>
--

-- Version 0.1
-- Created 11/22/2011 - v0.1 - created by Patrik Karlsson
author = "Patrik Karlsson"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = { "safe" }

-- the postrule displays the reverse-index once all hosts are scanned
postrule = function() return true end

-- the hostrule iterates over open ports for the host and pushes them into the registry
hostrule = function() return true end

hostaction = function(host)
  local names = stdnse.get_script_args(SCRIPT_NAME .. ".names")
  stdnse.debug1("names = %s", names)
  nmap.registry[SCRIPT_NAME] = nmap.registry[SCRIPT_NAME] or {tcp={}, udp={}}
  local db = nmap.registry[SCRIPT_NAME]
  for _, s in ipairs({"open", "open|filtered"}) do
    for _, p in ipairs({"tcp","udp"}) do
      local port = nil
      while( true ) do
        port = nmap.get_ports(host, port, p, s)
        if ( not(port) ) then break  end
        local key = names and port.service or port.number
        if key == "unknown" then
          -- If they are sorting by name, don't lump all "unknown" together.
          key = port.number
        end
        db[p][key] = db[p][key] or {}
        table.insert(db[p][key], host.ip)
      end
    end
  end
end

postaction = function()
  local db = nmap.registry[SCRIPT_NAME]
  if ( db == nil ) then
    return nil
  end

  local results
  local mode = stdnse.get_script_args("reverse-index.mode") or "horizontal"

  local results = stdnse.output_table()
  for proto, ports in pairs(db) do
    local portnumbers = tableaux.keys(ports)
    table.sort(portnumbers)
    for _, port in ipairs(portnumbers) do
      local result_entries = ports[port]
      ipOps.ip_sort(result_entries)
      if mode == 'horizontal' then
        outlib.list_sep(result_entries)
      end
      results[("%s/%s"):format(port, proto)] = result_entries
    end
  end

  return results
end

local Actions = {
  hostrule = hostaction,
  postrule = postaction
}

-- execute the action function corresponding to the current rule
action = function(...) return Actions[SCRIPT_TYPE](...) 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:REVERSE-INDEX.NSE