bb11805 fix multiple results. Refactor false positive and heuristic precedence logic.

This commit is contained in:
Steven Morgan 2017-04-18 12:03:36 -04:00
parent 21ef08e3e6
commit cbf5017a7d
22 changed files with 363 additions and 290 deletions

View file

@ -116,7 +116,7 @@ void clamd_virus_found_cb(int fd, const char *virname, void *ctx)
if (d == NULL) if (d == NULL)
return; return;
if (!(d->options & CL_SCAN_ALLMATCHES)) if (!(d->options & CL_SCAN_ALLMATCHES) && !(d->options & CL_SCAN_HEURISTIC_PRECEDENCE))
return; return;
if (virname == NULL) if (virname == NULL)
return; return;
@ -124,6 +124,7 @@ void clamd_virus_found_cb(int fd, const char *virname, void *ctx)
fname = (c && c->filename) ? c->filename : "(filename not set)"; fname = (c && c->filename) ? c->filename : "(filename not set)";
if (virname) { if (virname) {
d->infected++;
conn_reply_virus(d->conn, fname, virname); conn_reply_virus(d->conn, fname, virname);
if(c->virsize > 0 && optget(d->opts, "ExtendedDetectionInfo")->enabled) if(c->virsize > 0 && optget(d->opts, "ExtendedDetectionInfo")->enabled)
logg("~%s: %s(%s:%llu) FOUND\n", fname, virname, c->virhash, c->virsize); logg("~%s: %s(%s:%llu) FOUND\n", fname, virname, c->virhash, c->virsize);
@ -274,19 +275,18 @@ int scan_callback(STATBUF *sb, char *filename, const char *msg, enum cli_ftw_rea
} }
if (ret == CL_VIRUS) { if (ret == CL_VIRUS) {
scandata->infected++;
if (scandata->options & CL_SCAN_ALLMATCHES) { if (scandata->options & CL_SCAN_ALLMATCHES || (scandata->infected && scandata->options & CL_SCAN_HEURISTIC_PRECEDENCE)) {
if(optget(scandata->opts, "PreludeEnable")->enabled){ if(optget(scandata->opts, "PreludeEnable")->enabled){
prelude_logging(filename, virname, context.virhash, context.virsize); prelude_logging(filename, virname, context.virhash, context.virsize);
} }
virusaction(filename, virname, scandata->opts); virusaction(filename, virname, scandata->opts);
} else { } else {
scandata->infected++;
if (conn_reply_virus(scandata->conn, filename, virname) == -1) { if (conn_reply_virus(scandata->conn, filename, virname) == -1) {
free(filename); free(filename);
return CL_ETIMEOUT; return CL_ETIMEOUT;
} }
if(optget(scandata->opts, "PreludeEnable")->enabled){ if(optget(scandata->opts, "PreludeEnable")->enabled){
prelude_logging(filename, virname, context.virhash, context.virsize); prelude_logging(filename, virname, context.virhash, context.virsize);
} }

View file

@ -108,11 +108,7 @@ int cli_7unz (cli_ctx *ctx, size_t offset) {
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp); res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
if(res == SZ_ERROR_ENCRYPTED && DETECT_ENCRYPTED) { if(res == SZ_ERROR_ENCRYPTED && DETECT_ENCRYPTED) {
cli_dbgmsg("cli_7unz: Encrypted header found in archive.\n"); cli_dbgmsg("cli_7unz: Encrypted header found in archive.\n");
cli_append_virus(ctx, "Heuristics.Encrypted.7Zip"); found = cli_append_virus(ctx, "Heuristics.Encrypted.7Zip");
viruses_found++;
if(!SCAN_ALL) {
found = CL_VIRUS;
}
} else if(res == SZ_OK) { } else if(res == SZ_OK) {
UInt32 i, blockIndex = 0xFFFFFFFF; UInt32 i, blockIndex = 0xFFFFFFFF;
Byte *outBuffer = 0; Byte *outBuffer = 0;
@ -164,11 +160,13 @@ int cli_7unz (cli_ctx *ctx, size_t offset) {
encrypted = 1; encrypted = 1;
if(DETECT_ENCRYPTED) { if(DETECT_ENCRYPTED) {
cli_dbgmsg("cli_7unz: Encrypted files found in archive.\n"); cli_dbgmsg("cli_7unz: Encrypted files found in archive.\n");
cli_append_virus(ctx, "Heuristics.Encrypted.7Zip"); found = cli_append_virus(ctx, "Heuristics.Encrypted.7Zip");
viruses_found++; if (found != CL_CLEAN) {
if(!SCAN_ALL) { if (found == CL_VIRUS) {
found = CL_VIRUS; if (SCAN_ALL)
break; viruses_found++;
} else
break;
} }
} }
} }

View file

@ -248,6 +248,7 @@ static int apm_prtn_intxn(cli_ctx *ctx, struct apm_partition_info *aptable, size
int ret = CL_CLEAN, tmp = CL_CLEAN; int ret = CL_CLEAN, tmp = CL_CLEAN;
off_t pos; off_t pos;
uint32_t max_prtns = 0; uint32_t max_prtns = 0;
int virus_found = 0;
prtn_intxn_list_init(&prtncheck); prtn_intxn_list_init(&prtncheck);
@ -286,35 +287,30 @@ static int apm_prtn_intxn(cli_ctx *ctx, struct apm_partition_info *aptable, size
tmp = prtn_intxn_list_check(&prtncheck, &pitxn, apentry.pBlockStart, apentry.pBlockCount); tmp = prtn_intxn_list_check(&prtncheck, &pitxn, apentry.pBlockStart, apentry.pBlockCount);
if (tmp != CL_CLEAN) { if (tmp != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (tmp == CL_VIRUS)) { if (tmp == CL_VIRUS) {
apm_parsemsg("Name: %s\n", (char*)aptable.name); apm_parsemsg("Name: %s\n", (char*)aptable.name);
apm_parsemsg("Type: %s\n", (char*)aptable.type); apm_parsemsg("Type: %s\n", (char*)aptable.type);
cli_dbgmsg("cli_scanapm: detected intersection with partitions " cli_dbgmsg("cli_scanapm: detected intersection with partitions "
"[%u, %u]\n", pitxn, i); "[%u, %u]\n", pitxn, i);
cli_append_virus(ctx, PRTN_INTXN_DETECTION); ret = cli_append_virus(ctx, PRTN_INTXN_DETECTION);
if (ret == CL_VIRUS)
virus_found = 1;
if (SCAN_ALL || ret == CL_CLEAN)
tmp = 0;
else
goto leave;
} else {
ret = tmp; ret = tmp;
tmp = 0; goto leave;
}
else if (tmp == CL_VIRUS) {
apm_parsemsg("Name: %s\n", (char*)aptable.name);
apm_parsemsg("Type: %s\n", (char*)aptable.type);
cli_dbgmsg("cli_scanapm: detected intersection with partitions "
"[%u, %u]\n", pitxn, i);
cli_append_virus(ctx, PRTN_INTXN_DETECTION);
prtn_intxn_list_free(&prtncheck);
return CL_VIRUS;
}
else {
prtn_intxn_list_free(&prtncheck);
return tmp;
} }
} }
pos += sectorsize; pos += sectorsize;
} }
leave:
prtn_intxn_list_free(&prtncheck); prtn_intxn_list_free(&prtncheck);
if (virus_found)
return CL_VIRUS;
return ret; return ret;
} }

View file

@ -2810,11 +2810,10 @@ int cli_bytecode_runlsig(cli_ctx *cctx, struct cli_target_info *tinfo,
if (ctx.virname) { if (ctx.virname) {
int rc; int rc;
cli_dbgmsg("Bytecode found virus: %s\n", ctx.virname); cli_dbgmsg("Bytecode found virus: %s\n", ctx.virname);
cli_append_virus(cctx, ctx.virname);
if (!strncmp(ctx.virname, "BC.Heuristics", 13)) if (!strncmp(ctx.virname, "BC.Heuristics", 13))
rc = cli_found_possibly_unwanted(cctx); rc = cli_append_possibly_unwanted(cctx, ctx.virname);
else else
rc = CL_VIRUS; rc = cli_append_virus(cctx, ctx.virname);
cli_bytecode_context_clear(&ctx); cli_bytecode_context_clear(&ctx);
return rc; return rc;
} }

View file

@ -80,6 +80,7 @@ struct cl_fmap {
HANDLE fh; HANDLE fh;
HANDLE mh; HANDLE mh;
#endif #endif
unsigned char maphash[16];
uint32_t placeholder_for_bitmap; uint32_t placeholder_for_bitmap;
}; };

View file

@ -604,6 +604,7 @@ static int gpt_prtn_intxn(cli_ctx *ctx, struct gpt_header hdr, size_t sectorsize
off_t pos; off_t pos;
size_t maplen; size_t maplen;
uint32_t max_prtns = 0; uint32_t max_prtns = 0;
int virus_found = 0;
maplen = (*ctx->fmap)->real_len; maplen = (*ctx->fmap)->real_len;
@ -647,23 +648,19 @@ static int gpt_prtn_intxn(cli_ctx *ctx, struct gpt_header hdr, size_t sectorsize
else { else {
tmp = prtn_intxn_list_check(&prtncheck, &pitxn, gpe.firstLBA, gpe.lastLBA - gpe.firstLBA + 1); tmp = prtn_intxn_list_check(&prtncheck, &pitxn, gpe.firstLBA, gpe.lastLBA - gpe.firstLBA + 1);
if (tmp != CL_CLEAN) { if (tmp != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (tmp == CL_VIRUS)) { if (tmp == CL_VIRUS) {
cli_dbgmsg("cli_scangpt: detected intersection with partitions " cli_dbgmsg("cli_scangpt: detected intersection with partitions "
"[%u, %u]\n", pitxn, i); "[%u, %u]\n", pitxn, i);
cli_append_virus(ctx, PRTN_INTXN_DETECTION); ret = cli_append_virus(ctx, PRTN_INTXN_DETECTION);
if (ret == CL_VIRUS)
virus_found = 1;
if (SCAN_ALL || ret == CL_CLEAN)
tmp = 0;
else
goto leave;
} else {
ret = tmp; ret = tmp;
tmp = 0; goto leave;
}
else if (tmp == CL_VIRUS) {
cli_dbgmsg("cli_scangpt: detected intersection with partitions "
"[%u, %u]\n", pitxn, i);
cli_append_virus(ctx, PRTN_INTXN_DETECTION);
prtn_intxn_list_free(&prtncheck);
return CL_VIRUS;
}
else {
prtn_intxn_list_free(&prtncheck);
return tmp;
} }
} }
} }
@ -672,6 +669,9 @@ static int gpt_prtn_intxn(cli_ctx *ctx, struct gpt_header hdr, size_t sectorsize
pos += hdr.tableEntrySize; pos += hdr.tableEntrySize;
} }
leave:
prtn_intxn_list_free(&prtncheck); prtn_intxn_list_free(&prtncheck);
if (virus_found)
return CL_VIRUS;
return ret; return ret;
} }

View file

@ -176,8 +176,8 @@ struct macho_fat_arch
if(matcher) \ if(matcher) \
return -1; \ return -1; \
if(DETECT_BROKEN) { \ if(DETECT_BROKEN) { \
cli_append_virus(ctx, "Heuristics.Broken.Executable"); \ if (CL_VIRUS == cli_append_virus(ctx, "Heuristics.Broken.Executable")) \
return CL_VIRUS; \ return CL_VIRUS; \
} \ } \
return CL_EFORMAT return CL_EFORMAT

View file

@ -738,16 +738,15 @@ int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const char **
newres->offset = adjbuffer+p_res.match[0]; newres->offset = adjbuffer+p_res.match[0];
*res = newres; *res = newres;
} else { } else {
if (ctx && SCAN_ALL) { ret = CL_CLEAN;
viruses_found = 1; viruses_found = 1;
cli_append_virus(ctx, (const char *)pm->virname); if (ctx)
} ret = cli_append_virus(ctx, (const char *)pm->virname);
if (virname) if (virname)
*virname = pm->virname; *virname = pm->virname;
if (!ctx || !SCAN_ALL) { if (!ctx || !SCAN_ALL)
ret = CL_VIRUS; if (ret != CL_CLEAN)
break; break;
}
} }
} }
} }

View file

@ -157,8 +157,9 @@ static inline int matcher_run(const struct cli_matcher *root,
if (SCAN_ALL) if (SCAN_ALL)
viruses_found = 1; viruses_found = 1;
else { else {
cli_append_virus(ctx, *virname); ret = cli_append_virus(ctx, *virname);
return ret; if (ret != CL_CLEAN)
return ret;
} }
} }
} }
@ -169,8 +170,9 @@ static inline int matcher_run(const struct cli_matcher *root,
if (SCAN_ALL) if (SCAN_ALL)
viruses_found = 1; viruses_found = 1;
else { else {
cli_append_virus(ctx, *virname); ret = cli_append_virus(ctx, *virname);
return ret; if (ret != CL_CLEAN)
return ret;
} }
} else if (ret > CL_TYPENO && acmode & AC_SCAN_VIR) } else if (ret > CL_TYPENO && acmode & AC_SCAN_VIR)
saved_ret = ret; saved_ret = ret;
@ -227,7 +229,7 @@ static inline int matcher_run(const struct cli_matcher *root,
/* end experimental fragment */ /* end experimental fragment */
if (ctx && !SCAN_ALL && ret == CL_VIRUS) if (ctx && !SCAN_ALL && ret == CL_VIRUS)
cli_append_virus(ctx, *virname); return cli_append_virus(ctx, *virname);
if (ctx && SCAN_ALL && viruses_found) if (ctx && SCAN_ALL && viruses_found)
return CL_VIRUS; return CL_VIRUS;
@ -500,6 +502,11 @@ void cli_targetinfo(struct cli_target_info *info, unsigned int target, fmap_t *m
} }
int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx) int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx)
{
return cli_checkfp_virus(digest, size, ctx, NULL);
}
int cli_checkfp_virus(unsigned char *digest, size_t size, cli_ctx *ctx, const char * vname)
{ {
char md5[33]; char md5[33];
unsigned int i; unsigned int i;
@ -525,11 +532,11 @@ int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx)
sprintf(md5 + i * 2, "%02x", digest[i]); sprintf(md5 + i * 2, "%02x", digest[i]);
md5[32] = 0; md5[32] = 0;
cli_dbgmsg("FP SIGNATURE: %s:%u:%s\n", md5, (unsigned int) size, cli_dbgmsg("FP SIGNATURE: %s:%u:%s\n", md5, (unsigned int) size,
cli_get_last_virus(ctx) ? cli_get_last_virus(ctx) : "Name"); vname ? vname : "Name");
} }
if(cli_get_last_virus(ctx)) if(vname)
do_dsig_check = strncmp("W32S.", cli_get_last_virus(ctx), 5); do_dsig_check = strncmp("W32S.", vname, 5);
map = *ctx->fmap; map = *ctx->fmap;
have_sha1 = cli_hm_have_size(ctx->engine->hm_fp, CLI_HASH_SHA1, size) have_sha1 = cli_hm_have_size(ctx->engine->hm_fp, CLI_HASH_SHA1, size)
@ -586,7 +593,7 @@ int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx)
for(i=0; i<SHA1_HASH_SIZE; i++) for(i=0; i<SHA1_HASH_SIZE; i++)
sprintf((char *)shash1+i*2, "%02x", shash1[SHA1_HASH_SIZE+i]); sprintf((char *)shash1+i*2, "%02x", shash1[SHA1_HASH_SIZE+i]);
cli_errmsg("COLLECT:%s:%s:%u:%s:%s\n", shash256, shash1, size, cli_get_last_virus(ctx), ctx->entry_filename); cli_errmsg("COLLECT:%s:%s:%u:%s:%s\n", shash256, shash1, size, vname?vname:"noname", ctx->entry_filename);
} else } else
cli_errmsg("can't compute sha\n!"); cli_errmsg("can't compute sha\n!");
@ -614,10 +621,10 @@ int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx)
} }
if (ctx->engine->cb_hash) if (ctx->engine->cb_hash)
ctx->engine->cb_hash(fmap_fd(*ctx->fmap), size, (const unsigned char *)md5, cli_get_last_virus(ctx), ctx->cb_ctx); ctx->engine->cb_hash(fmap_fd(*ctx->fmap), size, (const unsigned char *)md5, vname?vname:"noname", ctx->cb_ctx);
if (ctx->engine->cb_stats_add_sample) if (ctx->engine->cb_stats_add_sample)
ctx->engine->cb_stats_add_sample(cli_get_last_virus(ctx), digest, size, &sections, ctx->engine->stats_data); ctx->engine->cb_stats_add_sample(vname?vname:"noname", digest, size, &sections, ctx->engine->stats_data);
if (sections.sections) if (sections.sections)
free(sections.sections); free(sections.sections);
@ -768,8 +775,9 @@ static int lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data
return CL_CLEAN; return CL_CLEAN;
if(matchicon(ctx, &target_info->exeinfo, ac_lsig->tdb.icongrp1, ac_lsig->tdb.icongrp2) == CL_VIRUS) { if(matchicon(ctx, &target_info->exeinfo, ac_lsig->tdb.icongrp1, ac_lsig->tdb.icongrp2) == CL_VIRUS) {
if(!ac_lsig->bc_idx) { if(!ac_lsig->bc_idx) {
cli_append_virus(ctx, ac_lsig->virname); rc = cli_append_virus(ctx, ac_lsig->virname);
return CL_VIRUS; if (rc != CL_CLEAN)
return rc;
} else if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, ac_lsig->bc_idx, acdata->lsigcnt[lsid], acdata->lsigsuboff_first[lsid], map) == CL_VIRUS) { } else if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, ac_lsig->bc_idx, acdata->lsigcnt[lsid], acdata->lsigsuboff_first[lsid], map) == CL_VIRUS) {
return CL_VIRUS; return CL_VIRUS;
} }
@ -777,8 +785,9 @@ static int lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data
return CL_CLEAN; return CL_CLEAN;
} }
if(!ac_lsig->bc_idx) { if(!ac_lsig->bc_idx) {
cli_append_virus(ctx, ac_lsig->virname); rc = cli_append_virus(ctx, ac_lsig->virname);
return CL_VIRUS; if (rc != CL_CLEAN)
return rc;
} }
if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, ac_lsig->bc_idx, acdata->lsigcnt[lsid], acdata->lsigsuboff_first[lsid], map) == CL_VIRUS) { if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, ac_lsig->bc_idx, acdata->lsigcnt[lsid], acdata->lsigsuboff_first[lsid], map) == CL_VIRUS) {
return CL_VIRUS; return CL_VIRUS;
@ -808,7 +817,7 @@ static int yara_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data
if (ac_lsig->flag & CLI_LSIG_FLAG_PRIVATE) { if (ac_lsig->flag & CLI_LSIG_FLAG_PRIVATE) {
rc = CL_CLEAN; rc = CL_CLEAN;
} else { } else {
cli_append_virus(ctx, ac_lsig->virname); rc = cli_append_virus(ctx, ac_lsig->virname);
} }
} }
return rc; return rc;
@ -1172,19 +1181,18 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
/* If matched size-based hash ... */ /* If matched size-based hash ... */
if (found % 2) { if (found % 2) {
viruses_found = 1; viruses_found = 1;
cli_append_virus(ctx, virname); ret = cli_append_virus(ctx, virname);
if (!SCAN_ALL) if (!SCAN_ALL || ret != CL_CLEAN)
break; break;
virname = NULL; virname = NULL;
} }
/* If matched size-agnostic hash ... */ /* If matched size-agnostic hash ... */
if (found > 1) { if (found > 1) {
viruses_found = 1; viruses_found = 1;
cli_append_virus(ctx, virname_w); ret = cli_append_virus(ctx, virname_w);
if (!SCAN_ALL || ret != CL_CLEAN)
if (!SCAN_ALL)
break; break;
} }
} }
} }
@ -1228,6 +1236,7 @@ int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer,
{ {
const struct cli_cdb *cdb; const struct cli_cdb *cdb;
unsigned int viruses_found = 0; unsigned int viruses_found = 0;
int ret = CL_CLEAN;
cli_dbgmsg("CDBNAME:%s:%llu:%s:%llu:%llu:%d:%u:%u:%p\n", cli_dbgmsg("CDBNAME:%s:%llu:%s:%llu:%llu:%d:%u:%u:%p\n",
cli_ftname(cli_get_container_type(ctx, -1)), (long long unsigned)fsizec, fname, (long long unsigned)fsizec, (long long unsigned)fsizer, cli_ftname(cli_get_container_type(ctx, -1)), (long long unsigned)fsizec, fname, (long long unsigned)fsizec, (long long unsigned)fsizer,
@ -1237,10 +1246,10 @@ int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer,
if (ctx->engine->cb_meta(cli_ftname(cli_get_container_type(ctx, -1)), fsizec, fname, fsizer, encrypted, filepos, ctx->cb_ctx) == CL_VIRUS) { if (ctx->engine->cb_meta(cli_ftname(cli_get_container_type(ctx, -1)), fsizec, fname, fsizer, encrypted, filepos, ctx->cb_ctx) == CL_VIRUS) {
cli_dbgmsg("inner file blacklisted by callback: %s\n", fname); cli_dbgmsg("inner file blacklisted by callback: %s\n", fname);
cli_append_virus(ctx, "Detected.By.Callback"); ret = cli_append_virus(ctx, "Detected.By.Callback");
viruses_found++; viruses_found++;
if(!SCAN_ALL) if(!SCAN_ALL || ret != CL_CLEAN)
return CL_VIRUS; return ret;
} }
if(!ctx->engine || !(cdb = ctx->engine->cdb)) if(!ctx->engine || !(cdb = ctx->engine->cdb))
@ -1273,10 +1282,10 @@ int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer,
if(cdb->name.re_magic && (!fname || cli_regexec(&cdb->name, fname, 0, NULL, 0) == REG_NOMATCH)) if(cdb->name.re_magic && (!fname || cli_regexec(&cdb->name, fname, 0, NULL, 0) == REG_NOMATCH))
continue; continue;
cli_append_virus(ctx, cdb->virname); ret = cli_append_virus(ctx, cdb->virname);
viruses_found++; viruses_found++;
if(!SCAN_ALL) if(!SCAN_ALL || ret != CL_CLEAN)
return CL_VIRUS; return ret;
} while((cdb = cdb->next)); } while((cdb = cdb->next));

View file

@ -208,6 +208,7 @@ int cli_exp_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acd
int cli_caloff(const char *offstr, const struct cli_target_info *info, unsigned int target, uint32_t *offdata, uint32_t *offset_min, uint32_t *offset_max); int cli_caloff(const char *offstr, const struct cli_target_info *info, unsigned int target, uint32_t *offdata, uint32_t *offset_min, uint32_t *offset_max);
int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx); int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx);
int cli_checkfp_virus(unsigned char *digest, size_t size, cli_ctx *ctx, const char * vname);
int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, int encrypted, unsigned int filepos, int res1, void *res2); int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, int encrypted, unsigned int filepos, int res1, void *res2);

View file

@ -590,9 +590,8 @@ cli_parse_mbox(const char *dir, cli_ctx *ctx)
if((retcode == CL_CLEAN) && ctx->found_possibly_unwanted && if((retcode == CL_CLEAN) && ctx->found_possibly_unwanted &&
(*ctx->virname == NULL || SCAN_ALL)) { (*ctx->virname == NULL || SCAN_ALL)) {
cli_append_virus(ctx, "Heuristics.Phishing.Email"); retcode = cli_append_virus(ctx, "Heuristics.Phishing.Email");
ctx->found_possibly_unwanted = 0; ctx->found_possibly_unwanted = 0;
retcode = CL_VIRUS;
} }
cli_dbgmsg("cli_mbox returning %d\n", retcode); cli_dbgmsg("cli_mbox returning %d\n", retcode);

View file

@ -502,23 +502,17 @@ static int mbr_primary_prtn_intxn(cli_ctx *ctx, struct mbr_boot_record mbr, size
tmp = prtn_intxn_list_check(&prtncheck, &pitxn, mbr.entries[i].firstLBA, tmp = prtn_intxn_list_check(&prtncheck, &pitxn, mbr.entries[i].firstLBA,
mbr.entries[i].numLBA); mbr.entries[i].numLBA);
if (tmp != CL_CLEAN) { if (tmp != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (tmp == CL_VIRUS)) { if (tmp == CL_VIRUS) {
cli_dbgmsg("cli_scanmbr: detected intersection with partitions " cli_dbgmsg("cli_scanmbr: detected intersection with partitions "
"[%u, %u]\n", pitxn, i); "[%u, %u]\n", pitxn, i);
cli_append_virus(ctx, PRTN_INTXN_DETECTION); ret = cli_append_virus(ctx, PRTN_INTXN_DETECTION);
if (SCAN_ALL || ret == CL_CLEAN)
tmp = 0;
else
goto leave;
} else {
ret = tmp; ret = tmp;
tmp = 0; goto leave;
}
else if (tmp == CL_VIRUS) {
cli_dbgmsg("cli_scanmbr: detected intersection with partitions "
"[%u, %u]\n", pitxn, i);
cli_append_virus(ctx, PRTN_INTXN_DETECTION);
prtn_intxn_list_free(&prtncheck);
return CL_VIRUS;
}
else {
prtn_intxn_list_free(&prtncheck);
return tmp;
} }
} }
@ -547,6 +541,7 @@ static int mbr_primary_prtn_intxn(cli_ctx *ctx, struct mbr_boot_record mbr, size
} }
} }
leave:
prtn_intxn_list_free(&prtncheck); prtn_intxn_list_free(&prtncheck);
return ret; return ret;
} }
@ -559,6 +554,7 @@ static int mbr_extended_prtn_intxn(cli_ctx *ctx, unsigned *prtncount, off_t extl
unsigned i, pitxn; unsigned i, pitxn;
int ret = CL_CLEAN, tmp = CL_CLEAN, mbr_base = 0; int ret = CL_CLEAN, tmp = CL_CLEAN, mbr_base = 0;
off_t pos = 0, logiclba = 0; off_t pos = 0, logiclba = 0;
int virus_found = 0;
mbr_base = sectorsize - sizeof(struct mbr_boot_record); mbr_base = sectorsize - sizeof(struct mbr_boot_record);
@ -585,23 +581,19 @@ static int mbr_extended_prtn_intxn(cli_ctx *ctx, unsigned *prtncount, off_t extl
/* assume that logical record is first and extended is second */ /* assume that logical record is first and extended is second */
tmp = prtn_intxn_list_check(&prtncheck, &pitxn, logiclba, ebr.entries[0].numLBA); tmp = prtn_intxn_list_check(&prtncheck, &pitxn, logiclba, ebr.entries[0].numLBA);
if (tmp != CL_CLEAN) { if (tmp != CL_CLEAN) {
if ((ctx->options & CL_SCAN_ALLMATCHES) && (tmp == CL_VIRUS)) { if (tmp == CL_VIRUS) {
cli_dbgmsg("cli_scanebr: detected intersection with partitions " cli_dbgmsg("cli_scanebr: detected intersection with partitions "
"[%u, %u]\n", pitxn, i); "[%u, %u]\n", pitxn, i);
cli_append_virus(ctx, PRTN_INTXN_DETECTION); ret = cli_append_virus(ctx, PRTN_INTXN_DETECTION);
if (ret == CL_VIRUS)
virus_found = 1;
if (SCAN_ALL || ret == CL_CLEAN)
tmp = 0;
else
goto leave;
} else {
ret = tmp; ret = tmp;
tmp = 0; goto leave;
}
else if (tmp == CL_VIRUS) {
cli_dbgmsg("cli_scanebr: detected intersection with partitions "
"[%u, %u]\n", pitxn, i);
cli_append_virus(ctx, PRTN_INTXN_DETECTION);
prtn_intxn_list_free(&prtncheck);
return CL_VIRUS;
}
else {
prtn_intxn_list_free(&prtncheck);
return tmp;
} }
} }
@ -616,6 +608,9 @@ static int mbr_extended_prtn_intxn(cli_ctx *ctx, unsigned *prtncount, off_t extl
++i; ++i;
} while (logiclba != 0 && (*prtncount) < ctx->engine->maxpartitions); } while (logiclba != 0 && (*prtncount) < ctx->engine->maxpartitions);
prtn_intxn_list_free(&prtncheck); leave:
prtn_intxn_list_free(&prtncheck);
if (virus_found)
return CL_VIRUS;
return ret; return ret;
} }

