From 4c6bafb3fa5a9b6c83573f8e7c914e996286bdc0 Mon Sep 17 00:00:00 2001 From: david Date: Sun, 23 Aug 2009 23:58:28 +0000 Subject: [PATCH] o There is a new OS detection pseudo-test, SCAN.DC, which records how the network distance in SCAN.DS was calculated. Its value can be "L" for localhost, "D" for a direct connection, "I" for an ICMP TTL calculation, and "T" for a traceroute hop count. This is mainly for the benefit of OS integration, when it is sometimes important to distinguish between DS=1%DC=I (probably the result of forged TTLs) and DS=1%DC=D (a true one-hop connection.) [David] --- CHANGELOG | 8 ++++++++ Target.h | 11 +++++++++++ osscan.cc | 49 +++++++++++++++++++++++++++++++++++++++++-------- osscan.h | 7 ++++++- osscan2.cc | 6 ++++++ output.cc | 6 +++--- traceroute.cc | 4 +++- 7 files changed, 78 insertions(+), 13 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a7056ab4e..c5ec50b79 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,13 @@ # Nmap Changelog ($Id$); -*-text-*- +o There is a new OS detection pseudo-test, SCAN.DC, which records how + the network distance in SCAN.DS was calculated. Its value can be "L" + for localhost, "D" for a direct connection, "I" for an ICMP TTL + calculation, and "T" for a traceroute hop count. This is mainly for + the benefit of OS integration, when it is sometimes important to + distinguish between DS=1%DC=I (probably the result of forged TTLs) + and DS=1%DC=D (a true one-hop connection.) [David] + o [Zenmap] New translation: Russian (contributed by Alexander Khodyrev). o Added the ssl-cert.nse script, which retrieves and prints the server diff --git a/Target.h b/Target.h index 5f832c685..f9c5d848e 100644 --- a/Target.h +++ b/Target.h @@ -114,6 +114,16 @@ enum osscan_flags { OS_NOTPERF=0, OS_PERF, OS_PERF_UNREL }; +/* The method used to calculate the Target::distance, included in OS + fingerprints. */ +enum dist_calc_method { + DIST_METHOD_NONE, + DIST_METHOD_LOCALHOST, + DIST_METHOD_DIRECT, + DIST_METHOD_ICMP, + DIST_METHOD_TRACEROUTE +}; + struct host_timeout_nfo { unsigned long msecs_used; /* How many msecs has this Target used? */ bool toclock_running; /* Is the clock running right now? */ @@ -242,6 +252,7 @@ class Target { struct seq_info seq; int distance; + enum dist_calc_method distance_calculation_method; FingerPrintResults *FPR; /* FP results get by the OS scan system. */ PortList ports; diff --git a/osscan.cc b/osscan.cc index 18bb0d796..a62eb2da7 100644 --- a/osscan.cc +++ b/osscan.cc @@ -443,17 +443,43 @@ if (!FP) return; return; } +static const char *dist_method_fp_string(enum dist_calc_method method) +{ + const char *s = ""; + + switch (method) { + case DIST_METHOD_NONE: + s = ""; + break; + case DIST_METHOD_LOCALHOST: + s = "L"; + break; + case DIST_METHOD_DIRECT: + s = "D"; + break; + case DIST_METHOD_ICMP: + s = "I"; + break; + case DIST_METHOD_TRACEROUTE: + s = "T"; + break; + } + + return s; +} /* Writes an informational "Test" result suitable for including at the top of a fingerprint. Gives info which might be useful when the FPrint is submitted (eg Nmap version, etc). Result is written (up to ostrlen) to the ostr var passed in */ static void WriteSInfo(char *ostr, int ostrlen, bool isGoodFP, - const struct in_addr * const addr, int distance, const u8 *mac, - int openTcpPort, int closedTcpPort, int closedUdpPort) { + const struct in_addr * const addr, int distance, + enum dist_calc_method distance_calculation_method, + const u8 *mac, int openTcpPort, + int closedTcpPort, int closedUdpPort) { struct tm *ltime; time_t timep; - char dsbuf[10], otbuf[8], ctbuf[8], cubuf[8]; + char dsbuf[10], otbuf[8], ctbuf[8], cubuf[8], dcbuf[8]; char macbuf[16]; timep = time(NULL); ltime = localtime(&timep); @@ -472,14 +498,19 @@ static void WriteSInfo(char *ostr, int ostrlen, bool isGoodFP, if(distance != -1) { Snprintf(dsbuf, sizeof(dsbuf), "%%DS=%d", distance); } + if (distance_calculation_method != DIST_METHOD_NONE) { + Snprintf(dcbuf, sizeof(dcbuf), "%%DC=%s", dist_method_fp_string(distance_calculation_method)); + } else { + dcbuf[0] = '\0'; + } macbuf[0] = '\0'; if (mac) Snprintf(macbuf, sizeof(macbuf), "%%M=%02X%02X%02X", mac[0], mac[1], mac[2]); - Snprintf(ostr, ostrlen, "SCAN(V=%s%%D=%d/%d%%OT=%s%%CT=%s%%CU=%s%%PV=%c%s%%G=%c%s%%TM=%X%%P=%s)", + Snprintf(ostr, ostrlen, "SCAN(V=%s%%D=%d/%d%%OT=%s%%CT=%s%%CU=%s%%PV=%c%s%s%%G=%c%s%%TM=%X%%P=%s)", NMAP_VERSION, ltime->tm_mon + 1, ltime->tm_mday, - otbuf, ctbuf, cubuf, isipprivate(addr)?'Y':'N', dsbuf, isGoodFP?'Y':'N', + otbuf, ctbuf, cubuf, isipprivate(addr)?'Y':'N', dsbuf, dcbuf, isGoodFP?'Y':'N', macbuf, (int) timep, NMAP_PLATFORM); } @@ -622,8 +653,10 @@ static bool FingerTest_lessthan(const FingerTest* a, const FingerTest* b) { are included only once. If wrapit is true, the string is wrapped for submission. */ const char *mergeFPs(FingerPrint *FPs[], int numFPs, bool isGoodFP, - const struct in_addr * const addr, int distance, const u8 *mac, - int openTcpPort, int closedTcpPort, int closedUdpPort, bool wrapit) { + const struct in_addr * const addr, int distance, + enum dist_calc_method distance_calculation_method, + const u8 *mac, int openTcpPort, int closedTcpPort, + int closedUdpPort, bool wrapit) { static char str[10240]; static char wrapstr[10240]; @@ -689,7 +722,7 @@ const char *mergeFPs(FingerPrint *FPs[], int numFPs, bool isGoodFP, p = str; /* Lets start by writing the fake "SCAN" test for submitting fingerprints */ - WriteSInfo(p, sizeof(str), isGoodFP, addr, distance, mac, openTcpPort, closedTcpPort, closedUdpPort); + WriteSInfo(p, sizeof(str), isGoodFP, addr, distance, distance_calculation_method, mac, openTcpPort, closedTcpPort, closedUdpPort); p = p + strlen(str); if (!wrapit) *p++ = '\n'; diff --git a/osscan.h b/osscan.h index 776eaad06..33999ebd1 100644 --- a/osscan.h +++ b/osscan.h @@ -96,6 +96,7 @@ #include "nmap.h" #include "global_structures.h" #include "FingerPrintResults.h" +#include "Target.h" #define OSSCAN_SUCCESS 0 #define OSSCAN_NOMATCHES -1 @@ -146,7 +147,11 @@ void match_fingerprint(FingerPrint *FP, FingerPrintResults *FPR, /* Returns true if perfect match -- if num_subtests & num_subtests_succeeded are non_null it updates them. if shortcircuit is zero, it does all the tests, otherwise it returns when the first one fails */ void freeFingerPrint(FingerPrint *FP); -const char *mergeFPs(FingerPrint *FPs[], int numFPs, bool isGoodFP, const struct in_addr * const addr, int distance, const u8 *mac, int openTcpPort, int closedTcpPort, int closedUdpPort, bool wrapit); +const char *mergeFPs(FingerPrint *FPs[], int numFPs, bool isGoodFP, + const struct in_addr * const addr, int distance, + enum dist_calc_method distance_calculation_method, + const u8 *mac, int openTcpPort, int closedTcpPort, + int closedUdpPort, bool wrapit); #endif /*OSSCAN_H*/ diff --git a/osscan2.cc b/osscan2.cc index f89d771d2..d17f3eafc 100644 --- a/osscan2.cc +++ b/osscan2.cc @@ -3623,6 +3623,7 @@ static void endRound(OsScanInfo *OSI, HostOsScan *HOS, int roundNum) { list::iterator hostI; HostOsScanInfo *hsi = NULL; int distance = -1; + enum dist_calc_method distance_calculation_method = DIST_METHOD_NONE; for(hostI = OSI->incompleteHosts.begin(); hostI != OSI->incompleteHosts.end(); hostI++) { @@ -3652,14 +3653,18 @@ static void endRound(OsScanInfo *OSI, HostOsScan *HOS, int roundNum) { if (islocalhost(hsi->target->v4hostip())) { /* scanning localhost */ distance = 0; + distance_calculation_method = DIST_METHOD_LOCALHOST; } else if (hsi->target->MACAddress()) { /* on the same network segment */ distance = 1; + distance_calculation_method = DIST_METHOD_DIRECT; } else if (hsi->hss->distance!=-1) { distance = hsi->hss->distance; + distance_calculation_method = DIST_METHOD_ICMP; } hsi->target->distance = hsi->target->FPR->distance = distance; + hsi->target->distance_calculation_method = distance_calculation_method; hsi->target->FPR->distance_guess = hsi->hss->distance_guess; } @@ -3717,6 +3722,7 @@ static void printFP(OsScanInfo *OSI) { hsi->target->targetipstr(), mergeFPs(FPR->FPs, FPR->numFPs, true, hsi->target->v4hostip(), hsi->target->distance, + hsi->target->distance_calculation_method, hsi->target->MACAddress(), FPR->osscan_opentcpport, FPR->osscan_closedtcpport, FPR->osscan_closedudpport, false)); diff --git a/output.cc b/output.cc index ffbf3265e..b39d400af 100644 --- a/output.cc +++ b/output.cc @@ -1562,9 +1562,9 @@ static const char *merge_fpr(const FingerPrintResults *FPR, const Target *currenths, bool isGoodFP, bool wrapit) { return mergeFPs(FPR->FPs, FPR->numFPs, isGoodFP, currenths->v4hostip(), - currenths->distance, currenths->MACAddress(), - FPR->osscan_opentcpport, FPR->osscan_closedtcpport, - FPR->osscan_closedudpport, wrapit); + currenths->distance, currenths->distance_calculation_method, + currenths->MACAddress(), FPR->osscan_opentcpport, + FPR->osscan_closedtcpport, FPR->osscan_closedudpport, wrapit); } static void write_merged_fpr(const FingerPrintResults *FPR, diff --git a/traceroute.cc b/traceroute.cc index a7d244efd..3fc87883d 100644 --- a/traceroute.cc +++ b/traceroute.cc @@ -808,8 +808,10 @@ Traceroute::trace(vector < Target * >&Targets) { for (targ = valid_targets.begin(); targ != valid_targets.end(); ++targ) { int distance; distance = TraceGroups[t->v4host().s_addr]->getDistance(); - if (distance != -1) + if (distance != -1) { (*targ)->distance = distance; + (*targ)->distance_calculation_method = DIST_METHOD_TRACEROUTE; + } } SPM->endTask(NULL, NULL);