1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-07 13:11:28 +00:00

IPv6 hop limit feature for OS detection, patch by Alexandru Geana

This commit is contained in:
dmiller
2015-04-07 17:12:55 +00:00
parent 3c3d3bc55a
commit d17ec63ba5
6 changed files with 947 additions and 851 deletions

View File

@@ -130,6 +130,7 @@
#include "nmap_error.h" #include "nmap_error.h"
#include "osscan.h" #include "osscan.h"
#include "linear.h" #include "linear.h"
#include "FPModel.h"
extern NmapOps o; extern NmapOps o;
@@ -697,14 +698,6 @@ FPEngine6::~FPEngine6() {
} }
/* From FPModel.cc. */
extern struct model FPModel;
extern double FPscale[][2];
extern double FPmean[][659];
extern double FPvariance[][659];
extern FingerMatch FPmatches[];
/* Not all operating systems allow setting the flow label in outgoing packets; /* Not all operating systems allow setting the flow label in outgoing packets;
notably all Unixes other than Linux when using raw sockets. This function notably all Unixes other than Linux when using raw sockets. This function
finds out whether the flow labels we set are likely really being sent. finds out whether the flow labels we set are likely really being sent.
@@ -784,6 +777,43 @@ static double vectorize_tc(const PacketElement *pe) {
return ipv6->getTrafficClass(); return ipv6->getTrafficClass();
} }
/* For reference, the dev@nmap.org email thread which contains the explanations for the
* design decisions of this vectorization method:
* http://seclists.org/nmap-dev/2015/q1/218
*/
static int vectorize_hlim(const PacketElement *pe, int target_distance, enum dist_calc_method method) {
const IPv6Header *ipv6;
int hlim;
int er_lim;
ipv6 = find_ipv6(pe);
if (ipv6 == NULL)
return -1;
hlim = ipv6->getHopLimit();
if (method != DIST_METHOD_NONE) {
if (method == DIST_METHOD_TRACEROUTE || method == DIST_METHOD_ICMP) {
if (target_distance > 0)
hlim += target_distance - 1;
}
er_lim = 5;
} else
er_lim = 20;
if (32 - er_lim <= hlim && hlim <= 32)
hlim = 32;
else if (64 - er_lim <= hlim && hlim <= 64)
hlim = 64;
else if (128 - er_lim <= hlim && hlim <= 128)
hlim = 128;
else if (255 - er_lim <= hlim && hlim <= 255)
hlim = 255;
else
hlim = -1;
return hlim;
}
static double vectorize_isr(std::map<std::string, FPPacket>& resps) { static double vectorize_isr(std::map<std::string, FPPacket>& resps) {
const char * const SEQ_PROBE_NAMES[] = {"S1", "S2", "S3", "S4", "S5", "S6"}; const char * const SEQ_PROBE_NAMES[] = {"S1", "S2", "S3", "S4", "S5", "S6"};
u32 seqs[NELEMS(SEQ_PROBE_NAMES)]; u32 seqs[NELEMS(SEQ_PROBE_NAMES)];
@@ -857,6 +887,7 @@ static struct feature_node *vectorize(const FingerPrintResultsIPv6 *FPR) {
probe_name = IPV6_PROBE_NAMES[i]; probe_name = IPV6_PROBE_NAMES[i];
features[idx++].value = vectorize_plen(resps[probe_name].getPacket()); features[idx++].value = vectorize_plen(resps[probe_name].getPacket());
features[idx++].value = vectorize_tc(resps[probe_name].getPacket()); features[idx++].value = vectorize_tc(resps[probe_name].getPacket());
features[idx++].value = vectorize_hlim(resps[probe_name].getPacket(), FPR->distance, FPR->distance_calculation_method);
} }
/* TCP features */ /* TCP features */
features[idx++].value = vectorize_isr(resps); features[idx++].value = vectorize_isr(resps);
@@ -1539,7 +1570,9 @@ void FPHost6::finish() {
} }
this->target_host->distance = this->target_host->FPR->distance = distance; this->target_host->distance = this->target_host->FPR->distance = distance;
this->target_host->distance_calculation_method = distance_calculation_method; this->target_host->distance_calculation_method =
this->target_host->FPR->distance_calculation_method =
distance_calculation_method;
} }
struct tcp_desc { struct tcp_desc {

1715
FPModel.cc

File diff suppressed because one or more lines are too long

10
FPModel.h Normal file
View File

@@ -0,0 +1,10 @@
#ifndef _FPMODEL_H_
#define _FPMODEL_H_
extern struct model FPModel;
extern double FPscale[][2];
extern double FPmean[][676];
extern double FPvariance[][676];
extern FingerMatch FPmatches[];
#endif

View File

@@ -137,6 +137,7 @@ FingerPrintResults::FingerPrintResults() {
osscan_opentcpport = osscan_closedtcpport = osscan_closedudpport = -1; osscan_opentcpport = osscan_closedtcpport = osscan_closedudpport = -1;
distance = -1; distance = -1;
distance_guess = -1; distance_guess = -1;
distance_calculation_method = DIST_METHOD_NONE;
maxTimingRatio = 0; maxTimingRatio = 0;
incomplete = false; incomplete = false;
} }

View File

@@ -143,6 +143,16 @@ struct OS_Classification_Results {
int overall_results; /* OSSCAN_TOOMANYMATCHES, OSSCAN_NOMATCHES, OSSCAN_SUCCESS, etc */ int overall_results; /* OSSCAN_TOOMANYMATCHES, OSSCAN_NOMATCHES, OSSCAN_SUCCESS, etc */
}; };
/* 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
};
class FingerPrintResults { class FingerPrintResults {
public: /* For now ... a lot of the data members should be made private */ public: /* For now ... a lot of the data members should be made private */
FingerPrintResults(); FingerPrintResults();
@@ -173,6 +183,7 @@ class FingerPrintResults {
otherwise -1) */ otherwise -1) */
int distance; /* How "far" is this FP gotten from? */ int distance; /* How "far" is this FP gotten from? */
int distance_guess; /* How "far" is this FP gotten from? by guessing based on ttl. */ int distance_guess; /* How "far" is this FP gotten from? by guessing based on ttl. */
enum dist_calc_method distance_calculation_method;
/* The largest ratio we have seen of time taken vs. target time /* The largest ratio we have seen of time taken vs. target time
between sending 1st tseq probe and sending first ICMP echo probe. between sending 1st tseq probe and sending first ICMP echo probe.

View File

@@ -151,16 +151,6 @@ enum osscan_flags {
OS_NOTPERF=0, OS_PERF, OS_PERF_UNREL 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 { struct host_timeout_nfo {
unsigned long msecs_used; /* How many msecs has this Target used? */ unsigned long msecs_used; /* How many msecs has this Target used? */
bool toclock_running; /* Is the clock running right now? */ bool toclock_running; /* Is the clock running right now? */