⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 service_scan.cc

📁 Ubuntu packages of security software。 相当不错的源码
💻 CC
📖 第 1 页 / 共 5 页
字号:
// This function takes a template string (tmpl) which can have// placeholders in it such as $1 for substring matches in a regexp// that was run against subject, and subjectlen, with the 'nummatches'// matches in ovector.  The NUL-terminated newly composted string is// placed into 'newstr', as long as it doesn't exceed 'newstrlen'// bytes.  Trailing whitespace and commas are removed.  Returns zero for successstatic int dotmplsubst(const u8 *subject, int subjectlen, 		       int *ovector, int nummatches, char *tmpl, char *newstr,		       int newstrlen) {  int newlen;  char *srcstart=tmpl, *srcend;  char *dst = newstr;  char *newstrend = newstr + newstrlen; // Right after the final char  if (!newstr || !tmpl) return -1;  if (newstrlen < 3) return -1; // fuck this!    while(*srcstart) {    // First do any literal text before '$'    srcend = strchr(srcstart, '$');    if (!srcend) {      // Only literal text remain!      while(*srcstart) {	if (dst >= newstrend - 1)	  return -1;	*dst++ = *srcstart++;      }      *dst = '\0';      while (--dst >= newstr) {	if (isspace(*dst) || *dst == ',') 	  *dst = '\0';	else break;      }      return 0;    } else {      // Copy the literal text up to the '$', then do the substitution      newlen = srcend - srcstart;      if (newlen > 0) {	if (newstrend - dst <= newlen - 1)	  return -1;	memcpy(dst, srcstart, newlen);	dst += newlen;      }      srcstart = srcend;      newlen = substvar(srcstart, &srcend, dst, newstrend - dst, subject, 		    subjectlen, ovector, nummatches);      if (newlen == -1) return -1;      dst += newlen;      srcstart = srcend;    }  }  if (dst >= newstrend - 1)    return -1;  *dst = '\0';  while (--dst >= newstr) {    if (isspace(*dst) || *dst == ',')       *dst = '\0';    else break;  }  return 0;}// Use the six version templates and the match data included here// to put the version info into the given strings, (as long as the sizes// are sufficient).  Returns zero for success.  If no template is available// for a string, that string will have zero length after the function// call (assuming the corresponding length passed in is at least 1)int ServiceProbeMatch::getVersionStr(const u8 *subject, int subjectlen, 	    int *ovector, int nummatches, char *product, int productlen,	    char *version, int versionlen, char *info, int infolen,                  char *hostname, int hostnamelen, char *ostype, int ostypelen,                  char *devicetype, int devicetypelen) {  int rc;  assert(productlen >= 0 && versionlen >= 0 && infolen >= 0 &&         hostnamelen >= 0 && ostypelen >= 0 && devicetypelen >= 0);    if (productlen > 0) *product = '\0';  if (versionlen > 0) *version = '\0';  if (infolen > 0) *info = '\0';  if (hostnamelen > 0) *hostname = '\0';  if (ostypelen > 0) *ostype = '\0';  if (devicetypelen > 0) *devicetype = '\0';  int retval = 0;  // Now lets get this started!  We begin with the product name  if (product_template) {    rc = dotmplsubst(subject, subjectlen, ovector, nummatches, product_template, product, productlen);    if (rc != 0) {      error("Warning: Servicescan failed to fill product_template (subjectlen: %d). Too long? Match string was line %d: v/%s/%s/%s", subjectlen, deflineno, (product_template)? product_template : "",	    (version_template)? version_template : "", (info_template)? info_template : "");      if (productlen > 0) *product = '\0';      retval = -1;    }  }  if (version_template) {    rc = dotmplsubst(subject, subjectlen, ovector, nummatches, version_template, version, versionlen);    if (rc != 0) {      error("Warning: Servicescan failed to fill version_template (subjectlen: %d). Too long? Match string was line %d: v/%s/%s/%s", subjectlen, deflineno, (product_template)? product_template : "",	    (version_template)? version_template : "", (info_template)? info_template : "");      if (versionlen > 0) *version = '\0';      retval = -1;    }  }  if (info_template) {    rc = dotmplsubst(subject, subjectlen, ovector, nummatches, info_template, info, infolen);    if (rc != 0) {      error("Warning: Servicescan failed to fill info_template (subjectlen: %d). Too long? Match string was line %d: v/%s/%s/%s", subjectlen, deflineno, (product_template)? product_template : "",	    (version_template)? version_template : "", (info_template)? info_template : "");      if (infolen > 0) *info = '\0';      retval = -1;    }  }    if (hostname_template) {    rc = dotmplsubst(subject, subjectlen, ovector, nummatches, hostname_template, hostname, hostnamelen);    if (rc != 0) {      error("Warning: Servicescan failed to fill hostname_template (subjectlen: %d). Too long? Match string was line %d: h/%s/", subjectlen, deflineno, (hostname_template)? hostname_template : "");      if (hostnamelen > 0) *hostname = '\0';      retval = -1;    }  }  if (ostype_template) {    rc = dotmplsubst(subject, subjectlen, ovector, nummatches, ostype_template, ostype, ostypelen);    if (rc != 0) {      error("Warning: Servicescan failed to fill ostype_template (subjectlen: %d). Too long? Match string was line %d: p/%s/", subjectlen, deflineno, (ostype_template)? ostype_template : "");      if (ostypelen > 0) *ostype = '\0';      retval = -1;    }  }  if (devicetype_template) {    rc = dotmplsubst(subject, subjectlen, ovector, nummatches, devicetype_template, devicetype, devicetypelen);    if (rc != 0) {      error("Warning: Servicescan failed to fill devicetype_template (subjectlen: %d). Too long? Match string was line %d: d/%s/", subjectlen, deflineno, (devicetype_template)? devicetype_template : "");      if (devicetypelen > 0) *devicetype = '\0';      retval = -1;    }  }    return retval;}ServiceProbe::ServiceProbe() {  int i;  probename = NULL;  probestring = NULL;  totalwaitms = DEFAULT_SERVICEWAITMS;  probestringlen = 0; probeprotocol = -1;  // The default rarity level for a probe without a rarity  // directive - should almost never have to be relied upon.  rarity = 5;  fallbackStr = NULL;  for (i=0; i<MAXFALLBACKS+1; i++) fallbacks[i] = NULL;}ServiceProbe::~ServiceProbe() {  vector<ServiceProbeMatch *>::iterator vi;  if (probename) free(probename);  if (probestring) free(probestring);  for(vi = matches.begin(); vi != matches.end(); vi++) {    delete *vi;  }  if (fallbackStr) free(fallbackStr);}  // Parses the "probe " line in the nmap-service-probes file.  Pass the rest of the line  // after "probe ".  The format better be:  // [TCP|UDP] [probename] q|probetext|  // Note that the delimiter (|) of the probetext can be anything (within reason)  // the lineno is requested because this function will bail with an error  // (giving the line number) if it fails to parse the string.void ServiceProbe::setProbeDetails(char *pd, int lineno) {  char *p;  unsigned int len;  char delimiter;  if (!pd || !*pd)    fatal("Parse error on line %d of nmap-service-probes: no arguments found!", lineno);  // First the protocol  if (strncmp(pd, "TCP ", 4) == 0)      probeprotocol = IPPROTO_TCP;  else if (strncmp(pd, "UDP ", 4) == 0)      probeprotocol = IPPROTO_UDP;  else fatal("Parse error on line %d of nmap-service-probes: invalid protocol", lineno);  pd += 4;  // Next the service name  if (!isalnum(*pd)) fatal("Parse error on line %d of nmap-service-probes - bad probe name", lineno);  p = strchr(pd, ' ');  if (!p) fatal("Parse error on line %d of nmap-service-probes - nothing after probe name", lineno);  len = p - pd;  probename = (char *) safe_malloc(len + 1);  memcpy(probename, pd, len);  probename[len]  = '\0';  // Now for the probe itself  pd = p+1;  if (*pd != 'q') fatal("Parse error on line %d of nmap-service-probes - probe string must begin with 'q'", lineno);  delimiter = *(++pd);  p = strchr(++pd, delimiter);  if (!p) fatal("Parse error on line %d of nmap-service-probes -- no ending delimiter for probe string", lineno);  *p = '\0';  if (!cstring_unescape(pd, &len)) {    fatal("Parse error on line %d of nmap-service-probes: bad probe string escaping", lineno);  }  setProbeString((const u8 *)pd, len);}void ServiceProbe::setProbeString(const u8 *ps, int stringlen) {  if (probestringlen) free(probestring);  probestringlen = stringlen;  if (stringlen > 0) {    probestring = (u8 *) safe_malloc(stringlen + 1);    memcpy(probestring, ps, stringlen);    probestring[stringlen] = '\0'; // but note that other \0 may be in string  } else probestring = NULL;}void ServiceProbe::setPortVector(vector<u16> *portv, const char *portstr, 				 int lineno) {  const char *current_range;  char *endptr;  long int rangestart = 0, rangeend = 0;  current_range = portstr;  do {    while(*current_range && isspace(*current_range)) current_range++;    if (isdigit((int) *current_range)) {      rangestart = strtol(current_range, &endptr, 10);      if (rangestart < 0 || rangestart > 65535) {	fatal("Parse error on line %d of nmap-service-probes: Ports must be between 0 and 65535 inclusive", lineno);      }      current_range = endptr;      while(isspace((int) *current_range)) current_range++;    } else {      fatal("Parse error on line %d of nmap-service-probes: An example of proper portlist form is \"21-25,53,80\"", lineno);    }    /* Now I have a rangestart, time to go after rangeend */    if (!*current_range || *current_range == ',') {      /* Single port specification */      rangeend = rangestart;    } else if (*current_range == '-') {      current_range++;      if (isdigit((int) *current_range)) {	rangeend = strtol(current_range, &endptr, 10);	if (rangeend < 0 || rangeend > 65535 || rangeend < rangestart) {	  fatal("Parse error on line %d of nmap-service-probes: Ports must be between 0 and 65535 inclusive", lineno);	}	current_range = endptr;      } else {	fatal("Parse error on line %d of nmap-service-probes: An example of proper portlist form is \"21-25,53,80\"", lineno);      }    } else {      fatal("Parse error on line %d of nmap-service-probes: An example of proper portlist form is \"21-25,53,80\"", lineno);    }    /* Now I have a rangestart and a rangeend, so I can add these ports */    while(rangestart <= rangeend) {      portv->push_back(rangestart);      rangestart++;    }        /* Find the next range */    while(isspace((int) *current_range)) current_range++;    if (*current_range && *current_range != ',') {      fatal("Parse error on line %d of nmap-service-probes: An example of proper portlist form is \"21-25,53,80\"", lineno);    }    if (*current_range == ',')      current_range++;  } while(current_range && *current_range);}  // Takes a string as given in the 'ports '/'sslports ' line of  // nmap-service-probes.  Pass in the list from the appropriate  // line.  For 'sslports', tunnel should be specified as  // SERVICE_TUNNEL_SSL.  Otherwise use SERVICE_TUNNEL_NONE.  The line  // number is requested because this function will bail with an error  // (giving the line number) if it fails to parse the string.  Ports  // are a comma separated list of ports and ranges  // (e.g. 53,80,6000-6010).void ServiceProbe::setProbablePorts(enum service_tunnel_type tunnel,				    const char *portstr, int lineno) {  if (tunnel == SERVICE_TUNNEL_NONE)    setPortVector(&probableports, portstr, lineno);  else {    assert(tunnel == SERVICE_TUNNEL_SSL);    setPortVector(&probablesslports, portstr, lineno);  }}  /* Returns true if the passed in port is on the list of probable     ports for this probe and tunnel type.  Use a tunnel of     SERVICE_TUNNEL_SSL or SERVICE_TUNNEL_NONE as appropriate */bool ServiceProbe::portIsProbable(enum service_tunnel_type tunnel, u16 portno) {  vector<u16> *portv;  portv = (tunnel == SERVICE_TUNNEL_SSL)? &probablesslports : &probableports;    if (find(portv->begin(), portv->end(), portno) == portv->end())    return false;  return true;} // Returns true if the passed in service name is among those that can  // be detected by the matches in this probe;bool ServiceProbe::serviceIsPossible(const char *sname) {  vector<const char *>::iterator vi;  for(vi = detectedServices.begin(); vi != detectedServices.end(); vi++) {    if (strcmp(*vi, sname) == 0)      return true;  }  return false;}// Takes a string following a Rarity directive in the probes file.// The string should contain a single integer between 1 and 9. The// default rarity is 5. This function will bail if the string is invalid.void ServiceProbe::setRarity(const char *portstr, int lineno) {  int tp;  tp = atoi(portstr);  if (tp < 1 || tp > 9)    fatal("%s: Rarity directive on line %d of nmap-service-probes must be between 1 and 9", __func__, lineno);

⌨️ 快捷键说明

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