View file

@ -1088,16 +1088,40 @@ int cli_unlink(const char *pathname)
return 0; return 0;
} }
void cli_append_virus(cli_ctx * ctx, const char * virname) void cli_virus_found_cb(cli_ctx * ctx)
{ {
if (ctx->virname == NULL) if (ctx->engine->cb_virus_found)
return; ctx->engine->cb_virus_found(fmap_fd(*ctx->fmap), (const char *)*ctx->virname, ctx->cb_ctx);
if (ctx->limit_exceeded == 0 || SCAN_ALL) { }
if (ctx->engine->cb_virus_found)
ctx->engine->cb_virus_found(fmap_fd(*ctx->fmap), virname, ctx->cb_ctx); int cli_append_possibly_unwanted(cli_ctx * ctx, const char * virname)
{
if (SCAN_ALL)
return cli_append_virus(ctx, virname);
else if (ctx->options & CL_SCAN_HEURISTIC_PRECEDENCE)
return cli_append_virus(ctx, virname);
else if (ctx->num_viruses == 0 && ctx->virname != NULL && *ctx->virname == NULL) {
ctx->found_possibly_unwanted = 1;
ctx->num_viruses++; ctx->num_viruses++;
*ctx->virname = virname; *ctx->virname = virname;
} }
return CL_CLEAN;
}
int cli_append_virus(cli_ctx * ctx, const char * virname)
{
if (ctx->virname == NULL)
return CL_CLEAN;
if (ctx->fmap != NULL && (*ctx->fmap) != NULL && CL_VIRUS != cli_checkfp_virus((*ctx->fmap)->maphash, (*ctx->fmap)->len, ctx, virname))
return CL_CLEAN;
if (!SCAN_ALL && ctx->num_viruses != 0)
if (ctx->options & CL_SCAN_HEURISTIC_PRECEDENCE)
return CL_CLEAN;
if (ctx->limit_exceeded == 0 || SCAN_ALL) {
ctx->num_viruses++;
*ctx->virname = virname;
cli_virus_found_cb(ctx);
}
#if HAVE_JSON #if HAVE_JSON
if (SCAN_PROPERTIES && ctx->wrkproperty) { if (SCAN_PROPERTIES && ctx->wrkproperty) {
json_object *arrobj, *virobj; json_object *arrobj, *virobj;
@ -1105,17 +1129,18 @@ void cli_append_virus(cli_ctx * ctx, const char * virname)
arrobj = json_object_new_array(); arrobj = json_object_new_array();
if (NULL == arrobj) { if (NULL == arrobj) {
cli_errmsg("cli_append_virus: no memory for json virus array\n"); cli_errmsg("cli_append_virus: no memory for json virus array\n");
return; return CL_EMEM;
} }
json_object_object_add(ctx->wrkproperty, "Viruses", arrobj); json_object_object_add(ctx->wrkproperty, "Viruses", arrobj);
} }
virobj = json_object_new_string(virname); virobj = json_object_new_string(virname);
if (NULL == virobj) { if (NULL == virobj) {
cli_errmsg("cli_append_virus: no memory for json virus name object\n"); cli_errmsg("cli_append_virus: no memory for json virus name object\n");
return; return CL_EMEM;
} }
json_object_array_add(arrobj, virobj); json_object_array_add(arrobj, virobj);
} }
return CL_VIRUS;
#endif #endif
} }

View file

@ -601,9 +601,10 @@ static inline void cli_writeint32(void *offset, uint32_t value)
} }
#endif #endif
void cli_append_virus(cli_ctx *ctx, const char *virname); int cli_append_virus(cli_ctx *ctx, const char *virname);
const char *cli_get_last_virus(const cli_ctx *ctx); const char *cli_get_last_virus(const cli_ctx *ctx);
const char *cli_get_last_virus_str(const cli_ctx *ctx); const char *cli_get_last_virus_str(const cli_ctx *ctx);
void cli_virus_found_cb(cli_ctx *ctx);
void cli_set_container(cli_ctx *ctx, cli_file_t type, size_t size); void cli_set_container(cli_ctx *ctx, cli_file_t type, size_t size);
cli_file_t cli_get_container_type(cli_ctx *ctx, int index); cli_file_t cli_get_container_type(cli_ctx *ctx, int index);

View file

