From 7f10cfee2c7208b7b9a438bbc69fa8678bd6b015 Mon Sep 17 00:00:00 2001 From: fyodor Date: Fri, 18 Aug 2006 06:22:23 +0000 Subject: [PATCH] OS detection improvements --- FingerPrintResults.cc | 35 +++++++++------------- Makefile.in | 2 +- osscan2.cc | 70 +++++++++++++++++++++++++++++++++---------- output.cc | 2 +- 4 files changed, 70 insertions(+), 39 deletions(-) diff --git a/FingerPrintResults.cc b/FingerPrintResults.cc index a9eb7e778..92fa496fa 100644 --- a/FingerPrintResults.cc +++ b/FingerPrintResults.cc @@ -136,36 +136,29 @@ const struct OS_Classification_Results *FingerPrintResults::getOSClassification( /* Are the attributes of this fingerprint good enough to warrant submission to the official DB? */ bool FingerPrintResults::fingerprintSuitableForSubmission() { + if (o.scan_delay > 500) // This can screw up the sequence timing return false; - if (osscan_opentcpport < 0 || osscan_closedtcpport < 0 ) + if (osscan_opentcpport <= 0 || osscan_closedtcpport <= 0 ) /* The results won't be complete */ return false; - if (osscan_closedudpport > 0) { if (distance > 5) - /* Too far away from us. */ + /* Too far away from us. */ + return false; + + if (osscan_closedudpport == 0) + return false; /* Too much risk of goofy results */ + + if (osscan_closedudpport < 0 && !o.udpscan) { + /* If we didn't get a U1 response, that might be just + because we didn't search for an open port rather than + because this OS doesn't respond to that sort of probe. + So we don't print FP if U1 response is lacking AND no UDP + scan was performed. */ return false; } - else { - if(!o.udpscan) { - /* not performed a udp scan at all. */ - return false; - } - else { - /* does have performed a udp scan but fails to find a closed udp port. */ - if(distance != 0 && distance != 1 && distance_guess > 5) { - /* - distance != 0: not scanning self. - distance != 1: not scanning the host on the same network segment. - distance_guess > 5: it seems that the target is too far away from us. - */ - return false; - } - } - } - return true; } diff --git a/Makefile.in b/Makefile.in index 19ff6fa0e..6c6606c18 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,6 +1,6 @@ export NMAP_VERSION = 4.20ALPHA5 NMAP_NAME= Nmap -NMAP_URL= http://www.insecure.org/nmap/ +NMAP_URL= http://insecure.org/nmap/ NMAP_PLATFORM=@host@ prefix = @prefix@ exec_prefix = @exec_prefix@ diff --git a/osscan2.cc b/osscan2.cc index 18dd4df9a..f562b31b0 100644 --- a/osscan2.cc +++ b/osscan2.cc @@ -509,36 +509,67 @@ void HostOsScanStats::initScanStats() { Port *tport = NULL; int i; - /* Lets find an open port to use */ + /* Lets find an open port to use if we don't already have one */ openTCPPort = (unsigned long) -1; - target->FPR->osscan_opentcpport = -1; + /* target->FPR->osscan_opentcpport = -1; target->FPR->osscan_closedtcpport = -1; - target->FPR->osscan_closedudpport = -1; + target->FPR->osscan_closedudpport = -1; */ - if ((tport = target->ports.nextPort(NULL, IPPROTO_TCP, PORT_OPEN))) { + if (target->FPR->osscan_opentcpport > 0) + openTCPPort = target->FPR->osscan_opentcpport; + else if ((tport = target->ports.nextPort(NULL, IPPROTO_TCP, PORT_OPEN))) { openTCPPort = tport->portno; - target->FPR->osscan_opentcpport = tport->portno; + /* If it is zero, let's try another one if there is one ) */ + if (tport->portno == 0) + if ((tport = target->ports.nextPort(tport, IPPROTO_TCP, PORT_OPEN))) + openTCPPort = tport->portno; + + target->FPR->osscan_opentcpport = openTCPPort; } /* Now we should find a closed port */ - if ((tport = target->ports.nextPort(NULL, IPPROTO_TCP, PORT_CLOSED))) { + if (target->FPR->osscan_closedtcpport > 0) + closedTCPPort = target->FPR->osscan_closedtcpport; + else if ((tport = target->ports.nextPort(NULL, IPPROTO_TCP, PORT_CLOSED))) { closedTCPPort = tport->portno; - target->FPR->osscan_closedtcpport = tport->portno; + + /* If it is zero, let's try another one if there is one ) */ + if (tport->portno == 0) + if ((tport = target->ports.nextPort(tport, IPPROTO_TCP, PORT_CLOSED))) + closedTCPPort = tport->portno; + + target->FPR->osscan_closedtcpport = closedTCPPort; } else if ((tport = target->ports.nextPort(NULL, IPPROTO_TCP, PORT_UNFILTERED))) { /* Well, we will settle for unfiltered */ closedTCPPort = tport->portno; + /* But again we'd prefer not to have zero */ + if (tport->portno == 0) + if ((tport = target->ports.nextPort(tport, IPPROTO_TCP, PORT_UNFILTERED))) + closedTCPPort = tport->portno; } else { + /* We'll just have to pick one at random :( */ closedTCPPort = (get_random_uint() % 14781) + 30000; } /* Now we should find a closed udp port */ - if ((tport = target->ports.nextPort(NULL, IPPROTO_UDP, PORT_CLOSED))) { + if (target->FPR->osscan_closedudpport > 0) + closedUDPPort = target->FPR->osscan_closedudpport; + else if ((tport = target->ports.nextPort(NULL, IPPROTO_UDP, PORT_CLOSED))) { closedUDPPort = tport->portno; - target->FPR->osscan_closedudpport = tport->portno; + /* Not zero, if possible */ + if (tport->portno == 0) + if ((tport = target->ports.nextPort(tport, IPPROTO_UDP, PORT_CLOSED))) + closedUDPPort = tport->portno; + target->FPR->osscan_closedudpport = closedUDPPort; } else if ((tport = target->ports.nextPort(NULL, IPPROTO_UDP, PORT_UNFILTERED))) { /* Well, we will settle for unfiltered */ closedUDPPort = tport->portno; + /* But not zero, please */ + if (tport->portno == 0) + if ((tport = target->ports.nextPort(NULL, IPPROTO_UDP, PORT_UNFILTERED))) + closedUDPPort = tport->portno; } else { + /* Pick one at random. Shrug. */ closedUDPPort = (get_random_uint() % 14781) + 30000; } @@ -1205,7 +1236,8 @@ void HostOsScan::sendTUdpProbe(HostOsScanStats *hss, int probeNo) { if(hss->closedUDPPort == (unsigned long)-1) return; send_closedudp_probe_2(hss->upi, rawsd, ethptr, hss->target->v4hostip(), - this->udpttl, udpPortBase + probeNo, hss->closedUDPPort); + this->udpttl, udpPortBase + probeNo, + hss->closedUDPPort); } bool HostOsScan::processResp(HostOsScanStats *hss, struct ip *ip, unsigned int len, struct timeval *rcvdtime) { @@ -2247,6 +2279,10 @@ bool HostOsScan::processTUdpResp(HostOsScanStats *hss, struct ip *ip) { current_testno++; + /* Also, we now know that the port we reached was closed */ + if (hss->target->FPR->osscan_closedudpport == -1) + hss->target->FPR->osscan_closedudpport = hss->upi.dport; + /* Now let us do an easy one, Don't fragment */ AVs[current_testno].attribute = "DF"; if(ntohs(ip->ip_off) & 0x4000) { @@ -3496,6 +3532,7 @@ static void endRound(OsScanInfo *OSI, HostOsScan *HOS, int roundNum) { hsi->target->distance = hsi->target->FPR->distance = distance; hsi->target->FPR->distance_guess = hsi->hss->distance_guess; + } OSI->removeCompletedHosts(); @@ -3563,12 +3600,13 @@ static void printFP(OsScanInfo *OSI) { FPR = hsi->target->FPR; log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT, - "No OS matches for %s by new os scan system.\n\nTCP/IP fingerprint:\n%s", - hsi->target->targetipstr(), - mergeFPs(FPR->FPs, FPR->numFPs, true, - hsi->target->v4hostip(), hsi->target->distance, hsi->target->MACAddress(), - FPR->osscan_opentcpport, FPR->osscan_closedtcpport, FPR->osscan_closedudpport, - false)); + "No OS matches for %s by new os scan system.\n\nTCP/IP fingerprint:\n%s", + hsi->target->targetipstr(), + mergeFPs(FPR->FPs, FPR->numFPs, true, + hsi->target->v4hostip(), hsi->target->distance, + hsi->target->MACAddress(), + FPR->osscan_opentcpport, FPR->osscan_closedtcpport, + FPR->osscan_closedudpport, false)); } } diff --git a/output.cc b/output.cc index 7bcc2d074..e88d924eb 100644 --- a/output.cc +++ b/output.cc @@ -1396,7 +1396,7 @@ void printosscanoutput(Target *currenths) { } if (distance!=-1) { - log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, "Network Distance: %d hops\n", distance); + log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, "Network Distance: %d hop%s\n", distance, (distance == 1)? "" : "s"); log_write(LOG_XML, "\n", distance); }