mirror of
https://github.com/nmap/nmap.git
synced 2025-12-10 17:59:04 +00:00
Nmap now does better OS detection guesses when there isn't an exact match because it uses the point system (MatchPoints) now given in nmap-os-db
This commit is contained in:
@@ -1,5 +1,9 @@
|
|||||||
# Nmap Changelog ($Id$); -*-text-*-
|
# Nmap Changelog ($Id$); -*-text-*-
|
||||||
|
|
||||||
|
o Nmap 2nd generation OS detection now has a more sophisticated
|
||||||
|
mechanism for guessing a target OS when there is no exact match in the
|
||||||
|
database (see http://insecure.org/nmap/osdetect/osdetect-guess.html )
|
||||||
|
|
||||||
o A dozen or so small patches to Nmap and NmapFE by Kris Katterjohn.
|
o A dozen or so small patches to Nmap and NmapFE by Kris Katterjohn.
|
||||||
|
|
||||||
4.20ALPHA7
|
4.20ALPHA7
|
||||||
|
|||||||
@@ -174,8 +174,8 @@ class NmapOps {
|
|||||||
int interactivemode;
|
int interactivemode;
|
||||||
int ping_group_sz;
|
int ping_group_sz;
|
||||||
int generate_random_ips; /* -iR option */
|
int generate_random_ips; /* -iR option */
|
||||||
FingerPrint **reference_FPs1; /* Used in the old OS scan system. */
|
FingerPrintDB *reference_FPs1; /* Used in the old OS scan system. */
|
||||||
FingerPrint **reference_FPs; /* Used in the new OS scan system. */
|
FingerPrintDB *reference_FPs; /* Used in the new OS scan system. */
|
||||||
u16 magic_port;
|
u16 magic_port;
|
||||||
unsigned short magic_port_set; /* Was this set by user? */
|
unsigned short magic_port_set; /* Was this set by user? */
|
||||||
int num_ping_synprobes;
|
int num_ping_synprobes;
|
||||||
|
|||||||
@@ -197,6 +197,13 @@ typedef struct FingerTest {
|
|||||||
struct FingerTest *next;
|
struct FingerTest *next;
|
||||||
} FingerPrint;
|
} FingerPrint;
|
||||||
|
|
||||||
|
/* This structure contains the important data from the fingerprint
|
||||||
|
database (nmap-os-db or nmap-os-fingerprints) */
|
||||||
|
typedef struct FingerPrintDB {
|
||||||
|
FingerPrint **prints;
|
||||||
|
FingerPrint *MatchPoints;
|
||||||
|
} FingerPrintDB;
|
||||||
|
|
||||||
struct timeout_info {
|
struct timeout_info {
|
||||||
int srtt; /* Smoothed rtt estimate (microseconds) */
|
int srtt; /* Smoothed rtt estimate (microseconds) */
|
||||||
int rttvar; /* Rout trip time variance */
|
int rttvar; /* Rout trip time variance */
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
# are used when there are no perfect matches to determine which OS
|
# are used when there are no perfect matches to determine which OS
|
||||||
# fingerprint matches a target machine most closely.
|
# fingerprint matches a target machine most closely.
|
||||||
MatchPoints
|
MatchPoints
|
||||||
SEQ(SP=30%GCD=50%ISR=30%TI=100%II=100%TS=100)
|
SEQ(SP=30%GCD=75%ISR=30%TI=100%II=100%SS=80%TS=100)
|
||||||
OPS(O1=20%O2=20%O3=20%O4=20%O5=20%O6=20)
|
OPS(O1=20%O2=20%O3=20%O4=20%O5=20%O6=20)
|
||||||
WIN(W1=15%W2=15%W3=15%W4=15%W5=15%W6=15)
|
WIN(W1=15%W2=15%W3=15%W4=15%W5=15%W6=15)
|
||||||
ECN(R=100%DF=20%T=20%TG=20%W=15%O=15%CC=100%Q=20)
|
ECN(R=100%DF=20%T=20%TG=20%W=15%O=15%CC=100%Q=20)
|
||||||
@@ -42,8 +42,8 @@ T4(R=100%DF=20%T=20%TG=20%W=30%S=20%A=20%F=30%O=10%RD=20%Q=20)
|
|||||||
T5(R=100%DF=20%T=20%TG=20%W=30%S=20%A=20%F=30%O=10%RD=20%Q=20)
|
T5(R=100%DF=20%T=20%TG=20%W=30%S=20%A=20%F=30%O=10%RD=20%Q=20)
|
||||||
T6(R=100%DF=20%T=20%TG=20%W=30%S=20%A=20%F=30%O=10%RD=20%Q=20)
|
T6(R=100%DF=20%T=20%TG=20%W=30%S=20%A=20%F=30%O=10%RD=20%Q=20)
|
||||||
T7(R=100%DF=20%T=20%TG=20%W=30%S=20%A=20%F=30%O=10%RD=20%Q=20)
|
T7(R=100%DF=20%T=20%TG=20%W=30%S=20%A=20%F=30%O=10%RD=20%Q=20)
|
||||||
U1(DF=20%T=20%TG=20%TOS=100%IPL=100%UN=100%RIPL=100%RID=100%RIPCK=100%RUCK=100%RUL=100%RUD=100)
|
U1(R=50%DF=20%T=20%TG=20%TOS=100%IPL=100%UN=100%RIPL=100%RID=100%RIPCK=100%RUCK=100%RUL=100%RUD=100)
|
||||||
IE(DFI=40%T=20%TG=20%TOSI=100%CD=100%SI=100%DLI=100)
|
IE(R=50%DFI=40%T=20%TG=20%TOSI=100%CD=100%SI=100%DLI=100)
|
||||||
|
|
||||||
# Device type: switch. Running: 3Com embedded.
|
# Device type: switch. Running: 3Com embedded.
|
||||||
# OS details: 3Com Superstack 3, 3300XM switch , Boot PROM Version: 1.00, Software Version: 2.69, Hardware Version: 0
|
# OS details: 3Com Superstack 3, 3300XM switch , Boot PROM Version: 1.00, Software Version: 2.69, Hardware Version: 0
|
||||||
|
|||||||
154
osscan.cc
154
osscan.cc
@@ -1176,16 +1176,20 @@ static struct AVal *gettestbyname(FingerPrint *FP, const char *name) {
|
|||||||
want to see the results from this match. if shortcircuit is zero,
|
want to see the results from this match. if shortcircuit is zero,
|
||||||
it does all the tests, otherwise it returns when the first one
|
it does all the tests, otherwise it returns when the first one
|
||||||
fails. If you want details of the match process printed, pass n
|
fails. If you want details of the match process printed, pass n
|
||||||
onzero for 'verbose'. In that case, you may also pass in the group
|
onzero for 'verbose'. If points is non-null, it is examined to
|
||||||
name (SEQ, T1, etc) to have that extra info printed. If you pass 0
|
find the number of points for each test in the fprint AVal and use
|
||||||
for verbose, you might as well pass NULL for testGroupName as it
|
that the increment num_subtests and num_subtests_succeeded
|
||||||
won't be used. */
|
appropriately. If it is NULL, each test is worth 1 point. In that
|
||||||
static int AVal_match(struct AVal *reference, struct AVal *fprint,
|
case, you may also pass in the group name (SEQ, T1, etc) to have
|
||||||
|
that extra info printed. If you pass 0 for verbose, you might as
|
||||||
|
well pass NULL for testGroupName as it won't be used. */
|
||||||
|
static int AVal_match(struct AVal *reference, struct AVal *fprint, struct AVal *points,
|
||||||
unsigned long *num_subtests,
|
unsigned long *num_subtests,
|
||||||
unsigned long *num_subtests_succeeded, int shortcut,
|
unsigned long *num_subtests_succeeded, int shortcut,
|
||||||
int verbose, const char *testGroupName) {
|
int verbose, const char *testGroupName) {
|
||||||
struct AVal *current_ref;
|
struct AVal *current_ref;
|
||||||
struct AVal *current_fp;
|
struct AVal *current_fp;
|
||||||
|
struct AVal *current_points;
|
||||||
unsigned int number, number1;
|
unsigned int number, number1;
|
||||||
unsigned int val;
|
unsigned int val;
|
||||||
char *p, *q, *q1; /* OHHHH YEEEAAAAAHHHH!#!@#$!% */
|
char *p, *q, *q1; /* OHHHH YEEEAAAAAHHHH!#!@#$!% */
|
||||||
@@ -1194,6 +1198,8 @@ static int AVal_match(struct AVal *reference, struct AVal *fprint,
|
|||||||
int andexp, orexp, expchar, numtrue;
|
int andexp, orexp, expchar, numtrue;
|
||||||
int testfailed;
|
int testfailed;
|
||||||
int subtests = 0, subtests_succeeded=0;
|
int subtests = 0, subtests_succeeded=0;
|
||||||
|
int pointsThisTest = 1;
|
||||||
|
|
||||||
|
|
||||||
for(current_ref = reference; current_ref; current_ref = current_ref->next) {
|
for(current_ref = reference; current_ref; current_ref = current_ref->next) {
|
||||||
current_fp = getattrbyname(fprint, current_ref->attribute);
|
current_fp = getattrbyname(fprint, current_ref->attribute);
|
||||||
@@ -1250,17 +1256,24 @@ static int AVal_match(struct AVal *reference, struct AVal *fprint,
|
|||||||
if (q) p = q + 1;
|
if (q) p = q + 1;
|
||||||
} while(q);
|
} while(q);
|
||||||
if (numtrue == 0) testfailed=1;
|
if (numtrue == 0) testfailed=1;
|
||||||
subtests++;
|
if (points) {
|
||||||
|
current_points = getattrbyname(points, current_ref->attribute);
|
||||||
|
if (!current_points) fatal("%s: Failed to find point amount for test %s.%s", __FUNCTION__, testGroupName? testGroupName : "", current_ref->attribute);
|
||||||
|
pointsThisTest = strtol(current_points->value, &endptr, 10);
|
||||||
|
if (pointsThisTest < 1)
|
||||||
|
fatal("%s: Got bogus point amount (%s) for test %s.%s", __FUNCTION__, current_points->value, testGroupName? testGroupName : "", current_ref->attribute);
|
||||||
|
}
|
||||||
|
subtests += pointsThisTest;
|
||||||
if (testfailed) {
|
if (testfailed) {
|
||||||
if (shortcut) {
|
if (shortcut) {
|
||||||
if (num_subtests) *num_subtests += subtests;
|
if (num_subtests) *num_subtests += subtests;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf("%s.%s: \"%s\" NOMATCH \"%s\"\n", testGroupName,
|
printf("%s.%s: \"%s\" NOMATCH \"%s\" (%d point%s)\n", testGroupName,
|
||||||
current_ref->attribute, current_fp->value,
|
current_ref->attribute, current_fp->value,
|
||||||
current_ref->value);
|
current_ref->value, pointsThisTest, (pointsThisTest == 1)? "point" : "points");
|
||||||
} else subtests_succeeded++;
|
} else subtests_succeeded += pointsThisTest;
|
||||||
/* Whew, we made it past one Attribute alive , on to the next! */
|
/* Whew, we made it past one Attribute alive , on to the next! */
|
||||||
}
|
}
|
||||||
if (num_subtests) *num_subtests += subtests;
|
if (num_subtests) *num_subtests += subtests;
|
||||||
@@ -1271,11 +1284,13 @@ static int AVal_match(struct AVal *reference, struct AVal *fprint,
|
|||||||
/* Compares 2 fingerprints -- a referenceFP (can have expression
|
/* Compares 2 fingerprints -- a referenceFP (can have expression
|
||||||
attributes) with an observed fingerprint (no expressions). If
|
attributes) with an observed fingerprint (no expressions). If
|
||||||
verbose is nonzero, differences will be printed. The comparison
|
verbose is nonzero, differences will be printed. The comparison
|
||||||
accuracy (between 0 and 1) is returned). */
|
accuracy (between 0 and 1) is returned). If MatchPoints is not NULL, it is
|
||||||
|
a special "fingerprints" which tells how many points each test is worth. */
|
||||||
double compare_fingerprints(FingerPrint *referenceFP, FingerPrint *observedFP,
|
double compare_fingerprints(FingerPrint *referenceFP, FingerPrint *observedFP,
|
||||||
int verbose) {
|
FingerPrint *MatchPoints, int verbose) {
|
||||||
FingerPrint *currentReferenceTest;
|
FingerPrint *currentReferenceTest;
|
||||||
struct AVal *currentObservedTest;
|
struct AVal *currentObservedTest;
|
||||||
|
struct AVal *currentTestMatchPoints;
|
||||||
unsigned long num_subtests = 0, num_subtests_succeeded = 0;
|
unsigned long num_subtests = 0, num_subtests_succeeded = 0;
|
||||||
unsigned long new_subtests, new_subtests_succeeded;
|
unsigned long new_subtests, new_subtests_succeeded;
|
||||||
assert(referenceFP);
|
assert(referenceFP);
|
||||||
@@ -1288,7 +1303,13 @@ double compare_fingerprints(FingerPrint *referenceFP, FingerPrint *observedFP,
|
|||||||
currentObservedTest = gettestbyname(observedFP, currentReferenceTest->name);
|
currentObservedTest = gettestbyname(observedFP, currentReferenceTest->name);
|
||||||
if (currentObservedTest) {
|
if (currentObservedTest) {
|
||||||
new_subtests = new_subtests_succeeded = 0;
|
new_subtests = new_subtests_succeeded = 0;
|
||||||
AVal_match(currentReferenceTest->results, currentObservedTest,
|
if (MatchPoints) {
|
||||||
|
currentTestMatchPoints = gettestbyname(MatchPoints, currentReferenceTest->name);
|
||||||
|
if (!currentTestMatchPoints)
|
||||||
|
fatal("%s: Failed to locate test %s in MatchPoints directive of fingerprint file", __FUNCTION__, currentReferenceTest->name);
|
||||||
|
} else currentTestMatchPoints = NULL;
|
||||||
|
|
||||||
|
AVal_match(currentReferenceTest->results, currentObservedTest, currentTestMatchPoints,
|
||||||
&new_subtests, &new_subtests_succeeded, 0, verbose, currentReferenceTest->name);
|
&new_subtests, &new_subtests_succeeded, 0, verbose, currentReferenceTest->name);
|
||||||
num_subtests += new_subtests;
|
num_subtests += new_subtests;
|
||||||
num_subtests_succeeded += new_subtests_succeeded;
|
num_subtests_succeeded += new_subtests_succeeded;
|
||||||
@@ -1299,20 +1320,21 @@ double compare_fingerprints(FingerPrint *referenceFP, FingerPrint *observedFP,
|
|||||||
return (num_subtests)? (num_subtests_succeeded / (double) num_subtests) : 0;
|
return (num_subtests)? (num_subtests_succeeded / (double) num_subtests) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Takes a fingerprint and looks for matches inside reference_FPs[].
|
/* Takes a fingerprint and looks for matches inside the passed in
|
||||||
The results are stored in FPR (which must point to an instantiated
|
reference fingerprint DB. The results are stored in in FPR (which
|
||||||
FingerPrintResults class) -- results will be reverse-sorted by
|
must point to an instantiated FingerPrintResults class) -- results
|
||||||
accuracy. No results below accuracy_threshhold will be included.
|
will be reverse-sorted by accuracy. No results below
|
||||||
The max matches returned is the maximum that fits in a
|
accuracy_threshhold will be included. The max matches returned is
|
||||||
FingerPrintResults class. */
|
the maximum that fits in a FingerPrintResults class. */
|
||||||
void match_fingerprint(FingerPrint *FP, FingerPrintResults *FPR,
|
void match_fingerprint(FingerPrint *FP, FingerPrintResults *FPR,
|
||||||
FingerPrint **reference_FPs, double accuracy_threshold) {
|
FingerPrintDB *DB, double accuracy_threshold) {
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
double FPR_entrance_requirement = accuracy_threshold; /* accuracy must be
|
double FPR_entrance_requirement = accuracy_threshold; /* accuracy must be
|
||||||
at least this big
|
at least this big
|
||||||
to be added to the
|
to be added to the
|
||||||
list */
|
list */
|
||||||
|
FingerPrint **reference_FPs = DB->prints;
|
||||||
FingerPrint *current_os;
|
FingerPrint *current_os;
|
||||||
double acc;
|
double acc;
|
||||||
int state;
|
int state;
|
||||||
@@ -1332,7 +1354,7 @@ void match_fingerprint(FingerPrint *FP, FingerPrintResults *FPR,
|
|||||||
current_os = reference_FPs[i];
|
current_os = reference_FPs[i];
|
||||||
skipfp = 0;
|
skipfp = 0;
|
||||||
|
|
||||||
acc = compare_fingerprints(current_os, FP, 0);
|
acc = compare_fingerprints(current_os, FP, DB->MatchPoints, 0);
|
||||||
|
|
||||||
/* error("Comp to %s: %li/%li=%f", o.reference_FPs1[i]->OS_name, num_subtests_succeeded, num_subtests, acc); */
|
/* error("Comp to %s: %li/%li=%f", o.reference_FPs1[i]->OS_name, num_subtests_succeeded, num_subtests, acc); */
|
||||||
if (acc >= FPR_entrance_requirement || acc == 1.0) {
|
if (acc >= FPR_entrance_requirement || acc == 1.0) {
|
||||||
@@ -1615,7 +1637,7 @@ do {
|
|||||||
one is the same */
|
one is the same */
|
||||||
if (i == numFPs - 1 || !currentFPs[i+1] ||
|
if (i == numFPs - 1 || !currentFPs[i+1] ||
|
||||||
strcmp(currentFPs[i]->name, currentFPs[i+1]->name) != 0 ||
|
strcmp(currentFPs[i]->name, currentFPs[i+1]->name) != 0 ||
|
||||||
AVal_match(currentFPs[i]->results,currentFPs[i+1]->results, NULL,
|
AVal_match(currentFPs[i]->results,currentFPs[i+1]->results, NULL, NULL,
|
||||||
NULL, 1, 0, NULL) ==0)
|
NULL, 1, 0, NULL) ==0)
|
||||||
{
|
{
|
||||||
changed = 1;
|
changed = 1;
|
||||||
@@ -1927,7 +1949,8 @@ FingerPrint *parse_single_fingerprint(char *fprint_orig) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void free_fingerprint_file(FingerPrint **FPs) {
|
void free_fingerprint_file(FingerPrintDB *DB) {
|
||||||
|
FingerPrint **FPs = DB->prints;
|
||||||
FingerPrint **current;
|
FingerPrint **current;
|
||||||
FingerPrint *c, *d;
|
FingerPrint *c, *d;
|
||||||
struct AVal *avc;
|
struct AVal *avc;
|
||||||
@@ -1950,21 +1973,47 @@ void free_fingerprint_file(FingerPrint **FPs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(FPs);
|
free(FPs);
|
||||||
|
|
||||||
|
if (DB->MatchPoints) {
|
||||||
|
for(c = DB->MatchPoints; c; c=d){
|
||||||
|
d = c->next;
|
||||||
|
if(c->name)
|
||||||
|
free((void*)c->name); //strdup
|
||||||
|
if(c->results){
|
||||||
|
for(avc = c->results; avc; avc = avd) {
|
||||||
|
avd = avc->next;
|
||||||
|
if(avc->attribute)
|
||||||
|
free(avc->attribute);
|
||||||
|
}
|
||||||
|
free(c->results);
|
||||||
|
}
|
||||||
|
free(c);
|
||||||
|
}
|
||||||
|
free(DB->MatchPoints);
|
||||||
|
}
|
||||||
|
free(DB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FingerPrint **parse_fingerprint_file(char *fname) {
|
FingerPrintDB *parse_fingerprint_file(char *fname) {
|
||||||
FingerPrint **FPs;
|
FingerPrintDB *DB = NULL;
|
||||||
FingerPrint *current;
|
FingerPrint *current;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int max_records = 4096;
|
int max_records = 4096;
|
||||||
char line[512];
|
char line[512];
|
||||||
int numrecords = 0;
|
int numrecords = 0;
|
||||||
int lineno = 0;
|
int lineno = 0;
|
||||||
|
bool parsingMatchPoints = false;
|
||||||
|
|
||||||
int classno = 0; /* Number of Class lines dealt with so far */
|
int classno = 0; /* Number of Class lines dealt with so far */
|
||||||
|
|
||||||
|
DB = (FingerPrintDB *) safe_zalloc(sizeof(FingerPrintDB));
|
||||||
|
|
||||||
char *p, *q; /* OH YEAH!!!! */
|
char *p, *q; /* OH YEAH!!!! */
|
||||||
|
|
||||||
FPs = (FingerPrint **) safe_zalloc(sizeof(FingerPrint *) * max_records);
|
if (!DB) fatal("non-allocated DB passed to %s", __FUNCTION__);
|
||||||
|
|
||||||
|
DB->prints = (FingerPrint **) safe_zalloc(sizeof(FingerPrint *) * max_records);
|
||||||
|
|
||||||
fp = fopen(fname, "r");
|
fp = fopen(fname, "r");
|
||||||
if (!fp) fatal("Unable to open Nmap fingerprint file: %s", fname);
|
if (!fp) fatal("Unable to open Nmap fingerprint file: %s", fname);
|
||||||
@@ -1978,29 +2027,39 @@ while(fgets(line, sizeof(line), fp)) {
|
|||||||
|
|
||||||
fparse:
|
fparse:
|
||||||
|
|
||||||
if (strncasecmp(line, "FingerPrint", 11)) {
|
if (strncasecmp(line, "FingerPrint", 11) == 0) {
|
||||||
|
parsingMatchPoints = false;
|
||||||
|
} else if (strncasecmp(line, "MatchPoints", 11) == 0) {
|
||||||
|
if (DB->MatchPoints) fatal("Found MatchPoints directive on line %d of %s even though it has previously been seen in the file", lineno, fname);
|
||||||
|
parsingMatchPoints = true;
|
||||||
|
} else {
|
||||||
fprintf(stderr, "Parse error on line %d of nmap-os-fingerprints file: %s\n", lineno, line);
|
fprintf(stderr, "Parse error on line %d of nmap-os-fingerprints file: %s\n", lineno, line);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = line + 12;
|
current = (FingerPrint *) safe_zalloc(sizeof(FingerPrint));
|
||||||
while(*p && isspace((int) *p)) p++;
|
|
||||||
|
|
||||||
q = strpbrk(p, "\n#");
|
if (parsingMatchPoints) {
|
||||||
if (!p) fatal("Parse error on line %d of fingerprint: %s", lineno, line);
|
current->OS_name = NULL;
|
||||||
|
DB->MatchPoints = current;
|
||||||
|
} else {
|
||||||
|
DB->prints[numrecords] = current;
|
||||||
|
p = line + 12;
|
||||||
|
while(*p && isspace((int) *p)) p++;
|
||||||
|
|
||||||
|
q = strpbrk(p, "\n#");
|
||||||
|
if (!p) fatal("Parse error on line %d of fingerprint: %s", lineno, line);
|
||||||
|
|
||||||
while(isspace(*(--q)))
|
while(isspace(*(--q)))
|
||||||
;
|
;
|
||||||
|
|
||||||
if (q < p) fatal("Parse error on line %d of fingerprint: %s", lineno, line);
|
if (q < p) fatal("Parse error on line %d of fingerprint: %s", lineno, line);
|
||||||
|
|
||||||
FPs[numrecords] = (FingerPrint *) safe_zalloc(sizeof(FingerPrint));
|
current->OS_name = (char *) cp_alloc(q - p + 2);
|
||||||
|
memcpy(current->OS_name, p, q - p + 1);
|
||||||
FPs[numrecords]->OS_name = (char *) cp_alloc(q - p + 2);
|
current->OS_name[q - p + 1] = '\0';
|
||||||
memcpy(FPs[numrecords]->OS_name, p, q - p + 1);
|
}
|
||||||
FPs[numrecords]->OS_name[q - p + 1] = '\0';
|
|
||||||
|
|
||||||
current = FPs[numrecords];
|
|
||||||
current->line = lineno;
|
current->line = lineno;
|
||||||
classno = 0;
|
classno = 0;
|
||||||
|
|
||||||
@@ -2039,23 +2098,24 @@ while(fgets(line, sizeof(line), fp)) {
|
|||||||
current->results = str2AVal(p);
|
current->results = str2AVal(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* printf("Read in fingerprint:\n%s\n", fp2ascii(FPs[numrecords])); */
|
/* printf("Read in fingerprint:\n%s\n", fp2ascii(DB->prints[numrecords])); */
|
||||||
numrecords++;
|
if (!parsingMatchPoints)
|
||||||
|
numrecords++;
|
||||||
if (numrecords >= max_records)
|
if (numrecords >= max_records)
|
||||||
fatal("Too many OS fingerprints -- 0verflow");
|
fatal("Too many OS fingerprints -- 0verflow");
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
FPs[numrecords] = NULL;
|
DB->prints[numrecords] = NULL;
|
||||||
return FPs;
|
return DB;
|
||||||
}
|
}
|
||||||
|
|
||||||
FingerPrint **parse_fingerprint_reference_file(char *dbname) {
|
FingerPrintDB *parse_fingerprint_reference_file(char *dbname) {
|
||||||
char filename[256];
|
char filename[256];
|
||||||
if (nmap_fetchfile(filename, sizeof(filename), dbname) == -1){
|
if (nmap_fetchfile(filename, sizeof(filename), dbname) == -1){
|
||||||
fatal("OS scan requested but I cannot find %s file. It should be in %s, ~/.nmap/ or .", dbname, NMAPDATADIR);
|
fatal("OS scan requested but I cannot find %s file. It should be in %s, ~/.nmap/ or .", dbname, NMAPDATADIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
return parse_fingerprint_file(filename);
|
return parse_fingerprint_file(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function takes an array of "numSamples" IP IDs and analyzes
|
/* This function takes an array of "numSamples" IP IDs and analyzes
|
||||||
|
|||||||
30
osscan.h
30
osscan.h
@@ -114,6 +114,7 @@
|
|||||||
|
|
||||||
/* We won't even consider matches with a lower accuracy than this */
|
/* We won't even consider matches with a lower accuracy than this */
|
||||||
#define OSSCAN_GUESS_THRESHOLD 0.85
|
#define OSSCAN_GUESS_THRESHOLD 0.85
|
||||||
|
|
||||||
/********************** STRUCTURES ***********************************/
|
/********************** STRUCTURES ***********************************/
|
||||||
|
|
||||||
/* moved to global_structures.h */
|
/* moved to global_structures.h */
|
||||||
@@ -128,26 +129,31 @@ char *fp2ascii(FingerPrint *FP);
|
|||||||
complete since it is used by scripts such as scripts/fingerwatch for
|
complete since it is used by scripts such as scripts/fingerwatch for
|
||||||
which some partial fingerpritns are OK. */
|
which some partial fingerpritns are OK. */
|
||||||
FingerPrint *parse_single_fingerprint(char *fprint_orig);
|
FingerPrint *parse_single_fingerprint(char *fprint_orig);
|
||||||
FingerPrint **parse_fingerprint_file(char *fname);
|
|
||||||
FingerPrint **parse_fingerprint_reference_file(char *dbname);
|
|
||||||
|
|
||||||
void free_fingerprint_file(FingerPrint **FPs);
|
/* These functions take a file/db name and open+parse it, returning an
|
||||||
|
(allocated) FingerPrintDB containing the results. They exit with
|
||||||
|
an error message in the case of error. */
|
||||||
|
FingerPrintDB *parse_fingerprint_file(char *fname);
|
||||||
|
FingerPrintDB *parse_fingerprint_reference_file(char *dbname);
|
||||||
|
|
||||||
|
void free_fingerprint_file(FingerPrintDB *DB);
|
||||||
|
|
||||||
/* Compares 2 fingerprints -- a referenceFP (can have expression
|
/* Compares 2 fingerprints -- a referenceFP (can have expression
|
||||||
attributes) with an observed fingerprint (no expressions). If
|
attributes) with an observed fingerprint (no expressions). If
|
||||||
verbose is nonzero, differences will be printed. The comparison
|
verbose is nonzero, differences will be printed. The comparison
|
||||||
accuracy (between 0 and 1) is returned) */
|
accuracy (between 0 and 1) is returned). If MatchPoints is not NULL, it is
|
||||||
|
a special "fingerprints" which tells how many points each test is worth. */
|
||||||
double compare_fingerprints(FingerPrint *referenceFP, FingerPrint *observedFP,
|
double compare_fingerprints(FingerPrint *referenceFP, FingerPrint *observedFP,
|
||||||
int verbose);
|
FingerPrint *MatchPoints, int verbose);
|
||||||
|
|
||||||
/* Takes a fingerprint and looks for matches inside reference_FPs[].
|
/* Takes a fingerprint and looks for matches inside the passed in
|
||||||
The results are stored in in FPR (which must point to an instantiated
|
reference fingerprint DB. The results are stored in in FPR (which
|
||||||
FingerPrintResults class) -- results will be reverse-sorted by
|
must point to an instantiated FingerPrintResults class) -- results
|
||||||
accuracy. No results below accuracy_threshhold will be included.
|
will be reverse-sorted by accuracy. No results below
|
||||||
The max matches returned is the maximum that fits in a
|
accuracy_threshhold will be included. The max matches returned is
|
||||||
FingerPrintResults class. */
|
the maximum that fits in a FingerPrintResults class. */
|
||||||
void match_fingerprint(FingerPrint *FP, FingerPrintResults *FPR,
|
void match_fingerprint(FingerPrint *FP, FingerPrintResults *FPR,
|
||||||
FingerPrint **reference_FPs, double accuracy_threshold);
|
FingerPrintDB *DB, double accuracy_threshold);
|
||||||
|
|
||||||
/* 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 */
|
/* 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 */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user