示例#1
0
static int hash_match(const struct regex_matcher *rlist, const char *host, size_t hlen, const char *path, size_t plen, int *prefix_matched)
{
	const char *virname;
#if 0
	char s[1024];
	strncpy(s, host, hlen);
	strncpy(s+hlen, path, plen);
	s[hlen+plen] = '\0';
	cli_dbgmsg("hash lookup for: %s\n",s);
#endif
    UNUSEDPARAM(prefix_matched);

	if(rlist->sha256_hashes.bm_patterns) {
	    const char hexchars[] = "0123456789ABCDEF";
	    unsigned char h[65];
	    unsigned char sha256_dig[32];
	    unsigned i;
        void *sha256;

        sha256 = cl_hash_init("sha256");
        if (!(sha256))
            return CL_EMEM;

        cl_update_hash(sha256, (void *)host, hlen);
        cl_update_hash(sha256, (void *)path, plen);
        cl_finish_hash(sha256, sha256_dig);

	    for(i=0;i<32;i++) {
		h[2*i] = hexchars[sha256_dig[i]>>4];
		h[2*i+1] = hexchars[sha256_dig[i]&0xf];
	    }
	    h[64]='\0';
	    cli_dbgmsg("Looking up hash %s for %s(%u)%s(%u)\n", h, host, (unsigned)hlen, path, (unsigned)plen);
#if 0
	    if (prefix_matched) {
		if (cli_bm_scanbuff(sha256_dig, 4, &virname, NULL, &rlist->hostkey_prefix,0,NULL,NULL,NULL) == CL_VIRUS) {
		    cli_dbgmsg("prefix matched\n");
		    *prefix_matched = 1;
		} else
		    return CL_SUCCESS;
	    }
#endif
	    if (cli_bm_scanbuff(sha256_dig, 32, &virname, NULL, &rlist->sha256_hashes,0,NULL,NULL,NULL) == CL_VIRUS) {
		cli_dbgmsg("This hash matched: %s\n", h);
		switch(*virname) {
		    case 'W':
			cli_dbgmsg("Hash is whitelisted, skipping\n");
			break;
		    case '1':
			return CL_PHISH_HASH1;
		    case '2':
			return CL_PHISH_HASH2;
		    default:
			return CL_PHISH_HASH0;
		}
	    }
	}
	return CL_SUCCESS;
}
END_TEST

START_TEST (test_bm_scanbuff_allscan) {
	struct cli_matcher *root;
	const char *virname = NULL;
	int ret;


    root = ctx.engine->root[0];
    fail_unless(root != NULL, "root == NULL");

#ifdef USE_MPOOL
    root->mempool = mpool_create();
#endif
    ret = cli_bm_init(root);
    fail_unless(ret == CL_SUCCESS, "cli_bm_init() failed");

    ret = cli_parse_add(root, "Sig1", "deadbabe", 0, 0, 0, "*", 0, NULL, 0);
    fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");
    ret = cli_parse_add(root, "Sig2", "deadbeef", 0, 0, 0, "*", 0, NULL, 0);
    fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");
    ret = cli_parse_add(root, "Sig3", "babedead", 0, 0, 0, "*", 0, NULL, 0);
    fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");

    ret = cli_bm_scanbuff((const unsigned char*)"blah\xde\xad\xbe\xef", 12, &virname, NULL, root, 0, NULL, NULL, NULL);
    fail_unless(ret == CL_VIRUS, "cli_bm_scanbuff() failed");
    fail_unless(!strncmp(virname, "Sig2", 4), "Incorrect signature matched in cli_bm_scanbuff()\n");
}
示例#3
0
END_TEST

START_TEST (test_bm_scanbuff) {
	struct cli_matcher *root;
	const char *virname = NULL;
	int ret;


    root = (struct cli_matcher *) cli_calloc(1, sizeof(struct cli_matcher));
    fail_unless(root != NULL, "root == NULL");

#ifdef USE_MPOOL
    root->mempool = mpool_create();
#endif
    ret = cli_bm_init(root);
    fail_unless(ret == CL_SUCCESS, "cli_bm_init() failed");

    ret = cli_parse_add(root, "Sig1", "deadbabe", 0, 0, NULL, 0, NULL, 0);
    fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");
    ret = cli_parse_add(root, "Sig2", "deadbeef", 0, 0, NULL, 0, NULL, 0);
    fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");
    ret = cli_parse_add(root, "Sig3", "babedead", 0, 0, NULL, 0, NULL, 0);
    fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");

    ret = cli_bm_scanbuff("blah\xde\xad\xbe\xef", 12, &virname, root, 0, 0, -1);
    fail_unless(ret == CL_VIRUS, "cli_bm_scanbuff() failed");
    fail_unless(!strncmp(virname, "Sig2", 4), "Incorrect signature matched in cli_bm_scanbuff()\n");
    cli_bm_free(root);
#ifdef USE_MPOOL
    mpool_destroy(root->mempool);
#endif
    free(root);
}
示例#4
0
static inline int matcher_run(const struct cli_matcher *root,
			      const unsigned char *buffer, uint32_t length,
			      const char **virname, struct cli_ac_data *mdata,
			      uint32_t offset,
			      const struct cli_target_info *tinfo,
			      cli_file_t ftype,
			      struct cli_matched_type **ftoffset,
			      unsigned int acmode,
                              unsigned int pcremode,
			      struct cli_ac_result **acres,
			      fmap_t *map,
			      struct cli_bm_off *offdata,
			      struct cli_pcre_off *poffdata,
			      cli_ctx *ctx)
{
    int ret, saved_ret = CL_CLEAN;
    int32_t pos = 0;
    struct filter_match_info info;
    uint32_t orig_length, orig_offset;
    const unsigned char* orig_buffer;
    unsigned int viruses_found = 0;

    if (root->filter) {
	if(filter_search_ext(root->filter, buffer, length, &info) == -1) {
	    /*  for safety always scan last maxpatlen bytes */
	    pos = length - root->maxpatlen - 1;
	    if (pos < 0) pos = 0;
	    PERF_LOG_FILTER(pos, length, root->type);
	} else {
	    /* must not cut buffer for 64[4-4]6161, because we must be able to check
	     * 64! */
	    pos = info.first_match - root->maxpatlen - 1;
	    if (pos < 0) pos = 0;
	    PERF_LOG_FILTER(pos, length, root->type);
	}
    } else {
	PERF_LOG_FILTER(0, length, root->type);
    }

    orig_length = length;
    orig_buffer = buffer;
    orig_offset = offset;
    length -= pos;
    buffer += pos;
    offset += pos;
    if (!root->ac_only) {
	PERF_LOG_TRIES(0, 1, length);
	if (root->bm_offmode) {
	    /* Don't use prefiltering for BM offset mode, since BM keeps tracks
	     * of offsets itself, and doesn't work if we skip chunks of input
	     * data */
	    ret = cli_bm_scanbuff(orig_buffer, orig_length, virname, NULL, root, orig_offset, tinfo, offdata, ctx);
	} else {
	    ret = cli_bm_scanbuff(buffer, length, virname, NULL, root, offset, tinfo, offdata, ctx);
	}
	if (ret != CL_CLEAN) {
	    if (ret != CL_VIRUS)
		return ret;

	    /* else (ret == CL_VIRUS) */
	    if (SCAN_ALL)
		viruses_found = 1;
	    else {
		cli_append_virus(ctx, *virname);
		return ret;
	    }
	}
    }
    PERF_LOG_TRIES(acmode, 0, length);
    ret = cli_ac_scanbuff(buffer, length, virname, NULL, acres, root, mdata, offset, ftype, ftoffset, acmode, ctx);
    if (ret != CL_CLEAN) {
	    if (ret == CL_VIRUS) {
            if (SCAN_ALL)
                viruses_found = 1;
            else {
                cli_append_virus(ctx, *virname);
                return ret;
            }
        } else if (ret > CL_TYPENO && acmode & AC_SCAN_VIR)
            saved_ret = ret;
        else
            return ret;
	}

    /* due to logical triggered, pcres cannot be evaluated until after full subsig matching */
    /* cannot save pcre execution state without possible evasion; must scan entire buffer */
    /* however, scanning the whole buffer may require the whole buffer being loaded into memory */
#if HAVE_PCRE
    if (root->pcre_metas) {
        int rc;
        uint64_t maxfilesize;

        if (map && (pcremode == PCRE_SCAN_FMAP)) {
            if (offset+length >= map->len) {
                /* check that scanned map does not exceed pcre maxfilesize limit */
                maxfilesize = (uint64_t)cl_engine_get_num(ctx->engine, CL_ENGINE_PCRE_MAX_FILESIZE, &rc);
                if (rc != CL_SUCCESS)
                    return rc;
                if (maxfilesize && (map->len > maxfilesize)) {
                    cli_dbgmsg("matcher_run: pcre max filesize (map) exceeded (limit: %llu, needed: %llu)\n",
                               (long long unsigned)maxfilesize, (long long unsigned)map->len);
                    return CL_EMAXSIZE;
                }

                cli_dbgmsg("matcher_run: performing regex matching on full map: %u+%u(%u) >= %zu\n", offset, length, offset+length, map->len);

                buffer = fmap_need_off_once(map, 0, map->len);
                if (!buffer)
                    return CL_EMEM;

                /* scan the full buffer */
                ret = cli_pcre_scanbuf(buffer, map->len, virname, acres, root, mdata, poffdata, ctx);
            }
        }
        else if (pcremode == PCRE_SCAN_BUFF) {
            /* check that scanned buffer does not exceed pcre maxfilesize limit */
            maxfilesize = (uint64_t)cl_engine_get_num(ctx->engine, CL_ENGINE_PCRE_MAX_FILESIZE, &rc);
            if (rc != CL_SUCCESS)
                return rc;
            if (maxfilesize && (length > maxfilesize)) {
                cli_dbgmsg("matcher_run: pcre max filesize (buf) exceeded (limit: %llu, needed: %u)\n", (long long unsigned)maxfilesize, length);
                return CL_EMAXSIZE;
            }

            cli_dbgmsg("matcher_run: performing regex matching on buffer with no map: %u+%u(%u)\n", offset, length, offset+length);
            /* scan the specified buffer */
            ret = cli_pcre_scanbuf(buffer, length, virname, acres, root, mdata, poffdata, ctx);
        }
    }
#endif /* HAVE_PCRE */
    /* end experimental fragment */

    if (ctx && !SCAN_ALL && ret == CL_VIRUS)
        cli_append_virus(ctx, *virname);
    if (ctx && SCAN_ALL && viruses_found)
        return CL_VIRUS;

    if (saved_ret && ret == CL_CLEAN)
        return saved_ret;
    return ret;
}
示例#5
0
static inline int matcher_run(const struct cli_matcher *root,
			      const unsigned char *buffer, uint32_t length,
			      const char **virname, struct cli_ac_data *mdata,
			      uint32_t offset,
			      const struct cli_target_info *tinfo,
			      cli_file_t ftype,
			      struct cli_matched_type **ftoffset,
			      unsigned int acmode,
			      struct cli_ac_result **acres,
			      fmap_t *map,
			      struct cli_bm_off *offdata,
			      uint32_t *viroffset,
			      cli_ctx *ctx)
{
    int ret;
    int32_t pos = 0;
    struct filter_match_info info;
    uint32_t orig_length, orig_offset;
    const unsigned char* orig_buffer;
    unsigned int viruses_found = 0;

    if (root->filter) {
	if(filter_search_ext(root->filter, buffer, length, &info) == -1) {
	    /*  for safety always scan last maxpatlen bytes */
	    pos = length - root->maxpatlen - 1;
	    if (pos < 0) pos = 0;
	    PERF_LOG_FILTER(pos, length, root->type);
	} else {
	    /* must not cut buffer for 64[4-4]6161, because we must be able to check
	     * 64! */
	    pos = info.first_match - root->maxpatlen - 1;
	    if (pos < 0) pos = 0;
	    PERF_LOG_FILTER(pos, length, root->type);
	}
    } else {
	PERF_LOG_FILTER(0, length, root->type);
    }

    orig_length = length;
    orig_buffer = buffer;
    orig_offset = offset;
    length -= pos;
    buffer += pos;
    offset += pos;
    if (!root->ac_only) {
	PERF_LOG_TRIES(0, 1, length);
	if (root->bm_offmode) {
	    /* Don't use prefiltering for BM offset mode, since BM keeps tracks
	     * of offsets itself, and doesn't work if we skip chunks of input
	     * data */
	    ret = cli_bm_scanbuff(orig_buffer, orig_length, virname, NULL, root, orig_offset, tinfo, offdata, viroffset);
	} else {
	    ret = cli_bm_scanbuff(buffer, length, virname, NULL, root, offset, tinfo, offdata, viroffset);
	}
	if (ret == CL_VIRUS) {
	    if (ctx) {
		cli_append_virus(ctx, *virname);
		if (SCAN_ALL)
		    viruses_found++;
		else
		    return ret;
	    }
	}
    }
    PERF_LOG_TRIES(acmode, 0, length);
    ret = cli_ac_scanbuff(buffer, length, virname, NULL, acres, root, mdata, offset, ftype, ftoffset, acmode, ctx);

    if (ctx && !SCAN_ALL && ret == CL_VIRUS)
	cli_append_virus(ctx, *virname);
    if (ctx && SCAN_ALL && viruses_found)
	return CL_VIRUS;

    return ret;
}
示例#6
0
static inline int matcher_run(const struct cli_matcher *root,
			      const unsigned char *buffer, uint32_t length,
			      const char **virname, struct cli_ac_data *mdata,
			      uint32_t offset,
			      const struct cli_target_info *tinfo,
			      cli_file_t ftype,
			      struct cli_matched_type **ftoffset,
			      unsigned int acmode,
			      struct cli_ac_result **acres,
			      fmap_t *map,
			      struct cli_bm_off *offdata,
			      uint32_t *viroffset,
			      cli_ctx *ctx)
{
    cli_infomsg(NULL,"DEBUG: in matcher_run\n");//CHR
    int ret;
    int32_t pos = 0;
    struct filter_match_info info;
    uint32_t orig_length, orig_offset;
    const unsigned char* orig_buffer;
    unsigned int viruses_found = 0;

    if (root->filter) {
    cli_infomsg(NULL,"DEBUG: has filter\n");//CHR
    // CHR function filter_search_ext will do pre-matchon prefix for a given pattern
	if(filter_search_ext(root->filter, buffer, length, &info) == -1) {
        cli_infomsg(NULL,"DEBUG: filter and in if\n");//CHR
	    /*  for safety always scan last maxpatlen bytes */
	    pos = length - root->maxpatlen - 1;
	    if (pos < 0) pos = 0;
	    PERF_LOG_FILTER(pos, length, root->type);
	} else { // CHR FSM match
        cli_infomsg(NULL,"DEBUG: filter and in else\n");//CHR
	    /* must not cut buffer for 64[4-4]6161, because we must be able to check
	     * 64! */
        //CHR if first_match is far more beyond max pattern length
        //CHR we need to move forward a little bit to speed up the following scan
	    pos = info.first_match - root->maxpatlen - 1;
        cli_infomsg(NULL,"DEBUG: pos=%d\n",pos);//CHR
	    if (pos < 0) pos = 0;
	    PERF_LOG_FILTER(pos, length, root->type);
	}
    } else {
	PERF_LOG_FILTER(0, length, root->type);
    }

    orig_length = length;
    orig_buffer = buffer;
    orig_offset = offset;
    //CHR pos is 0 in this case
    length -= pos;
    buffer += pos;
    offset += pos;
    if (!root->ac_only) {
    cli_infomsg(NULL,"DEBUG: !ac_only, bm scan first\n");//CHR
	PERF_LOG_TRIES(0, 1, length);
	if (root->bm_offmode) {
	    /* Don't use prefiltering for BM offset mode, since BM keeps tracks
	     * of offsets itself, and doesn't work if we skip chunks of input
	     * data */
         cli_infomsg(NULL,"DEBUG: scan in bm_offmode=1 mode\n"); //CHR
	    ret = cli_bm_scanbuff(orig_buffer, orig_length, virname, NULL, root, orig_offset, tinfo, offdata, viroffset);
	} else {
        cli_infomsg(NULL,"DEBUG: scan in bm_offmode=0 mode\n"); //CHR
        cli_infomsg(NULL,"DEBUG: pass into cli_bm_scanbuff with length=%d,offset=%d\n",length,offset);//CHR
	    ret = cli_bm_scanbuff(buffer, length, virname, NULL, root, offset, tinfo, offdata, viroffset);
	}
	if (ret == CL_VIRUS) {
        cli_infomsg(NULL,"DEBUG: bm scan find virus, won't do ac scan\n");//CHR
	    if (ctx) {
		cli_append_virus(ctx, *virname);
		if (SCAN_ALL)
		    viruses_found++;
		else
		    return ret;
	    }
	}
    }
    PERF_LOG_TRIES(acmode, 0, length);
    cli_infomsg(NULL,"DEBUG: ac scan\n");//CHR
    ret = cli_ac_scanbuff(buffer, length, virname, NULL, acres, root, mdata, offset, ftype, ftoffset, acmode, NULL);

    if (ctx && ret == CL_VIRUS)
	cli_append_virus(ctx, *virname);
    if (ctx && SCAN_ALL && viruses_found)
	return CL_VIRUS;

    return ret;
}