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, ¤t->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, ¤t->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), ¤ths->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