scan_engine.cc

来自「Ubuntu packages of security software。 相」· CC 代码 · 共 1,755 行 · 第 1/5 页

CC
1,755
字号
    numprobes = ports->prot_count;  } else if (ping_scan_arp) {    numprobes = 1;  } else if (ping_scan) {    numprobes = 0;    if (ptech.rawtcpscan) {      if (o.pingtype & PINGTYPE_TCP_USE_ACK)        numprobes += o.num_ping_ackprobes;      if (o.pingtype & PINGTYPE_TCP_USE_SYN)        numprobes += o.num_ping_synprobes;    }    if (ptech.rawudpscan)      numprobes += o.num_ping_udpprobes;    if (ptech.rawicmpscan) {      if (o.pingtype & PINGTYPE_ICMP_PING)        numprobes++;      if (o.pingtype & PINGTYPE_ICMP_MASK)        numprobes++;      if (o.pingtype & PINGTYPE_ICMP_TS)        numprobes++;    }    if (ptech.rawprotoscan)      numprobes += o.num_ping_protoprobes;    if (ptech.connecttcpscan)      numprobes += o.num_ping_synprobes;  } else assert(0); /* TODO: RPC scan */  return numprobes;}  /* Consults with the group stats, and the hstats for every     incomplete hosts to determine whether any probes may be sent.     Returns true if they can be sent immediately.  If when is     non-NULL, it is filled with the next possible time that probes     can be sent, assuming no probe responses are received (call it     again if they are).  when will be now, if the function returns     true */bool UltraScanInfo::sendOK(struct timeval *when) {  struct timeval lowhtime = {0};  struct timeval tmptv;  list<HostScanStats *>::iterator host;  bool ggood = false;  bool hgood = false;  bool thisHostGood = false;  bool foundgood = false;  ggood = gstats->sendOK();  if (!ggood) {    if (when) {      TIMEVAL_MSEC_ADD(lowhtime, now, 1000);       // Can't do anything until global is OK - means packet receipt      // or probe timeout.      for(host = incompleteHosts.begin(); host != incompleteHosts.end(); 	  host++) {	if ((*host)->nextTimeout(&tmptv)) {	  if (TIMEVAL_SUBTRACT(tmptv, lowhtime) < 0)	    lowhtime = tmptv;	}      }      *when = lowhtime;    }  } else {    for(host = incompleteHosts.begin(); host != incompleteHosts.end(); host++) {      thisHostGood = (*host)->sendOK(&tmptv);      if (ggood && thisHostGood) {	lowhtime = tmptv;	hgood = true;	foundgood = true;	break;      }            if (!foundgood || TIMEVAL_SUBTRACT(lowhtime, tmptv) > 0) {	lowhtime = tmptv;	foundgood = true;      }    }        assert(foundgood);  }    if (TIMEVAL_MSEC_SUBTRACT(lowhtime, now) < 0)    lowhtime = now;  if (when) *when = lowhtime;  return (TIMEVAL_MSEC_SUBTRACT(lowhtime, now) == 0)? true : false;}/* Find a HostScanStats by its IP address in the incomplete and completed lists.   Returns NULL if none are found. */HostScanStats *UltraScanInfo::findHost(struct sockaddr_storage *ss) {  list<HostScanStats *>::iterator hss;  struct sockaddr_in *sin = (struct sockaddr_in *) ss;  if (sin->sin_family != AF_INET)    fatal("%s passed a non IPv4 address", __func__);  for(hss = incompleteHosts.begin(); hss != incompleteHosts.end(); hss++) {    if ((*hss)->target->v4hostip()->s_addr == sin->sin_addr.s_addr) {      if (o.debugging > 2)	log_write(LOG_STDOUT, "Found %s in incomplete hosts list.\n", (*hss)->target->targetipstr());      return *hss;    }  }  for(hss = completedHosts.begin(); hss != completedHosts.end(); hss++) {    if ((*hss)->target->v4hostip()->s_addr == sin->sin_addr.s_addr) {      if (o.debugging > 2)	log_write(LOG_STDOUT, "Found %s in completed hosts list.\n", (*hss)->target->targetipstr());      return *hss;    }  }  return NULL;}bool UltraScanInfo::numIncompleteHostsLessThan(unsigned int n) {  std::list<HostScanStats *>::iterator hostI;  unsigned int count;  count = 0;  hostI = incompleteHosts.begin();  while (count < n && hostI != incompleteHosts.end()) {    hostI++;    count++;  }  return count < n;}  /* Removes any hosts that have completed their scans from the incompleteHosts     list.  Returns the number of hosts removed. */int UltraScanInfo::removeCompletedHosts() {  list<HostScanStats *>::iterator hostI, nxt;  HostScanStats *hss = NULL;  int hostsRemoved = 0;  bool timedout = false;  for(hostI = incompleteHosts.begin(); hostI != incompleteHosts.end();      hostI = nxt) {    nxt = hostI;    nxt++;    hss = *hostI;    timedout = hss->target->timedOut(&now);    if (hss->completed() || timedout) {      /* A host to remove!  First adjust nextI appropriately */      if (nextI == hostI && incompleteHosts.size() > 1) {	nextI++;	if (nextI == incompleteHosts.end())	  nextI = incompleteHosts.begin();      }      if (o.verbose && gstats->numprobes > 50) {	int remain = incompleteHosts.size() - 1;	if (remain && !timedout)	  log_write(LOG_STDOUT, "Completed %s against %s in %.2fs (%d %s)\n",		    scantype2str(scantype), hss->target->targetipstr(), 		    TIMEVAL_MSEC_SUBTRACT(now, SPM->begin) / 1000.0, remain, 		    (remain == 1)? "host left" : "hosts left");	else if (timedout)	  log_write(LOG_STDOUT, "%s timed out during %s (%d %s)\n",		    hss->target->targetipstr(), scantype2str(scantype), remain,		    (remain == 1)? "host left" : "hosts left");      }      if (o.debugging > 2) {        unsigned int num_outstanding_probes;        num_outstanding_probes = hss->probes_outstanding.size();        log_write(LOG_PLAIN, "Moving %s to completed hosts list with %d outstanding %s.\n",                  hss->target->targetipstr(), num_outstanding_probes,                  num_outstanding_probes == 1 ? "probe" : "probes");        if (o.debugging > 3) {          char tmpbuf[32];          std::list<UltraProbe *>::iterator iter;          for (iter = hss->probes_outstanding.begin(); iter != hss->probes_outstanding.end(); iter++)            log_write(LOG_PLAIN, "* %s\n", probespec2ascii((probespec *) (*iter)->pspec(), tmpbuf, sizeof(tmpbuf)));        }      }      completedHosts.push_front(hss);      incompleteHosts.erase(hostI);      hostsRemoved++;      if (timedout) gstats->num_hosts_timedout++;      hss->target->stopTimeOutClock(&now);    }  }  return hostsRemoved;}/* Determines an ideal number of hosts to be scanned (port scan, os   scan, version detection, etc.) in parallel after the ping scan is   completed.  This is a balance between efficiency (more hosts in   parallel often reduces scan time per host) and results latency (you   need to wait for all hosts to finish before Nmap can spit out the   results).  Memory consumption usually also increases with the   number of hosts scanned in parallel, though rarely to significant   levels. */int determineScanGroupSize(int hosts_scanned_so_far, 			   struct scan_lists *ports) {  int groupsize = 10;  if (o.UDPScan())    groupsize = 50;  else if (o.TCPScan()) {    groupsize = MAX(1024 / (ports->tcp_count ? ports->tcp_count : 1), 30);    if (ports->tcp_count > 1000 && hosts_scanned_so_far == 0 && 	o.timing_level < 4)      groupsize = 5; // Give quick results for the very first batch  }  groupsize = box(o.minHostGroupSz(), o.maxHostGroupSz(), groupsize);  return groupsize;}/* Initialize the ultra_timing_vals structure timing.  The utt must be   TIMING_HOST or TIMING_GROUP.  If you happen to have the current   time handy, pass it as now, otherwise pass NULL */static void init_ultra_timing_vals(ultra_timing_vals *timing, 				   enum ultra_timing_type utt, 				   int num_hosts_in_group, 				   struct ultra_scan_performance_vars *perf,				   struct timeval *now) {  timing->cwnd = (utt == TIMING_HOST)? perf->host_initial_cwnd : perf->group_initial_cwnd;  timing->ccthresh = perf->initial_ccthresh; /* Will be reduced if any packets are dropped anyway */  timing->num_updates = 0;  if (now)    timing->last_drop = *now;  else gettimeofday(&timing->last_drop, NULL);}/* Returns the next probe to try against target.  Supports many   different types of probes (see probespec structure).  Returns 0 and   fills in pspec if there is a new probe, -1 if there are none   left. */static int get_next_target_probe(UltraScanInfo *USI, HostScanStats *hss, 				 probespec *pspec) {  assert(pspec);  if (USI->tcp_scan) {    if (hss->next_portidx >= USI->ports->tcp_count)      return -1;    if (USI->scantype == CONNECT_SCAN)      pspec->type = PS_CONNECTTCP;    else      pspec->type = PS_TCP;    pspec->proto = IPPROTO_TCP;    pspec->pd.tcp.dport = USI->ports->tcp_ports[hss->next_portidx++];    if (USI->scantype == CONNECT_SCAN)       pspec->pd.tcp.flags = TH_SYN;    else if (o.scanflags != -1)      pspec->pd.tcp.flags = o.scanflags;    else {      switch(USI->scantype) {      case SYN_SCAN: pspec->pd.tcp.flags = TH_SYN; break;      case ACK_SCAN: pspec->pd.tcp.flags = TH_ACK; break;      case XMAS_SCAN: pspec->pd.tcp.flags = TH_FIN|TH_URG|TH_PUSH; break;      case NULL_SCAN: pspec->pd.tcp.flags = 0; break;      case FIN_SCAN: pspec->pd.tcp.flags = TH_FIN; break;      case MAIMON_SCAN: pspec->pd.tcp.flags = TH_FIN|TH_ACK; break;      case WINDOW_SCAN: pspec->pd.tcp.flags = TH_ACK; break;      default:	assert(0);	break;      }    }    return 0;  } else if (USI->udp_scan) {    if (hss->next_portidx >= USI->ports->udp_count)      return -1;    pspec->type = PS_UDP;    pspec->proto = IPPROTO_UDP;    pspec->pd.udp.dport = USI->ports->udp_ports[hss->next_portidx++];    return 0;  } else if (USI->prot_scan) {    if (hss->next_portidx >= USI->ports->prot_count)      return -1;    pspec->type = PS_PROTO;    pspec->proto = USI->ports->prots[hss->next_portidx++];    return 0;  } else if (USI->ping_scan_arp) {    if (hss->sent_arp)      return -1;    pspec->type = PS_ARP;    hss->sent_arp = true;    return 0;  } else if (USI->ping_scan) {    if (USI->ptech.rawtcpscan) {      pspec->type = PS_TCP;      pspec->proto = IPPROTO_TCP;      if ((o.pingtype & PINGTYPE_TCP_USE_ACK)        && hss->next_ackportpingidx < o.num_ping_ackprobes) {        pspec->pd.tcp.dport = o.ping_ackprobes[hss->next_ackportpingidx++];        pspec->pd.tcp.flags = TH_ACK;        return 0;      }      if ((o.pingtype & PINGTYPE_TCP_USE_SYN)        && hss->next_synportpingidx < o.num_ping_synprobes) {        pspec->pd.tcp.dport = o.ping_synprobes[hss->next_synportpingidx++];        pspec->pd.tcp.flags = TH_SYN;        return 0;      }    }    if (USI->ptech.rawudpscan && hss->next_udpportpingidx < o.num_ping_udpprobes) {      pspec->type = PS_UDP;      pspec->proto = IPPROTO_UDP;      pspec->pd.udp.dport = o.ping_udpprobes[hss->next_udpportpingidx++];      return 0;    }    if (USI->ptech.rawicmpscan) {      pspec->type = PS_ICMP;      pspec->proto = IPPROTO_ICMP;      if ((o.pingtype & PINGTYPE_ICMP_PING) && !hss->sent_icmp_ping) {        hss->sent_icmp_ping = true;        pspec->pd.icmp.type = ICMP_ECHO;        pspec->pd.icmp.code = 0;        return 0;      }      if ((o.pingtype & PINGTYPE_ICMP_MASK) && !hss->sent_icmp_mask) {        hss->sent_icmp_mask = true;        pspec->pd.icmp.type = ICMP_MASK;        pspec->pd.icmp.code = 0;        return 0;      }      if ((o.pingtype & PINGTYPE_ICMP_TS) && !hss->sent_icmp_ts) {        hss->sent_icmp_ts = true;        pspec->pd.icmp.type = ICMP_TSTAMP;        pspec->pd.icmp.code = 0;        return 0;      }    }    if (USI->ptech.rawprotoscan) {      pspec->type = PS_PROTO;      pspec->proto = o.ping_protoprobes[hss->next_protoportpingidx++];      return 0;    }    if (USI->ptech.connecttcpscan && hss->next_synportpingidx < o.num_ping_synprobes) {      pspec->type = PS_CONNECTTCP;      pspec->proto = IPPROTO_TCP;      pspec->pd.tcp.dport = o.ping_synprobes[hss->next_synportpingidx++];      pspec->pd.tcp.flags = TH_SYN;      return 0;    }  }  assert(0); /* TODO: need to handle other protocols */  return -1;}/* Returns the number of ports remaining to probe */int HostScanStats::freshPortsLeft() {  if (USI->tcp_scan) {    if (next_portidx >= USI->ports->tcp_count)      return 0;    return USI->p

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?