📄 osscan.cc
字号:
/* Create the Avals */ AVs = (struct AVal *) safe_zalloc(numtests * sizeof(struct AVal)); /* Link them together */ for(i=0; i < numtests - 1; i++) AVs[i].next = &AVs[i+1]; /* First of all, if we got this far the response was yes */ AVs[current_testno].attribute = "Resp"; strcpy(AVs[current_testno].value, "Y"); current_testno++; /* Now let us do an easy one, Don't fragment */ AVs[current_testno].attribute = "DF"; if(ntohs(ip->ip_off) & 0x4000) { strcpy(AVs[current_testno].value,"Y"); } else strcpy(AVs[current_testno].value, "N"); current_testno++; /* Now lets do TOS of the response (note, I've never seen this be useful */ AVs[current_testno].attribute = "TOS"; sprintf(AVs[current_testno].value, "%hX", ip->ip_tos); current_testno++; /* Now we look at the IP datagram length that was returned, some machines send more of the original packet back than others */ AVs[current_testno].attribute = "IPLEN"; sprintf(AVs[current_testno].value, "%hX", ntohs(ip->ip_len)); current_testno++; /* OK, lets check the returned IP length, some systems @$@ this up */ AVs[current_testno].attribute = "RIPTL"; sprintf(AVs[current_testno].value, "%hX", ntohs(ip2->ip_len)); current_testno++; /* This next test doesn't work on Solaris because the lamers overwrite our ip_id */#if !defined(SOLARIS) && !defined(SUNOS) && !defined(IRIX) && !defined(HPUX) /* Now lets see how they treated the ID we sent ... */ AVs[current_testno].attribute = "RID"; if (ntohs(ip2->ip_id) == 0) strcpy(AVs[current_testno].value, "0"); else if (ip2->ip_id == upi->ipid) strcpy(AVs[current_testno].value, "E"); /* The "expected" value */ else strcpy(AVs[current_testno].value, "F"); /* They fucked it up */ current_testno++;#endif /* Let us see if the IP checksum we got back computes */ AVs[current_testno].attribute = "RIPCK"; /* Thanks to some machines not having struct ip member ip_sum we have to go with this BS */ checksumptr = (unsigned short *) ((char *) ip2 + 10); checksum = *checksumptr; if (checksum == 0) strcpy(AVs[current_testno].value, "0"); else { *checksumptr = 0; if (in_cksum((unsigned short *)ip2, 20) == checksum) { strcpy(AVs[current_testno].value, "E"); /* The "expected" value */ } else { strcpy(AVs[current_testno].value, "F"); /* They fucked it up */ } *checksumptr = checksum; } current_testno++; /* UDP checksum */ AVs[current_testno].attribute = "UCK"; if (udp->uh_sum == 0) strcpy(AVs[current_testno].value, "0"); else if (udp->uh_sum == upi->udpck) strcpy(AVs[current_testno].value, "E"); /* The "expected" value */ else strcpy(AVs[current_testno].value, "F"); /* They fucked it up */ current_testno++; /* UDP length ... */ AVs[current_testno].attribute = "ULEN"; sprintf(AVs[current_testno].value, "%hX", ntohs(udp->uh_ulen)); current_testno++; /* Finally we ensure the data is OK */ datastart = ((unsigned char *)udp) + 8; dataend = (unsigned char *) ip + ntohs(ip->ip_len); while(datastart < dataend) { if (*datastart != upi->patternbyte) break; datastart++; } AVs[current_testno].attribute = "DAT"; if (datastart < dataend) strcpy(AVs[current_testno].value, "F"); /* They fucked it up */ else strcpy(AVs[current_testno].value, "E"); AVs[current_testno].next = NULL; return AVs;}static FingerPrint *get_fingerprint(Target *target, struct seq_info *si) { FingerPrint *FP = NULL, *FPtmp = NULL; FingerPrint *FPtests[9]; struct AVal *seq_AVs; u16 lastipid=0; /* For catching duplicate packets */ int last; u32 timestamp = 0; /* TCP timestamp we receive back */ struct ip *ip; struct tcphdr *tcp; struct icmp *icmp; struct timeval t1,t2; int i; pcap_t *pd = NULL; int rawsd; int tries = 0; int newcatches; int current_port = 0; int testsleft; int testno; int timeout; int avnum; unsigned int sequence_base; unsigned long openport; unsigned int bytes; unsigned int closedport = 31337; Port *tport = NULL; char filter[512]; double seq_inc_sum = 0; unsigned int seq_avg_inc = 0; struct udpprobeinfo *upi = NULL; u32 seq_gcd = 1; u32 seq_diffs[NUM_SEQ_SAMPLES]; u32 ts_diffs[NUM_SEQ_SAMPLES]; unsigned long time_usec_diffs[NUM_SEQ_SAMPLES]; struct timeval seq_send_times[NUM_SEQ_SAMPLES]; int ossofttimeout, oshardtimeout; int seq_packets_sent = 0; int seq_response_num; /* response # for sequencing */ double avg_ts_hz = 0.0; /* Avg. amount that timestamps incr. each second */ struct link_header linkhdr; struct eth_nfo eth; struct eth_nfo *ethptr; // for passing to send_ functions if (target->timedOut(NULL)) return NULL; /* The seqs must start out as zero for the si struct */ memset(si->seqs, 0, sizeof(si->seqs)); si->ipid_seqclass = IPID_SEQ_UNKNOWN; si->ts_seqclass = TS_SEQ_UNKNOWN; si->lastboot = 0; /* Init our fingerprint tests to each be NULL */ memset(FPtests, 0, sizeof(FPtests)); get_random_bytes(&sequence_base, sizeof(unsigned int)); if ((o.sendpref & PACKET_SEND_ETH) && target->ifType() == devt_ethernet) { memcpy(eth.srcmac, target->SrcMACAddress(), 6); memcpy(eth.dstmac, target->NextHopMACAddress(), 6); eth.ethsd = eth_open_cached(target->deviceName()); if (eth.ethsd == NULL) fatal("%s: Failed to open ethernet device (%s)", __FUNCTION__, target->deviceName()); rawsd = -1; ethptr = ð } else { /* Init our raw socket */ if ((rawsd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0 ) pfatal("socket troubles in get_fingerprint"); unblock_socket(rawsd); broadcast_socket(rawsd);#ifndef WIN32 sethdrinclude(rawsd);#endif ethptr = NULL; eth.ethsd = NULL; } /* Now for the pcap opening nonsense ... */ /* Note that the snaplen is 152 = 64 byte max IPhdr + 24 byte max link_layer * header + 64 byte max TCP header. Had to up it for UDP test */ ossofttimeout = MAX(200000, target->to.timeout); oshardtimeout = MAX(500000, 5 * target->to.timeout); pd = my_pcap_open_live(target->deviceName(), /*650*/ 8192, (o.spoofsource)? 1 : 0, (ossofttimeout + 500)/ 1000); if (o.debugging > 1) log_write(LOG_STDOUT, "Wait time is %dms\n", (ossofttimeout +500)/1000); snprintf(filter, sizeof(filter), "dst host %s and (icmp or (tcp and src host %s))", inet_ntoa(target->v4source()), target->targetipstr()); set_pcap_filter(target->deviceName(), pd, filter); target->osscan_performed = 1; /* Let Nmap know that we did try an OS scan */ /* Lets find an open port to use */ openport = (unsigned long) -1; target->FPR1->osscan_opentcpport = -1; target->FPR1->osscan_closedtcpport = -1; target->FPR1->osscan_closedudpport = -1; tport = NULL; if ((tport = target->ports.nextPort(NULL, IPPROTO_TCP, PORT_OPEN))) { openport = tport->portno; target->FPR1->osscan_opentcpport = tport->portno; } /* Now we should find a closed port */ if ((tport = target->ports.nextPort(NULL, IPPROTO_TCP, PORT_CLOSED))) { closedport = tport->portno; target->FPR1->osscan_closedtcpport = tport->portno; } else if ((tport = target->ports.nextPort(NULL, IPPROTO_TCP, PORT_UNFILTERED))) { /* Well, we will settle for unfiltered */ closedport = tport->portno; } else { closedport = (get_random_uint() % 14781) + 30000; } if (o.verbose && openport != (unsigned long) -1) log_write(LOG_STDOUT, "For OSScan assuming port %lu is open, %d is closed, and neither are firewalled\n", openport, closedport); current_port = o.magic_port + NUM_SEQ_SAMPLES +1; /* Now lets do the NULL packet technique */ testsleft = (openport == (unsigned long) -1)? 4 : 8; FPtmp = NULL; tries = 0; do { newcatches = 0; if (openport != (unsigned long) -1) { /* Test 1 */ if (!FPtests[1]) { if (o.scan_delay) enforce_scan_delay(NULL); send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl, false, NULL, 0, current_port, openport, sequence_base, 0, 0, TH_ECE|TH_SYN, 0, 0, (u8 *) "\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000", 20, NULL, 0); } /* Test 2 */ if (!FPtests[2]) { if (o.scan_delay) enforce_scan_delay(NULL); send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl, false, NULL, 0, current_port +1, openport, sequence_base, 0, 0, 0, 0, 0, (u8 *) "\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0); } /* Test 3 */ if (!FPtests[3]) { if (o.scan_delay) enforce_scan_delay(NULL); send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl, false, NULL, 0, current_port +2, openport, sequence_base, 0, 0, TH_SYN|TH_FIN|TH_URG|TH_PUSH, 0, 0, (u8 *) "\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0); } /* Test 4 */ if (!FPtests[4]) { if (o.scan_delay) enforce_scan_delay(NULL); send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl, false, NULL, 0, current_port +3, openport, sequence_base, 0, 0, TH_ACK, 0, 0, (u8 *) "\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0); } } /* Test 5 */ if (!FPtests[5]) { if (o.scan_delay) enforce_scan_delay(NULL); send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl, false, NULL, 0, current_port +4, closedport, sequence_base, 0, 0, TH_SYN, 0, 0, (u8 *) "\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0); } /* Test 6 */ if (!FPtests[6]) { if (o.scan_delay) enforce_scan_delay(NULL); send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl, false, NULL, 0, current_port +5, closedport, sequence_base, 0, 0, TH_ACK, 0, 0, (u8 *) "\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0); } /* Test 7 */ if (!FPtests[7]) { if (o.scan_delay) enforce_scan_delay(NULL); send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl, false, NULL, 0, current_port +6, closedport, sequence_base, 0, 0, TH_FIN|TH_PUSH|TH_URG, 0, 0, (u8 *) "\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0); } /* Test 8 */ if (!FPtests[8]) { if (o.scan_delay) enforce_scan_delay(NULL); upi = send_closedudp_probe(rawsd, ethptr, target->v4hostip(), o.magic_port, closedport); } gettimeofday(&t1, NULL); timeout = 0; /* Insure we haven't overrun our allotted time ... */ if (target->timedOut(&t1)) goto osscan_timedout; while(( ip = (struct ip*) readip_pcap(pd, &bytes, oshardtimeout, NULL, &linkhdr)) && !timeout) { gettimeofday(&t2, NULL); if (TIMEVAL_SUBTRACT(t2,t1) > oshardtimeout) { timeout = 1; } if (target->timedOut(&t2)) goto osscan_timedout; if (bytes < (4 * ip->ip_hl) + 4U || bytes < 20) continue; setTargetMACIfAvailable(target, &linkhdr, ip, 0); if (ip->ip_p == IPPROTO_TCP) { tcp = ((struct tcphdr *) (((char *) ip) + 4 * ip->ip_hl)); testno = ntohs(tcp->th_dport) - current_port + 1; if (testno <= 0 || testno > 7) continue; if (o.debugging > 1) log_write(LOG_STDOUT, "Got packet for test number %d\n", testno); if (FPtests[testno]) continue; testsleft--; newcatches++; FPtests[testno] = (FingerPrint *) safe_zalloc(sizeof(FingerPrint)); FPtests[testno]->results = fingerprint_iptcppacket(ip, 265, sequence_base); FPtests[testno]->name = (testno == 1)? "T1" : (testno == 2)? "T2" : (testno == 3)? "T3" : (testno == 4)? "T4" : (testno == 5)? "T5" : (testno == 6)? "T6" : (testno == 7)? "T7" : "PU"; } else if (ip->ip_p == IPPROTO_ICMP) { icmp = ((struct icmp *) (((char *) ip) + 4 * ip->ip_hl)); /* It must be a destination port unreachable */ if (icmp->icmp_type != 3 || icmp->icmp_code != 3) { /* This ain't no stinking port unreachable! */ continue; } if (bytes < (unsigned int) ntohs(ip->ip_len)) { error("We only got %d bytes out of %d on our ICMP port unreachable packet, skipping", bytes, ntohs(ip->ip_len)); continue; } if (FPtests[8]) continue; FPtests[8] = (FingerPrint *) safe_zalloc(sizeof(FingerPrint)); FPtests[8]->results = fingerprint_portunreach(ip, upi); if (FPtests[8]->results) { FPtests[8]->name = "PU"; testsleft--; newcatches++; } else { free(FPtests[8]); FPtests[8] = NULL; } } if (testsleft == 0) break; } } while ( testsleft > 0 && (tries++ < 5 && (newcatches || tries == 1))); si->responses = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -