Index: scripts/db2-info.nse =================================================================== --- scripts/db2-info.nse (.../nmap) (revision 18160) +++ scripts/db2-info.nse (.../nmap-exp/djalal/nmap-nse) (revision 18278) @@ -29,7 +29,9 @@ -- parseVersion was ripped from the old db2-info.nse written by Tom Sellers -- -portrule = shortport.port_or_service({50000,60000},"ibm-db2", "tcp", {"open", "open|filtered"}) +portrule = shortport.version_port_or_service({50000,60000}, + "ibm-db2", "tcp", + {"open", "open|filtered"}) --- Converts the prodrel server string to a version string -- @@ -86,4 +88,4 @@ results = results .. "External Name: " .. response.extname return results -end \ No newline at end of file +end Index: scripts/db2-das-info.nse =================================================================== --- scripts/db2-das-info.nse (.../nmap) (revision 18160) +++ scripts/db2-das-info.nse (.../nmap-exp/djalal/nmap-nse) (revision 18278) @@ -85,7 +85,9 @@ -- -- Details on how to reproduce these steps with the CLI are welcome. -portrule = shortport.portnumber({523}, {"tcp","udp"}, {"open", "open|filtered"}) +portrule = shortport.version_port_or_service({523}, nil, + {"tcp","udp"}, + {"open", "open|filtered"}) --- Extracts the server profile from an already parsed db2 packet -- Index: scripts/jdwp-version.nse =================================================================== --- scripts/jdwp-version.nse (.../nmap) (revision 18160) +++ scripts/jdwp-version.nse (.../nmap-exp/djalal/nmap-nse) (revision 18278) @@ -17,12 +17,14 @@ -- 9999/tcp open jdwp Java Debug Wire Protocol (Reference Implementation) version 1.6 1.6.0_17 require "comm" +require "shortport" portrule = function(host, port) -- JDWP will close the port if there is no valid handshake within 2 -- seconds, Service detection's NULL probe detects it as tcpwrapped. return port.service == "tcpwrapped" and port.protocol == "tcp" and port.state == "open" + and not(shortport.port_is_excluded(port.number,port.protocol)) end action = function(host, port) Index: scripts/iax2-version.nse =================================================================== --- scripts/iax2-version.nse (.../nmap) (revision 18160) +++ scripts/iax2-version.nse (.../nmap-exp/djalal/nmap-nse) (revision 18278) @@ -18,7 +18,7 @@ require "comm" require "shortport" -portrule = shortport.portnumber(4569, "udp") +portrule = shortport.version_port_or_service(4569, nil, "udp") action = function(host, port) -- see http://www.cornfed.com/iax.pdf for all options. Index: scripts/pptp-version.nse =================================================================== --- scripts/pptp-version.nse (.../nmap) (revision 18160) +++ scripts/pptp-version.nse (.../nmap-exp/djalal/nmap-nse) (revision 18278) @@ -18,7 +18,7 @@ require "comm" require "shortport" -portrule = shortport.portnumber(1723) +portrule = shortport.version_port_or_service(1723) action = function(host, port) -- build a PPTP Start-Control-Connection-Request packet Index: scripts/skypev2-version.nse =================================================================== --- scripts/skypev2-version.nse (.../nmap) (revision 18160) +++ scripts/skypev2-version.nse (.../nmap-exp/djalal/nmap-nse) (revision 18278) @@ -12,6 +12,7 @@ categories = {"version"} require "comm" +require "shortport" portrule = function(host, port) return (port.number == 80 or port.number == 443 or @@ -19,6 +20,7 @@ port.service == "unknown") and port.protocol == "tcp" and port.state == "open" and port.service ~= "http" and port.service ~= "ssl/http" + and not(shortport.port_is_excluded(port.number,port.protocol)) end action = function(host, port) Index: service_scan.cc =================================================================== --- service_scan.cc (.../nmap) (revision 18160) +++ service_scan.cc (.../nmap-exp/djalal/nmap-nse) (revision 18278) @@ -1172,7 +1172,29 @@ } } +// Function that calls isExcluded() function to check if the port +// is in the excludedports list. +int AllProbes::check_excluded_port(unsigned short portno, int proto) +{ + int excluded; + // Check if the -sV version scan option was specified + // or if the --allports option was used + if (!o.servicescan || o.override_excludeports) + return 0; + + if (global_AP == NULL) + fatal("Failed to check the list of excluded ports: %s", __func__); + + if (excluded = global_AP->isExcluded(portno, proto)) { + if (o.debugging) + log_write(LOG_PLAIN, "EXCLUDING %d/%s\n", + portno, IPPROTO2STR(proto)); + } + + return excluded; +} + // If the buf (of length buflen) matches one of the regexes in this // ServiceProbe, returns the details of nth match (service name, // version number if applicable, and whether this is a "soft" match. Index: nse_nmaplib.cc =================================================================== --- nse_nmaplib.cc (.../nmap) (revision 18160) +++ nse_nmaplib.cc (.../nmap-exp/djalal/nmap-nse) (revision 18278) @@ -11,6 +11,7 @@ #include "NmapOps.h" #include "Target.h" #include "portlist.h" +#include "service_scan.h" #include "nmap_rpc.h" #include "nmap_dns.h" #include "osscan.h" @@ -502,6 +503,29 @@ return 1; } +/* this function must be used by version category scripts or any other + * lua code to check if a given port with it's protocol are in the + * exclude directive found in the nmap-service-probes file. + * */ +static int l_port_is_excluded (lua_State *L) +{ + unsigned short portno; + int protocol; + + if (!lua_isnumber(L, 1)) + luaL_error(L, "port 'number' field must be a number"); + if (!lua_isstring(L, 2)) + luaL_error(L, "port 'protocol' field must be a string"); + + portno = (unsigned short) lua_tointeger(L, 1); + protocol = strcmp(lua_tostring(L, 2), "tcp") == 0 ? IPPROTO_TCP : + strcmp(lua_tostring(L, 2), "udp") == 0 ? IPPROTO_UDP : + luaL_error(L, "port 'protocol' field must be \"tcp\" or \"udp\""); + + lua_pushboolean(L,AllProbes::check_excluded_port(portno, protocol)); + return 1; +} + /* unlike set_portinfo() this function sets the port state in nmap. * if for example a udp port was seen by the script as open instead of * filtered, the script is free to say so. @@ -699,6 +723,7 @@ {"get_ports", l_get_ports}, {"set_port_state", l_set_port_state}, {"set_port_version", l_set_port_version}, + {"port_is_excluded", l_port_is_excluded}, {"new_socket", l_nsock_new}, {"new_dnet", l_dnet_new}, {"get_interface_link", l_dnet_get_interface_link}, Index: nselib/shortport.lua =================================================================== --- nselib/shortport.lua (.../nmap) (revision 18160) +++ nselib/shortport.lua (.../nmap-exp/djalal/nmap-nse) (revision 18278) @@ -6,6 +6,8 @@ module(... or "shortport", package.seeall) +local nmap = require "nmap" + --- -- See if a table contains a value. -- @param t A table repesenting a set. @@ -20,6 +22,17 @@ return false end +--- Check if the port and it's protocol are in the exclude directive. +-- +-- @param port A port number. +-- @param proto The protocol to match against, default "tcp". +-- @return True if the port and protocol are +-- in the exclude directive. +port_is_excluded = function(port, proto) + proto = proto or "tcp" + return nmap.port_is_excluded(port, proto) +end + --- Return a portrule that returns true when given an open port matching a -- single port number or a list of port numbers. -- @param ports A single port number or a list of port numbers. @@ -110,3 +123,28 @@ return port_checker(host, port) or service_checker(host, port) end end + +--- Return a portrule that returns true when given an open port matching +-- either a port number or service name and has not been listed in the +-- exclude port directive of the nmap-service-probes file. +-- +-- This function is a combination of the port_is_excluded +-- and port_or_service functions. The port, service, proto may +-- be single values or a list of values as in those functions. +-- This function can be used by version category scripts to check if a +-- given port and it's protocol are in the exclude directive. +-- @usage portrule = shortport.version_port_or_service(22) +-- @usage portrule = shortport.version_port_or_service(nil, "ssh", "tcp") +-- @param services Service name or a list of names to run against. +-- @param protos The protocol or list of protocols to match against, default +-- "tcp". +-- @param states A state or list of states to match against, default +-- {"open", "open|filtered"}. +-- @return Function for the portrule. +version_port_or_service = function(ports, services, protos, states) + return function(host, port) + local p_s_check = port_or_service(ports, services, protos, states) + return p_s_check(host, port) + and not(port_is_excluded(port.number, port.protocol)) + end +end Index: service_scan.h =================================================================== --- service_scan.h (.../nmap) (revision 18160) +++ service_scan.h (.../nmap-exp/djalal/nmap-nse) (revision 18278) @@ -332,6 +332,7 @@ static AllProbes *service_scan_init(void); static void service_scan_free(void); + static int check_excluded_port(unsigned short port, int proto); protected: static AllProbes *global_AP; };