1
0
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:
dmiller
2014-03-15 12:37:54 +00:00
parent 573f9c1a73
commit c4a541ac1e

View File

@@ -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;
}
}