From 84e2e9be528c321d718e5fe7912c157e45db36dc Mon Sep 17 00:00:00 2001 From: dmiller Date: Mon, 10 Oct 2022 20:48:15 +0000 Subject: [PATCH] Add DTLS tunnel scanning to -sV --- CHANGELOG | 5 ++++ nmap-service-probes | 2 +- service_scan.cc | 66 ++++++++++++++++++++++----------------------- 3 files changed, 38 insertions(+), 35 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a03987345..efd7fd9da 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,10 @@ #Nmap Changelog ($Id$); -*-text-*- +o Nmap's service scan (-sV) can now probe the UDP service behind a DTLS tunnel, + the same as it already does for TCP services with SSL/TLS encryption. The + DTLSSessionReq probe has had its rarity lowered to 2 to allow it to be sent + sooner in the scan. [Daniel Miller] + o [Ncat] Ncat in listen mode with --udp --ssl will use DTLS to secure incoming connections. [Daniel Miller] diff --git a/nmap-service-probes b/nmap-service-probes index 10b5822b9..f792d2bc5 100644 --- a/nmap-service-probes +++ b/nmap-service-probes @@ -16455,7 +16455,7 @@ softmatch coap m|^`E| ##############################NEXT PROBE############################## # DTLS Client Hello. Dissection available in nmap-payloads Probe UDP DTLSSessionReq q|\x16\xfe\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x36\x01\x00\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x2a\xfe\xfd\x00\x00\x00\x00\x7c\x77\x40\x1e\x8a\xc8\x22\xa0\xa0\x18\xff\x93\x08\xca\xac\x0a\x64\x2f\xc9\x22\x64\xbc\x08\xa8\x16\x89\x19\x30\x00\x00\x00\x02\x00\x2f\x01\x00| -rarity 5 +rarity 2 ports 443,853,4433,4740,5349,5684,5868,6514,6636,8232,10161,10162,12346,12446,12546,12646,12746,12846,12946,13046 # OpenSSL 1.1.0 s_server -dtls -listen diff --git a/service_scan.cc b/service_scan.cc index ef11b6143..efeffd3ac 100644 --- a/service_scan.cc +++ b/service_scan.cc @@ -2055,44 +2055,40 @@ static void startNextProbe(nsock_pool nsp, nsock_iod nsi, ServiceGroup *SG, if (!isInitial) probe = svc->nextProbe(true); // if was initial, currentProbe() returned the right one to execute. if (probe) { - // For a TCP probe, we start by requesting a new connection to the target - if (svc->proto == IPPROTO_TCP) { - nsock_iod_delete(nsi, NSOCK_PENDING_SILENT); - if ((svc->niod = nsock_iod_new(nsp, svc)) == NULL) { - fatal("Failed to allocate Nsock I/O descriptor in %s()", __func__); - } - if (o.spoofsource) { - o.SourceSockAddr(&ss, &ss_len); - nsock_iod_set_localaddr(svc->niod, &ss, ss_len); - } - if (o.ipoptionslen) - nsock_iod_set_ipoptions(svc->niod, o.ipoptions, o.ipoptionslen); - if (svc->target->TargetName()) { - if (nsock_iod_set_hostname(svc->niod, svc->target->TargetName()) == -1) - fatal("nsock_iod_set_hostname(\"%s\" failed in %s()", - svc->target->TargetName(), __func__); - } - svc->target->TargetSockAddr(&ss, &ss_len); - if (svc->tunnel == SERVICE_TUNNEL_NONE) { + nsock_iod_delete(nsi, NSOCK_PENDING_SILENT); + if ((svc->niod = nsock_iod_new(nsp, svc)) == NULL) { + fatal("Failed to allocate Nsock I/O descriptor in %s()", __func__); + } + if (o.spoofsource) { + o.SourceSockAddr(&ss, &ss_len); + nsock_iod_set_localaddr(svc->niod, &ss, ss_len); + } + if (o.ipoptionslen) + nsock_iod_set_ipoptions(svc->niod, o.ipoptions, o.ipoptionslen); + if (svc->target->TargetName()) { + if (nsock_iod_set_hostname(svc->niod, svc->target->TargetName()) == -1) + fatal("nsock_iod_set_hostname(\"%s\" failed in %s()", + svc->target->TargetName(), __func__); + } + svc->target->TargetSockAddr(&ss, &ss_len); + if (svc->tunnel == SERVICE_TUNNEL_NONE) { + if (svc->proto == IPPROTO_TCP) { nsock_connect_tcp(nsp, svc->niod, servicescan_connect_handler, DEFAULT_CONNECT_TIMEOUT, svc, (struct sockaddr *) &ss, ss_len, svc->portno); - } else { - assert(svc->tunnel == SERVICE_TUNNEL_SSL); - nsock_connect_ssl(nsp, svc->niod, servicescan_connect_handler, - DEFAULT_CONNECT_SSL_TIMEOUT, svc, - (struct sockaddr *) &ss, - ss_len, svc->proto, svc->portno, svc->ssl_session); + } + else { + nsock_connect_udp(nsp, svc->niod, servicescan_connect_handler, + svc, (struct sockaddr *) &ss, ss_len, + svc->portno); } } else { - assert(svc->proto == IPPROTO_UDP); - /* Can maintain the same UDP "connection" */ - svc->currentprobe_exec_time = *nsock_gettimeofday(); - send_probe_text(nsp, nsi, svc, probe); - // Now let us read any results - nsock_read(nsp, nsi, servicescan_read_handler, - svc->probe_timemsleft(probe, nsock_gettimeofday()), svc); + assert(svc->tunnel == SERVICE_TUNNEL_SSL); + nsock_connect_ssl(nsp, svc->niod, servicescan_connect_handler, + DEFAULT_CONNECT_SSL_TIMEOUT, svc, + (struct sockaddr *) &ss, + ss_len, svc->proto, svc->portno, svc->ssl_session); } } else { // No more probes remaining! Failed to match @@ -2135,8 +2131,9 @@ static int scanThroughTunnel(nsock_pool nsp, nsock_iod nsi, ServiceGroup *SG, return 0; } - if (svc->proto != IPPROTO_TCP || - !svc->probe_matched || strcmp(svc->probe_matched, "ssl") != 0) + if (!svc->probe_matched || + (strcmp(svc->probe_matched, "ssl") != 0 && + strcmp(svc->probe_matched, "dtls") != 0)) return 0; // Not SSL // Alright! We are going to start the tests over using SSL @@ -2789,6 +2786,7 @@ int service_scan(std::vector &Targets) { #if HAVE_OPENSSL /* We don't care about connection security in version detection. */ nsock_pool_ssl_init(nsp, NSOCK_SSL_MAX_SPEED); + nsock_pool_dtls_init(nsp, NSOCK_SSL_MAX_SPEED); #endif launchSomeServiceProbes(nsp, SG);