📄 output.cc
字号:
}}/* Helper function to write the status and address/hostname info of a host into the XML log */static void write_xml_initial_hostinfo(Target *currenths, const char *status) { log_write(LOG_XML, "<status state=\"%s\" />\n<address addr=\"%s\" addrtype=\"%s\" />\n", status,currenths->targetipstr(), (o.af() == AF_INET)? "ipv4" : "ipv6"); print_MAC_XML_Info(currenths); if (*currenths->HostName()) { log_write(LOG_XML, "<hostnames><hostname name=\"%s\" type=\"PTR\" /></hostnames>\n", currenths->HostName()); } else /* If machine is up, put blank hostname so front ends know that no name resolution is forthcoming */ if (strcmp(status, "up") == 0) log_write(LOG_XML, "<hostnames />\n"); log_flush_all();}/* Writes host status info to the log streams (including STDOUT). An example is "Host: 10.11.12.13 (foo.bar.example.com)\tStatus: Up\n" to machine log. resolve_all should be passed nonzero if the user asked for all hosts (even down ones) to be resolved */void write_host_status(Target *currenths, int resolve_all) { char hostname[1200]; if (o.listscan) { /* write "unknown" to stdout, machine, and xml */ log_write(LOG_STDOUT|LOG_NORMAL|LOG_SKID, "Host %s not scanned\n", currenths->NameIP(hostname, sizeof(hostname))); log_write(LOG_MACHINE, "Host: %s (%s)\tStatus: Unknown\n", currenths->targetipstr(), currenths->HostName()); write_xml_initial_hostinfo(currenths, "unknown"); } else if (currenths->wierd_responses) { /* SMURF ADDRESS */ /* Write xml "down" or "up" based on flags and the smurf info */ write_xml_initial_hostinfo(currenths, (currenths->flags & HOST_UP)? "up" : "down"); log_write(LOG_XML, "<smurf responses=\"%d\" />\n", currenths->wierd_responses); log_write(LOG_MACHINE,"Host: %s (%s)\tStatus: Smurf (%d responses)\n", currenths->targetipstr(), currenths->HostName(), currenths->wierd_responses); if (o.pingscan) log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"Host %s seems to be a subnet broadcast address (returned %d extra pings).%s\n", currenths->NameIP(hostname, sizeof(hostname)), currenths->wierd_responses, (currenths->flags & HOST_UP)? " Note -- the actual IP also responded." : ""); else { log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"Host %s seems to be a subnet broadcast address (returned %d extra pings). %s.\n", currenths->NameIP(hostname, sizeof(hostname)), currenths->wierd_responses, (currenths->flags & HOST_UP)? " Still scanning it due to ping response from its own IP" : "Skipping host"); } } else if (o.pingscan) { write_xml_initial_hostinfo(currenths, (currenths->flags & HOST_UP)? "up" : "down"); if (currenths->flags & HOST_UP) { log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"Host %s appears to be up.\n", currenths->NameIP(hostname, sizeof(hostname))); log_write(LOG_MACHINE,"Host: %s (%s)\tStatus: Up\n", currenths->targetipstr(), currenths->HostName()); } else if (o.verbose || resolve_all) { if (resolve_all) log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"Host %s appears to be down.\n", currenths->NameIP(hostname, sizeof(hostname))); else log_write(LOG_STDOUT,"Host %s appears to be down.\n", currenths->NameIP(hostname, sizeof(hostname))); log_write(LOG_MACHINE, "Host: %s (%s)\tStatus: Down\n", currenths->targetipstr(), currenths->HostName()); } } else { /* Normal case (non ping/list scan or smurf address) */ write_xml_initial_hostinfo(currenths, (currenths->flags & HOST_UP)? "up" : "down"); if (o.verbose) { if (currenths->flags & HOST_UP) { log_write(LOG_STDOUT, "Host %s appears to be up ... good.\n", currenths->NameIP(hostname, sizeof(hostname))); } else { if (resolve_all) { log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"Host %s appears to be down, skipping it.\n", currenths->NameIP(hostname, sizeof(hostname))); } else { log_write(LOG_STDOUT,"Host %s appears to be down, skipping it.\n", currenths->NameIP(hostname, sizeof(hostname))); } log_write(LOG_MACHINE, "Host: %s (%s)\tStatus: Down\n", currenths->targetipstr(), currenths->HostName()); } } }}/* Returns -1 if adding the entry is not possible because it would overflow. Otherwise it returns the new number of entries. Note that only unique entries are added. Also note that *numentries is incremented if the candidate is added. arrsize is the number of char * members that fit into arr */static int addtochararrayifnew(char *arr[], int *numentries, int arrsize, char *candidate) { int i; // First lets see if the member already exists for(i=0; i < *numentries; i++) { if (strcmp(arr[i], candidate) == 0) return *numentries; } // Not already there... do we have room for a new one? if (*numentries >= arrsize ) return -1; // OK, not already there and we have room, so we'll add it. arr[*numentries] = candidate; (*numentries)++; return *numentries;}/* guess is true if we should print guesses */#define MAX_OS_CLASSMEMBERS 8static void printosclassificationoutput(const struct OS_Classification_Results *OSR, bool guess) { int classno, i, familyno; int overflow = 0; /* Whether we have too many devices to list */ char *types[MAX_OS_CLASSMEMBERS]; char fullfamily[MAX_OS_CLASSMEMBERS][128]; // "[vendor] [os family]" double familyaccuracy[MAX_OS_CLASSMEMBERS]; // highest accuracy for this fullfamily char familygenerations[MAX_OS_CLASSMEMBERS][48]; // example: "4.X|5.X|6.X" int numtypes = 0, numfamilies=0; char tmpbuf[1024]; for(i=0; i < MAX_OS_CLASSMEMBERS; i++) { familygenerations[i][0] = '\0'; familyaccuracy[i] = 0.0; } if (OSR->overall_results == OSSCAN_SUCCESS) { /* Print the OS Classification results to XML output */ for (classno=0; classno < OSR->OSC_num_matches; classno++) { // Because the OS_Generation filed is optional if (OSR->OSC[classno]->OS_Generation) { snprintf(tmpbuf, sizeof(tmpbuf), " osgen=\"%s\"", OSR->OSC[classno]->OS_Generation); } else tmpbuf[0] = '\0'; { char *xml_type, *xml_vendor, *xml_class; xml_type = xml_convert(OSR->OSC[classno]->Device_Type); xml_vendor = xml_convert(OSR->OSC[classno]->OS_Vendor); xml_class = xml_convert(OSR->OSC[classno]->OS_Family); log_write(LOG_XML, "<osclass type=\"%s\" vendor=\"%s\" osfamily=\"%s\"%s accuracy=\"%d\" />\n", xml_type, xml_vendor, xml_class, tmpbuf, (int) (OSR->OSC_Accuracy[classno] * 100)); free(xml_type); free(xml_vendor); free(xml_class); } } // Now to create the fodder for normal output for (classno=0; classno < OSR->OSC_num_matches; classno++) { /* We have processed enough if any of the following are true */ if (!guess && OSR->OSC_Accuracy[classno] < 1.0 || OSR->OSC_Accuracy[classno] <= OSR->OSC_Accuracy[0] - 0.1 || OSR->OSC_Accuracy[classno] < 1.0 && classno > 9) break; if (addtochararrayifnew(types, &numtypes, MAX_OS_CLASSMEMBERS, OSR->OSC[classno]->Device_Type) == -1) overflow = 1; // If family and vendor names are the same, no point being redundant if (strcmp(OSR->OSC[classno]->OS_Vendor, OSR->OSC[classno]->OS_Family) == 0) Strncpy(tmpbuf, OSR->OSC[classno]->OS_Family, sizeof(tmpbuf)); else snprintf(tmpbuf, sizeof(tmpbuf), "%s %s", OSR->OSC[classno]->OS_Vendor, OSR->OSC[classno]->OS_Family); // Let's see if it is already in the array for(familyno = 0; familyno < numfamilies; familyno++) { if (strcmp(fullfamily[familyno], tmpbuf) == 0) { // got a match ... do we need to add the generation? if (OSR->OSC[classno]->OS_Generation && !strstr(familygenerations[familyno], OSR->OSC[classno]->OS_Generation)) { int flen = strlen(familygenerations[familyno]); // We add it, preceded by | if something is already there if (flen + 2 + strlen(OSR->OSC[classno]->OS_Generation) >= sizeof(familygenerations[familyno])) fatal("buffer 0verfl0w of familygenerations"); if (*familygenerations[familyno]) strcat(familygenerations[familyno], "|"); strncat(familygenerations[familyno], OSR->OSC[classno]->OS_Generation, sizeof(familygenerations[familyno]) - flen - 1); } break; } } if (familyno == numfamilies) { // Looks like the new family is not in the list yet. Do we have room to add it? if (numfamilies >= MAX_OS_CLASSMEMBERS) { overflow = 1; break; } // Have space, time to add... Strncpy(fullfamily[numfamilies], tmpbuf, 128); if (OSR->OSC[classno]->OS_Generation) Strncpy(familygenerations[numfamilies], OSR->OSC[classno]->OS_Generation, 48); familyaccuracy[numfamilies] = OSR->OSC_Accuracy[classno]; numfamilies++; } } if (!overflow && numfamilies >= 1) { log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, "Device type: "); for(classno=0; classno < numtypes; classno++) log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, "%s%s", types[classno], (classno < numtypes - 1)? "|" : ""); log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, "\nRunning%s: ", (familyaccuracy[0] < 1.0)? " (JUST GUESSING) " : ""); for(familyno = 0; familyno < numfamilies; familyno++) { if (familyno > 0) log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, ", "); log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, "%s", fullfamily[familyno]); if (*familygenerations[familyno]) log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, " %s", familygenerations[familyno]); if (familyaccuracy[familyno] < 1.0) log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, " (%d%%)", (int) (familyaccuracy[familyno] * 100)); } log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, "\n"); } } log_flush_all(); return;}/* Prints the MAC address if one was found for the target (generally this means that the target is directly connected on an ethernet network. This only prints to human output -- XML is handled by a separate call ( print_MAC_XML_Info ) because it needs to be printed in a certain place to conform to DTD. */void printmacinfo(Target *currenths) { const u8 *mac = currenths->MACAddress(); char macascii[32]; 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]); log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, "MAC Address: %s (%s)\n", macascii, macvendor? macvendor : "Unknown"); }}/* Prints the formatted OS Scan output to stdout, logfiles, etc (but only if an OS Scan was performed).*/void printosscanoutput(Target *currenths) { int i; char numlst[512]; /* For creating lists of numbers */ char *p; /* Used in manipulating numlst above */ FingerPrintResults *FPR; int osscanSys = 0; int distance = -1; if (!currenths->osscan_performed) return; if (currenths->FPR == NULL && currenths->FPR1 == NULL) { return; } else if (currenths->FPR != NULL && currenths->FPR1 == NULL) { osscanSys = 2; FPR = currenths->FPR; } else if (currenths->FPR == NULL && currenths->FPR1 != NULL) { osscanSys = 1; FPR = currenths->FPR1; } else { /* Neither is NULL. This happens when new OS scan system fails to get a perfect match and falls back on the old OS scan system. */ if (currenths->FPR->num_perfect_matches > 0) { osscanSys = 2; FPR = currenths->FPR; /* Just an ensurance. */ } else if (currenths->FPR1->num_perfect_matches > 0) { osscanSys = 1; FPR = currenths->FPR1; } else if (currenths->FPR->overall_results == OSSCAN_SUCCESS) { osscanSys = 2; FPR = currenths->FPR; } else if (currenths->FPR1->overall_results == OSSCAN_SUCCESS) { osscanSys = 1; FPR = currenths->FPR1; } else { /* Both fails. */ osscanSys = 2; FPR = currenths->FPR; } } if (currenths->distance != -1) distance = currenths->distance; log_write(LOG_XML, "<os>"); if (FPR->osscan_opentcpport > 0) { log_write(LOG_XML, "<portused state=\"open\" proto=\"tcp\" portid=\"%hu\" />\n", FPR->osscan_opentcpport); } if (FPR->osscan_closedtcpport > 0) { log_write(LOG_XML, "<portused state=\"closed\" proto=\"tcp\" portid=\"%hu\" />\n", FPR->osscan_closedtcpport); } if (FPR->osscan_closedudpport > 0) { log_write(LOG_XML, "<portused state=\"closed\" proto=\"udp\" portid=\"%hu\" />\n", FPR->osscan_closedudpport); } // If the FP can't be submitted anyway, might as well make a guess. const char *reason = FPR->OmitSubmissionFP(); printosclassificationoutput(FPR->getOSClassification(), o.osscan_guess || reason); if (FPR->overall_results == OSSCAN_SUCCESS && (FPR->num_perfect_matches <= 8 || o.debugging)) { if (FPR->num_perfect_matches > 0) { char *p; log_write(LOG_MACHINE,"\tOS: %s", FPR->prints[0]->OS_name); log_write(LOG_XML, "<osmatch name=\"%s\" accuracy=\"100\" line=\"%d\" />\n", p = xml_convert(FPR->prints[0]->OS_name), FPR->prints[0]->line); free(p); i = 1; while(FPR->accuracy[i] == 1 ) { log_write(LOG_MACHINE,"|%s", FPR->prints[i]->OS_name); log_write(LOG_XML, "<osmatch name=\"%s\" accuracy=\"100\" line=\"%d\" />\n", p = xml_convert(FPR->prints[i]->OS_name), FPR->prints[i]->line); free(p); i++; } if (FPR->num_perfect_matches == 1) log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, "OS details: %s", FPR->prints[0]->OS_name);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -