targets.cc
来自「Ubuntu packages of security software。 相」· CC 代码 · 共 1,812 行 · 第 1/5 页
CC
1,812 行
exclude_group[i].skip_range(TargetGroup::THIRD_OCTET); continue; } }#if HAVE_IPV6 else if (targets_type == TargetGroup::IPV6_ADDRESS) { fatal("exclude file not supported for IPV6 -- If it is important to you, send a mail to fyodor@insecure.org so I can guage support\n"); }#endif } exclude_group[i++].rewind(); } /* we did not find the host */ return 0;}static int get_ping_results(int sd, pcap_t *pd, Target *hostbatch[], int pingtype, struct timeval *time, struct pingtune *pt, struct timeout_info *to, int id, struct pingtech *ptech, struct scan_lists *ports) { fd_set fd_r, fd_x; struct timeval myto, tmpto, start, rcvdtime; unsigned int bytes; int res; struct ppkt { unsigned char type; unsigned char code; unsigned short checksum; unsigned short id; unsigned short seq; } *ping = NULL, *ping2 = NULL; char response[16536]; struct tcphdr *tcp; udphdr_bsd *udp; struct ip *ip, *ip2; u32 hostnum = 0xFFFFFF; /* This ought to crash us if it is used uninitialized */ int tm; int dotimeout = 1; int newstate = HOST_DOWN; int foundsomething; unsigned short newport = 0; int newportstate; /* Hack so that in some specific cases we can determine the state of a port and even skip the real scan */ u32 trynum = 0xFFFFFF; enum pingstyle pingstyle = pingstyle_unknown; int timeout = 0; u16 sequence = 65534; unsigned long tmpl; unsigned short sportbase; struct link_header linkhdr; FD_ZERO(&fd_r); FD_ZERO(&fd_x); /* Decide on the timeout, based on whether we need to also watch for TCP stuff */ if (ptech->icmpscan && !ptech->rawtcpscan && !ptech->rawudpscan) { /* We only need to worry about pings, so we set timeout for the whole she-bang! */ myto.tv_sec = to->timeout / 1000000; myto.tv_usec = to->timeout % 1000000; } else { myto.tv_sec = 0; myto.tv_usec = 20000; } if (o.magic_port_set) sportbase = o.magic_port; else sportbase = o.magic_port + 20; gettimeofday(&start, NULL); newportstate = PORT_UNKNOWN; while(pt->block_unaccounted > 0 && !timeout) { keyWasPressed(); // Check for status message printing tmpto = myto; if (pd) { ip = (struct ip *) readip_pcap(pd, &bytes, to->timeout, &rcvdtime, &linkhdr); if (!ip) gettimeofday(&rcvdtime, NULL); } else { FD_SET(sd, &fd_r); FD_SET(sd, &fd_x); res = select(sd+1, &fd_r, NULL, &fd_x, &tmpto); if (res == 0) break; bytes = recv(sd, response,sizeof(response), 0 ); ip = (struct ip *) response; gettimeofday(&rcvdtime, NULL); if (bytes > 0) { PacketTrace::trace(PacketTrace::RCVD, (u8 *) response, bytes, &rcvdtime); } } tm = TIMEVAL_SUBTRACT(rcvdtime,start); if (tm > (MAX(400000,3 * to->timeout))) timeout = 1; if (bytes == 0 && tm > to->timeout) { timeout = 1; } if (bytes == 0) continue; if (bytes > 0 && bytes <= 20) { error("%d byte micro packet received in get_ping_results", bytes); continue; } foundsomething = 0; dotimeout = 0; /* First check if it is ICMP, TCP, or UDP */ if (ip->ip_p == IPPROTO_ICMP) { /* if it is our response */ ping = (struct ppkt *) ((ip->ip_hl * 4) + (char *) ip); if (bytes < ip->ip_hl * 4 + 8U) { if (!ip->ip_off) error("Supposed ping packet is only %d bytes long!", bytes); continue; } /* Echo reply, Timestamp reply, or Address Mask Reply */ if ( (ping->type == 0 || ping->type == 14 || ping->type == 18) && !ping->code && ping->id == id) { sequence = ping->seq - pt->seq_offset; hostnum = sequence / pt->max_tries; if (hostnum > (u32) pt->group_end) { if (o.debugging) error("Ping sequence %hu leads to hostnum %d which is beyond the end of this group (%d)", sequence, hostnum, pt->group_end); continue; } if (o.debugging) log_write(LOG_STDOUT, "We got a ping packet back from %s: id = %d seq = %d checksum = %d\n", inet_ntoa(ip->ip_src), ping->id, ping->seq, ping->checksum); if (hostbatch[hostnum]->v4host().s_addr == ip->ip_src.s_addr) { foundsomething = 1; pingstyle = pingstyle_icmp; newstate = HOST_UP; trynum = sequence % pt->max_tries; dotimeout = 1; if (!hostbatch[hostnum]->v4sourceip()) { struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = ip->ip_dst.s_addr;#if HAVE_SOCKADDR_SA_LEN sin.sin_len = sizeof(sin);#endif hostbatch[hostnum]->setSourceSockAddr((struct sockaddr_storage *) &sin, sizeof(sin)); } } else hostbatch[hostnum]->wierd_responses++; } // Destination unreachable, source quench, or time exceeded else if (ping->type == 3 || ping->type == 4 || ping->type == 11 || o.debugging) { if (bytes < ip->ip_hl * 4 + 28U) { if (o.debugging) error("ICMP type %d code %d packet is only %d bytes\n", ping->type, ping->code, bytes); continue; } ip2 = (struct ip *) ((char *)ip + ip->ip_hl * 4 + 8); if (bytes < ip->ip_hl * 4 + 8U + ip2->ip_hl * 4 + 8U) { if (o.debugging) error("ICMP (embedded) type %d code %d packet is only %d bytes\n", ping->type, ping->code, bytes); continue; } if (ip2->ip_p == IPPROTO_ICMP) { /* The response was based on a ping packet we sent */ if (!ptech->icmpscan && !ptech->rawicmpscan) { if (o.debugging) error("Got ICMP error referring to ICMP msg which we did not send"); continue; } ping2 = (struct ppkt *) ((char *)ip2 + ip2->ip_hl * 4); if (ping2->id != id) { if (o.debugging) { error("Illegal id %d found, should be %d (icmp type/code %d/%d)", ping2->id, id, ping->type, ping->code); if (o.debugging > 1) lamont_hdump((char *)ip, bytes); } continue; } sequence = ping2->seq - pt->seq_offset; hostnum = sequence / pt->max_tries; trynum = sequence % pt->max_tries; if (trynum >= (u32) pt->max_tries || hostnum > (u32) pt->group_end || hostbatch[hostnum]->v4host().s_addr != ip2->ip_dst.s_addr) { if (o.debugging) { error("Bogus trynum, sequence number or unexpected IP address in ICMP error message\n"); } continue; } } else if (ip2->ip_p == IPPROTO_TCP) { /* The response was based our TCP probe */ if (!ptech->rawtcpscan) { if (o.debugging) error("Got ICMP error referring to TCP msg which we did not send"); continue; } tcp = (struct tcphdr *) (((char *) ip2) + 4 * ip2->ip_hl); /* No need to check size here, the "+8" check a ways up takes care of it */ newport = ntohs(tcp->th_dport); trynum = ntohs(tcp->th_sport) - sportbase; if (trynum >= (u32) pt->max_tries) { if (o.debugging) error("Bogus trynum %d", trynum); continue; } /* Grab the sequence nr */ tmpl = ntohl(tcp->th_seq); if ((tmpl & 0x3F) == 0x1E) { sequence = ((tmpl >> 6) & 0xffff) - pt->seq_offset; hostnum = sequence / pt->max_tries; trynum = sequence % pt->max_tries; } else { if (o.debugging) { error("Whacked seq number from %s", inet_ntoa(ip->ip_src)); } continue; } if (trynum >= (u32) pt->max_tries || hostnum > (u32) pt->group_end || hostbatch[hostnum]->v4host().s_addr != ip2->ip_dst.s_addr) { if (o.debugging) { error("Bogus trynum, sequence number or unexpected IP address in ICMP error message\n"); } continue; } } else if (ip2->ip_p == IPPROTO_UDP) { /* The response was based our UDP probe */ if (!ptech->rawudpscan) { if (o.debugging) error("Got ICMP error referring to UDP msg which we did not send"); continue; } sequence = ntohs(ip2->ip_id) - pt->seq_offset; hostnum = sequence / pt->max_tries; trynum = sequence % pt->max_tries; if (trynum >= (u32) pt->max_tries || hostnum > (u32) pt->group_end || hostbatch[hostnum]->v4host().s_addr != ip2->ip_dst.s_addr) { if (o.debugging) { error("Bogus trynum, sequence number or unexpected IP address in ICMP error message\n"); } continue; } } else { if (o.debugging) error("Got ICMP response to a packet which was not TCP, UDP, or ICMP"); continue; } assert (hostnum <= (u32) pt->group_end); if (ping->type == 3) { dotimeout = 1; foundsomething = 1; pingstyle = pingstyle_icmp; if (ping->code == 3 && ptech->rawudpscan) { /* ICMP port unreachable -- the port is closed but aparently the machine is up! */ newstate = HOST_UP; } else { if (o.debugging) log_write(LOG_STDOUT, "Got destination unreachable for %s\n", hostbatch[hostnum]->targetipstr()); /* Since this gives an idea of how long it takes to get an answer, we add it into our times */ newstate = HOST_DOWN; newportstate = PORT_FILTERED; } } else if (ping->type == 11) { if (o.debugging) log_write(LOG_STDOUT, "Got Time Exceeded for %s\n", hostbatch[hostnum]->targetipstr()); dotimeout = 0; /* I don't want anything to do with timing this */ foundsomething = 1; pingstyle = pingstyle_icmp; newstate = HOST_DOWN; } else if (ping->type == 4) { if (o.debugging) log_write(LOG_STDOUT, "Got ICMP source quench\n"); usleep(50000); } else if (o.debugging > 0) { log_write(LOG_STDOUT, "Got ICMP message type %d code %d\n", ping->type, ping->code); } } } else if (ip->ip_p == IPPROTO_TCP) { if (!ptech->rawtcpscan) { continue; } if (bytes < 4 * ip->ip_hl + 16U) { error("TCP packet is only %d bytes, we can't get enough information from it\n", bytes); continue; } tcp = (struct tcphdr *) (((char *) ip) + 4 * ip->ip_hl); if (!(tcp->th_flags & TH_RST) && ((tcp->th_flags & (TH_SYN|TH_ACK)) != (TH_SYN|TH_ACK))) continue; newport = ntohs(tcp->th_sport); tmpl = ntohl(tcp->th_ack); if ((tmpl & 0x3F) != 0x1E && (tmpl & 0x3F) != 0x1F) tmpl = ntohl(tcp->th_seq); // We'll try the seq -- it is often helpful // in ACK scan responses if ((tmpl & 0x3F) == 0x1E || (tmpl & 0x3F) == 0x1F) { sequence = ((tmpl >> 6) & 0xffff) - pt->seq_offset; hostnum = sequence / pt->max_tries; trynum = sequence % pt->max_tries; } else { // Didn't get it back in either field -- we'll brute force it ... for(hostnum = pt->group_end; hostnum != (u32) -1; hostnum--) { if (hostbatch[hostnum]->v4host().s_addr == ip->ip_src.s_addr) break; } if (hostnum == (u32) -1) { if (o.debugging > 1) error("Warning, unexpected packet from machine %s", inet_ntoa(ip->ip_src)); continue; } trynum = ntohs(tcp->th_dport) - sportbase; sequence = hostnum * pt->max_tries + trynum; } if (trynum >= (u32) pt->max_tries) { if (o.debugging) error("Bogus trynum %d", trynum); continue; } if (hostnum > (u32) pt->group_end) { if (o.debugging) { error("Response from host beyond group_end"); } continue; } if (hostbatch[hostnum]->v4host().s_addr != ip->ip_src.s_addr) { if (o.debugging) { error("TCP ping response from unexpected host %s\n", inet_ntoa(ip->ip_src)); } continue; } if (o.debugging) log_write(LOG_STDOUT, "We got a TCP ping packet back from %s port %hi (hostnum = %d trynum = %d\n", inet_ntoa(ip->ip_src), ntohs(tcp->th_sport), hostnum, trynum); pingstyle = pingstyle_rawtcp;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?