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 + -
显示快捷键?