📄 output.cc
字号:
} } log_flush_all();}char* xml_convert (const char* str) { char *temp, ch=0, prevch = 0, *p; int strl = strlen(str); temp = (char *) malloc(strl*6+1); char *end = temp + strl * 6 + 1; for (p = temp;(prevch = ch, ch = *str);str++) { char *a; switch (ch) { case '<': a = "<"; break; case '>': a = ">"; break; case '&': a = "&"; break; case '"': a = """; break; case '\'': a = "'"; break; case '-': if (prevch == '-') { /* Must escape -- for comments */ a = "-"; break; } default: *p++ = ch; continue; } assert(end - p > 1); Strncpy(p,a, end - p - 1); p += strlen(a); // SAFE } *p = 0; temp = (char *) realloc(temp,strlen(temp)+1); return temp;}/* This is the workhorse of the logging functions. Usually it is called through log_write(), but it can be called directly if you are dealing with a vfprintf-style va_list. Unlike log_write, YOU CAN ONLY CALL THIS WITH ONE LOG TYPE (not a bitmask full of them). In addition, YOU MUST SANDWHICH EACH EXECUTION IF THIS CALL BETWEEN va_start() AND va_end() calls. */void log_vwrite(int logt, const char *fmt, va_list ap) { static char *writebuf = NULL; static int writebuflen = 8192; bool skid_noxlate = false; int rc = 0; int len; int fileidx = 0; int l; va_list apcopy; if (!writebuf) writebuf = (char *) safe_malloc(writebuflen); if (logt == LOG_SKID_NOXLT) { logt = LOG_SKID; skid_noxlate = true; } switch(logt) { case LOG_STDOUT: vfprintf(o.nmap_stdout, fmt, ap); break; case LOG_STDERR: fflush(stdout); // Otherwise some systems will print stderr out of order vfprintf(stderr, fmt, ap); break; case LOG_NORMAL: case LOG_MACHINE: case LOG_SKID: case LOG_XML:#ifdef WIN32 apcopy = ap;#else va_copy(apcopy, ap); /* Needed in case we need to so a second vnsprintf */#endif l = logt; fileidx = 0; while ((l&1)==0) { fileidx++; l>>=1; } assert(fileidx < LOG_NUM_FILES); if (o.logfd[fileidx]) { len = vsnprintf(writebuf, writebuflen, fmt, ap); if (len == 0) { va_end(apcopy); return; } else if (len < 0) { fprintf(stderr, "vnsprintf returned %d in %s -- bizarre. Quitting.\n", len, __FUNCTION__); exit(1); } else if (len >= writebuflen) { /* Didn't have enough space. Expand writebuf and try again */ free(writebuf); writebuflen = len + 1024; writebuf = (char *) safe_malloc(writebuflen); len = vsnprintf(writebuf, writebuflen, fmt, apcopy); if (len <= 0 || len >= writebuflen) { fprintf(stderr, "%s: vnsprintf failed. Even after increasing bufferlen to %d, vsnprintf returned %d (logt == %d). Please email this message to fyodor@insecure.org. Quitting.\n", __FUNCTION__, writebuflen, len, logt); exit(1); } } if (logt == LOG_SKID && !skid_noxlate) skid_output(writebuf); rc = fwrite(writebuf,len,1,o.logfd[fileidx]); if (rc != 1) { fprintf(stderr, "Failed to write %d bytes of data to (logt==%d) stream. fwrite returned %d. Quitting.\n", len, logt, rc); exit(1); } va_end(apcopy); } break; default: fprintf(stderr, "log_vwrite(): Passed unknown log type (%d). Note that this function, unlike log_write, can only handle one log type at a time (no bitmasks)\n", logt); exit(1); } return;}/* Write some information (printf style args) to the given log stream(s). Remember to watch out for format string bugs. */void log_write(int logt, const char *fmt, ...){ va_list ap; assert(logt > 0); if (!fmt || !*fmt) return; for (int l = 1; l <= LOG_MAX; l <<= 1) { if (logt & l) { va_start(ap, fmt); log_vwrite(l, fmt, ap); va_end(ap); } } return;}/* Close the given log stream(s) */void log_close(int logt){ int i; if (logt<0 || logt>LOG_FILE_MASK) return; for (i=0;logt;logt>>=1,i++) if (o.logfd[i] && (logt&1)) fclose(o.logfd[i]);}/* Flush the given log stream(s). In other words, all buffered output is written to the log immediately */void log_flush(int logt) { int i; if (logt & LOG_STDOUT) { fflush(o.nmap_stdout); logt -= LOG_STDOUT; } if (logt & LOG_STDERR) { fflush(stderr); logt -= LOG_STDERR; } if (logt & LOG_SKID_NOXLT) fatal("You are not allowed to log_flush() with LOG_SKID_NOXLT"); if (logt<0 || logt>LOG_FILE_MASK) return; for (i=0;logt;logt>>=1,i++) { if (!o.logfd[i] || !(logt&1)) continue; fflush(o.logfd[i]); }}/* Flush every single log stream -- all buffered output is written to the corresponding logs immediately */void log_flush_all() { int fileno; for(fileno = 0; fileno < LOG_NUM_FILES; fileno++) { if (o.logfd[fileno]) fflush(o.logfd[fileno]); } fflush(stdout); fflush(stderr);}/* Open a log descriptor of the type given to the filename given. If append is nonzero, the file will be appended instead of clobbered if it already exists. If the file does not exist, it will be created */int log_open(int logt, int append, char *filename){ int i=0; if (logt<=0 || logt>LOG_FILE_MASK) return -1; while ((logt&1)==0) { i++; logt>>=1; } if (o.logfd[i]) fatal("Only one %s output filename allowed",logtypes[i]); if (*filename == '-' && *(filename + 1) == '\0') { o.logfd[i]=stdout; o.nmap_stdout = fopen(DEVNULL, "w"); if (!o.nmap_stdout) fatal("Could not assign %s to stdout for writing", DEVNULL); } else { if (o.append_output) o.logfd[i] = fopen(filename, "a"); else o.logfd[i] = fopen(filename, "w"); if (!o.logfd[i]) fatal("Failed to open %s output file %s for writing", logtypes[i], filename); } return 1;}/* The items in ports should be in sequential order for space savings and easier to read output. Outputs the rangelist to the log stream given (such as LOG_MACHINE or LOG_XML) */static void output_rangelist_given_ports(int logt, unsigned short *ports, int numports) {int i, previous_port = -2, range_start = -2, port;char outpbuf[128]; for(i=0; i <= numports; i++) { port = (i < numports)? ports[i] : 0xABCDE; if (port != previous_port + 1) { outpbuf[0] = '\0'; if (range_start != previous_port && range_start != -2) sprintf(outpbuf, "-%hu", previous_port); if (port != 0xABCDE) { if (range_start != -2) strcat(outpbuf, ","); sprintf(outpbuf + strlen(outpbuf), "%hu", port); } if (*outpbuf) log_write(logt, "%s", outpbuf); range_start = port; } previous_port = port; }}/* Output the list of ports scanned to the top of machine parseable logs (in a comment, unfortunately). The items in ports should be in sequential order for space savings and easier to read output */void output_ports_to_machine_parseable_output(struct scan_lists *ports, int tcpscan, int udpscan, int protscan) { int tcpportsscanned = ports->tcp_count; int udpportsscanned = ports->udp_count; int protsscanned = ports->prot_count; log_write(LOG_MACHINE, "# Ports scanned: TCP(%d;", tcpportsscanned); if (tcpportsscanned) output_rangelist_given_ports(LOG_MACHINE, ports->tcp_ports, tcpportsscanned); log_write(LOG_MACHINE, ") UDP(%d;", udpportsscanned); if (udpportsscanned) output_rangelist_given_ports(LOG_MACHINE, ports->udp_ports, udpportsscanned); log_write(LOG_MACHINE, ") PROTOCOLS(%d;", protsscanned); if (protsscanned) output_rangelist_given_ports(LOG_MACHINE, ports->prots, protsscanned); log_write(LOG_MACHINE, ")\n"); log_flush_all();}/* Simple helper function for output_xml_scaninfo_records */static void doscaninfo(char *type, char *proto, unsigned short *ports, int numports) { log_write(LOG_XML, "<scaninfo type=\"%s\" protocol=\"%s\" numservices=\"%d\" services=\"", type, proto, numports); output_rangelist_given_ports(LOG_XML, ports, numports); log_write(LOG_XML, "\" />\n");}/* Similar to output_ports_to_machine_parseable_output, this function outputs the XML version, which is scaninfo records of each scan requested and the ports which it will scan for */void output_xml_scaninfo_records(struct scan_lists *scanlist) { if (o.synscan) doscaninfo("syn", "tcp", scanlist->tcp_ports, scanlist->tcp_count); if (o.ackscan) doscaninfo("ack", "tcp", scanlist->tcp_ports, scanlist->tcp_count); if (o.bouncescan) doscaninfo("bounce", "tcp", scanlist->tcp_ports, scanlist->tcp_count); if (o.connectscan) doscaninfo("connect", "tcp", scanlist->tcp_ports, scanlist->tcp_count); if (o.nullscan) doscaninfo("null", "tcp", scanlist->tcp_ports, scanlist->tcp_count); if (o.xmasscan) doscaninfo("xmas", "tcp", scanlist->tcp_ports, scanlist->tcp_count); if (o.windowscan) doscaninfo("window", "tcp", scanlist->tcp_ports, scanlist->tcp_count); if (o.maimonscan) doscaninfo("maimon", "tcp", scanlist->tcp_ports, scanlist->tcp_count); if (o.finscan) doscaninfo("fin", "tcp", scanlist->tcp_ports, scanlist->tcp_count); if (o.udpscan) doscaninfo("udp", "udp", scanlist->udp_ports, scanlist->udp_count); if (o.ipprotscan) doscaninfo("ipproto", "ip", scanlist->prots, scanlist->prot_count); log_flush_all();}/* Prints the MAC address (if discovered) to XML output */static void print_MAC_XML_Info(Target *currenths) { const u8 *mac = currenths->MACAddress(); char macascii[32]; char vendorstr[128]; char *xml_mac = NULL; if (mac) { const char *macvendor = MACPrefix2Corp(mac); snprintf(macascii, sizeof(macascii), "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); if (macvendor) { xml_mac = xml_convert(macvendor); snprintf(vendorstr, sizeof(vendorstr), " vendor=\"%s\"", xml_mac); free(xml_mac); } else vendorstr[0] = '\0'; log_write(LOG_XML, "<address addr=\"%s\" addrtype=\"mac\"%s />\n", macascii, vendorstr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -