1 
2 /***************************************************************************
3  * output.cc -- Handles the Nmap output system.  This currently involves   *
4  * console-style human readable output, XML output, Script |<iddi3         *
5  * output, and the legacy grepable output (used to be called "machine      *
6  * readable").  I expect that future output forms (such as HTML) may be    *
7  * created by a different program, library, or script using the XML        *
8  * output.                                                                 *
9  *                                                                         *
10  ***********************IMPORTANT NMAP LICENSE TERMS************************
11  *                                                                         *
12  * The Nmap Security Scanner is (C) 1996-2020 Insecure.Com LLC ("The Nmap  *
13  * Project"). Nmap is also a registered trademark of the Nmap Project.     *
14  *                                                                         *
15  * This program is distributed under the terms of the Nmap Public Source   *
16  * License (NPSL). The exact license text applying to a particular Nmap    *
17  * release or source code control revision is contained in the LICENSE     *
18  * file distributed with that version of Nmap or source code control       *
19  * revision. More Nmap copyright/legal information is available from       *
20  * https://nmap.org/book/man-legal.html, and further information on the    *
21  * NPSL license itself can be found at https://nmap.org/npsl. This header  *
22  * summarizes some key points from the Nmap license, but is no substitute  *
23  * for the actual license text.                                            *
24  *                                                                         *
25  * Nmap is generally free for end users to download and use themselves,    *
26  * including commercial use. It is available from https://nmap.org.        *
27  *                                                                         *
28  * The Nmap license generally prohibits companies from using and           *
29  * redistributing Nmap in commercial products, but we sell a special Nmap  *
30  * OEM Edition with a more permissive license and special features for     *
31  * this purpose. See https://nmap.org/oem                                  *
32  *                                                                         *
33  * If you have received a written Nmap license agreement or contract       *
34  * stating terms other than these (such as an Nmap OEM license), you may   *
35  * choose to use and redistribute Nmap under those terms instead.          *
36  *                                                                         *
37  * The official Nmap Windows builds include the Npcap software             *
38  * (https://npcap.org) for packet capture and transmission. It is under    *
39  * separate license terms which forbid redistribution without special      *
40  * permission. So the official Nmap Windows builds may not be              *
41  * redistributed without special permission (such as an Nmap OEM           *
42  * license).                                                               *
43  *                                                                         *
44  * Source is provided to this software because we believe users have a     *
45  * right to know exactly what a program is going to do before they run it. *
46  * This also allows you to audit the software for security holes.          *
47  *                                                                         *
48  * Source code also allows you to port Nmap to new platforms, fix bugs,    *
49  * and add new features.  You are highly encouraged to submit your         *
50  * changes as a Github PR or by email to the dev@nmap.org mailing list     *
51  * for possible incorporation into the main distribution. Unless you       *
52  * specify otherwise, it is understood that you are offering us very       *
53  * broad rights to use your submissions as described in the Nmap Public    *
54  * Source License Contributor Agreement. This is important because we      *
55  * fund the project by selling licenses with various terms, and also       *
56  * because the inability to relicense code has caused devastating          *
57  * problems for other Free Software projects (such as KDE and NASM).       *
58  *                                                                         *
59  * The free version of Nmap is distributed in the hope that it will be     *
60  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of  *
61  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Warranties,        *
62  * indemnification and commercial support are all available through the    *
63  * Npcap OEM program--see https://nmap.org/oem.                            *
64  *                                                                         *
65  ***************************************************************************/
66 
67 /* $Id: output.cc 38078 2020-10-02 16:12:22Z dmiller $ */
68 
69 #include "nmap.h"
70 #include "output.h"
71 #include "osscan.h"
72 #include "osscan2.h"
73 #include "NmapOps.h"
74 #include "NmapOutputTable.h"
75 #include "MACLookup.h"
76 #include "portreasons.h"
77 #include "protocols.h"
78 #include "FingerPrintResults.h"
79 #include "tcpip.h"
80 #include "Target.h"
81 #include "nmap_error.h"
82 #include "utils.h"
83 #include "xml.h"
84 #include "nbase.h"
85 #include "libnetutil/netutil.h"
86 #include <nsock.h>
87 
88 #include <math.h>
89 
90 #include <set>
91 #include <vector>
92 #include <list>
93 #include <sys/param.h>
94 #include <sstream>
95 
96 extern NmapOps o;
97 static const char *logtypes[LOG_NUM_FILES] = LOG_NAMES;
98 
99 /* Used in creating skript kiddie style output.  |<-R4d! */
skid_output(char * s)100 static void skid_output(char *s) {
101   int i;
102   for (i = 0; s[i]; i++)
103     /* We need a 50/50 chance here, use a random number */
104     if ((get_random_u8() & 0x01) == 0)
105       /* Substitutions commented out are not known to me, but maybe look nice */
106       switch (s[i]) {
107       case 'A':
108         s[i] = '4';
109         break;
110         /*    case 'B': s[i]='8'; break;
111            case 'b': s[i]='6'; break;
112            case 'c': s[i]='k'; break;
113            case 'C': s[i]='K'; break; */
114       case 'e':
115       case 'E':
116         s[i] = '3';
117         break;
118       case 'i':
119       case 'I':
120         s[i] = "!|1"[get_random_u8() % 3];
121         break;
122         /*      case 'k': s[i]='c'; break;
123            case 'K': s[i]='C'; break; */
124       case 'o':
125       case 'O':
126         s[i] = '0';
127         break;
128       case 's':
129       case 'S':
130         if (s[i + 1] && !isalnum((int) (unsigned char) s[i + 1]))
131           s[i] = 'z';
132         else
133           s[i] = '$';
134         break;
135       case 'z':
136         s[i] = 's';
137         break;
138       case 'Z':
139         s[i] = 'S';
140         break;
141     } else {
142       if (s[i] >= 'A' && s[i] <= 'Z' && (get_random_u8() % 3 == 0)) {
143         s[i] += 'a' - 'A';      /* 1/3 chance of lower-case */
144       } else if (s[i] >= 'a' && s[i] <= 'z' && (get_random_u8() % 3 == 0)) {
145         s[i] -= 'a' - 'A';      /* 1/3 chance of upper-case */
146       }
147     }
148 }
149 
150 /* Remove all "\nSF:" from fingerprints */
servicefp_sf_remove(const char * str)151 static char *servicefp_sf_remove(const char *str) {
152   char *temp = (char *) safe_malloc(strlen(str) + 1);
153   char *dst = temp, *src = (char *) str;
154   char *ampptr = 0;
155 
156   while (*src) {
157     if (strncmp(src, "\nSF:", 4) == 0) {
158       src += 4;
159       continue;
160     }
161     /* Needed so "&something;" is not truncated midway */
162     if (*src == '&') {
163       ampptr = dst;
164     } else if (*src == ';') {
165       ampptr = 0;
166     }
167     *dst++ = *src++;
168   }
169   if (ampptr != 0) {
170     *ampptr = '\0';
171   } else {
172     *dst = '\0';
173   }
174   return temp;
175 }
176 
177 // Prints an XML <service> element for the information given in
178 // serviceDeduction.  This function should only be called if ether
179 // the service name or the service fingerprint is non-null.
print_xml_service(const struct serviceDeductions * sd)180 static void print_xml_service(const struct serviceDeductions *sd) {
181   xml_open_start_tag("service");
182 
183   xml_attribute("name", "%s", sd->name ? sd->name : "unknown");
184   if (sd->product)
185     xml_attribute("product", "%s", sd->product);
186   if (sd->version)
187     xml_attribute("version", "%s", sd->version);
188   if (sd->extrainfo)
189     xml_attribute("extrainfo", "%s", sd->extrainfo);
190   if (sd->hostname)
191     xml_attribute("hostname", "%s", sd->hostname);
192   if (sd->ostype)
193     xml_attribute("ostype", "%s", sd->ostype);
194   if (sd->devicetype)
195     xml_attribute("devicetype", "%s", sd->devicetype);
196   if (sd->service_fp) {
197     char *servicefp = servicefp_sf_remove(sd->service_fp);
198     xml_attribute("servicefp", "%s", servicefp);
199     free(servicefp);
200   }
201 
202   if (sd->service_tunnel == SERVICE_TUNNEL_SSL)
203     xml_attribute("tunnel", "ssl");
204   xml_attribute("method", "%s", (sd->dtype == SERVICE_DETECTION_TABLE) ? "table" : "probed");
205   xml_attribute("conf", "%i", sd->name_confidence);
206 
207   if (sd->cpe.empty()) {
208     xml_close_empty_tag();
209   } else {
210     unsigned int i;
211 
212     xml_close_start_tag();
213     for (i = 0; i < sd->cpe.size(); i++) {
214       xml_start_tag("cpe");
215       xml_write_escaped("%s", sd->cpe[i]);
216       xml_end_tag();
217     }
218     xml_end_tag();
219   }
220 }
221 
222 #ifdef WIN32
223 /* Show a fatal error explaining that an interface is not Ethernet and won't
224    work on Windows. Do nothing if --send-ip (PACKET_SEND_IP_STRONG) was used. */
win32_fatal_raw_sockets(const char * devname)225 void win32_fatal_raw_sockets(const char *devname) {
226   if ((o.sendpref & PACKET_SEND_IP_STRONG) != 0)
227     return;
228 
229   if (devname != NULL) {
230     fatal("Only ethernet devices can be used for raw scans on Windows, and\n"
231           "\"%s\" is not an ethernet device. Use the --unprivileged option\n"
232           "for this scan.", devname);
233   } else {
234     fatal("Only ethernet devices can be used for raw scans on Windows. Use\n"
235           "the --unprivileged option for this scan.");
236   }
237 }
238 
239 /* Display the mapping from libdnet interface names (like "eth0") to WinPcap
240    interface names (like "\Device\NPF_{...}"). This is the same mapping used by
241    eth_open and so can help diagnose connection problems.  Additionally display
242    WinPcap interface names that are not mapped to by any libdnet name, in other
243    words the names of interfaces Nmap has no way of using.*/
print_iflist_pcap_mapping(const struct interface_info * iflist,int numifs)244 static void print_iflist_pcap_mapping(const struct interface_info *iflist,
245                                       int numifs) {
246   pcap_if_t *pcap_ifs = NULL;
247   char errbuf[PCAP_ERRBUF_SIZE];
248   std::list<const pcap_if_t *> leftover_pcap_ifs;
249   std::list<const pcap_if_t *>::iterator leftover_p;
250   int i;
251 
252   /* Build a list of "leftover" libpcap interfaces. Initially it contains all
253      the interfaces. */
254   if (o.have_pcap) {
255     if (pcap_findalldevs(&pcap_ifs, errbuf) == -1) {
256       fatal("pcap_findalldevs(): Cannot retrieve pcap interfaces: %s", errbuf);
257     }
258     for (const pcap_if_t *p = pcap_ifs; p != NULL; p = p->next)
259       leftover_pcap_ifs.push_front(p);
260   }
261 
262   if (numifs > 0 || !leftover_pcap_ifs.empty()) {
263     NmapOutputTable Tbl(1 + numifs + leftover_pcap_ifs.size(), 2);
264 
265     Tbl.addItem(0, 0, false, "DEV");
266     Tbl.addItem(0, 1, false, "WINDEVICE");
267 
268     /* Show the libdnet names and what they map to. */
269     for (i = 0; i < numifs; i++) {
270       char pcap_name[1024];
271 
272       if (DnetName2PcapName(iflist[i].devname, pcap_name, sizeof(pcap_name))) {
273         /* We got a name. Remove it from the list of leftovers. */
274         std::list<const pcap_if_t *>::iterator next;
275         for (leftover_p = leftover_pcap_ifs.begin();
276              leftover_p != leftover_pcap_ifs.end(); leftover_p = next) {
277           next = leftover_p;
278           next++;
279           if (strcmp((*leftover_p)->name, pcap_name) == 0)
280             leftover_pcap_ifs.erase(leftover_p);
281         }
282       } else {
283         Strncpy(pcap_name, "<none>", sizeof(pcap_name));
284       }
285 
286       Tbl.addItem(i + 1, 0, false, iflist[i].devname);
287       Tbl.addItem(i + 1, 1, true, pcap_name);
288     }
289 
290     /* Show the "leftover" libpcap interface names (those without a libdnet
291        name that maps to them). */
292     for (leftover_p = leftover_pcap_ifs.begin();
293          leftover_p != leftover_pcap_ifs.end();
294          leftover_p++) {
295       Tbl.addItem(i + 1, 0, false, "<none>");
296       Tbl.addItem(i + 1, 1, false, (*leftover_p)->name);
297       i++;
298     }
299 
300     log_write(LOG_PLAIN, "%s\n", Tbl.printableTable(NULL));
301     log_flush_all();
302   }
303 
304   if (pcap_ifs) {
305     pcap_freealldevs(pcap_ifs);
306   }
307 }
308 #endif
309 
310 /* Print a detailed list of Nmap interfaces and routes to
311    normal/skiddy/stdout output */
print_iflist(void)312 int print_iflist(void) {
313   int numifs = 0, numroutes = 0;
314   struct interface_info *iflist;
315   struct sys_route *routes;
316   NmapOutputTable *Tbl = NULL;
317   char errstr[256];
318   const char *address = NULL;
319   errstr[0]='\0';
320 
321   iflist = getinterfaces(&numifs, errstr, sizeof(errstr));
322 
323   int i;
324   /* First let's handle interfaces ... */
325   if (iflist==NULL || numifs<=0) {
326     log_write(LOG_PLAIN, "INTERFACES: NONE FOUND(!)\n");
327     if (o.debugging)
328       log_write(LOG_STDOUT, "Reason: %s\n", errstr);
329   } else {
330     int devcol = 0, shortdevcol = 1, ipcol = 2, typecol = 3, upcol = 4, mtucol = 5, maccol = 6;
331     Tbl = new NmapOutputTable(numifs + 1, 7);
332     Tbl->addItem(0, devcol, false, "DEV", 3);
333     Tbl->addItem(0, shortdevcol, false, "(SHORT)", 7);
334     Tbl->addItem(0, ipcol, false, "IP/MASK", 7);
335     Tbl->addItem(0, typecol, false, "TYPE", 4);
336     Tbl->addItem(0, upcol, false, "UP", 2);
337     Tbl->addItem(0, mtucol, false, "MTU", 3);
338     Tbl->addItem(0, maccol, false, "MAC", 3);
339     for (i = 0; i < numifs; i++) {
340       Tbl->addItem(i + 1, devcol, false, iflist[i].devfullname);
341       Tbl->addItemFormatted(i + 1, shortdevcol, false, "(%s)",
342                             iflist[i].devname);
343       address = inet_ntop_ez(&(iflist[i].addr), sizeof(iflist[i].addr));
344       Tbl->addItemFormatted(i + 1, ipcol, false, "%s/%d",
345                             address == NULL ? "(none)" : address,
346                             iflist[i].netmask_bits);
347       if (iflist[i].device_type == devt_ethernet) {
348         Tbl->addItem(i + 1, typecol, false, "ethernet");
349         Tbl->addItemFormatted(i + 1, maccol, false,
350                               "%02X:%02X:%02X:%02X:%02X:%02X",
351                               iflist[i].mac[0], iflist[i].mac[1],
352                               iflist[i].mac[2], iflist[i].mac[3],
353                               iflist[i].mac[4], iflist[i].mac[5]);
354       } else if (iflist[i].device_type == devt_loopback)
355         Tbl->addItem(i + 1, typecol, false, "loopback");
356       else if (iflist[i].device_type == devt_p2p)
357         Tbl->addItem(i + 1, typecol, false, "point2point");
358       else
359         Tbl->addItem(i + 1, typecol, false, "other");
360       Tbl->addItem(i + 1, upcol, false,
361                    (iflist[i].device_up ? "up" : "down"));
362       Tbl->addItemFormatted(i + 1, mtucol, false, "%d", iflist[i].mtu);
363     }
364     log_write(LOG_PLAIN, "************************INTERFACES************************\n");
365     log_write(LOG_PLAIN, "%s\n", Tbl->printableTable(NULL));
366     log_flush_all();
367     delete Tbl;
368   }
369 
370 #ifdef WIN32
371   /* Print the libdnet->libpcap interface name mapping. */
372   print_iflist_pcap_mapping(iflist, numifs);
373 #endif
374 
375   /* OK -- time to handle routes */
376   errstr[0]='\0';
377   routes = getsysroutes(&numroutes, errstr, sizeof(errstr));
378   u16 nbits;
379   if (routes==NULL || numroutes<= 0) {
380     log_write(LOG_PLAIN, "ROUTES: NONE FOUND(!)\n");
381     if (o.debugging)
382       log_write(LOG_STDOUT, "Reason: %s\n", errstr);
383   } else {
384     int dstcol = 0, devcol = 1, metcol = 2, gwcol = 3;
385     Tbl = new NmapOutputTable(numroutes + 1, 4);
386     Tbl->addItem(0, dstcol, false, "DST/MASK", 8);
387     Tbl->addItem(0, devcol, false, "DEV", 3);
388     Tbl->addItem(0, metcol, false, "METRIC", 6);
389     Tbl->addItem(0, gwcol, false, "GATEWAY", 7);
390     for (i = 0; i < numroutes; i++) {
391       nbits = routes[i].netmask_bits;
392       Tbl->addItemFormatted(i + 1, dstcol, false, "%s/%d",
393       	inet_ntop_ez(&routes[i].dest, sizeof(routes[i].dest)), nbits);
394       Tbl->addItem(i + 1, devcol, false, routes[i].device->devfullname);
395       Tbl->addItemFormatted(i + 1, metcol, false, "%d", routes[i].metric);
396       if (!sockaddr_equal_zero(&routes[i].gw))
397         Tbl->addItem(i + 1, gwcol, true, inet_ntop_ez(&routes[i].gw, sizeof(routes[i].gw)));
398     }
399     log_write(LOG_PLAIN, "**************************ROUTES**************************\n");
400     log_write(LOG_PLAIN, "%s\n", Tbl->printableTable(NULL));
401     log_flush_all();
402     delete Tbl;
403   }
404   return 0;
405 }
406 
407 #ifndef NOLUA
408 /* Escape control characters to make a string safe to display on a terminal. */
escape_for_screen(const std::string s)409 static std::string escape_for_screen(const std::string s) {
410   std::string r;
411 
412   for (unsigned int i = 0; i < s.size(); i++) {
413     char buf[5];
414     unsigned char c = s[i];
415     // Printable and some whitespace ok. "\r" not ok because it overwrites the line.
416     if (c == '\t' || c == '\n' || (0x20 <= c && c <= 0x7e)) {
417       r += c;
418     } else {
419       Snprintf(buf, sizeof(buf), "\\x%02X", c);
420       r += buf;
421     }
422   }
423 
424   return r;
425 }
426 
427 /* Do something to protect characters that can't appear in XML. This is not a
428    reversible transform, more a last-ditch effort to write readable XML with
429    characters that shouldn't be part of regular output anyway. The escaping that
430    xml_write_escaped is not enough; some characters are not allowed to appear in
431    XML, not even escaped. */
protect_xml(const std::string s)432 std::string protect_xml(const std::string s) {
433   std::string r;
434 
435   for (unsigned int i = 0; i < s.size(); i++) {
436     char buf[5];
437     unsigned char c = s[i];
438     // Printable and some whitespace ok.
439     if (c == '\t' || c == '\r' || c == '\n' || (0x20 <= c && c <= 0x7e)) {
440       r += c;
441     } else {
442       Snprintf(buf, sizeof(buf), "\\x%02X", c);
443       r += buf;
444     }
445   }
446 
447   return r;
448 }
449 
450 /* This is a helper function to determine the ordering of the script results
451    based on their id. */
scriptid_lessthan(const ScriptResult & a,const ScriptResult & b)452 static bool scriptid_lessthan(const ScriptResult &a, const ScriptResult &b) {
453   return strcmp(a.get_id(), b.get_id()) < 0;
454 }
455 
formatScriptOutput(const ScriptResult & sr)456 static char *formatScriptOutput(const ScriptResult &sr) {
457   std::vector<std::string> lines;
458 
459   std::string c_output;
460   const char *p, *q;
461   std::string result;
462   unsigned int i;
463 
464   c_output = escape_for_screen(sr.get_output_str());
465   if (c_output.empty())
466     return NULL;
467   p = c_output.c_str();
468 
469   while (*p != '\0') {
470     q = strchr(p, '\n');
471     if (q == NULL) {
472       lines.push_back(std::string(p));
473       break;
474     } else {
475       lines.push_back(std::string(p, q - p));
476       p = q + 1;
477     }
478   }
479 
480   if (lines.empty())
481     lines.push_back("");
482   for (i = 0; i < lines.size(); i++) {
483     if (i < lines.size() - 1)
484       result += "| ";
485     else
486       result += "|_";
487     if (i == 0)
488       result += std::string(sr.get_id()) + ": ";
489     result += lines[i];
490     if (i < lines.size() - 1)
491       result += "\n";
492   }
493 
494   return strdup(result.c_str());
495 }
496 #endif /* NOLUA */
497 
498 /* Prints the familiar Nmap tabular output showing the "interesting"
499    ports found on the machine.  It also handles the Machine/Grepable
500    output and the XML output.  It is pretty ugly -- in particular I
501    should write helper functions to handle the table creation */
printportoutput(Target * currenths,PortList * plist)502 void printportoutput(Target *currenths, PortList *plist) {
503   char protocol[MAX_IPPROTOSTRLEN + 1];
504   char portinfo[64];
505   char grepvers[256];
506   char *p;
507   const char *state;
508   char serviceinfo[64];
509   int i;
510   int first = 1;
511   struct protoent *proto;
512   Port *current;
513   Port port;
514   char hostname[1200];
515   struct serviceDeductions sd;
516   NmapOutputTable *Tbl = NULL;
517   int portcol = -1;             // port or IP protocol #
518   int statecol = -1;            // port/protocol state
519   int servicecol = -1;          // service or protocol name
520   int versioncol = -1;
521   int reasoncol = -1;
522   int colno = 0;
523   unsigned int rowno;
524   int numrows;
525   int numignoredports = plist->numIgnoredPorts();
526   int numports = plist->numPorts();
527 
528   std::vector<const char *> saved_servicefps;
529 
530   if (o.noportscan)
531     return;
532 
533   xml_start_tag("ports");
534   int prevstate = PORT_UNKNOWN;
535   int istate;
536 
537   while ((istate = plist->nextIgnoredState(prevstate)) != PORT_UNKNOWN) {
538     xml_open_start_tag("extraports");
539     xml_attribute("state", "%s", statenum2str(istate));
540     xml_attribute("count", "%d", plist->getStateCounts(istate));
541     xml_close_start_tag();
542     xml_newline();
543     print_xml_state_summary(plist, istate);
544     xml_end_tag();
545     xml_newline();
546     prevstate = istate;
547   }
548 
549   if (numignoredports == numports) {
550     if (numignoredports == 0) {
551       log_write(LOG_PLAIN, "0 ports scanned on %s\n",
552                 currenths->NameIP(hostname, sizeof(hostname)));
553     } else {
554       log_write(LOG_PLAIN, "%s %d scanned %s on %s %s ",
555                 (numignoredports == 1) ? "The" : "All", numignoredports,
556                 (numignoredports == 1) ? "port" : "ports",
557                 currenths->NameIP(hostname, sizeof(hostname)),
558                 (numignoredports == 1) ? "is" : "are");
559       if (plist->numIgnoredStates() == 1) {
560         log_write(LOG_PLAIN, "%s", statenum2str(plist->nextIgnoredState(PORT_UNKNOWN)));
561       } else {
562         prevstate = PORT_UNKNOWN;
563         while ((istate = plist->nextIgnoredState(prevstate)) != PORT_UNKNOWN) {
564           if (prevstate != PORT_UNKNOWN)
565             log_write(LOG_PLAIN, " or ");
566           log_write(LOG_PLAIN, "%s (%d)", statenum2str(istate),
567                     plist->getStateCounts(istate));
568           prevstate = istate;
569         }
570       }
571       if (o.reason)
572         print_state_summary(plist, STATE_REASON_EMPTY);
573       log_write(LOG_PLAIN, "\n");
574     }
575 
576     log_write(LOG_MACHINE, "Host: %s (%s)\tStatus: Up",
577               currenths->targetipstr(), currenths->HostName());
578     xml_end_tag(); /* ports */
579     xml_newline();
580     return;
581   }
582 
583   if ((o.verbose > 1 || o.debugging) && currenths->StartTime()) {
584     time_t tm_secs, tm_sece;
585     struct tm tm;
586     int err;
587     char tbufs[128];
588     tm_secs = currenths->StartTime();
589     tm_sece = currenths->EndTime();
590     err = n_localtime(&tm_secs, &tm);
591     if (err) {
592       error("Error in localtime: %s", strerror(err));
593       log_write(LOG_PLAIN, "Scanned for %lds\n",
594           (long) (tm_sece - tm_secs));
595     }
596     else {
597       if (strftime(tbufs, sizeof(tbufs), "%Y-%m-%d %H:%M:%S %Z", &tm) <= 0) {
598         error("Unable to properly format host start time");
599         log_write(LOG_PLAIN, "Scanned for %lds\n",
600             (long) (tm_sece - tm_secs));
601       }
602       else {
603         log_write(LOG_PLAIN, "Scanned at %s for %lds\n",
604             tbufs, (long) (tm_sece - tm_secs));
605       }
606     }
607   }
608   log_write(LOG_MACHINE, "Host: %s (%s)", currenths->targetipstr(),
609             currenths->HostName());
610 
611   /* Show line like:
612      Not shown: 3995 closed ports, 514 filtered ports
613      if appropriate (note that states are reverse-sorted by # of ports) */
614   prevstate = PORT_UNKNOWN;
615   while ((istate = plist->nextIgnoredState(prevstate)) != PORT_UNKNOWN) {
616     if (prevstate == PORT_UNKNOWN)
617       log_write(LOG_PLAIN, "Not shown: ");
618     else
619       log_write(LOG_PLAIN, ", ");
620     char desc[32];
621     if (o.ipprotscan)
622       Snprintf(desc, sizeof(desc),
623                (plist->getStateCounts(istate) ==
624                 1) ? "protocol" : "protocols");
625     else
626       Snprintf(desc, sizeof(desc),
627                (plist->getStateCounts(istate) == 1) ? "port" : "ports");
628     log_write(LOG_PLAIN, "%d %s %s", plist->getStateCounts(istate),
629               statenum2str(istate), desc);
630     prevstate = istate;
631   }
632 
633   log_write(LOG_PLAIN, "\n");
634 
635   if (o.reason)
636     print_state_summary(plist, STATE_REASON_FULL);
637 
638   /* OK, now it is time to deal with the service table ... */
639   colno = 0;
640   portcol = colno++;
641   statecol = colno++;
642   servicecol = colno++;
643   if (o.reason)
644     reasoncol = colno++;
645   if (o.servicescan)
646     versioncol = colno++;
647 
648   numrows = numports - numignoredports;
649 
650 #ifndef NOLUA
651   int scriptrows = 0;
652   if (plist->numscriptresults > 0)
653     scriptrows = plist->numscriptresults;
654   numrows += scriptrows;
655 #endif
656 
657   assert(numrows > 0);
658   numrows++; // The header counts as a row
659 
660   Tbl = new NmapOutputTable(numrows, colno);
661 
662   // Lets start with the headers
663   if (o.ipprotscan)
664     Tbl->addItem(0, portcol, false, "PROTOCOL", 8);
665   else
666     Tbl->addItem(0, portcol, false, "PORT", 4);
667   Tbl->addItem(0, statecol, false, "STATE", 5);
668   Tbl->addItem(0, servicecol, false, "SERVICE", 7);
669   if (versioncol > 0)
670     Tbl->addItem(0, versioncol, false, "VERSION", 7);
671   if (reasoncol > 0)
672     Tbl->addItem(0, reasoncol, false, "REASON", 6);
673 
674   log_write(LOG_MACHINE, "\t%s: ", (o.ipprotscan) ? "Protocols" : "Ports");
675 
676   rowno = 1;
677   if (o.ipprotscan) {
678     current = NULL;
679     while ((current = plist->nextPort(current, &port, IPPROTO_IP, 0)) != NULL) {
680       if (!plist->isIgnoredState(current->state)) {
681         if (!first)
682           log_write(LOG_MACHINE, ", ");
683         else
684           first = 0;
685         if (o.reason) {
686           if (current->reason.ttl)
687             Tbl->addItemFormatted(rowno, reasoncol, false, "%s ttl %d",
688                                 port_reason_str(current->reason), current->reason.ttl);
689           else
690             Tbl->addItem(rowno, reasoncol, true, port_reason_str(current->reason));
691         }
692         state = statenum2str(current->state);
693         proto = nmap_getprotbynum(current->portno);
694         Snprintf(portinfo, sizeof(portinfo), "%s", proto ? proto->p_name : "unknown");
695         Tbl->addItemFormatted(rowno, portcol, false, "%d", current->portno);
696         Tbl->addItem(rowno, statecol, true, state);
697         Tbl->addItem(rowno, servicecol, true, portinfo);
698         log_write(LOG_MACHINE, "%d/%s/%s/", current->portno, state,
699                   (proto) ? proto->p_name : "");
700         xml_open_start_tag("port");
701         xml_attribute("protocol", "ip");
702         xml_attribute("portid", "%d", current->portno);
703         xml_close_start_tag();
704         xml_open_start_tag("state");
705         xml_attribute("state", "%s", state);
706         xml_attribute("reason", "%s", reason_str(current->reason.reason_id, SINGULAR));
707         xml_attribute("reason_ttl", "%d", current->reason.ttl);
708         if (current->reason.ip_addr.sockaddr.sa_family != AF_UNSPEC) {
709           struct sockaddr_storage ss;
710           memcpy(&ss, &current->reason.ip_addr, sizeof(current->reason.ip_addr));
711           xml_attribute("reason_ip", "%s", inet_ntop_ez(&ss, sizeof(ss)));
712         }
713         xml_close_empty_tag();
714 
715         if (proto && proto->p_name && *proto->p_name) {
716           xml_newline();
717           xml_open_start_tag("service");
718           xml_attribute("name", "%s", proto->p_name);
719           xml_attribute("conf", "8");
720           xml_attribute("method", "table");
721           xml_close_empty_tag();
722         }
723         xml_end_tag(); /* port */
724         xml_newline();
725         rowno++;
726       }
727     }
728   } else {
729     char fullversion[160];
730 
731     current = NULL;
732     while ((current = plist->nextPort(current, &port, TCPANDUDPANDSCTP, 0)) != NULL) {
733       if (!plist->isIgnoredState(current->state)) {
734         if (!first)
735           log_write(LOG_MACHINE, ", ");
736         else
737           first = 0;
738         strcpy(protocol, IPPROTO2STR(current->proto));
739         Snprintf(portinfo, sizeof(portinfo), "%d/%s", current->portno, protocol);
740         state = statenum2str(current->state);
741         plist->getServiceDeductions(current->portno, current->proto, &sd);
742         if (sd.service_fp && saved_servicefps.size() <= 8)
743           saved_servicefps.push_back(sd.service_fp);
744 
745         current->getNmapServiceName(serviceinfo, sizeof(serviceinfo));
746 
747         Tbl->addItem(rowno, portcol, true, portinfo);
748         Tbl->addItem(rowno, statecol, false, state);
749         Tbl->addItem(rowno, servicecol, true, serviceinfo);
750         if (o.reason) {
751           if (current->reason.ttl)
752             Tbl->addItemFormatted(rowno, reasoncol, false, "%s ttl %d",
753                                   port_reason_str(current->reason), current->reason.ttl);
754           else
755             Tbl->addItem(rowno, reasoncol, true, port_reason_str(current->reason));
756         }
757 
758         sd.populateFullVersionString(fullversion, sizeof(fullversion));
759         if (*fullversion && versioncol > 0)
760           Tbl->addItem(rowno, versioncol, true, fullversion);
761 
762         // How should we escape illegal chars in grepable output?
763         // Well, a reasonably clean way would be backslash escapes
764         // such as \/ and \\ .  // But that makes it harder to pick
765         // out fields with awk, cut, and such.  So I'm gonna use the
766         // ugly hack (fitting to grepable output) of replacing the '/'
767         // character with '|' in the version field.
768         Strncpy(grepvers, fullversion, sizeof(grepvers) / sizeof(*grepvers));
769         p = grepvers;
770         while ((p = strchr(p, '/'))) {
771           *p = '|';
772           p++;
773         }
774         if (sd.name || sd.service_fp || sd.service_tunnel != SERVICE_TUNNEL_NONE) {
775           p = serviceinfo;
776           while ((p = strchr(p, '/'))) {
777             *p = '|';
778             p++;
779           }
780         }
781         else {
782           serviceinfo[0] = '\0';
783         }
784         log_write(LOG_MACHINE, "%d/%s/%s//%s//%s/", current->portno,
785                   state, protocol, serviceinfo, grepvers);
786 
787         xml_open_start_tag("port");
788         xml_attribute("protocol", "%s", protocol);
789         xml_attribute("portid", "%d", current->portno);
790         xml_close_start_tag();
791         xml_open_start_tag("state");
792         xml_attribute("state", "%s", state);
793         xml_attribute("reason", "%s", reason_str(current->reason.reason_id, SINGULAR));
794         xml_attribute("reason_ttl", "%d", current->reason.ttl);
795         if (current->reason.ip_addr.sockaddr.sa_family != AF_UNSPEC) {
796           struct sockaddr_storage ss;
797           memcpy(&ss, &current->reason.ip_addr, sizeof(current->reason.ip_addr));
798           xml_attribute("reason_ip", "%s", inet_ntop_ez(&ss, sizeof(ss)));
799         }
800         xml_close_empty_tag();
801 
802         if (sd.name || sd.service_fp || sd.service_tunnel != SERVICE_TUNNEL_NONE)
803           print_xml_service(&sd);
804 
805         rowno++;
806 #ifndef NOLUA
807         if (o.script) {
808           ScriptResults::const_iterator ssr_iter;
809           //Sort the results before outputting them on the screen
810           current->scriptResults.sort(scriptid_lessthan);
811           for (ssr_iter = current->scriptResults.begin();
812                ssr_iter != current->scriptResults.end(); ssr_iter++) {
813             ssr_iter->write_xml();
814 
815             char *script_output = formatScriptOutput((*ssr_iter));
816             if (script_output != NULL) {
817               Tbl->addItem(rowno, 0, true, true, script_output);
818               free(script_output);
819             }
820             rowno++;
821           }
822 
823         }
824 #endif
825 
826         xml_end_tag(); /* port */
827         xml_newline();
828       }
829     }
830 
831   }
832   /*  log_write(LOG_PLAIN,"\n"); */
833   /* Grepable output supports only one ignored state. */
834   if (plist->numIgnoredStates() == 1) {
835     istate = plist->nextIgnoredState(PORT_UNKNOWN);
836     if (plist->getStateCounts(istate) > 0)
837       log_write(LOG_MACHINE, "\tIgnored State: %s (%d)",
838                 statenum2str(istate), plist->getStateCounts(istate));
839   }
840   xml_end_tag(); /* ports */
841   xml_newline();
842 
843   if (o.defeat_rst_ratelimit && o.TCPScan() && plist->getStateCounts(PORT_FILTERED) > 0) {
844     log_write(LOG_PLAIN, "Some closed ports may be reported as filtered due to --defeat-rst-ratelimit\n");
845   }
846 
847   // Now we write the table for the user
848   log_write(LOG_PLAIN, "%s", Tbl->printableTable(NULL));
849   delete Tbl;
850 
851   // There may be service fingerprints I would like the user to submit
852   if (saved_servicefps.size() > 0) {
853     int numfps = saved_servicefps.size();
854     log_write(LOG_PLAIN, "%d service%s unrecognized despite returning data."
855               " If you know the service/version, please submit the following"
856               " fingerprint%s at"
857               " https://nmap.org/cgi-bin/submit.cgi?new-service :\n",
858               numfps, (numfps > 1) ? "s" : "", (numfps > 1) ? "s" : "");
859     for (i = 0; i < numfps; i++) {
860       if (numfps > 1)
861         log_write(LOG_PLAIN, "==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============\n");
862       log_write(LOG_PLAIN, "%s\n", saved_servicefps[i]);
863     }
864   }
865   log_flush_all();
866 }
867 
868 
logfilename(const char * str,struct tm * tm)869 char *logfilename(const char *str, struct tm *tm) {
870   char *ret, *end, *p;
871   char tbuf[10];
872   int retlen = strlen(str) * 6 + 1;
873 
874   ret = (char *) safe_malloc(retlen);
875   end = ret + retlen;
876 
877   for (p = ret; *str; str++) {
878     if (*str == '%') {
879       str++;
880 
881       if (!*str)
882         break;
883 
884       switch (*str) {
885       case 'H':
886         strftime(tbuf, sizeof tbuf, "%H", tm);
887         break;
888       case 'M':
889         strftime(tbuf, sizeof tbuf, "%M", tm);
890         break;
891       case 'S':
892         strftime(tbuf, sizeof tbuf, "%S", tm);
893         break;
894       case 'T':
895         strftime(tbuf, sizeof tbuf, "%H%M%S", tm);
896         break;
897       case 'R':
898         strftime(tbuf, sizeof tbuf, "%H%M", tm);
899         break;
900       case 'm':
901         strftime(tbuf, sizeof tbuf, "%m", tm);
902         break;
903       case 'd':
904         strftime(tbuf, sizeof tbuf, "%d", tm);
905         break;
906       case 'y':
907         strftime(tbuf, sizeof tbuf, "%y", tm);
908         break;
909       case 'Y':
910         strftime(tbuf, sizeof tbuf, "%Y", tm);
911         break;
912       case 'D':
913         strftime(tbuf, sizeof tbuf, "%m%d%y", tm);
914         break;
915       case 'F':
916         strftime(tbuf, sizeof tbuf, "%Y-%m-%d", tm);
917         break;
918       default:
919         *p++ = *str;
920         continue;
921       }
922 
923       assert(end - p > 1);
924       Strncpy(p, tbuf, end - p - 1);
925       p += strlen(tbuf);
926     } else {
927       *p++ = *str;
928     }
929   }
930 
931   *p = 0;
932 
933   return (char *) safe_realloc(ret, strlen(ret) + 1);
934 }
935 
936 /* This is the workhorse of the logging functions.  Usually it is
937    called through log_write(), but it can be called directly if you are dealing
938    with a vfprintf-style va_list. YOU MUST SANDWICH EACH EXECUTION OF THIS CALL
939    BETWEEN va_start() AND va_end() calls. */
log_vwrite(int logt,const char * fmt,va_list ap)940 void log_vwrite(int logt, const char *fmt, va_list ap) {
941   char *writebuf;
942   bool skid_noxlate = false;
943   int rc = 0;
944   int len;
945   int fileidx = 0;
946   int l;
947   int logtype;
948   va_list apcopy;
949 
950   for (logtype = 1; logtype <= LOG_MAX; logtype <<= 1) {
951 
952     if (!(logt & logtype))
953       continue;
954 
955     switch (logtype) {
956       case LOG_STDOUT:
957         vfprintf(o.nmap_stdout, fmt, ap);
958         break;
959 
960       case LOG_STDERR:
961         fflush(stdout); // Otherwise some systems will print stderr out of order
962         vfprintf(stderr, fmt, ap);
963         break;
964 
965       case LOG_SKID_NOXLT:
966         skid_noxlate = true;
967         /* no break */
968       case LOG_NORMAL:
969       case LOG_MACHINE:
970       case LOG_SKID:
971       case LOG_XML:
972         if (logtype == LOG_SKID_NOXLT)
973             l = LOG_SKID;
974         else
975             l = logtype;
976         fileidx = 0;
977         while ((l & 1) == 0) {
978           fileidx++;
979           l >>= 1;
980         }
981         assert(fileidx < LOG_NUM_FILES);
982         if (o.logfd[fileidx]) {
983           len = alloc_vsprintf(&writebuf, fmt, ap);
984           if (writebuf == NULL)
985             fatal("%s: alloc_vsprintf failed.", __func__);
986           if (len) {
987             if ((logtype & (LOG_SKID|LOG_SKID_NOXLT)) && !skid_noxlate)
988               skid_output(writebuf);
989 
990             rc = fwrite(writebuf, len, 1, o.logfd[fileidx]);
991             if (rc != 1) {
992               fatal("Failed to write %d bytes of data to (logt==%d) stream. fwrite returned %d.  Quitting.", len, logtype, rc);
993             }
994             va_end(apcopy);
995           }
996           free(writebuf);
997         }
998         break;
999 
1000       default:
1001         /* Unknown log type.
1002          * ---
1003          * Note that we're not calling fatal() here to avoid infinite call loop
1004          * between fatal() and this log_vwrite() function. */
1005         assert(0); /* We want people to report it. */
1006     }
1007   }
1008 
1009   return;
1010 }
1011 
1012 /* Write some information (printf style args) to the given log stream(s).
1013  Remember to watch out for format string bugs.  */
log_write(int logt,const char * fmt,...)1014 void log_write(int logt, const char *fmt, ...) {
1015   va_list ap;
1016   assert(logt > 0);
1017 
1018   if (!fmt || !*fmt)
1019     return;
1020 
1021   for (int l = 1; l <= LOG_MAX; l <<= 1) {
1022     if (logt & l) {
1023       va_start(ap, fmt);
1024       log_vwrite(l, fmt, ap);
1025       va_end(ap);
1026     }
1027   }
1028   return;
1029 }
1030 
1031 /* Close the given log stream(s) */
log_close(int logt)1032 void log_close(int logt) {
1033   int i;
1034   if (logt < 0 || logt > LOG_FILE_MASK)
1035     return;
1036   for (i = 0; logt; logt >>= 1, i++)
1037     if (o.logfd[i] && (logt & 1))
1038       fclose(o.logfd[i]);
1039 }
1040 
1041 /* Flush the given log stream(s).  In other words, all buffered output
1042    is written to the log immediately */
log_flush(int logt)1043 void log_flush(int logt) {
1044   int i;
1045 
1046   if (logt & LOG_STDOUT) {
1047     fflush(o.nmap_stdout);
1048     logt -= LOG_STDOUT;
1049   }
1050 
1051   if (logt & LOG_STDERR) {
1052     fflush(stderr);
1053     logt -= LOG_STDERR;
1054   }
1055 
1056   if (logt & LOG_SKID_NOXLT)
1057     fatal("You are not allowed to %s() with LOG_SKID_NOXLT", __func__);
1058 
1059   if (logt < 0 || logt > LOG_FILE_MASK)
1060     return;
1061 
1062   for (i = 0; logt; logt >>= 1, i++) {
1063     if (!o.logfd[i] || !(logt & 1))
1064       continue;
1065     fflush(o.logfd[i]);
1066   }
1067 
1068 }
1069 
1070 /* Flush every single log stream -- all buffered output is written to the
1071    corresponding logs immediately */
log_flush_all()1072 void log_flush_all() {
1073   int fileno;
1074 
1075   for (fileno = 0; fileno < LOG_NUM_FILES; fileno++) {
1076     if (o.logfd[fileno])
1077       fflush(o.logfd[fileno]);
1078   }
1079   fflush(stdout);
1080   fflush(stderr);
1081 }
1082 
1083 /* Open a log descriptor of the type given to the filename given.  If
1084    append is true, the file will be appended instead of clobbered if
1085    it already exists.  If the file does not exist, it will be created */
log_open(int logt,bool append,char * filename)1086 int log_open(int logt, bool append, char *filename) {
1087   int i = 0;
1088   if (logt <= 0 || logt > LOG_FILE_MASK)
1089     return -1;
1090   while ((logt & 1) == 0) {
1091     i++;
1092     logt >>= 1;
1093   }
1094   if (o.logfd[i])
1095     fatal("Only one %s output filename allowed", logtypes[i]);
1096   if (*filename == '-' && *(filename + 1) == '\0') {
1097     o.logfd[i] = stdout;
1098     o.nmap_stdout = fopen(DEVNULL, "w");
1099     if (!o.nmap_stdout)
1100       fatal("Could not assign %s to stdout for writing", DEVNULL);
1101   } else {
1102     if (append)
1103       o.logfd[i] = fopen(filename, "a");
1104     else
1105       o.logfd[i] = fopen(filename, "w");
1106     if (!o.logfd[i])
1107       fatal("Failed to open %s output file %s for writing", logtypes[i],
1108             filename);
1109   }
1110   return 1;
1111 }
1112 
1113 
1114 /* The items in ports should be
1115    in sequential order for space savings and easier to read output.  Outputs the
1116    rangelist to the log stream given (such as LOG_MACHINE or LOG_XML) */
output_rangelist_given_ports(int logt,unsigned short * ports,int numports)1117 static void output_rangelist_given_ports(int logt, unsigned short *ports,
1118                                          int numports) {
1119   int start, end;
1120 
1121   start = 0;
1122   while (start < numports) {
1123     end = start;
1124     while (end + 1 < numports && ports[end + 1] == ports[end] + 1)
1125       end++;
1126     if (start > 0)
1127       log_write(logt, ",");
1128     if (start == end)
1129       log_write(logt, "%hu", ports[start]);
1130     else
1131       log_write(logt, "%hu-%hu", ports[start], ports[end]);
1132     start = end + 1;
1133   }
1134 }
1135 
1136 /* Output the list of ports scanned to the top of machine parseable
1137    logs (in a comment, unfortunately).  The items in ports should be
1138    in sequential order for space savings and easier to read output */
output_ports_to_machine_parseable_output(struct scan_lists * ports)1139 void output_ports_to_machine_parseable_output(struct scan_lists *ports) {
1140   int tcpportsscanned = ports->tcp_count;
1141   int udpportsscanned = ports->udp_count;
1142   int sctpportsscanned = ports->sctp_count;
1143   int protsscanned = ports->prot_count;
1144   log_write(LOG_MACHINE, "# Ports scanned: TCP(%d;", tcpportsscanned);
1145   if (tcpportsscanned)
1146     output_rangelist_given_ports(LOG_MACHINE, ports->tcp_ports, tcpportsscanned);
1147   log_write(LOG_MACHINE, ") UDP(%d;", udpportsscanned);
1148   if (udpportsscanned)
1149     output_rangelist_given_ports(LOG_MACHINE, ports->udp_ports, udpportsscanned);
1150   log_write(LOG_MACHINE, ") SCTP(%d;", sctpportsscanned);
1151   if (sctpportsscanned)
1152     output_rangelist_given_ports(LOG_MACHINE, ports->sctp_ports, sctpportsscanned);
1153   log_write(LOG_MACHINE, ") PROTOCOLS(%d;", protsscanned);
1154   if (protsscanned)
1155     output_rangelist_given_ports(LOG_MACHINE, ports->prots, protsscanned);
1156   log_write(LOG_MACHINE, ")\n");
1157   log_flush_all();
1158 }
1159 
1160 // A simple helper function for doscaninfo handles the c14n of o.scanflags
doscanflags()1161 static void doscanflags() {
1162   struct {
1163     unsigned char flag;
1164     const char *name;
1165   } flags[] = {
1166     { TH_FIN, "FIN" },
1167     { TH_SYN, "SYN" },
1168     { TH_RST, "RST" },
1169     { TH_PUSH, "PSH" },
1170     { TH_ACK, "ACK" },
1171     { TH_URG, "URG" },
1172     { TH_ECE, "ECE" },
1173     { TH_CWR, "CWR" }
1174   };
1175 
1176   if (o.scanflags != -1) {
1177     std::string flagstring;
1178 
1179     for (unsigned int i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
1180       if (o.scanflags & flags[i].flag)
1181         flagstring += flags[i].name;
1182     }
1183     xml_attribute("scanflags", "%s", flagstring.c_str());
1184   }
1185 }
1186 
1187 /* Simple helper function for output_xml_scaninfo_records */
doscaninfo(const char * type,const char * proto,unsigned short * ports,int numports)1188 static void doscaninfo(const char *type, const char *proto,
1189                        unsigned short *ports, int numports) {
1190   xml_open_start_tag("scaninfo");
1191   xml_attribute("type", "%s", type);
1192   if (strncmp(proto, "tcp", 3) == 0) {
1193     doscanflags();
1194   }
1195   xml_attribute("protocol", "%s", proto);
1196   xml_attribute("numservices", "%d", numports);
1197   xml_write_raw(" services=\"");
1198   output_rangelist_given_ports(LOG_XML, ports, numports);
1199   xml_write_raw("\"");
1200   xml_close_empty_tag();
1201   xml_newline();
1202 }
1203 
quote(const char * s)1204 static std::string quote(const char *s) {
1205   std::string result("");
1206   const char *p;
1207   bool space;
1208 
1209   space = false;
1210   for (p = s; *p != '\0'; p++) {
1211     if (isspace(*p))
1212       space = true;
1213     if (*p == '"' || *p == '\\')
1214       result += "\\";
1215     result += *p;
1216   }
1217 
1218   if (space)
1219     result = "\"" + result + "\"";
1220 
1221   return result;
1222 }
1223 
1224 /* Return a std::string containing all n strings separated by whitespace, and
1225    individually quoted if needed. */
join_quoted(const char * const strings[],unsigned int n)1226 std::string join_quoted(const char * const strings[], unsigned int n) {
1227   std::string result("");
1228   unsigned int i;
1229 
1230   for (i = 0; i < n; i++) {
1231     if (i > 0)
1232       result += " ";
1233     result += quote(strings[i]);
1234   }
1235 
1236   return result;
1237 }
1238 
1239 /* Similar to output_ports_to_machine_parseable_output, this function
1240    outputs the XML version, which is scaninfo records of each scan
1241    requested and the ports which it will scan for */
output_xml_scaninfo_records(struct scan_lists * scanlist)1242 void output_xml_scaninfo_records(struct scan_lists *scanlist) {
1243   if (o.synscan)
1244     doscaninfo("syn", "tcp", scanlist->tcp_ports, scanlist->tcp_count);
1245   if (o.ackscan)
1246     doscaninfo("ack", "tcp", scanlist->tcp_ports, scanlist->tcp_count);
1247   if (o.bouncescan)
1248     doscaninfo("bounce", "tcp", scanlist->tcp_ports, scanlist->tcp_count);
1249   if (o.connectscan)
1250     doscaninfo("connect", "tcp", scanlist->tcp_ports, scanlist->tcp_count);
1251   if (o.nullscan)
1252     doscaninfo("null", "tcp", scanlist->tcp_ports, scanlist->tcp_count);
1253   if (o.xmasscan)
1254     doscaninfo("xmas", "tcp", scanlist->tcp_ports, scanlist->tcp_count);
1255   if (o.windowscan)
1256     doscaninfo("window", "tcp", scanlist->tcp_ports, scanlist->tcp_count);
1257   if (o.maimonscan)
1258     doscaninfo("maimon", "tcp", scanlist->tcp_ports, scanlist->tcp_count);
1259   if (o.finscan)
1260     doscaninfo("fin", "tcp", scanlist->tcp_ports, scanlist->tcp_count);
1261   if (o.udpscan)
1262     doscaninfo("udp", "udp", scanlist->udp_ports, scanlist->udp_count);
1263   if (o.sctpinitscan)
1264     doscaninfo("sctpinit", "sctp", scanlist->sctp_ports, scanlist->sctp_count);
1265   if (o.sctpcookieechoscan)
1266     doscaninfo("sctpcookieecho", "sctp", scanlist->sctp_ports, scanlist->sctp_count);
1267   if (o.ipprotscan)
1268     doscaninfo("ipproto", "ip", scanlist->prots, scanlist->prot_count);
1269   log_flush_all();
1270 }
1271 
1272 /* Prints the MAC address (if discovered) to XML output */
print_MAC_XML_Info(Target * currenths)1273 static void print_MAC_XML_Info(Target *currenths) {
1274   const u8 *mac = currenths->MACAddress();
1275   char macascii[32];
1276 
1277   if (mac) {
1278     const char *macvendor = MACPrefix2Corp(mac);
1279     Snprintf(macascii, sizeof(macascii), "%02X:%02X:%02X:%02X:%02X:%02X",
1280              mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
1281     xml_open_start_tag("address");
1282     xml_attribute("addr", "%s", macascii);
1283     xml_attribute("addrtype", "mac");
1284     if (macvendor)
1285       xml_attribute("vendor", "%s", macvendor);
1286     xml_close_empty_tag();
1287     xml_newline();
1288   }
1289 }
1290 
1291 /* Helper function to write the status and address/hostname info of a host
1292    into the XML log */
write_xml_initial_hostinfo(Target * currenths,const char * status)1293 static void write_xml_initial_hostinfo(Target *currenths,
1294                                        const char *status) {
1295   xml_open_start_tag("status");
1296   xml_attribute("state", "%s", status);
1297   xml_attribute("reason", "%s", reason_str(currenths->reason.reason_id, SINGULAR));
1298   xml_attribute("reason_ttl", "%d", currenths->reason.ttl);
1299   xml_close_empty_tag();
1300   xml_newline();
1301   xml_open_start_tag("address");
1302   xml_attribute("addr", "%s", currenths->targetipstr());
1303   xml_attribute("addrtype", "%s", (o.af() == AF_INET) ? "ipv4" : "ipv6");
1304   xml_close_empty_tag();
1305   xml_newline();
1306   print_MAC_XML_Info(currenths);
1307   /* Output a hostnames element whenever we have a name to write or the target
1308      is up. */
1309   if (currenths->TargetName() != NULL || *currenths->HostName() || strcmp(status, "up") == 0) {
1310     xml_start_tag("hostnames");
1311     xml_newline();
1312     if (currenths->TargetName() != NULL) {
1313       xml_open_start_tag("hostname");
1314       xml_attribute("name", "%s", currenths->TargetName());
1315       xml_attribute("type", "user");
1316       xml_close_empty_tag();
1317       xml_newline();
1318     }
1319     if (*currenths->HostName()) {
1320       xml_open_start_tag("hostname");
1321       xml_attribute("name", "%s", currenths->HostName());
1322       xml_attribute("type", "PTR");
1323       xml_close_empty_tag();
1324       xml_newline();
1325     }
1326     xml_end_tag();
1327     xml_newline();
1328   }
1329   log_flush_all();
1330 }
1331 
write_xml_hosthint(Target * currenths)1332 void write_xml_hosthint(Target *currenths) {
1333   xml_start_tag("hosthint");
1334   write_xml_initial_hostinfo(currenths, (currenths->flags & HOST_UP) ? "up" : "down");
1335   xml_end_tag();
1336   xml_newline();
1337   log_flush_all();
1338 }
1339 
write_xml_osclass(const OS_Classification * osclass,double accuracy)1340 static void write_xml_osclass(const OS_Classification *osclass, double accuracy) {
1341   xml_open_start_tag("osclass");
1342   xml_attribute("type", "%s", osclass->Device_Type);
1343   xml_attribute("vendor", "%s", osclass->OS_Vendor);
1344   xml_attribute("osfamily", "%s", osclass->OS_Family);
1345   // Because the OS_Generation field is optional.
1346   if (osclass->OS_Generation)
1347     xml_attribute("osgen", "%s", osclass->OS_Generation);
1348   xml_attribute("accuracy", "%d", (int) (accuracy * 100));
1349   if (osclass->cpe.empty()) {
1350     xml_close_empty_tag();
1351   } else {
1352     unsigned int i;
1353 
1354     xml_close_start_tag();
1355     for (i = 0; i < osclass->cpe.size(); i++) {
1356       xml_start_tag("cpe");
1357       xml_write_escaped("%s", osclass->cpe[i]);
1358       xml_end_tag();
1359     }
1360     xml_end_tag();
1361   }
1362   xml_newline();
1363 }
1364 
write_xml_osmatch(const FingerMatch * match,double accuracy)1365 static void write_xml_osmatch(const FingerMatch *match, double accuracy) {
1366   xml_open_start_tag("osmatch");
1367   xml_attribute("name", "%s", match->OS_name);
1368   xml_attribute("accuracy", "%d", (int) (accuracy * 100));
1369   xml_attribute("line", "%d", match->line);
1370   /* When o.deprecated_xml_osclass is true, we don't write osclass elements as
1371      children of osmatch but rather as unrelated siblings. */
1372   if (match->OS_class.empty() || o.deprecated_xml_osclass) {
1373     xml_close_empty_tag();
1374   } else {
1375     unsigned int i;
1376 
1377     xml_close_start_tag();
1378     xml_newline();
1379     for (i = 0; i < match->OS_class.size(); i++)
1380       write_xml_osclass(&match->OS_class[i], accuracy);
1381     xml_end_tag();
1382   }
1383   xml_newline();
1384 }
1385 
1386 /* Convert a number to a string, keeping the given number of significant digits.
1387    The result is returned in a static buffer. */
num_to_string_sigdigits(double d,int digits)1388 static char *num_to_string_sigdigits(double d, int digits) {
1389   static char buf[32];
1390   int shift;
1391   int n;
1392 
1393   assert(digits >= 0);
1394   if (d == 0.0) {
1395     shift = -digits;
1396   } else {
1397     shift = (int) floor(log10(fabs(d))) - digits + 1;
1398     d = floor(d / pow(10.0, shift) + 0.5);
1399     d = d * pow(10.0, shift);
1400   }
1401 
1402   n = Snprintf(buf, sizeof(buf), "%.*f", MAX(0, -shift), d);
1403   assert(n > 0 && n < (int) sizeof(buf));
1404 
1405   return buf;
1406 }
1407 
1408 /* Writes a heading for a full scan report ("Nmap scan report for..."),
1409    including host status and DNS records. */
write_host_header(Target * currenths)1410 void write_host_header(Target *currenths) {
1411   if ((currenths->flags & HOST_UP) || o.verbose || o.always_resolve) {
1412     if (currenths->flags & HOST_UP) {
1413       log_write(LOG_PLAIN, "Nmap scan report for %s\n", currenths->NameIP());
1414     } else if (currenths->flags & HOST_DOWN) {
1415       log_write(LOG_PLAIN, "Nmap scan report for %s [host down", currenths->NameIP());
1416       if (o.reason)
1417         log_write(LOG_PLAIN, ", %s", target_reason_str(currenths));
1418       log_write(LOG_PLAIN, "]\n");
1419     }
1420   }
1421   write_host_status(currenths);
1422   if (currenths->TargetName() != NULL
1423       && !currenths->unscanned_addrs.empty()) {
1424 
1425     log_write(LOG_PLAIN, "Other addresses for %s (not scanned):",
1426       currenths->TargetName());
1427     for (std::list<struct sockaddr_storage>::const_iterator it = currenths->unscanned_addrs.begin(), end = currenths->unscanned_addrs.end();
1428         it != end; it++) {
1429       struct sockaddr_storage ss = *it;
1430       log_write(LOG_PLAIN, " %s", inet_ntop_ez(&ss, sizeof(ss)));
1431     }
1432     log_write(LOG_PLAIN, "\n");
1433   }
1434   /* Print reverse DNS if it differs. */
1435   if (currenths->TargetName() != NULL
1436       && currenths->HostName() != NULL && currenths->HostName()[0] != '\0'
1437       && strcmp(currenths->TargetName(), currenths->HostName()) != 0) {
1438     log_write(LOG_PLAIN, "rDNS record for %s: %s\n",
1439       currenths->targetipstr(), currenths->HostName());
1440   }
1441 }
1442 
1443 /* Writes host status info to the log streams (including STDOUT).  An
1444    example is "Host: 10.11.12.13 (foo.bar.example.com)\tStatus: Up\n" to
1445    machine log. */
write_host_status(Target * currenths)1446 void write_host_status(Target *currenths) {
1447   if (o.listscan) {
1448     /* write "unknown" to machine and xml */
1449     log_write(LOG_MACHINE, "Host: %s (%s)\tStatus: Unknown\n",
1450               currenths->targetipstr(), currenths->HostName());
1451     write_xml_initial_hostinfo(currenths, "unknown");
1452   } else if (currenths->weird_responses) {
1453     /* SMURF ADDRESS */
1454     /* Write xml "down" or "up" based on flags and the smurf info */
1455     write_xml_initial_hostinfo(currenths,
1456                                (currenths->
1457                                 flags & HOST_UP) ? "up" : "down");
1458     xml_open_start_tag("smurf");
1459     xml_attribute("responses", "%d", currenths->weird_responses);
1460     xml_close_empty_tag();
1461     xml_newline();
1462     log_write(LOG_MACHINE, "Host: %s (%s)\tStatus: Smurf (%d responses)\n",
1463               currenths->targetipstr(), currenths->HostName(),
1464               currenths->weird_responses);
1465 
1466     if (o.noportscan) {
1467       log_write(LOG_PLAIN, "Host seems to be a subnet broadcast address (returned %d extra pings).%s\n",
1468                 currenths->weird_responses,
1469                 (currenths->flags & HOST_UP) ? " Note -- the actual IP also responded." : "");
1470     } else {
1471       log_write(LOG_PLAIN, "Host seems to be a subnet broadcast address (returned %d extra pings). %s.\n",
1472                 currenths->weird_responses,
1473                 (currenths->flags & HOST_UP) ? " Still scanning it due to ping response from its own IP" : "Skipping host");
1474     }
1475   } else {
1476     /* Ping scan / port scan. */
1477 
1478     write_xml_initial_hostinfo(currenths, (currenths->flags & HOST_UP) ? "up" : "down");
1479     if (currenths->flags & HOST_UP) {
1480       log_write(LOG_PLAIN, "Host is up");
1481       if (o.reason)
1482         log_write(LOG_PLAIN, ", %s", target_reason_str(currenths));
1483       if (o.reason && currenths->reason.ttl)
1484         log_write(LOG_PLAIN, " ttl %d", currenths->reason.ttl);
1485       if (currenths->to.srtt != -1)
1486         log_write(LOG_PLAIN, " (%ss latency)",
1487                   num_to_string_sigdigits(currenths->to.srtt / 1000000.0, 2));
1488       log_write(LOG_PLAIN, ".\n");
1489 
1490       log_write(LOG_MACHINE, "Host: %s (%s)\tStatus: Up\n",
1491                 currenths->targetipstr(), currenths->HostName());
1492     } else if (currenths->flags & HOST_DOWN) {
1493       log_write(LOG_MACHINE, "Host: %s (%s)\tStatus: Down\n",
1494                 currenths->targetipstr(), currenths->HostName());
1495     }
1496   }
1497 }
1498 
1499 /* Returns -1 if adding the entry is not possible because it would
1500    overflow.  Otherwise it returns the new number of entries.  Note
1501    that only unique entries are added.  Also note that *numentries is
1502    incremented if the candidate is added.  arrsize is the number of
1503    char * members that fit into arr */
addtochararrayifnew(const char * arr[],int * numentries,int arrsize,const char * candidate)1504 static int addtochararrayifnew(const char *arr[], int *numentries, int arrsize,
1505                                const char *candidate) {
1506   int i;
1507 
1508   // First lets see if the member already exists
1509   for (i = 0; i < *numentries; i++) {
1510     if (strcmp(arr[i], candidate) == 0)
1511       return *numentries;
1512   }
1513 
1514   // Not already there... do we have room for a new one?
1515   if (*numentries >= arrsize)
1516     return -1;
1517 
1518   // OK, not already there and we have room, so we'll add it.
1519   arr[*numentries] = candidate;
1520   (*numentries)++;
1521   return *numentries;
1522 }
1523 
1524 /* guess is true if we should print guesses */
1525 #define MAX_OS_CLASSMEMBERS 8
printosclassificationoutput(const struct OS_Classification_Results * OSR,bool guess)1526 static void printosclassificationoutput(const struct
1527                                         OS_Classification_Results *OSR,
1528                                         bool guess) {
1529   int classno, cpeno, familyno;
1530   unsigned int i;
1531   int overflow = 0;             /* Whether we have too many devices to list */
1532   const char *types[MAX_OS_CLASSMEMBERS];
1533   const char *cpes[MAX_OS_CLASSMEMBERS];
1534   char fullfamily[MAX_OS_CLASSMEMBERS][128];    // "[vendor] [os family]"
1535   double familyaccuracy[MAX_OS_CLASSMEMBERS];   // highest accuracy for this fullfamily
1536   char familygenerations[MAX_OS_CLASSMEMBERS][96];      // example: "4.X|5.X|6.X"
1537   int numtypes = 0, numcpes = 0, numfamilies = 0;
1538   char tmpbuf[1024];
1539 
1540   for (i = 0; i < MAX_OS_CLASSMEMBERS; i++) {
1541     familygenerations[i][0] = '\0';
1542     familyaccuracy[i] = 0.0;
1543   }
1544 
1545   if (OSR->overall_results == OSSCAN_SUCCESS) {
1546 
1547     if (o.deprecated_xml_osclass) {
1548       for (classno = 0; classno < OSR->OSC_num_matches; classno++)
1549         write_xml_osclass(OSR->OSC[classno], OSR->OSC_Accuracy[classno]);
1550     }
1551 
1552     // Now to create the fodder for normal output
1553     for (classno = 0; classno < OSR->OSC_num_matches; classno++) {
1554       /* We have processed enough if any of the following are true */
1555       if ((!guess && classno >= OSR->OSC_num_perfect_matches) ||
1556           OSR->OSC_Accuracy[classno] <= OSR->OSC_Accuracy[0] - 0.1 ||
1557           (OSR->OSC_Accuracy[classno] < 1.0 && classno > 9))
1558         break;
1559       if (addtochararrayifnew(types, &numtypes, MAX_OS_CLASSMEMBERS,
1560                               OSR->OSC[classno]->Device_Type) == -1) {
1561         overflow = 1;
1562       }
1563       for (i = 0; i < OSR->OSC[classno]->cpe.size(); i++) {
1564         if (addtochararrayifnew(cpes, &numcpes, MAX_OS_CLASSMEMBERS,
1565                                 OSR->OSC[classno]->cpe[i]) == -1) {
1566           overflow = 1;
1567         }
1568       }
1569 
1570       // If family and vendor names are the same, no point being redundant
1571       if (strcmp(OSR->OSC[classno]->OS_Vendor, OSR->OSC[classno]->OS_Family) == 0)
1572         Strncpy(tmpbuf, OSR->OSC[classno]->OS_Family, sizeof(tmpbuf));
1573       else
1574         Snprintf(tmpbuf, sizeof(tmpbuf), "%s %s", OSR->OSC[classno]->OS_Vendor, OSR->OSC[classno]->OS_Family);
1575 
1576 
1577       // Let's see if it is already in the array
1578       for (familyno = 0; familyno < numfamilies; familyno++) {
1579         if (strcmp(fullfamily[familyno], tmpbuf) == 0) {
1580           // got a match ... do we need to add the generation?
1581           if (OSR->OSC[classno]->OS_Generation
1582               && !strstr(familygenerations[familyno],
1583                          OSR->OSC[classno]->OS_Generation)) {
1584             int flen = strlen(familygenerations[familyno]);
1585             // We add it, preceded by | if something is already there
1586             if (flen + 2 + strlen(OSR->OSC[classno]->OS_Generation) >=
1587                 sizeof(familygenerations[familyno]))
1588               fatal("buffer 0verfl0w of familygenerations");
1589             if (*familygenerations[familyno])
1590               strcat(familygenerations[familyno], "|");
1591             strncat(familygenerations[familyno],
1592                     OSR->OSC[classno]->OS_Generation,
1593                     sizeof(familygenerations[familyno]) - flen - 1);
1594           }
1595           break;
1596         }
1597       }
1598 
1599       if (familyno == numfamilies) {
1600         // Looks like the new family is not in the list yet.  Do we have room to add it?
1601         if (numfamilies >= MAX_OS_CLASSMEMBERS) {
1602           overflow = 1;
1603           break;
1604         }
1605         // Have space, time to add...
1606         Strncpy(fullfamily[numfamilies], tmpbuf, 128);
1607         if (OSR->OSC[classno]->OS_Generation)
1608           Strncpy(familygenerations[numfamilies],
1609                   OSR->OSC[classno]->OS_Generation, 48);
1610         familyaccuracy[numfamilies] = OSR->OSC_Accuracy[classno];
1611         numfamilies++;
1612       }
1613     }
1614 
1615     if (!overflow && numfamilies >= 1) {
1616       log_write(LOG_PLAIN, "Device type: ");
1617       for (classno = 0; classno < numtypes; classno++)
1618         log_write(LOG_PLAIN, "%s%s", types[classno], (classno < numtypes - 1) ? "|" : "");
1619       log_write(LOG_PLAIN, "\nRunning%s: ", OSR->OSC_num_perfect_matches == 0 ? " (JUST GUESSING)" : "");
1620       for (familyno = 0; familyno < numfamilies; familyno++) {
1621         if (familyno > 0)
1622           log_write(LOG_PLAIN, ", ");
1623         log_write(LOG_PLAIN, "%s", fullfamily[familyno]);
1624         if (*familygenerations[familyno])
1625           log_write(LOG_PLAIN, " %s", familygenerations[familyno]);
1626         if (familyno >= OSR->OSC_num_perfect_matches)
1627           log_write(LOG_PLAIN, " (%.f%%)",
1628                     floor(familyaccuracy[familyno] * 100));
1629       }
1630       log_write(LOG_PLAIN, "\n");
1631 
1632       if (numcpes > 0) {
1633         log_write(LOG_PLAIN, "OS CPE:");
1634         for (cpeno = 0; cpeno < numcpes; cpeno++)
1635           log_write(LOG_PLAIN, " %s", cpes[cpeno]);
1636         log_write(LOG_PLAIN, "\n");
1637       }
1638     }
1639   }
1640   log_flush_all();
1641   return;
1642 }
1643 
1644 /* Prints the MAC address if one was found for the target (generally
1645    this means that the target is directly connected on an ethernet
1646    network.  This only prints to human output -- XML is handled by a
1647    separate call ( print_MAC_XML_Info ) because it needs to be printed
1648    in a certain place to conform to DTD. */
printmacinfo(Target * currenths)1649 void printmacinfo(Target *currenths) {
1650   const u8 *mac = currenths->MACAddress();
1651   char macascii[32];
1652 
1653   if (mac) {
1654     const char *macvendor = MACPrefix2Corp(mac);
1655     Snprintf(macascii, sizeof(macascii), "%02X:%02X:%02X:%02X:%02X:%02X",
1656              mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
1657     log_write(LOG_PLAIN, "MAC Address: %s (%s)\n", macascii,
1658               macvendor ? macvendor : "Unknown");
1659   }
1660 }
1661 
1662 
1663 
1664 /* A convenience wrapper around mergeFPs. */
merge_fpr(const Target * currenths,bool isGoodFP,bool wrapit) const1665 const char *FingerPrintResultsIPv4::merge_fpr(const Target *currenths,
1666                              bool isGoodFP, bool wrapit) const {
1667   return mergeFPs(this->FPs, this->numFPs, isGoodFP, currenths->TargetSockAddr(),
1668                   currenths->distance,
1669                   currenths->distance_calculation_method,
1670                   currenths->MACAddress(), this->osscan_opentcpport,
1671                   this->osscan_closedtcpport, this->osscan_closedudpport,
1672                   wrapit);
1673 }
1674 
1675 /* Run-length encode a string in chunks of two bytes. The output sequence
1676    AA{n} means to repeat AA n times. The input must not contain '{' or '}'
1677    characters. */
run_length_encode(const std::string & s)1678 static std::string run_length_encode(const std::string &s) {
1679   std::ostringstream result;
1680   const char *p, *q;
1681   unsigned int reps;
1682 
1683   p = s.c_str();
1684   while (*p != '\0' && *(p + 1) != '\0') {
1685     for (q = p + 2; *q == *p && *(q + 1) == *(p + 1); q += 2)
1686       ;
1687     reps = (q - p) / 2;
1688     if (reps < 3)
1689       result << std::string(p, q);
1690     else
1691       result << std::string(p, 2) << "{" << reps << "}";
1692     p = q;
1693   }
1694   if (*p != '\0')
1695     result << std::string(p);
1696 
1697   return result.str();
1698 }
1699 
wrap(const std::string & s)1700 static std::string wrap(const std::string &s) {
1701   const static char *prefix = "OS:";
1702   std::string t, buf;
1703   int i, len, prefixlen;
1704   size_t p;
1705 
1706   t = s;
1707   /* Remove newlines. */
1708   p = 0;
1709   while ((p = t.find("\n", p)) != std::string::npos)
1710     t.erase(p, 1);
1711 
1712   len = t.size();
1713   prefixlen = strlen(prefix);
1714   assert(FP_RESULT_WRAP_LINE_LEN > prefixlen);
1715   for (i = 0; i < len; i += FP_RESULT_WRAP_LINE_LEN - prefixlen) {
1716     buf.append(prefix);
1717     buf.append(t, i, FP_RESULT_WRAP_LINE_LEN - prefixlen);
1718     buf.append("\n");
1719   }
1720 
1721   return buf;
1722 }
1723 
scrub_packet(PacketElement * pe,unsigned char fill)1724 static void scrub_packet(PacketElement *pe, unsigned char fill) {
1725   unsigned char fillbuf[16];
1726 
1727   memset(fillbuf, fill, sizeof(fillbuf));
1728   for (; pe != NULL; pe = pe->getNextElement()) {
1729     if (pe->protocol_id() == HEADER_TYPE_IPv6) {
1730       IPv6Header *ipv6 = (IPv6Header *) pe;
1731       ipv6->setSourceAddress(fillbuf);
1732       ipv6->setDestinationAddress(fillbuf);
1733     } else if (pe->protocol_id() == HEADER_TYPE_ICMPv6) {
1734       ICMPv6Header *icmpv6 = (ICMPv6Header *) pe;
1735       in6_addr *addr = (in6_addr *) fillbuf;
1736       if (icmpv6->getType() == ICMPV6_NEIGHBOR_ADVERTISEMENT)
1737         icmpv6->setTargetAddress(*addr);
1738     }
1739   }
1740 }
1741 
get_scrubbed_buffer(const FPResponse * resp)1742 static std::string get_scrubbed_buffer(const FPResponse *resp) {
1743   std::ostringstream result;
1744   PacketElement *scrub1, *scrub2;
1745   u8 *buf1, *buf2;
1746   int len1, len2;
1747   unsigned int i;
1748 
1749   scrub1 = PacketParser::split(resp->buf, resp->len);
1750   assert(scrub1 != NULL);
1751   scrub_packet(scrub1, 0x00);
1752 
1753   scrub2 = PacketParser::split(resp->buf, resp->len);
1754   assert(scrub2 != NULL);
1755   scrub_packet(scrub2, 0xFF);
1756 
1757   buf1 = scrub1->getBinaryBuffer(&len1);
1758   buf2 = scrub2->getBinaryBuffer(&len2);
1759 
1760   assert(resp->len == (unsigned int) len1);
1761   assert(resp->len == (unsigned int) len2);
1762 
1763   result.fill('0');
1764   result << std::hex;
1765   for (i = 0; i < resp->len; i++) {
1766     if (resp->buf[i] == buf1[i] && resp->buf[i] == buf2[i]) {
1767       result.width(2);
1768       result << (unsigned int) resp->buf[i];
1769     } else {
1770       result << "XX";
1771     }
1772   }
1773 
1774   free(buf1);
1775   free(buf2);
1776   PacketParser::freePacketChain(scrub1);
1777   PacketParser::freePacketChain(scrub2);
1778 
1779   return result.str();
1780 }
1781 
merge_fpr(const Target * currenths,bool isGoodFP,bool wrapit) const1782 const char *FingerPrintResultsIPv6::merge_fpr(const Target *currenths,
1783                              bool isGoodFP, bool wrapit) const {
1784   static char str[10240];
1785   const FingerPrintResultsIPv6 *FPR;
1786   std::ostringstream result;
1787   std::string output;
1788   unsigned int i;
1789 
1790   /* Write the SCAN line. */
1791   WriteSInfo(str, sizeof(str), isGoodFP, "6", currenths->TargetSockAddr(),
1792     currenths->distance, currenths->distance_calculation_method,
1793     currenths->MACAddress(), this->osscan_opentcpport,
1794     this->osscan_closedtcpport, this->osscan_closedudpport);
1795   result << str << "\n";
1796 
1797   FPR = (FingerPrintResultsIPv6 *) currenths->FPR;
1798   assert(FPR->begin_time.tv_sec != 0);
1799   for (i = 0; i < sizeof(FPR->fp_responses) / sizeof(FPR->fp_responses[0]); i++) {
1800     const FPResponse *resp;
1801     std::string scrubbed;
1802 
1803     resp = this->fp_responses[i];
1804     if (resp == NULL)
1805       continue;
1806     scrubbed = get_scrubbed_buffer(resp);
1807     if (wrapit)
1808       scrubbed = run_length_encode(scrubbed);
1809     result << resp->probe_id << "(P=" << scrubbed;
1810     assert(resp->senttime.tv_sec != 0);
1811     result << "%ST=" << TIMEVAL_FSEC_SUBTRACT(resp->senttime, FPR->begin_time);
1812     assert(resp->rcvdtime.tv_sec != 0);
1813     result << "%RT=" << TIMEVAL_FSEC_SUBTRACT(resp->rcvdtime, FPR->begin_time);
1814     result << ")\n";
1815   }
1816 
1817   result << "EXTRA(";
1818   result << "FL=";
1819   result.fill('0');
1820   result << std::hex;
1821   result.width(5);
1822   result << FPR->flow_label;
1823   result << ")\n";
1824 
1825   output = result.str();
1826   if (wrapit) {
1827     output = wrap(output);
1828   }
1829 
1830   Strncpy(str, output.c_str(), sizeof(str));
1831 
1832   return str;
1833 }
1834 
write_merged_fpr(const FingerPrintResults * FPR,const Target * currenths,bool isGoodFP,bool wrapit)1835 static void write_merged_fpr(const FingerPrintResults *FPR,
1836                              const Target *currenths,
1837                              bool isGoodFP, bool wrapit) {
1838   log_write(LOG_NORMAL | LOG_SKID_NOXLT | LOG_STDOUT,
1839             "TCP/IP fingerprint:\n%s\n",
1840             FPR->merge_fpr(currenths, isGoodFP, wrapit));
1841 
1842   /* Added code here to print fingerprint to XML file any time it would be
1843      printed to any other output format  */
1844   xml_open_start_tag("osfingerprint");
1845   xml_attribute("fingerprint", "%s", FPR->merge_fpr(currenths, isGoodFP, wrapit));
1846   xml_close_empty_tag();
1847   xml_newline();
1848 }
1849 
1850 /* Prints the formatted OS Scan output to stdout, logfiles, etc (but only
1851    if an OS Scan was performed).*/
printosscanoutput(Target * currenths)1852 void printosscanoutput(Target *currenths) {
1853   int i;
1854   char numlst[512];             /* For creating lists of numbers */
1855   char *p;                      /* Used in manipulating numlst above */
1856   FingerPrintResults *FPR;
1857   int osscan_flag;
1858 
1859   if (!(osscan_flag = currenths->osscanPerformed()))
1860     return;
1861 
1862   if (currenths->FPR == NULL)
1863     return;
1864   FPR = currenths->FPR;
1865 
1866   xml_start_tag("os");
1867   if (FPR->osscan_opentcpport > 0) {
1868     xml_open_start_tag("portused");
1869     xml_attribute("state", "open");
1870     xml_attribute("proto", "tcp");
1871     xml_attribute("portid", "%d", FPR->osscan_opentcpport);
1872     xml_close_empty_tag();
1873     xml_newline();
1874   }
1875   if (FPR->osscan_closedtcpport > 0) {
1876     xml_open_start_tag("portused");
1877     xml_attribute("state", "closed");
1878     xml_attribute("proto", "tcp");
1879     xml_attribute("portid", "%d", FPR->osscan_closedtcpport);
1880     xml_close_empty_tag();
1881     xml_newline();
1882   }
1883   if (FPR->osscan_closedudpport > 0) {
1884     xml_open_start_tag("portused");
1885     xml_attribute("state", "closed");
1886     xml_attribute("proto", "udp");
1887     xml_attribute("portid", "%d", FPR->osscan_closedudpport);
1888     xml_close_empty_tag();
1889     xml_newline();
1890   }
1891 
1892   if (osscan_flag == OS_PERF_UNREL &&
1893       !(FPR->overall_results == OSSCAN_TOOMANYMATCHES ||
1894         (FPR->num_perfect_matches > 8 && !o.debugging)))
1895     log_write(LOG_PLAIN, "Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port\n");
1896 
1897   // If the FP can't be submitted anyway, might as well make a guess.
1898   const char *reason = FPR->OmitSubmissionFP();
1899   printosclassificationoutput(FPR->getOSClassification(), o.osscan_guess || reason);
1900 
1901   if (FPR->overall_results == OSSCAN_SUCCESS &&
1902       (FPR->num_perfect_matches <= 8 || o.debugging)) {
1903     /* Success, not too many perfect matches. */
1904     if (FPR->num_perfect_matches > 0) {
1905       /* Some perfect matches. */
1906       for (i = 0; i < FPR->num_perfect_matches; i++)
1907         write_xml_osmatch(FPR->matches[i], FPR->accuracy[i]);
1908 
1909       log_write(LOG_MACHINE, "\tOS: %s", FPR->matches[0]->OS_name);
1910       for (i = 1; i < FPR->num_perfect_matches; i++)
1911         log_write(LOG_MACHINE, "|%s", FPR->matches[i]->OS_name);
1912 
1913       unsigned short numprints = FPR->matches[0]->numprints;
1914       log_write(LOG_PLAIN, "OS details: %s", FPR->matches[0]->OS_name);
1915       for (i = 1; i < FPR->num_perfect_matches; i++) {
1916         numprints = MIN(numprints, FPR->matches[i]->numprints);
1917         log_write(LOG_PLAIN, ", %s", FPR->matches[i]->OS_name);
1918       }
1919       log_write(LOG_PLAIN, "\n");
1920 
1921       /* Suggest submission of an already-matching IPv6 fingerprint with
1922        * decreasing probability as numprints increases, and never if the group
1923        * has 5 or more prints or if the print is unsuitable. */
1924       bool suggest_submission = currenths->af() == AF_INET6 && reason == NULL && rand() % 5 >= numprints;
1925       if (suggest_submission)
1926         log_write(LOG_NORMAL | LOG_SKID_NOXLT | LOG_STDOUT,
1927             "Nmap needs more fingerprint submissions of this type. Please submit via https://nmap.org/submit/\n");
1928       if (suggest_submission || o.debugging || o.verbose > 1)
1929         write_merged_fpr(FPR, currenths, reason == NULL, true);
1930     } else {
1931       /* No perfect matches. */
1932       if ((o.verbose > 1 || o.debugging) && reason)
1933         log_write(LOG_NORMAL | LOG_SKID_NOXLT | LOG_STDOUT,
1934                   "OS fingerprint not ideal because: %s\n", reason);
1935 
1936       for (i = 0; i < 10 && i < FPR->num_matches && FPR->accuracy[i] > FPR->accuracy[0] - 0.10; i++)
1937         write_xml_osmatch(FPR->matches[i], FPR->accuracy[i]);
1938 
1939       if ((o.osscan_guess || reason) && FPR->num_matches > 0) {
1940         /* Print the best guesses available */
1941         log_write(LOG_PLAIN, "Aggressive OS guesses: %s (%.f%%)",
1942                   FPR->matches[0]->OS_name, floor(FPR->accuracy[0] * 100));
1943         for (i = 1; i < 10 && FPR->num_matches > i && FPR->accuracy[i] > FPR->accuracy[0] - 0.10; i++)
1944           log_write(LOG_PLAIN, ", %s (%.f%%)", FPR->matches[i]->OS_name, floor(FPR->accuracy[i] * 100));
1945 
1946         log_write(LOG_PLAIN, "\n");
1947       }
1948 
1949       if (!reason) {
1950         log_write(LOG_NORMAL | LOG_SKID_NOXLT | LOG_STDOUT,
1951                   "No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).\n");
1952         write_merged_fpr(FPR, currenths, true, true);
1953       } else {
1954         log_write(LOG_NORMAL | LOG_SKID_NOXLT | LOG_STDOUT,
1955                   "No exact OS matches for host (test conditions non-ideal).\n");
1956         if (o.verbose > 1 || o.debugging)
1957           write_merged_fpr(FPR, currenths, false, false);
1958       }
1959     }
1960   } else if (FPR->overall_results == OSSCAN_NOMATCHES) {
1961     /* No matches at all. */
1962     if (!reason) {
1963       log_write(LOG_NORMAL | LOG_SKID_NOXLT | LOG_STDOUT,
1964                 "No OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).\n");
1965       write_merged_fpr(FPR, currenths, true, true);
1966     } else {
1967       log_write(LOG_NORMAL | LOG_SKID_NOXLT | LOG_STDOUT,
1968                 "OS fingerprint not ideal because: %s\n", reason);
1969       log_write(LOG_NORMAL | LOG_SKID_NOXLT | LOG_STDOUT,
1970                 "No OS matches for host\n");
1971       if (o.debugging || o.verbose > 1)
1972         write_merged_fpr(FPR, currenths, false, false);
1973     }
1974   } else if (FPR->overall_results == OSSCAN_TOOMANYMATCHES
1975              || (FPR->num_perfect_matches > 8 && !o.debugging)) {
1976     /* Too many perfect matches. */
1977     log_write(LOG_NORMAL | LOG_SKID_NOXLT | LOG_STDOUT,
1978               "Too many fingerprints match this host to give specific OS details\n");
1979     if (o.debugging || o.verbose > 1)
1980       write_merged_fpr(FPR, currenths, false, false);
1981   } else {
1982     assert(0);
1983   }
1984 
1985   xml_end_tag(); /* os */
1986   xml_newline();
1987 
1988   if (currenths->seq.lastboot) {
1989     char tmbuf[128];
1990     struct timeval tv;
1991     double uptime;
1992     int err = n_ctime(tmbuf, sizeof(tmbuf), &currenths->seq.lastboot);
1993     chomp(tmbuf);
1994     gettimeofday(&tv, NULL);
1995     uptime = difftime(tv.tv_sec, currenths->seq.lastboot);
1996     if (o.verbose) {
1997       if (err)
1998         log_write(LOG_PLAIN, "Uptime guess: %.3f days\n",
1999                 uptime / 86400);
2000       else
2001         log_write(LOG_PLAIN, "Uptime guess: %.3f days (since %s)\n",
2002                 uptime / 86400,
2003                 tmbuf);
2004     }
2005     xml_open_start_tag("uptime");
2006     xml_attribute("seconds", "%.0f", uptime);
2007     if (!err)
2008       xml_attribute("lastboot", "%s", tmbuf);
2009     xml_close_empty_tag();
2010     xml_newline();
2011   }
2012 
2013   if (currenths->distance != -1) {
2014     log_write(LOG_PLAIN, "Network Distance: %d hop%s\n",
2015               currenths->distance, (currenths->distance == 1) ? "" : "s");
2016     xml_open_start_tag("distance");
2017     xml_attribute("value", "%d", currenths->distance);
2018     xml_close_empty_tag();
2019     xml_newline();
2020   }
2021 
2022   if (currenths->seq.responses > 3) {
2023     p = numlst;
2024     for (i = 0; i < currenths->seq.responses; i++) {
2025       if (p - numlst > (int) (sizeof(numlst) - 15))
2026         fatal("STRANGE ERROR #3877 -- please report to fyodor@nmap.org\n");
2027       if (p != numlst)
2028         *p++ = ',';
2029       sprintf(p, "%X", currenths->seq.seqs[i]);
2030       while (*p)
2031         p++;
2032     }
2033 
2034     xml_open_start_tag("tcpsequence");
2035     xml_attribute("index", "%li", (long) currenths->seq.index);
2036     xml_attribute("difficulty", "%s", seqidx2difficultystr(currenths->seq.index));
2037     xml_attribute("values", "%s", numlst);
2038     xml_close_empty_tag();
2039     xml_newline();
2040     if (o.verbose)
2041       log_write(LOG_PLAIN, "TCP Sequence Prediction: Difficulty=%d (%s)\n", currenths->seq.index, seqidx2difficultystr(currenths->seq.index));
2042 
2043     log_write(LOG_MACHINE, "\tSeq Index: %d", currenths->seq.index);
2044   }
2045 
2046   if (currenths->seq.responses > 2) {
2047     p = numlst;
2048     for (i = 0; i < currenths->seq.responses; i++) {
2049       if (p - numlst > (int) (sizeof(numlst) - 15))
2050         fatal("STRANGE ERROR #3876 -- please report to fyodor@nmap.org\n");
2051       if (p != numlst)
2052         *p++ = ',';
2053       sprintf(p, "%hX", currenths->seq.ipids[i]);
2054       while (*p)
2055         p++;
2056     }
2057     xml_open_start_tag("ipidsequence");
2058     xml_attribute("class", "%s", ipidclass2ascii(currenths->seq.ipid_seqclass));
2059     xml_attribute("values", "%s", numlst);
2060     xml_close_empty_tag();
2061     xml_newline();
2062     if (o.verbose)
2063       log_write(LOG_PLAIN, "IP ID Sequence Generation: %s\n",
2064                 ipidclass2ascii(currenths->seq.ipid_seqclass));
2065     log_write(LOG_MACHINE, "\tIP ID Seq: %s",
2066               ipidclass2ascii(currenths->seq.ipid_seqclass));
2067 
2068     p = numlst;
2069     for (i = 0; i < currenths->seq.responses; i++) {
2070       if (p - numlst > (int) (sizeof(numlst) - 15))
2071         fatal("STRANGE ERROR #3878 -- please report to fyodor@nmap.org\n");
2072       if (p != numlst)
2073         *p++ = ',';
2074       sprintf(p, "%X", currenths->seq.timestamps[i]);
2075       while (*p)
2076         p++;
2077     }
2078 
2079     xml_open_start_tag("tcptssequence");
2080     xml_attribute("class", "%s", tsseqclass2ascii(currenths->seq.ts_seqclass));
2081     if (currenths->seq.ts_seqclass != TS_SEQ_UNSUPPORTED) {
2082       xml_attribute("values", "%s", numlst);
2083     }
2084     xml_close_empty_tag();
2085     xml_newline();
2086   }
2087   log_flush_all();
2088 }
2089 
2090 /* An auxiliary function for printserviceinfooutput(). Returns
2091    non-zero if a and b are considered the same hostnames. */
hostcmp(const char * a,const char * b)2092 static int hostcmp(const char *a, const char *b) {
2093   return strcasecmp(a, b) == 0;
2094 }
2095 
2096 /* Prints the alternate hostname/OS/device information we got from the service
2097    scan (if it was performed) */
printserviceinfooutput(Target * currenths)2098 void printserviceinfooutput(Target *currenths) {
2099   Port *p = NULL;
2100   Port port;
2101   struct serviceDeductions sd;
2102   int i, numhostnames = 0, numostypes = 0, numdevicetypes = 0, numcpes = 0;
2103   char hostname_tbl[MAX_SERVICE_INFO_FIELDS][FQDN_LEN+1];
2104   char ostype_tbl[MAX_SERVICE_INFO_FIELDS][64];
2105   char devicetype_tbl[MAX_SERVICE_INFO_FIELDS][64];
2106   char cpe_tbl[MAX_SERVICE_INFO_FIELDS][80];
2107   const char *delim;
2108 
2109   for (i = 0; i < MAX_SERVICE_INFO_FIELDS; i++)
2110     hostname_tbl[i][0] = ostype_tbl[i][0] = devicetype_tbl[i][0] = cpe_tbl[i][0] = '\0';
2111 
2112   while ((p = currenths->ports.nextPort(p, &port, TCPANDUDPANDSCTP, PORT_OPEN))) {
2113     std::vector<char *>::iterator it;
2114 
2115     // The following 2 lines (from portlist.h) tell us that we don't need to
2116     // worry about free()ing anything in the serviceDeductions struct. pass in
2117     // an allocated struct serviceDeductions (don't worry about initializing, and
2118     // you don't have to free any internal ptrs.
2119     currenths->ports.getServiceDeductions(p->portno, p->proto, &sd);
2120 
2121     if (sd.hostname && !hostcmp(currenths->HostName(), sd.hostname)) {
2122       for (i = 0; i < MAX_SERVICE_INFO_FIELDS; i++) {
2123         if (hostname_tbl[i][0] && hostcmp(&hostname_tbl[i][0], sd.hostname))
2124           break;
2125 
2126         if (!hostname_tbl[i][0]) {
2127           numhostnames++;
2128           strncpy(&hostname_tbl[i][0], sd.hostname, sizeof(hostname_tbl[i]));
2129           break;
2130         }
2131       }
2132     }
2133 
2134     if (sd.ostype) {
2135       for (i = 0; i < MAX_SERVICE_INFO_FIELDS; i++) {
2136         if (ostype_tbl[i][0] && !strcmp(&ostype_tbl[i][0], sd.ostype))
2137           break;
2138 
2139         if (!ostype_tbl[i][0]) {
2140           numostypes++;
2141           strncpy(&ostype_tbl[i][0], sd.ostype, sizeof(ostype_tbl[i]));
2142           break;
2143         }
2144       }
2145     }
2146 
2147     if (sd.devicetype) {
2148       for (i = 0; i < MAX_SERVICE_INFO_FIELDS; i++) {
2149         if (devicetype_tbl[i][0] && !strcmp(&devicetype_tbl[i][0], sd.devicetype))
2150           break;
2151 
2152         if (!devicetype_tbl[i][0]) {
2153           numdevicetypes++;
2154           strncpy(&devicetype_tbl[i][0], sd.devicetype, sizeof(devicetype_tbl[i]));
2155           break;
2156         }
2157       }
2158     }
2159 
2160     for (it = sd.cpe.begin(); it != sd.cpe.end(); it++) {
2161       for (i = 0; i < MAX_SERVICE_INFO_FIELDS; i++) {
2162         if (cpe_tbl[i][0] && !strcmp(&cpe_tbl[i][0], *it))
2163           break;
2164         /* Applications (CPE part "a") aren't shown in this summary list in
2165            normal output. "a" classifications belong to an individual port, not
2166            the entire host, unlike "h" (hardware) and "o" (operating system).
2167            There isn't a good place to put the "a" classifications, so they are
2168            written to XML only. */
2169         if (cpe_get_part(*it) == 'a')
2170           break;
2171 
2172         if (!cpe_tbl[i][0]) {
2173           numcpes++;
2174           strncpy(&cpe_tbl[i][0], *it, sizeof(cpe_tbl[i]));
2175           break;
2176         }
2177       }
2178     }
2179 
2180   }
2181 
2182   if (!numhostnames && !numostypes && !numdevicetypes && !numcpes)
2183     return;
2184 
2185   log_write(LOG_PLAIN, "Service Info:");
2186 
2187   delim = " ";
2188   if (numhostnames) {
2189     log_write(LOG_PLAIN, "%sHost%s: %s", delim, numhostnames == 1 ? "" : "s", &hostname_tbl[0][0]);
2190     for (i = 1; i < MAX_SERVICE_INFO_FIELDS; i++) {
2191       if (hostname_tbl[i][0])
2192         log_write(LOG_PLAIN, ", %s", &hostname_tbl[i][0]);
2193     }
2194     delim = "; ";
2195   }
2196 
2197   if (numostypes) {
2198     log_write(LOG_PLAIN, "%sOS%s: %s", delim, numostypes == 1 ? "" : "s",
2199               &ostype_tbl[0][0]);
2200     for (i = 1; i < MAX_SERVICE_INFO_FIELDS; i++) {
2201       if (ostype_tbl[i][0])
2202         log_write(LOG_PLAIN, ", %s", &ostype_tbl[i][0]);
2203     }
2204     delim = "; ";
2205   }
2206 
2207   if (numdevicetypes) {
2208     log_write(LOG_PLAIN, "%sDevice%s: %s", delim,
2209               numdevicetypes == 1 ? "" : "s", &devicetype_tbl[0][0]);
2210     for (i = 1; i < MAX_SERVICE_INFO_FIELDS; i++) {
2211       if (devicetype_tbl[i][0])
2212         log_write(LOG_PLAIN, ", %s", &devicetype_tbl[i][0]);
2213     }
2214     delim = "; ";
2215   }
2216 
2217   if (numcpes > 0) {
2218     log_write(LOG_PLAIN, "%sCPE: %s", delim, &cpe_tbl[0][0]);
2219     for (i = 1; i < MAX_SERVICE_INFO_FIELDS; i++) {
2220       if (cpe_tbl[i][0])
2221         log_write(LOG_PLAIN, ", %s", &cpe_tbl[i][0]);
2222     }
2223     delim = "; ";
2224   }
2225 
2226   log_write(LOG_PLAIN, "\n");
2227   log_flush_all();
2228 }
2229 
2230 #ifndef NOLUA
printscriptresults(ScriptResults * scriptResults,stype scantype)2231 void printscriptresults(ScriptResults *scriptResults, stype scantype) {
2232   ScriptResults::iterator iter;
2233   char *script_output;
2234 
2235   if (scriptResults->size() > 0) {
2236     scriptResults->sort(scriptid_lessthan);
2237     if (scantype == SCRIPT_PRE_SCAN) {
2238       xml_start_tag("prescript");
2239       log_write(LOG_PLAIN, "Pre-scan script results:\n");
2240     } else {
2241       xml_start_tag("postscript");
2242       log_write(LOG_PLAIN, "Post-scan script results:\n");
2243     }
2244     for (iter = scriptResults->begin(); iter != scriptResults->end(); iter++) {
2245       iter->write_xml();
2246       script_output = formatScriptOutput((*iter));
2247       if (script_output != NULL) {
2248         log_write(LOG_PLAIN, "%s\n", script_output);
2249         free(script_output);
2250       }
2251     }
2252     xml_end_tag();
2253   }
2254 }
2255 
printhostscriptresults(Target * currenths)2256 void printhostscriptresults(Target *currenths) {
2257   ScriptResults::iterator iter;
2258   char *script_output;
2259 
2260   if (currenths->scriptResults.size() > 0) {
2261     currenths->scriptResults.sort(scriptid_lessthan);
2262     xml_start_tag("hostscript");
2263     log_write(LOG_PLAIN, "\nHost script results:\n");
2264     for (iter = currenths->scriptResults.begin();
2265          iter != currenths->scriptResults.end();
2266          iter++) {
2267       iter->write_xml();
2268 
2269       script_output = formatScriptOutput((*iter));
2270       if (script_output != NULL) {
2271         log_write(LOG_PLAIN, "%s\n", script_output);
2272         free(script_output);
2273       }
2274     }
2275     xml_end_tag();
2276   }
2277 }
2278 #endif
2279 
2280 /* Print a table with traceroute hops. */
printtraceroute_normal(Target * currenths)2281 static void printtraceroute_normal(Target *currenths) {
2282   static const int HOP_COL = 0, RTT_COL = 1, HOST_COL = 2;
2283   NmapOutputTable Tbl(currenths->traceroute_hops.size() + 1, 3);
2284   struct probespec probe;
2285   std::list<TracerouteHop>::iterator it;
2286   int row;
2287 
2288   /* No trace, must be localhost. */
2289   if (currenths->traceroute_hops.size() == 0)
2290     return;
2291 
2292   /* Print header. */
2293   log_write(LOG_PLAIN, "\n");
2294   probe = currenths->traceroute_probespec;
2295   if (probe.type == PS_TCP) {
2296     log_write(LOG_PLAIN, "TRACEROUTE (using port %d/%s)\n",
2297               probe.pd.tcp.dport, proto2ascii_lowercase(probe.proto));
2298   } else if (probe.type == PS_UDP) {
2299     log_write(LOG_PLAIN, "TRACEROUTE (using port %d/%s)\n",
2300               probe.pd.udp.dport, proto2ascii_lowercase(probe.proto));
2301   } else if (probe.type == PS_SCTP) {
2302     log_write(LOG_PLAIN, "TRACEROUTE (using port %d/%s)\n",
2303               probe.pd.sctp.dport, proto2ascii_lowercase(probe.proto));
2304   } else if (probe.type == PS_ICMP || probe.type == PS_ICMPV6 || probe.type == PS_PROTO) {
2305     struct protoent *proto = nmap_getprotbynum(probe.proto);
2306     log_write(LOG_PLAIN, "TRACEROUTE (using proto %d/%s)\n",
2307               probe.proto, proto ? proto->p_name : "unknown");
2308   } else if (probe.type == PS_NONE) {
2309     /* "Traces" of directly connected targets don't send any packets. */
2310     log_write(LOG_PLAIN, "TRACEROUTE\n");
2311   } else {
2312     fatal("Unknown probe type %d.", probe.type);
2313   }
2314 
2315   row = 0;
2316   Tbl.addItem(row, HOP_COL, false, "HOP");
2317   Tbl.addItem(row, RTT_COL, false, "RTT");
2318   Tbl.addItem(row, HOST_COL, false, "ADDRESS");
2319   row++;
2320 
2321   it = currenths->traceroute_hops.begin();
2322 
2323   if (!o.debugging) {
2324     /* Consolidate shared hops. */
2325     TracerouteHop *shared_hop = NULL;
2326     struct sockaddr_storage addr;
2327     size_t sslen;
2328 
2329     sslen = sizeof(addr);
2330     currenths->TargetSockAddr(&addr, &sslen);
2331     while (it != currenths->traceroute_hops.end()
2332            && !sockaddr_storage_equal(&it->tag, &addr)) {
2333       shared_hop = &*it;
2334       it++;
2335     }
2336 
2337     if (shared_hop != NULL) {
2338       Tbl.addItem(row, HOP_COL, false, "-");
2339       if (shared_hop->ttl == 1) {
2340         Tbl.addItemFormatted(row, RTT_COL, true,
2341           "Hop 1 is the same as for %s",
2342           inet_ntop_ez(&shared_hop->tag, sizeof(shared_hop->tag)));
2343       } else if (shared_hop->ttl > 1) {
2344         Tbl.addItemFormatted(row, RTT_COL, true,
2345           "Hops 1-%d are the same as for %s", shared_hop->ttl,
2346           inet_ntop_ez(&shared_hop->tag, sizeof(shared_hop->tag)));
2347       }
2348       row++;
2349     }
2350   }
2351 
2352   while (it != currenths->traceroute_hops.end()) {
2353     Tbl.addItemFormatted(row, HOP_COL, false, "%d", it->ttl);
2354     if (it->timedout) {
2355       if (o.debugging) {
2356         Tbl.addItem(row, RTT_COL, false, "...");
2357         it++;
2358       } else {
2359         /* The beginning and end of timeout consolidation. */
2360         int begin_ttl, end_ttl;
2361         begin_ttl = end_ttl = it->ttl;
2362         for (; it != currenths->traceroute_hops.end() && it->timedout; it++)
2363           end_ttl = it->ttl;
2364         if (begin_ttl == end_ttl)
2365           Tbl.addItem(row, RTT_COL, false, "...");
2366         else
2367           Tbl.addItemFormatted(row, RTT_COL, false, "... %d", end_ttl);
2368       }
2369       row++;
2370     } else {
2371       /* Normal hop output. */
2372       char namebuf[256];
2373 
2374       it->display_name(namebuf, sizeof(namebuf));
2375       if (it->rtt < 0)
2376         Tbl.addItem(row, RTT_COL, false, "--");
2377       else
2378         Tbl.addItemFormatted(row, RTT_COL, false, "%.2f ms", it->rtt);
2379       Tbl.addItemFormatted(row, HOST_COL, false, "%s", namebuf);
2380       row++;
2381       it++;
2382     }
2383   }
2384 
2385   log_write(LOG_PLAIN, "%s", Tbl.printableTable(NULL));
2386 
2387   log_flush(LOG_PLAIN);
2388 }
2389 
printtraceroute_xml(Target * currenths)2390 static void printtraceroute_xml(Target *currenths) {
2391   struct probespec probe;
2392   std::list<TracerouteHop>::iterator it;
2393 
2394   /* No trace, must be localhost. */
2395   if (currenths->traceroute_hops.size() == 0)
2396     return;
2397 
2398   /* XML traceroute header */
2399   xml_open_start_tag("trace");
2400 
2401   probe = currenths->traceroute_probespec;
2402   if (probe.type == PS_TCP) {
2403     xml_attribute("port", "%d", probe.pd.tcp.dport);
2404     xml_attribute("proto", "%s", proto2ascii_lowercase(probe.proto));
2405   } else if (probe.type == PS_UDP) {
2406     xml_attribute("port", "%d", probe.pd.udp.dport);
2407     xml_attribute("proto", "%s", proto2ascii_lowercase(probe.proto));
2408   } else if (probe.type == PS_SCTP) {
2409     xml_attribute("port", "%d", probe.pd.sctp.dport);
2410     xml_attribute("proto", "%s", proto2ascii_lowercase(probe.proto));
2411   } else if (probe.type == PS_ICMP || probe.type == PS_PROTO) {
2412     struct protoent *proto = nmap_getprotbynum(probe.proto);
2413     if (proto == NULL)
2414       xml_attribute("proto", "%d", probe.proto);
2415     else
2416       xml_attribute("proto", "%s", proto->p_name);
2417   }
2418   xml_close_start_tag();
2419   xml_newline();
2420 
2421   for (it = currenths->traceroute_hops.begin();
2422        it != currenths->traceroute_hops.end();
2423        it++) {
2424     if (it->timedout)
2425       continue;
2426     xml_open_start_tag("hop");
2427     xml_attribute("ttl", "%d", it->ttl);
2428     xml_attribute("ipaddr", "%s", inet_ntop_ez(&it->addr, sizeof(it->addr)));
2429     if (it->rtt < 0)
2430       xml_attribute("rtt", "--");
2431     else
2432       xml_attribute("rtt", "%.2f", it->rtt);
2433     if (!it->name.empty())
2434       xml_attribute("host", "%s", it->name.c_str());
2435     xml_close_empty_tag();
2436     xml_newline();
2437   }
2438 
2439   /* traceroute XML footer */
2440   xml_end_tag();
2441   xml_newline();
2442   log_flush(LOG_XML);
2443 }
2444 
printtraceroute(Target * currenths)2445 void printtraceroute(Target *currenths) {
2446   printtraceroute_normal(currenths);
2447   printtraceroute_xml(currenths);
2448 }
2449 
printtimes(Target * currenths)2450 void printtimes(Target *currenths) {
2451   if (currenths->to.srtt != -1 || currenths->to.rttvar != -1) {
2452     if (o.debugging) {
2453       log_write(LOG_STDOUT, "Final times for host: srtt: %d rttvar: %d  to: %d\n",
2454         currenths->to.srtt, currenths->to.rttvar, currenths->to.timeout);
2455     }
2456     xml_open_start_tag("times");
2457     xml_attribute("srtt", "%d", currenths->to.srtt);
2458     xml_attribute("rttvar", "%d", currenths->to.rttvar);
2459     xml_attribute("to", "%d", currenths->to.timeout);
2460     xml_close_empty_tag();
2461     xml_newline();
2462   }
2463 }
2464 
2465 /* Prints a status message while the program is running */
printStatusMessage()2466 void printStatusMessage() {
2467   // Pre-computations
2468   struct timeval tv;
2469   gettimeofday(&tv, NULL);
2470   int time = (int) (o.TimeSinceStart(&tv));
2471 
2472   log_write(LOG_STDOUT, "Stats: %d:%02d:%02d elapsed; %d hosts completed (%d up), %d undergoing %s\n",
2473             time / 60 / 60, time / 60 % 60, time % 60, o.numhosts_scanned,
2474             o.numhosts_up, o.numhosts_scanning,
2475             scantype2str(o.current_scantype));
2476 }
2477 
2478 /* Prints the beginning of a "finished" start tag, with time, timestr, and
2479    elapsed attributes. Leaves the start tag open so you can add more attributes.
2480    You have to close the tag with xml_close_empty_tag. */
print_xml_finished_open(time_t timep,const struct timeval * tv)2481 void print_xml_finished_open(time_t timep, const struct timeval *tv) {
2482   char mytime[128];
2483   int err = n_ctime(mytime, sizeof(mytime), &timep);
2484 
2485   chomp(mytime);
2486 
2487   xml_open_start_tag("finished");
2488   xml_attribute("time", "%lu", (unsigned long) timep);
2489   if (!err) {
2490     xml_attribute("timestr", "%s", mytime);
2491     xml_attribute("summary",
2492         "Nmap done at %s; %u %s (%u %s up) scanned in %.2f seconds",
2493         mytime, o.numhosts_scanned,
2494         (o.numhosts_scanned == 1) ? "IP address" : "IP addresses",
2495         o.numhosts_up, (o.numhosts_up == 1) ? "host" : "hosts",
2496         o.TimeSinceStart(tv));
2497   }
2498   else {
2499     xml_attribute("summary",
2500         "Nmap done; %u %s (%u %s up) scanned in %.2f seconds",
2501         o.numhosts_scanned,
2502         (o.numhosts_scanned == 1) ? "IP address" : "IP addresses",
2503         o.numhosts_up, (o.numhosts_up == 1) ? "host" : "hosts",
2504         o.TimeSinceStart(tv));
2505   }
2506   xml_attribute("elapsed", "%.2f", o.TimeSinceStart(tv));
2507 }
2508 
print_xml_hosts()2509 void print_xml_hosts() {
2510   xml_open_start_tag("hosts");
2511   xml_attribute("up", "%d", o.numhosts_up);
2512   xml_attribute("down", "%d", o.numhosts_scanned - o.numhosts_up);
2513   xml_attribute("total", "%d", o.numhosts_scanned);
2514   xml_close_empty_tag();
2515 }
2516 
2517 /* Prints the statistics and other information that goes at the very end
2518    of an Nmap run */
printfinaloutput()2519 void printfinaloutput() {
2520   time_t timep;
2521   char mytime[128];
2522   int err = 0;
2523   struct timeval tv;
2524   char statbuf[128];
2525 
2526   gettimeofday(&tv, NULL);
2527   timep = time(NULL);
2528 
2529   if (o.numhosts_scanned == 0
2530 #ifndef NOLUA
2531       && !o.scriptupdatedb
2532 #endif
2533       )
2534     error("WARNING: No targets were specified, so 0 hosts scanned.");
2535   if (o.numhosts_scanned == 1 && o.numhosts_up == 0 && !o.listscan &&
2536       o.pingtype != PINGTYPE_NONE)
2537     log_write(LOG_STDOUT, "Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn\n");
2538   else if (o.numhosts_up > 0) {
2539     if (o.osscan && o.servicescan)
2540       log_write(LOG_PLAIN, "OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .\n");
2541     else if (o.osscan)
2542       log_write(LOG_PLAIN, "OS detection performed. Please report any incorrect results at https://nmap.org/submit/ .\n");
2543     else if (o.servicescan)
2544       log_write(LOG_PLAIN, "Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .\n");
2545     else if (o.udpscan && o.defeat_icmp_ratelimit)
2546       log_write(LOG_PLAIN, "WARNING: Some ports marked closed|filtered may actually be open. For more accurate results, do not use --defeat-icmp-ratelimit .\n");
2547 
2548   }
2549 
2550   log_write(LOG_STDOUT | LOG_SKID,
2551             "Nmap done: %u %s (%u %s up) scanned in %.2f seconds\n",
2552             o.numhosts_scanned,
2553             (o.numhosts_scanned == 1) ? "IP address" : "IP addresses",
2554             o.numhosts_up, (o.numhosts_up == 1) ? "host" : "hosts",
2555             o.TimeSinceStart(&tv));
2556   if (o.verbose && o.isr00t && o.RawScan())
2557     log_write(LOG_STDOUT | LOG_SKID, "           %s\n",
2558               getFinalPacketStats(statbuf, sizeof(statbuf)));
2559 
2560   xml_start_tag("runstats");
2561   print_xml_finished_open(timep, &tv);
2562   xml_attribute("exit", "success");
2563   xml_close_empty_tag();
2564   print_xml_hosts();
2565   xml_newline();
2566   xml_end_tag();
2567   xml_newline();
2568 
2569   err = n_ctime(mytime, sizeof(mytime), &timep);
2570   if (!err) {
2571     chomp(mytime);
2572     log_write(LOG_NORMAL | LOG_MACHINE,
2573         "# Nmap done at %s -- %u %s (%u %s up) scanned in %.2f seconds\n",
2574         mytime, o.numhosts_scanned,
2575         (o.numhosts_scanned == 1) ? "IP address" : "IP addresses",
2576         o.numhosts_up, (o.numhosts_up == 1) ? "host" : "hosts",
2577         o.TimeSinceStart(&tv));
2578   }
2579   else {
2580     log_write(LOG_NORMAL | LOG_MACHINE,
2581         "# Nmap done -- %u %s (%u %s up) scanned in %.2f seconds\n",
2582         o.numhosts_scanned,
2583         (o.numhosts_scanned == 1) ? "IP address" : "IP addresses",
2584         o.numhosts_up, (o.numhosts_up == 1) ? "host" : "hosts",
2585         o.TimeSinceStart(&tv));
2586   }
2587 
2588   xml_end_tag(); /* nmaprun */
2589   xml_newline();
2590   log_flush_all();
2591 }
2592 
2593 /* A record consisting of a data file name ("nmap-services", "nmap-os-db",
2594    etc.), and the directory and file in which is was found. This is a
2595    broken-down version of what is stored in o.loaded_data_files. It is used in
2596    printdatafilepaths. */
2597 struct data_file_record {
2598   std::string data_file;
2599   std::string dir;
2600   std::string file;
2601 
2602   /* Compares this record to another. First compare the directory names, then
2603      compare the file names. */
operator <data_file_record2604   bool operator<(const struct data_file_record &other) const {
2605     int cmp;
2606 
2607     cmp = dir.compare(other.dir);
2608     if (cmp == 0)
2609       cmp = file.compare(other.file);
2610 
2611     return cmp < 0;
2612   }
2613 };
2614 
2615 /* Prints the names of data files that were loaded and the paths at which they
2616    were found. */
printdatafilepaths()2617 void printdatafilepaths() {
2618   std::list<struct data_file_record> df;
2619   std::list<struct data_file_record>::iterator iter;
2620   std::map<std::string, std::string>::iterator map_iter;
2621   std::string dir;
2622   unsigned int num_dirs;
2623 
2624   /* Copy the elements of o.loaded_data_files (each a (data file, path) pair) to
2625      a list of data_file_records to make them easier to manipulate. */
2626   for (map_iter = o.loaded_data_files.begin();
2627        map_iter != o.loaded_data_files.end(); map_iter++) {
2628     struct data_file_record r;
2629     char *s;
2630 
2631     r.data_file = map_iter->first;
2632     s = path_get_dirname(map_iter->second.c_str());
2633     if (s == NULL)
2634       fatal("%s: failed to allocate temporary memory", __func__);
2635     r.dir = std::string(s);
2636     free(s);
2637     s = path_get_basename(map_iter->second.c_str());
2638     if (s == NULL)
2639       fatal("%s: failed to allocate temporary memory", __func__);
2640     r.file = std::string(s);
2641     free(s);
2642 
2643     df.push_back(r);
2644   }
2645 
2646   /* Sort the list, first by directory name, then by file name. This ensures
2647      that records with the same directory name are contiguous. */
2648   df.sort();
2649 
2650   /* Count the number of distinct directories. Normally we print something only
2651      if files came from more than one directory. */
2652   if (df.empty()) {
2653     num_dirs = 0;
2654   } else {
2655     num_dirs = 1;
2656     iter = df.begin();
2657     dir = iter->dir;
2658     for (iter++; iter != df.end(); iter++) {
2659       if (iter->dir != dir) {
2660         num_dirs++;
2661         dir = iter->dir;
2662       }
2663     }
2664   }
2665 
2666   /* Decide what to print out based on the number of distinct directories and
2667      the verbosity and debugging levels. */
2668   if (num_dirs == 0) {
2669     /* If no files were read, print a message only in debugging mode. */
2670     if (o.debugging > 0)
2671       log_write(LOG_PLAIN, "No data files read.\n");
2672   } else if (num_dirs == 1 && o.verbose && !o.debugging) {
2673     /* If all the files were from the same directory and we're in verbose mode,
2674        print a brief message unless we are also in debugging mode. */
2675     log_write(LOG_PLAIN, "Read data files from: %s\n", dir.c_str());
2676   } else if ((num_dirs == 1 && o.debugging) || num_dirs > 1) {
2677     /* If files were read from more than one directory, or if they were read
2678        from one directory and we are in debugging mode, display all the files
2679        grouped by directory. */
2680     iter = df.begin();
2681     while (iter != df.end()) {
2682       dir = iter->dir;
2683       /* Write the directory name. */
2684       log_write(LOG_PLAIN, "Read from %s:", dir.c_str());
2685       /* Write files in that directory on the same line. */
2686       while (iter != df.end() && iter->dir == dir) {
2687         log_write(LOG_PLAIN, " %s", iter->file.c_str());
2688         iter++;
2689       }
2690       log_write(LOG_PLAIN, ".\n");
2691     }
2692   }
2693 }
2694 
nslog2str(nsock_loglevel_t loglevel)2695 static inline const char *nslog2str(nsock_loglevel_t loglevel) {
2696   switch(loglevel) {
2697     case NSOCK_LOG_DBG_ALL:
2698       return "DEBUG FULL";
2699     case NSOCK_LOG_DBG:
2700       return "DEBUG";
2701     case NSOCK_LOG_INFO:
2702       return "INFO";
2703     case NSOCK_LOG_ERROR:
2704       return "ERROR";
2705     default:
2706       return "???";
2707   };
2708 }
2709 
nmap_adjust_loglevel(bool trace)2710 void nmap_adjust_loglevel(bool trace) {
2711   nsock_loglevel_t nsock_loglevel;
2712 
2713   if (o.debugging >= 7)
2714     nsock_loglevel = NSOCK_LOG_DBG_ALL;
2715   else if (o.debugging >= 4)
2716     nsock_loglevel = NSOCK_LOG_DBG;
2717   else if (trace || o.debugging >= 2)
2718     nsock_loglevel = NSOCK_LOG_INFO;
2719   else
2720     nsock_loglevel = NSOCK_LOG_ERROR;
2721 
2722   nsock_set_loglevel(nsock_loglevel);
2723 }
2724 
nmap_nsock_stderr_logger(const struct nsock_log_rec * rec)2725 static void nmap_nsock_stderr_logger(const struct nsock_log_rec *rec) {
2726   int elapsed_time;
2727 
2728   elapsed_time = TIMEVAL_MSEC_SUBTRACT(rec->time, *(o.getStartTime()));
2729 
2730   log_write(LOG_STDERR, "NSOCK %s [%.4fs] %s(): %s\n", nslog2str(rec->level),
2731             elapsed_time/1000.0, rec->func, rec->msg);
2732 }
2733 
nmap_set_nsock_logger()2734 void nmap_set_nsock_logger() {
2735   nsock_set_log_function(nmap_nsock_stderr_logger);
2736 }
2737