@@ -44,6 +44,23 @@ 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+ SERVICE_FAMILY_ALIASES = {
48+ "null" => { probe_names : [ "NULL" ] , services : [ ] } ,
49+ "genericlines" => { probe_names : [ "GenericLines" ] , services : [ ] } ,
50+ "httpoptions" => { probe_names : [ "HTTPOptions" ] , services : [ "http" ] } ,
51+ "rtsprequest" => { probe_names : [ "RTSPRequest" ] , services : [ "rtsp" ] } ,
52+ "sslsessionreq" => { probe_names : [ "SSLSessionReq" ] , services : [ "ssl" , "https" ] } ,
53+ "sshsessionreq" => { probe_names : [ ] , services : [ "ssh" ] } ,
54+ "smtprequest" => { probe_names : [ ] , services : [ "smtp" ] } ,
55+ "ftprequest" => { probe_names : [ ] , services : [ "ftp" ] } ,
56+ "mssqlquery" => { probe_names : [ "Sqlping" ] , services : [ "ms-sql-s" ] } ,
57+ "mysqlrequest" => { probe_names : [ ] , services : [ "mysql" , "mysqlx" ] } ,
58+ "postgresrequest" => { probe_names : [ ] , services : [ "postgresql" ] } ,
59+ "redisrequest" => { probe_names : [ "redis-server" ] , services : [ "redis" ] } ,
60+ "mongodbrequest" => { probe_names : [ "mongodb" ] , services : [ "mongodb" ] } ,
61+ "dnsquery" => { probe_names : [ "DNSVersionBindReq" , "DNSVersionBindReqTCP" , "DNSStatusRequest" , "DNSStatusRequestTCP" , "DNS-SD" , "DNS-SD-TCP" , "DNS_SD_QU" ] , services : [ "domain" , "mdns" ] } ,
62+ "sipoptions" => { probe_names : [ "SIPOptions" ] , services : [ "sip" ] }
63+ } . freeze
4764
4865 class << self
4966 private
@@ -238,6 +255,31 @@ def service_for(port, proto)
238255 def top_ports ( count )
239256 TOP_PORTS . first ( count . to_i )
240257 end
258+
259+ def probes_for_service ( service , proto : nil )
260+ family = SERVICE_FAMILY_ALIASES . fetch ( service . to_s . strip . downcase , {
261+ probe_names : [ service . to_s ] ,
262+ services : [ service . to_s . downcase ]
263+ } )
264+ PROBES . select do |probe |
265+ next false if proto && probe . proto != proto . to_sym
266+
267+ family [ :probe_names ] . include? ( probe . name ) || service_match? ( probe , family [ :services ] )
268+ end
269+ end
270+
271+ def supports_service? ( service , proto : nil )
272+ !probes_for_service ( service , proto : proto ) . empty?
273+ end
274+
275+ private
276+
277+ def service_match? ( probe , services )
278+ return false if services . empty?
279+
280+ all_services = probe . matches . map { |entry | entry [ :service ] } + probe . softmatches . map { |entry | entry [ :service ] }
281+ services . any? { |service | all_services . include? ( service ) }
282+ end
241283 end
242284 end
243285end
0 commit comments