1
2 /***************************************************************************
3 * osscan2.cc -- Routines used for 2nd Generation OS detection via *
4 * TCP/IP fingerprinting. * For more information on how this works in *
5 * Nmap, see https://nmap.org/osdetect/ *
6 * *
7 ***********************IMPORTANT NMAP LICENSE TERMS************************
8 * *
9 * The Nmap Security Scanner is (C) 1996-2020 Insecure.Com LLC ("The Nmap *
10 * Project"). Nmap is also a registered trademark of the Nmap Project. *
11 * *
12 * This program is distributed under the terms of the Nmap Public Source *
13 * License (NPSL). The exact license text applying to a particular Nmap *
14 * release or source code control revision is contained in the LICENSE *
15 * file distributed with that version of Nmap or source code control *
16 * revision. More Nmap copyright/legal information is available from *
17 * https://nmap.org/book/man-legal.html, and further information on the *
18 * NPSL license itself can be found at https://nmap.org/npsl. This header *
19 * summarizes some key points from the Nmap license, but is no substitute *
20 * for the actual license text. *
21 * *
22 * Nmap is generally free for end users to download and use themselves, *
23 * including commercial use. It is available from https://nmap.org. *
24 * *
25 * The Nmap license generally prohibits companies from using and *
26 * redistributing Nmap in commercial products, but we sell a special Nmap *
27 * OEM Edition with a more permissive license and special features for *
28 * this purpose. See https://nmap.org/oem *
29 * *
30 * If you have received a written Nmap license agreement or contract *
31 * stating terms other than these (such as an Nmap OEM license), you may *
32 * choose to use and redistribute Nmap under those terms instead. *
33 * *
34 * The official Nmap Windows builds include the Npcap software *
35 * (https://npcap.org) for packet capture and transmission. It is under *
36 * separate license terms which forbid redistribution without special *
37 * permission. So the official Nmap Windows builds may not be *
38 * redistributed without special permission (such as an Nmap OEM *
39 * license). *
40 * *
41 * Source is provided to this software because we believe users have a *
42 * right to know exactly what a program is going to do before they run it. *
43 * This also allows you to audit the software for security holes. *
44 * *
45 * Source code also allows you to port Nmap to new platforms, fix bugs, *
46 * and add new features. You are highly encouraged to submit your *
47 * changes as a Github PR or by email to the dev@nmap.org mailing list *
48 * for possible incorporation into the main distribution. Unless you *
49 * specify otherwise, it is understood that you are offering us very *
50 * broad rights to use your submissions as described in the Nmap Public *
51 * Source License Contributor Agreement. This is important because we *
52 * fund the project by selling licenses with various terms, and also *
53 * because the inability to relicense code has caused devastating *
54 * problems for other Free Software projects (such as KDE and NASM). *
55 * *
56 * The free version of Nmap is distributed in the hope that it will be *
57 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of *
58 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Warranties, *
59 * indemnification and commercial support are all available through the *
60 * Npcap OEM program--see https://nmap.org/oem. *
61 * *
62 ***************************************************************************/
63
64 /* $Id: osscan2.cc 38078 2020-10-02 16:12:22Z dmiller $ */
65
66 #include "osscan.h"
67 #include "osscan2.h"
68 #include "timing.h"
69 #include "NmapOps.h"
70 #include "tcpip.h"
71 #include "Target.h"
72 #include "utils.h"
73 #include "nmap_error.h"
74 #include "FPEngine.h"
75 #include "FingerPrintResults.h"
76 #include <dnet.h>
77
78 #include "struct_ip.h"
79 #include "string_pool.h"
80
81 #include <list>
82 #include <math.h>
83
84 extern NmapOps o;
85 #ifdef WIN32
86 /* from libdnet's intf-win32.c */
87 extern "C" int g_has_npcap_loopback;
88 #endif
89
90 /* 8 options:
91 * 0~5: six options for SEQ/OPS/WIN/T1 probes.
92 * 6: ECN probe.
93 * 7-12: T2~T7 probes.
94 *
95 * option 0: WScale (10), Nop, MSS (1460), Timestamp, SackP
96 * option 1: MSS (1400), WScale (0), SackP, T(0xFFFFFFFF,0x0), EOL
97 * option 2: T(0xFFFFFFFF, 0x0), Nop, Nop, WScale (5), Nop, MSS (640)
98 * option 3: SackP, T(0xFFFFFFFF,0x0), WScale (10), EOL
99 * option 4: MSS (536), SackP, T(0xFFFFFFFF,0x0), WScale (10), EOL
100 * option 5: MSS (265), SackP, T(0xFFFFFFFF,0x0)
101 * option 6: WScale (10), Nop, MSS (1460), SackP, Nop, Nop
102 * option 7-11: WScale (10), Nop, MSS (265), T(0xFFFFFFFF,0x0), SackP
103 * option 12: WScale (15), Nop, MSS (265), T(0xFFFFFFFF,0x0), SackP
104 */
105 static struct {
106 u8* val;
107 int len;
108 } prbOpts[] = {
109 {(u8*) "\x03\x03\x0A\x01\x02\x04\x05\xb4\x08\x0A\xff\xff\xff\xff\x00\x00\x00\x00\x04\x02", 20},
110 {(u8*) "\x02\x04\x05\x78\x03\x03\x00\x04\x02\x08\x0A\xff\xff\xff\xff\x00\x00\x00\x00\x00", 20},
111 {(u8*) "\x08\x0A\xff\xff\xff\xff\x00\x00\x00\x00\x01\x01\x03\x03\x05\x01\x02\x04\x02\x80", 20},
112 {(u8*) "\x04\x02\x08\x0A\xff\xff\xff\xff\x00\x00\x00\x00\x03\x03\x0A\x00", 16},
113 {(u8*) "\x02\x04\x02\x18\x04\x02\x08\x0A\xff\xff\xff\xff\x00\x00\x00\x00\x03\x03\x0A\x00", 20},
114 {(u8*) "\x02\x04\x01\x09\x04\x02\x08\x0A\xff\xff\xff\xff\x00\x00\x00\x00", 16},
115 {(u8*) "\x03\x03\x0A\x01\x02\x04\x05\xb4\x04\x02\x01\x01", 12},
116 {(u8*) "\x03\x03\x0A\x01\x02\x04\x01\x09\x08\x0A\xff\xff\xff\xff\x00\x00\x00\x00\x04\x02", 20},
117 {(u8*) "\x03\x03\x0A\x01\x02\x04\x01\x09\x08\x0A\xff\xff\xff\xff\x00\x00\x00\x00\x04\x02", 20},
118 {(u8*) "\x03\x03\x0A\x01\x02\x04\x01\x09\x08\x0A\xff\xff\xff\xff\x00\x00\x00\x00\x04\x02", 20},
119 {(u8*) "\x03\x03\x0A\x01\x02\x04\x01\x09\x08\x0A\xff\xff\xff\xff\x00\x00\x00\x00\x04\x02", 20},
120 {(u8*) "\x03\x03\x0A\x01\x02\x04\x01\x09\x08\x0A\xff\xff\xff\xff\x00\x00\x00\x00\x04\x02", 20},
121 {(u8*) "\x03\x03\x0f\x01\x02\x04\x01\x09\x08\x0A\xff\xff\xff\xff\x00\x00\x00\x00\x04\x02", 20}
122 };
123
124 /* TCP Window sizes. Numbering is the same as for prbOpts[] */
125 u16 prbWindowSz[] = { 1, 63, 4, 4, 16, 512, 3, 128, 256, 1024, 31337, 32768, 65535 };
126
127 /* Current time. It is globally accessible so it can save calls to gettimeofday() */
128 static struct timeval now;
129
130 /* Global to store performance info */
131 static struct scan_performance_vars perf;
132
133
134 /******************************************************************************
135 * Miscellaneous functions *
136 ******************************************************************************/
137
138 /* Fill in a struct AVal with a value based on the IP ID sequence generation
139 class (one of the IPID_SEQ_* constants). If ipid_seqclass is such that the
140 test result should be omitted, the function returns NULL and doesn't modify
141 *av. Otherwise, it returns av after filling in the information. */
make_aval_ipid_seq(struct AVal * av,const char * attribute,int ipid_seqclass,u32 ipids[NUM_SEQ_SAMPLES])142 static struct AVal *make_aval_ipid_seq(struct AVal *av, const char *attribute,
143 int ipid_seqclass, u32 ipids[NUM_SEQ_SAMPLES]) {
144 switch (ipid_seqclass) {
145 case IPID_SEQ_CONSTANT:
146 av->value = string_pool_sprintf("%X", ipids[0]);
147 break;
148 case IPID_SEQ_INCR_BY_2:
149 case IPID_SEQ_INCR:
150 av->value = "I";
151 break;
152 case IPID_SEQ_BROKEN_INCR:
153 av->value = "BI";
154 break;
155 case IPID_SEQ_RPI:
156 av->value = "RI";
157 break;
158 case IPID_SEQ_RD:
159 av->value = "RD";
160 break;
161 case IPID_SEQ_ZERO:
162 av->value = "Z";
163 break;
164 default:
165 /* Signal to omit test result. */
166 return NULL;
167 break;
168 }
169
170 av->attribute = string_pool_insert(attribute);
171
172 return av;
173 }
174
175
176 /* Returns a guess about the original TTL based on an observed TTL value.
177 * This function assumes that the target from which we received the packet was
178 * less than 32 hops away. Also, note that although some systems use an
179 * initial TTL of 60, this function rounds that to 64, as both values
180 * cannot be reliably distinguished based on a simple observed hop count. */
get_initial_ttl_guess(u8 ttl)181 int get_initial_ttl_guess(u8 ttl) {
182 if (ttl <= 32)
183 return 32;
184 else if (ttl <= 64)
185 return 64;
186 else if (ttl <= 128)
187 return 128;
188 else
189 return 255;
190 }
191
192
193 /* This function takes an array of "numSamples" IP IDs and analyzes
194 them to determine their sequence classification. It returns
195 one of the IPID_SEQ_* classifications defined in nmap.h . If the
196 function cannot determine the sequence, IPID_SEQ_UNKNOWN is returned.
197 This islocalhost argument is a boolean specifying whether these
198 numbers were generated by scanning localhost. */
identify_sequence(int numSamples,u32 * ipid_diffs,int islocalhost)199 int identify_sequence(int numSamples, u32 *ipid_diffs, int islocalhost) {
200 int i, j, k, l;
201
202 if (islocalhost) {
203 int allgto = 1; /* ALL diffs greater than one */
204
205 for (i = 0; i < numSamples - 1; i++) {
206 if (ipid_diffs[i] < 2) {
207 allgto = 0; break;
208 }
209 }
210
211 if (allgto) {
212 for (i = 0; i < numSamples - 1; i++) {
213 if (ipid_diffs[i] % 256 == 0) /* Stupid MS */
214 ipid_diffs[i] -= 256;
215 else
216 ipid_diffs[i]--; /* Because on localhost the RST sent back use an IPID */
217 }
218 }
219 }
220
221 /* Constant */
222 j = 1; /* j is a flag meaning "all differences seen are zero" */
223 for (i = 0; i < numSamples - 1; i++) {
224 if (ipid_diffs[i] != 0) {
225 j = 0;
226 break;
227 }
228 }
229 if (j) {
230 return IPID_SEQ_CONSTANT;
231 }
232
233 /* Random Positive Increments */
234 for (i = 0; i < numSamples - 1; i++) {
235 if (ipid_diffs[i] > 1000 &&
236 (ipid_diffs[i] % 256 != 0 ||
237 (ipid_diffs[i] % 256 == 0 && ipid_diffs[i] >= 25600))) {
238 return IPID_SEQ_RPI;
239 }
240 }
241
242 j = 1; /* j is a flag meaning "all differences seen are < 10" */
243 k = 1; /* k is a flag meaning "all difference seen are multiples of 256 and
244 * no greater than 5120" */
245 l = 1; /* l is a flag meaning "all differences are multiples of 2" */
246 for (i = 0; i < numSamples - 1; i++) {
247 if (k && (ipid_diffs[i] > 5120 || ipid_diffs[i] % 256 != 0)) {
248 k = 0;
249 }
250
251 if (l && ipid_diffs[i] % 2 != 0) {
252 l = 0;
253 }
254
255 if (j && ipid_diffs[i] > 9) {
256 j = 0;
257 }
258 }
259
260 /* Broken Increment */
261 if (k == 1) {
262 return IPID_SEQ_BROKEN_INCR;
263 }
264
265 /* Incrementing by 2 */
266 if (l == 1)
267 return IPID_SEQ_INCR_BY_2;
268
269 /* Incremental by 1 */
270 if (j == 1)
271 return IPID_SEQ_INCR;
272
273 return IPID_SEQ_UNKNOWN;
274 }
275
276 /* Calculate the distances between the ipids and write them
277 into the ipid_diffs array. If the sequence class can be determined
278 immediately, return it; otherwise return -1 */
get_diffs(u32 * ipid_diffs,int numSamples,u32 * ipids,int islocalhost)279 int get_diffs(u32 *ipid_diffs, int numSamples, u32 *ipids, int islocalhost) {
280 int i;
281 bool allipideqz = true;
282
283 if (numSamples < 2)
284 return IPID_SEQ_UNKNOWN;
285
286 for (i = 1; i < numSamples; i++) {
287 if (ipids[i - 1] != 0 || ipids[i] != 0)
288 allipideqz = false; /* All IP.ID values do *NOT* equal zero */
289
290 ipid_diffs[i - 1] = ipids[i] - ipids[i - 1];
291
292 /* Random */
293 if (numSamples > 2 && ipid_diffs[i - 1] > 20000)
294 return IPID_SEQ_RD;
295 }
296
297 if (allipideqz) {
298 return IPID_SEQ_ZERO;
299 }
300 else {
301 return -1;
302 }
303
304 }
305
306 /* Indentify the ipid sequence for 32-bit IPID values (IPv6) */
get_ipid_sequence_32(int numSamples,u32 * ipids,int islocalhost)307 int get_ipid_sequence_32(int numSamples, u32 *ipids, int islocalhost) {
308 int ipid_seq = IPID_SEQ_UNKNOWN;
309 u32 ipid_diffs[32];
310 assert(numSamples < (int) (sizeof(ipid_diffs) / 2));
311 ipid_seq = get_diffs(ipid_diffs, numSamples, ipids, islocalhost);
312 if (ipid_seq < 0) {
313 return identify_sequence(numSamples, ipid_diffs, islocalhost);
314 }
315 else {
316 return ipid_seq;
317 }
318 }
319
320 /* Indentify the ipid sequence for 16-bit IPID values (IPv4) */
get_ipid_sequence_16(int numSamples,u32 * ipids,int islocalhost)321 int get_ipid_sequence_16(int numSamples, u32 *ipids, int islocalhost) {
322 int i;
323 int ipid_seq = IPID_SEQ_UNKNOWN;
324 u32 ipid_diffs[32];
325 assert(numSamples < (int) (sizeof(ipid_diffs) / 2));
326 ipid_seq = get_diffs(ipid_diffs, numSamples, ipids, islocalhost);
327 /* AND with 0xffff so that in case the 16 bit counter was
328 * flipped over we still have a continuous sequence */
329 for (i = 0; i < numSamples; i++) {
330 ipid_diffs[i] = ipid_diffs[i] & 0xffff;
331 }
332 if (ipid_seq < 0) {
333 return identify_sequence(numSamples, ipid_diffs, islocalhost);
334 }
335 else {
336 return ipid_seq;
337 }
338 }
339
340 /* Convert a TCP sequence prediction difficulty index like 1264386
341 into a difficulty string like "Worthy Challenge */
seqidx2difficultystr(unsigned long idx)342 const char *seqidx2difficultystr(unsigned long idx) {
343 return (idx < 3) ? "Trivial joke" : (idx < 6) ? "Easy" : (idx < 11) ? "Medium" : (idx < 12) ? "Formidable" : (idx < 16) ? "Worthy challenge" : "Good luck!";
344 }
345
ipidclass2ascii(int seqclass)346 const char *ipidclass2ascii(int seqclass) {
347 switch (seqclass) {
348 case IPID_SEQ_CONSTANT:
349 return "Duplicated ipid (!)";
350 case IPID_SEQ_INCR:
351 return "Incremental";
352 case IPID_SEQ_INCR_BY_2:
353 return "Incrementing by 2";
354 case IPID_SEQ_BROKEN_INCR:
355 return "Broken little-endian incremental";
356 case IPID_SEQ_RD:
357 return "Randomized";
358 case IPID_SEQ_RPI:
359 return "Random positive increments";
360 case IPID_SEQ_ZERO:
361 return "All zeros";
362 case IPID_SEQ_UNKNOWN:
363 return "Busy server or unknown class";
364 default:
365 return "ERROR, WTF?";
366 }
367 }
368
tsseqclass2ascii(int seqclass)369 const char *tsseqclass2ascii(int seqclass) {
370 switch (seqclass) {
371 case TS_SEQ_ZERO:
372 return "zero timestamp";
373 case TS_SEQ_2HZ:
374 return "2HZ";
375 case TS_SEQ_100HZ:
376 return "100HZ";
377 case TS_SEQ_1000HZ:
378 return "1000HZ";
379 case TS_SEQ_OTHER_NUM:
380 return "other";
381 case TS_SEQ_UNSUPPORTED:
382 return "none returned (unsupported)";
383 case TS_SEQ_UNKNOWN:
384 return "unknown class";
385 default:
386 return "ERROR, WTF?";
387 }
388 }
389
390
391 /** Sets up the pcap descriptor in HOS (obtains a descriptor and sets the
392 * appropriate BPF filter, based on the supplied list of targets). */
begin_sniffer(HostOsScan * HOS,std::vector<Target * > & Targets)393 static void begin_sniffer(HostOsScan *HOS, std::vector<Target *> &Targets) {
394 char pcap_filter[2048];
395 /* 20 IPv6 addresses is max (45 byte addy + 14 (" or src host ")) * 20 == 1180 */
396 char dst_hosts[1200];
397 int filterlen = 0;
398 int len;
399 unsigned int targetno;
400 bool doIndividual = Targets.size() <= 20; // Don't bother IP limits if scanning huge # of hosts
401 pcap_filter[0] = '\0';
402
403 /* If we have 20 or less targets, build a list of addresses so we can set
404 * an explicit BPF filter */
405 if (doIndividual) {
406 for (targetno = 0; targetno < Targets.size(); targetno++) {
407 len = Snprintf(dst_hosts + filterlen,
408 sizeof(dst_hosts) - filterlen,
409 "%ssrc host %s", (targetno == 0)? "" : " or ",
410 Targets[targetno]->targetipstr());
411 if (len < 0 || len + filterlen >= (int) sizeof(dst_hosts))
412 fatal("ran out of space in dst_hosts");
413 filterlen += len;
414 }
415 len = Snprintf(dst_hosts + filterlen, sizeof(dst_hosts) - filterlen, ")))");
416 if (len < 0 || len + filterlen >= (int) sizeof(dst_hosts))
417 fatal("ran out of space in dst_hosts");
418 }
419
420 /* Open a network interface for packet capture */
421 HOS->pd = my_pcap_open_live(Targets[0]->deviceName(), 8192,
422 o.spoofsource ? 1 : 0, pcap_selectable_fd_valid() ? 200 : 2);
423 if (HOS->pd == NULL)
424 fatal("%s", PCAP_OPEN_ERRMSG);
425
426 struct sockaddr_storage ss = Targets[0]->source();
427 /* Build the final BPF filter */
428 if (ss.ss_family == AF_INET) {
429 if (doIndividual)
430 len = Snprintf(pcap_filter, sizeof(pcap_filter), "dst host %s and (icmp or (tcp and (%s",
431 inet_ntoa(((struct sockaddr_in *)&ss)->sin_addr), dst_hosts);
432 else
433 len = Snprintf(pcap_filter, sizeof(pcap_filter), "dst host %s and (icmp or tcp)",
434 inet_ntoa(((struct sockaddr_in *)&ss)->sin_addr));
435 if (len < 0 || len >= (int) sizeof(pcap_filter))
436 fatal("ran out of space in pcap filter");
437
438 /* Compile and apply the filter to the pcap descriptor */
439 if (o.debugging)
440 log_write(LOG_PLAIN, "Packet capture filter (device %s): %s\n", Targets[0]->deviceFullName(), pcap_filter);
441 set_pcap_filter(Targets[0]->deviceFullName(), HOS->pd, pcap_filter);
442 }
443
444 return;
445 }
446
447
448 /* Sets everything up so the current round can be performed. This includes
449 * reinitializing some variables of the supplied objects and deleting
450 * some old information. */
startRound(OsScanInfo * OSI,HostOsScan * HOS,int roundNum)451 static void startRound(OsScanInfo *OSI, HostOsScan *HOS, int roundNum) {
452 std::list<HostOsScanInfo *>::iterator hostI;
453 HostOsScanInfo *hsi = NULL;
454
455 /* Reinitial some parameters of the scan system. */
456 HOS->reInitScanSystem();
457
458 for (hostI = OSI->incompleteHosts.begin(); hostI != OSI->incompleteHosts.end(); hostI++) {
459 hsi = *hostI;
460 if (hsi->FPs[roundNum]) {
461 delete hsi->FPs[roundNum];
462 hsi->FPs[roundNum] = NULL;
463 }
464 hsi->hss->initScanStats();
465 }
466 }
467
468 /* Run the sequence generation tests (6 TCP probes sent 100ms apart) */
doSeqTests(OsScanInfo * OSI,HostOsScan * HOS)469 static void doSeqTests(OsScanInfo *OSI, HostOsScan *HOS) {
470 std::list<HostOsScanInfo *>::iterator hostI;
471 HostOsScanInfo *hsi = NULL;
472 HostOsScanStats *hss = NULL;
473 unsigned int unableToSend = 0; /* # of times in a row that hosts were unable to send probe */
474 unsigned int expectReplies = 0;
475 long to_usec = 0;
476 int timeToSleep = 0;
477 struct ip *ip = NULL;
478 struct link_header linkhdr;
479 struct sockaddr_storage ss;
480 unsigned int bytes = 0;
481 struct timeval rcvdtime;
482 struct timeval stime;
483 struct timeval tmptv;
484 bool timedout = false;
485 bool thisHostGood = false;
486 bool foundgood = false;
487 bool goodResponse = false;
488 int numProbesLeft = 0;
489
490 memset(&stime, 0, sizeof(stime));
491 memset(&tmptv, 0, sizeof(tmptv));
492
493 /* For each host, build a list of sequence probes to send */
494 for (hostI = OSI->incompleteHosts.begin(); hostI != OSI->incompleteHosts.end(); hostI++) {
495 hsi = *hostI;
496 hss = hsi->hss;
497 HOS->buildSeqProbeList(hss);
498 }
499
500 /* Iterate until we have sent all the probes */
501 do {
502 if (timeToSleep > 0) {
503 if (o.debugging > 1)
504 log_write(LOG_PLAIN, "Sleep %dus for next sequence probe\n", timeToSleep);
505 usleep(timeToSleep);
506 }
507
508 gettimeofday(&now, NULL);
509 expectReplies = 0;
510 unableToSend = 0;
511
512 if (o.debugging > 2) {
513 for (hostI = OSI->incompleteHosts.begin(); hostI != OSI->incompleteHosts.end(); hostI++) {
514 hss = (*hostI)->hss;
515 log_write(LOG_PLAIN, "Host %s. ProbesToSend %d: \tProbesActive %d\n",
516 hss->target->targetipstr(), hss->numProbesToSend(),
517 hss->numProbesActive());
518 }
519 }
520
521 /* Send a seq probe to each host. */
522 while (unableToSend < OSI->numIncompleteHosts() && HOS->stats->sendOK()) {
523 hsi = OSI->nextIncompleteHost();
524 hss = hsi->hss;
525 gettimeofday(&now, NULL);
526 if (hss->numProbesToSend()>0 && HOS->hostSeqSendOK(hss, NULL)) {
527 HOS->sendNextProbe(hss);
528 expectReplies++;
529 unableToSend = 0;
530 } else {
531 unableToSend++;
532 }
533 }
534
535 HOS->stats->num_probes_sent_at_last_wait = HOS->stats->num_probes_sent;
536
537 gettimeofday(&now, NULL);
538
539 /* Count the pcap wait time. */
540 if (!HOS->stats->sendOK()) {
541 TIMEVAL_MSEC_ADD(stime, now, 1000);
542
543 for (hostI = OSI->incompleteHosts.begin(); hostI != OSI->incompleteHosts.end(); hostI++) {
544 if (HOS->nextTimeout((*hostI)->hss, &tmptv)) {
545 if (TIMEVAL_SUBTRACT(tmptv, stime) < 0)
546 stime = tmptv;
547 }
548 }
549 } else {
550 foundgood = false;
551 for (hostI = OSI->incompleteHosts.begin(); hostI != OSI->incompleteHosts.end(); hostI++) {
552 thisHostGood = HOS->hostSeqSendOK((*hostI)->hss, &tmptv);
553 if (thisHostGood) {
554 stime = tmptv;
555 foundgood = true;
556 break;
557 }
558
559 if (!foundgood || TIMEVAL_SUBTRACT(tmptv, stime) < 0) {
560 stime = tmptv;
561 foundgood = true;
562 }
563 }
564 }
565
566 do {
567 to_usec = TIMEVAL_SUBTRACT(stime, now);
568 if (to_usec < 2000)
569 to_usec = 2000;
570
571 if (o.debugging > 2)
572 log_write(LOG_PLAIN, "pcap wait time is %ld.\n", to_usec);
573
574 ip = (struct ip*) readipv4_pcap(HOS->pd, &bytes, to_usec, &rcvdtime, &linkhdr, true);
575
576 gettimeofday(&now, NULL);
577
578 if (!ip && TIMEVAL_SUBTRACT(stime, now) < 0) {
579 timedout = true;
580 break;
581 } else if (!ip) {
582 continue;
583 }
584
585 if (TIMEVAL_SUBTRACT(now, stime) > 200000) {
586 /* While packets are still being received, I'll be generous and give
587 an extra 1/5 sec. But we have to draw the line somewhere */
588 timedout = true;
589 }
590
591 if (bytes < (4 * ip->ip_hl) + 4U)
592 continue;
593
594 memset(&ss, 0, sizeof(ss));
595 ((struct sockaddr_in *) &ss)->sin_addr.s_addr = ip->ip_src.s_addr;
596 ss.ss_family = AF_INET;
597 hsi = OSI->findIncompleteHost(&ss);
598 if (!hsi)
599 continue; /* Not from one of our targets. */
600 setTargetMACIfAvailable(hsi->target, &linkhdr, &ss, 0);
601
602 goodResponse = HOS->processResp(hsi->hss, ip, bytes, &rcvdtime);
603
604 if (goodResponse)
605 expectReplies--;
606
607 } while (!timedout && expectReplies > 0);
608
609 /* Remove any timeout hosts during the scan. */
610 OSI->removeCompletedHosts();
611
612 numProbesLeft = 0;
613 for (hostI = OSI->incompleteHosts.begin();
614 hostI != OSI->incompleteHosts.end(); hostI++) {
615 hss = (*hostI)->hss;
616 HOS->updateActiveSeqProbes(hss);
617 numProbesLeft += hss->numProbesToSend();
618 numProbesLeft += hss->numProbesActive();
619 }
620
621 gettimeofday(&now, NULL);
622
623 if (expectReplies == 0) {
624 timeToSleep = TIMEVAL_SUBTRACT(stime, now);
625 } else {
626 timeToSleep = 0;
627 }
628
629 } while (numProbesLeft > 0);
630
631 }
632
633
634 /* TCP, UDP, ICMP Tests */
doTUITests(OsScanInfo * OSI,HostOsScan * HOS)635 static void doTUITests(OsScanInfo *OSI, HostOsScan *HOS) {
636 std::list<HostOsScanInfo *>::iterator hostI;
637 HostOsScanInfo *hsi = NULL;
638 HostOsScanStats *hss = NULL;
639 unsigned int unableToSend; /* # of times in a row that hosts were unable to send probe */
640 unsigned int expectReplies;
641 long to_usec;
642 int timeToSleep = 0;
643
644 struct ip *ip = NULL;
645 struct link_header linkhdr;
646 struct sockaddr_storage ss;
647 unsigned int bytes;
648 struct timeval rcvdtime;
649
650 struct timeval stime, tmptv;
651
652 bool timedout = false;
653 bool thisHostGood;
654 bool foundgood;
655 bool goodResponse;
656 int numProbesLeft = 0;
657
658 memset(&stime, 0, sizeof(stime));
659 memset(&tmptv, 0, sizeof(tmptv));
660
661 for (hostI = OSI->incompleteHosts.begin();
662 hostI != OSI->incompleteHosts.end(); hostI++) {
663 hsi = *hostI;
664 hss = hsi->hss;
665 HOS->buildTUIProbeList(hss);
666 }
667
668 do {
669
670 if (timeToSleep > 0) {
671 if (o.debugging > 1) {
672 log_write(LOG_PLAIN, "Time to sleep %d. Sleeping. \n", timeToSleep);
673 }
674
675 usleep(timeToSleep);
676 }
677
678 gettimeofday(&now, NULL);
679 expectReplies = 0;
680 unableToSend = 0;
681
682 if (o.debugging > 2) {
683 for (hostI = OSI->incompleteHosts.begin();
684 hostI != OSI->incompleteHosts.end(); hostI++) {
685 hss = (*hostI)->hss;
686 log_write(LOG_PLAIN, "Host %s. ProbesToSend %d: \tProbesActive %d\n",
687 hss->target->targetipstr(), hss->numProbesToSend(),
688 hss->numProbesActive());
689 }
690 }
691
692 while (unableToSend < OSI->numIncompleteHosts() && HOS->stats->sendOK()) {
693 hsi = OSI->nextIncompleteHost();
694 hss = hsi->hss;
695 gettimeofday(&now, NULL);
696 if (hss->numProbesToSend()>0 && HOS->hostSendOK(hss, NULL)) {
697 HOS->sendNextProbe(hss);
698 expectReplies++;
699 unableToSend = 0;
700 } else {
701 unableToSend++;
702 }
703 }
704
705 HOS->stats->num_probes_sent_at_last_wait = HOS->stats->num_probes_sent;
706
707 gettimeofday(&now, NULL);
708
709 /* Count the pcap wait time. */
710 if (!HOS->stats->sendOK()) {
711 TIMEVAL_MSEC_ADD(stime, now, 1000);
712
713 for (hostI = OSI->incompleteHosts.begin(); hostI != OSI->incompleteHosts.end();
714 hostI++) {
715 if (HOS->nextTimeout((*hostI)->hss, &tmptv)) {
716 if (TIMEVAL_SUBTRACT(tmptv, stime) < 0)
717 stime = tmptv;
718 }
719 }
720 }
721 else {
722 foundgood = false;
723 for (hostI = OSI->incompleteHosts.begin(); hostI != OSI->incompleteHosts.end(); hostI++) {
724 thisHostGood = HOS->hostSendOK((*hostI)->hss, &tmptv);
725 if (thisHostGood) {
726 stime = tmptv;
727 foundgood = true;
728 break;
729 }
730
731 if (!foundgood || TIMEVAL_SUBTRACT(tmptv, stime) < 0) {
732 stime = tmptv;
733 foundgood = true;
734 }
735 }
736 }
737
738 do {
739 to_usec = TIMEVAL_SUBTRACT(stime, now);
740 if (to_usec < 2000) to_usec = 2000;
741
742 if (o.debugging > 2)
743 log_write(LOG_PLAIN, "pcap wait time is %ld.\n", to_usec);
744
745 ip = (struct ip*) readipv4_pcap(HOS->pd, &bytes, to_usec, &rcvdtime, &linkhdr, true);
746
747 gettimeofday(&now, NULL);
748
749 if (!ip && TIMEVAL_SUBTRACT(stime, now) < 0) {
750 timedout = true;
751 break;
752 } else if (!ip) {
753 continue;
754 }
755
756 if (TIMEVAL_SUBTRACT(now, stime) > 200000) {
757 /* While packets are still being received, I'll be generous and give
758 an extra 1/5 sec. But we have to draw the line somewhere */
759 timedout = true;
760 }
761
762 if (bytes < (4 * ip->ip_hl) + 4U)
763 continue;
764
765 memset(&ss, 0, sizeof(ss));
766 ((struct sockaddr_in *) &ss)->sin_addr.s_addr = ip->ip_src.s_addr;
767 ss.ss_family = AF_INET;
768 hsi = OSI->findIncompleteHost(&ss);
769 if (!hsi)
770 continue; /* Not from one of our targets. */
771 setTargetMACIfAvailable(hsi->target, &linkhdr, &ss, 0);
772
773 goodResponse = HOS->processResp(hsi->hss, ip, bytes, &rcvdtime);
774
775 if (goodResponse)
776 expectReplies--;
777
778 } while (!timedout && expectReplies > 0);
779
780 /* Remove any timeout hosts during the scan. */
781 OSI->removeCompletedHosts();
782
783 numProbesLeft = 0;
784 for (hostI = OSI->incompleteHosts.begin();
785 hostI != OSI->incompleteHosts.end(); hostI++) {
786 hss = (*hostI)->hss;
787 HOS->updateActiveTUIProbes(hss);
788 numProbesLeft += hss->numProbesToSend();
789 numProbesLeft += hss->numProbesActive();
790 }
791
792 gettimeofday(&now, NULL);
793
794 if (expectReplies == 0) {
795 timeToSleep = TIMEVAL_SUBTRACT(stime, now);
796 } else {
797 timeToSleep = 0;
798 }
799
800 } while (numProbesLeft > 0);
801 }
802
803
endRound(OsScanInfo * OSI,HostOsScan * HOS,int roundNum)804 static void endRound(OsScanInfo *OSI, HostOsScan *HOS, int roundNum) {
805 std::list<HostOsScanInfo *>::iterator hostI;
806 HostOsScanInfo *hsi = NULL;
807 int distance = -1;
808 enum dist_calc_method distance_calculation_method = DIST_METHOD_NONE;
809
810 for (hostI = OSI->incompleteHosts.begin(); hostI != OSI->incompleteHosts.end(); hostI++) {
811 distance = -1;
812 hsi = *hostI;
813 HOS->makeFP(hsi->hss);
814
815 hsi->FPs[roundNum] = hsi->hss->getFP();
816 hsi->FPR->FPs[roundNum] = hsi->FPs[roundNum];
817 hsi->FPR->numFPs = roundNum + 1;
818 double tr = hsi->hss->timingRatio();
819 hsi->target->FPR->maxTimingRatio = MAX(hsi->target->FPR->maxTimingRatio, tr);
820 match_fingerprint(hsi->FPs[roundNum], &hsi->FP_matches[roundNum],
821 o.reference_FPs, OSSCAN_GUESS_THRESHOLD);
822
823 if (hsi->FP_matches[roundNum].overall_results == OSSCAN_SUCCESS &&
824 hsi->FP_matches[roundNum].num_perfect_matches > 0) {
825 memcpy(&(hsi->target->seq), &hsi->hss->si, sizeof(struct seq_info));
826 if (roundNum > 0) {
827 if (o.verbose)
828 log_write(LOG_STDOUT, "WARNING: OS didn't match until try #%d\n", roundNum + 1);
829 }
830 match_fingerprint(hsi->FPR->FPs[roundNum], hsi->FPR,
831 o.reference_FPs, OSSCAN_GUESS_THRESHOLD);
832 hsi->isCompleted = true;
833 }
834
835 if (islocalhost(hsi->target->TargetSockAddr())) {
836 /* scanning localhost */
837 distance = 0;
838 distance_calculation_method = DIST_METHOD_LOCALHOST;
839 } else if (hsi->target->MACAddress()) {
840 /* on the same network segment */
841 distance = 1;
842 distance_calculation_method = DIST_METHOD_DIRECT;
843 } else if (hsi->hss->distance!=-1) {
844 distance = hsi->hss->distance;
845 distance_calculation_method = DIST_METHOD_ICMP;
846 }
847
848 hsi->target->distance = hsi->target->FPR->distance = distance;
849 hsi->target->distance_calculation_method = distance_calculation_method;
850 hsi->target->FPR->distance_guess = hsi->hss->distance_guess;
851
852 }
853 OSI->removeCompletedHosts();
854 }
855
856
findBestFPs(OsScanInfo * OSI)857 static void findBestFPs(OsScanInfo *OSI) {
858 std::list<HostOsScanInfo *>::iterator hostI;
859 HostOsScanInfo *hsi = NULL;
860 int i;
861
862 double bestacc;
863 int bestaccidx;
864
865 for (hostI = OSI->incompleteHosts.begin(); hostI != OSI->incompleteHosts.end(); hostI++) {
866 hsi = *hostI;
867 memcpy(&(hsi->target->seq), &hsi->hss->si, sizeof(struct seq_info));
868
869 /* Now lets find the best match */
870 bestacc = 0;
871 bestaccidx = 0;
872 for (i = 0; i < hsi->FPR->numFPs; i++) {
873 if (hsi->FP_matches[i].overall_results == OSSCAN_SUCCESS &&
874 hsi->FP_matches[i].num_matches > 0 &&
875 hsi->FP_matches[i].accuracy[0] > bestacc) {
876 bestacc = hsi->FP_matches[i].accuracy[0];
877 bestaccidx = i;
878 if (hsi->FP_matches[i].num_perfect_matches)
879 break;
880 }
881 }
882
883 // Now we redo the match, since target->FPR has various data (such as
884 // target->FPR->numFPs) which is not in FP_matches[bestaccidx]. This is
885 // kinda ugly.
886 match_fingerprint(hsi->FPR->FPs[bestaccidx], (FingerPrintResultsIPv4 *) hsi->target->FPR,
887 o.reference_FPs, OSSCAN_GUESS_THRESHOLD);
888 }
889 }
890
891
printFP(OsScanInfo * OSI)892 static void printFP(OsScanInfo *OSI) {
893 std::list<HostOsScanInfo *>::iterator hostI;
894 HostOsScanInfo *hsi = NULL;
895 FingerPrintResultsIPv4 *FPR;
896
897 for (hostI = OSI->incompleteHosts.begin(); hostI != OSI->incompleteHosts.end(); hostI++) {
898 hsi = *hostI;
899 FPR = hsi->FPR;
900
901 log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT,
902 "No OS matches for %s by new os scan system.\n\nTCP/IP fingerprint:\n%s",
903 hsi->target->targetipstr(),
904 mergeFPs(FPR->FPs, FPR->numFPs, true,
905 hsi->target->TargetSockAddr(), hsi->target->distance,
906 hsi->target->distance_calculation_method,
907 hsi->target->MACAddress(),
908 FPR->osscan_opentcpport, FPR->osscan_closedtcpport,
909 FPR->osscan_closedudpport, false));
910 }
911 }
912
913
914 /* Goes through every unmatched host in OSI. If a host has completed
915 the maximum number of OS detection tries allowed for it without
916 matching, it is transferred to the passed in unMatchedHosts list.
917 Returns the number of hosts moved to unMatchedHosts. */
expireUnmatchedHosts(OsScanInfo * OSI,std::list<HostOsScanInfo * > * unMatchedHosts)918 static int expireUnmatchedHosts(OsScanInfo *OSI, std::list<HostOsScanInfo *> *unMatchedHosts) {
919 std::list<HostOsScanInfo *>::iterator hostI, nextHost;
920 int hostsRemoved = 0;
921 HostOsScanInfo *HOS;
922
923 gettimeofday(&now, NULL);
924 for (hostI = OSI->incompleteHosts.begin(); hostI != OSI->incompleteHosts.end(); hostI = nextHost) {
925 HOS = *hostI;
926 nextHost = hostI;
927 nextHost++;
928
929 int max_tries = o.maxOSTries(); /* The amt. if print is suitable for submission */
930 if (HOS->target->FPR->OmitSubmissionFP())
931 max_tries = MIN(max_tries, STANDARD_OS2_TRIES);
932
933 if (HOS->FPR->numFPs >= max_tries) {
934 /* We've done all the OS2 tries we're going to do ... move this
935 to unMatchedHosts */
936 HOS->target->stopTimeOutClock(&now);
937 OSI->incompleteHosts.erase(hostI);
938 /* We need to adjust nextI if necessary */
939 OSI->resetHostIterator();
940 hostsRemoved++;
941 unMatchedHosts->push_back(HOS);
942 }
943 }
944 return hostsRemoved;
945 }
946
947
948 /******************************************************************************
949 * Implementation of class OFProbe *
950 ******************************************************************************/
951
OFProbe()952 OFProbe::OFProbe() {
953 type = OFP_UNSET;
954 subid = 0;
955 tryno = -1;
956 retransmitted = false;
957 memset(&sent, 0, sizeof(sent));
958 memset(&prevSent, 0, sizeof(prevSent));
959 }
960
961
typestr()962 const char *OFProbe::typestr() {
963 switch (type) {
964 case OFP_UNSET:
965 return "OFP_UNSET";
966 case OFP_TSEQ:
967 return "OFP_TSEQ";
968 case OFP_TOPS:
969 return "OFP_TOPS";
970 case OFP_TECN:
971 return "OFP_TECN";
972 case OFP_T1_7:
973 return "OFP_T1_7";
974 case OFP_TUDP:
975 return "OFP_TUDP";
976 case OFP_TICMP:
977 return "OFP_TICMP";
978 default:
979 assert(false);
980 return "ERROR";
981 }
982 }
983
984
985 /******************************************************************************
986 * Implementation of class HostOsScanStats *
987 ******************************************************************************/
988
HostOsScanStats(Target * t)989 HostOsScanStats::HostOsScanStats(Target * t) {
990 int i;
991
992 target = t;
993 FP = NULL;
994
995 memset(&si, 0, sizeof(si));
996 memset(&ipid, 0, sizeof(ipid));
997
998 openTCPPort = -1;
999 closedTCPPort = -1;
1000 closedUDPPort = -1;
1001
1002 num_probes_sent = 0;
1003 sendDelayMs = MAX(o.scan_delay, OS_PROBE_DELAY);
1004 lastProbeSent = now;
1005
1006 /* Timing */
1007 timing.cwnd = perf.host_initial_cwnd;
1008 timing.ssthresh = perf.initial_ssthresh; /* Will be reduced if any packets are dropped anyway */
1009 timing.num_replies_expected = 0;
1010 timing.num_replies_received = 0;
1011 timing.num_updates = 0;
1012 gettimeofday(&timing.last_drop, NULL);
1013
1014 for (i = 0; i < NUM_FPTESTS; i++)
1015 FPtests[i] = NULL;
1016 for (i = 0; i < 6; i++) {
1017 TOps_AVs[i] = NULL;
1018 TWin_AVs[i] = NULL;
1019 }
1020
1021 icmpEchoReply = NULL;
1022
1023 distance = -1;
1024 distance_guess = -1;
1025 }
1026
1027
~HostOsScanStats()1028 HostOsScanStats::~HostOsScanStats() {
1029 int i;
1030
1031 for (i = 0; i < NUM_FPTESTS; i++) {
1032 if (FPtests[i] != NULL)
1033 delete FPtests[i];
1034 }
1035 for (i = 0; i < 6; i++) {
1036 if (TOps_AVs[i])
1037 free(TOps_AVs[i]);
1038 if (TWin_AVs[i])
1039 free(TWin_AVs[i]);
1040 }
1041
1042 while (!probesToSend.empty()) {
1043 delete probesToSend.front();
1044 probesToSend.pop_front();
1045 }
1046
1047 while (!probesActive.empty()) {
1048 delete probesActive.front();
1049 probesActive.pop_front();
1050 }
1051
1052 if (icmpEchoReply) free(icmpEchoReply);
1053 }
1054
1055
initScanStats()1056 void HostOsScanStats::initScanStats() {
1057 Port *tport = NULL;
1058 Port port;
1059 int i;
1060
1061 /* Lets find an open port to use if we don't already have one */
1062 openTCPPort = -1;
1063 /* target->FPR->osscan_opentcpport = -1;
1064 target->FPR->osscan_closedtcpport = -1;
1065 target->FPR->osscan_closedudpport = -1; */
1066
1067 if (target->FPR->osscan_opentcpport > 0)
1068 openTCPPort = target->FPR->osscan_opentcpport;
1069 else if ((tport = target->ports.nextPort(NULL, &port, IPPROTO_TCP, PORT_OPEN))) {
1070 openTCPPort = tport->portno;
1071 /* If it is zero, let's try another one if there is one ) */
1072 if (tport->portno == 0)
1073 if ((tport = target->ports.nextPort(tport, &port, IPPROTO_TCP, PORT_OPEN)))
1074 openTCPPort = tport->portno;
1075
1076 target->FPR->osscan_opentcpport = openTCPPort;
1077 }
1078
1079 /* We should look at a different port if we know that this port is tcpwrapped */
1080 if (o.servicescan && openTCPPort > 0 && target->ports.isTCPwrapped(openTCPPort)) {
1081 if (o.debugging) {
1082 log_write(LOG_STDOUT, "First choice open TCP port %d is tcpwrapped. ", openTCPPort);
1083 }
1084 /* Keep moving to other ports until we find one which is not tcpwrapped, or until we run out of ports */
1085 while ((tport = target->ports.nextPort(tport, &port, IPPROTO_TCP, PORT_OPEN))) {
1086 openTCPPort = tport->portno;
1087 if (!target->ports.isTCPwrapped(openTCPPort)) {
1088 break;
1089 }
1090 }
1091
1092 target->FPR->osscan_opentcpport = openTCPPort;
1093
1094 if (o.debugging) {
1095 if (target->ports.isTCPwrapped(openTCPPort)) {
1096 log_write(LOG_STDOUT, "All open TCP ports are found to be tcpwrapped. Using %d for OS detection, but results might not be accurate.\n", openTCPPort);
1097 } else {
1098 log_write(LOG_STDOUT, "Using non-tcpwrapped port %d for OS detection.\n", openTCPPort);
1099 }
1100 }
1101 }
1102
1103 /* Now we should find a closed TCP port */
1104 if (target->FPR->osscan_closedtcpport > 0)
1105 closedTCPPort = target->FPR->osscan_closedtcpport;
1106 else if ((tport = target->ports.nextPort(NULL, &port, IPPROTO_TCP, PORT_CLOSED))) {
1107 closedTCPPort = tport->portno;
1108
1109 /* If it is zero, let's try another one if there is one ) */
1110 if (tport->portno == 0)
1111 if ((tport = target->ports.nextPort(tport, &port, IPPROTO_TCP, PORT_CLOSED)))
1112 closedTCPPort = tport->portno;
1113
1114 target->FPR->osscan_closedtcpport = closedTCPPort;
1115 } else if ((tport = target->ports.nextPort(NULL, &port, IPPROTO_TCP, PORT_UNFILTERED))) {
1116 /* Well, we will settle for unfiltered */
1117 closedTCPPort = tport->portno;
1118 /* But again we'd prefer not to have zero */
1119 if (tport->portno == 0)
1120 if ((tport = target->ports.nextPort(tport, &port, IPPROTO_TCP, PORT_UNFILTERED)))
1121 closedTCPPort = tport->portno;
1122 } else {
1123 /* We'll just have to pick one at random :( */
1124 closedTCPPort = (get_random_uint() % 14781) + 30000;
1125 }
1126
1127 /* Now we should find a closed UDP port */
1128 if (target->FPR->osscan_closedudpport > 0)
1129 closedUDPPort = target->FPR->osscan_closedudpport;
1130 else if ((tport = target->ports.nextPort(NULL, &port, IPPROTO_UDP, PORT_CLOSED))) {
1131 closedUDPPort = tport->portno;
1132 /* Not zero, if possible */
1133 if (tport->portno == 0)
1134 if ((tport = target->ports.nextPort(tport, &port, IPPROTO_UDP, PORT_CLOSED)))
1135 closedUDPPort = tport->portno;
1136 target->FPR->osscan_closedudpport = closedUDPPort;
1137 } else if ((tport = target->ports.nextPort(NULL, &port, IPPROTO_UDP, PORT_UNFILTERED))) {
1138 /* Well, we will settle for unfiltered */
1139 closedUDPPort = tport->portno;
1140 /* But not zero, please */
1141 if (tport->portno == 0)
1142 if ((tport = target->ports.nextPort(NULL, &port, IPPROTO_UDP, PORT_UNFILTERED)))
1143 closedUDPPort = tport->portno;
1144 } else {
1145 /* Pick one at random. Shrug. */
1146 closedUDPPort = (get_random_uint() % 14781) + 30000;
1147 }
1148
1149 FP = NULL;
1150 for (i = 0; i < NUM_FPTESTS; i++) {
1151 if (FPtests[i] != NULL)
1152 delete FPtests[i];
1153 FPtests[i] = NULL;
1154 }
1155 for (i = 0; i < 6; i++) {
1156 if (TOps_AVs[i])
1157 free(TOps_AVs[i]);
1158 if (TWin_AVs[i])
1159 free(TWin_AVs[i]);
1160 TOps_AVs[i] = NULL;
1161 TWin_AVs[i] = NULL;
1162 }
1163
1164 TOpsReplyNum = 0;
1165 TWinReplyNum = 0;
1166
1167 lastipid = 0;
1168 memset(&si, 0, sizeof(si));
1169
1170 for (i = 0; i < NUM_SEQ_SAMPLES; i++) {
1171 ipid.tcp_ipids[i] = -1;
1172 ipid.tcp_closed_ipids[i] = -1;
1173 ipid.icmp_ipids[i] = -1;
1174 }
1175
1176 memset(&seq_send_times, 0, sizeof(seq_send_times));
1177
1178 if (icmpEchoReply) {
1179 free(icmpEchoReply);
1180 icmpEchoReply = NULL;
1181 }
1182 storedIcmpReply = -1;
1183
1184 memset(&upi, 0, sizeof(upi));
1185 }
1186
1187
1188 /* Fill in an eth_nfo struct with the appropriate source and destination MAC
1189 addresses and a given Ethernet handle. The return value is suitable to pass
1190 to send_ip_packet: if ethsd is NULL, returns NULL; otherwise returns eth. */
fill_eth_nfo(struct eth_nfo * eth,eth_t * ethsd) const1191 struct eth_nfo *HostOsScanStats::fill_eth_nfo(struct eth_nfo *eth, eth_t *ethsd) const {
1192 if (ethsd == NULL)
1193 return NULL;
1194
1195 memcpy(eth->srcmac, target->SrcMACAddress(), sizeof(eth->srcmac));
1196 memcpy(eth->dstmac, target->NextHopMACAddress(), sizeof(eth->srcmac));
1197 eth->ethsd = ethsd;
1198 eth->devname[0] = '\0';
1199
1200 return eth;
1201 }
1202
1203
1204 /* Add a probe to the probe list. */
addNewProbe(OFProbeType type,int subid)1205 void HostOsScanStats::addNewProbe(OFProbeType type, int subid) {
1206 OFProbe *probe = new OFProbe();
1207 probe->type = type;
1208 probe->subid = subid;
1209 probesToSend.push_back(probe);
1210 }
1211
1212
1213 /* Remove a probe from the probesActive. */
removeActiveProbe(std::list<OFProbe * >::iterator probeI)1214 void HostOsScanStats::removeActiveProbe(std::list<OFProbe *>::iterator probeI) {
1215 OFProbe *probe = *probeI;
1216 probesActive.erase(probeI);
1217 delete probe;
1218 }
1219
1220
1221 /* Get an active probe from active probe list identified by probe type
1222 and subid. Returns probesActive.end() if there isn't one */
getActiveProbe(OFProbeType type,int subid)1223 std::list<OFProbe *>::iterator HostOsScanStats::getActiveProbe(OFProbeType type, int subid) {
1224 std::list<OFProbe *>::iterator probeI;
1225 OFProbe *probe = NULL;
1226
1227 for (probeI = probesActive.begin(); probeI != probesActive.end(); probeI++) {
1228 probe = *probeI;
1229 if (probe->type == type && probe->subid == subid)
1230 break;
1231 }
1232
1233 if (probeI == probesActive.end()) {
1234 /* not found!? */
1235 if (o.debugging > 1)
1236 log_write(LOG_PLAIN, "Probe doesn't exist! Probe type: %d. Probe subid: %d\n", type, subid);
1237 return probesActive.end();
1238 }
1239
1240 return probeI;
1241 }
1242
1243
1244 /* Move a probe from probesToSend to probesActive. */
moveProbeToActiveList(std::list<OFProbe * >::iterator probeI)1245 void HostOsScanStats::moveProbeToActiveList(std::list<OFProbe *>::iterator probeI) {
1246 probesActive.push_back(*probeI);
1247 probesToSend.erase(probeI);
1248 }
1249
1250
1251 /* Move a probe from probesActive to probesToSend. */
moveProbeToUnSendList(std::list<OFProbe * >::iterator probeI)1252 void HostOsScanStats::moveProbeToUnSendList(std::list<OFProbe *>::iterator probeI) {
1253 probesToSend.push_back(*probeI);
1254 probesActive.erase(probeI);
1255 }
1256
1257
1258 /* Compute the ratio of amount of time taken between sending 1st TSEQ
1259 probe and 1st ICMP probe compared to the amount of time it should
1260 have taken. Ratios far from 1 can cause bogus results */
timingRatio()1261 double HostOsScanStats::timingRatio() {
1262 if (openTCPPort < 0)
1263 return 0;
1264 int msec_ideal = OS_SEQ_PROBE_DELAY * (NUM_SEQ_SAMPLES - 1);
1265 int msec_taken = TIMEVAL_MSEC_SUBTRACT(seq_send_times[NUM_SEQ_SAMPLES -1 ], seq_send_times[0]);
1266 if (o.debugging) {
1267 log_write(LOG_PLAIN, "OS detection timingRatio() == (%.3f - %.3f) * 1000 / %d == %.3f\n",
1268 seq_send_times[NUM_SEQ_SAMPLES - 1].tv_sec + seq_send_times[NUM_SEQ_SAMPLES - 1].tv_usec / 1000000.0, seq_send_times[0].tv_sec + (float) seq_send_times[0].tv_usec / 1000000.0, msec_ideal, (float) msec_taken / msec_ideal);
1269 }
1270 return (double) msec_taken / msec_ideal;
1271 }
1272
1273
1274 /******************************************************************************
1275 * Implementation of class HostOsScan *
1276 ******************************************************************************/
1277
1278 /* If there are pending probe timeouts, fills in when with the time of
1279 * the earliest one and returns true. Otherwise returns false and
1280 * puts now in when. */
nextTimeout(HostOsScanStats * hss,struct timeval * when)1281 bool HostOsScan::nextTimeout(HostOsScanStats *hss, struct timeval *when) {
1282 assert(hss);
1283 struct timeval probe_to, earliest_to;
1284 std::list<OFProbe *>::iterator probeI;
1285 bool firstgood = true;
1286
1287 assert(when);
1288 memset(&probe_to, 0, sizeof(probe_to));
1289 memset(&earliest_to, 0, sizeof(earliest_to));
1290
1291 for (probeI = hss->probesActive.begin(); probeI != hss->probesActive.end(); probeI++) {
1292 TIMEVAL_ADD(probe_to, (*probeI)->sent, timeProbeTimeout(hss));
1293 if (firstgood || TIMEVAL_SUBTRACT(probe_to, earliest_to) < 0) {
1294 earliest_to = probe_to;
1295 firstgood = false;
1296 }
1297 }
1298
1299 *when = (firstgood)? now : earliest_to;
1300 return !firstgood;
1301 }
1302
1303
adjust_times(HostOsScanStats * hss,OFProbe * probe,struct timeval * rcvdtime)1304 void HostOsScan::adjust_times(HostOsScanStats *hss, OFProbe *probe, struct timeval *rcvdtime) {
1305 assert(hss);
1306 assert(probe);
1307
1308 /* Adjust timing */
1309 if (rcvdtime) {
1310 adjust_timeouts2(&(probe->sent), rcvdtime, &(hss->target->to));
1311 adjust_timeouts2(&(probe->sent), rcvdtime, &(stats->to));
1312 }
1313
1314 stats->timing.num_replies_expected++;
1315 stats->timing.num_updates++;
1316
1317 hss->timing.num_replies_expected++;
1318 hss->timing.num_updates++;
1319
1320 /* Notice a drop if
1321 1. We get a response to a retransmitted probe (meaning the first reply was
1322 dropped), or
1323 2. We get no response after a timeout (rcvdtime == NULL). */
1324 if (probe->tryno > 0 || rcvdtime == NULL) {
1325 if (o.debugging > 1) {
1326 if (probe->tryno > 0) {
1327 log_write(LOG_PLAIN, "OS scan DROPPED probe to %s detected (tryno %d)\n",
1328 hss->target->targetipstr(), probe->tryno);
1329 } else {
1330 log_write(LOG_PLAIN, "OS scan DROPPED probe to %s detected (rcvdtime == NULL)\n",
1331 hss->target->targetipstr());
1332 }
1333 }
1334 if (TIMEVAL_AFTER(probe->sent, hss->timing.last_drop))
1335 hss->timing.drop(hss->numProbesActive(), &perf, &now);
1336 if (TIMEVAL_AFTER(probe->sent, stats->timing.last_drop))
1337 stats->timing.drop_group(stats->num_probes_active, &perf, &now);
1338 }
1339
1340 /* Increase the window for a positive reply. This can overlap with case (1)
1341 above. */
1342 if (rcvdtime != NULL) {
1343 stats->timing.ack(&perf);
1344 hss->timing.ack(&perf);
1345 }
1346 }
1347
1348
HostOsScan(Target * t)1349 HostOsScan::HostOsScan(Target *t) {
1350 pd = NULL;
1351 rawsd = -1;
1352 ethsd = NULL;
1353
1354 if ((o.sendpref & PACKET_SEND_ETH) && (t->ifType() == devt_ethernet
1355 #ifdef WIN32
1356 || (g_has_npcap_loopback && t->ifType() == devt_loopback)
1357 #endif
1358 )) {
1359 if ((ethsd = eth_open_cached(t->deviceName())) == NULL)
1360 fatal("%s: Failed to open ethernet device (%s)", __func__, t->deviceName());
1361 rawsd = -1;
1362 } else {
1363 #ifdef WIN32
1364 win32_fatal_raw_sockets(t->deviceName());
1365 #endif
1366 rawsd = nmap_raw_socket();
1367 if (rawsd < 0)
1368 pfatal("socket troubles in %s", __func__);
1369 unblock_socket(rawsd);
1370 ethsd = NULL;
1371 }
1372
1373 tcpPortBase = o.magic_port_set? o.magic_port : o.magic_port + get_random_u8();
1374 udpPortBase = o.magic_port_set? o.magic_port : o.magic_port + get_random_u8();
1375 reInitScanSystem();
1376
1377 stats = new ScanStats();
1378 }
1379
1380
~HostOsScan()1381 HostOsScan::~HostOsScan() {
1382 if (rawsd >= 0) {
1383 close(rawsd);
1384 rawsd = -1;
1385 }
1386 if (pd) {
1387 pcap_close(pd);
1388 pd = NULL;
1389 }
1390 /* No need to close ethsd due to caching. */
1391 delete stats;
1392 }
1393
1394
reInitScanSystem()1395 void HostOsScan::reInitScanSystem() {
1396 tcpSeqBase = get_random_u32();
1397 tcpAck = get_random_u32();
1398 tcpMss = 265;
1399 icmpEchoId = get_random_u16();
1400 icmpEchoSeq = 295;
1401 udpttl = (time(NULL) % 14) + 51;
1402 }
1403
1404
1405 /* Initiate seq probe list */
buildSeqProbeList(HostOsScanStats * hss)1406 void HostOsScan::buildSeqProbeList(HostOsScanStats *hss) {
1407 assert(hss);
1408 int i;
1409 if (hss->openTCPPort == -1)
1410 return;
1411 if (hss->FP_TSeq)
1412 return;
1413
1414 for (i = 0; i < NUM_SEQ_SAMPLES; i++)
1415 hss->addNewProbe(OFP_TSEQ, i);
1416 }
1417
1418
1419 /* Update the seq probes in the active probe list and remove the ones that have
1420 * timed out. */
updateActiveSeqProbes(HostOsScanStats * hss)1421 void HostOsScan::updateActiveSeqProbes(HostOsScanStats *hss) {
1422 assert(hss);
1423 std::list<OFProbe *>::iterator probeI, nxt;
1424 OFProbe *probe = NULL;
1425
1426 for (probeI = hss->probesActive.begin(); probeI != hss->probesActive.end(); probeI = nxt) {
1427 nxt = probeI;
1428 nxt++;
1429 probe = *probeI;
1430
1431 /* Is the probe timedout? */
1432 if (TIMEVAL_SUBTRACT(now, probe->sent) > (long) timeProbeTimeout(hss)) {
1433 hss->removeActiveProbe(probeI);
1434 assert(stats->num_probes_active > 0);
1435 stats->num_probes_active--;
1436 }
1437 }
1438 }
1439
1440
1441 /* Initialize the normal TCP/UDP/ICMP probe list */
buildTUIProbeList(HostOsScanStats * hss)1442 void HostOsScan::buildTUIProbeList(HostOsScanStats *hss) {
1443 assert(hss);
1444 int i;
1445
1446 /* The order of these probes are important for ipid generation
1447 * algorithm test and should not be changed.
1448 *
1449 * At doSeqTests we sent 6 TSeq probes to generate 6 tcp replies,
1450 * and here we follow with 3 probes to generate 3 icmp replies. In
1451 * this way we can expect to get "good" IPid sequence.
1452 *
1453 * **** Should be done in a more elegant way. *****
1454 */
1455
1456 /* ticmp */
1457 if (!hss->FP_TIcmp) {
1458 for (i = 0; i < 2; i++) {
1459 hss->addNewProbe(OFP_TICMP, i);
1460 }
1461 }
1462
1463 /* tudp */
1464 if (!hss->FP_TUdp) {
1465 hss->addNewProbe(OFP_TUDP, 0);
1466 }
1467
1468 if (hss->openTCPPort != -1) {
1469 /* tops/twin probes. We send the probe again if we didn't get a
1470 response by the corresponding seq probe. */
1471 if (!hss->FP_TOps || !hss->FP_TWin) {
1472 for (i = 0; i < 6; i++) {
1473 if (!hss->TOps_AVs[i] || !hss->TWin_AVs[i])
1474 hss->addNewProbe(OFP_TOPS, i);
1475 }
1476 }
1477
1478 /* tecn */
1479 if (!hss->FP_TEcn) {
1480 hss->addNewProbe(OFP_TECN, 0);
1481 }
1482
1483 /* t1_7: t1_t4 */
1484 for (i = 0; i < 4; i++) {
1485 if (!hss->FPtests[FP_T1_7_OFF + i]) {
1486 hss->addNewProbe(OFP_T1_7, i);
1487 }
1488 }
1489 }
1490
1491 /* t1_7: t5_t7 */
1492 for (i = 4; i < 7; i++) {
1493 if (!hss->FPtests[FP_T1_7_OFF + i]) {
1494 hss->addNewProbe(OFP_T1_7, i);
1495 }
1496 }
1497 }
1498
1499
1500 /* Update the probes in the active probe list:
1501 * 1) Remove the expired probes (timedout and reached the retry limit);
1502 * 2) Move timedout probes to probeNeedToSend; */
updateActiveTUIProbes(HostOsScanStats * hss)1503 void HostOsScan::updateActiveTUIProbes(HostOsScanStats *hss) {
1504 assert(hss);
1505 std::list<OFProbe *>::iterator probeI, nxt;
1506 OFProbe *probe = NULL;
1507
1508 for (probeI = hss->probesActive.begin(); probeI != hss->probesActive.end(); probeI = nxt) {
1509 nxt = probeI;
1510 nxt++;
1511 probe = *probeI;
1512
1513 if (TIMEVAL_SUBTRACT(now, probe->sent) > (long) timeProbeTimeout(hss)) {
1514 if (probe->tryno >= 3) {
1515 /* The probe is expired. */
1516 hss->removeActiveProbe(probeI);
1517 assert(stats->num_probes_active > 0);
1518 stats->num_probes_active--;
1519 }
1520 else {
1521 /* It is timedout, move it to the sendlist */
1522 hss->moveProbeToUnSendList(probeI);
1523 assert(stats->num_probes_active > 0);
1524 stats->num_probes_active--;
1525 }
1526 }
1527 }
1528 }
1529
1530
1531 /* Check whether the host is sendok. If not, fill _when_ with the time
1532 * when it will be sendOK and return false; else, fill it with now and
1533 * return true. */
hostSendOK(HostOsScanStats * hss,struct timeval * when)1534 bool HostOsScan::hostSendOK(HostOsScanStats *hss, struct timeval *when) {
1535 assert(hss);
1536 std::list<OFProbe *>::iterator probeI;
1537 int packTime;
1538 struct timeval probe_to, earliest_to, sendTime;
1539 long tdiff;
1540
1541 if (hss->target->timedOut(&now)) {
1542 if (when)
1543 *when = now;
1544 return false;
1545 }
1546
1547 if (hss->sendDelayMs > 0) {
1548 packTime = TIMEVAL_MSEC_SUBTRACT(now, hss->lastProbeSent);
1549 if (packTime < (int) hss->sendDelayMs) {
1550 if (when) {
1551 TIMEVAL_MSEC_ADD(*when, hss->lastProbeSent, hss->sendDelayMs);
1552 }
1553 return false;
1554 }
1555 }
1556
1557 if (hss->timing.cwnd >= hss->numProbesActive() + .5) {
1558 if (when)
1559 *when = now;
1560 return true;
1561 }
1562
1563 if (!when)
1564 return false;
1565
1566 TIMEVAL_MSEC_ADD(earliest_to, now, 10000);
1567
1568 /* Any timeouts coming up? */
1569 for (probeI = hss->probesActive.begin(); probeI != hss->probesActive.end(); probeI++) {
1570 TIMEVAL_MSEC_ADD(probe_to, (*probeI)->sent, timeProbeTimeout(hss) / 1000);
1571 if (TIMEVAL_SUBTRACT(probe_to, earliest_to) < 0) {
1572 earliest_to = probe_to;
1573 }
1574 }
1575
1576 // Will any scan delay affect this?
1577 if (hss->sendDelayMs > 0) {
1578 TIMEVAL_MSEC_ADD(sendTime, hss->lastProbeSent, hss->sendDelayMs);
1579 if (TIMEVAL_MSEC_SUBTRACT(sendTime, now) < 0)
1580 sendTime = now;
1581 tdiff = TIMEVAL_MSEC_SUBTRACT(earliest_to, sendTime);
1582
1583 /* Timeouts previous to the sendTime requirement are pointless,
1584 and those later than sendTime are not needed if we can send a
1585 new packet at sendTime */
1586 if (tdiff < 0) {
1587 earliest_to = sendTime;
1588 } else {
1589 if (tdiff > 0 && hss->timing.cwnd > hss->numProbesActive() + .5) {
1590 earliest_to = sendTime;
1591 }
1592 }
1593 }
1594
1595 *when = earliest_to;
1596 return false;
1597 }
1598
1599
1600 /* Check whether it is OK to send the next seq probe to the host. If
1601 * not, fill param "when" with the time when it will be sendOK and return
1602 * false; else, fill it with now and return true. */
hostSeqSendOK(HostOsScanStats * hss,struct timeval * when)1603 bool HostOsScan::hostSeqSendOK(HostOsScanStats *hss, struct timeval *when) {
1604 assert(hss);
1605 std::list<OFProbe *>::iterator probeI;
1606 int packTime = 0, maxWait = 0;
1607 struct timeval probe_to, earliest_to, sendTime;
1608 long tdiff;
1609
1610 if (hss->target->timedOut(&now)) {
1611 if (when)
1612 *when = now;
1613 return false;
1614 }
1615
1616 packTime = TIMEVAL_SUBTRACT(now, hss->lastProbeSent);
1617
1618 /*
1619 * If the user insist a larger sendDelayMs, use it. But
1620 * the seq result may be inaccurate.
1621 */
1622 maxWait = MAX(OS_SEQ_PROBE_DELAY * 1000, hss->sendDelayMs * 1000);
1623 if (packTime < maxWait) {
1624 if (when) {
1625 TIMEVAL_ADD(*when, hss->lastProbeSent, maxWait);
1626 }
1627 return false;
1628 }
1629
1630 if (hss->timing.cwnd >= hss->numProbesActive() + .5) {
1631 if (when)
1632 *when = now;
1633 return true;
1634 }
1635
1636 if (!when)
1637 return false;
1638
1639 TIMEVAL_MSEC_ADD(earliest_to, now, 10000);
1640
1641 /* Any timeouts coming up? */
1642 for (probeI = hss->probesActive.begin(); probeI != hss->probesActive.end(); probeI++) {
1643 TIMEVAL_MSEC_ADD(probe_to, (*probeI)->sent, timeProbeTimeout(hss) / 1000);
1644 if (TIMEVAL_SUBTRACT(probe_to, earliest_to) < 0) {
1645 earliest_to = probe_to;
1646 }
1647 }
1648
1649 TIMEVAL_ADD(sendTime, hss->lastProbeSent, maxWait);
1650 if (TIMEVAL_SUBTRACT(sendTime, now) < 0)
1651 sendTime = now;
1652 tdiff = TIMEVAL_SUBTRACT(earliest_to, sendTime);
1653
1654 /* Timeouts previous to the sendTime requirement are pointless,
1655 and those later than sendTime are not needed if we can send a
1656 new packet at sendTime */
1657 if (tdiff < 0) {
1658 earliest_to = sendTime;
1659 } else {
1660 if (tdiff > 0 && hss->timing.cwnd > hss->numProbesActive() + .5) {
1661 earliest_to = sendTime;
1662 }
1663 }
1664
1665 *when = earliest_to;
1666 return false;
1667 }
1668
1669
timeProbeTimeout(HostOsScanStats * hss)1670 unsigned long HostOsScan::timeProbeTimeout(HostOsScanStats *hss) {
1671 assert(hss);
1672 if (hss->target->to.srtt > 0) {
1673 /* We have at least one timing value to use. Good enough, I suppose */
1674 return hss->target->to.timeout;
1675 } else if (stats->to.srtt > 0) {
1676 /* OK, we'll use this one instead */
1677 return stats->to.timeout;
1678 } else {
1679 return hss->target->to.timeout; /* It comes with a default */
1680 }
1681 }
1682
1683
sendNextProbe(HostOsScanStats * hss)1684 void HostOsScan::sendNextProbe(HostOsScanStats *hss) {
1685 assert(hss);
1686 std::list<OFProbe *>::iterator probeI;
1687 OFProbe *probe = NULL;
1688
1689 if (hss->probesToSend.empty())
1690 return;
1691
1692 if (!hss->target->timeOutClockRunning() && !hss->target->timedOut(NULL)) {
1693 hss->target->startTimeOutClock(&now);
1694 }
1695
1696 probeI = hss->probesToSend.begin();
1697 probe = *probeI;
1698
1699 switch (probe->type) {
1700 case OFP_TSEQ:
1701 sendTSeqProbe(hss, probe->subid);
1702 break;
1703 case OFP_TOPS:
1704 sendTOpsProbe(hss, probe->subid);
1705 break;
1706 case OFP_TECN:
1707 sendTEcnProbe(hss);
1708 break;
1709 case OFP_T1_7:
1710 sendT1_7Probe(hss, probe->subid);
1711 break;
1712 case OFP_TICMP:
1713 sendTIcmpProbe(hss, probe->subid);
1714 break;
1715 case OFP_TUDP:
1716 sendTUdpProbe(hss, probe->subid);
1717 break;
1718 default:
1719 assert(false);
1720 }
1721
1722 probe->tryno++;
1723 if (probe->tryno > 0) {
1724 /* This is a retransmission */
1725 probe->retransmitted = true;
1726 probe->prevSent = probe->sent;
1727 }
1728 probe->sent = now;
1729
1730 hss->lastProbeSent = now;
1731 hss->num_probes_sent++;
1732 stats->num_probes_sent++;
1733
1734 hss->moveProbeToActiveList(probeI);
1735 stats->num_probes_active++;
1736
1737 if (o.debugging > 1) {
1738 log_write(LOG_PLAIN, "Send probe (type: %s, subid: %d) to %s\n",
1739 probe->typestr(), probe->subid, hss->target->targetipstr());
1740 }
1741
1742 }
1743
1744
sendTSeqProbe(HostOsScanStats * hss,int probeNo)1745 void HostOsScan::sendTSeqProbe(HostOsScanStats *hss, int probeNo) {
1746 assert(hss);
1747 assert(probeNo >= 0 && probeNo < NUM_SEQ_SAMPLES);
1748
1749 if (hss->openTCPPort == -1)
1750 return;
1751
1752 send_tcp_probe(hss, o.ttl, false, NULL, 0,
1753 tcpPortBase + probeNo, hss->openTCPPort,
1754 tcpSeqBase + probeNo, tcpAck,
1755 0, TH_SYN, prbWindowSz[probeNo], 0,
1756 prbOpts[probeNo].val, prbOpts[probeNo].len, NULL, 0);
1757
1758 hss->seq_send_times[probeNo] = now;
1759 }
1760
1761
sendTOpsProbe(HostOsScanStats * hss,int probeNo)1762 void HostOsScan::sendTOpsProbe(HostOsScanStats *hss, int probeNo) {
1763 assert(hss);
1764 assert(probeNo >= 0 && probeNo < NUM_SEQ_SAMPLES);
1765
1766 if (hss->openTCPPort == -1)
1767 return;
1768
1769 send_tcp_probe(hss, o.ttl, false, NULL, 0,
1770 tcpPortBase + NUM_SEQ_SAMPLES + probeNo, hss->openTCPPort,
1771 tcpSeqBase, tcpAck,
1772 0, TH_SYN, prbWindowSz[probeNo], 0,
1773 prbOpts[probeNo].val, prbOpts[probeNo].len, NULL, 0);
1774 }
1775
1776
sendTEcnProbe(HostOsScanStats * hss)1777 void HostOsScan::sendTEcnProbe(HostOsScanStats *hss) {
1778 assert(hss);
1779
1780 if (hss->openTCPPort == -1)
1781 return;
1782
1783 send_tcp_probe(hss, o.ttl, false, NULL, 0,
1784 tcpPortBase + NUM_SEQ_SAMPLES + 6, hss->openTCPPort,
1785 tcpSeqBase, 0,
1786 8, TH_CWR|TH_ECE|TH_SYN, prbWindowSz[6], 63477,
1787 prbOpts[6].val, prbOpts[6].len, NULL, 0);
1788 }
1789
1790
sendT1_7Probe(HostOsScanStats * hss,int probeNo)1791 void HostOsScan::sendT1_7Probe(HostOsScanStats *hss, int probeNo) {
1792 assert(hss);
1793 assert(probeNo >=0 && probeNo < 7);
1794
1795 int port_base = tcpPortBase + NUM_SEQ_SAMPLES + 7;
1796
1797 switch (probeNo) {
1798 case 0: /* T1 */
1799 /* T1 is normally filled in by sendTSeqProbe so this case doesn't happen. In
1800 case all six Seq probes failed, this one will be re-sent. It is the same
1801 as the first probe sent by sendTSeqProbe. */
1802 if (hss->openTCPPort == -1)
1803 return;
1804 send_tcp_probe(hss, o.ttl, false, NULL, 0,
1805 port_base, hss->openTCPPort,
1806 tcpSeqBase, tcpAck,
1807 0, TH_SYN, prbWindowSz[0], 0,
1808 prbOpts[0].val, prbOpts[0].len, NULL, 0);
1809 break;
1810 case 1: /* T2 */
1811 if (hss->openTCPPort == -1)
1812 return;
1813 send_tcp_probe(hss, o.ttl, true, NULL, 0,
1814 port_base + 1, hss->openTCPPort,
1815 tcpSeqBase, tcpAck,
1816 0, 0, prbWindowSz[7], 0,
1817 prbOpts[7].val, prbOpts[7].len, NULL, 0);
1818 break;
1819 case 2: /* T3 */
1820 if (hss->openTCPPort == -1)
1821 return;
1822 send_tcp_probe(hss, o.ttl, false, NULL, 0,
1823 port_base + 2, hss->openTCPPort,
1824 tcpSeqBase, tcpAck,
1825 0, TH_SYN|TH_FIN|TH_URG|TH_PUSH, prbWindowSz[8], 0,
1826 prbOpts[8].val, prbOpts[8].len, NULL, 0);
1827 break;
1828 case 3: /* T4 */
1829 if (hss->openTCPPort == -1)
1830 return;
1831 send_tcp_probe(hss, o.ttl, true, NULL, 0,
1832 port_base + 3, hss->openTCPPort,
1833 tcpSeqBase, tcpAck,
1834 0, TH_ACK, prbWindowSz[9], 0,
1835 prbOpts[9].val, prbOpts[9].len, NULL, 0);
1836 break;
1837 case 4: /* T5 */
1838 if (hss->closedTCPPort == -1)
1839 return;
1840 send_tcp_probe(hss, o.ttl, false, NULL, 0,
1841 port_base + 4, hss->closedTCPPort,
1842 tcpSeqBase, tcpAck,
1843 0, TH_SYN, prbWindowSz[10], 0,
1844 prbOpts[10].val, prbOpts[10].len, NULL, 0);
1845 break;
1846 case 5: /* T6 */
1847 if (hss->closedTCPPort == -1)
1848 return;
1849 send_tcp_probe(hss, o.ttl, true, NULL, 0,
1850 port_base + 5, hss->closedTCPPort,
1851 tcpSeqBase, tcpAck,
1852 0, TH_ACK, prbWindowSz[11], 0,
1853 prbOpts[11].val, prbOpts[11].len, NULL, 0);
1854 break;
1855 case 6: /* T7 */
1856 if (hss->closedTCPPort == -1)
1857 return;
1858 send_tcp_probe(hss, o.ttl, false, NULL, 0,
1859 port_base + 6, hss->closedTCPPort,
1860 tcpSeqBase, tcpAck,
1861 0, TH_FIN|TH_PUSH|TH_URG, prbWindowSz[12], 0,
1862 prbOpts[12].val, prbOpts[12].len, NULL, 0);
1863 }
1864 }
1865
1866
sendTIcmpProbe(HostOsScanStats * hss,int probeNo)1867 void HostOsScan::sendTIcmpProbe(HostOsScanStats *hss, int probeNo) {
1868 assert(hss);
1869 assert(probeNo >= 0 && probeNo < 2);
1870 if (probeNo == 0) {
1871 send_icmp_echo_probe(hss, IP_TOS_DEFAULT,
1872 true, 9, icmpEchoId, icmpEchoSeq, 120);
1873 }
1874 else {
1875 send_icmp_echo_probe(hss, IP_TOS_RELIABILITY,
1876 false, 0, icmpEchoId + 1, icmpEchoSeq + 1, 150);
1877 }
1878 }
1879
1880
sendTUdpProbe(HostOsScanStats * hss,int probeNo)1881 void HostOsScan::sendTUdpProbe(HostOsScanStats *hss, int probeNo) {
1882 assert(hss);
1883 if (hss->closedUDPPort == -1)
1884 return;
1885 send_closedudp_probe(hss, udpttl, udpPortBase + probeNo, hss->closedUDPPort);
1886 }
1887
1888
processResp(HostOsScanStats * hss,struct ip * ip,unsigned int len,struct timeval * rcvdtime)1889 bool HostOsScan::processResp(HostOsScanStats *hss, struct ip *ip, unsigned int len, struct timeval *rcvdtime) {
1890 struct ip *ip2;
1891 struct tcp_hdr *tcp;
1892 struct icmp *icmp;
1893 int testno;
1894 bool isPktUseful = false;
1895 std::list<OFProbe *>::iterator probeI;
1896 OFProbe *probe;
1897
1898 if (len < 20 || len < (4 * ip->ip_hl) + 4U)
1899 return false;
1900
1901 len -= 4 * ip->ip_hl;
1902
1903 if (ip->ip_p == IPPROTO_TCP) {
1904 if (len < 20)
1905 return false;
1906 tcp = ((struct tcp_hdr *) (((char *) ip) + 4 * ip->ip_hl));
1907 if (len < (unsigned int)(4 * tcp->th_off))
1908 return false;
1909 testno = ntohs(tcp->th_dport) - tcpPortBase;
1910
1911 if (testno >= 0 && testno < NUM_SEQ_SAMPLES) {
1912 /* TSeq */
1913 isPktUseful = processTSeqResp(hss, ip, testno);
1914
1915 if (isPktUseful) {
1916 hss->ipid.tcp_ipids[testno] = ntohs(ip->ip_id);
1917 probeI = hss->getActiveProbe(OFP_TSEQ, testno);
1918 /* printf("tcp ipid = %d\n", ntohs(ip->ip_id)); */
1919 }
1920
1921 /* Use the seq response to do other tests. We don't care if it
1922 * is useful for these tests.
1923 */
1924 if (testno == 0) {
1925 /* the first reply is used to do T1 */
1926 processT1_7Resp(hss, ip, 0);
1927 }
1928 /* the 1st NUM_SEQ_SAMPLES replies are used to do TOps and TWin */
1929 processTOpsResp(hss, tcp, testno);
1930 processTWinResp(hss, tcp, testno);
1931
1932 } else if (testno >= NUM_SEQ_SAMPLES && testno < NUM_SEQ_SAMPLES + 6) {
1933
1934 /* TOps/Twin */
1935 isPktUseful = processTOpsResp(hss, tcp, testno - NUM_SEQ_SAMPLES);
1936 isPktUseful |= processTWinResp(hss, tcp, testno - NUM_SEQ_SAMPLES);
1937 if (isPktUseful) {
1938 probeI = hss->getActiveProbe(OFP_TOPS, testno - NUM_SEQ_SAMPLES);
1939 }
1940
1941 } else if (testno == NUM_SEQ_SAMPLES + 6) {
1942
1943 /* TEcn */
1944 isPktUseful = processTEcnResp(hss, ip);
1945 if (isPktUseful) {
1946 probeI = hss->getActiveProbe(OFP_TECN, 0);
1947 }
1948
1949 } else if (testno >= NUM_SEQ_SAMPLES + 7 && testno < NUM_SEQ_SAMPLES + 14) {
1950
1951 isPktUseful = processT1_7Resp(hss, ip, testno - NUM_SEQ_SAMPLES - 7);
1952
1953 if (isPktUseful) {
1954 probeI = hss->getActiveProbe(OFP_T1_7, testno - NUM_SEQ_SAMPLES - 7);
1955
1956 /* Closed-port TCP IP ID sequence numbers (SEQ.CI). Uses T5, T6, and T7.
1957 T5 starts at NUM_SEQ_SAMPLES + 11. */
1958 if (testno >= NUM_SEQ_SAMPLES + 11)
1959 hss->ipid.tcp_closed_ipids[testno - (NUM_SEQ_SAMPLES + 11)] = ntohs(ip->ip_id);
1960 }
1961 }
1962 }
1963 else if (ip->ip_p == IPPROTO_ICMP) {
1964 if (len < 8)
1965 return false;
1966 icmp = ((struct icmp *)(((char *) ip) + 4 * ip->ip_hl));
1967
1968 /* Is it an icmp echo reply? */
1969 if (icmp->icmp_type == ICMP_ECHOREPLY) {
1970 testno = ntohs(icmp->icmp_id) - icmpEchoId;
1971 if (testno == 0 || testno == 1) {
1972 isPktUseful = processTIcmpResp(hss, ip, testno);
1973 if (isPktUseful) {
1974 probeI = hss->getActiveProbe(OFP_TICMP, testno);
1975 }
1976
1977 if (isPktUseful && probeI != hss->probesActive.end() && !(*probeI)->retransmitted) { /* Retransmitted ipid is useless. */
1978 hss->ipid.icmp_ipids[testno] = ntohs(ip->ip_id);
1979 /* printf("icmp ipid = %d\n", ntohs(ip->ip_id)); */
1980 }
1981 }
1982 }
1983
1984 /* Is it a destination port unreachable? */
1985 if (icmp->icmp_type == 3 && icmp->icmp_code == 3) {
1986 len -= 8; /* icmp destination unreachable header len. */
1987 if (len < 28)
1988 return false; /* must larger than an ip and an udp header length */
1989 ip2 = (struct ip*)((char *)icmp + 8);
1990 len -= 4 * ip2->ip_hl;
1991 if (len < 8)
1992 return false;
1993
1994 isPktUseful = processTUdpResp(hss, ip);
1995 if (isPktUseful) {
1996 probeI = hss->getActiveProbe(OFP_TUDP, 0);
1997 }
1998 }
1999
2000 }
2001
2002 if (isPktUseful && probeI != hss->probesActive.end()) {
2003 probe = *probeI;
2004
2005 if (rcvdtime)
2006 adjust_times(hss, probe, rcvdtime);
2007
2008 if (o.debugging > 1) {
2009 log_write(LOG_PLAIN, "Got a valid response for probe (type: %s subid: %d) from %s\n",
2010 probe->typestr(), probe->subid, hss->target->targetipstr());
2011 }
2012
2013 /* delete the probe. */
2014 hss->removeActiveProbe(probeI);
2015 assert(stats->num_probes_active > 0);
2016 stats->num_probes_active--;
2017
2018 return true;
2019 }
2020
2021 return false;
2022 }
2023
2024
makeFP(HostOsScanStats * hss)2025 void HostOsScan::makeFP(HostOsScanStats *hss) {
2026 assert(hss);
2027
2028 int i;
2029 struct AVal AV;
2030 std::vector<struct AVal>::iterator it;
2031
2032 int ttl;
2033
2034 if (!hss->FP_TSeq)
2035 makeTSeqFP(hss);
2036
2037 if (!hss->FP_TOps)
2038 makeTOpsFP(hss);
2039
2040 if (!hss->FP_TWin)
2041 makeTWinFP(hss);
2042
2043 for (i = 3; i < NUM_FPTESTS; i++) {
2044 if (!hss->FPtests[i] &&
2045 ((i >= 3 && i <= 7 && hss->openTCPPort != -1) ||
2046 (i >= 8 && i <= 10 && hss->target->FPR->osscan_closedtcpport != -1) ||
2047 i >= 11)) {
2048 /* We create a Resp (response) attribute with value of N (no) because
2049 it is important here to note whether responses were or were not
2050 received */
2051 hss->FPtests[i] = new FingerTest;
2052 AV.attribute = "R";
2053 AV.value = "N";
2054 hss->FPtests[i]->results.push_back(AV);
2055 hss->FPtests[i]->name = (i == 3)? "ECN" : (i == 4)? "T1" : (i == 5)? "T2" : (i == 6)? "T3" : (i == 7)? "T4" : (i == 8)? "T5" : (i == 9)? "T6" : (i == 10)? "T7" : (i == 11)? "U1" : "IE";
2056 }
2057 else if (hss->FPtests[i]) {
2058 /* Replace TTL with initial TTL. */
2059 for (it = hss->FPtests[i]->results.begin(); it != hss->FPtests[i]->results.end(); it++) {
2060 if (strcmp(it->attribute, "T") == 0) {
2061 /* Found TTL item. The value for this attribute is the
2062 * received TTL encoded in decimal. We replace it with the
2063 * initial TTL encoded in hex. */
2064 ttl = atoi(it->value);
2065
2066 if (hss->distance_guess == -1)
2067 hss->distance_guess = get_initial_ttl_guess(ttl) - ttl;
2068
2069 if (hss->distance != -1) {
2070 /* We've gotten response for the UDP probe and thus have
2071 the "true" hop count. Add the number of hops between
2072 us and the target (hss->distance - 1) to the received
2073 TTL to get the initial TTL. */
2074 it->value = string_pool_sprintf("%hX", ttl + hss->distance - 1);
2075 } else {
2076 /* Guess the initial TTL value */
2077 it->attribute = "TG";
2078 it->value = string_pool_sprintf("%hX", get_initial_ttl_guess(ttl));
2079 }
2080 break;
2081 }
2082 }
2083 }
2084 }
2085
2086 /* Link them up. */
2087 hss->FP = new FingerPrint;
2088 for (i = 0; i < NUM_FPTESTS; i++) {
2089 if (hss->FPtests[i] == NULL)
2090 continue;
2091 hss->FP->tests.push_back(*hss->FPtests[i]);
2092 }
2093 }
2094
2095
2096 /* Send a TCP probe. This takes care of decoys and filling in Ethernet
2097 * addresses if necessary. Used for the SEQ, OPS, WIN, ECN, and T1-T7 probes. */
send_tcp_probe(HostOsScanStats * hss,int ttl,bool df,u8 * ipopt,int ipoptlen,u16 sport,u16 dport,u32 seq,u32 ack,u8 reserved,u8 flags,u16 window,u16 urp,u8 * options,int optlen,char * data,u16 datalen)2098 int HostOsScan::send_tcp_probe(HostOsScanStats *hss,
2099 int ttl, bool df, u8* ipopt, int ipoptlen,
2100 u16 sport, u16 dport, u32 seq, u32 ack,
2101 u8 reserved, u8 flags, u16 window, u16 urp,
2102 u8 *options, int optlen,
2103 char *data, u16 datalen) {
2104 struct eth_nfo eth, *ethptr;
2105
2106 ethptr = hss->fill_eth_nfo(ð, ethsd);
2107
2108 return send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(),
2109 ttl, df, ipopt, ipoptlen, sport, dport, seq, ack,
2110 reserved, flags, window, urp,
2111 options, optlen, data, datalen);
2112 }
2113
2114
2115 /* Send an echo probe. This takes care of decoys and filling in Ethernet
2116 * addresses if necessary. Used for the IE probes. */
send_icmp_echo_probe(HostOsScanStats * hss,u8 tos,bool df,u8 pcode,unsigned short id,u16 seq,u16 datalen)2117 int HostOsScan::send_icmp_echo_probe(HostOsScanStats *hss,
2118 u8 tos, bool df, u8 pcode,
2119 unsigned short id, u16 seq, u16 datalen) {
2120 u8 *packet = NULL;
2121 u32 packetlen = 0;
2122 int decoy;
2123 int res = -1;
2124 struct eth_nfo eth, *ethptr;
2125
2126 ethptr = hss->fill_eth_nfo(ð, ethsd);
2127
2128 for (decoy = 0; decoy < o.numdecoys; decoy++) {
2129 packet = build_icmp_raw(&((struct sockaddr_in *)&o.decoys[decoy])->sin_addr, hss->target->v4hostip(),
2130 o.ttl, get_random_u16(), tos, df, NULL, 0, seq, id,
2131 ICMP_ECHO, pcode, NULL, datalen, &packetlen);
2132 if (!packet)
2133 return -1;
2134 res = send_ip_packet(rawsd, ethptr, hss->target->TargetSockAddr(), packet, packetlen);
2135 free(packet);
2136 if (res == -1)
2137 return -1;
2138 }
2139
2140 return 0;
2141 }
2142
2143
2144 /* Send a UDP probe. This takes care of decoys and filling in Ethernet
2145 * addresses if necessary. Used for the U1 probe. */
send_closedudp_probe(HostOsScanStats * hss,int ttl,u16 sport,u16 dport)2146 int HostOsScan::send_closedudp_probe(HostOsScanStats *hss,
2147 int ttl, u16 sport, u16 dport) {
2148 static int myttl = 0;
2149 static u8 patternbyte = 0x43; /* character 'C' */
2150 static u16 id = 0x1042;
2151 u8 packet[328]; /* 20 IP hdr + 8 UDP hdr + 300 data */
2152 struct ip *ip = (struct ip *) packet;
2153 struct udp_hdr *udp = (struct udp_hdr *) (packet + sizeof(struct ip));
2154 struct in_addr *source;
2155 int datalen = 300;
2156 unsigned char *data = packet + 28;
2157 unsigned short realcheck; /* the REAL checksum */
2158 int res;
2159 int decoy;
2160 struct eth_nfo eth, *ethptr;
2161
2162 ethptr = hss->fill_eth_nfo(ð, ethsd);
2163
2164 /* if (!patternbyte) patternbyte = (get_random_uint() % 60) + 65; */
2165 memset(data, patternbyte, datalen);
2166
2167 /* while (!id) id = get_random_uint(); */
2168
2169 if (ttl == -1) {
2170 myttl = (time(NULL) % 14) + 51;
2171 } else {
2172 myttl = ttl;
2173 }
2174
2175 /* check that required fields are there and not too silly */
2176 if (!sport || !dport) {
2177 error("%s: One or more of your parameters suck!", __func__);
2178 return 1;
2179 }
2180
2181 for (decoy = 0; decoy < o.numdecoys; decoy++) {
2182 if (o.decoys[decoy].ss_family == AF_INET6)
2183 return 1;
2184 source = &((struct sockaddr_in *)&o.decoys[decoy])->sin_addr;
2185
2186 memset((char *) packet, 0, sizeof(struct ip) + sizeof(struct udp_hdr));
2187
2188 udp->uh_sport = htons(sport);
2189 udp->uh_dport = htons(dport);
2190 udp->uh_ulen = htons(8 + datalen);
2191
2192 /* OK, now we should be able to compute a valid checksum */
2193 realcheck = ipv4_pseudoheader_cksum(source, hss->target->v4hostip(), IPPROTO_UDP,
2194 sizeof(struct udp_hdr) + datalen, (char *) udp);
2195 #if STUPID_SOLARIS_CHECKSUM_BUG
2196 udp->uh_sum = sizeof(struct udp_hdr) + datalen;
2197 #else
2198 udp->uh_sum = realcheck;
2199 #endif
2200
2201 /* Now for the ip header */
2202 ip->ip_v = 4;
2203 ip->ip_hl = 5;
2204 ip->ip_len = htons(sizeof(struct ip) + sizeof(struct udp_hdr) + datalen);
2205 ip->ip_id = htons(id);
2206 ip->ip_ttl = myttl;
2207 ip->ip_p = IPPROTO_UDP;
2208 ip->ip_src.s_addr = source->s_addr;
2209 ip->ip_dst.s_addr= hss->target->v4hostip()->s_addr;
2210
2211 hss->upi.ipck = in_cksum((unsigned short *)ip, sizeof(struct ip));
2212 #if HAVE_IP_IP_SUM
2213 ip->ip_sum = hss->upi.ipck;
2214 #endif
2215
2216 /* OK, now if this is the real she-bang (ie not a decoy) then
2217 we stick all the inph0 in our upi */
2218 if (decoy == o.decoyturn) {
2219 hss->upi.iptl = 28 + datalen;
2220 hss->upi.ipid = id;
2221 hss->upi.sport = sport;
2222 hss->upi.dport = dport;
2223 hss->upi.udpck = realcheck;
2224 hss->upi.udplen = 8 + datalen;
2225 hss->upi.patternbyte = patternbyte;
2226 hss->upi.target.s_addr = ip->ip_dst.s_addr;
2227 }
2228
2229 if ((res = send_ip_packet(rawsd, ethptr, hss->target->TargetSockAddr(), packet, ntohs(ip->ip_len))) == -1)
2230 {
2231 gh_perror("send_ip_packet in %s", __func__);
2232 return 1;
2233 }
2234 }
2235
2236 return 0;
2237 }
2238
2239
2240 /******************************************************************************
2241 * Implementation of class ScanStats *
2242 ******************************************************************************/
2243
ScanStats()2244 ScanStats::ScanStats() {
2245 /* init timing val */
2246 timing.cwnd = perf.group_initial_cwnd;
2247 timing.ssthresh = perf.initial_ssthresh; /* Will be reduced if any packets are dropped anyway */
2248 timing.num_replies_expected = 0;
2249 timing.num_replies_received = 0;
2250 timing.num_updates = 0;
2251 gettimeofday(&timing.last_drop, NULL);
2252
2253 initialize_timeout_info(&to);
2254
2255 num_probes_active = 0;
2256 num_probes_sent = num_probes_sent_at_last_wait = 0;
2257 }
2258
2259
2260 /* Returns true if the os scan system says that sending is OK.*/
sendOK()2261 bool ScanStats::sendOK() {
2262 if (num_probes_sent - num_probes_sent_at_last_wait >= 50)
2263 return false;
2264
2265 if (timing.cwnd < num_probes_active + 0.5)
2266 return false;
2267
2268 return true;
2269 }
2270
2271
2272 /******************************************************************************
2273 * Implementation of class HostOsScan *
2274 ******************************************************************************/
2275
gcd_n_uint(int nvals,unsigned int * val)2276 static unsigned int gcd_n_uint(int nvals, unsigned int *val) {
2277 unsigned int a, b, c;
2278
2279 if (!nvals)
2280 return 1;
2281 a = *val;
2282 for (nvals--; nvals; nvals--) {
2283 b = *++val;
2284 if (a < b) {
2285 c = a;
2286 a = b;
2287 b = c;
2288 }
2289 while (b) {
2290 c = a % b;
2291 a = b;
2292 b = c;
2293 }
2294 }
2295 return a;
2296 }
2297
makeTSeqFP(HostOsScanStats * hss)2298 void HostOsScan::makeTSeqFP(HostOsScanStats *hss) {
2299 int i, j;
2300 u32 seq_diffs[NUM_SEQ_SAMPLES];
2301 u32 ts_diffs[NUM_SEQ_SAMPLES];
2302 float seq_rates[NUM_SEQ_SAMPLES];
2303 unsigned long time_usec_diffs[NUM_SEQ_SAMPLES];
2304 double seq_stddev = 0;
2305 double seq_rate = 0;
2306 double seq_avg_rate = 0;
2307 double avg_ts_hz = 0.0; /* Avg. amount that timestamps incr. each second */
2308 u32 seq_gcd = 1;
2309 int tcp_ipid_seqclass; /* TCP IPID SEQ TYPE defines in nmap.h */
2310 int tcp_closed_ipid_seqclass; /* TCP IPID SEQ TYPE defines in nmap.h */
2311 int icmp_ipid_seqclass; /* ICMP IPID SEQ TYPE defines in nmap.h */
2312 int good_tcp_ipid_num, good_tcp_closed_ipid_num, good_icmp_ipid_num;
2313 int tsnewval = 0;
2314
2315 std::vector<struct AVal> seq_AVs;
2316 struct AVal AV;
2317
2318 /* Need 8 AVals for SP, GCD, ISR, TI, CI, II, SS, TS. */
2319 seq_AVs.reserve(8);
2320
2321 /* Now we make sure there are no gaps in our response array ... */
2322 for (i = 0, j = 0; i < NUM_SEQ_SAMPLES; i++) {
2323 if (hss->si.seqs[i] != 0) /* We found a good one */ {
2324 if (j < i) {
2325 hss->si.seqs[j] = hss->si.seqs[i];
2326 hss->si.ipids[j] = hss->si.ipids[i];
2327 hss->si.timestamps[j] = hss->si.timestamps[i];
2328 hss->seq_send_times[j] = hss->seq_send_times[i];
2329 }
2330 if (j > 0) {
2331 seq_diffs[j - 1] = MOD_DIFF(hss->si.seqs[j], hss->si.seqs[j - 1]);
2332
2333 ts_diffs[j - 1] = MOD_DIFF(hss->si.timestamps[j], hss->si.timestamps[j - 1]);
2334 time_usec_diffs[j - 1] = TIMEVAL_SUBTRACT(hss->seq_send_times[j], hss->seq_send_times[j - 1]);
2335 if (!time_usec_diffs[j - 1]) time_usec_diffs[j - 1]++; /* We divide by this later */
2336 /* Rate of ISN increase per second */
2337 seq_rates[j - 1] = seq_diffs[j - 1] * 1000000.0 / time_usec_diffs[j - 1];
2338 seq_avg_rate += seq_rates[j - 1];
2339 }
2340 j++;
2341 } /* Otherwise nothing good in this slot to copy */
2342 }
2343
2344 hss->si.responses = j; /* Just for assurance */
2345
2346 /* Time to look at the TCP ISN predictability */
2347 if (hss->si.responses >= 4 && o.scan_delay <= 1000) {
2348 seq_avg_rate /= hss->si.responses - 1;
2349 seq_rate = seq_avg_rate;
2350
2351 /* First calculate the GCD */
2352 seq_gcd = gcd_n_uint(hss->si.responses -1, seq_diffs);
2353
2354 if (!seq_gcd) {
2355 /* Constant ISN */
2356 seq_rate = 0;
2357 seq_stddev = 0;
2358 hss->si.index = 0;
2359 } else {
2360
2361 /* Finally we take a binary logarithm, multiply by 8, and round
2362 * to get the final result */
2363 seq_rate = log(seq_rate) / log(2.0);
2364 seq_rate = (unsigned int) (seq_rate * 8 + 0.5);
2365
2366 /* Normally we don't divide by gcd in computing the rate stddev
2367 * because otherwise we'll get an artificially low value about
2368 * 1/32 of the time if the responses all happen to be even. On
2369 * the other hand, if a system inherently uses a large gcd such
2370 * as 64,000, we want to get rid of it. So as a compromise, we
2371 * divide by the gcd if it is at least 9 */
2372 int div_gcd = 1;
2373 if (seq_gcd > 9)
2374 div_gcd = seq_gcd;
2375
2376 for (i = 0; i < hss->si.responses - 1; i++) {
2377 double rtmp = seq_rates[i] / div_gcd - seq_avg_rate / div_gcd;
2378 seq_stddev += rtmp * rtmp;
2379 }
2380
2381 /* We divide by ((numelements in seq_diffs) - 1), which is
2382 * (si.responses - 2), because that gives a better approx of
2383 * std. dev when you're only looking at a subset of whole
2384 * population. */
2385 seq_stddev /= hss->si.responses - 2;
2386
2387 /* Next we need to take the square root of this value */
2388 seq_stddev = sqrt(seq_stddev);
2389
2390 /* Finally we take a binary logarithm, multiply by 8, and round
2391 * to get the final result */
2392 if (seq_stddev <= 1)
2393 hss->si.index = 0;
2394 else {
2395 seq_stddev = log(seq_stddev) / log(2.0);
2396 hss->si.index = (int) (seq_stddev * 8 + 0.5);
2397 }
2398 }
2399
2400 AV.attribute = "SP";
2401 AV.value = string_pool_sprintf("%X", hss->si.index);
2402 seq_AVs.push_back(AV);
2403 AV.attribute = "GCD";
2404 AV.value = string_pool_sprintf("%X", seq_gcd);
2405 seq_AVs.push_back(AV);
2406 AV.attribute = "ISR";
2407 AV.value = string_pool_sprintf("%X", (unsigned int) seq_rate);
2408 seq_AVs.push_back(AV);
2409 } else if (hss->si.responses > 0) {
2410 if (o.debugging)
2411 log_write(LOG_PLAIN, "Insufficient responses from %s for TCP sequencing (%d), OS detection may be less accurate\n", hss->target->targetipstr(), hss->si.responses);
2412 }
2413
2414 /* Now it is time to deal with IPIDs */
2415 good_tcp_ipid_num = 0;
2416 good_tcp_closed_ipid_num = 0;
2417 good_icmp_ipid_num = 0;
2418
2419 for (i = 0; i < NUM_SEQ_SAMPLES; i++) {
2420 if (hss->ipid.tcp_ipids[i] != 0xffffffff) {
2421 if (good_tcp_ipid_num < i) {
2422 hss->ipid.tcp_ipids[good_tcp_ipid_num] = hss->ipid.tcp_ipids[i];
2423 }
2424 good_tcp_ipid_num++;
2425 }
2426
2427 if (hss->ipid.tcp_closed_ipids[i] != 0xffffffff) {
2428 if (good_tcp_closed_ipid_num < i) {
2429 hss->ipid.tcp_closed_ipids[good_tcp_closed_ipid_num] = hss->ipid.tcp_closed_ipids[i];
2430 }
2431 good_tcp_closed_ipid_num++;
2432 }
2433
2434 if (hss->ipid.icmp_ipids[i] != 0xffffffff) {
2435 if (good_icmp_ipid_num < i) {
2436 hss->ipid.icmp_ipids[good_icmp_ipid_num] = hss->ipid.icmp_ipids[i];
2437 }
2438 good_icmp_ipid_num++;
2439 }
2440 }
2441
2442 if (good_tcp_ipid_num >= 3) {
2443 tcp_ipid_seqclass = get_ipid_sequence_16(good_tcp_ipid_num, hss->ipid.tcp_ipids, islocalhost(hss->target->TargetSockAddr()));
2444 } else {
2445 tcp_ipid_seqclass = IPID_SEQ_UNKNOWN;
2446 }
2447 /* Only print open tcp ipid seqclass in the final report. */
2448 hss->si.ipid_seqclass = tcp_ipid_seqclass;
2449
2450 if (good_tcp_closed_ipid_num >= 2) {
2451 tcp_closed_ipid_seqclass = get_ipid_sequence_16(good_tcp_closed_ipid_num, hss->ipid.tcp_closed_ipids, islocalhost(hss->target->TargetSockAddr()));
2452 } else {
2453 tcp_closed_ipid_seqclass = IPID_SEQ_UNKNOWN;
2454 }
2455
2456 if (good_icmp_ipid_num >= 2) {
2457 icmp_ipid_seqclass = get_ipid_sequence_16(good_icmp_ipid_num, hss->ipid.icmp_ipids, islocalhost(hss->target->TargetSockAddr()));
2458 } else {
2459 icmp_ipid_seqclass = IPID_SEQ_UNKNOWN;
2460 }
2461
2462 /* This fills in TI=Z or something like that. */
2463 if (make_aval_ipid_seq(&AV, "TI", tcp_ipid_seqclass, hss->ipid.tcp_ipids) != NULL)
2464 seq_AVs.push_back(AV);
2465 if (make_aval_ipid_seq(&AV, "CI", tcp_closed_ipid_seqclass, hss->ipid.tcp_closed_ipids) != NULL)
2466 seq_AVs.push_back(AV);
2467 if (make_aval_ipid_seq(&AV, "II", icmp_ipid_seqclass, hss->ipid.icmp_ipids) != NULL)
2468 seq_AVs.push_back(AV);
2469
2470 /* SS: Shared IP ID sequence boolean */
2471 if ((tcp_ipid_seqclass == IPID_SEQ_INCR ||
2472 tcp_ipid_seqclass == IPID_SEQ_BROKEN_INCR ||
2473 tcp_ipid_seqclass == IPID_SEQ_RPI) &&
2474 (icmp_ipid_seqclass == IPID_SEQ_INCR ||
2475 icmp_ipid_seqclass == IPID_SEQ_BROKEN_INCR ||
2476 icmp_ipid_seqclass == IPID_SEQ_RPI)) {
2477 /* Both are incremental. Thus we have "SS" test. Check if they
2478 are in the same sequence. */
2479 AV.attribute = "SS";
2480 u32 avg = (hss->ipid.tcp_ipids[good_tcp_ipid_num - 1] - hss->ipid.tcp_ipids[0]) / (good_tcp_ipid_num - 1);
2481 if (hss->ipid.icmp_ipids[0] < hss->ipid.tcp_ipids[good_tcp_ipid_num - 1] + 3 * avg) {
2482 AV.value = "S";
2483 } else {
2484 AV.value = "O";
2485 }
2486 seq_AVs.push_back(AV);
2487 }
2488
2489 /* Now we look at TCP Timestamp sequence prediction */
2490 /* Battle plan:
2491 1) Compute average increments per second, and variance in incr. per second
2492 2) If any are 0, set to constant
2493 3) If variance is high, set to random incr. [ skip for now ]
2494 4) if ~10/second, set to appropriate thing
2495 5) Same with ~100/sec
2496 */
2497 if (hss->si.ts_seqclass == TS_SEQ_UNKNOWN && hss->si.responses >= 2) {
2498 time_t uptime = 0;
2499 avg_ts_hz = 0.0;
2500 for (i = 0; i < hss->si.responses - 1; i++) {
2501 double dhz;
2502
2503 dhz = (double) ts_diffs[i] / (time_usec_diffs[i] / 1000000.0);
2504 /* printf("ts incremented by %d in %li usec -- %fHZ\n", ts_diffs[i], time_usec_diffs[i], dhz); */
2505 avg_ts_hz += dhz / (hss->si.responses - 1);
2506 }
2507
2508 if (avg_ts_hz > 0 && avg_ts_hz < 5.66) { /* relatively wide range because sampling time so short and frequency so slow */
2509 hss->si.ts_seqclass = TS_SEQ_2HZ;
2510 uptime = hss->si.timestamps[0] / 2;
2511 }
2512 else if (avg_ts_hz > 70 && avg_ts_hz < 150) {
2513 hss->si.ts_seqclass = TS_SEQ_100HZ;
2514 uptime = hss->si.timestamps[0] / 100;
2515 }
2516 else if (avg_ts_hz > 724 && avg_ts_hz < 1448) {
2517 hss->si.ts_seqclass = TS_SEQ_1000HZ;
2518 uptime = hss->si.timestamps[0] / 1000;
2519 }
2520 else if (avg_ts_hz > 0) {
2521 hss->si.ts_seqclass = TS_SEQ_OTHER_NUM;
2522 uptime = hss->si.timestamps[0] / (unsigned int)(0.5 + avg_ts_hz);
2523 }
2524
2525 if (uptime > 63072000) {
2526 /* Up 2 years? Perhaps, but they're probably lying. */
2527 if (o.debugging) {
2528 /* long long is probably excessive for number of days, but sick of
2529 * truncation warnings and finding the right format string for time_t
2530 */
2531 log_write(LOG_STDOUT, "Ignoring claimed %s uptime of %lld days\n",
2532 hss->target->targetipstr(), (long long) (uptime / 86400));
2533 }
2534 uptime = 0;
2535 }
2536 hss->si.lastboot = hss->seq_send_times[0].tv_sec - uptime;
2537 }
2538
2539 switch (hss->si.ts_seqclass) {
2540
2541 case TS_SEQ_ZERO:
2542 AV.attribute = "TS";
2543 AV.value = "0";
2544 seq_AVs.push_back(AV);
2545 break;
2546 case TS_SEQ_2HZ:
2547 case TS_SEQ_100HZ:
2548 case TS_SEQ_1000HZ:
2549 case TS_SEQ_OTHER_NUM:
2550 AV.attribute = "TS";
2551
2552 /* Here we "cheat" a little to make the classes correspond more
2553 closely to common real-life frequencies (particularly 100)
2554 which aren't powers of two. */
2555 if (avg_ts_hz <= 5.66) {
2556 /* 1 would normally range from 1.4 - 2.82, but we expand that
2557 to 0 - 5.66, so we won't ever even get a value of 2. Needs
2558 to be wide because our test is so fast that it is hard to
2559 match slow frequencies exactly. */
2560 tsnewval = 1;
2561 } else if (avg_ts_hz > 70 && avg_ts_hz <= 150) {
2562 /* mathematically 7 would be 90.51 - 181, but we change to 70-150 to
2563 better align with common freq 100 */
2564 tsnewval = 7;
2565 } else if (avg_ts_hz > 150 && avg_ts_hz <= 350) {
2566 /* would normally be 181 - 362. Now aligns better with 200 */
2567 tsnewval = 8;
2568 } else {
2569 /* Do a log base2 rounded to nearest int */
2570 tsnewval = (unsigned int)(0.5 + log(avg_ts_hz) / log(2.0));
2571 }
2572
2573 AV.value = string_pool_sprintf("%X", tsnewval);
2574 seq_AVs.push_back(AV);
2575 break;
2576 case TS_SEQ_UNSUPPORTED:
2577 AV.attribute = "TS";
2578 AV.value = "U";
2579 seq_AVs.push_back(AV);
2580 break;
2581 }
2582
2583 /* Now generate the SEQ line of the fingerprint if there are any test results
2584 in seq_AVs. */
2585 if (!seq_AVs.empty()) {
2586 hss->FP_TSeq = new FingerTest;
2587 hss->FP_TSeq->name = "SEQ";
2588 hss->FP_TSeq->results = seq_AVs;
2589 }
2590 }
2591
2592
makeTOpsFP(HostOsScanStats * hss)2593 void HostOsScan::makeTOpsFP(HostOsScanStats *hss) {
2594 assert(hss);
2595 std::vector<struct AVal> AVs;
2596 int i, n;
2597
2598 if (hss->TOpsReplyNum != 6)
2599 return;
2600
2601 for (n = 0; n < 6; n++) {
2602 if (!hss->TOps_AVs[n])
2603 break;
2604 }
2605 if (n < 6) {
2606 if (o.debugging)
2607 error("We didn't get all the TOps replies from %s", hss->target->targetipstr());
2608 return;
2609 }
2610
2611 AVs.reserve(n);
2612
2613 for (i = 0; i < n; i++)
2614 AVs.push_back(*hss->TOps_AVs[i]);
2615
2616 hss->FP_TOps = new FingerTest;
2617 hss->FP_TOps->results = AVs;
2618 hss->FP_TOps->name = "OPS";
2619 }
2620
2621
makeTWinFP(HostOsScanStats * hss)2622 void HostOsScan::makeTWinFP(HostOsScanStats *hss) {
2623 assert(hss);
2624 std::vector<struct AVal> AVs;
2625 int i, n;
2626
2627 if (hss->TWinReplyNum != 6)
2628 return;
2629
2630 for (n = 0; n < 6; n++) {
2631 if (!hss->TWin_AVs[n])
2632 break;
2633 }
2634 if (n < 6) {
2635 if (o.debugging)
2636 error("We didn't get all the TWin replies from %s", hss->target->targetipstr());
2637 return;
2638 }
2639
2640 AVs.reserve(n);
2641
2642 for (i = 0; i < n; i++)
2643 AVs.push_back(*hss->TWin_AVs[i]);
2644
2645 hss->FP_TWin = new FingerTest;
2646 hss->FP_TWin->results = AVs;
2647 hss->FP_TWin->name = "WIN";
2648 }
2649
2650
processTSeqResp(HostOsScanStats * hss,struct ip * ip,int replyNo)2651 bool HostOsScan::processTSeqResp(HostOsScanStats *hss, struct ip *ip, int replyNo) {
2652 assert(replyNo >= 0 && replyNo < NUM_SEQ_SAMPLES);
2653
2654 struct tcp_hdr *tcp;
2655 int seq_response_num; /* response # for sequencing */
2656 u32 timestamp = 0; /* TCP timestamp we receive back */
2657
2658 if (hss->lastipid != 0 && ip->ip_id == hss->lastipid) {
2659 /* Probably a duplicate -- this happens sometimes when scanning localhost */
2660 return false;
2661 }
2662 hss->lastipid = ip->ip_id;
2663
2664 tcp = ((struct tcp_hdr *) (((char *) ip) + 4 * ip->ip_hl));
2665
2666 if ((tcp->th_flags & TH_RST)) {
2667 if (hss->si.responses == 0) {
2668 error("WARNING: RST from %s port %d -- is this port really open?",
2669 hss->target->targetipstr(), hss->openTCPPort);
2670 }
2671 return false;
2672 }
2673
2674 if ((tcp->th_flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) {
2675 /* error("DEBUG: response is SYN|ACK to port %hu\n", ntohs(tcp->th_dport)); */
2676 /*readtcppacket((char *)ip, ntohs(ip->ip_len));*/
2677 /* We use the ACK value to match up our sent with rcv'd packets */
2678 seq_response_num = ntohl(tcp->th_ack) - tcpSeqBase - 1;
2679 /* printf("seq_response_num = %d\treplyNo = %d\n", seq_response_num, replyNo); */
2680
2681 if (seq_response_num != replyNo) {
2682 /* BzzT! Value out of range */
2683 if (o.debugging) {
2684 error("Unable to associate os scan response with sent packet for %s.",
2685 hss->target->targetipstr());
2686 error("Received ack: %lX; sequence sent: %lX. Packet:",
2687 (unsigned long) ntohl(tcp->th_ack),
2688 (unsigned long) tcpSeqBase);
2689 readtcppacket((unsigned char *)ip, ntohs(ip->ip_len));
2690 }
2691 seq_response_num = replyNo;
2692 }
2693
2694 if (hss->si.seqs[seq_response_num] == 0) {
2695 /* New response found! */
2696 hss->si.responses++;
2697 hss->si.seqs[seq_response_num] = ntohl(tcp->th_seq); /* TCP ISN */
2698 hss->si.ipids[seq_response_num] = ntohs(ip->ip_id);
2699
2700 if ((gettcpopt_ts(tcp, ×tamp, NULL) == 0))
2701 hss->si.ts_seqclass = TS_SEQ_UNSUPPORTED;
2702 else {
2703 if (timestamp == 0) {
2704 hss->si.ts_seqclass = TS_SEQ_ZERO;
2705 }
2706 }
2707 hss->si.timestamps[seq_response_num] = timestamp;
2708 /* printf("Response #%d -- ipid=%hu ts=%i\n", seq_response_num, ntohs(ip->ip_id), timestamp); */
2709
2710 return true;
2711 }
2712 }
2713
2714 return false;
2715 }
2716
2717
processTOpsResp(HostOsScanStats * hss,struct tcp_hdr * tcp,int replyNo)2718 bool HostOsScan::processTOpsResp(HostOsScanStats *hss, struct tcp_hdr *tcp, int replyNo) {
2719 assert(replyNo >= 0 && replyNo < 6);
2720 char ops_buf[256];
2721 bool opsParseResult;
2722
2723 if (hss->FP_TOps || hss->TOps_AVs[replyNo])
2724 return false;
2725
2726 hss->TOps_AVs[replyNo] = (struct AVal *) safe_zalloc(sizeof(struct AVal));
2727 opsParseResult = get_tcpopt_string(tcp, this->tcpMss, ops_buf, sizeof(ops_buf));
2728
2729 if (!opsParseResult) {
2730 if (o.debugging)
2731 error("Option parse error for TOps response %d from %s.", replyNo, hss->target->targetipstr());
2732 hss->TOps_AVs[replyNo]->value = "";
2733 }
2734
2735 hss->TOps_AVs[replyNo]->value = string_pool_insert(ops_buf);
2736
2737 switch (replyNo) {
2738 case 0:
2739 hss->TOps_AVs[replyNo]->attribute = "O1";
2740 break;
2741 case 1:
2742 hss->TOps_AVs[replyNo]->attribute = "O2";
2743 break;
2744 case 2:
2745 hss->TOps_AVs[replyNo]->attribute = "O3";
2746 break;
2747 case 3:
2748 hss->TOps_AVs[replyNo]->attribute = "O4";
2749 break;
2750 case 4:
2751 hss->TOps_AVs[replyNo]->attribute = "O5";
2752 break;
2753 case 5:
2754 hss->TOps_AVs[replyNo]->attribute = "O6";
2755 break;
2756 }
2757
2758 hss->TOpsReplyNum++;
2759 return true;
2760 }
2761
2762
processTWinResp(HostOsScanStats * hss,struct tcp_hdr * tcp,int replyNo)2763 bool HostOsScan::processTWinResp(HostOsScanStats *hss, struct tcp_hdr *tcp, int replyNo) {
2764 assert(replyNo >= 0 && replyNo < 6);
2765
2766 if (hss->FP_TWin || hss->TWin_AVs[replyNo])
2767 return false;
2768
2769 hss->TWin_AVs[replyNo] = (struct AVal *) safe_zalloc(sizeof(struct AVal));
2770 hss->TWin_AVs[replyNo]->value = string_pool_sprintf("%hX", ntohs(tcp->th_win));
2771
2772 switch (replyNo) {
2773 case 0:
2774 hss->TWin_AVs[replyNo]->attribute = "W1";
2775 break;
2776 case 1:
2777 hss->TWin_AVs[replyNo]->attribute = "W2";
2778 break;
2779 case 2:
2780 hss->TWin_AVs[replyNo]->attribute = "W3";
2781 break;
2782 case 3:
2783 hss->TWin_AVs[replyNo]->attribute = "W4";
2784 break;
2785 case 4:
2786 hss->TWin_AVs[replyNo]->attribute = "W5";
2787 break;
2788 case 5:
2789 hss->TWin_AVs[replyNo]->attribute = "W6";
2790 break;
2791 }
2792
2793 hss->TWinReplyNum++;
2794 return true;
2795 }
2796
2797
processTEcnResp(HostOsScanStats * hss,struct ip * ip)2798 bool HostOsScan::processTEcnResp(HostOsScanStats *hss, struct ip *ip) {
2799 std::vector<struct AVal> AVs;
2800 struct AVal AV;
2801 char ops_buf[256];
2802 char quirks_buf[10];
2803 char *p;
2804 int numtests = 7;
2805 struct tcp_hdr *tcp = ((struct tcp_hdr *) (((char *) ip) + 4 * ip->ip_hl));
2806 bool opsParseResult;
2807
2808 if (hss->FP_TEcn)
2809 return false;
2810
2811 /* Create the Avals */
2812 AVs.reserve(numtests);
2813
2814 AV.attribute = "R";
2815 AV.value = "Y";
2816 AVs.push_back(AV);
2817
2818 /* don't frag flag */
2819 AV.attribute = "DF";
2820 if (ntohs(ip->ip_off) & IP_DF)
2821 AV.value = "Y";
2822 else
2823 AV.value = "N";
2824 AVs.push_back(AV);
2825
2826 /* TTL */
2827 AV.attribute = "T";
2828 AV.value = string_pool_sprintf("%d", ip->ip_ttl);
2829 AVs.push_back(AV);
2830
2831 /* TCP Window size */
2832 AV.attribute = "W";
2833 AV.value = string_pool_sprintf("%hX", ntohs(tcp->th_win));
2834 AVs.push_back(AV);
2835
2836 /* Now for the TCP options ... */
2837 AV.attribute = "O";
2838 opsParseResult = get_tcpopt_string(tcp, this->tcpMss, ops_buf, sizeof(ops_buf));
2839
2840 if (!opsParseResult) {
2841 if (o.debugging)
2842 error("Option parse error for ECN response from %s.", hss->target->targetipstr());
2843 AV.value = "";
2844 }
2845
2846 AV.value = string_pool_insert(ops_buf);
2847 AVs.push_back(AV);
2848
2849 /* Explicit Congestion Notification support test */
2850 AV.attribute = "CC";
2851 if ((tcp->th_flags & TH_ECE) && (tcp->th_flags & TH_CWR))
2852 /* echo back */
2853 AV.value = "S";
2854 else if (tcp->th_flags & TH_ECE)
2855 /* support */
2856 AV.value = "Y";
2857 else if (!(tcp->th_flags & TH_CWR))
2858 /* not support */
2859 AV.value = "N";
2860 else
2861 AV.value = "O";
2862 AVs.push_back(AV);
2863
2864 /* TCP miscellaneous quirks test */
2865 AV.attribute = "Q";
2866 p = quirks_buf;
2867 if (tcp->th_x2) {
2868 /* Reserved field of TCP is not zero */
2869 assert(p + 1 < quirks_buf + sizeof(quirks_buf));
2870 *p++ = 'R';
2871 }
2872 if (!(tcp->th_flags & TH_URG) && tcp->th_urp) {
2873 /* URG pointer value when urg flag not set */
2874 assert(p + 1 < quirks_buf + sizeof(quirks_buf));
2875 *p++ = 'U';
2876 }
2877 *p = '\0';
2878 AV.value = string_pool_insert(quirks_buf);
2879 AVs.push_back(AV);
2880
2881 hss->FP_TEcn = new FingerTest;
2882 hss->FP_TEcn->name = "ECN";
2883 hss->FP_TEcn->results = AVs;
2884
2885 return true;
2886 }
2887
2888
processT1_7Resp(HostOsScanStats * hss,struct ip * ip,int replyNo)2889 bool HostOsScan::processT1_7Resp(HostOsScanStats *hss, struct ip *ip, int replyNo) {
2890 std::vector<struct AVal> AVs;
2891 struct AVal AV;
2892 assert(replyNo >= 0 && replyNo < 7);
2893
2894 int numtests;
2895 struct tcp_hdr *tcp = ((struct tcp_hdr *) (((char *) ip) + 4 * ip->ip_hl));
2896
2897 int i;
2898 bool opsParseResult;
2899 int length;
2900 char flags_buf[10];
2901 char quirks_buf[10];
2902 char *p;
2903
2904 if (hss->FPtests[FP_T1_7_OFF + replyNo])
2905 return false;
2906
2907 if (replyNo == 0)
2908 numtests = 8; /* T1 doesn't has 'Win', 'Ops' tests. */
2909 else numtests = 10;
2910
2911 /* Create the Avals */
2912 AVs.reserve(numtests);
2913
2914 /* First we give the "response" flag to say we did actually receive
2915 a packet -- this way we won't match a template with R=N */
2916 AV.attribute = "R";
2917 AV.value = "Y";
2918 AVs.push_back(AV);
2919
2920 /* Next we check whether the Don't Fragment bit is set */
2921 AV.attribute = "DF";
2922 if (ntohs(ip->ip_off) & IP_DF)
2923 AV.value = "Y";
2924 else
2925 AV.value = "N";
2926 AVs.push_back(AV);
2927
2928 /* TTL */
2929 AV.attribute = "T";
2930 AV.value = string_pool_sprintf("%d", ip->ip_ttl);
2931 AVs.push_back(AV);
2932
2933 if (replyNo != 0) {
2934 /* Now we do the TCP Window size */
2935 AV.attribute = "W";
2936 AV.value = string_pool_sprintf("%hX", ntohs(tcp->th_win));
2937 AVs.push_back(AV);
2938 }
2939
2940 /* Seq test values:
2941 Z = zero
2942 A = same as ack
2943 A+ = ack + 1
2944 O = other
2945 */
2946 AV.attribute = "S";
2947 if (ntohl(tcp->th_seq) == 0)
2948 AV.value = "Z";
2949 else if (ntohl(tcp->th_seq) == tcpAck)
2950 AV.value = "A";
2951 else if (ntohl(tcp->th_seq) == tcpAck + 1)
2952 AV.value = "A+";
2953 else
2954 AV.value = "O";
2955 AVs.push_back(AV);
2956
2957 /* ACK test values:
2958 Z = zero
2959 S = same as syn
2960 S+ = syn + 1
2961 O = other
2962 */
2963 AV.attribute = "A";
2964 if (ntohl(tcp->th_ack) == 0)
2965 AV.value = "Z";
2966 else if (ntohl(tcp->th_ack) == tcpSeqBase)
2967 AV.value = "S";
2968 else if (ntohl(tcp->th_ack) == tcpSeqBase + 1)
2969 AV.value = "S+";
2970 else
2971 AV.value = "O";
2972 AVs.push_back(AV);
2973
2974 /* Flags. They must be in this order:
2975 E = ECN Echo
2976 U = Urgent
2977 A = Acknowledgement
2978 P = Push
2979 R = Reset
2980 S = Synchronize
2981 F = Final
2982 */
2983 struct {
2984 u8 flag;
2985 char c;
2986 } flag_defs[] = {
2987 { TH_ECE, 'E' },
2988 { TH_URG, 'U' },
2989 { TH_ACK, 'A' },
2990 { TH_PUSH, 'P' },
2991 { TH_RST, 'R' },
2992 { TH_SYN, 'S' },
2993 { TH_FIN, 'F' },
2994 };
2995 assert(sizeof(flag_defs) / sizeof(flag_defs[0]) < sizeof(flags_buf));
2996 AV.attribute = "F";
2997 p = flags_buf;
2998 for (i = 0; i < (int) (sizeof(flag_defs) / sizeof(flag_defs[0])); i++) {
2999 if (tcp->th_flags & flag_defs[i].flag)
3000 *p++ = flag_defs[i].c;
3001 }
3002 *p = '\0';
3003 AV.value = string_pool_insert(flags_buf);
3004 AVs.push_back(AV);
3005
3006 if (replyNo != 0) {
3007 char ops_buf[256];
3008
3009 /* Now for the TCP options ... */
3010 AV.attribute = "O";
3011 opsParseResult = get_tcpopt_string(tcp, this->tcpMss, ops_buf, sizeof(ops_buf));
3012 if (!opsParseResult) {
3013 if (o.debugging)
3014 error("Option parse error for T%d response from %s.", replyNo, hss->target->targetipstr());
3015 AV.value = "";
3016 }
3017
3018 AV.value = string_pool_insert(ops_buf);
3019 AVs.push_back(AV);
3020 }
3021
3022 /* Rst Data CRC32 */
3023 AV.attribute = "RD";
3024 length = (int) ntohs(ip->ip_len) - 4 * ip->ip_hl -4 * tcp->th_off;
3025 if ((tcp->th_flags & TH_RST) && length>0) {
3026 AV.value = string_pool_sprintf("%08lX", nbase_crc32(((u8 *)tcp) + 4 * tcp->th_off, length));
3027 } else {
3028 AV.value = "0";
3029 }
3030 AVs.push_back(AV);
3031
3032 /* TCP miscellaneous quirks test */
3033 AV.attribute = "Q";
3034 p = quirks_buf;
3035 if (tcp->th_x2) {
3036 /* Reserved field of TCP is not zero */
3037 assert(p + 1 < quirks_buf + sizeof(quirks_buf));
3038 *p++ = 'R';
3039 }
3040 if (!(tcp->th_flags & TH_URG) && tcp->th_urp) {
3041 /* URG pointer value when urg flag not set */
3042 assert(p + 1 < quirks_buf + sizeof(quirks_buf));
3043 *p++ = 'U';
3044 }
3045 *p = '\0';
3046 AV.value = string_pool_insert(quirks_buf);
3047 AVs.push_back(AV);
3048
3049 hss->FPtests[FP_T1_7_OFF + replyNo] = new FingerTest;
3050 hss->FPtests[FP_T1_7_OFF + replyNo]->results = AVs;
3051 hss->FPtests[FP_T1_7_OFF + replyNo]->name = (replyNo == 0) ? "T1" : (replyNo == 1) ? "T2" : (replyNo == 2) ? "T3" : (replyNo == 3) ? "T4" : (replyNo == 4) ? "T5" : (replyNo == 5) ? "T6" : "T7";
3052
3053 return true;
3054 }
3055
3056
processTUdpResp(HostOsScanStats * hss,struct ip * ip)3057 bool HostOsScan::processTUdpResp(HostOsScanStats *hss, struct ip *ip) {
3058 std::vector<struct AVal> AVs;
3059 struct AVal AV;
3060
3061 assert(hss);
3062 assert(ip);
3063
3064 struct icmp *icmp;
3065 struct ip *ip2;
3066 int numtests;
3067 unsigned short checksum;
3068 unsigned short *checksumptr;
3069 struct udp_hdr *udp;
3070 unsigned char *datastart, *dataend;
3071
3072 #if !defined(SOLARIS) && !defined(SUNOS) && !defined(IRIX) && !defined(HPUX)
3073 numtests = 10;
3074 #else
3075 /* We don't do RID test under these operating systems, thus the
3076 number of test is 1 less. */
3077 numtests = 9;
3078 #endif
3079
3080 if (hss->FP_TUdp)
3081 return false;
3082
3083 icmp = ((struct icmp *)(((char *) ip) + 4 * ip->ip_hl));
3084
3085 /* Make sure this is icmp port unreachable. */
3086 assert(icmp->icmp_type == 3 && icmp->icmp_code == 3);
3087
3088 ip2 = (struct ip*)((char *)icmp + 8);
3089 udp = (struct udp_hdr *)((char *)ip2 + 4 * ip2->ip_hl);
3090
3091 /* The ports should match. */
3092 if (ntohs(udp->uh_sport) != hss->upi.sport || ntohs(udp->uh_dport) != hss->upi.dport) {
3093 return false;
3094 }
3095
3096 /* Create the Avals */
3097 AVs.reserve(numtests);
3098
3099 /* First of all, if we got this far the response was yes */
3100 AV.attribute = "R";
3101 AV.value = "Y";
3102 AVs.push_back(AV);
3103
3104 /* Also, we now know that the port we reached was closed */
3105 if (hss->target->FPR->osscan_closedudpport == -1)
3106 hss->target->FPR->osscan_closedudpport = hss->upi.dport;
3107
3108 /* Now let us do an easy one, Don't fragment */
3109 AV.attribute = "DF";
3110 if (ntohs(ip->ip_off) & IP_DF)
3111 AV.value = "Y";
3112 else
3113 AV.value = "N";
3114 AVs.push_back(AV);
3115
3116 /* TTL */
3117 AV.attribute = "T";
3118 AV.value = string_pool_sprintf("%d", ip->ip_ttl);
3119 AVs.push_back(AV);
3120
3121 /* Now we look at the IP datagram length that was returned, some
3122 machines send more of the original packet back than others */
3123 AV.attribute = "IPL";
3124 AV.value = string_pool_sprintf("%hX", ntohs(ip->ip_len));
3125 AVs.push_back(AV);
3126
3127 /* unused filed not zero in Destination Unreachable Message */
3128 AV.attribute = "UN";
3129 AV.value = string_pool_sprintf("%hX", ntohl(icmp->icmp_void));
3130 AVs.push_back(AV);
3131
3132 /* OK, lets check the returned IP length, some systems @$@ this
3133 up */
3134 AV.attribute = "RIPL";
3135 if (ntohs(ip2->ip_len) == 328)
3136 AV.value = "G";
3137 else
3138 AV.value = string_pool_sprintf("%hX", ntohs(ip2->ip_len));
3139 AVs.push_back(AV);
3140
3141 /* This next test doesn't work on Solaris because the lamers
3142 overwrite our ip_id */
3143 #if !defined(SOLARIS) && !defined(SUNOS) && !defined(IRIX) && !defined(HPUX)
3144
3145 /* Now lets see how they treated the ID we sent ... */
3146 AV.attribute = "RID";
3147 if (ntohs(ip2->ip_id) == hss->upi.ipid)
3148 AV.value = "G"; /* The good "expected" value */
3149 else
3150 AV.value = string_pool_sprintf("%hX", ntohs(ip2->ip_id));
3151 AVs.push_back(AV);
3152
3153 #endif
3154
3155 /* Let us see if the IP checksum we got back computes */
3156
3157 AV.attribute = "RIPCK";
3158 /* Thanks to some machines not having struct ip member ip_sum we
3159 have to go with this BS */
3160 checksumptr = (unsigned short *) ((char *) ip2 + 10);
3161 checksum = *checksumptr;
3162
3163 if (checksum == 0) {
3164 AV.value = "Z";
3165 } else {
3166 *checksumptr = 0;
3167 if (in_cksum((unsigned short *)ip2, 20) == checksum) {
3168 AV.value = "G"; /* The "expected" good value */
3169 } else {
3170 AV.value = "I"; /* They modified it */
3171 }
3172 *checksumptr = checksum;
3173 }
3174 AVs.push_back(AV);
3175
3176 /* UDP checksum */
3177 AV.attribute = "RUCK";
3178 if (udp->uh_sum == hss->upi.udpck)
3179 AV.value = "G"; /* The "expected" good value */
3180 else
3181 AV.value = string_pool_sprintf("%hX", ntohs(udp->uh_sum));
3182 AVs.push_back(AV);
3183
3184 /* Finally we ensure the data is OK */
3185 datastart = ((unsigned char *)udp) + 8;
3186 dataend = (unsigned char *) ip + ntohs(ip->ip_len);
3187
3188 while (datastart < dataend) {
3189 if (*datastart != hss->upi.patternbyte)
3190 break;
3191 datastart++;
3192 }
3193 AV.attribute = "RUD";
3194 if (datastart < dataend)
3195 AV.value = "I"; /* They modified it */
3196 else
3197 AV.value = "G";
3198 AVs.push_back(AV);
3199
3200 hss->FP_TUdp = new FingerTest;
3201 hss->FP_TUdp->name = "U1";
3202 hss->FP_TUdp->results = AVs;
3203
3204 /* Count hop count */
3205 if (hss->distance == -1) {
3206 hss->distance = this->udpttl - ip2->ip_ttl + 1;
3207 }
3208
3209 return true;
3210 }
3211
3212
processTIcmpResp(HostOsScanStats * hss,struct ip * ip,int replyNo)3213 bool HostOsScan::processTIcmpResp(HostOsScanStats *hss, struct ip *ip, int replyNo) {
3214 assert(replyNo == 0 || replyNo == 1);
3215
3216 std::vector<struct AVal> AVs;
3217 struct AVal AV;
3218 int numtests = 4;
3219 struct ip *ip1, *ip2;
3220 struct icmp *icmp1, *icmp2;
3221 unsigned short value1, value2;
3222
3223 if (hss->FP_TIcmp)
3224 return false;
3225
3226 if (hss->icmpEchoReply == NULL) {
3227 /* This is the first icmp reply we get, store it and return. */
3228 hss->icmpEchoReply = (struct ip *) safe_malloc(ntohs(ip->ip_len));
3229 memcpy(hss->icmpEchoReply, ip, ntohs(ip->ip_len));
3230 hss->storedIcmpReply = replyNo;
3231 return true;
3232 } else if (hss->storedIcmpReply == replyNo) {
3233 /* This is a duplicated icmp reply. */
3234 return false;
3235 }
3236
3237 /* Ok, now we get another reply. */
3238 if (hss->storedIcmpReply == 0) {
3239 ip1 = hss->icmpEchoReply;
3240 ip2 = ip;
3241 } else {
3242 ip1 = ip;
3243 ip2 = hss->icmpEchoReply;
3244 }
3245
3246 icmp1 = ((struct icmp *)(((char *) ip1) + 4 * ip1->ip_hl));
3247 icmp2 = ((struct icmp *)(((char *) ip2) + 4 * ip2->ip_hl));
3248
3249 assert(icmp1->icmp_type == 0 && icmp2->icmp_type == 0);
3250
3251 /* Create the Avals */
3252 AVs.reserve(numtests);
3253
3254 AV.attribute = "R";
3255 AV.value = "Y";
3256 AVs.push_back(AV);
3257
3258 /* DFI test values:
3259 * Y. Both set DF;
3260 * S. Both use the DF that the sender uses;
3261 * N. Both not set;
3262 * O. Other(both different with the sender, -_-b).
3263 */
3264 AV.attribute = "DFI";
3265 value1 = (ntohs(ip1->ip_off) & IP_DF);
3266 value2 = (ntohs(ip2->ip_off) & IP_DF);
3267 if (value1 && value2)
3268 /* both set */
3269 AV.value = "Y";
3270 else if (value1 && !value2)
3271 /* echo back */
3272 AV.value = "S";
3273 else if (!value1 && !value2)
3274 /* neither set */
3275 AV.value = "N";
3276 else
3277 AV.value = "O";
3278 AVs.push_back(AV);
3279
3280 /* TTL */
3281
3282 AV.attribute = "T";
3283 AV.value = string_pool_sprintf("%d", ip1->ip_ttl);
3284 AVs.push_back(AV);
3285
3286 /* ICMP Code value. Test values:
3287 * [Value]. Both set Code to the same value [Value];
3288 * S. Both use the Code that the sender uses;
3289 * O. Other.
3290 */
3291 AV.attribute = "CD";
3292 value1 = icmp1->icmp_code;
3293 value2 = icmp2->icmp_code;
3294 if (value1 == value2) {
3295 if (value1 == 0)
3296 AV.value = "Z";
3297 else
3298 AV.value = string_pool_sprintf("%hX", value1);
3299 }
3300 else if (value1 == 9 && value2 == 0)
3301 /* both the same as in the corresponding probe */
3302 AV.value = "S";
3303 else
3304 AV.value = "O";
3305 AVs.push_back(AV);
3306
3307 hss->FP_TIcmp= new FingerTest;
3308 hss->FP_TIcmp->name = "IE";
3309 hss->FP_TIcmp->results = AVs;
3310
3311 return true;
3312 }
3313
3314
get_tcpopt_string(struct tcp_hdr * tcp,int mss,char * result,int maxlen)3315 bool HostOsScan::get_tcpopt_string(struct tcp_hdr *tcp, int mss, char *result, int maxlen) {
3316 char *p, *q;
3317 u16 tmpshort;
3318 u32 tmpword;
3319 int length;
3320 int opcode;
3321
3322 p = result;
3323 length = (tcp->th_off * 4) - sizeof(struct tcp_hdr);
3324 q = ((char *)tcp) + sizeof(struct tcp_hdr);
3325
3326 /*
3327 * Example parsed result: M5B4ST11NW2
3328 * MSS, Sack Permitted, Timestamp with both value not zero, Nop, WScale with value 2
3329 */
3330
3331 /* Be aware of the max increment value for p in parsing,
3332 * now is 5 = strlen("Mxxxx") <-> MSS Option
3333 */
3334 while (length > 0 && (p - result) < (maxlen - 5)) {
3335 opcode = *q++;
3336 if (!opcode) { /* End of List */
3337 *p++ = 'L';
3338 length--;
3339 } else if (opcode == 1) { /* No Op */
3340 *p++ = 'N';
3341 length--;
3342 } else if (opcode == 2) { /* MSS */
3343 if (length < 4)
3344 break; /* MSS has 4 bytes */
3345 *p++ = 'M';
3346 q++;
3347 memcpy(&tmpshort, q, 2);
3348 /* if (ntohs(tmpshort) == mss) */
3349 /* *p++ = 'E'; */
3350 sprintf(p, "%hX", ntohs(tmpshort));
3351 p += strlen(p); /* max movement of p is 4 (0xFFFF) */
3352 q += 2;
3353 length -= 4;
3354 } else if (opcode == 3) { /* Window Scale */
3355 if (length < 3)
3356 break; /* Window Scale option has 3 bytes */
3357 *p++ = 'W';
3358 q++;
3359 snprintf(p, length, "%hhX", *((u8*)q));
3360 p += strlen(p); /* max movement of p is 2 (max WScale value is 0xFF) */
3361 q++;
3362 length -= 3;
3363 } else if (opcode == 4) { /* SACK permitted */
3364 if (length < 2)
3365 break; /* SACK permitted option has 2 bytes */
3366 *p++ = 'S';
3367 q++;
3368 length -= 2;
3369 } else if (opcode == 8) { /* Timestamp */
3370 if (length < 10)
3371 break; /* Timestamp option has 10 bytes */
3372 *p++ = 'T';
3373 q++;
3374 memcpy(&tmpword, q, 4);
3375 if (tmpword)
3376 *p++ = '1';
3377 else
3378 *p++ = '0';
3379 q += 4;
3380 memcpy(&tmpword, q, 4);
3381 if (tmpword)
3382 *p++ = '1';
3383 else
3384 *p++ = '0';
3385 q += 4;
3386 length -= 10;
3387 }
3388 }
3389
3390 if (length > 0) {
3391 /* We could reach here for one of the two reasons:
3392 * 1. At least one option is not correct. (Eg. Should have 4 bytes but only has 3 bytes left).
3393 * 2. The option string is too long.
3394 */
3395 *result = '\0';
3396 return false;
3397 }
3398
3399 *p = '\0';
3400 return true;
3401 }
3402
3403
3404 /******************************************************************************
3405 * Implementation of class HostOsScanInfo *
3406 ******************************************************************************/
3407
HostOsScanInfo(Target * t,OsScanInfo * OsSI)3408 HostOsScanInfo::HostOsScanInfo(Target *t, OsScanInfo *OsSI) {
3409 target = t;
3410 OSI = OsSI;
3411
3412 FPs = (FingerPrint **) safe_zalloc(o.maxOSTries() * sizeof(FingerPrint *));
3413 FP_matches = new FingerPrintResultsIPv4[o.maxOSTries()];
3414 timedOut = false;
3415 isCompleted = false;
3416
3417 if (target->FPR == NULL) {
3418 this->FPR = new FingerPrintResultsIPv4;
3419 target->FPR = this->FPR;
3420 }
3421 target->osscanSetFlag(OS_PERF);
3422
3423 hss = new HostOsScanStats(t);
3424 }
3425
3426
~HostOsScanInfo()3427 HostOsScanInfo::~HostOsScanInfo() {
3428 delete hss;
3429 free(FPs);
3430 delete[] FP_matches;
3431 }
3432
3433
3434 /******************************************************************************
3435 * Implementation of class OsScanInfo *
3436 ******************************************************************************/
3437
OsScanInfo(std::vector<Target * > & Targets)3438 OsScanInfo::OsScanInfo(std::vector<Target *> &Targets) {
3439 unsigned int targetno;
3440 HostOsScanInfo *hsi;
3441 int num_timedout = 0;
3442
3443 gettimeofday(&now, NULL);
3444
3445 numInitialTargets = 0;
3446
3447 /* build up incompleteHosts list */
3448 for (targetno = 0; targetno < Targets.size(); targetno++) {
3449 /* check if Targets[targetno] is good to be scanned
3450 * if yes, append it to the list
3451 */
3452 if (Targets[targetno]->timedOut(&now)) {
3453 num_timedout++;
3454 continue;
3455 }
3456
3457 #ifdef WIN32
3458 if (g_has_npcap_loopback == 0 && Targets[targetno]->ifType() == devt_loopback) {
3459 log_write(LOG_STDOUT, "Skipping OS Scan against %s because it doesn't work against your own machine (localhost)\n", Targets[targetno]->NameIP());
3460 continue;
3461 }
3462 #endif
3463
3464 if (Targets[targetno]->ports.getStateCounts(IPPROTO_TCP, PORT_OPEN) == 0 ||
3465 (Targets[targetno]->ports.getStateCounts(IPPROTO_TCP, PORT_CLOSED) == 0 &&
3466 Targets[targetno]->ports.getStateCounts(IPPROTO_TCP, PORT_UNFILTERED) == 0)) {
3467 if (o.osscan_limit) {
3468 if (o.verbose)
3469 log_write(LOG_PLAIN, "Skipping OS Scan against %s due to absence of open (or perhaps closed) ports\n", Targets[targetno]->NameIP());
3470 continue;
3471 } else {
3472 Targets[targetno]->osscanSetFlag(OS_PERF_UNREL);
3473 }
3474 }
3475
3476 hsi = new HostOsScanInfo(Targets[targetno], this);
3477 incompleteHosts.push_back(hsi);
3478 numInitialTargets++;
3479 }
3480
3481 nextI = incompleteHosts.begin();
3482 }
3483
3484
~OsScanInfo()3485 OsScanInfo::~OsScanInfo()
3486 {
3487 while (!incompleteHosts.empty()) {
3488 delete incompleteHosts.front();
3489 incompleteHosts.pop_front();
3490 }
3491 }
3492
3493
3494 /* Find a HostScanStats by IP its address in the incomplete list. Returns NULL if
3495 none are found. */
findIncompleteHost(struct sockaddr_storage * ss)3496 HostOsScanInfo *OsScanInfo::findIncompleteHost(struct sockaddr_storage *ss) {
3497 std::list<HostOsScanInfo *>::iterator hostI;
3498 struct sockaddr_in *sin = (struct sockaddr_in *) ss;
3499
3500 if (sin->sin_family != AF_INET)
3501 fatal("%s passed a non IPv4 address", __func__);
3502
3503 for (hostI = incompleteHosts.begin(); hostI != incompleteHosts.end(); hostI++) {
3504 if ((*hostI)->target->v4hostip()->s_addr == sin->sin_addr.s_addr)
3505 return *hostI;
3506 }
3507 return NULL;
3508 }
3509
3510
3511 /* A circular buffer of the incompleteHosts. nextIncompleteHost() gives
3512 the next one. The first time it is called, it will give the
3513 first host in the list. If incompleteHosts is empty, returns
3514 NULL. */
nextIncompleteHost()3515 HostOsScanInfo *OsScanInfo::nextIncompleteHost() {
3516 HostOsScanInfo *nxt;
3517
3518 if (incompleteHosts.empty())
3519 return NULL;
3520
3521 nxt = *nextI;
3522 nextI++;
3523 if (nextI == incompleteHosts.end())
3524 nextI = incompleteHosts.begin();
3525
3526 return nxt;
3527 }
3528
3529
3530 /* Removes any hosts that have completed their scans from the incompleteHosts
3531 list. Returns the number of hosts removed. */
removeCompletedHosts()3532 int OsScanInfo::removeCompletedHosts() {
3533 std::list<HostOsScanInfo *>::iterator hostI, nxt;
3534 HostOsScanInfo *hsi = NULL;
3535 int hostsRemoved = 0;
3536 bool timedout = false;
3537
3538 for (hostI = incompleteHosts.begin(); hostI != incompleteHosts.end();
3539 hostI = nxt) {
3540 nxt = hostI;
3541 nxt++;
3542 hsi = *hostI;
3543 timedout = hsi->target->timedOut(&now);
3544 if (hsi->isCompleted || timedout) {
3545 /* A host to remove! First adjust nextI appropriately */
3546 if (nextI == hostI && incompleteHosts.size() > 1) {
3547 nextI++;
3548 if (nextI == incompleteHosts.end())
3549 nextI = incompleteHosts.begin();
3550 }
3551
3552 if (o.verbose && numInitialTargets > 50) {
3553 int remain = incompleteHosts.size() - 1;
3554 if (remain && !timedout)
3555 log_write(LOG_STDOUT, "Completed os scan against %s in %.3fs (%d %s)\n",
3556 hsi->target->targetipstr(),
3557 o.TimeSinceStart() - this->starttime, remain,
3558 (remain == 1)? "host left" : "hosts left");
3559 else if (timedout)
3560 log_write(LOG_STDOUT, "%s timed out during os scan (%d %s)\n",
3561 hsi->target->targetipstr(), remain,
3562 (remain == 1)? "host left" : "hosts left");
3563 }
3564 incompleteHosts.erase(hostI);
3565 hostsRemoved++;
3566 hsi->target->stopTimeOutClock(&now);
3567 delete hsi;
3568 }
3569 }
3570 return hostsRemoved;
3571 }
3572
3573 /******************************************************************************
3574 * Implementation of class OSScan() *
3575 ******************************************************************************/
3576
3577 /* Constructor */
OSScan()3578 OSScan::OSScan() {
3579 this->reset();
3580 return;
3581 }
3582
3583 /* Destructor */
~OSScan()3584 OSScan::~OSScan() {
3585 return;
3586 }
3587
3588 /* Function that initializes internal variables */
reset()3589 void OSScan::reset() {
3590
3591 }
3592
3593
3594 /* This function takes a group of targets and divides it in chunks if there are
3595 * too many to be processed at the same time. The threshold is based on Nmap's
3596 * timing level (when timing level is above 4, no chunking is performed).
3597 * The reason targets are processed in smaller groups is to improve accuracy. */
chunk_and_do_scan(std::vector<Target * > & Targets,int family)3598 int OSScan::chunk_and_do_scan(std::vector<Target *> &Targets, int family) {
3599 unsigned int max_os_group_sz = 20;
3600 double fudgeratio = 1.2; /* Allow a slightly larger final group rather than finish with a tiny one */
3601 std::vector<Target *> tmpTargets;
3602 unsigned int startidx = 0;
3603
3604 if (o.timing_level == 4)
3605 max_os_group_sz = (unsigned int) (max_os_group_sz * 1.5);
3606
3607 if (o.timing_level > 4 || Targets.size() <= max_os_group_sz * fudgeratio) {
3608 if (family == AF_INET6)
3609 os_scan_ipv6(Targets);
3610 else
3611 os_scan_ipv4(Targets);
3612 return OP_SUCCESS;
3613 }
3614
3615 /* We need to split it up */
3616 while (startidx < Targets.size()) {
3617 int diff = Targets.size() - startidx;
3618 if (diff > max_os_group_sz * fudgeratio) {
3619 diff = max_os_group_sz;
3620 }
3621 tmpTargets.assign(Targets.begin() + startidx, Targets.begin() + startidx + diff);
3622 if (family == AF_INET6)
3623 os_scan_ipv6(Targets);
3624 else
3625 os_scan_ipv4(Targets);
3626 startidx += diff;
3627 }
3628 return OP_SUCCESS;
3629 }
3630
3631
3632 /* Performs the OS detection for IPv4 hosts. This method should not be called
3633 * directly. os_scan() should be used instead, as it handles chunking so
3634 * you don't do too many targets in parallel */
os_scan_ipv4(std::vector<Target * > & Targets)3635 int OSScan::os_scan_ipv4(std::vector<Target *> &Targets) {
3636 int itry = 0;
3637 /* Hosts which haven't matched and have been removed from incompleteHosts because
3638 * they have exceeded the number of retransmissions the host is allowed. */
3639 std::list<HostOsScanInfo *> unMatchedHosts;
3640
3641 /* Check we have at least one target*/
3642 if (Targets.size() == 0) {
3643 return OP_FAILURE;
3644 }
3645
3646 perf.init();
3647
3648 OsScanInfo OSI(Targets);
3649 if (OSI.numIncompleteHosts() == 0) {
3650 /* no one will be scanned */
3651 return OP_FAILURE;
3652 }
3653 OSI.starttime = o.TimeSinceStart();
3654
3655 HostOsScan HOS(Targets[0]);
3656
3657 /* Initialize the pcap session handler in HOS */
3658 begin_sniffer(&HOS, Targets);
3659 while (OSI.numIncompleteHosts() != 0) {
3660 if (itry > 0)
3661 sleep(1);
3662 if (itry == 3)
3663 usleep(1500000); /* Try waiting a little longer just in case it matters */
3664 if (o.verbose) {
3665 char targetstr[128];
3666 bool plural = (OSI.numIncompleteHosts() != 1);
3667 if (!plural) {
3668 (*(OSI.incompleteHosts.begin()))->target->NameIP(targetstr, sizeof(targetstr));
3669 } else Snprintf(targetstr, sizeof(targetstr), "%d hosts", (int) OSI.numIncompleteHosts());
3670 log_write(LOG_STDOUT, "%s OS detection (try #%d) against %s\n", (itry == 0)? "Initiating" : "Retrying", itry + 1, targetstr);
3671 log_flush_all();
3672 }
3673 startRound(&OSI, &HOS, itry);
3674 doSeqTests(&OSI, &HOS);
3675 doTUITests(&OSI, &HOS);
3676 endRound(&OSI, &HOS, itry);
3677 expireUnmatchedHosts(&OSI, &unMatchedHosts);
3678 itry++;
3679 }
3680
3681 /* Now move the unMatchedHosts array back to IncompleteHosts */
3682 if (!unMatchedHosts.empty())
3683 OSI.incompleteHosts.splice(OSI.incompleteHosts.begin(), unMatchedHosts);
3684
3685 if (OSI.numIncompleteHosts()) {
3686 /* For hosts that don't have a perfect match, find the closest fingerprint
3687 * in the DB and, if we are in debugging mode, print them. */
3688 findBestFPs(&OSI);
3689 if (o.debugging > 1)
3690 printFP(&OSI);
3691 }
3692
3693 return OP_SUCCESS;
3694 }
3695
3696
3697 /* Performs the OS detection for IPv6 hosts. This method should not be called
3698 * directly. os_scan() should be used instead, as it handles chunking so
3699 * you don't do too many targets in parallel */
os_scan_ipv6(std::vector<Target * > & Targets)3700 int OSScan::os_scan_ipv6(std::vector<Target *> &Targets) {
3701
3702 /* Object instantiation */
3703 FPEngine6 fp6;
3704
3705 /* Safe checks. */
3706 if (Targets.size() == 0) {
3707 return OP_FAILURE;
3708 }
3709
3710 return fp6.os_scan(Targets);
3711 }
3712
3713
3714 /* This function performs the OS detection. It processes the supplied list of
3715 * targets and classifies it into two groups: IPv4 and IPv6 targets. Then,
3716 * OS detection is carried out for those two separate groups. It returns
3717 * OP_SUCCESS on success or OP_FAILURE in case of error. */
os_scan(std::vector<Target * > & Targets)3718 int OSScan::os_scan(std::vector<Target *> &Targets) {
3719 std::vector<Target *> ip4_targets;
3720 std::vector<Target *> ip6_targets;
3721 int res4 = OP_SUCCESS, res6 = OP_SUCCESS;
3722
3723 /* Make sure we have at least one target */
3724 if (Targets.size() <= 0)
3725 return OP_FAILURE;
3726
3727 /* Classify targets into two groups: IPv4 and IPv6 */
3728 for (size_t i = 0; i < Targets.size(); i++) {
3729 if (Targets[i]->af() == AF_INET6)
3730 ip6_targets.push_back(Targets[i]);
3731 else
3732 ip4_targets.push_back(Targets[i]);
3733 }
3734
3735 /* Do IPv4 OS Detection */
3736 if (ip4_targets.size() > 0)
3737 res4 = this->os_scan_ipv4(ip4_targets);
3738
3739 /* Do IPv6 OS Detection */
3740 if (ip6_targets.size() > 0)
3741 res6 = this->os_scan_ipv6(ip6_targets);
3742
3743 /* If both scans were successful, return OK */
3744 if (res4 == OP_SUCCESS && res6 == OP_SUCCESS)
3745 return OP_SUCCESS;
3746 else
3747 return OP_FAILURE;
3748 }
3749