mirror of
https://github.com/nmap/nmap.git
synced 2025-12-15 04:09:01 +00:00
Fix IPID sequence detection in the case of Random
Reported by Lior Levinsky. As part of r32469, which added IPv6 IPID sequnce detection, the logic to detect all-zero IPID sequences was split. get_diffs was returning IPID_SEQ_UNKNOWN, IPID_SEQ_RD, or 1 for all-zeros, but the get_ipid_sequence_* functions were treating every non-zero return value as indicating all-zeros, which meant that IPID sequence detection was broken. http://seclists.org/nmap-dev/2014/q1/287
This commit is contained in:
42
osscan2.cc
42
osscan2.cc
@@ -249,13 +249,9 @@ int get_initial_ttl_guess(u8 ttl) {
|
||||
function cannot determine the sequence, IPID_SEQ_UNKNOWN is returned.
|
||||
This islocalhost argument is a boolean specifying whether these
|
||||
numbers were generated by scanning localhost. */
|
||||
int identify_sequence(int numSamples, u32 *ipid_diffs, int islocalhost, int allipideqz) {
|
||||
int identify_sequence(int numSamples, u32 *ipid_diffs, int islocalhost) {
|
||||
int i, j, k, l;
|
||||
|
||||
/* ZERO */
|
||||
if (allipideqz)
|
||||
return IPID_SEQ_ZERO;
|
||||
|
||||
if (islocalhost) {
|
||||
int allgto = 1; /* ALL diffs greater than one */
|
||||
|
||||
@@ -331,17 +327,18 @@ int identify_sequence(int numSamples, u32 *ipid_diffs, int islocalhost, int alli
|
||||
}
|
||||
|
||||
/* Calculate the distances between the ipids and write them
|
||||
into the ipid_diffs array */
|
||||
into the ipid_diffs array. If the sequence class can be determined
|
||||
immediately, return it; otherwise return -1 */
|
||||
int get_diffs(u32 *ipid_diffs, int numSamples, u32 *ipids, int islocalhost) {
|
||||
int i;
|
||||
int allipideqz = 1;
|
||||
bool allipideqz = true;
|
||||
|
||||
if (numSamples < 2)
|
||||
return IPID_SEQ_UNKNOWN;
|
||||
|
||||
for (i = 1; i < numSamples; i++) {
|
||||
if (ipids[i - 1] != 0 || ipids[i] != 0)
|
||||
allipideqz = 0; /* All IP.ID values do *NOT* equal zero */
|
||||
allipideqz = false; /* All IP.ID values do *NOT* equal zero */
|
||||
|
||||
ipid_diffs[i - 1] = ipids[i] - ipids[i - 1];
|
||||
|
||||
@@ -350,32 +347,47 @@ int get_diffs(u32 *ipid_diffs, int numSamples, u32 *ipids, int islocalhost) {
|
||||
return IPID_SEQ_RD;
|
||||
}
|
||||
|
||||
return allipideqz;
|
||||
if (allipideqz) {
|
||||
return IPID_SEQ_ZERO;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Indentify the ipid sequence for 32-bit IPID values (IPv6) */
|
||||
int get_ipid_sequence_32(int numSamples, u32 *ipids, int islocalhost) {
|
||||
int allipideqz=1;
|
||||
int ipid_seq = IPID_SEQ_UNKNOWN;
|
||||
u32 ipid_diffs[32];
|
||||
assert(numSamples < (int) (sizeof(ipid_diffs) / 2));
|
||||
allipideqz = get_diffs(ipid_diffs, numSamples, ipids, islocalhost);
|
||||
return identify_sequence(numSamples, ipid_diffs, islocalhost, allipideqz);
|
||||
ipid_seq = get_diffs(ipid_diffs, numSamples, ipids, islocalhost);
|
||||
if (ipid_seq < 0) {
|
||||
return identify_sequence(numSamples, ipid_diffs, islocalhost);
|
||||
}
|
||||
else {
|
||||
return ipid_seq;
|
||||
}
|
||||
}
|
||||
|
||||
/* Indentify the ipid sequence for 16-bit IPID values (IPv4) */
|
||||
int get_ipid_sequence_16(int numSamples, u32 *ipids, int islocalhost) {
|
||||
int i;
|
||||
int allipideqz=1;
|
||||
int ipid_seq = IPID_SEQ_UNKNOWN;
|
||||
u32 ipid_diffs[32];
|
||||
assert(numSamples < (int) (sizeof(ipid_diffs) / 2));
|
||||
allipideqz = get_diffs(ipid_diffs, numSamples, ipids, islocalhost);
|
||||
ipid_seq = get_diffs(ipid_diffs, numSamples, ipids, islocalhost);
|
||||
/* AND with 0xffff so that in case the 16 bit counter was
|
||||
* flipped over we still have a continuous sequence */
|
||||
for (i = 0; i < numSamples; i++) {
|
||||
ipid_diffs[i] = ipid_diffs[i] & 0xffff;
|
||||
}
|
||||
return identify_sequence(numSamples, ipid_diffs, islocalhost, allipideqz);
|
||||
if (ipid_seq < 0) {
|
||||
return identify_sequence(numSamples, ipid_diffs, islocalhost);
|
||||
}
|
||||
else {
|
||||
return ipid_seq;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user