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(&eth, 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(&eth, 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(&eth, 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, &timestamp, 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