@ -2458,10 +2458,10 @@ int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset)
pdf_parseobj(&pdf, obj); pdf_parseobj(&pdf, obj);
if (SCAN_ALGO && obj->numfilters > PDF_FILTER_DTRIGGER) { if (SCAN_ALGO && obj->numfilters > PDF_FILTER_DTRIGGER) {
cli_append_virus(ctx, "Heuristic.PDF.TooManyFilters"); rc = cli_append_virus(ctx, "Heuristic.PDF.TooManyFilters");
alerts++; alerts++;
if (!SCAN_ALL) if (SCAN_ALL && rc == CL_VIRUS)
rc = CL_VIRUS; rc = CL_CLEAN;
} }
} }
@ -2479,8 +2479,8 @@ int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset)
* a password to decrypt */ * a password to decrypt */
cli_append_virus(ctx, "Heuristics.Encrypted.PDF"); cli_append_virus(ctx, "Heuristics.Encrypted.PDF");
alerts++; alerts++;
if (!SCAN_ALL) if (SCAN_ALL && rc == CL_VIRUS)
rc = CL_VIRUS; rc = CL_CLEAN;
} }
if (!rc) { if (!rc) {
@ -2547,8 +2547,7 @@ int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset)
if (!rc && SCAN_ALGO && (ctx->dconf->other & OTHER_CONF_PDFNAMEOBJ)) { if (!rc && SCAN_ALGO && (ctx->dconf->other & OTHER_CONF_PDFNAMEOBJ)) {
if (pdf.flags & (1 << ESCAPED_COMMON_PDFNAME)) { if (pdf.flags & (1 << ESCAPED_COMMON_PDFNAME)) {
/* for example /Fl#61te#44#65#63#6f#64#65 instead of /FlateDecode */ /* for example /Fl#61te#44#65#63#6f#64#65 instead of /FlateDecode */
cli_append_virus(ctx, "Heuristics.PDF.ObfuscatedNameObject"); cli_append_possibly_unwanted(ctx, "Heuristics.PDF.ObfuscatedNameObject");
rc = cli_found_possibly_unwanted(ctx);
} }
} }
#if 0 #if 0

View file

@ -555,7 +555,7 @@ static int scan_pe_mdb (cli_ctx * ctx, struct cli_exe_section *exe_section)
if (cli_debug_flag) { if (cli_debug_flag) {
md5 = hashset[CLI_HASH_MD5]; md5 = hashset[CLI_HASH_MD5];
if (md5) { if (md5) {
cli_dbgmsg("MDB: %u:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", cli_dbgmsg("MDB hashset: %u:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
exe_section->rsz, md5[0], md5[1], md5[2], md5[3], md5[4], md5[5], md5[6], md5[7], exe_section->rsz, md5[0], md5[1], md5[2], md5[3], md5[4], md5[5], md5[6], md5[7],
md5[8], md5[9], md5[10], md5[11], md5[12], md5[13], md5[14], md5[15]); md5[8], md5[9], md5[10], md5[11], md5[12], md5[13], md5[14], md5[15]);
} else if (cli_always_gen_section_hash) { } else if (cli_always_gen_section_hash) {
@ -589,17 +589,21 @@ static int scan_pe_mdb (cli_ctx * ctx, struct cli_exe_section *exe_section)
/* Do scans */ /* Do scans */
for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++) { for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++) {
if(foundsize[type] && cli_hm_scan(hashset[type], exe_section->rsz, &virname, mdb_sect, type) == CL_VIRUS) { if(foundsize[type] && cli_hm_scan(hashset[type], exe_section->rsz, &virname, mdb_sect, type) == CL_VIRUS) {
cli_append_virus(ctx, virname); ret = cli_append_virus(ctx, virname);
ret = CL_VIRUS; if (ret != CL_CLEAN) {
if (!SCAN_ALL) { if (ret != CL_VIRUS)
break; break;
else if (!SCAN_ALL)
break;
} }
} }
if(foundwild[type] && cli_hm_scan_wild(hashset[type], &virname, mdb_sect, type) == CL_VIRUS) { if(foundwild[type] && cli_hm_scan_wild(hashset[type], &virname, mdb_sect, type) == CL_VIRUS) {
cli_append_virus(ctx, virname); ret = cli_append_virus(ctx, virname);
ret = CL_VIRUS; if (ret != CL_CLEAN) {
if (!SCAN_ALL) { if (ret != CL_VIRUS)
break; break;
else if (!SCAN_ALL)
break;
} }
} }
} }
@ -2209,10 +2213,10 @@ static int validate_impname(const char *name, uint32_t length, int dll)
static inline int hash_impfns(cli_ctx *ctx, void **hashctx, uint32_t *impsz, struct pe_image_import_descriptor *image, const char *dllname, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size, int pe_plus, int *first) static inline int hash_impfns(cli_ctx *ctx, void **hashctx, uint32_t *impsz, struct pe_image_import_descriptor *image, const char *dllname, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size, int pe_plus, int *first)
{ {
uint32_t thuoff, offset; uint32_t thuoff = 0, offset;
fmap_t *map = *ctx->fmap; fmap_t *map = *ctx->fmap;
size_t dlllen = 0, fsize = map->len; size_t dlllen = 0, fsize = map->len;
int i, j, err, num_fns = 0, ret = CL_SUCCESS; int i, j, err = 0, num_fns = 0, ret = CL_SUCCESS;
const char *buffer; const char *buffer;
enum CLI_HASH_TYPE type; enum CLI_HASH_TYPE type;
#if HAVE_JSON #if HAVE_JSON
@ -2557,17 +2561,23 @@ static int scan_pe_imp(cli_ctx *ctx, struct pe_image_data_dir *dirs, struct cli_
/* Do scans */ /* Do scans */
for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++) { for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++) {
if(cli_hm_scan(hashset[type], impsz, &virname, imp, type) == CL_VIRUS) { if(cli_hm_scan(hashset[type], impsz, &virname, imp, type) == CL_VIRUS) {
cli_append_virus(ctx, virname); ret = cli_append_virus(ctx, virname);
ret = CL_VIRUS; if (ret != CL_CLEAN) {
if(!SCAN_ALL) if (ret != CL_VIRUS)
break; break;
else if (!SCAN_ALL)
break;
}
} }
if(cli_hm_scan_wild(hashset[type], &virname, imp, type) == CL_VIRUS) { if(cli_hm_scan_wild(hashset[type], &virname, imp, type) == CL_VIRUS) {
cli_append_virus(ctx, virname); cli_append_virus(ctx, virname);
ret = CL_VIRUS; if (ret != CL_CLEAN) {
if(!SCAN_ALL) if (ret != CL_VIRUS)
break; break;
} else if (!SCAN_ALL)
break;
}
}
} }
for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++) for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++)
@ -2759,8 +2769,8 @@ int cli_scanpe(cli_ctx *ctx)
cli_dbgmsg("Can't read new header address\n"); cli_dbgmsg("Can't read new header address\n");
/* truncated header? */ /* truncated header? */
if(DETECT_BROKEN_PE) { if(DETECT_BROKEN_PE) {
cli_append_virus(ctx,"Heuristics.Broken.Executable"); ret = cli_append_virus(ctx,"Heuristics.Broken.Executable");
return CL_VIRUS; return ret;
} }
return CL_CLEAN; return CL_CLEAN;
@ -2775,7 +2785,7 @@ int cli_scanpe(cli_ctx *ctx)
if(fmap_readn(map, &file_hdr, e_lfanew, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) { if(fmap_readn(map, &file_hdr, e_lfanew, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) {
/* bad information in e_lfanew - probably not a PE file */ /* bad information in e_lfanew - probably not a PE file */
cli_dbgmsg("Can't read file header\n"); cli_dbgmsg("cli_scanpe: Can't read file header\n");
return CL_CLEAN; return CL_CLEAN;
} }
@ -2908,8 +2918,8 @@ int cli_scanpe(cli_ctx *ctx)
pe_add_heuristic_property(ctx, "BadNumberOfSections"); pe_add_heuristic_property(ctx, "BadNumberOfSections");
#endif #endif
if(DETECT_BROKEN_PE) { if(DETECT_BROKEN_PE) {
cli_append_virus(ctx,"Heuristics.Broken.Executable"); ret = cli_append_virus(ctx,"Heuristics.Broken.Executable");
return CL_VIRUS; return ret;
} }
if(!ctx->corrupted_input) { if(!ctx->corrupted_input) {
@ -2945,8 +2955,8 @@ int cli_scanpe(cli_ctx *ctx)
#endif #endif
cli_dbgmsg("SizeOfOptionalHeader too small\n"); cli_dbgmsg("SizeOfOptionalHeader too small\n");
if(DETECT_BROKEN_PE) { if(DETECT_BROKEN_PE) {
cli_append_virus(ctx,"Heuristics.Broken.Executable"); ret = cli_append_virus(ctx,"Heuristics.Broken.Executable");
return CL_VIRUS; return ret;
} }
return CL_CLEAN; return CL_CLEAN;
@ -2956,8 +2966,8 @@ int cli_scanpe(cli_ctx *ctx)
if(fmap_readn(map, &optional_hdr32, at, sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr32)) { if(fmap_readn(map, &optional_hdr32, at, sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr32)) {
cli_dbgmsg("Can't read optional file header\n"); cli_dbgmsg("Can't read optional file header\n");
if(DETECT_BROKEN_PE) { if(DETECT_BROKEN_PE) {
cli_append_virus(ctx,"Heuristics.Broken.Executable"); ret = cli_append_virus(ctx,"Heuristics.Broken.Executable");
return CL_VIRUS; return ret;
} }
return CL_CLEAN; return CL_CLEAN;
@ -2974,8 +2984,8 @@ int cli_scanpe(cli_ctx *ctx)
cli_dbgmsg("Incorrect SizeOfOptionalHeader for PE32+\n"); cli_dbgmsg("Incorrect SizeOfOptionalHeader for PE32+\n");
if(DETECT_BROKEN_PE) { if(DETECT_BROKEN_PE) {
cli_append_virus(ctx,"Heuristics.Broken.Executable"); ret = cli_append_virus(ctx,"Heuristics.Broken.Executable");
return CL_VIRUS; return ret;
} }
return CL_CLEAN; return CL_CLEAN;
@ -3044,8 +3054,8 @@ int cli_scanpe(cli_ctx *ctx)
if(fmap_readn(map, &optional_hdr32 + 1, at, sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) { if(fmap_readn(map, &optional_hdr32 + 1, at, sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) {
cli_dbgmsg("Can't read optional file header\n"); cli_dbgmsg("Can't read optional file header\n");
if(DETECT_BROKEN_PE) { if(DETECT_BROKEN_PE) {
cli_append_virus(ctx,"Heuristics.Broken.Executable"); ret = cli_append_virus(ctx,"Heuristics.Broken.Executable");
return CL_VIRUS; return ret;
} }
return CL_CLEAN; return CL_CLEAN;
@ -3168,14 +3178,14 @@ int cli_scanpe(cli_ctx *ctx)
if (DETECT_BROKEN_PE && !native && (!(pe_plus?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment)) || (pe_plus?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment))%0x1000)) { if (DETECT_BROKEN_PE && !native && (!(pe_plus?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment)) || (pe_plus?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment))%0x1000)) {
cli_dbgmsg("Bad virtual alignment\n"); cli_dbgmsg("Bad virtual alignment\n");
cli_append_virus(ctx,"Heuristics.Broken.Executable"); ret = cli_append_virus(ctx,"Heuristics.Broken.Executable");
return CL_VIRUS; return ret;
} }
if (DETECT_BROKEN_PE && !native && (!(pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment)) || (pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment))%0x200)) { if (DETECT_BROKEN_PE && !native && (!(pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment)) || (pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment))%0x200)) {
cli_dbgmsg("Bad file alignment\n"); cli_dbgmsg("Bad file alignment\n");
cli_append_virus(ctx, "Heuristics.Broken.Executable"); ret = cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS; return ret;
} }
fsize = map->len; fsize = map->len;
@ -3206,8 +3216,8 @@ int cli_scanpe(cli_ctx *ctx)
free(exe_sections); free(exe_sections);
if(DETECT_BROKEN_PE) { if(DETECT_BROKEN_PE) {
cli_append_virus(ctx,"Heuristics.Broken.Executable"); ret = cli_append_virus(ctx,"Heuristics.Broken.Executable");
return CL_VIRUS; return ret;
} }
return CL_CLEAN; return CL_CLEAN;
@ -3251,8 +3261,8 @@ int cli_scanpe(cli_ctx *ctx)
free(exe_sections); free(exe_sections);
if(DETECT_BROKEN_PE) { if(DETECT_BROKEN_PE) {
cli_append_virus(ctx, "Heuristics.Broken.Executable"); ret = cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS; return ret;
} }
return CL_CLEAN; /* no ninjas to see here! move along! */ return CL_CLEAN; /* no ninjas to see here! move along! */
@ -3324,10 +3334,10 @@ int cli_scanpe(cli_ctx *ctx)
if (DETECT_BROKEN_PE && (!valign || (exe_sections[i].urva % valign))) { /* Bad virtual alignment */ if (DETECT_BROKEN_PE && (!valign || (exe_sections[i].urva % valign))) { /* Bad virtual alignment */
cli_dbgmsg("VirtualAddress is misaligned\n"); cli_dbgmsg("VirtualAddress is misaligned\n");
cli_dbgmsg("------------------------------------\n"); cli_dbgmsg("------------------------------------\n");
cli_append_virus(ctx, "Heuristics.Broken.Executable"); ret = cli_append_virus(ctx, "Heuristics.Broken.Executable");
free(section_hdr); free(section_hdr);
free(exe_sections); free(exe_sections);
return CL_VIRUS; return ret;
} }
if (exe_sections[i].rsz) { /* Don't bother with virtual only sections */ if (exe_sections[i].rsz) { /* Don't bother with virtual only sections */
@ -3355,8 +3365,8 @@ int cli_scanpe(cli_ctx *ctx)
free(section_hdr); free(section_hdr);
free(exe_sections); free(exe_sections);
if(DETECT_BROKEN_PE) { if(DETECT_BROKEN_PE) {
cli_append_virus(ctx, "Heuristics.Broken.Executable"); ret = cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS; return ret;
} }
return CL_CLEAN; return CL_CLEAN;
@ -3365,10 +3375,10 @@ int cli_scanpe(cli_ctx *ctx)
if(!i) { if(!i) {
if (DETECT_BROKEN_PE && exe_sections[i].urva!=hdr_size) { /* Bad first section RVA */ if (DETECT_BROKEN_PE && exe_sections[i].urva!=hdr_size) { /* Bad first section RVA */
cli_dbgmsg("First section is in the wrong place\n"); cli_dbgmsg("First section is in the wrong place\n");
cli_append_virus(ctx, "Heuristics.Broken.Executable"); ret = cli_append_virus(ctx, "Heuristics.Broken.Executable");
free(section_hdr); free(section_hdr);
free(exe_sections); free(exe_sections);
return CL_VIRUS; return ret;
} }
min = exe_sections[i].rva; min = exe_sections[i].rva;
@ -3376,10 +3386,10 @@ int cli_scanpe(cli_ctx *ctx)
} else { } else {
if (DETECT_BROKEN_PE && exe_sections[i].urva - exe_sections[i-1].urva != exe_sections[i-1].vsz) { /* No holes, no overlapping, no virtual disorder */ if (DETECT_BROKEN_PE && exe_sections[i].urva - exe_sections[i-1].urva != exe_sections[i-1].vsz) { /* No holes, no overlapping, no virtual disorder */
cli_dbgmsg("Virtually misplaced section (wrong order, overlapping, non contiguous)\n"); cli_dbgmsg("Virtually misplaced section (wrong order, overlapping, non contiguous)\n");
cli_append_virus(ctx, "Heuristics.Broken.Executable"); ret = cli_append_virus(ctx, "Heuristics.Broken.Executable");
free(section_hdr); free(section_hdr);
free(exe_sections); free(exe_sections);
return CL_VIRUS; return ret;
} }
if(exe_sections[i].rva < min) if(exe_sections[i].rva < min)
@ -3398,8 +3408,8 @@ int cli_scanpe(cli_ctx *ctx)
cli_dbgmsg("EntryPoint out of file\n"); cli_dbgmsg("EntryPoint out of file\n");
free(exe_sections); free(exe_sections);
if(DETECT_BROKEN_PE) { if(DETECT_BROKEN_PE) {
cli_append_virus(ctx,"Heuristics.Broken.Executable"); ret = cli_append_virus(ctx,"Heuristics.Broken.Executable");
return CL_VIRUS; return ret;
} }
return CL_CLEAN; return CL_CLEAN;
@ -3517,13 +3527,20 @@ int cli_scanpe(cli_ctx *ctx)
if(pt) { if(pt) {
pt += 15; pt += 15;
if((((uint32_t)cli_readint32(pt) ^ (uint32_t)cli_readint32(pt + 4)) == 0x505a4f) && (((uint32_t)cli_readint32(pt + 8) ^ (uint32_t)cli_readint32(pt + 12)) == 0xffffb) && (((uint32_t)cli_readint32(pt + 16) ^ (uint32_t)cli_readint32(pt + 20)) == 0xb8)) { if((((uint32_t)cli_readint32(pt) ^ (uint32_t)cli_readint32(pt + 4)) == 0x505a4f) && (((uint32_t)cli_readint32(pt + 8) ^ (uint32_t)cli_readint32(pt + 12)) == 0xffffb) && (((uint32_t)cli_readint32(pt + 16) ^ (uint32_t)cli_readint32(pt + 20)) == 0xb8)) {
cli_append_virus(ctx,"Heuristics.W32.Parite.B"); ret = cli_append_virus(ctx,"Heuristics.W32.Parite.B");
if (!SCAN_ALL) { if (ret != CL_CLEAN) {
free(exe_sections); if (ret == CL_VIRUS) {
return CL_VIRUS; if (!SCAN_ALL) {
free(exe_sections);
return ret;
}
else
viruses_found++;
} else {
free(exe_sections);
return ret;
}
} }
viruses_found++;
} }
} }
} }
@ -3635,15 +3652,21 @@ int cli_scanpe(cli_ctx *ctx)
break; break;
case KZSLOOP: case KZSLOOP:
if (op==kzdsize+0x48 && *kzcode==0x75 && kzlen-(int8_t)kzcode[1]-3<=kzinitlen && kzlen-(int8_t)kzcode[1]>=kzxorlen) { if (op==kzdsize+0x48 && *kzcode==0x75 && kzlen-(int8_t)kzcode[1]-3<=kzinitlen && kzlen-(int8_t)kzcode[1]>=kzxorlen) {
cli_append_virus(ctx,"Heuristics.W32.Kriz"); ret = cli_append_virus(ctx,"Heuristics.W32.Kriz");
if (!SCAN_ALL) { if (ret != CL_CLEAN) {
free(exe_sections); if (ret == CL_VIRUS) {
return CL_VIRUS; if (!SCAN_ALL) {
free(exe_sections);
return ret;
}
else
viruses_found++;
} else {
free(exe_sections);
return ret;
}
} }
viruses_found++;
} }
cli_dbgmsg("kriz: loop out of bounds, corrupted sample?\n"); cli_dbgmsg("kriz: loop out of bounds, corrupted sample?\n");
kzstate++; kzstate++;
} }
@ -3667,13 +3690,20 @@ int cli_scanpe(cli_ctx *ctx)
if((tbuff = fmap_need_off_once(map, exe_sections[nsections - 1].raw + rsize - bw, 4096))) { if((tbuff = fmap_need_off_once(map, exe_sections[nsections - 1].raw + rsize - bw, 4096))) {
if(cli_memstr(tbuff, 4091, "\xe8\x2c\x61\x00\x00", 5)) { if(cli_memstr(tbuff, 4091, "\xe8\x2c\x61\x00\x00", 5)) {
cli_append_virus(ctx, dam ? "Heuristics.W32.Magistr.A.dam" : "Heuristics.W32.Magistr.A"); ret = cli_append_virus(ctx, dam ? "Heuristics.W32.Magistr.A.dam" : "Heuristics.W32.Magistr.A");
if (!SCAN_ALL) { if (ret != CL_CLEAN) {
free(exe_sections); if (ret == CL_VIRUS) {
return CL_VIRUS; if (!SCAN_ALL) {
free(exe_sections);
return ret;
}
else
viruses_found++;
} else {
free(exe_sections);
return ret;
}
} }
viruses_found++;
} }
} }
} else if(rsize >= 0x7000 && vsize >= 0x7000 && ((vsize & 0xff) == 0xed)) { } else if(rsize >= 0x7000 && vsize >= 0x7000 && ((vsize & 0xff) == 0xed)) {
@ -3682,13 +3712,20 @@ int cli_scanpe(cli_ctx *ctx)
if((tbuff = fmap_need_off_once(map, exe_sections[nsections - 1].raw + rsize - bw, 4096))) { if((tbuff = fmap_need_off_once(map, exe_sections[nsections - 1].raw + rsize - bw, 4096))) {
if(cli_memstr(tbuff, 4091, "\xe8\x04\x72\x00\x00", 5)) { if(cli_memstr(tbuff, 4091, "\xe8\x04\x72\x00\x00", 5)) {
cli_append_virus(ctx,dam ? "Heuristics.W32.Magistr.B.dam" : "Heuristics.W32.Magistr.B"); ret = cli_append_virus(ctx,dam ? "Heuristics.W32.Magistr.B.dam" : "Heuristics.W32.Magistr.B");
if (!SCAN_ALL) { if (ret != CL_CLEAN) {
free(exe_sections); if (ret == CL_VIRUS) {
return CL_VIRUS; if (!SCAN_ALL) {
free(exe_sections);
return ret;
}
else
viruses_found++;
} else {
free(exe_sections);
return ret;
}
} }
viruses_found++;
} }
} }
} }
@ -3752,14 +3789,22 @@ int cli_scanpe(cli_ctx *ctx)
continue; continue;
if((jump=cli_readint32(code))==0x60ec8b55 || (code[4]==0x0ec && ((jump==0x83ec8b55 && code[6]==0x60) || (jump==0x81ec8b55 && !code[7] && !code[8])))) { if((jump=cli_readint32(code))==0x60ec8b55 || (code[4]==0x0ec && ((jump==0x83ec8b55 && code[6]==0x60) || (jump==0x81ec8b55 && !code[7] && !code[8])))) {
cli_append_virus(ctx,"Heuristics.W32.Polipos.A"); ret = cli_append_virus(ctx,"Heuristics.W32.Polipos.A");
if (!SCAN_ALL) { if (ret != CL_CLEAN) {
free(jumps); if (ret == CL_VIRUS) {
free(exe_sections); if (!SCAN_ALL) {
return CL_VIRUS; free(jumps);
free(exe_sections);
return ret;
}
else
viruses_found++;
} else {
free(jumps);
free(exe_sections);
return ret;
}
} }
viruses_found++;
} }
} }
@ -3775,21 +3820,28 @@ int cli_scanpe(cli_ctx *ctx)
ret = CL_CLEAN; ret = CL_CLEAN;
if (!stats) { if (!stats) {
ret = CL_EMEM; free(exe_sections);
return CL_EMEM;
} else { } else {
cli_parseres_special(EC32(dirs[2].VirtualAddress), EC32(dirs[2].VirtualAddress), map, exe_sections, nsections, fsize, hdr_size, 0, 0, &m, stats); cli_parseres_special(EC32(dirs[2].VirtualAddress), EC32(dirs[2].VirtualAddress), map, exe_sections, nsections, fsize, hdr_size, 0, 0, &m, stats);
if ((ret = cli_detect_swizz(stats)) == CL_VIRUS) if ((ret = cli_detect_swizz(stats)) == CL_VIRUS) {
cli_append_virus(ctx,"Heuristics.Trojan.Swizzor.Gen"); ret = cli_append_virus(ctx,"Heuristics.Trojan.Swizzor.Gen");
if (ret != CL_CLEAN) {
free(stats); if (ret == CL_VIRUS) {
} if (!SCAN_ALL) {
if (ret != CL_CLEAN) { free(stats);
if (!(ret == CL_VIRUS && SCAN_ALL)) { free(exe_sections);
free(exe_sections); return ret;
return ret; }
else
viruses_found++;
} else {
free(stats);
free(exe_sections);
return ret;
}
}
} }
viruses_found++;
} }
} }
} }
@ -4982,7 +5034,7 @@ int cli_peheader(fmap_t *map, struct cli_exe_info *peinfo)
if(fmap_readn(map, &file_hdr, peinfo->offset + e_lfanew, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) { if(fmap_readn(map, &file_hdr, peinfo->offset + e_lfanew, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) {
/* bad information in e_lfanew - probably not a PE file */ /* bad information in e_lfanew - probably not a PE file */
cli_dbgmsg("Can't read file header\n"); cli_dbgmsg("cli_peheader: Can't read file header\n");
return -1; return -1;
} }

View file

@ -814,32 +814,31 @@ int phishingScan(cli_ctx* ctx,tag_arguments_t* hrefs)
case CL_PHISH_CLEAN: case CL_PHISH_CLEAN:
continue; continue;
case CL_PHISH_NUMERIC_IP: case CL_PHISH_NUMERIC_IP:
cli_append_virus(ctx, "Heuristics.Phishing.Email.Cloaked.NumericIP"); cli_append_possibly_unwanted(ctx, "Heuristics.Phishing.Email.Cloaked.NumericIP");
break; break;
case CL_PHISH_CLOAKED_NULL: case CL_PHISH_CLOAKED_NULL:
cli_append_virus(ctx, "Heuristics.Phishing.Email.Cloaked.Null");/*fakesite%01%00@fake.example.com*/ cli_append_possibly_unwanted(ctx, "Heuristics.Phishing.Email.Cloaked.Null");/*fakesite%01%00@fake.example.com*/
break; break;
case CL_PHISH_SSL_SPOOF: case CL_PHISH_SSL_SPOOF:
cli_append_virus(ctx, "Heuristics.Phishing.Email.SSL-Spoof"); cli_append_possibly_unwanted(ctx, "Heuristics.Phishing.Email.SSL-Spoof");
break; break;
case CL_PHISH_CLOAKED_UIU: case CL_PHISH_CLOAKED_UIU:
cli_append_virus(ctx, "Heuristics.Phishing.Email.Cloaked.Username");/*http://banksite@fake.example.com*/ cli_append_possibly_unwanted(ctx, "Heuristics.Phishing.Email.Cloaked.Username");/*http://banksite@fake.example.com*/
break; break;
case CL_PHISH_HASH0: case CL_PHISH_HASH0:
cli_append_virus(ctx, "Heuristics.Safebrowsing.Suspected-malware_safebrowsing.clamav.net"); cli_append_possibly_unwanted(ctx, "Heuristics.Safebrowsing.Suspected-malware_safebrowsing.clamav.net");
break; break;
case CL_PHISH_HASH1: case CL_PHISH_HASH1:
cli_append_virus(ctx, "Heuristics.Phishing.URL.Blacklisted"); cli_append_possibly_unwanted(ctx, "Heuristics.Phishing.URL.Blacklisted");
break; break;
case CL_PHISH_HASH2: case CL_PHISH_HASH2:
cli_append_virus(ctx, "Heuristics.Safebrowsing.Suspected-phishing_safebrowsing.clamav.net"); cli_append_possibly_unwanted(ctx, "Heuristics.Safebrowsing.Suspected-phishing_safebrowsing.clamav.net");
break; break;
case CL_PHISH_NOMATCH: case CL_PHISH_NOMATCH:
default: default:
cli_append_virus(ctx, "Heuristics.Phishing.Email.SpoofedDomain"); cli_append_possibly_unwanted(ctx, "Heuristics.Phishing.Email.SpoofedDomain");
break; break;
} }
return cli_found_possibly_unwanted(ctx);
} }
return CL_CLEAN; return CL_CLEAN;
} }

