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

📄 service_scan.cc

📁 Ubuntu packages of security software。 相当不错的源码
💻 CC
📖 第 1 页 / 共 5 页
字号:
  if (*matchtext == 'm') {    if (!*(matchtext+1))      fatal("%s: parse error on line %d of nmap-service-probes: matchtext must begin with 'm'", __func__, lineno);    matchtype = SERVICEMATCH_REGEX;    delimchar = *(++matchtext);    ++matchtext;    // find the end of the regex    p = strchr(matchtext, delimchar);    if (!p) fatal("%s: parse error on line %d of nmap-service-probes: could not find end delimiter for regex", __func__, lineno);    matchstrlen = p - matchtext;    matchstr = (char *) safe_malloc(matchstrlen + 1);    memcpy(matchstr, matchtext, matchstrlen);    matchstr[matchstrlen]  = '\0';        matchtext = p + 1; // skip past the delim    // any options?    while(*matchtext && !isspace(*matchtext)) {      if (*matchtext == 'i')	matchops_ignorecase = true;      else if (*matchtext == 's')	matchops_dotall = true;      else fatal("%s: illegal regexp option on line %d of nmap-service-probes", __func__, lineno);      matchtext++;    }    // Next we compile and study the regular expression to match    if (matchops_ignorecase)      pcre_compile_ops |= PCRE_CASELESS;    if (matchops_dotall)      pcre_compile_ops |= PCRE_DOTALL;        regex_compiled = pcre_compile(matchstr, pcre_compile_ops, &pcre_errptr, 				     &pcre_erroffset, NULL);        if (regex_compiled == NULL)      fatal("%s: illegal regexp on line %d of nmap-service-probes (at regexp offset %d): %s\n", __func__, lineno, pcre_erroffset, pcre_errptr);            // Now study the regexp for greater efficiency    regex_extra = pcre_study(regex_compiled, 0, &pcre_errptr);    if (pcre_errptr != NULL)      fatal("%s: failed to pcre_study regexp on line %d of nmap-service-probes: %s\n", __func__, lineno, pcre_errptr);  } else {    /* Invalid matchtext */    fatal("%s: parse error on line %d of nmap-service-probes: match string must begin with 'm'", __func__, lineno);  }  /* OK! Now we look for any templates of the form ?/.../   * where ? is either p, v, i, h, o, or d. / is any   * delimiter character and ... is a template */  while(1) {  while(isspace(*matchtext)) matchtext++;    if (*matchtext == '\0' || *matchtext == '\r' || *matchtext == '\n') break;    modechar = *(matchtext++);    if (*matchtext == 0 || *matchtext == '\r' || *matchtext == '\n')      fatal("%s: parse error on line %d of nmap-service-probes", __func__, lineno);    delimchar = *(matchtext++);    p = strchr(matchtext, delimchar);    if (!p) fatal("%s: parse error on line %d of nmap-service-probes", __func__, lineno);    tmptemplate = NULL;    tmpbuflen = p - matchtext;    if (tmpbuflen > 0) {      tmptemplate = (char *) safe_malloc(tmpbuflen + 1);      memcpy(tmptemplate, matchtext, tmpbuflen);      tmptemplate[tmpbuflen] = '\0';    }    switch(modechar){    case 'p': curr_tmp = &product_template; break;    case 'v': curr_tmp = &version_template; break;    case 'i': curr_tmp = &info_template; break;    case 'h': curr_tmp = &hostname_template; break;    case 'o': curr_tmp = &ostype_template; break;    case 'd': curr_tmp = &devicetype_template; break;    default:    	fatal("%s: Unknown template specifier '%c' on line %d of nmap-service-probes", __func__, modechar, lineno);    }    if(*curr_tmp){      if(o.debugging)        error("WARNING: Template \"%c/%s/\" replaced with \"%c/%s/\" on line %d of nmap-service-probes",        	modechar,    	  	*curr_tmp,        	modechar,    	  	tmptemplate,    	  	lineno);    	free(*curr_tmp);      }    *curr_tmp = tmptemplate;    matchtext = p + 1;  }  isInitialized = 1;}  // If the buf (of length buflen) match the regex in this  // ServiceProbeMatch, returns the details of the match (service  // name, version number if applicable, and whether this is a "soft"  // match.  If the buf doesn't match, the serviceName field in the  // structure will be NULL.  The MatchDetails sructure returned is  // only valid until the next time this function is called. The only  // exception is that the serviceName field can be saved throughought  // program execution.  If no version matched, that field will be  // NULL.const struct MatchDetails *ServiceProbeMatch::testMatch(const u8 *buf, int buflen) {  int rc;  int i;  static char product[80];  static char version[80];  static char info[128];  static char hostname[80];  static char ostype[32];  static char devicetype[32];  char *bufc = (char *) buf;  int ovector[150]; // allows 50 substring matches (including the overall match)  assert(isInitialized);  assert (matchtype == SERVICEMATCH_REGEX);  // Clear out the output struct  memset(&MD_return, 0, sizeof(MD_return));  MD_return.isSoft = isSoft;  rc = pcre_exec(regex_compiled, regex_extra, bufc, buflen, 0, 0, ovector, sizeof(ovector) / sizeof(*ovector));  if (rc < 0) {#ifdef PCRE_ERROR_MATCHLIMIT  // earlier PCRE versions lack this    if (rc == PCRE_ERROR_MATCHLIMIT) {      if (o.debugging || o.verbose > 1) 	error("Warning: Hit PCRE_ERROR_MATCHLIMIT when probing for service %s with the regex '%s'", servicename, matchstr);    } else#endif // PCRE_ERROR_MATCHLIMIT      if (rc != PCRE_ERROR_NOMATCH) {	fatal("Unexpected PCRE error (%d) when probing for service %s with the regex '%s'", rc, servicename, matchstr);      }  } else {    // Yeah!  Match apparently succeeded.    // Now lets get the version number if available    i = getVersionStr(buf, buflen, ovector, rc, product, sizeof(product), version, sizeof(version), info, sizeof(info),                      hostname, sizeof(hostname), ostype, sizeof(ostype), devicetype, sizeof(devicetype));        if (*product) MD_return.product = product;    if (*version) MD_return.version = version;    if (*info) MD_return.info = info;    if (*hostname) MD_return.hostname = hostname;    if (*ostype) MD_return.ostype = ostype;    if (*devicetype) MD_return.devicetype = devicetype;      MD_return.serviceName = servicename;  }  return &MD_return;}// This simple function parses arguments out of a string.  The string// starts with the first argument.  Each argument can be a string or// an integer.  Strings must be enclosed in double quotes ("").  Most// standard C-style escapes are supported.  If this is successful, the// number of args found is returned, args is filled appropriately, and// args_end (if non-null) is set to the character after the closing// ')'.  Otherwise we return -1 and the values of args and args_end// are undefined.static int getsubstcommandargs(struct substargs *args, char *args_start, 			char **args_end) {  char *p;  unsigned int len;  if (!args || !args_start) return -1;  memset(args, 0, sizeof(*args));  while(*args_start && *args_start != ')') {    // Find the next argument.    while(isspace(*args_start)) args_start++;    if (*args_start == ')')      break;    else if (*args_start == '"') {      // OK - it is a string      // Do we have space for another arg?      if (args->num_args == SUBSTARGS_MAX_ARGS)	return -1;      do {	args_start++;	if (*args_start == '"' && (*(args_start - 1) != '\\' || *(args_start - 2) == '\\'))	  break;	len = args->str_args_len[args->num_args];	if (len >= SUBSTARGS_STRLEN - 1)	  return -1;	args->str_args[args->num_args][len] = *args_start;	args->str_args_len[args->num_args]++;      } while(*args_start);      len = args->str_args_len[args->num_args];      args->str_args[args->num_args][len] = '\0';      // Now handle escaped characters and such      if (!cstring_unescape(args->str_args[args->num_args], &len))	return -1;      args->str_args_len[args->num_args] = len;      args->arg_types[args->num_args] = SUBSTARGS_ARGTYPE_STRING;      args->num_args++;      args_start++;      args_start = strpbrk(args_start, ",)");      if (!args_start) return -1;      if (*args_start == ',') args_start++;    } else {      // Must be an integer argument      args->int_args[args->num_args] = (int) strtol(args_start, &p, 0);      if (p <= args_start) return -1;      args_start = p;      args->arg_types[args->num_args] = SUBSTARGS_ARGTYPE_INT;      args->num_args++;      args_start = strpbrk(args_start, ",)");      if (!args_start) return -1;      if (*args_start == ',') args_start++;    }  }  if (*args_start == ')') args_start++;  if (args_end) *args_end = args_start;  return args->num_args;}// This function does the actual substitution of a placeholder like $2// or $U(4) into the given buffer.  It returns the number of chars// written, or -1 if it fails.  tmplvar is a template variable, such// as "$U(2)".  We determine the appropriate string representing that,// and place it in newstr (as long as it doesn't exceed newstrlen).// We then set *tmplvarend to the character after the// variable. subject, subjectlen, ovector, and nummatches mean the// same as in dotmplsubst().static int substvar(char *tmplvar, char **tmplvarend, char *newstr, 	     int newstrlen, const u8 *subject, int subjectlen, int *ovector,	     int nummatches) {  char substcommand[16];  char *p = NULL;  char *p_end;  int len;  int subnum = 0;  int offstart, offend;  int byteswritten = 0; // for return val  int rc;  int i;  struct substargs command_args;  // skip the '$'  if (*tmplvar != '$') return -1;  tmplvar++;  if (!isdigit(*tmplvar)) {    p = strchr(tmplvar, '(');    if (!p) return -1;    len = p - tmplvar;    if (!len || len >= (int) sizeof(substcommand))      return -1;    memcpy(substcommand, tmplvar, len);    substcommand[len] = '\0';    tmplvar = p+1;    // Now we grab the arguments.    rc = getsubstcommandargs(&command_args, tmplvar, &p_end);    if (rc <= 0) return -1;    tmplvar = p_end;  } else {    substcommand[0] = '\0';    subnum = *tmplvar - '0';    tmplvar++;  }  if (tmplvarend) *tmplvarend = tmplvar;  if (!*substcommand) {    if (subnum > 9 || subnum <= 0) return -1;    if (subnum >= nummatches) return -1;    offstart = ovector[subnum * 2];    offend = ovector[subnum * 2 + 1];    assert(offstart >= 0 && offstart < subjectlen);    assert(offend >= 0 && offend <= subjectlen);    len = offend - offstart;    // A plain-jane copy    if (newstrlen <= len - 1)      return -1;    memcpy(newstr, subject + offstart, len);    byteswritten = len;  } else if (strcmp(substcommand, "P") == 0) {    if (command_args.arg_types[0] != SUBSTARGS_ARGTYPE_INT)      return -1;    subnum = command_args.int_args[0];    if (subnum > 9 || subnum <= 0) return -1;    if (subnum >= nummatches) return -1;    offstart = ovector[subnum * 2];    offend = ovector[subnum * 2 + 1];    assert(offstart >= 0 && offstart < subjectlen);    assert(offend >= 0 && offend <= subjectlen);    // This filter only includes printable characters.  It is particularly    // useful for collapsing unicode text that looks like     // "W\0O\0R\0K\0G\0R\0O\0U\0P\0"    for(i=offstart; i < offend; i++)      if (isprint((int) subject[i])) {	if (byteswritten >= newstrlen - 1)	  return -1;	newstr[byteswritten++] = subject[i];      }  } else if (strcmp(substcommand, "SUBST") == 0) {    char *findstr, *replstr;    int findstrlen, replstrlen;   if (command_args.arg_types[0] != SUBSTARGS_ARGTYPE_INT)      return -1;    subnum = command_args.int_args[0];    if (subnum > 9 || subnum <= 0) return -1;    if (subnum >= nummatches) return -1;    offstart = ovector[subnum * 2];    offend = ovector[subnum * 2 + 1];    assert(offstart >= 0 && offstart < subjectlen);    assert(offend >= 0 && offend <= subjectlen);    if (command_args.arg_types[1] != SUBSTARGS_ARGTYPE_STRING ||	command_args.arg_types[2] != SUBSTARGS_ARGTYPE_STRING)      return -1;    findstr = command_args.str_args[1];    findstrlen = command_args.str_args_len[1];    replstr = command_args.str_args[2];    replstrlen = command_args.str_args_len[2];    for(i=offstart; i < offend; ) {      if (byteswritten >= newstrlen - 1)	return -1;      if (offend - i < findstrlen)	newstr[byteswritten++] = subject[i++]; // No room for match      else if (memcmp(subject + i, findstr, findstrlen) != 0)	newstr[byteswritten++] = subject[i++]; // no match      else {	// The find string was found, copy it to newstring	if (newstrlen - 1 - byteswritten < replstrlen)	  return -1;	memcpy(newstr + byteswritten, replstr, replstrlen);	byteswritten += replstrlen;	i += findstrlen;      }    }  } else return -1; // Unknown command  if (byteswritten >= newstrlen) return -1;  newstr[byteswritten] = '\0';  return byteswritten;}

⌨️ 快捷键说明

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