mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 12:41:29 +00:00
Add wrapper class for a fingerprint observation, used by submission processing tools
This commit is contained in:
88
osscan.cc
88
osscan.cc
@@ -102,6 +102,74 @@ template<u8 _MaxStrLen> void ShortStr<_MaxStrLen>::setStr(const char *in, const
|
|||||||
trunc = i < (end - in);
|
trunc = i < (end - in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *FingerPrintScan::attr_names[static_cast<int>(MAX_ATTR)] = {
|
||||||
|
"V", "E", "D", "OT", "CT", "CU", "PV", "DS", "DC", "G", "M", "TM", "P"
|
||||||
|
};
|
||||||
|
|
||||||
|
bool FingerPrintScan::parse(const char *str, const char *end) {
|
||||||
|
const char *q = str, *p=str;
|
||||||
|
int min_attr_i = 0;
|
||||||
|
|
||||||
|
while (p < end) {
|
||||||
|
q = strchr_p(p, end, '=');
|
||||||
|
if (!q) {
|
||||||
|
error("Missing '=' in SCAN line (%s)", str);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
FPstr name(p, q);
|
||||||
|
p = q+1;
|
||||||
|
q = strchr_p(p, end, '%');
|
||||||
|
if (!q) {
|
||||||
|
q = end;
|
||||||
|
}
|
||||||
|
for (int i = min_attr_i; i < static_cast<int>(MAX_ATTR); i++) {
|
||||||
|
if (name == attr_names[i]) {
|
||||||
|
values[i] = string_pool_substr(p, q);
|
||||||
|
while (min_attr_i <= i && values[min_attr_i]) min_attr_i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p = q + 1;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *FingerPrintScan::scan2str() const {
|
||||||
|
static char str[2048];
|
||||||
|
char *p = str;
|
||||||
|
char *end = p + sizeof(str) - 1;
|
||||||
|
|
||||||
|
if (!present)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
p += Snprintf(p, end - p, "SCAN(");
|
||||||
|
|
||||||
|
for (int j = 0; j < static_cast<int>(MAX_ATTR); j++) {
|
||||||
|
if (values[j] == NULL)
|
||||||
|
continue;
|
||||||
|
p += Snprintf(p, end - p, "%s=%s%%", FingerPrintScan::attr_names[j], values[j]);
|
||||||
|
if (p > end)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// overwrite last '%' with ')'
|
||||||
|
if (*(p - 1) == '%')
|
||||||
|
*(p - 1) = ')';
|
||||||
|
// if there were no results and there is space for it, close parenthesis
|
||||||
|
else if (*(p - 1) == '(' && p < end)
|
||||||
|
*p++ = ')';
|
||||||
|
// otherwise, something went wrong.
|
||||||
|
else
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
*p = '\0';
|
||||||
|
return str;
|
||||||
|
|
||||||
|
error:
|
||||||
|
*str = '\0';
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
const char *FingerPrintDef::test_attrs[NUM_FPTESTS][FP_MAX_TEST_ATTRS] = {
|
const char *FingerPrintDef::test_attrs[NUM_FPTESTS][FP_MAX_TEST_ATTRS] = {
|
||||||
/* SEQ */ {"SP", "GCD", "ISR", "TI", "CI", "II", "SS", "TS"},
|
/* SEQ */ {"SP", "GCD", "ISR", "TI", "CI", "II", "SS", "TS"},
|
||||||
/* OPS */ {"O1", "O2", "O3", "O4", "O5", "O6"},
|
/* OPS */ {"O1", "O2", "O3", "O4", "O5", "O6"},
|
||||||
@@ -900,14 +968,14 @@ static void parse_cpeline(FingerPrint *FP, const char *thisline, const char *lin
|
|||||||
which some partial fingerpritns are OK. */
|
which some partial fingerpritns are OK. */
|
||||||
/* This function is not currently used by Nmap, but it is present here because
|
/* This function is not currently used by Nmap, but it is present here because
|
||||||
it is used by fingerprint utilities that link with Nmap object files. */
|
it is used by fingerprint utilities that link with Nmap object files. */
|
||||||
FingerPrint *parse_single_fingerprint(const FingerPrintDB *DB, const char *fprint) {
|
ObservationPrint *parse_single_fingerprint(const FingerPrintDB *DB, const char *fprint) {
|
||||||
int lineno = 0;
|
int lineno = 0;
|
||||||
const char *p, *q;
|
const char *p, *q;
|
||||||
const char *thisline, *nextline;
|
const char *thisline, *nextline;
|
||||||
const char * const end = strchr(fprint, '\0');
|
const char * const end = strchr(fprint, '\0');
|
||||||
FingerPrint *FP;
|
|
||||||
|
|
||||||
FP = new FingerPrint;
|
ObservationPrint *ObFP = new ObservationPrint;
|
||||||
|
FingerPrint *FP = &ObFP->fp;
|
||||||
|
|
||||||
thisline = fprint;
|
thisline = fprint;
|
||||||
|
|
||||||
@@ -950,6 +1018,16 @@ FingerPrint *parse_single_fingerprint(const FingerPrintDB *DB, const char *fprin
|
|||||||
|
|
||||||
parse_cpeline(FP, thisline, nextline, lineno);
|
parse_cpeline(FP, thisline, nextline, lineno);
|
||||||
|
|
||||||
|
} else if (strncmp(thisline, "SCAN(", 5) == 0) {
|
||||||
|
ObFP->scan_info.present = true;
|
||||||
|
p = thisline + 5;
|
||||||
|
q = strchr_p(p, nextline, ')');
|
||||||
|
if (!q) {
|
||||||
|
fatal("Parse error on line %d of fingerprint: %.*s\n", lineno, (int)(nextline - thisline), thisline);
|
||||||
|
}
|
||||||
|
if (!ObFP->scan_info.parse(p, q)) {
|
||||||
|
fatal("Parse error on line %d of fingerprint: %.*s\n", lineno, (int)(nextline - thisline), thisline);
|
||||||
|
}
|
||||||
} else if ((q = strchr_p(thisline, nextline, '('))) {
|
} else if ((q = strchr_p(thisline, nextline, '('))) {
|
||||||
FingerTest test(FPstr(thisline, q), *DB->MatchPoints);
|
FingerTest test(FPstr(thisline, q), *DB->MatchPoints);
|
||||||
p = q+1;
|
p = q+1;
|
||||||
@@ -960,7 +1038,7 @@ FingerPrint *parse_single_fingerprint(const FingerPrintDB *DB, const char *fprin
|
|||||||
if (!test.str2AVal(p, q)) {
|
if (!test.str2AVal(p, q)) {
|
||||||
fatal("Parse error on line %d of fingerprint: %.*s\n", lineno, (int)(nextline - thisline), thisline);
|
fatal("Parse error on line %d of fingerprint: %.*s\n", lineno, (int)(nextline - thisline), thisline);
|
||||||
}
|
}
|
||||||
FP->setTest(test);
|
ObFP->mergeTest(test);
|
||||||
} else {
|
} else {
|
||||||
fatal("Parse error on line %d of fingerprint: %.*s\n", lineno, (int)(nextline - thisline), thisline);
|
fatal("Parse error on line %d of fingerprint: %.*s\n", lineno, (int)(nextline - thisline), thisline);
|
||||||
}
|
}
|
||||||
@@ -969,7 +1047,7 @@ FingerPrint *parse_single_fingerprint(const FingerPrintDB *DB, const char *fprin
|
|||||||
lineno++;
|
lineno++;
|
||||||
} while (thisline && thisline < end);
|
} while (thisline && thisline < end);
|
||||||
|
|
||||||
return FP;
|
return ObFP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
42
osscan.h
42
osscan.h
@@ -110,6 +110,9 @@ struct ShortStr {
|
|||||||
// Helpers for type conversion
|
// Helpers for type conversion
|
||||||
operator const char *() const {return this->str;}
|
operator const char *() const {return this->str;}
|
||||||
operator char *() {return this->str;}
|
operator char *() {return this->str;}
|
||||||
|
bool operator==(const char *other) const {
|
||||||
|
return (!trunc && strncmp(str, other, _MaxStrLen) == 0);
|
||||||
|
}
|
||||||
bool operator==(const ShortStr &other) const {
|
bool operator==(const ShortStr &other) const {
|
||||||
return (!trunc && !other.trunc
|
return (!trunc && !other.trunc
|
||||||
&& strncmp(str, other.str, _MaxStrLen) == 0);
|
&& strncmp(str, other.str, _MaxStrLen) == 0);
|
||||||
@@ -212,6 +215,7 @@ struct FingerTest {
|
|||||||
int getMaxPoints() const;
|
int getMaxPoints() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Same struct used for reference prints (DB) and observations */
|
||||||
struct FingerPrint {
|
struct FingerPrint {
|
||||||
FingerMatch match;
|
FingerMatch match;
|
||||||
FingerTest tests[NUM_FPTESTS];
|
FingerTest tests[NUM_FPTESTS];
|
||||||
@@ -221,6 +225,42 @@ struct FingerPrint {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* These structs are used in fingerprint-processing code outside of Nmap itself
|
||||||
|
* {
|
||||||
|
*/
|
||||||
|
/* SCAN pseudo-test */
|
||||||
|
struct FingerPrintScan {
|
||||||
|
enum Attribute { V, E, D, OT, CT, CU, PV, DS, DC, G, M, TM, P, MAX_ATTR };
|
||||||
|
static const char *attr_names[static_cast<int>(MAX_ATTR)];
|
||||||
|
|
||||||
|
const char *values[static_cast<int>(MAX_ATTR)];
|
||||||
|
bool present;
|
||||||
|
FingerPrintScan() : present(false) {memset(values, 0, sizeof(values));}
|
||||||
|
bool parse(const char *str, const char *end);
|
||||||
|
const char *scan2str() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* An observation parsed from string representation */
|
||||||
|
struct ObservationPrint {
|
||||||
|
FingerPrint fp;
|
||||||
|
FingerPrintScan scan_info;
|
||||||
|
std::vector<FingerTest> extra_tests;
|
||||||
|
const char *getInfo(FingerPrintScan::Attribute attr) const {
|
||||||
|
if (attr >= FingerPrintScan::MAX_ATTR)
|
||||||
|
return NULL;
|
||||||
|
return scan_info.values[static_cast<int>(attr)];
|
||||||
|
}
|
||||||
|
void mergeTest(const FingerTest &test) {
|
||||||
|
FingerTest &ours = fp.tests[ID2INT(test.id)];
|
||||||
|
if (ours.id == FingerPrintDef::INVALID)
|
||||||
|
ours = test;
|
||||||
|
else {
|
||||||
|
extra_tests.push_back(test);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/* } */
|
||||||
|
|
||||||
/* This structure contains the important data from the fingerprint
|
/* This structure contains the important data from the fingerprint
|
||||||
database (nmap-os-db) */
|
database (nmap-os-db) */
|
||||||
struct FingerPrintDB {
|
struct FingerPrintDB {
|
||||||
@@ -240,7 +280,7 @@ const char *fp2ascii(const FingerPrint *FP);
|
|||||||
when done. This function does not require the fingerprint to be 100%
|
when done. This function does not require the fingerprint to be 100%
|
||||||
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 fingerprints are OK. */
|
which some partial fingerprints are OK. */
|
||||||
FingerPrint *parse_single_fingerprint(const char *fprint_orig);
|
ObservationPrint *parse_single_fingerprint(const FingerPrintDB *DB, const char *fprint);
|
||||||
|
|
||||||
/* These functions take a file/db name and open+parse it, returning an
|
/* These functions take a file/db name and open+parse it, returning an
|
||||||
(allocated) FingerPrintDB containing the results. They exit with
|
(allocated) FingerPrintDB containing the results. They exit with
|
||||||
|
|||||||
Reference in New Issue
Block a user