1 
2 /***************************************************************************
3  * Target.cc -- The Target class encapsulates much of the information Nmap *
4  * has about a host.  Results (such as ping, OS scan, etc) are stored in   *
5  * this class as they are determined.                                      *
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: Target.cc 38078 2020-10-02 16:12:22Z dmiller $ */
65 
66 #ifdef WIN32
67 #include "nmap_winconfig.h"
68 #endif
69 
70 #include "Target.h"
71 #include "FingerPrintResults.h" /* for ~FingerPrintResults() */
72 #include <dnet.h>
73 #include "nbase.h"
74 #include "NmapOps.h"
75 #include "nmap.h"
76 #include "nmap_error.h"
77 
78 extern NmapOps o;
79 
Target()80 Target::Target() {
81   Initialize();
82 }
83 
Initialize()84 void Target::Initialize() {
85   hostname = NULL;
86   targetname = NULL;
87   memset(&seq, 0, sizeof(seq));
88   distance = -1;
89   distance_calculation_method = DIST_METHOD_NONE;
90   FPR = NULL;
91   osscan_flag = OS_NOTPERF;
92   weird_responses = flags = 0;
93   traceroute_probespec.type = PS_NONE;
94   memset(&to, 0, sizeof(to));
95   memset(&targetsock, 0, sizeof(targetsock));
96   memset(&sourcesock, 0, sizeof(sourcesock));
97   memset(&nexthopsock, 0, sizeof(nexthopsock));
98   targetsocklen = sourcesocklen = nexthopsocklen = 0;
99   directly_connected = -1;
100   targetipstring[0] = '\0';
101   sourceipstring[0] = '\0';
102   nameIPBuf = NULL;
103   memset(&MACaddress, 0, sizeof(MACaddress));
104   memset(&SrcMACaddress, 0, sizeof(SrcMACaddress));
105   memset(&NextHopMACaddress, 0, sizeof(NextHopMACaddress));
106   MACaddress_set = SrcMACaddress_set = NextHopMACaddress_set = false;
107   htn.msecs_used = 0;
108   htn.toclock_running = false;
109   htn.host_start = htn.host_end = 0;
110   interface_type = devt_other;
111   devname[0] = '\0';
112   devfullname[0] = '\0';
113   mtu = 0;
114   state_reason_init(&reason);
115   memset(&pingprobe, 0, sizeof(pingprobe));
116   pingprobe_state = PORT_UNKNOWN;
117 }
118 
119 
deviceName() const120 const char * Target::deviceName() const {
121         return (devname[0] != '\0')? devname : NULL;
122 }
123 
deviceFullName() const124 const char * Target::deviceFullName() const {
125         return (devfullname[0] != '\0')? devfullname : NULL;
126 }
127 
Recycle()128 void Target::Recycle() {
129   FreeInternal();
130   Initialize();
131 }
132 
~Target()133 Target::~Target() {
134   FreeInternal();
135 #ifndef NOLUA
136   while (!scriptResults.empty()) {
137     scriptResults.front().clear();
138     scriptResults.pop_front();
139   }
140 #endif
141 }
142 
FreeInternal()143 void Target::FreeInternal() {
144   /* Free the DNS name if we resolved one */
145   if (hostname)
146     free(hostname);
147 
148   if (targetname)
149     free(targetname);
150 
151   if (nameIPBuf) {
152     free(nameIPBuf);
153     nameIPBuf = NULL;
154   }
155 
156   if (FPR) delete FPR;
157 }
158 
159 /*  Creates a "presentation" formatted string out of the IPv4/IPv6 address.
160     Called when the IP changes */
GenerateTargetIPString()161 void Target::GenerateTargetIPString() {
162   struct sockaddr_in *sin = (struct sockaddr_in *) &targetsock;
163 #if HAVE_IPV6
164   struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &targetsock;
165 #endif
166 
167   if (inet_ntop(sin->sin_family, (sin->sin_family == AF_INET)?
168                 (char *) &sin->sin_addr :
169 #if HAVE_IPV6
170                 (char *) &sin6->sin6_addr,
171 #else
172                 (char *) NULL,
173 #endif
174                 targetipstring, sizeof(targetipstring)) == NULL) {
175     fatal("Failed to convert target address to presentation format!?!  Error: %s", strerror(socket_errno()));
176   }
177 }
178 
179 /*  Creates a "presentation" formatted string out of the IPv4/IPv6 address.
180     Called when the IP changes */
GenerateSourceIPString()181 void Target::GenerateSourceIPString() {
182   struct sockaddr_in *sin = (struct sockaddr_in *) &sourcesock;
183 #if HAVE_IPV6
184   struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &sourcesock;
185 #endif
186 
187   if (inet_ntop(sin->sin_family, (sin->sin_family == AF_INET)?
188                 (char *) &sin->sin_addr :
189 #if HAVE_IPV6
190                 (char *) &sin6->sin6_addr,
191 #else
192                 (char *) NULL,
193 #endif
194                 sourceipstring, sizeof(sourceipstring)) == NULL) {
195     fatal("Failed to convert source address to presentation format!?!  Error: %s", strerror(socket_errno()));
196   }
197 }
198 
199 /* Returns the address family of the destination address. */
af() const200 int Target::af() const {
201   return targetsock.ss_family;
202 }
203 
204 /* Fills a sockaddr_storage with the AF_INET or AF_INET6 address
205      information of the target.  This is a preferred way to get the
206      address since it is portable for IPv6 hosts.  Returns 0 for
207      success. ss_len must be provided.  It is not examined, but is set
208      to the size of the sockaddr copied in. */
TargetSockAddr(struct sockaddr_storage * ss,size_t * ss_len) const209 int Target::TargetSockAddr(struct sockaddr_storage *ss, size_t *ss_len) const {
210   assert(ss);
211   assert(ss_len);
212   if (targetsocklen <= 0)
213     return 1;
214   assert(targetsocklen <= sizeof(*ss));
215   memcpy(ss, &targetsock, targetsocklen);
216   *ss_len = targetsocklen;
217   return 0;
218 }
219 
TargetSockAddr() const220 const struct sockaddr_storage *Target::TargetSockAddr() const {
221   return &targetsock;
222 }
223 
224 /* Note that it is OK to pass in a sockaddr_in or sockaddr_in6 casted
225      to sockaddr_storage */
setTargetSockAddr(const struct sockaddr_storage * ss,size_t ss_len)226 void Target::setTargetSockAddr(const struct sockaddr_storage *ss, size_t ss_len) {
227 
228   assert(ss_len > 0 && ss_len <= sizeof(*ss));
229   if (targetsocklen > 0) {
230     /* We had an old target sock, so we better blow away the hostname as
231        this one may be new. */
232     setHostName(NULL);
233     setTargetName(NULL);
234   }
235   memcpy(&targetsock, ss, ss_len);
236   targetsocklen = ss_len;
237   GenerateTargetIPString();
238   /* The ports array needs to know a name too */
239   ports.setIdStr(targetipstr());
240 }
241 
242 // Returns IPv4 host address or {0} if unavailable.
v4host() const243 struct in_addr Target::v4host() const {
244   const struct in_addr *addy = v4hostip();
245   struct in_addr in;
246   if (addy) return *addy;
247   in.s_addr = 0;
248   return in;
249 }
250 
251 // Returns IPv4 host address or NULL if unavailable.
v4hostip() const252 const struct in_addr *Target::v4hostip() const {
253   struct sockaddr_in *sin = (struct sockaddr_in *) &targetsock;
254   if (sin->sin_family == AF_INET) {
255     return &(sin->sin_addr);
256   }
257   return NULL;
258 }
259 
v6hostip() const260 const struct in6_addr *Target::v6hostip() const {
261   struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &targetsock;
262   if (sin6->sin6_family == AF_INET6) {
263     return &(sin6->sin6_addr);
264   }
265   return NULL;
266 }
267 
268  /* The source address used to reach the target */
SourceSockAddr(struct sockaddr_storage * ss,size_t * ss_len) const269 int Target::SourceSockAddr(struct sockaddr_storage *ss, size_t *ss_len) const {
270   if (sourcesocklen <= 0)
271     return 1;
272   assert(sourcesocklen <= sizeof(*ss));
273   if (ss)
274     memcpy(ss, &sourcesock, sourcesocklen);
275   if (ss_len)
276     *ss_len = sourcesocklen;
277   return 0;
278 }
279 
SourceSockAddr() const280 const struct sockaddr_storage *Target::SourceSockAddr() const {
281   return &sourcesock;
282 }
283 
284 /* Note that it is OK to pass in a sockaddr_in or sockaddr_in6 casted
285      to sockaddr_storage */
setSourceSockAddr(const struct sockaddr_storage * ss,size_t ss_len)286 void Target::setSourceSockAddr(const struct sockaddr_storage *ss, size_t ss_len) {
287   assert(ss_len > 0 && ss_len <= sizeof(*ss));
288   memcpy(&sourcesock, ss, ss_len);
289   sourcesocklen = ss_len;
290   GenerateSourceIPString();
291 }
292 
293 // Returns IPv4 host address or {0} if unavailable.
source() const294 struct sockaddr_storage Target::source() const {
295   return sourcesock;
296 }
297 
298 // Returns IPv4 host address or NULL if unavailable.
v4sourceip() const299 const struct in_addr *Target::v4sourceip() const {
300   struct sockaddr_in *sin = (struct sockaddr_in *) &sourcesock;
301   if (sin->sin_family == AF_INET) {
302     return &(sin->sin_addr);
303   }
304   return NULL;
305 }
306 
307 // Returns IPv6 host address or NULL if unavailable.
v6sourceip() const308 const struct in6_addr *Target::v6sourceip() const {
309   struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &sourcesock;
310   if (sin6->sin6_family == AF_INET6) {
311     return &(sin6->sin6_addr);
312   }
313   return NULL;
314 }
315 
316   /* You can set to NULL to erase a name or if it failed to resolve -- or
317      just don't call this if it fails to resolve */
setHostName(const char * name)318 void Target::setHostName(const char *name) {
319   char *p;
320   if (hostname) {
321     free(hostname);
322     hostname = NULL;
323   }
324   if (name) {
325     p = hostname = strdup(name);
326     while (*p) {
327       // I think only a-z A-Z 0-9 . and - are allowed, but I'll be a little more
328       // generous.
329       if (!isalnum((int) (unsigned char) *p) && !strchr(".-+=:_~*", *p)) {
330         log_write(LOG_STDOUT, "Illegal character(s) in hostname -- replacing with '*'\n");
331         *p = '*';
332       }
333       p++;
334     }
335   }
336 }
337 
setTargetName(const char * name)338 void Target::setTargetName(const char *name) {
339   if (targetname) {
340     free(targetname);
341     targetname = NULL;
342   }
343   if (name) {
344     targetname = strdup(name);
345   }
346 }
347 
348  /* Generates a printable string consisting of the host's IP
349      address and hostname (if available).  Eg "www.insecure.org
350      (64.71.184.53)" or "fe80::202:e3ff:fe14:1102".  The name is
351      written into the buffer provided, which is also returned.  Results
352      that do not fit in buflen will be truncated. */
NameIP(char * buf,size_t buflen) const353 const char *Target::NameIP(char *buf, size_t buflen) const {
354   assert(buf);
355   assert(buflen > 8);
356   if (targetname)
357     Snprintf(buf, buflen, "%s (%s)", targetname, targetipstring);
358   else if (hostname)
359     Snprintf(buf, buflen, "%s (%s)", hostname, targetipstring);
360   else
361     Strncpy(buf, targetipstring, buflen);
362   return buf;
363 }
364 
365 /* This next version returns a static buffer -- so no concurrency */
NameIP() const366 const char *Target::NameIP() const {
367   /* Add 3 characters for the hostname and IP string, hence we allocate
368     (FQDN_LEN + INET6_ADDRSTRLEN + 4) octets, with octet for the null terminator */
369   if (!nameIPBuf) nameIPBuf = (char *) safe_malloc(FQDN_LEN + INET6_ADDRSTRLEN + 4);
370   return NameIP(nameIPBuf, FQDN_LEN + INET6_ADDRSTRLEN + 4);
371 }
372 
373   /* Returns the next hop for sending packets to this host.  Returns true if
374      next_hop was filled in.  It might be false, for example, if
375      next_hop has never been set */
nextHop(struct sockaddr_storage * next_hop,size_t * next_hop_len)376 bool Target::nextHop(struct sockaddr_storage *next_hop, size_t *next_hop_len) {
377   if (nexthopsocklen <= 0)
378     return false;
379   assert(nexthopsocklen <= sizeof(*next_hop));
380   if (next_hop)
381     memcpy(next_hop, &nexthopsock, nexthopsocklen);
382   if (next_hop_len)
383     *next_hop_len = nexthopsocklen;
384   return true;
385 }
386 
387   /* If the host is directly connected on a network, set and retrieve
388      that information here.  directlyConnected() will abort if it hasn't
389      been set yet.  */
setDirectlyConnected(bool connected)390 void Target::setDirectlyConnected(bool connected) {
391   directly_connected = connected? 1 : 0;
392 }
393 
directlyConnectedOrUnset() const394 int Target::directlyConnectedOrUnset() const {
395     return directly_connected;
396 }
397 
directlyConnected() const398 bool Target::directlyConnected() const {
399   assert(directly_connected == 0 || directly_connected == 1);
400   return directly_connected;
401 }
402 
403 /* Note that it is OK to pass in a sockaddr_in or sockaddr_in6 casted
404      to sockaddr_storage */
setNextHop(struct sockaddr_storage * next_hop,size_t next_hop_len)405 void Target::setNextHop(struct sockaddr_storage *next_hop, size_t next_hop_len) {
406   assert(next_hop_len > 0 && next_hop_len <= sizeof(nexthopsock));
407   memcpy(&nexthopsock, next_hop, next_hop_len);
408   nexthopsocklen = next_hop_len;
409 }
410 
411 /* Set MTU (to correspond with devname) */
setMTU(int devmtu)412 void Target::setMTU(int devmtu) {
413   mtu = devmtu;
414 }
415 
416 /* Get MTU (to correspond with devname) */
MTU(void)417 int Target::MTU(void) {
418   return mtu;
419 }
420 
421   /* Starts the timeout clock for the host running (e.g. you are
422      beginning a scan).  If you do not have the current time handy,
423      you can pass in NULL.  When done, call stopTimeOutClock (it will
424      also automatically be stopped of timedOut() returns true) */
startTimeOutClock(const struct timeval * now)425 void Target::startTimeOutClock(const struct timeval *now) {
426   assert(htn.toclock_running == false);
427   htn.toclock_running = true;
428   if (now) htn.toclock_start = *now;
429   else gettimeofday(&htn.toclock_start, NULL);
430   if (!htn.host_start) htn.host_start = htn.toclock_start.tv_sec;
431 }
432   /* The complement to startTimeOutClock. */
stopTimeOutClock(const struct timeval * now)433 void Target::stopTimeOutClock(const struct timeval *now) {
434   struct timeval tv;
435   assert(htn.toclock_running == true);
436   htn.toclock_running = false;
437   if (now) tv = *now;
438   else gettimeofday(&tv, NULL);
439   htn.msecs_used += TIMEVAL_MSEC_SUBTRACT(tv, htn.toclock_start);
440   htn.host_end = tv.tv_sec;
441 }
442   /* Returns whether the host is timedout.  If the timeoutclock is
443      running, counts elapsed time for that.  Pass NULL if you don't have the
444      current time handy.  You might as well also pass NULL if the
445      clock is not running, as the func won't need the time. */
timedOut(const struct timeval * now)446 bool Target::timedOut(const struct timeval *now) {
447   unsigned long used = htn.msecs_used;
448   struct timeval tv;
449 
450   if (!o.host_timeout) return false;
451   if (htn.toclock_running) {
452     if (now) tv = *now;
453     else gettimeofday(&tv, NULL);
454     used += TIMEVAL_MSEC_SUBTRACT(tv, htn.toclock_start);
455   }
456 
457   return (used > o.host_timeout);
458 }
459 
460 
461 /* Returns zero if MAC address set successfully */
setMACAddress(const u8 * addy)462 int Target::setMACAddress(const u8 *addy) {
463   if (!addy) return 1;
464   memcpy(MACaddress, addy, 6);
465   MACaddress_set = 1;
466   return 0;
467 }
468 
setSrcMACAddress(const u8 * addy)469 int Target::setSrcMACAddress(const u8 *addy) {
470   if (!addy) return 1;
471   memcpy(SrcMACaddress, addy, 6);
472   SrcMACaddress_set = 1;
473   return 0;
474 }
475 
setNextHopMACAddress(const u8 * addy)476 int Target::setNextHopMACAddress(const u8 *addy) {
477   if (!addy) return 1;
478   memcpy(NextHopMACaddress, addy, 6);
479   NextHopMACaddress_set = 1;
480   return 0;
481 }
482 
483 /* Set the device names so that they can be returned by deviceName()
484    and deviceFullName().  The normal name may not include alias
485    qualifier, while the full name may include it (e.g. "eth1:1").  If
486    these are non-null, they will overwrite the stored version */
setDeviceNames(const char * name,const char * fullname)487 void Target::setDeviceNames(const char *name, const char *fullname) {
488   if (name) Strncpy(devname, name, sizeof(devname));
489   if (fullname) Strncpy(devfullname, fullname, sizeof(devfullname));
490 }
491 
492 /* Returns the 6-byte long MAC address, or NULL if none has been set */
MACAddress() const493 const u8 *Target::MACAddress() const {
494   return (MACaddress_set)? MACaddress : NULL;
495 }
496 
SrcMACAddress() const497 const u8 *Target::SrcMACAddress() const {
498   return (SrcMACaddress_set)? SrcMACaddress : NULL;
499 }
500 
NextHopMACAddress() const501 const u8 *Target::NextHopMACAddress() const {
502   return (NextHopMACaddress_set)? NextHopMACaddress : NULL;
503 }
504 
osscanPerformed(void)505 int Target::osscanPerformed(void) {
506         return osscan_flag;
507 }
508 
osscanSetFlag(int flag)509 void Target::osscanSetFlag(int flag) {
510         if(osscan_flag == OS_PERF_UNREL)
511                 return;
512         else
513                 osscan_flag = flag;
514 }
515