From 0d47952611198ef6b1163f366dc03922d20b1475 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 09:42:04 +0200 Subject: Adding upstream version 7.94+git20230807.3be01efb1+dfsg. Signed-off-by: Daniel Baumann --- scripts/unusual-port.nse | 130 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 scripts/unusual-port.nse (limited to 'scripts/unusual-port.nse') diff --git a/scripts/unusual-port.nse b/scripts/unusual-port.nse new file mode 100644 index 0000000..2dd83bb --- /dev/null +++ b/scripts/unusual-port.nse @@ -0,0 +1,130 @@ +local datafiles = require "datafiles" +local nmap = require "nmap" +local shortport = require "shortport" +local stdnse = require "stdnse" + +description = [[ +Compares the detected service on a port against the expected service for that +port number (e.g. ssh on 22, http on 80) and reports deviations. The script +requires that a version scan has been run in order to be able to discover what +service is actually running on each port. +]] + +--- +-- @usage +-- nmap --script unusual-port +-- +-- @output +-- 23/tcp open ssh OpenSSH 5.8p1 Debian 7ubuntu1 (protocol 2.0) +-- |_unusual-port: ssh unexpected on port tcp/23 +-- 25/tcp open smtp Postfix smtpd +-- + +author = "Patrik Karlsson" +license = "Same as Nmap--See https://nmap.org/book/man-legal.html" +categories = { "safe" } + + +local svc_table + +portrule = function() + local status + status, svc_table = datafiles.parse_services() + if not status then + return false --Can't check if we don't have a table! + end + return true +end + +hostrule = function() return true end + +-- the hostrule is only needed to warn +hostaction = function(host) + local port, state = nil, "open" + local is_version_scan = false + + -- iterate over ports and check whether name_confidence > 3 this would + -- suggest that a version scan has been run + for _, proto in ipairs({"tcp", "udp"}) do + repeat + port = nmap.get_ports(host, port, proto, state) + if ( port and port.version.name_confidence > 3 ) then + is_version_scan = true + break + end + until( not(port) ) + end + + -- if no version scan has been run, warn the user as the script requires a + -- version scan in order to work. + if ( not(is_version_scan) ) then + return stdnse.format_output(true, "WARNING: this script depends on Nmap's service/version detection (-sV)") + end + +end + +portchecks = { + + ['tcp'] = { + [113] = function(host, port) return ( port.service == "ident" ) end, + [445] = function(host, port) return ( port.service == "netbios-ssn" ) end, + [587] = function(host, port) return ( port.service == "smtp" ) end, + [593] = function(host, port) return ( port.service == "ncacn_http" ) end, + [636] = function(host, port) return ( port.service == "ldapssl" ) end, + [3268] = function(host, port) return ( port.service == "ldap" ) end, + }, + + ['udp'] = { + [5353] = function(host, port) return ( port.service == "mdns" ) end, + } + +} + +servicechecks = { + ['http'] = function(host, port) + local service = port.service + port.service = "unknown" + local status = shortport.http(host, port) + port.service = service + return status + end, + + -- accept msrpc on any port for now, we might want to limit it to certain + -- port ranges in the future. + ['msrpc'] = function(host, port) return true end, + + -- accept ncacn_http on any port for now, we might want to limit it to + -- certain port ranges in the future. + ['ncacn_http'] = function(host, port) return true end, +} + +portaction = function(host, port) + local ok = false + + if ( port.version.name_confidence <= 3 ) then + return + end + if ( portchecks[port.protocol][port.number] ) then + ok = portchecks[port.protocol][port.number](host, port) + end + if ( not(ok) and servicechecks[port.service] ) then + ok = servicechecks[port.service](host, port) + end + if ( not(ok) and port.service and + ( port.service == svc_table[port.protocol][port.number] or + "unknown" == svc_table[port.protocol][port.number] or + not(svc_table[port.protocol][port.number]) ) ) then + ok = true + end + if ( not(ok) ) then + return ("%s unexpected on port %s/%d"):format(port.service, port.protocol, port.number) + end +end + +local Actions = { + hostrule = hostaction, + portrule = portaction +} + +-- execute the action function corresponding to the current rule +action = function(...) return Actions[SCRIPT_TYPE](...) end -- cgit v1.2.3