📄 osscan.cc
字号:
#endif if (o.verbose) { starttimems = o.TimeSinceStartMS(); log_write(LOG_STDOUT, "Initiating gen1 OS Detection against %s at %.3fs\n", target->targetipstr(), starttimems / 1000.0); } if (target->FPR1 == NULL) target->FPR1 = new FingerPrintResults; memset(si, 0, sizeof(si)); if (target->ports.getStateCounts(IPPROTO_TCP, PORT_OPEN) == 0 || (target->ports.getStateCounts(IPPROTO_TCP, PORT_CLOSED) == 0 && target->ports.getStateCounts(IPPROTO_TCP, PORT_UNFILTERED) == 0)) { if (o.osscan_limit) { if (o.verbose) log_write(LOG_STDOUT|LOG_NORMAL|LOG_SKID, "Skipping OS Scan due to absence of open (or perhaps closed) ports\n"); return 1; } else { log_write(LOG_STDOUT|LOG_NORMAL|LOG_SKID,"Warning: OS detection will be MUCH less reliable because we did not find at least 1 open and 1 closed TCP port\n"); } } for(itry=0; itry < 3; itry++) { gettimeofday(&now, NULL); if (target->timedOut(&now)) return 1; // Check if a status message is requested if (keyWasPressed()) { // Do nothing because the keyWasPressed Method prints out the basic status line } target->FPR1->FPs[itry] = get_fingerprint(target, &si[itry]); match_fingerprint(target->FPR1->FPs[itry], &FP_matches[itry], o.reference_FPs1, OSSCAN_GUESS_THRESHOLD); if (FP_matches[itry].overall_results == OSSCAN_SUCCESS && FP_matches[itry].num_perfect_matches > 0) break; if (itry < 2) sleep(2); } target->FPR1->numFPs = (itry == 3)? 3 : itry + 1; memcpy(&(target->seq), &si[target->FPR1->numFPs - 1], sizeof(struct seq_info)); /* Now lets find the best match */ bestacc = 0; bestaccidx = 0; for(itry=0; itry < target->FPR1->numFPs; itry++) { if (FP_matches[itry].overall_results == OSSCAN_SUCCESS && FP_matches[itry].num_matches > 0 && FP_matches[itry].accuracy[0] > bestacc) { bestacc = FP_matches[itry].accuracy[0]; bestaccidx = itry; if (FP_matches[itry].num_perfect_matches) break; } } for(i=0; i < target->FPR1->numFPs; i++) { if (i == bestaccidx) continue; if (o.debugging) { error("Failed exact match #%d (0-based):\n%s", i, fp2ascii(target->FPR1->FPs[i])); } } if (target->FPR1->numFPs > 1 && target->FPR1->overall_results == OSSCAN_SUCCESS && target->FPR1->accuracy[0] == 1.0) { if (o.verbose) error("WARNING: OS didn't match until the try #%d", target->FPR1->numFPs); } target->FPR1->goodFP = bestaccidx; // Now we redo the match, since target->FPR1 has various data (such as // target->FPR1->numFPs) which is not in FP_matches[bestaccidx]. This is // kinda ugly. if (target->FPR1->goodFP >= 0) match_fingerprint(target->FPR1->FPs[target->FPR1->goodFP], target->FPR1, o.reference_FPs1, OSSCAN_GUESS_THRESHOLD); if (o.debugging > 2) { log_write(LOG_STDOUT|LOG_NORMAL|LOG_SKID, "Completed OS Detection against %s at %.3fs (took %.3fs)\n", target->targetipstr(), o.TimeSinceStartMS() / 1000.0, (o.TimeSinceStartMS() - starttimems) / 1000.0); } return 1;}/* Writes an informational "Test" result suitable for including at the top of a fingerprint. Gives info which might be useful when the FPrint is submitted (eg Nmap version, etc). Result is written (up to ostrlen) to the ostr var passed in */static void WriteSInfo(char *ostr, int ostrlen, bool isGoodFP, const struct in_addr * const addr, int distance, const u8 *mac, int openTcpPort, int closedTcpPort, int closedUdpPort) { struct tm *ltime; time_t timep; char dsbuf[8], otbuf[8], ctbuf[8], cubuf[8]; char macbuf[16]; timep = time(NULL); ltime = localtime(&timep); otbuf[0] = '\0'; if(openTcpPort != -1) snprintf(otbuf, sizeof(otbuf), "%d", openTcpPort); ctbuf[0] = '\0'; if(closedTcpPort != -1) snprintf(ctbuf, sizeof(ctbuf), "%d", closedTcpPort); cubuf[0] = '\0'; if(closedUdpPort != -1) snprintf(cubuf, sizeof(cubuf), "%d", closedUdpPort); dsbuf[0] = '\0'; if(distance != -1) { snprintf(dsbuf, sizeof(dsbuf), "%%DS=%d", distance); } macbuf[0] = '\0'; if (mac) snprintf(macbuf, sizeof(macbuf), "%%M=%02X%02X%02X", mac[0], mac[1], mac[2]); snprintf(ostr, ostrlen, "SCAN(V=%s%%D=%d/%d%%OT=%s%%CT=%s%%CU=%s%%PV=%c%s%%G=%c%s%%TM=%X%%P=%s)", NMAP_VERSION, ltime->tm_mon + 1, ltime->tm_mday, otbuf, ctbuf, cubuf, isipprivate(addr)?'Y':'N', dsbuf, isGoodFP?'Y':'N', macbuf, (int) timep, NMAP_PLATFORM);}char *mergeFPs(FingerPrint *FPs[], int numFPs, bool isGoodFP, const struct in_addr * const addr, int distance, const u8 *mac, int openTcpPort, int closedTcpPort, int closedUdpPort, bool wrapit) {static char str[10240]; static char wrapstr[10240]; struct AVal *AV;FingerPrint *currentFPs[32];char *p = str;int i;int changed;char *end = str + sizeof(str) - 1; /* Last byte allowed to write into */ if (numFPs <=0) return "(None)";if (numFPs > 32) return "(Too many)"; memset(str, 0, sizeof(str));for(i=0; i < numFPs; i++) { if (FPs[i] == NULL) { fatal("mergeFPs was handed a pointer to null fingerprint"); } currentFPs[i] = FPs[i];} /* Lets start by writing the fake "SCAN" test for submitting fingerprints */ WriteSInfo(str, sizeof(str), isGoodFP, addr, distance, mac, openTcpPort, closedTcpPort, closedUdpPort); p = p + strlen(str); if (!wrapit) *p++ = '\n';do { changed = 0; for(i = 0; i < numFPs; i++) { assert (end - p > 100); if (currentFPs[i]) { /* This junk means do not print this one if the next one is the same */ if (i == numFPs - 1 || !currentFPs[i+1] || strcmp(currentFPs[i]->name, currentFPs[i+1]->name) != 0 || AVal_match(currentFPs[i]->results,currentFPs[i+1]->results, NULL, NULL, NULL, 1, 0, NULL) ==0) { changed = 1; Strncpy(p, currentFPs[i]->name, end - p); p += strlen(currentFPs[i]->name); *p++='('; for(AV = currentFPs[i]->results; AV; AV = AV->next) { Strncpy(p, AV->attribute, end - p); p += strlen(AV->attribute); *p++='='; Strncpy(p, AV->value, end - p); p += strlen(AV->value); *p++ = '%'; } if(*(p-1) != '(') p--; /* Kill the final & */ *p++ = ')'; if(!wrapit) *p++ = '\n'; } /* Now prepare for the next one */ currentFPs[i] = currentFPs[i]->next; } }} while(changed);*p = '\0'; if(!wrapit) {return str; } else { /* Wrap the str. */ int len; char *p1 = wrapstr; end = wrapstr + sizeof(wrapstr) - 1; p = str; while(*p && end-p1 >= 3) { len = 0; strcpy(p1, "OS:"); p1 += 3; len +=3; while(*p && len <= FP_RESULT_WRAP_LINE_LEN && end-p1 > 0) { *p1++=*p++; len++; } if(end-p1<=0) { fatal("Wrapped result too long!\n"); break; } *p1++ = '\n';} *p1 = '\0'; return wrapstr; }}char *fp2ascii(FingerPrint *FP) {static char str[2048];FingerPrint *current;struct AVal *AV;char *p = str;int len;memset(str, 0, sizeof(str));if (!FP) return "(None)";if(FP->OS_name && *(FP->OS_name)) { len = snprintf(str, 128, "FingerPrint %s\n", FP->OS_name); if (len < 0) fatal("OS name too long"); p += len;}for(current = FP; current ; current = current->next) { Strncpy(p, current->name, sizeof(str) - (p-str)); p += strlen(p); assert(p-str < (int) sizeof(str) - 30); *p++='('; for(AV = current->results; AV; AV = AV->next) { Strncpy(p, AV->attribute, sizeof(str) - (p-str)); p += strlen(p); assert(p-str < (int) sizeof(str) - 30); *p++='='; Strncpy(p, AV->value, sizeof(str) - (p-str)); p += strlen(p); assert(p-str < (int) sizeof(str) - 30); *p++ = '%'; } if(*(p-1) != '(') p--; /* Kill the final & */ *p++ = ')'; *p++ = '\n';}*p = '\0';return str;}/* Parse a 'Class' line found in the fingerprint file into the current FP. Classno is the number of 'class' lines found so far in the current fingerprint. The function quits if there is a parse error */static void parse_classline(FingerPrint *FP, char *thisline, int lineno, int *classno) { char *p, *q;// Wtf???? fflush(stdout); if (!thisline || strncmp(thisline, "Class ", 6) == 1) { fatal("Bogus line #%d (%s) passed to parse_classline()", lineno, thisline); } if (*classno >= MAX_OS_CLASSIFICATIONS_PER_FP) fatal("Too many Class lines in fingerprint (line %d: %s), remove some or increase MAX_OS_CLASSIFICATIONS_PER_FP", lineno, thisline); p = thisline + 6; /* First lets get the vendor name */ while(*p && isspace(*p)) p++; q = strchr(p, '|'); if (!q) { fatal("Parse error on line %d of fingerprint: %s\n", lineno, thisline); } // Trim any trailing whitespace q--; while(isspace(*q)) q--; q++; if (q < p) { fatal("Parse error on line %d of fingerprint: %s\n", lineno, thisline); } FP->OS_class[*classno].OS_Vendor = (char *) cp_alloc(q - p + 1); memcpy(FP->OS_class[*classno].OS_Vendor, p, q - p); FP->OS_class[*classno].OS_Vendor[q - p] = '\0'; /* Next comes the OS Family */ p = q; while(*p && !isalnum(*p)) p++; q = strchr(p, '|'); if (!q) { fatal("Parse error on line %d of fingerprint: %s\n", lineno, thisline); } // Trim any trailing whitespace q--; while(isspace(*q)) q--; q++; if (q < p) { fatal("Parse error on line %d of fingerprint: %s\n", lineno, thisline); } FP->OS_class[*classno].OS_Family = (char *) cp_alloc(q - p + 1); memcpy(FP->OS_class[*classno].OS_Family, p, q - p); FP->OS_class[*classno].OS_Family[q - p] = '\0'; /* And now the the OS generation, if available */ p = q; while(*p && *p != '|') p++; if (*p) p++; while(*p && isspace(*p) && *p != '|') p++; if (*p == '|') { FP->OS_class[*classno].OS_Generation = NULL; q = p; } else { q = strpbrk(p, " |"); if (!q) { fatal("Parse error on line %d of fingerprint: %s\n", lineno, thisline); } // Trim any trailing whitespace q--; while(isspace(*q)) q--; q++; if (q < p) { fatal("Parse error on line %d of fingerprint: %s\n", lineno, thisline); } FP->OS_class[*classno].OS_Generation = (char *) cp_alloc(q - p + 1); memcpy(FP->OS_class[*classno].OS_Generation, p, q - p); FP->OS_class[*classno].OS_Generation[q - p] = '\0'; } /* And finally the device type */ p = q; while(*p && !isalnum(*p)) p++; q = strchr(p, '|'); if (!q) { q = p; while(*q) q++; } // Trim any trailing whitespace q--; while(isspace(*q)) q--; q++; if (q < p) { fatal("Parse error on line %d of fingerprint: %s\n", lineno, thisline); } FP->OS_class[*classno].Device_Type = (char *) cp_alloc(q - p + 1); memcpy(FP->OS_class[*classno].Device_Type, p, q - p); FP->OS_class[*classno].Device_Type[q - p] = '\0'; // printf("Got classification #%d for the O
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -