mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Update nmap-os-db syntax to support nested ranges
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#
|
||||
# For a complete description of Nmap OS detection and the format of
|
||||
# fingerprints in this file, see https://nmap.org/book/osdetect.html.
|
||||
This nmap-os-db is only valid for Nmap 7.94.2 and later
|
||||
|
||||
# This first element provides the number of points every fingerprint
|
||||
# test is worth. Tests like TTL or Don't fragment are worth less
|
||||
|
||||
2
nmap.h
2
nmap.h
@@ -123,7 +123,7 @@
|
||||
file by the makefiles. */
|
||||
#define NMAP_MAJOR 7
|
||||
#define NMAP_MINOR 94
|
||||
#define NMAP_BUILD 1
|
||||
#define NMAP_BUILD 2
|
||||
/* SVN, BETA, etc. */
|
||||
#define NMAP_SPECIAL "SVN"
|
||||
|
||||
|
||||
96
osscan.cc
96
osscan.cc
@@ -292,43 +292,99 @@ void FingerPrint::erase() {
|
||||
| (or)
|
||||
- (range)
|
||||
No parentheses are allowed. */
|
||||
bool expr_match(const char *val, size_t vlenx, const char *expr, size_t explen, bool do_nested) {
|
||||
bool expr_match(const char *val, size_t vlen, const char *expr, size_t explen, bool do_nested) {
|
||||
const char *p, *q, *q1; /* OHHHH YEEEAAAAAHHHH!#!@#$!% */
|
||||
size_t vlen = strlen(val);
|
||||
if (vlen == 0)
|
||||
vlen = strlen(val);
|
||||
if (explen == 0)
|
||||
explen = strlen(expr);
|
||||
|
||||
// If both are empty, match; else if either is empty, no match.
|
||||
if (vlen == 0) {
|
||||
return explen == 0;
|
||||
}
|
||||
else if (explen == 0) {
|
||||
return vlen == 0;
|
||||
}
|
||||
|
||||
p = expr;
|
||||
|
||||
do {
|
||||
const char *nest = NULL; // where the [] nested expr starts
|
||||
const char *subval = val; // portion of val after previous nest and before the next one
|
||||
size_t sublen; // length of subval not subject to nested matching
|
||||
q = strchr(p, '|');
|
||||
size_t explen = q ? q - p : strlen(p);
|
||||
|
||||
// if we're already in a nested expr, we skip this and just match as usual.
|
||||
if (do_nested) {
|
||||
nest = strchr(p, '[');
|
||||
subval = val;
|
||||
// As long as we keep finding nested portions, e.g. M[>500]ST11W[1-5]
|
||||
while (nest) {
|
||||
q1 = strchr(nest, ']');
|
||||
assert(q1);
|
||||
if (q && q < q1) {
|
||||
// "AB[C|D]E|XYZ"
|
||||
q = strchr(q1, '|');
|
||||
}
|
||||
// "AB[C-D]E" or or "AB[C-D]E|F"
|
||||
sublen = nest - p;
|
||||
if (strncmp(p, subval, sublen) != 0) {
|
||||
goto next_expr;
|
||||
}
|
||||
nest++;
|
||||
subval += sublen;
|
||||
size_t nlen = 0;
|
||||
while (isxdigit(subval[nlen])) {
|
||||
nlen++;
|
||||
}
|
||||
p = q1 + 1;
|
||||
// fprintf(stderr, "nest: %-.*s cmp %-.*s\n", nlen, subval, q1 - nest, nest);
|
||||
if (nlen > 0 && expr_match(subval, nlen, nest, q1 - nest, false)) {
|
||||
subval += nlen;
|
||||
nest = strchr(p, '[');
|
||||
}
|
||||
else {
|
||||
goto next_expr;
|
||||
}
|
||||
}
|
||||
// No more nested portions. string match the rest:
|
||||
sublen = vlen - (subval - val);
|
||||
if ((explen - (p - expr)) == sublen && !strncmp(subval, p, sublen)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
sublen = q ? q - p : explen - (p - expr);
|
||||
if (*p == '>') {
|
||||
if ((vlen > explen - 1)
|
||||
|| (vlen == explen - 1 && strncmp(val, p + 1, vlen) > 0)) {
|
||||
if ((vlen > sublen - 1)
|
||||
|| (vlen == sublen - 1 && strncmp(subval, p + 1, vlen) > 0)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (*p == '<') {
|
||||
if ((vlen < explen - 1)
|
||||
|| (vlen == explen - 1 && strncmp(val, p + 1, vlen) < 0)) {
|
||||
if ((vlen < sublen - 1)
|
||||
|| (vlen == sublen - 1 && strncmp(subval, p + 1, vlen) < 0)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
q1 = strchr(p, '-');
|
||||
if (q1 != NULL) {
|
||||
size_t explen1 = q1 - p;
|
||||
if ((vlen > explen1)
|
||||
|| (vlen == explen1 && strncmp(val, p + 1, vlen) >= 0)) {
|
||||
explen -= (explen1 + 1);
|
||||
if ((vlen < explen)
|
||||
|| (vlen == explen && strncmp(val, p + 1, vlen) <= 0)) {
|
||||
size_t sublen1 = q1 - p;
|
||||
if ((vlen > sublen1)
|
||||
|| (vlen == sublen1 && strncmp(subval, p, vlen) >= 0)) {
|
||||
p = q1 + 1;
|
||||
sublen -= (sublen1 + 1);
|
||||
if ((vlen < sublen)
|
||||
|| (vlen == sublen && strncmp(subval, p, vlen) <= 0)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (vlen == explen && !strncmp(p, val, vlen)) {
|
||||
else if (vlen == sublen && !strncmp(p, subval, vlen)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
next_expr:
|
||||
if (q)
|
||||
p = q + 1;
|
||||
} while (q);
|
||||
@@ -348,6 +404,7 @@ static void AVal_match(const FingerTest &reference, const FingerTest &fprint, co
|
||||
return;
|
||||
|
||||
const std::vector<Attr> &pointsV = points.Attrs;
|
||||
bool tcp_opt_match = points.name == "OPS";
|
||||
|
||||
const std::vector<const char *> &refV = *reference.results;
|
||||
assert(refV.size() == points.numAttrs);
|
||||
@@ -366,7 +423,7 @@ static void AVal_match(const FingerTest &reference, const FingerTest &fprint, co
|
||||
fatal("%s: Got bogus point amount (%d) for test %s.%s", __func__, pointsThisTest, points.name.str, aDef.name.str);
|
||||
subtests += pointsThisTest;
|
||||
|
||||
if (expr_match(current_fp, 0, current_ref, 0)) {
|
||||
if (expr_match(current_fp, 0, current_ref, 0, tcp_opt_match || aDef.name == "O")) {
|
||||
subtests_succeeded += pointsThisTest;
|
||||
} else {
|
||||
if (verbose)
|
||||
@@ -1072,6 +1129,15 @@ fparse:
|
||||
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 if (strncmp(line, "This nmap-os-db", 15) == 0) {
|
||||
p = strstr(line, "Nmap ");
|
||||
if (!p)
|
||||
fatal("Parse error on line %d of nmap-os-db file: %s", lineno, line);
|
||||
q = strchr(p + 5, ' ');
|
||||
if (strncmp(p + 5, NMAP_NUM_VERSION, q - p) > 0) {
|
||||
error("%sOS detection results may be inaccurate.", line);
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
error("Parse error on line %d of nmap-os-db file: %s", lineno, line);
|
||||
continue;
|
||||
|
||||
@@ -75,7 +75,6 @@ const struct expr_test tests[] = {
|
||||
{"<A", "", false},
|
||||
{">A", "", false},
|
||||
{"1-9", "", false},
|
||||
#if 0
|
||||
{"M[1-9]", "M2", true},
|
||||
{"M[<5]S", "M2S", true},
|
||||
{"M[>A]S", "MFS", true},
|
||||
@@ -116,7 +115,6 @@ const struct expr_test tests[] = {
|
||||
{"[<5]S", "2B", false},
|
||||
{"[>A7]S", "FS", false},
|
||||
{"[>A7]S", "A6S", false},
|
||||
#endif
|
||||
{"", "", true}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user