mirror of
https://github.com/nmap/nmap.git
synced 2026-02-10 07:26:34 +00:00
IPv6 idle scan patch by Mathias Morbitzer.
http://seclists.org/nmap-dev/2013/q3/549
This commit is contained in:
99
osscan2.cc
99
osscan2.cc
@@ -198,6 +198,7 @@ static struct AVal *make_aval_ipid_seq(struct AVal *av, const char *attribute,
|
||||
case IPID_SEQ_CONSTANT:
|
||||
av->value = string_pool_sprintf("%X", ipids[0]);
|
||||
break;
|
||||
case IPID_SEQ_INCR_BY_2:
|
||||
case IPID_SEQ_INCR:
|
||||
av->value = "I";
|
||||
break;
|
||||
@@ -247,32 +248,9 @@ int get_initial_ttl_guess(u8 ttl) {
|
||||
one of the IPID_SEQ_* classifications defined in nmap.h . If the
|
||||
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. NOTE: the "ipids" argument
|
||||
may be modified if localhost is set to true. */
|
||||
int get_ipid_sequence(int numSamples, int *ipids, int islocalhost) {
|
||||
u16 ipid_diffs[32];
|
||||
int i, j, k;
|
||||
int allipideqz = 1; /* Flag that means "All IP.IDs returned during sequencing
|
||||
* are zero. This is unset if we find a nonzero */
|
||||
|
||||
assert(numSamples < (int) (sizeof(ipid_diffs) / 2));
|
||||
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 */
|
||||
|
||||
if (ipids[i - 1] <= ipids[i]) {
|
||||
ipid_diffs[i - 1] = ipids[i] - ipids[i - 1];
|
||||
} else {
|
||||
ipid_diffs[i - 1] = (u16) (ipids[i] - ipids[i - 1] + 65536);
|
||||
}
|
||||
|
||||
/* Random */
|
||||
if (numSamples > 2 && ipid_diffs[i - 1] > 20000)
|
||||
return IPID_SEQ_RD;
|
||||
}
|
||||
numbers were generated by scanning localhost. */
|
||||
int identify_sequence(int numSamples, u32 *ipid_diffs, int islocalhost, int allipideqz) {
|
||||
int i, j, k, l;
|
||||
|
||||
/* ZERO */
|
||||
if (allipideqz)
|
||||
@@ -321,11 +299,16 @@ int get_ipid_sequence(int numSamples, int *ipids, int islocalhost) {
|
||||
j = 1; /* j is a flag meaning "all differences seen are < 10" */
|
||||
k = 1; /* k is a flag meaning "all difference seen are multiples of 256 and
|
||||
* no greater than 5120" */
|
||||
l = 1; /* l is a flag meaning "all differences are multiples of 2" */
|
||||
for (i = 0; i < numSamples - 1; i++) {
|
||||
if (k && (ipid_diffs[i] > 5120 || ipid_diffs[i] % 256 != 0)) {
|
||||
k = 0;
|
||||
}
|
||||
|
||||
if (l && ipid_diffs[i] % 2 != 0) {
|
||||
l = 0;
|
||||
}
|
||||
|
||||
if (j && ipid_diffs[i] > 9) {
|
||||
j = 0;
|
||||
}
|
||||
@@ -336,13 +319,69 @@ int get_ipid_sequence(int numSamples, int *ipids, int islocalhost) {
|
||||
return IPID_SEQ_BROKEN_INCR;
|
||||
}
|
||||
|
||||
/* Incremental */
|
||||
/* Incrementing by 2 */
|
||||
if (l == 1)
|
||||
return IPID_SEQ_INCR_BY_2;
|
||||
|
||||
/* Incremental by 1 */
|
||||
if (j == 1)
|
||||
return IPID_SEQ_INCR;
|
||||
|
||||
return IPID_SEQ_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Calculate the distances between the ipids and write them
|
||||
into the ipid_diffs array */
|
||||
int get_diffs(u32 *ipid_diffs, int numSamples, int *ipids, int islocalhost) {
|
||||
int i;
|
||||
int allipideqz = 1;
|
||||
|
||||
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 */
|
||||
|
||||
if (ipids[i - 1] <= ipids[i]) {
|
||||
ipid_diffs[i - 1] = ipids[i] - ipids[i - 1];
|
||||
} else {
|
||||
ipid_diffs[i - 1] = (u32) (ipids[i] - ipids[i - 1] + 4294967296);
|
||||
}
|
||||
|
||||
/* Random */
|
||||
if (numSamples > 2 && ipid_diffs[i - 1] > 20000)
|
||||
return IPID_SEQ_RD;
|
||||
}
|
||||
|
||||
return allipideqz;
|
||||
|
||||
}
|
||||
|
||||
/* Indentify the ipid sequence for 32-bit IPID values (IPv6) */
|
||||
int get_ipid_sequence_32(int numSamples, int *ipids, int islocalhost) {
|
||||
int allipideqz=1;
|
||||
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);
|
||||
}
|
||||
|
||||
/* Indentify the ipid sequence for 16-bit IPID values (IPv4) */
|
||||
int get_ipid_sequence_16(int numSamples, int *ipids, int islocalhost) {
|
||||
int i;
|
||||
int allipideqz=1;
|
||||
u32 ipid_diffs[32];
|
||||
assert(numSamples < (int) (sizeof(ipid_diffs) / 2));
|
||||
allipideqz = 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);
|
||||
}
|
||||
|
||||
|
||||
/* Start the timeout clocks of any targets that aren't already timedout */
|
||||
static void startTimeOutClocks(OsScanInfo *OSI) {
|
||||
@@ -2374,7 +2413,7 @@ void HostOsScan::makeTSeqFP(HostOsScanStats *hss) {
|
||||
}
|
||||
|
||||
if (good_tcp_ipid_num >= 3) {
|
||||
tcp_ipid_seqclass = get_ipid_sequence(good_tcp_ipid_num, hss->ipid.tcp_ipids, islocalhost(hss->target->TargetSockAddr()));
|
||||
tcp_ipid_seqclass = get_ipid_sequence_16(good_tcp_ipid_num, hss->ipid.tcp_ipids, islocalhost(hss->target->TargetSockAddr()));
|
||||
} else {
|
||||
tcp_ipid_seqclass = IPID_SEQ_UNKNOWN;
|
||||
}
|
||||
@@ -2382,13 +2421,13 @@ void HostOsScan::makeTSeqFP(HostOsScanStats *hss) {
|
||||
hss->si.ipid_seqclass = tcp_ipid_seqclass;
|
||||
|
||||
if (good_tcp_closed_ipid_num >= 2) {
|
||||
tcp_closed_ipid_seqclass = get_ipid_sequence(good_tcp_closed_ipid_num, hss->ipid.tcp_closed_ipids, islocalhost(hss->target->TargetSockAddr()));
|
||||
tcp_closed_ipid_seqclass = get_ipid_sequence_16(good_tcp_closed_ipid_num, hss->ipid.tcp_closed_ipids, islocalhost(hss->target->TargetSockAddr()));
|
||||
} else {
|
||||
tcp_closed_ipid_seqclass = IPID_SEQ_UNKNOWN;
|
||||
}
|
||||
|
||||
if (good_icmp_ipid_num >= 2) {
|
||||
icmp_ipid_seqclass = get_ipid_sequence(good_icmp_ipid_num, hss->ipid.icmp_ipids, islocalhost(hss->target->TargetSockAddr()));
|
||||
icmp_ipid_seqclass = get_ipid_sequence_16(good_icmp_ipid_num, hss->ipid.icmp_ipids, islocalhost(hss->target->TargetSockAddr()));
|
||||
} else {
|
||||
icmp_ipid_seqclass = IPID_SEQ_UNKNOWN;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user