View file

@ -227,9 +227,9 @@ static int cli_unrar_scanmetadata(int desc, unrar_metadata_t *metadata, cli_ctx
cli_dbgmsg("RAR: Encrypted files found in archive.\n"); cli_dbgmsg("RAR: Encrypted files found in archive.\n");
ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL); ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL);
if(ret != CL_VIRUS) { if(ret != CL_VIRUS) {
cli_append_virus(ctx, "Heuristics.Encrypted.RAR"); if (CL_VIRUS == cli_append_virus(ctx, "Heuristics.Encrypted.RAR"))
return CL_VIRUS; return CL_VIRUS;
} }
} }
if (virus_found != 0) if (virus_found != 0)
@ -269,13 +269,13 @@ static int cli_scanrar(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_c
cli_dbgmsg("RAR: Encrypted main header\n"); cli_dbgmsg("RAR: Encrypted main header\n");
if(DETECT_ENCRYPTED) { if(DETECT_ENCRYPTED) {
if (lseek(desc, 0, SEEK_SET) == -1) { if (lseek(desc, 0, SEEK_SET) == -1) {
cli_dbgmsg("RAR: call to lseek() failed\n"); cli_dbgmsg("RAR: call to lseek() failed\n");
return CL_ESEEK; return CL_ESEEK;
} }
ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL); ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL);
if(ret != CL_VIRUS) if(ret != CL_VIRUS)
cli_append_virus(ctx, "Heuristics.Encrypted.RAR"); if (CL_VIRUS == cli_append_virus(ctx, "Heuristics.Encrypted.RAR"))
return CL_VIRUS; return CL_VIRUS;
} }
return CL_CLEAN; return CL_CLEAN;
} if(ret == UNRAR_EMEM) { } if(ret == UNRAR_EMEM) {
@ -1179,9 +1179,9 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
cli_jsonbool(ctx->wrkproperty, "HasMacros", 1); cli_jsonbool(ctx->wrkproperty, "HasMacros", 1);
#endif #endif
if(BLOCK_MACROS && hasmacros) { if(BLOCK_MACROS && hasmacros) {
cli_append_virus(ctx, "Heuristics.OLE2.ContainsMacros"); ret = cli_append_virus(ctx, "Heuristics.OLE2.ContainsMacros");
ret = CL_VIRUS; if (ret == CL_VIRUS)
viruses_found++; viruses_found++;
} }
if (SCAN_ALL && viruses_found) if (SCAN_ALL && viruses_found)
return CL_VIRUS; return CL_VIRUS;
@ -1609,24 +1609,20 @@ static int cli_scanscrenc(cli_ctx *ctx)
static int cli_scanriff(cli_ctx *ctx) static int cli_scanriff(cli_ctx *ctx)
{ {
int ret = CL_CLEAN; int ret = CL_CLEAN;
if(cli_check_riff_exploit(ctx) == 2) { if (cli_check_riff_exploit(ctx) == 2)
ret = CL_VIRUS; ret = cli_append_virus(ctx, "Heuristics.Exploit.W32.MS05-002");
cli_append_virus(ctx, "Heuristics.Exploit.W32.MS05-002");
}
return ret; return ret;
} }
static int cli_scanjpeg(cli_ctx *ctx) static int cli_scanjpeg(cli_ctx *ctx)
{ {
int ret = CL_CLEAN; int ret = CL_CLEAN;
if(cli_check_jpeg_exploit(ctx, 0) == 1) { if(cli_check_jpeg_exploit(ctx, 0) == 1)
ret = CL_VIRUS; ret = cli_append_virus(ctx, "Heuristics.Exploit.W32.MS04-028");
cli_append_virus(ctx, "Heuristics.Exploit.W32.MS04-028");
}
return ret; return ret;
} }
@ -1872,20 +1868,20 @@ static int cli_scan_structured(cli_ctx *ctx)
if(cc_count != 0 && cc_count >= ctx->engine->min_cc_count) { if(cc_count != 0 && cc_count >= ctx->engine->min_cc_count) {
cli_dbgmsg("cli_scan_structured: %u credit card numbers detected\n", cc_count); cli_dbgmsg("cli_scan_structured: %u credit card numbers detected\n", cc_count);
cli_append_virus(ctx,"Heuristics.Structured.CreditCardNumber"); if (CL_VIRUS == cli_append_virus(ctx,"Heuristics.Structured.CreditCardNumber"))
if (SCAN_ALL) if (SCAN_ALL)
viruses_found++; viruses_found++;
else else
return CL_VIRUS; return CL_VIRUS;
} }
if(ssn_count != 0 && ssn_count >= ctx->engine->min_ssn_count) { if(ssn_count != 0 && ssn_count >= ctx->engine->min_ssn_count) {
cli_dbgmsg("cli_scan_structured: %u social security numbers detected\n", ssn_count); cli_dbgmsg("cli_scan_structured: %u social security numbers detected\n", ssn_count);
cli_append_virus(ctx,"Heuristics.Structured.SSN"); if (CL_VIRUS == cli_append_virus(ctx,"Heuristics.Structured.SSN"))
if (SCAN_ALL) if (SCAN_ALL)
viruses_found++; viruses_found++;
else else
return CL_VIRUS; return CL_VIRUS;
} }
if (viruses_found) if (viruses_found)
@ -2161,32 +2157,32 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_
case CL_TYPE_MHTML: case CL_TYPE_MHTML:
if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX)) { if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX)) {
cli_dbgmsg("MHTML signature found at %u\n", (unsigned int) fpt->offset); cli_dbgmsg("MHTML signature found at %u\n", (unsigned int) fpt->offset);
ret = cli_scanmail(ctx); nret = ret = cli_scanmail(ctx);
} }
break; break;
case CL_TYPE_XDP: case CL_TYPE_XDP:
if(SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF)) { if(SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF)) {
cli_dbgmsg("XDP signature found at %u\n", (unsigned int) fpt->offset); cli_dbgmsg("XDP signature found at %u\n", (unsigned int) fpt->offset);
ret = cli_scanxdp(ctx); nret = ret = cli_scanxdp(ctx);
} }
break; break;
case CL_TYPE_XML_WORD: case CL_TYPE_XML_WORD:
if(SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_MSXML)) { if(SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_MSXML)) {
cli_dbgmsg("XML-WORD signature found at %u\n", (unsigned int) fpt->offset); cli_dbgmsg("XML-WORD signature found at %u\n", (unsigned int) fpt->offset);
ret = cli_scanmsxml(ctx); nret = ret = cli_scanmsxml(ctx);
} }
break; break;
case CL_TYPE_XML_XL: case CL_TYPE_XML_XL:
if(SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_MSXML)) { if(SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_MSXML)) {
cli_dbgmsg("XML-XL signature found at %u\n", (unsigned int) fpt->offset); cli_dbgmsg("XML-XL signature found at %u\n", (unsigned int) fpt->offset);
ret = cli_scanmsxml(ctx); nret = ret = cli_scanmsxml(ctx);
} }
break; break;
case CL_TYPE_XML_HWP: case CL_TYPE_XML_HWP:
if(SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_HWP)) { if(SCAN_XMLDOCS && (DCONF_DOC & DOC_CONF_HWP)) {
cli_dbgmsg("XML-HWP signature found at %u\n", (unsigned int) fpt->offset); cli_dbgmsg("XML-HWP signature found at %u\n", (unsigned int) fpt->offset);
ret = cli_scanhwpml(ctx); nret = ret = cli_scanhwpml(ctx);
} }
break; break;
case CL_TYPE_RARSFX: case CL_TYPE_RARSFX:
@ -2441,10 +2437,16 @@ static int magic_scandesc_cleanup(cli_ctx *ctx, cli_file_t type, unsigned char *
UNUSEDPARAM(type); UNUSEDPARAM(type);
if (retcode == CL_CLEAN && (ctx->found_possibly_unwanted || ctx->num_viruses != 0)) if (retcode == CL_CLEAN && ctx->found_possibly_unwanted) {
cli_virus_found_cb(ctx);
cb_retcode = CL_VIRUS; cb_retcode = CL_VIRUS;
else }
cb_retcode = retcode; else {
if (retcode == CL_CLEAN && ctx->num_viruses != 0)
cb_retcode = CL_VIRUS;
else
cb_retcode = retcode;
}
cli_dbgmsg("cli_magic_scandesc: returning %d %s\n", retcode, __AT__); cli_dbgmsg("cli_magic_scandesc: returning %d %s\n", retcode, __AT__);
if(ctx->engine->cb_post_scan) { if(ctx->engine->cb_post_scan) {
@ -2689,6 +2691,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
perf_stop(ctx, PERFT_CACHE); perf_stop(ctx, PERFT_CACHE);
hashed_size = (*ctx->fmap)->len; hashed_size = (*ctx->fmap)->len;
memcpy((*ctx->fmap)->maphash, hash, 16);
ctx->hook_lsig_matches = NULL; ctx->hook_lsig_matches = NULL;
if(!(ctx->options&~CL_SCAN_ALLMATCHES) || (ctx->recursion == ctx->engine->maxreclevel)) { /* raw mode (stdin, etc.) or last level of recursion */ if(!(ctx->options&~CL_SCAN_ALLMATCHES) || (ctx->recursion == ctx->engine->maxreclevel)) { /* raw mode (stdin, etc.) or last level of recursion */

View file

@ -90,8 +90,7 @@ int cli_check_mydoom_log(cli_ctx *ctx)
if ((~check) != key) if ((~check) != key)
return CL_CLEAN; return CL_CLEAN;
cli_append_virus(ctx, "Heuristics.Worm.Mydoom.M.log"); return cli_append_virus(ctx, "Heuristics.Worm.Mydoom.M.log");
return CL_VIRUS;
} }
static int jpeg_check_photoshop_8bim(cli_ctx *ctx, off_t *off) static int jpeg_check_photoshop_8bim(cli_ctx *ctx, off_t *off)

View file

@ -146,8 +146,7 @@ int cli_parsetiff(cli_ctx *ctx)
if(entry.value + value_size > map->len) { if(entry.value + value_size > map->len) {
cli_warnmsg("cli_parsetiff: TFD entry field %u exceeds bounds of TIFF file [%llu > %llu]\n", cli_warnmsg("cli_parsetiff: TFD entry field %u exceeds bounds of TIFF file [%llu > %llu]\n",
i, (long long unsigned)(entry.value + value_size), (long long unsigned)map->len); i, (long long unsigned)(entry.value + value_size), (long long unsigned)map->len);
cli_append_virus(ctx, "Heuristic.TIFF.OutOfBoundsAccess"); return cli_append_virus(ctx, "Heuristic.TIFF.OutOfBoundsAccess");
return CL_VIRUS;
} }
} }
} }

