diff --git a/FingerPrintResults.cc b/FingerPrintResults.cc index 9dd26a020..e26ded091 100644 --- a/FingerPrintResults.cc +++ b/FingerPrintResults.cc @@ -113,6 +113,7 @@ FingerPrintResults::FingerPrintResults() { osscan_opentcpport = osscan_closedtcpport = osscan_closedudpport = -1; distance = -1; distance_guess = -1; + max_init_ttl = -1; /* We keep FPs holding at least 10 records because Gen1 OS detection doesn't support maxOSTries() */ FPs = (FingerPrint **) safe_zalloc(MAX(o.maxOSTries(), 10) * sizeof(FingerPrint *)); @@ -159,6 +160,20 @@ const char *FingerPrintResults::OmitSubmissionFP() { if (osscan_closedtcpport <= 0) return "Missing a closed TCP port so results incomplete"; + if (max_init_ttl > 0xFF) { + snprintf(reason, sizeof(reason), "An initial TTL (%d) is greater than 255", max_init_ttl); + return reason; + } + + /* This can happen if the TTL in the response to the UDP probe is somehow + greater than the TTL in the probe itself. We exclude -1 because that is + used to mean the distance is unknown, though there's a chance it could + have come from the distance calculation. */ + if (distance < -1) { + snprintf(reason, sizeof(reason), "Host distance (%d network hops) appears to be negative", distance); + return reason; + } + if (distance > 5) { snprintf(reason, sizeof(reason), "Host distance (%d network hops) is greater than five", distance); return reason; diff --git a/FingerPrintResults.h b/FingerPrintResults.h index 986e17fa5..383dce0e5 100644 --- a/FingerPrintResults.h +++ b/FingerPrintResults.h @@ -148,6 +148,10 @@ class FingerPrintResults { otherwise -1) */ int distance; /* How "far" is this FP gotten from? */ int distance_guess; /* How "far" is this FP gotten from? by guessing based on ttl. */ + /* What's the highest initial TTL we have calculated? It's possible for the + TTL to be altered in a nonstandard way in transit. If a TTL is ever greater + than 255, we can detect it. */ + int max_init_ttl; /* The largest ratio we have seen of time taken vs. target time between sending 1st tseq probe and sending first ICMP echo probe. diff --git a/osscan2.cc b/osscan2.cc index c67a3eb8e..64cc9db43 100644 --- a/osscan2.cc +++ b/osscan2.cc @@ -1573,15 +1573,31 @@ void HostOsScan::makeFP(HostOsScanStats *hss) { /* Replace TTL with initial TTL. */ for(pAV = hss->FPtests[i]->results; pAV; pAV = pAV->next) { if(pAV->attribute == "T") { + /* Found TTL item. The value for this attribute is the + received TTL encoded in decimal. We replace it with the + initial TTL encoded in hex. */ ttl = atoi(pAV->value); - /* found TTL item */ if(hss->distance_guess == -1) hss->distance_guess = get_initial_ttl_guess(ttl) - ttl; if(hss->distance != -1) { - /* We've gotten response for the UDP probe and thus have the "true" hop count. */ - sprintf(pAV->value, "%hX", ttl + hss->distance); + /* We've gotten response for the UDP probe and thus have + the "true" hop count. Add the received TTL to the hop + count to get the initial TTL. */ + ttl = ttl + hss->distance; + /* Keep track of the highest initial TTL we've seen. */ + if (ttl > hss->target->FPR->max_init_ttl) + hss->target->FPR->max_init_ttl = ttl; + /* It's not possible for an initial TTL to be greater + than 255, but we might calculate it to be so if the + TTL was monkeyed with in transit. We cap the TTL at + 255 to aid OS detection, while the too-high TTL is + stored in hss->target->FPR->max_init_ttl so we know + what happened. */ + if (ttl > 0xFF) + ttl = 0xFF; + sprintf(pAV->value, "%hX", ttl); } else { /* Guess the initial TTL value */ pAV->attribute = "TG"; diff --git a/traceroute.cc b/traceroute.cc index 100d01b3f..64664bf91 100644 --- a/traceroute.cc +++ b/traceroute.cc @@ -942,9 +942,9 @@ Traceroute::addConsolidationMessage(NmapOutputTable *Tbl, unsigned short row_cou char *ip = inet_ntoa(ref_ipaddr); if(ttl == 1) - len = snprintf(mbuf, 64, "Hop 1 is the same as %s", ip); + len = snprintf(mbuf, 64, "Hop 1 is the same as for %s", ip); else - len = snprintf(mbuf, 64, "Hops 1-%d are the same as %s", ttl, ip); + len = snprintf(mbuf, 64, "Hops 1-%d are the same as for %s", ttl, ip); assert(len); Tbl->addItem(row_count, HOP_COL, true, "-", 1);