mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
OS detection changes to improve timing/reliability, print fprint in more cases, etc. Also some tiny changes from Kris Katterjohn
This commit is contained in:
@@ -114,6 +114,7 @@ FingerPrintResults::FingerPrintResults() {
|
|||||||
distance = -1;
|
distance = -1;
|
||||||
distance_guess = -1;
|
distance_guess = -1;
|
||||||
memset(FPs, 0, sizeof(FPs));
|
memset(FPs, 0, sizeof(FPs));
|
||||||
|
maxTimingRatio = 0;
|
||||||
numFPs = goodFP = 0;
|
numFPs = goodFP = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,22 +135,29 @@ const struct OS_Classification_Results *FingerPrintResults::getOSClassification(
|
|||||||
return &OSR;
|
return &OSR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Are the attributes of this fingerprint good enough to warrant submission to the official DB? */
|
/* If the fingerprint is of potentially poor quality, we don't want to
|
||||||
bool FingerPrintResults::fingerprintSuitableForSubmission() {
|
print it and ask the user to submit it. In that case, the reason
|
||||||
|
for skipping the FP is returned as a static string. If the FP is
|
||||||
|
great and should be printed, NULL is returned. */
|
||||||
|
const char *FingerPrintResults::OmitSubmissionFP() {
|
||||||
|
|
||||||
if (o.scan_delay > 500) // This can screw up the sequence timing
|
if (o.scan_delay > 500) // This can screw up the sequence timing
|
||||||
return false;
|
return "Scan delay is greater than 500";
|
||||||
|
|
||||||
if (osscan_opentcpport <= 0 || osscan_closedtcpport <= 0 )
|
if (o.timing_level > 4)
|
||||||
/* The results won't be complete */
|
return "Timing level 5 (Insane) used";
|
||||||
return false;
|
|
||||||
|
if (osscan_opentcpport <= 0)
|
||||||
|
return "Missing an open TCP port so results incomplete";
|
||||||
|
|
||||||
|
if (osscan_closedtcpport <= 0)
|
||||||
|
return "Missing a closed TCP port so results incomplete";
|
||||||
|
|
||||||
if (distance > 5)
|
if (distance > 5)
|
||||||
/* Too far away from us. */
|
return "Host more than five network hops away";
|
||||||
return false;
|
|
||||||
|
|
||||||
if (osscan_closedudpport == 0)
|
if (maxTimingRatio > 1.4)
|
||||||
return false; /* Too much risk of goofy results */
|
return "maxTimingRatio is greater than 1.4";
|
||||||
|
|
||||||
if (osscan_closedudpport < 0 && !o.udpscan) {
|
if (osscan_closedudpport < 0 && !o.udpscan) {
|
||||||
/* If we didn't get a U1 response, that might be just
|
/* If we didn't get a U1 response, that might be just
|
||||||
@@ -157,9 +165,10 @@ bool FingerPrintResults::fingerprintSuitableForSubmission() {
|
|||||||
because this OS doesn't respond to that sort of probe.
|
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
|
So we don't print FP if U1 response is lacking AND no UDP
|
||||||
scan was performed. */
|
scan was performed. */
|
||||||
return false;
|
return "Didn't receive UDP response. Please try again with -sU";
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -147,14 +147,23 @@ 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. */
|
||||||
|
|
||||||
|
/* The largest ratio we have seen of time taken vs. target time
|
||||||
|
between sending 1st tseq probe and sending first ICMP echo probe.
|
||||||
|
Zero means we didn't see any ratios (the tseq probes weren't
|
||||||
|
sent), 1 is ideal, and larger values are undesirable from a
|
||||||
|
consistancy standpoint. */
|
||||||
|
double maxTimingRatio;
|
||||||
|
|
||||||
FingerPrint *FPs[10]; /* Fingerprint data obtained from host */
|
FingerPrint *FPs[10]; /* Fingerprint data obtained from host */
|
||||||
int numFPs;
|
int numFPs;
|
||||||
int goodFP;
|
int goodFP;
|
||||||
|
|
||||||
/* Are the attributes of this fingerprint good enough to warrant submission to the official DB? */
|
/* If the fingerprint is of potentially poor quality, we don't want to
|
||||||
bool fingerprintSuitableForSubmission();
|
print it and ask the user to submit it. In that case, the reason
|
||||||
|
for skipping the FP is returned as a static string. If the FP is
|
||||||
|
great and should be printed, NULL is returned. */
|
||||||
|
const char *OmitSubmissionFP();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isClassified; // Whether populateClassification() has been called
|
bool isClassified; // Whether populateClassification() has been called
|
||||||
|
|||||||
4
main.cc
4
main.cc
@@ -138,7 +138,7 @@ static BOOL OpenLibs(void) {
|
|||||||
extern NmapOps o; /* option structure */
|
extern NmapOps o; /* option structure */
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
|
|
||||||
int main(int argc, char *argv[], char *envp[]) {
|
int main(int argc, char *argv[]) {
|
||||||
/* The "real" main is nmap_main(). This function hijacks control at the
|
/* The "real" main is nmap_main(). This function hijacks control at the
|
||||||
beginning to do the following:
|
beginning to do the following:
|
||||||
1) Check if Nmap called under name listed in INTERACTIVE_NAMES or with
|
1) Check if Nmap called under name listed in INTERACTIVE_NAMES or with
|
||||||
@@ -314,7 +314,7 @@ int main(int argc, char *argv[], char *envp[]) {
|
|||||||
} else fatal("Arguments too long.");
|
} else fatal("Arguments too long.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* First we stick our arguments into envp */
|
|
||||||
if (o.debugging) {
|
if (o.debugging) {
|
||||||
error("Adding to environment: %s", nmapargs);
|
error("Adding to environment: %s", nmapargs);
|
||||||
}
|
}
|
||||||
|
|||||||
2
nmap.cc
2
nmap.cc
@@ -1570,7 +1570,7 @@ int nmap_main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (o.osscan == OS_SCAN_DEFAULT || o.osscan == OS_SCAN_SYS_2_ONLY)
|
if (o.osscan == OS_SCAN_DEFAULT || o.osscan == OS_SCAN_SYS_2_ONLY)
|
||||||
os_scan_2(Targets);
|
os_scan2(Targets);
|
||||||
|
|
||||||
for(targetno = 0; targetno < Targets.size(); targetno++) {
|
for(targetno = 0; targetno < Targets.size(); targetno++) {
|
||||||
currenths = Targets[targetno];
|
currenths = Targets[targetno];
|
||||||
|
|||||||
@@ -1447,9 +1447,9 @@ o.current_scantype = OS_SCAN;
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (o.debugging > 2) {
|
if (o.verbose) {
|
||||||
starttimems = o.TimeSinceStartMS();
|
starttimems = o.TimeSinceStartMS();
|
||||||
log_write(LOG_STDOUT|LOG_NORMAL|LOG_SKID, "Initiating OS Detection against %s at %.3fs\n", target->targetipstr(), starttimems / 1000.0);
|
log_write(LOG_STDOUT|LOG_NORMAL|LOG_SKID, "Initiating gen1 OS Detection against %s at %.3fs\n", target->targetipstr(), starttimems / 1000.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target->FPR1 == NULL)
|
if (target->FPR1 == NULL)
|
||||||
|
|||||||
113
osscan2.cc
113
osscan2.cc
@@ -114,11 +114,15 @@
|
|||||||
// sent to a single host, in milliseconds.
|
// sent to a single host, in milliseconds.
|
||||||
#define OS_PROBE_DELAY 25
|
#define OS_PROBE_DELAY 25
|
||||||
|
|
||||||
// The minimum (and target) amount of time to wait between sequencing
|
// The target amount of time to wait between sequencing probes sent to
|
||||||
// probes sent to a single host, in milliseconds. It is important
|
// a single host, in milliseconds. The ideal is 500ms because of the
|
||||||
// that the seq probes (which involves 5 gaps) take more than 500ms so
|
// common 2Hz timestamp frequencies. Less than 500ms and we might not
|
||||||
// we can detect timestamps which increase at a frequency of 2Hz.
|
// see any change in the TS counter (and it gets less accurate even if
|
||||||
#define OS_SEQ_PROBE_DELAY 110
|
// we do). More than 500MS and we risk having two changes (and it
|
||||||
|
// gets less accurate even if we have just one). So we delay 100MS
|
||||||
|
// between probes, leaving 500MS between 1st and 6th.
|
||||||
|
|
||||||
|
#define OS_SEQ_PROBE_DELAY 100
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
extern NmapOps o;
|
extern NmapOps o;
|
||||||
@@ -298,6 +302,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
int distance;
|
int distance;
|
||||||
int distance_guess;
|
int distance_guess;
|
||||||
|
|
||||||
|
/* Returns the amount of time taken between sending 1st tseq probe
|
||||||
|
and the 1st ICMP probe divided by the amount of time it should
|
||||||
|
have taken. Ratios far from 1 can cause bogus results. Zero is
|
||||||
|
returned if we didn't send the tseq probes because there was no
|
||||||
|
open tcp port */
|
||||||
|
double timingRatio();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* Ports of the targets used in os fingerprinting. */
|
/* Ports of the targets used in os fingerprinting. */
|
||||||
@@ -355,6 +366,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
u16 lastipid;
|
u16 lastipid;
|
||||||
struct timeval seq_send_times[NUM_SEQ_SAMPLES];
|
struct timeval seq_send_times[NUM_SEQ_SAMPLES];
|
||||||
|
struct timeval first_icmp_send_time;
|
||||||
|
|
||||||
int TWinReplyNum; /* how many TWin replies are received. */
|
int TWinReplyNum; /* how many TWin replies are received. */
|
||||||
int TOpsReplyNum; /* how many TOps replies are received. Actually it is the same with TOpsReplyNum. */
|
int TOpsReplyNum; /* how many TOps replies are received. Actually it is the same with TOpsReplyNum. */
|
||||||
@@ -720,7 +732,8 @@ void HostOsScanStats::initScanStats() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
memset(&seq_send_times, 0, sizeof(seq_send_times));
|
memset(&seq_send_times, 0, sizeof(seq_send_times));
|
||||||
|
memset(&first_icmp_send_time, 0, sizeof(first_icmp_send_time));
|
||||||
|
|
||||||
if (icmpEchoReply) {
|
if (icmpEchoReply) {
|
||||||
free(icmpEchoReply);
|
free(icmpEchoReply);
|
||||||
icmpEchoReply = NULL;
|
icmpEchoReply = NULL;
|
||||||
@@ -779,6 +792,18 @@ void HostOsScanStats::moveProbeToUnSendList(list<OFProbe *>::iterator probeI) {
|
|||||||
probesActive.erase(probeI);
|
probesActive.erase(probeI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Compute the ratio of amount of time taken between sending 1st TSEQ
|
||||||
|
probe and 1st ICMP probe compared to the amount of time it should
|
||||||
|
have taken. Ratios far from 1 can cause bogus results */
|
||||||
|
double HostOsScanStats::timingRatio() {
|
||||||
|
if (openTCPPort < 0)
|
||||||
|
return 0;
|
||||||
|
int msec_ideal = OS_SEQ_PROBE_DELAY * 5 + OS_PROBE_DELAY;
|
||||||
|
int msec_taken = TIMEVAL_MSEC_SUBTRACT(first_icmp_send_time, seq_send_times[0]);
|
||||||
|
return (double) msec_taken / msec_ideal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* If there are pending probe timeouts, fills in when with the time of
|
/* If there are pending probe timeouts, fills in when with the time of
|
||||||
* the earliest one and returns true. Otherwise returns false and
|
* the earliest one and returns true. Otherwise returns false and
|
||||||
* puts now in when.
|
* puts now in when.
|
||||||
@@ -1351,6 +1376,7 @@ void HostOsScan::sendTIcmpProbe(HostOsScanStats *hss, int probeNo) {
|
|||||||
assert(hss);
|
assert(hss);
|
||||||
assert(probeNo>=0&&probeNo<2);
|
assert(probeNo>=0&&probeNo<2);
|
||||||
if(probeNo==0) {
|
if(probeNo==0) {
|
||||||
|
gettimeofday(&hss->first_icmp_send_time, NULL);
|
||||||
send_icmp_echo_probe(rawsd, ethptr, hss->target->v4hostip(), IP_TOS_DEFAULT,
|
send_icmp_echo_probe(rawsd, ethptr, hss->target->v4hostip(), IP_TOS_DEFAULT,
|
||||||
true, 9, icmpEchoId, icmpEchoSeq, 120);
|
true, 9, icmpEchoId, icmpEchoSeq, 120);
|
||||||
}
|
}
|
||||||
@@ -1651,7 +1677,8 @@ void HostOsScan::makeTSeqFP(HostOsScanStats *hss) {
|
|||||||
if (hss->si.lastboot && (hss->seq_send_times[0].tv_sec - hss->si.lastboot > 63072000)) {
|
if (hss->si.lastboot && (hss->seq_send_times[0].tv_sec - hss->si.lastboot > 63072000)) {
|
||||||
/* Up 2 years? Perhaps, but they're probably lying. */
|
/* Up 2 years? Perhaps, but they're probably lying. */
|
||||||
if (o.debugging) {
|
if (o.debugging) {
|
||||||
error("Ignoring claimed uptime of %lu days",
|
error("Ignoring claimed %s uptime of %lu days",
|
||||||
|
hss->target->targetipstr(),
|
||||||
(hss->seq_send_times[0].tv_sec - hss->si.lastboot) / 86400);
|
(hss->seq_send_times[0].tv_sec - hss->si.lastboot) / 86400);
|
||||||
}
|
}
|
||||||
hss->si.lastboot = 0;
|
hss->si.lastboot = 0;
|
||||||
@@ -3639,6 +3666,7 @@ static void endRound(OsScanInfo *OSI, HostOsScan *HOS, int roundNum) {
|
|||||||
|
|
||||||
hsi->FPs[roundNum] = hsi->hss->getFP();
|
hsi->FPs[roundNum] = hsi->hss->getFP();
|
||||||
hsi->target->FPR->FPs[roundNum] = hsi->FPs[roundNum];
|
hsi->target->FPR->FPs[roundNum] = hsi->FPs[roundNum];
|
||||||
|
hsi->target->FPR->maxTimingRatio = MAX(hsi->target->FPR->maxTimingRatio, hsi->hss->timingRatio());
|
||||||
match_fingerprint(hsi->FPs[roundNum], &hsi->FP_matches[roundNum],
|
match_fingerprint(hsi->FPs[roundNum], &hsi->FP_matches[roundNum],
|
||||||
o.reference_FPs, OSSCAN_GUESS_THRESHOLD);
|
o.reference_FPs, OSSCAN_GUESS_THRESHOLD);
|
||||||
|
|
||||||
@@ -3753,14 +3781,20 @@ static void doOsScan1(OsScanInfo *OSI) {
|
|||||||
|
|
||||||
for(hostI = OSI->incompleteHosts.begin();
|
for(hostI = OSI->incompleteHosts.begin();
|
||||||
hostI != OSI->incompleteHosts.end(); hostI++) {
|
hostI != OSI->incompleteHosts.end(); hostI++) {
|
||||||
if(o.verbose)
|
/* If the fingerprint found was so good that we want the user to
|
||||||
log_write(LOG_STDOUT, "OSScan against host %s now falls back on the old OS scan system\n",
|
submit it, don't do gen1 os scan because the results might bias
|
||||||
(*hostI)->target->targetipstr());
|
the user into a wrong submission (or make the user less likely
|
||||||
os_scan((*hostI)->target);
|
to actually submit */
|
||||||
|
if ((*hostI)->target->FPR->OmitSubmissionFP()) {
|
||||||
|
os_scan((*hostI)->target);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int os_scan_2(vector<Target *> &Targets) {
|
|
||||||
|
|
||||||
|
/* You should call os_scan2 rather than this function */
|
||||||
|
static int os_scan_2(vector<Target *> &Targets) {
|
||||||
OsScanInfo *OSI;
|
OsScanInfo *OSI;
|
||||||
HostOsScan *HOS;
|
HostOsScan *HOS;
|
||||||
int itry;
|
int itry;
|
||||||
@@ -3783,12 +3817,15 @@ int os_scan_2(vector<Target *> &Targets) {
|
|||||||
startTimeOutClocks(OSI);
|
startTimeOutClocks(OSI);
|
||||||
|
|
||||||
itry = 0;
|
itry = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
begin_sniffer(HOS, Targets); /* initial the pcap session handler in HOS */
|
begin_sniffer(HOS, Targets); /* initial the pcap session handler in HOS */
|
||||||
while(OSI->numIncompleteHosts() != 0 && itry<MAX_SCAN_ROUND) {
|
while(OSI->numIncompleteHosts() != 0 && itry < MAX_SCAN_ROUND) {
|
||||||
if (itry > 0) sleep(1);
|
if (itry > 0) sleep(1);
|
||||||
startRound(OSI, HOS, itry);
|
startRound(OSI, HOS, itry);
|
||||||
doSeqTests(OSI, HOS);
|
doSeqTests(OSI, HOS);
|
||||||
doTUITests(OSI, HOS);
|
doTUITests(OSI, HOS);
|
||||||
endRound(OSI, HOS, itry);
|
endRound(OSI, HOS, itry);
|
||||||
itry++;
|
itry++;
|
||||||
}
|
}
|
||||||
@@ -3800,22 +3837,56 @@ int os_scan_2(vector<Target *> &Targets) {
|
|||||||
stopTimeOutClocks(OSI);
|
stopTimeOutClocks(OSI);
|
||||||
|
|
||||||
/* Find the most matching item in the db. */
|
/* Find the most matching item in the db. */
|
||||||
findBestFPs(OSI, MAX_SCAN_ROUND);
|
findBestFPs(OSI, MAX_SCAN_ROUND);
|
||||||
|
|
||||||
/* Print the fp in debug mode.
|
/* Print the fp in debug mode.
|
||||||
Normally let output.cc to print the FP. */
|
Normally let output.cc to print the FP. */
|
||||||
if(o.debugging > 1)
|
if(o.debugging > 1)
|
||||||
printFP(OSI);
|
printFP(OSI);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OK. Now let's fall back on the former os_scan engine which has
|
* For the incomplete hosts, we fall back on the former os_scan engine which has
|
||||||
* a larger os-fingerprint db.
|
* a larger os-fingerprint db.
|
||||||
*/
|
*/
|
||||||
if(o.osscan != OS_SCAN_SYS_2_ONLY)
|
if(o.osscan != OS_SCAN_SYS_2_ONLY) {
|
||||||
|
|
||||||
doOsScan1(OSI);
|
doOsScan1(OSI);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete HOS;
|
delete HOS;
|
||||||
delete OSI;
|
delete OSI;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is the primary OS detection function. If many Targets are
|
||||||
|
passed in (the threshold is based on timing level), they are
|
||||||
|
processed as smaller groups to improve accuracy */
|
||||||
|
void os_scan2(vector<Target *> &Targets) {
|
||||||
|
unsigned int max_os_group_sz = 20;
|
||||||
|
double fudgeratio = 1.2; /* Allow a slightly larger final group rather than finish with a tiny one */
|
||||||
|
vector<Target *> tmpTargets;
|
||||||
|
unsigned int startidx = 0;
|
||||||
|
|
||||||
|
if (o.timing_level == 4)
|
||||||
|
max_os_group_sz = (unsigned int) (max_os_group_sz * 1.5);
|
||||||
|
|
||||||
|
if (o.timing_level > 4 || Targets.size() <= max_os_group_sz * fudgeratio) {
|
||||||
|
os_scan_2(Targets);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We need to split it up */
|
||||||
|
while(startidx < Targets.size()) {
|
||||||
|
int diff = Targets.size() - startidx;
|
||||||
|
if (diff > max_os_group_sz * fudgeratio) {
|
||||||
|
diff = max_os_group_sz;
|
||||||
|
}
|
||||||
|
tmpTargets.assign(Targets.begin() + startidx,
|
||||||
|
Targets.begin() + startidx + diff);
|
||||||
|
os_scan_2(tmpTargets);
|
||||||
|
startidx += diff;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -111,7 +111,11 @@
|
|||||||
|
|
||||||
/********************** PROTOTYPES ***********************************/
|
/********************** PROTOTYPES ***********************************/
|
||||||
|
|
||||||
int os_scan_2(std::vector<Target *> &Targets);
|
|
||||||
|
/* This is the primary OS detection function. If many Targets are
|
||||||
|
passed in (the threshold is based on timing level), they are
|
||||||
|
processed as smaller groups to improve accuracy */
|
||||||
|
void os_scan2(std::vector<Target *> &Targets);
|
||||||
|
|
||||||
int send_closedudp_probe_2(struct udpprobeinfo &upi, int sd,
|
int send_closedudp_probe_2(struct udpprobeinfo &upi, int sd,
|
||||||
struct eth_nfo *eth, const struct in_addr *victim,
|
struct eth_nfo *eth, const struct in_addr *victim,
|
||||||
|
|||||||
52
output.cc
52
output.cc
@@ -1276,7 +1276,7 @@ void printosscanoutput(Target *currenths) {
|
|||||||
|
|
||||||
// If the FP can't be submitted anyway, might as well make a guess.
|
// If the FP can't be submitted anyway, might as well make a guess.
|
||||||
printosclassificationoutput(FPR->getOSClassification(),
|
printosclassificationoutput(FPR->getOSClassification(),
|
||||||
o.osscan_guess || !FPR->fingerprintSuitableForSubmission());
|
o.osscan_guess || FPR->OmitSubmissionFP());
|
||||||
|
|
||||||
if (FPR->overall_results == OSSCAN_SUCCESS && (FPR->num_perfect_matches <= 8 || o.debugging)) {
|
if (FPR->overall_results == OSSCAN_SUCCESS && (FPR->num_perfect_matches <= 8 || o.debugging)) {
|
||||||
if (FPR->num_perfect_matches > 0) {
|
if (FPR->num_perfect_matches > 0) {
|
||||||
@@ -1312,28 +1312,31 @@ void printosscanoutput(Target *currenths) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((o.osscan_guess || !FPR->fingerprintSuitableForSubmission()) && FPR->num_matches > 0) {
|
const char *reason = FPR->OmitSubmissionFP();
|
||||||
|
if ((o.verbose > 1 || o.debugging) && reason)
|
||||||
|
log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT,"OS fingerprint not ideal because: %s\n", reason);
|
||||||
|
if ((o.osscan_guess || reason) && FPR->num_matches > 0) {
|
||||||
/* Print the best guesses available */
|
/* Print the best guesses available */
|
||||||
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"Aggressive OS guesses: %s (%d%%)", FPR->prints[0]->OS_name, (int) (FPR->accuracy[0] * 100));
|
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"Aggressive OS guesses: %s (%d%%)", FPR->prints[0]->OS_name, (int) (FPR->accuracy[0] * 100));
|
||||||
for(i=1; i < 10 && FPR->num_matches > i && FPR->accuracy[i] > FPR->accuracy[0] - 0.10; i++) {
|
for(i=1; i < 10 && FPR->num_matches > i && FPR->accuracy[i] > FPR->accuracy[0] - 0.10; i++) {
|
||||||
char *p;
|
char *p;
|
||||||
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,", %s (%d%%)", FPR->prints[i]->OS_name, (int) (FPR->accuracy[i] * 100));
|
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,", %s (%d%%)", FPR->prints[i]->OS_name, (int) (FPR->accuracy[i] * 100));
|
||||||
log_write(LOG_XML, "<osmatch name=\"%s\" accuracy=\"%d\" line=\"%d\"/>\n",
|
log_write(LOG_XML, "<osmatch name=\"%s\" accuracy=\"%d\" line=\"%d\"/>\n",
|
||||||
p = xml_convert(FPR->prints[i]->OS_name),
|
p = xml_convert(FPR->prints[i]->OS_name),
|
||||||
(int) (FPR->accuracy[i] * 100),
|
(int) (FPR->accuracy[i] * 100),
|
||||||
FPR->prints[i]->line);
|
FPR->prints[i]->line);
|
||||||
free(p);
|
free(p);
|
||||||
|
}
|
||||||
|
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, "\n");
|
||||||
}
|
}
|
||||||
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, "\n");
|
if (osscanSys == 2 && !reason) {
|
||||||
}
|
log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT,"No exact OS matches for host (If you know what OS is running on it, see http://www.insecure.org/cgi-bin/nmap-submit.cgi).\nTCP/IP fingerprint:\n%s\n",
|
||||||
if (osscanSys == 2 && FPR->fingerprintSuitableForSubmission()) {
|
mergeFPs(FPR->FPs, FPR->numFPs, true,
|
||||||
log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT,"No exact OS matches for host (If you know what OS is running on it, see http://www.insecure.org/cgi-bin/nmap-submit.cgi).\nTCP/IP fingerprint:\n%s\n",
|
currenths->v4hostip(), distance, currenths->MACAddress(),
|
||||||
mergeFPs(FPR->FPs, FPR->numFPs, true,
|
FPR->osscan_opentcpport, FPR->osscan_closedtcpport, FPR->osscan_closedudpport,
|
||||||
currenths->v4hostip(), distance, currenths->MACAddress(),
|
true));
|
||||||
FPR->osscan_opentcpport, FPR->osscan_closedtcpport, FPR->osscan_closedudpport,
|
|
||||||
true));
|
} else {
|
||||||
|
|
||||||
} else {
|
|
||||||
log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT,"No exact OS matches for host (test conditions non-ideal).");
|
log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT,"No exact OS matches for host (test conditions non-ideal).");
|
||||||
if (o.verbose > 1)
|
if (o.verbose > 1)
|
||||||
log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT, "\nTCP/IP fingerprint by osscan system #%d:\n%s",
|
log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT, "\nTCP/IP fingerprint by osscan system #%d:\n%s",
|
||||||
@@ -1349,14 +1352,17 @@ void printosscanoutput(Target *currenths) {
|
|||||||
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"OS Fingerprint:\n%s\n", fp2ascii(FPR->FPs[FPR->goodFP]));
|
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"OS Fingerprint:\n%s\n", fp2ascii(FPR->FPs[FPR->goodFP]));
|
||||||
}
|
}
|
||||||
} else if (FPR->overall_results == OSSCAN_NOMATCHES) {
|
} else if (FPR->overall_results == OSSCAN_NOMATCHES) {
|
||||||
if (osscanSys == 2 && FPR->fingerprintSuitableForSubmission()) {
|
const char *reason = FPR->OmitSubmissionFP();
|
||||||
|
if ((o.verbose > 1 || o.debugging) && reason)
|
||||||
|
log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT,"OS fingerprint not ideal because: %s\n", reason);
|
||||||
|
if (osscanSys == 2 && !reason) {
|
||||||
log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT,"No OS matches for host (If you know what OS is running on it, see http://www.insecure.org/cgi-bin/nmap-submit.cgi).\nTCP/IP fingerprint:\n%s\n",
|
log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT,"No OS matches for host (If you know what OS is running on it, see http://www.insecure.org/cgi-bin/nmap-submit.cgi).\nTCP/IP fingerprint:\n%s\n",
|
||||||
mergeFPs(FPR->FPs, FPR->numFPs, true,
|
mergeFPs(FPR->FPs, FPR->numFPs, true,
|
||||||
currenths->v4hostip(), distance, currenths->MACAddress(),
|
currenths->v4hostip(), distance, currenths->MACAddress(),
|
||||||
FPR->osscan_opentcpport, FPR->osscan_closedtcpport, FPR->osscan_closedudpport,
|
FPR->osscan_opentcpport, FPR->osscan_closedtcpport, FPR->osscan_closedudpport,
|
||||||
true));
|
true));
|
||||||
} else {
|
} else {
|
||||||
log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT,"No OS matches for host (test conditions non-ideal).\n");
|
log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT,"No OS matches for host\n");
|
||||||
if (o.verbose > 1)
|
if (o.verbose > 1)
|
||||||
log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT, "\nTCP/IP fingerprint by osscan system #%d:\n%s",
|
log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT, "\nTCP/IP fingerprint by osscan system #%d:\n%s",
|
||||||
osscanSys, mergeFPs(FPR->FPs, FPR->numFPs, false,
|
osscanSys, mergeFPs(FPR->FPs, FPR->numFPs, false,
|
||||||
|
|||||||
2
tcpip.cc
2
tcpip.cc
@@ -785,7 +785,7 @@ int resolve(char *hostname, struct sockaddr_storage *ss, size_t *sslen,
|
|||||||
|
|
||||||
int islocalhost(const struct in_addr * const addr) {
|
int islocalhost(const struct in_addr * const addr) {
|
||||||
char dev[128];
|
char dev[128];
|
||||||
/* If it is 0.0.0.0 or starts with 127.0.0.1 then it is
|
/* If it is 0.0.0.0 or starts with 127 then it is
|
||||||
probably localhost */
|
probably localhost */
|
||||||
if ((addr->s_addr & htonl(0xFF000000)) == htonl(0x7F000000))
|
if ((addr->s_addr & htonl(0xFF000000)) == htonl(0x7F000000))
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user