View file

@ -556,9 +556,8 @@ static unsigned int lhdr(fmap_t *map, uint32_t loff,uint32_t zsize, unsigned int
if(detect_encrypted && (LH_flags & F_ENCR) && DETECT_ENCRYPTED) { if(detect_encrypted && (LH_flags & F_ENCR) && DETECT_ENCRYPTED) {
cli_dbgmsg("cli_unzip: Encrypted files found in archive.\n"); cli_dbgmsg("cli_unzip: Encrypted files found in archive.\n");
cli_append_virus(ctx, "Heuristics.Encrypted.Zip"); *ret = cli_append_virus(ctx, "Heuristics.Encrypted.Zip");
*ret = CL_VIRUS; if ((*ret == CL_VIRUS && !SCAN_ALL) || *ret != CL_CLEAN) {
if (!SCAN_ALL) {
fmap_unneed_off(map, loff, SIZEOF_LH); fmap_unneed_off(map, loff, SIZEOF_LH);
return 0; return 0;
} }

View file

@ -461,27 +461,27 @@ static void do_phishing_test_allscan(const struct rtest *rtest)
fail_unless(rc == CL_CLEAN,"phishingScan"); fail_unless(rc == CL_CLEAN,"phishingScan");
switch(rtest->result) { switch(rtest->result) {
case 0: case 0:
fail_unless_fmt(ctx.found_possibly_unwanted, fail_unless_fmt(ctx.num_viruses,
"this should be phishing, realURL: %s, displayURL: %s", "this should be phishing, realURL: %s, displayURL: %s",
rtest->realurl, rtest->displayurl); rtest->realurl, rtest->displayurl);
break; break;
case 1: case 1:
fail_unless_fmt(!ctx.found_possibly_unwanted, fail_unless_fmt(!ctx.num_viruses,
"this should be whitelisted, realURL: %s, displayURL: %s", "this should be whitelisted, realURL: %s, displayURL: %s",
rtest->realurl, rtest->displayurl); rtest->realurl, rtest->displayurl);
break; break;
case 2: case 2:
fail_unless_fmt(!ctx.found_possibly_unwanted, fail_unless_fmt(!ctx.num_viruses,
"this should be clean, realURL: %s, displayURL: %s", "this should be clean, realURL: %s, displayURL: %s",
rtest->realurl, rtest->displayurl); rtest->realurl, rtest->displayurl);
break; break;
case 3: case 3:
if(!loaded_2) if(!loaded_2)
fail_unless_fmt(!ctx.found_possibly_unwanted, fail_unless_fmt(!ctx.num_viruses,
"this should be clean, realURL: %s, displayURL: %s", "this should be clean, realURL: %s, displayURL: %s",
rtest->realurl, rtest->displayurl); rtest->realurl, rtest->displayurl);
else { else {
fail_unless_fmt(ctx.found_possibly_unwanted, fail_unless_fmt(ctx.num_viruses,
"this should be blacklisted, realURL: %s, displayURL: %s", "this should be blacklisted, realURL: %s, displayURL: %s",
rtest->realurl, rtest->displayurl); rtest->realurl, rtest->displayurl);
if (*ctx.virname) if (*ctx.virname)