@@ -44,6 +44,46 @@ def to_h
4444 ROOT = File . expand_path ( "../../../temp/nmap" , __dir__ )
4545 SERVICES_PATH = File . join ( ROOT , "nmap-services" )
4646 PROBES_PATH = File . join ( ROOT , "nmap-service-probes" )
47+ FALLBACK_SERVICE_NAMES = {
48+ 1 => "tcpmux" ,
49+ 7 => "echo" ,
50+ 20 => "ftp-data" ,
51+ 21 => "ftp" ,
52+ 22 => "ssh" ,
53+ 23 => "telnet" ,
54+ 25 => "smtp" ,
55+ 53 => "domain" ,
56+ 80 => "http" ,
57+ 110 => "pop3" ,
58+ 111 => "rpcbind" ,
59+ 135 => "msrpc" ,
60+ 139 => "netbios-ssn" ,
61+ 143 => "imap" ,
62+ 389 => "ldap" ,
63+ 443 => "https" ,
64+ 445 => "microsoft-ds" ,
65+ 465 => "smtps" ,
66+ 587 => "submission" ,
67+ 993 => "imaps" ,
68+ 995 => "pop3s"
69+ } . freeze
70+ FALLBACK_SERVICE_LOOKUP_EXTRAS = {
71+ [ 53 , :udp ] => "domain" ,
72+ [ 67 , :udp ] => "bootps" ,
73+ [ 68 , :udp ] => "bootpc" ,
74+ [ 69 , :udp ] => "tftp" ,
75+ [ 123 , :udp ] => "ntp" ,
76+ [ 161 , :udp ] => "snmp" ,
77+ [ 443 , :tcp ] => "https" ,
78+ [ 1433 , :tcp ] => "ms-sql-s" ,
79+ [ 1434 , :udp ] => "ms-sql-m" ,
80+ [ 3306 , :tcp ] => "mysql" ,
81+ [ 5060 , :udp ] => "sip" ,
82+ [ 5432 , :tcp ] => "postgresql" ,
83+ [ 6379 , :tcp ] => "redis" ,
84+ [ 8443 , :tcp ] => "https-alt" ,
85+ [ 27017 , :tcp ] => "mongodb"
86+ } . freeze
4787 SERVICE_FAMILY_ALIASES = {
4888 "null" => { probe_names : [ "NULL" ] , services : [ ] } ,
4989 "genericlines" => { probe_names : [ "GenericLines" ] , services : [ ] } ,
@@ -66,6 +106,8 @@ class << self
66106 private
67107
68108 def load_services
109+ return fallback_services unless File . file? ( SERVICES_PATH )
110+
69111 top_ports = [ ]
70112 lookup = { }
71113
@@ -95,6 +137,8 @@ def load_services
95137 end
96138
97139 def load_probes
140+ return fallback_probes unless File . file? ( PROBES_PATH )
141+
98142 probes = [ ]
99143 current = nil
100144
@@ -237,6 +281,76 @@ def expand_ports(spec)
237281 end
238282 end . uniq
239283 end
284+
285+ def fallback_services
286+ top_ports = ( 1 ..1000 ) . map do |port |
287+ {
288+ port : port ,
289+ proto : :tcp ,
290+ service : FALLBACK_SERVICE_NAMES . fetch ( port , "unknown" ) ,
291+ frequency : ( 1001 - port ) . to_f
292+ }
293+ end
294+ lookup = top_ports . each_with_object ( { } ) do |entry , memo |
295+ memo [ [ entry [ :port ] , entry [ :proto ] ] ] = entry [ :service ]
296+ end
297+ FALLBACK_SERVICE_LOOKUP_EXTRAS . each do |key , value |
298+ lookup [ key ] = value
299+ end
300+ [ top_ports . freeze , lookup . freeze ]
301+ end
302+
303+ def fallback_probes
304+ [
305+ fallback_probe ( "NULL" , :tcp , "" , matches : [ ] , softmatches : [ ] ) ,
306+ fallback_probe ( "GenericLines" , :tcp , "\r \n " , ports : [ 21 , 22 , 23 , 25 , 80 , 110 , 143 ] , matches : [ ] , softmatches : [ ] ) ,
307+ fallback_probe ( "HTTPOptions" , :tcp , "OPTIONS / HTTP/1.0\r \n \r \n " , ports : [ 80 , 8080 , 8000 ] , ssl_ports : [ 443 , 8443 ] , matches : [ match_entry ( "http" , "^HTTP/1\\ .[01] 200" , metadata : { product : "Generic HTTP" , version : nil , extra : nil , cpes : [ ] } ) ] ) ,
308+ fallback_probe ( "RTSPRequest" , :tcp , "OPTIONS * RTSP/1.0\r \n \r \n " , ports : [ 554 ] , matches : [ match_entry ( "rtsp" , "^RTSP/" , metadata : { product : "Generic RTSP" , version : nil , extra : nil , cpes : [ ] } ) ] ) ,
309+ fallback_probe ( "SSLSessionReq" , :tcp , "" , ports : [ ] , ssl_ports : [ 443 , 8443 ] , matches : [ ] , softmatches : [ match_entry ( "ssl" , "a^" , metadata : { product : nil , version : nil , extra : nil , cpes : [ ] } ) ] ) ,
310+ fallback_probe ( "SSHSessionReq" , :tcp , "SSH-2.0-ASRFacet-Rb\r \n " , ports : [ 22 ] , matches : [ match_entry ( "ssh" , "^SSH-" , metadata : { product : "Generic SSH" , version : nil , extra : nil , cpes : [ ] } ) ] ) ,
311+ fallback_probe ( "SMTPRequest" , :tcp , "EHLO asrfacet-rb.local\r \n " , ports : [ 25 , 465 , 587 ] , matches : [ match_entry ( "smtp" , "^220" , metadata : { product : "Generic SMTP" , version : nil , extra : nil , cpes : [ ] } ) ] ) ,
312+ fallback_probe ( "FTPRequest" , :tcp , "QUIT\r \n " , ports : [ 21 ] , matches : [ match_entry ( "ftp" , "^220" , metadata : { product : "Generic FTP" , version : nil , extra : nil , cpes : [ ] } ) ] ) ,
313+ fallback_probe ( "Sqlping" , :udp , "\x02 " . b , ports : [ 1434 ] , matches : [ match_entry ( "ms-sql-s" , "." , flags : "s" , metadata : { product : "Microsoft SQL Server" , version : nil , extra : nil , cpes : [ ] } ) ] ) ,
314+ fallback_probe ( "MySQLRequest" , :tcp , "\n " . b , ports : [ 3306 ] , matches : [ match_entry ( "mysql" , "." , flags : "s" , metadata : { product : "MySQL" , version : nil , extra : nil , cpes : [ ] } ) ] ) ,
315+ fallback_probe ( "PostgresRequest" , :tcp , "\x00 \x00 \x00 \x08 \x04 \xd2 \x16 /" . b , ports : [ 5432 ] , matches : [ match_entry ( "postgresql" , "." , flags : "s" , metadata : { product : "PostgreSQL" , version : nil , extra : nil , cpes : [ ] } ) ] ) ,
316+ fallback_probe ( "redis-server" , :tcp , "INFO\r \n " , ports : [ 6379 ] , matches : [ match_entry ( "redis" , "." , flags : "s" , metadata : { product : "Redis" , version : nil , extra : nil , cpes : [ ] } ) ] ) ,
317+ fallback_probe ( "mongodb" , :tcp , "\x3a \x00 \x00 \x00 " . b , ports : [ 27_017 ] , matches : [ match_entry ( "mongodb" , "." , flags : "s" , metadata : { product : "MongoDB" , version : nil , extra : nil , cpes : [ ] } ) ] ) ,
318+ fallback_probe ( "DNSVersionBindReq" , :udp , "\x00 \x00 \x10 \x00 \x00 \x01 \x00 \x00 \x00 \x00 \x00 \x00 \x07 version\x04 bind\x00 \x00 \x10 \x00 \x03 " . b , ports : [ 53 ] , matches : [ match_entry ( "domain" , "." , flags : "s" , metadata : { product : "DNS" , version : nil , extra : nil , cpes : [ ] } ) ] ) ,
319+ fallback_probe ( "SIPOptions" , :udp , "OPTIONS sip:asrfacet-rb SIP/2.0\r \n \r \n " , ports : [ 5060 ] , matches : [ match_entry ( "sip" , "SIP/" , metadata : { product : "SIP" , version : nil , extra : nil , cpes : [ ] } ) ] )
320+ ] . freeze
321+ end
322+
323+ def fallback_probe ( name , proto , probe_str , ports : [ ] , ssl_ports : [ ] , matches : nil , softmatches : nil , rarity : 5 , wait_ms : 5000 )
324+ Probe . new (
325+ name : name ,
326+ proto : proto ,
327+ probe_str : probe_str ,
328+ rarity : rarity ,
329+ wait_ms : wait_ms ,
330+ ports : ports ,
331+ ssl_ports : ssl_ports ,
332+ matches : matches || [ ] ,
333+ softmatches : softmatches || [ ]
334+ )
335+ end
336+
337+ def match_entry ( service , pattern_source , flags : "" , metadata : { } )
338+ {
339+ soft : false ,
340+ service : service ,
341+ pattern_source : pattern_source ,
342+ pattern_flags : flags ,
343+ metadata : {
344+ product : metadata [ :product ] ,
345+ version : metadata [ :version ] ,
346+ extra : metadata [ :extra ] ,
347+ hostname : metadata [ :hostname ] ,
348+ os : metadata [ :os ] ,
349+ device : metadata [ :device ] ,
350+ cpes : Array ( metadata [ :cpes ] )
351+ }
352+ }
353+ end
240354 end
241355
242356 TOP_PORTS , SERVICE_LOOKUP = send ( :load_services )
0 commit comments